diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/CREDITS linux-2.4.20/CREDITS
--- linux-2.4.19/CREDITS	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/CREDITS	2002-10-04 00:41:12.000000000 +0000
@@ -704,6 +704,11 @@
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Martin Devera
+E: devik@cdi.cz
+W: http://luxik.cdi.cz/~devik/qos/
+D: HTB qdisc and random networking hacks
+
 N: Alex deVries
 E: adevries@thepuffingroup.com
 D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
@@ -1329,6 +1334,12 @@
 S: Provo, Utah 84606-5607
 S: USA
 
+N: Marcel Holtmann
+E: marcel@holtmann.org
+W: http://www.holtmann.org
+D: Author of the Linux Bluetooth Subsystem PC Card drivers
+S: Germany
+
 N: Rob W. W. Hooft
 E: hooft@EMBL-Heidelberg.DE
 D: Shared libs for graphics-tools and for the f2c compiler
@@ -2154,7 +2165,7 @@
 S: South Australia
 
 N. Wolfgang Muees
-E: wmues@nexgo.de
+E: wolfgang@iksw-muees.de
 D: Auerswald USB driver
 
 N: Ian A. Murdock
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bk-kernel-howto.txt linux-2.4.20/Documentation/BK-usage/bk-kernel-howto.txt
--- linux-2.4.19/Documentation/BK-usage/bk-kernel-howto.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/bk-kernel-howto.txt	2002-10-04 00:41:18.000000000 +0000
@@ -0,0 +1,275 @@
+
+		   Doing the BK Thing, Penguin-Style
+
+
+
+
+This set of notes is intended mainly for kernel developers, occasional
+or full-time, but sysadmins and power users may find parts of it useful
+as well.  It assumes at least a basic familiarity with CVS, both at a
+user level (use on the cmd line) and at a higher level (client-server model).
+Due to the author's background, an operation may be described in terms
+of CVS, or in terms of how that operation differs from CVS.
+
+This is -not- intended to be BitKeeper documentation.  Always run
+"bk help <command>" or in X "bk helptool <command>" for reference
+documentation.
+
+
+BitKeeper Concepts
+------------------
+
+In the true nature of the Internet itself, BitKeeper is a distributed
+system.  When applied to revision control, this means doing away with
+client-server, and changing to a parent-child model... essentially
+peer-to-peer.  On the developer's end, this also represents a
+fundamental disruption in the standard workflow of changes, commits,
+and merges.  You will need to take a few minutes to think about
+how to best work under BitKeeper, and re-optimize things a bit.
+In some sense it is a bit radical, because it might described as
+tossing changes out into a maelstrom and having them magically
+land at the right destination... but I'm getting ahead of myself.
+
+Let's start with this progression:
+Each BitKeeper source tree on disk is a repository unto itself.
+Each repository has a parent.
+Each repository contains a set of a changesets ("csets").
+Each cset is one or more changed files, bundled together.
+
+Each tree is a repository, so all changes are checked into the local
+tree.  When a change is checked in, all modified files are grouped
+into a logical unit, the changeset.  Internally, BK links these
+changesets in a tree, representing various converging and diverging
+lines of development.  These changesets are the bread and butter of
+the BK system.
+
+After the concept of changesets, the next thing you need to get used
+to is having multiple copies of source trees lying around.  This -really-
+takes some getting used to, for some people.  Separate source trees
+are the means in BitKeeper by which you delineate parallel lines
+of development, both minor and major.  What would be branches in
+CVS become separate source trees, or "clones" in BitKeeper [heh,
+or Star Wars] terminology.
+
+Clones and changesets are the tools from which most of the power of
+BitKeeper is derived.  As mentioned earlier, each clone has a parent,
+the tree used as the source when the new clone was created.  In a
+CVS-like setup, the parent would be a remote server on the Internet,
+and the child is your local clone of that tree.
+
+Once you have established a common baseline between two source trees --
+a common parent -- then you can merge changesets between those two
+trees with ease.  Merging changes into a tree is called a "pull", and
+is analagous to 'cvs update'.  A pull downloads all the changesets in
+the remote tree you do not have, and merges them.  Sending changes in
+one tree to another tree is called a "push".  Push sends all changes
+in the local tree the remote does not yet have, and merges them.
+
+From these concepts come some initial command examples:
+
+1) bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5
+Download a 2.5 stock kernel tree, naming it "linus-2.5" in the local dir.
+The "-q" disables listing every single file as it is downloaded.
+
+2) bk clone -ql linus-2.5 alpha-2.5
+Create a separate source tree for the Alpha AXP architecture.
+The "-l" uses hard links instead of copying data, since both trees are
+on the local disk.  You can also replace the above with "bk lclone -q ..."
+
+You only clone a tree -once-.  After cloning the tree lives a long time
+on disk, being updating by pushes and pulls.
+
+3) cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5
+Download changes in "alpha-2.5" repository which are not present
+in the local repository, and merge them into the source tree.
+
+4) bk -r co -q
+Because every tree is a repository, files must be checked out before
+they will be in their standard places in the source tree.
+
+5)	bk vi fs/inode.c				# example change...
+	bk citool					# checkin, using X tool
+	bk push bk://gkernel@bkbits.net/alpha-2.5	# upload change
+Typical example of a BK sequence that would replace the analagous CVS
+situation,
+	vi fs/inode.c
+	cvs commit
+
+As this is just supposed to be a quick BK intro, for more in-depth
+tutorials, live working demos, and docs, see http://www.bitkeeper.com/
+
+
+
+BK and Kernel Development Workflow
+----------------------------------
+Currently the latest 2.5 tree is available via "bk clone $URL"
+and "bk pull $URL" at http://linux.bkbits.net/linux-2.5
+This should change in a few weeks to a kernel.org URL.
+
+
+A big part of using BitKeeper is organizing the various trees you have
+on your local disk, and organizing the flow of changes among those
+trees, and remote trees.  If one were to graph the relationships between
+a desired BK setup, you are likely to see a few-many-few graph, like
+this:
+
+		    linux-2.5
+		        |
+	       merge-to-linus-2.5
+		 /    |      |
+	        /     |      |
+	vm-hacks  bugfixes  filesys   personal-hacks
+	      \	      |	     |		/
+	       \      |      |         /
+		\     |      |        /
+	         testing-and-validation
+
+Since a "bk push" sends all changes not in the target tree, and
+since a "bk pull" receives all changes not in the source tree, you want
+to make sure you are only pushing specific changes to the desired tree,
+not all changes from "peer parent" trees.  For example, pushing a change
+from the testing-and-validation tree would probably be a bad idea,
+because it will push all changes from vm-hacks, bugfixes, filesys, and
+personal-hacks trees into the target tree.
+
+One would typically work on only one "theme" at a time, either
+vm-hacks or bugfixes or filesys, keeping those changes isolated in
+their own tree during development, and only merge the isolated with
+other changes when going upstream (to Linus or other maintainers) or
+downstream (to your "union" trees, like testing-and-validation above).
+
+It should be noted that some of this separation is not just recommended
+practice, it's actually [for now] -enforced- by BitKeeper.  BitKeeper
+requires that changesets maintain a certain order, which is the reason
+that "bk push" sends all local changesets the remote doesn't have.  This
+separation may look like a lot of wasted disk space at first, but it
+helps when two unrelated changes may "pollute" the same area of code, or
+don't follow the same pace of development, or any other of the standard
+reasons why one creates a development branch.
+
+Small development branches (clones) will appear and disappear:
+
+	-------- A --------- B --------- C --------- D -------
+	          \                                 /
+		   -----short-term devel branch-----
+
+While long-term branches will parallel a tree (or trees), with period
+merge points.  In this first example, we pull from a tree (pulls,
+"\") periodically, such as what occurs when tracking changes in a
+vendor tree, never pushing changes back up the line:
+
+	-------- A --------- B --------- C --------- D -------
+	          \                       \           \
+	           ----long-term devel branch-----------------
+
+And then a more common case in Linux kernel development, a long term
+branch with periodic merges back into the tree (pushes, "/"):
+
+	-------- A --------- B --------- C --------- D -------
+	          \                       \         / \
+	           ----long-term devel branch-----------------
+
+
+
+
+
+Submitting Changes to Linus
+---------------------------
+There's a bit of an art, or style, of submitting changes to Linus.
+Since Linus's tree is now (you might say) fully integrated into the
+distributed BitKeeper system, there are several prerequisites to
+properly submitting a BitKeeper change.  All these prereq's are just
+general cleanliness of BK usage, so as people become experts at BK, feel
+free to optimize this process further (assuming Linus agrees, of
+course).
+
+
+
+0) Make sure your tree was originally cloned from the linux-2.5 tree
+created by Linus.  If your tree does not have this as its ancestor, it
+is impossible to reliably exchange changesets.
+
+
+
+1) Pay attention to your commit text.  The commit message that
+accompanies each changeset you submit will live on forever in history,
+and is used by Linus to accurately summarize the changes in each
+pre-patch.  Remember that there is no context, so
+	"fix for new scheduler changes"
+would be too vague, but
+	"fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics"
+would be much better.
+
+You can and should use the command "bk comment -C<rev>" to update the
+commit text, and improve it after the fact.  This is very useful for
+development: poor, quick descriptions during development, which get
+cleaned up using "bk comment" before issuing the "bk push" to submit the
+changes.
+
+
+
+2) Include an Internet-available URL for Linus to pull from, such as
+
+	Pull from:  http://gkernel.bkbits.net/net-drivers-2.5
+
+
+
+3) Include a summary and "diffstat -p1" of each changeset that will be
+downloaded, when Linus issues a "bk pull".  The author auto-generates
+these summaries using "bk push -nl <parent> 2>&1", to obtain a listing
+of all the pending-to-send changesets, and their commit messages.
+
+It is important to show Linus what he will be downloading when he issues
+a "bk pull", to reduce the time required to sift the changes once they
+are downloaded to Linus's local machine.
+
+IMPORTANT NOTE:  One of the features of BK is that your repository does
+not have to be up to date, in order for Linus to receive your changes.
+It is considered a courtesy to keep your repository fairly recent, to
+lessen any potential merge work Linus may need to do.
+
+
+4) Split up your changes.  Each maintainer<->Linus situation is likely
+to be slightly different here, so take this just as general advice.  The
+author splits up changes according to "themes" when merging with Linus.
+Simultaneous pushes from local development go to special trees which
+exist solely to house changes "queued" for Linus.  Example of the trees:
+
+	net-drivers-2.5 -- on-going net driver maintenance
+	vm-2.5 -- VM-related changes
+	fs-2.5 -- filesystem-related changes
+
+Linus then has much more freedom for pulling changes.  He could (for
+example) issue a "bk pull" on vm-2.5 and fs-2.5 trees, to merge their
+changes, but hold off net-drivers-2.5 because of a change that needs
+more discussion.
+
+Other maintainers may find that a single linus-pull-from tree is
+adequate for passing BK changesets to him.
+
+
+
+Frequently Answered Questions
+-----------------------------
+1) How do I change the e-mail address shown in the changelog?
+A. When you run "bk citool" or "bk commit", set environment
+   variables BK_USER and BK_HOST to the desired username
+   and host/domain name.
+
+
+2) How do I use tags / get a diff between two kernel versions?
+A. Pass the tags Linus uses to 'bk export'.
+
+ChangeSets are in a forward-progressing order, so it's pretty easy
+to get a snapshot starting and ending at any two points in time.
+Linus puts tags on each release and pre-release, so you could use
+these two examples:
+
+    bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less
+        # creates patch-2.5.5 essentially
+    bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less
+        # changes from pre1 to final
+
+A tag is just an alias for a specific changeset... and since changesets
+are ordered, a tag is thus a marker for a specific point in time (or
+specific state of the tree).
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bk-make-sum linux-2.4.20/Documentation/BK-usage/bk-make-sum
--- linux-2.4.19/Documentation/BK-usage/bk-make-sum	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/bk-make-sum	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,37 @@
+#!/bin/sh -e
+# DIR=$HOME/BK/axp-2.5
+# cd $DIR
+
+LINUS_REPO=$1
+DIRBASE=`basename $PWD`
+
+{
+cat <<EOT
+Linus, please do a
+
+	bk pull http://gkernel.bkbits.net/$DIRBASE
+
+This will update the following files:
+
+EOT
+
+bk changes -L -d'$unless(:MERGE:){:CSETREV:\n}' $LINUS_REPO |
+while read rev; do
+  bk export -tpatch -r$rev
+done | diffstat -p1 2>/dev/null
+
+cat <<EOT
+
+through these ChangeSets:
+
+EOT
+
+bk changes -L -d'$unless(:MERGE:){ChangeSet|:CSETREV:\n}' $LINUS_REPO |
+bk -R prs -h -d'$unless(:MERGE:){<:P:@:HOST:> (:D: :I:)\n$each(:C:){   (:C:)\n}\n}' -
+
+} > /tmp/linus.txt
+
+cat <<EOT
+Mail text in /tmp/linus.txt; please check and send using your favourite
+mailer.
+EOT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bksend linux-2.4.20/Documentation/BK-usage/bksend
--- linux-2.4.19/Documentation/BK-usage/bksend	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/bksend	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+# A script to format BK changeset output in a manner that is easy to read.
+# Andreas Dilger <adilger@turbolabs.com>  13/02/2002
+#
+# Add diffstat output after Changelog <adilger@turbolabs.com>   21/02/2002
+
+PROG=bksend
+
+usage() {
+	echo "usage: $PROG -r<rev>"
+	echo -e "\twhere <rev> is of the form '1.23', '1.23..', '1.23..1.27',"
+	echo -e "\tor '+' to indicate the most recent revision"
+
+	exit 1
+}
+
+case $1 in
+-r) REV=$2; shift ;;
+-r*) REV=`echo $1 | sed 's/^-r//'` ;;
+*) echo "$PROG: no revision given, you probably don't want that";;
+esac
+
+[ -z "$REV" ] && usage
+
+echo "You can import this changeset into BK by piping this whole message to:"
+echo "'| bk receive [path to repository]' or apply the patch as usual."
+
+SEP="\n===================================================================\n\n"
+echo -e $SEP
+bk changes -r$REV
+echo
+bk export -tpatch -du -h -r$REV | diffstat
+echo; echo
+bk export -tpatch -du -h -r$REV
+echo -e $SEP
+bk send -wgzip_uu -r$REV -
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bz64wrap linux-2.4.20/Documentation/BK-usage/bz64wrap
--- linux-2.4.19/Documentation/BK-usage/bz64wrap	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/bz64wrap	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# bz64wrap - the sending side of a bzip2 | base64 stream
+# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
+
+
+PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
+
+# A program to generate base64 encoding on stdout
+BASE64_ENCODE="uuencode -m /dev/stdout"
+BASE64_BEGIN=
+BASE64_END=
+
+BZIP=NO
+BASE64=NO
+
+# Test if we have the bzip program installed
+bzip2 -c /dev/null > /dev/null 2>&1 && BZIP=YES
+
+# Test if uuencode can handle the -m (MIME) encoding option
+$BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
+
+if [ $BASE64 = NO ]; then
+	BASE64_ENCODE=mimencode
+	BASE64_BEGIN="begin-base64 644 -"
+	BASE64_END="===="
+
+	$BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
+fi
+
+if [ $BZIP = NO -o $BASE64 = NO ]; then
+	echo "$0: can't use bz64 encoding: bzip2=$BZIP, $BASE64_ENCODE=$BASE64"
+	exit 1
+fi
+
+# Sadly, mimencode does not appear to have good "begin" and "end" markers
+# like uuencode does, and it is picky about getting the right start/end of
+# the base64 stream, so we handle this internally.
+echo "$BASE64_BEGIN"
+bzip2 -9 | $BASE64_ENCODE
+echo "$BASE64_END"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/cset-to-linus linux-2.4.20/Documentation/BK-usage/cset-to-linus
--- linux-2.4.19/Documentation/BK-usage/cset-to-linus	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/cset-to-linus	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my ($lhs, $rev, $tmp, $rhs, $s);
+my @cset_text = ();
+my @pipe_text = ();
+my $have_cset = 0;
+
+while (<>) {
+	next if /^---/;
+
+	if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
+		&cset_rev if ($have_cset);
+
+		$rev = $tmp;
+		$have_cset = 1;
+
+		push(@cset_text, $_);
+	}
+
+	elsif ($have_cset) {
+		push(@cset_text, $_);
+	}
+}
+&cset_rev if ($have_cset);
+exit(0);
+
+
+sub cset_rev {
+	my $empty_cset = 0;
+
+	open PIPE, "bk export -tpatch -hdu -r $rev | diffstat -p1 2>/dev/null |" or die;
+	while ($s = <PIPE>) {
+		$empty_cset = 1 if ($s =~ /0 files changed/);
+		push(@pipe_text, $s);
+	}
+	close(PIPE);
+
+	if (! $empty_cset) {
+		print @cset_text;
+		print @pipe_text;
+		print "\n\n";
+	}
+
+	@pipe_text = ();
+	@cset_text = ();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/csets-to-patches linux-2.4.20/Documentation/BK-usage/csets-to-patches
--- linux-2.4.19/Documentation/BK-usage/csets-to-patches	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/csets-to-patches	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my ($lhs, $rev, $tmp, $rhs, $s);
+my @cset_text = ();
+my @pipe_text = ();
+my $have_cset = 0;
+
+while (<>) {
+	next if /^---/;
+
+	if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
+		&cset_rev if ($have_cset);
+
+		$rev = $tmp;
+		$have_cset = 1;
+
+		push(@cset_text, $_);
+	}
+
+	elsif ($have_cset) {
+		push(@cset_text, $_);
+	}
+}
+&cset_rev if ($have_cset);
+exit(0);
+
+
+sub cset_rev {
+	my $empty_cset = 0;
+
+	system("bk export -tpatch -du -r $rev > /tmp/rev-$rev.patch");
+
+	if (! $empty_cset) {
+		print @cset_text;
+		print @pipe_text;
+		print "\n\n";
+	}
+
+	@pipe_text = ();
+	@cset_text = ();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/unbz64wrap linux-2.4.20/Documentation/BK-usage/unbz64wrap
--- linux-2.4.19/Documentation/BK-usage/unbz64wrap	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/BK-usage/unbz64wrap	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# unbz64wrap - the receiving side of a bzip2 | base64 stream
+# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
+
+# Sadly, mimencode does not appear to have good "begin" and "end" markers
+# like uuencode does, and it is picky about getting the right start/end of
+# the base64 stream, so we handle this explicitly here.
+
+PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
+
+if mimencode -u < /dev/null > /dev/null 2>&1 ; then
+	SHOW=
+	while read LINE; do
+		case $LINE in
+		begin-base64*) SHOW=YES ;;
+		====) SHOW= ;;
+		*) [ "$SHOW" ] && echo "$LINE" ;;
+		esac
+	done | mimencode -u | bunzip2
+	exit $?
+else
+	cat - | uudecode -o /dev/stdout | bunzip2
+	exit $?
+fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Changes linux-2.4.20/Documentation/Changes
--- linux-2.4.19/Documentation/Changes	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/Changes	2002-10-04 00:41:29.000000000 +0000
@@ -55,7 +55,7 @@
 o  modutils               2.4.2                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
 o  jfsutils               1.0.12                  # fsck.jfs -V
-o  reiserfsprogs          3.x.1b                  # reiserfsck 2>&1|grep reiserfsprogs
+o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
@@ -225,7 +225,6 @@
 version v0.99.0 or higher. Running old versions may cause problems
 with programs using shared memory.
 
-
 Networking
 ==========
 
@@ -326,7 +325,7 @@
 
 Reiserfsprogs
 -------------
-o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
+o  <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz>
 
 LVM toolset
 -----------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Configure.help linux-2.4.20/Documentation/Configure.help
--- linux-2.4.19/Documentation/Configure.help	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/Configure.help	2002-10-04 00:41:30.000000000 +0000
@@ -2,10 +2,7 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Version 3.00: current with 2.4.19
-#
-# This version of the Linux kernel configuration help texts
-# corresponds to kernel versions 2.4.x and 2.5.x.
+# Version 3.01: current with 2.4.19+
 #
 # Translations of this file available on the WWW:
 #
@@ -233,6 +230,22 @@
   network and embedded applications.  For more information see the
   Axis Communication site, <http://developer.axis.com/>.
 
+Unsynced TSC support
+CONFIG_X86_TSC_DISABLE
+  This option is used for getting Linux to run on a NUMA multi-node 
+  boxes, laptops and other systems suffering from unsynced TSCs or 
+  TSC drift, which can cause gettimeofday to return non-monotonic values. 
+  Choosing this option will disable the CONFIG_X86_TSC optimization,
+  and allows you to then specify "notsc" as a boot option regardless of 
+  which processor you have compiled for. 
+  
+  NOTE: If your system hangs when init should run, you are probably
+  using a i686 compiled glibc which reads the TSC without checking for 
+  availability. Boot without "notsc" and install a i386 compiled glibc 
+  to solve the problem.
+
+  If unsure, say N.
+
 Multiquad support for NUMA systems
 CONFIG_MULTIQUAD
   This option is used for getting Linux to run on a (IBM/Sequent) NUMA 
@@ -376,6 +389,12 @@
   Select this if you have a 32-bit processor and more than 4
   gigabytes of physical RAM.
 
+HIGHMEM I/O support
+CONFIG_HIGHIO
+  If you want to be able to do I/O to high memory pages, say Y.
+  Otherwise low memory pages are used as bounce buffers causing a
+  degrade in performance.
+
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
   If you want to use the floppy disk drive(s) of your PC under Linux,
@@ -534,6 +553,17 @@
 
   If unsure, say N.
 
+Per partition statistics in /proc/partitions
+CONFIG_BLK_STATS
+  If you say yes here, your kernel will keep statistical information
+  for every partition. The information includes things as numbers of
+  read and write accesses, the number of merged requests etc.
+
+  This is required for the full functionality of sar(8) and interesting
+  if you want to do performance tuning, by tweaking the elevator, e.g.
+
+  If unsure, say N.
+
 ATA/IDE/MFM/RLL support
 CONFIG_IDE
   If you say Y here, your kernel will be able to manage low cost mass
@@ -1004,6 +1034,11 @@
   Please read the comments at the top of
   <file:drivers/scsi/3w-xxxx.c>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called 3w-xxxx.o.
+
 AEC62XX chipset support
 CONFIG_BLK_DEV_AEC62XX
   This driver adds up to 4 more EIDE devices sharing a single
@@ -1067,10 +1102,10 @@
   This effect can be also invoked by calling "idex=ata66"
   If unsure, say N.
 
-CMD64X chipset support
+CMD64X and CMD680 chipset support
 CONFIG_BLK_DEV_CMD64X
   Say Y here if you have an IDE controller which uses any of these
-  chipsets: CMD643, CMD646, or CMD648.
+  chipsets: CMD643, CMD646, CMD648, CMD649 or CMD680.
 
 CY82C693 chipset support
 CONFIG_BLK_DEV_CY82C693
@@ -2493,6 +2528,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+skb->pkt_type packet match support
+CONFIG_IP_NF_MATCH_PKTTYPE
+  This patch allows you to match packet in accrodance
+  to its "class", eg. BROADCAST, MULTICAST, ...
+  
+  Typical usage:
+  iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
+  
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP_NF_MATCH_MAC
   MAC matching allows you to match packets based on the source
@@ -2543,6 +2589,28 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
 
+DSCP match support
+CONFIG_IP_NF_MATCH_DSCP
+  This option adds a `DSCP' match, which allows you to match against
+  the IPv4 header DSCP field (DSCP codepoint).
+
+  The DSCP codepoint can have any value between 0x0 and 0x4f.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN match support
+CONFIG_IP_NF_MATCH_ECN
+  This option adds a `ECN' match, which allows you to match against
+  the IPv4 and TCP header ECN fields.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS match support
 CONFIG_IP_NF_MATCH_TOS
   TOS matching allows you to match packets based on the Type Of
@@ -2551,6 +2619,18 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+conntrack match support
+CONFIG_IP_NF_MATCH_CONNTRACK
+  This is a general conntrack match module, a superset of the state match.
+
+  It allows matching on additional conntrack information, which is
+  useful in complex configurations, such as NAT gateways with multiple
+  internet links or tunnels.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
 Connection state match support
 CONFIG_IP_NF_MATCH_STATE
   Connection state matching allows you to match packets based on their
@@ -2668,6 +2748,36 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+DSCP target support
+CONFIG_IP_NF_TARGET_DSCP
+  This option adds a `DSCP' target, which allows you to create rules in
+  the iptables mangle table. The selected packet has the DSCP field set
+  to the hex value provided on the command line; unlike the TOS target
+  which will only set the legal values within ip.h.
+
+  The DSCP field can be set to any value between 0x0 and 0x4f. It does
+  take into account that bits 6 and 7 are used by ECN.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN target support
+CONFIG_IP_NF_TARGET_ECN
+  This option adds a `ECN' target, which can be used in the iptables mangle
+  table.  
+
+  You can use this target to remove the ECN bits from the IPv4 header of
+  an IP packet.  This is particularly useful, if you need to work around
+  existing ECN blackholes on the internet, but don't want to disable
+  ECN support in general.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS target support
 CONFIG_IP_NF_TARGET_TOS
   This option adds a `TOS' target, which allows you to create rules in
@@ -2714,6 +2824,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Helper match support
+CONFIG_IP_NF_MATCH_HELPER
+  Helper matching allows you to match packets in dynamic connections
+  tracked by a conntrack-helper, ie. ip_conntrack_ftp
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `Y'.
+
 TCPMSS match support
 CONFIG_IP_NF_MATCH_TCPMSS
   This option adds a `tcpmss' match, which allows you to examine the
@@ -2766,6 +2884,15 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+EUI64 address check (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_EUI64
+  This module performs checking on the IPv6 source address
+  Compares the last 64 bits with the EUI64 (delivered
+  from the MAC address) address
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP6_NF_MATCH_MAC
   mac matching allows you to match packets based on the source
@@ -2774,6 +2901,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+length match support
+CONFIG_IP6_NF_MATCH_LENGTH
+  This option allows you to match the length of a packet against a
+  specific value or range of values.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 Netfilter MARK match support
 CONFIG_IP6_NF_MATCH_MARK
   Netfilter mark matching allows you to match packets based on the
@@ -3278,6 +3413,16 @@
   a module, say M here and read <file:Documentation/modules.txt>.
   If unsure, say N.
 
+CONFIG_SYNCLINK_CS
+  Enable support for the SyncLink PC Card serial adapter, running
+  asynchronous and HDLC communications up to 512Kbps. The port is
+  selectable for RS-232, V.35, RS-449, RS-530, and X.21
+
+  This driver may be built as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called synclink_cs.o.  If you want to do that, say M
+  here.
+
 ACP Modem (Mwave) support
 CONFIG_MWAVE
   The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
@@ -3511,6 +3656,16 @@
 
   When in doubt, say N.
 
+ACPI PCI Hotplug driver
+CONFIG_HOTPLUG_PCI_ACPI
+  Say Y here if you have a system that supports PCI Hotplug using
+  ACPI.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called acpiphp.o. If you want to compile it
+  as a module, say M here and read <file:Documentation/modules.txt>.
+
 MCA support
 CONFIG_MCA
   MicroChannel Architecture is found in some IBM PS/2 machines and
@@ -5810,6 +5965,11 @@
   useful if some other computer on your local network has a direct
   amateur radio connection.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called bpqether.o.
+
 High-speed (DMA) SCC driver for AX.25
 CONFIG_DMASCC
   This is a driver for high-speed SCC boards, i.e. those supporting
@@ -5874,9 +6034,10 @@
   port and includes some of the functions of a Terminal Node
   Controller. If you have one of those, say Y here.
 
-  If you want to compile this as a module ( = code which can be
+  If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
-  say M here and read <file:Documentation/modules.txt>.
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called yam.o.
 
 BAYCOM picpar and par96 driver for AX.25
 CONFIG_BAYCOM_PAR
@@ -7048,6 +7209,11 @@
   intended to replace the previous aic7xxx driver maintained by Doug
   Ledford since Doug is no longer maintaining that driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called aic7xxx.o.
+
 Adaptec I2O RAID support
 CONFIG_SCSI_DPT_I2O
   This driver supports all of Adaptec's I2O based RAID controllers as 
@@ -7244,6 +7410,11 @@
   Say Y here to compile in support for the Compaq StorageWorks Fibre
   Channel 64-bit/66Mhz Host Bus Adapter.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called cpqfc.o.
+
 DMX3191D SCSI support
 CONFIG_SCSI_DMX3191D
   This is support for Domex DMX3191D SCSI Host Adapters.
@@ -7401,6 +7572,11 @@
   Unless you have an NCR manufactured machine, the chances are that
   you do not have this SCSI card, so say N.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called NCR_D700.o.
+
 HP LASI SCSI support for 53c700/710
 CONFIG_SCSI_LASI700
   This is a driver for the lasi baseboard in some parisc machines
@@ -7469,6 +7645,11 @@
   Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sym53c8xx.o.
+
 PCI DMA addressing mode
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
   This option only applies to PCI-SCSI chip that are PCI DAC capable 
@@ -7531,6 +7712,11 @@
   Please read <file:drivers/scsi/README.ncr53c8xx> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ncr53c8xx.o.
+
 SYM53C8XX Version 1 SCSI support
 CONFIG_SCSI_SYM53C8XX
   This driver supports all the features of recent 53C8XX chips (used
@@ -7556,6 +7742,11 @@
   Please read <file:drivers/scsi/README.ncr53c8xx> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sym53c8xx.o.
+
 Synchronous transfer frequency in MHz
 CONFIG_SCSI_NCR53C8XX_SYNC
   The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
@@ -8128,10 +8319,10 @@
   in the kernel source in <file:drivers/scsi/gdth.c> and
   <file:drivers/scsi/gdth.h.>
 
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  If you want to compile it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called gdth.o.
 
 IOMEGA parallel port (ppa - older drives)
 CONFIG_SCSI_PPA
@@ -8221,6 +8412,11 @@
   important data. This is primarily of use to people trying to debug
   the middle and upper layers of the SCSI subsystem. If unsure, say N.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called scsi_debug.o.
+
 Fibre Channel and FC4 SCSI support
 CONFIG_FC4
   Fibre Channel is a high speed serial protocol mainly used to
@@ -8648,9 +8844,10 @@
   a modem (not a synchronous or ISDN modem) to contact your ISP, you
   need this option.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_async.o.
 
   If unsure, say Y.
 
@@ -8660,10 +8857,10 @@
   (HDLC) tty devices, such as the SyncLink adapter. These devices
   are often used for high-speed leased lines like T1/E1.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_synctty.o.
 
 PPP Deflate compression
 CONFIG_PPP_DEFLATE
@@ -8674,10 +8871,10 @@
   Deflate compression method as well for this to be useful.  Even if
   they don't support it, it is safe to say Y here.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_deflate.o.
 
 PPP BSD-Compress compression
 CONFIG_PPP_BSDCOMP
@@ -9096,6 +9293,11 @@
   configure your card and that /etc/pcmcia/wireless.opts works :
   <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hermes.o.
+
 Hermes 802.11b in PLX9052 based PCI adaptor support
 CONFIG_PLX_HERMES
   Enable support for PCMCIA cards supported by the "Hermes" (aka
@@ -9134,6 +9336,11 @@
   configure your card and that /etc/pcmcia/wireless.opts works:
   <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called orinoco_cs.o.
+
 Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards
 CONFIG_AIRO
   This is the standard Linux driver to support Cisco/Aironet ISA and
@@ -9168,6 +9375,11 @@
   for location).  You also want to check out the PCMCIA-HOWTO,
   available from <http://www.tldp.org/docs.html#howto>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called airo_cs.o.
+
 Aviator/Raytheon 2.4MHz wireless support
 CONFIG_PCMCIA_RAYCS
   Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
@@ -9353,6 +9565,11 @@
   of the Cisco HDLC/PPP driver (syncppp.c).
   The SyncLink WAN driver (in character devices) must also be enabled.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called syncppp.o.
+
 FarSync T-Series X.21 (and V.35/V.24) cards
 CONFIG_FARSYNC
   This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
@@ -9558,6 +9775,20 @@
   whenever you want).  If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
+CONFIG_NET_SCH_HTB
+  Say Y here if you want to use the Hierarchical Token Buckets (HTB)
+  packet scheduling algorithm for some of your network devices. See
+  URL http://luxik.cdi.cz/~devik/qos/htb/ for complete manual and
+  in-depth articles.
+
+  HTB is very similar to the CBQ regarding its goals however is has 
+  different properties and different algorithm.
+
+  This code is also available as a module called sch_htb.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want).  If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
+
 CSZ packet scheduler
 CONFIG_NET_SCH_CSZ
   Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet
@@ -9839,6 +10070,11 @@
 
   At this point, the driver can only be compiled as a module.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hostess_sv11.o.
+
 COSA/SRP sync serial board support
 CONFIG_COSA
   This is a driver for COSA and SRP synchronous serial boards. These
@@ -10207,6 +10443,11 @@
   Generic HDLC driver currently supports raw HDLC, Cisco HDLC, Frame
   Relay, synchronous Point-to-Point Protocol (PPP) and X.25.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hdlc.o.
+
   If unsure, say N here.
 
 Raw HDLC support
@@ -10259,6 +10500,11 @@
 
   Note that N2csu and N2dds cards are not supported by this driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called n2.o.
+
   If unsure, say N here.
 
 Moxa C101 support
@@ -10267,6 +10513,11 @@
   Technologies Co., Ltd. If you have such a card,
   say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called c101.o.
+
   If unsure, say N here.
 
 Ethernet (10 or 100Mbit)
@@ -10474,12 +10725,14 @@
   in case your mainboard has memory consistency issues.  If unsure,
   say N.
 
-Support for automatic channel equalization
+Support for uncommon RTL-8139 rev. K (automatic channel equalization)
 CONFIG_8139TOO_TUNE_TWISTER
-  This implements a function which might come in handy in case you are
-  using low quality on long cabling. It tries to match the transceiver
-  to the cable characteristics. This is experimental since hardly
-  documented by the manufacturer.  If unsure, say N.
+  This implements a function which might come in handy in case you
+  are using low quality on long cabling. It is required for RealTek
+  RTL-8139 revision K boards, and totally unused otherwise.  It tries
+  to match the transceiver to the cable characteristics. This is
+  experimental since hardly documented by the manufacturer.
+  If unsure, say Y.
 
 Support for older RTL-8129/8130 boards
 CONFIG_8139TOO_8129
@@ -10488,6 +10741,14 @@
   instead of an internal one.  Disabling this option will save some
   memory by making the code size smaller.  If unsure, say Y.
 
+Use older RX-reset method
+CONFIG_8139_OLD_RX_RESET
+  The 8139too driver was recently updated to contain a more rapid
+  reset sequence, in the face of severe receive errors.  This "new"
+  RX-reset method should be adequate for all boards.  But if you
+  experience problems, you can enable this option to restore the
+  old RX-reset behavior.  If unsure, say N.
+
 SiS 900/7016 PCI Fast Ethernet Adapter support
 CONFIG_SIS900
   This is a driver for the Fast Ethernet PCI network cards based on
@@ -10609,6 +10870,11 @@
   Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
   <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sungem.o.
+
 Broadcom Tigon3 support
 CONFIG_TIGON3
   This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
@@ -10639,6 +10905,123 @@
   say M here and read <file:Documentation/modules.txt>.  This is
   recommended.  The module will be called dl2k.o.
 
+EtherExpress Pro/100 support (e100, Alternate Intel driver)
+CONFIG_E100
+  This driver supports Intel(R) PRO/100 family of adapters, which
+  includes:
+
+     Controller  Adapter Name                       Board IDs
+     ----------  ------------                       ---------
+
+     82558       PRO/100+ PCI Adapter               668081-xxx,
+                                                    689661-xxx
+     82558       PRO/100+ Management Adapter        691334-xxx,
+                                                    701738-xxx,
+                                                    721383-xxx
+     82558       PRO/100+ Dual Port Server Adapter  714303-xxx,
+                                                    711269-xxx,
+                                                    A28276-xxx
+     82558       PRO/100+ PCI Server Adapter        710550-xxx
+     82550       PRO/100 S Server Adapter           752438-xxx
+     82559                                          A56831-xxx,
+                                                    A10563-xxx,
+                                                    A12171-xxx,
+                                                    A12321-xxx,
+                                                    A12320-xxx,
+                                                    A12170-xxx
+                                                    748568-xxx
+                                                    748565-xxx
+     82550       PRO/100 S Desktop Adapter          751767-xxx
+     82559                                          748592-xxx,
+                                                    A12167-xxx,
+                                                    A12318-xxx,
+                                                    A12317-xxx,
+                                                    A12165-xxx,
+                                                    748569-xxx
+     82559       PRO/100+ Server Adapter            729757-xxx
+     82559       PRO/100 S Management Adapter       748566-xxx,
+                                                    748564-xxx
+     82550       PRO/100 S Dual Port Server Adapter A56831-xxx
+     82551       PRO/100 M Desktop Adapter          A80897-xxx
+                 PRO/100 S Advanced Management Adapter
+                                                    747842-xxx,
+                                                    745171-xxx
+     CNR         PRO/100 VE Desktop Adapter         A10386-xxx,
+                                                    A10725-xxx,
+                                                    A23801-xxx,
+                                                    A19716-xxx
+                 PRO/100 VM Desktop Adapter         A14323-xxx,
+                                                    A19725-xxx,
+                                                    A23801-xxx,
+                                                    A22220-xxx,
+                                                    A23796-xxx
+
+
+  To verify that your adapter is supported, find the board ID number
+  on the adapter. Look for a label that has a barcode and a number
+  in the format 123456-001 (six digits hyphen three digits). Match
+  this to the list of numbers above.
+
+  For more information on how to identify your adapter, go to the
+  Adapter & Driver ID Guide at:
+
+    http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+  For the latest Intel PRO/100 network driver for Linux, see:
+
+    http://appsr.intel.com/scripts-df/support_intel.asp
+
+  More specific information on configuring the driver is in
+  <file:Documentation/networking/e100.txt>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called e100.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt> as well
+  as <file:Documentation/networking/net-modules.txt>.
+
+Intel(R) PRO/1000 Gigabit Ethernet support
+CONFIG_E1000
+  This driver supports Intel(R) PRO/1000 gigabit ethernet family of
+  adapters, which includes:
+
+     Controller  Adapter Name                         Board IDs
+     ----------  ------------                         ---------
+     82542       PRO/1000 Gigabit Server Adapter      700262-xxx,
+                                                      717037-xxx
+     82543       PRO/1000 F Server Adapter            738640-xxx,
+                                                      A38888-xxx
+     82543       PRO/1000 T Server Adapter            A19845-xxx,
+                                                      A33948-xxx
+     82544       PRO/1000 XT Server Adapter           A51580-xxx
+     82544       PRO/1000 XF Server Adapter           A50484-xxx
+     82544       PRO/1000 T Desktop Adapter           A62947-xxx
+     82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+     82545       PRO/1000 MT Server Adapter           A92165-xxx
+     82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
+     82545       PRO/1000 MF Server Adapter           A91622-xxx
+     82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
+     82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx 
+
+  For more information on how to identify your adapter, go to the
+  Adapter & Driver ID Guide at:
+
+   <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+  For general information and support, go to the Intel support
+  website at:
+
+   <http://support.intel.com>
+
+  More specific information on configuring the driver is in 
+  <file:Documentation/networking/e1000.txt>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called e1000.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt> as well
+  as <file:Documentation/networking/net-modules.txt>.
+
 AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
@@ -10798,10 +11181,10 @@
   <file:Documentation/networking/vortex.txt> and in the comments at
   the beginning of <file:drivers/net/3c59x.c>.
 
-  If you want to compile this as a module ( = code which can be
+  If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
-  say M here and read <file:Documentation/modules.txt> as well as
-  <file:Documentation/networking/net-modules.txt>.
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called 3c59x.o.
 
 Other ISA cards
 CONFIG_NET_ISA
@@ -10852,6 +11235,11 @@
   documentation in <file:Documentation/networking/arcnet.txt> for more
   information about using arc0e and arc0s.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called rfc1051.o.
+
 Enable standard ARCNet packet format (RFC 1201)
 CONFIG_ARCNET_1201
   This allows you to use RFC1201 with your ARCnet card via the virtual
@@ -10861,12 +11249,22 @@
   ARCnet documentation in <file:Documentation/networking/arcnet.txt>
   for more information about using arc0.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called rfc1201.o.
+
 Enable raw mode packet interface
 CONFIG_ARCNET_RAW
   ARCnet "raw mode" packet encapsulation, no soft headers.  Unlikely
   to work unless talking to a copy of the same Linux arcnet driver,
   but perhaps marginally faster in that case.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called arc-rawmode.o.
+
 ARCnet COM90xx (normal) chipset driver
 CONFIG_ARCNET_COM90xx
   This is the chipset driver for the standard COM90xx cards. If you
@@ -11115,6 +11513,11 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/natsemi.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called natsemi.o.
+
 NatSemi workaround for high errors
 CONFIG_NATSEMI_CABLE_MAGIC
   Some systems see lots of errors with NatSemi ethernet controllers
@@ -11171,6 +11574,11 @@
   boards with this driver should be possible, but has not been tested
   up to now due to lack of hardware.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ibmlana.o.
+
 EISA, VLB, PCI and on board controllers
 CONFIG_NET_PCI
   This is another class of network cards which attach directly to the
@@ -11340,12 +11748,22 @@
   cards. Specifications and data at
   <http://www.myson.com.hk/mtd/datasheet/>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called fealnx.o.
+
 LP486E on board Ethernet
 CONFIG_LP486E
   Say Y here to support the 82596-based on-board Ethernet controller
   for the Panther motherboard, which is one of the two shipped in the
   Intel Professional Workstation.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called lp486e.o.
+
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
@@ -11431,6 +11849,11 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/epic100.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called epic100.o.
+
 DEC LANCE Ethernet controller support
 CONFIG_DECLANCE
   This driver is for the series of Ethernet controllers produced by
@@ -11448,6 +11871,19 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/sundance.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sundance.o.
+
+Sundance Alta memory-mapped I/O support
+CONFIG_SUNDANCE_MMIO
+  Enable memory-mapped I/O for interaction with Sundance NIC registers.
+  Do NOT enable this by default, PIO (enabled when MMIO is disabled)
+  is known to solve bugs on certain chips.
+
+  If unsure, say N.
+
 Sun3/Sun3x on-board LANCE support
 CONFIG_SUN3LANCE
   Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
@@ -11795,6 +12231,11 @@
   This is support for the DIGITAL series of EISA (DEFEA) and PCI
   (DEFPA) controllers which can connect you to a local FDDI network.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called defxx.o.
+
 SysKonnect FDDI PCI support
 CONFIG_SKFP
   Say Y here if you have a SysKonnect FDDI PCI adapter.
@@ -13108,9 +13549,9 @@
   The module will be called wacom.o.  If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Aiptek 8000U tablet support
+Aiptek 6000U/8000U tablet support
 CONFIG_USB_AIPTEK
-  Say Y here if you want to use the USB version of the Aiptek 8000U
+  Say Y here if you want to use the USB version of the Aiptek 6000U/8000U
   tablet.  Make sure to say Y to "Event interface support"
   (CONFIG_INPUT_EVDEV) as well.
 
@@ -13242,7 +13683,6 @@
   inserted in and removed from the running kernel whenever you want).
   The module will be called audio.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
-			
 
 USB Modem (CDC ACM) support
 CONFIG_USB_ACM
@@ -13418,6 +13858,14 @@
 CONFIG_USB_SERIAL_KEYSPAN_USA19W
   Say Y here to include firmware for the USA-19W converter.
 
+USB Keyspan USA-19QW Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW
+  Say Y here to include firmware for the USA-19QW converter.
+
+USB Keyspan USA-19QI Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI
+  Say Y here to include firmware for the USA-19QI converter.
+
 USB Keyspan USA-49W Firmware
 CONFIG_USB_SERIAL_KEYSPAN_USA49W
   Say Y here to include firmware for the USA-49W converter.
@@ -13761,6 +14209,7 @@
 CONFIG_USB_CATC
   Say Y if you want to use one of the following 10Mbps USB Ethernet
   device based on the EL1210A chip. Supported devices are:
+    Belkin F5U011
     Belkin F5U111
     CATC NetMate
     CATC NetMate II
@@ -13940,6 +14389,11 @@
   Say Y here to include additional code to support the Sandisk SDDR-09
   SmartMedia reader in the USB Mass Storage driver.
 
+SanDisk SDDR-55 SmartMedia support
+CONFIG_USB_STORAGE_SDDR55
+  Say Y here to include additional code to support the Sandisk SDDR-55
+  SmartMedia reader in the USB Mass Storage driver.
+
 USB Diamond Rio500 support
 CONFIG_USB_RIO500
   Say Y here if you want to connect a USB Rio500 mp3 player to your
@@ -13949,7 +14403,7 @@
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called rio500.o. If you want to compile it as
-  a module, say M here and read <file:Documentation/modules.txt>.
+  a module, say M here and read <file:Documenatation/modules.txt>.
 
 USB Auerswald ISDN device support
 CONFIG_USB_AUERSWALD
@@ -13959,7 +14413,26 @@
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called auerswald.o. If you want to compile it as
-  a module, say M here and read <file:Documentation/modules.txt>.
+  a module, say M here and read <file:Documenatation/modules.txt>
+
+CONFIG_USB_TIGL
+  If you own a Texas Instruments graphing calculator and use a 
+  TI-GRAPH LINK USB cable (aka SilverLink), then you might be 
+  interested in this driver.
+
+  If you enable this driver, you will be able to communicate with
+  your calculator through a set of device nodes under /dev.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called tiglusb.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+  If you don't know what the SilverLink cable is or what a Texas
+  Instruments graphing calculator is, then you probably don't need this
+  driver.
+
+  If unsure, say N.
 
 Tieman Voyager USB Braille display support
 CONFIG_USB_BRLVOYAGER
@@ -13972,10 +14445,22 @@
   The module will be called brlvger.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
-D-Link DSB-R100 FM radio support
-CONFIG_USB_DSBR
-  Say Y here if you want to connect this type of radio to your
-  computer's USB port. Note that the audio is not digital, and
+USBLCD support
+CONFIG_USB_LCD
+  Say Y here if you want to connect an USBLCD to your computer's
+  USB port. The USBLCD is a small USB interface board for
+  alphanumeric LCD modules. See <http://www.usblcd.de> for more
+  information.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usblcd.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
+D-Link DSB-R100 FM radio support
+CONFIG_USB_DSBR
+  Say Y here if you want to connect this type of radio to your
+  computer's USB port. Note that the audio is not digital, and
   you must connect the line out connector to a sound card or a
   set of speakers.
 
@@ -14314,12 +14799,13 @@
 
 Publish some reiserfs-specific info under /proc/fs/reiserfs
 CONFIG_REISERFS_PROC_INFO
-  Create under /proc/fs/reiserfs hierarchy of files, displaying
-  various ReiserFS statistics and internal data on the expense of
-  making your kernel or module slightly larger (+8 KB).  This also
-  increases amount of kernel memory required for each mount.  Almost
-  everyone but ReiserFS developers and people fine-tuning reiserfs or
-  tracing problems should say N.
+  Create under /proc/fs/reiserfs a hierarchy of files, displaying
+  various ReiserFS statistics and internal data at the expense of making
+  your kernel or module slightly larger (+8 KB). This also increases the
+  amount of kernel memory required for each mount by 440 bytes.
+  It isn't useful to average persons, and you probably can't measure the
+  performance cost of it.  If you are fine-tuning reiserfs, say Y,
+  otherwise say N.
 
 Second extended fs support
 CONFIG_EXT2_FS
@@ -14884,13 +15370,10 @@
   If you would like to include the NFSv3 server as well as the NFSv2
   server, say Y here.  If unsure, say Y.
 
-Provide NFS over TCP server support DEVELOPER ONLY
+Provide NFS over TCP server support EXPERIMENTAL
 CONFIG_NFSD_TCP
-  If you are a developer and want to work on fixing problems with
-  NFS server over TCP support, say Y here.  If unsure, say N.
-
-  Some problems can be found by looking for FIXME in
-  <file:net/sunrpc/svcsock.c>.
+  Enable NFS service over TCP connections.  This the officially
+  still experimental, but seems to work well.
 
 OS/2 HPFS file system support
 CONFIG_HPFS_FS
@@ -15331,12 +15814,6 @@
   were partitioned using EFI GPT.  Presently only useful on the
   IA-64 platform.
 
-/dev/guid support (EXPERIMENTAL)
-CONFIG_DEVFS_GUID
-  Say Y here if you would like to access disks and partitions by
-  their Globally Unique Identifiers (GUIDs) which will appear as
-  symbolic links in /dev/guid.
-
 Ultrix partition table support
 CONFIG_ULTRIX_PARTITION
   Say Y here if you would like to be able to read the hard disk
@@ -15345,9 +15822,11 @@
 
 IBM disk label and partition support
 CONFIG_IBM_PARTITION
-  Say Y here if you would like to be able to read the hard disk
-  partition table format used by IBM DASD disks operating under CMS.
-  Otherwise, say N.
+  You have to say Y here if you would like to be able to read volume 
+  labels of IBM DASD disks. These can be ECKD DASD disks with 
+  compatible disk layout (cdl) and standard Linux disk layout (ldl), 
+  FBA DASD disks and CMS reserved minidisks.
+  Otherwise, say N and you will not be able to access these disks.
 
 ADFS file system support
 CONFIG_ADFS_FS
@@ -15375,6 +15854,25 @@
   hard drives and ADFS-formatted floppy disks. This is experimental
   codes, so if you're unsure, say N.
 
+JFS filesystem support
+CONFIG_JFS_FS
+  This is a port of IBM's Journalling Filesystem .  More information is
+  available in the file Documentation/filesystems/jfs.txt.
+
+  If you do not intend to use the JFS filesystem, say N.
+
+JFS Debugging
+CONFIG_JFS_DEBUG
+  If you are experiencing any problems with the JFS filesystem, say
+  Y here.  This will result in additional debugging messages to be
+  written to the system log.  Under normal circumstances, this
+  results in very little overhead.
+
+JFS Statistics
+CONFIG_JFS_STATISTICS
+  Enabling this option will cause statistics from the JFS file system
+  to be made available to the user in the /proc/fs/jfs/ directory.
+
 /dev/pts file system for Unix98 PTYs
 CONFIG_DEVPTS_FS
   You should say Y here if you said Y to "Unix98 PTY support" above.
@@ -16487,6 +16985,17 @@
   The module will be called synclink.o.  If you want to do that, say M
   here.
 
+CONFIG_SYNCLINKMP
+  Enable support for the SyncLink Multiport (2 or 4 ports)
+  serial adapter, running asynchronous and HDLC communications up
+  to 2.048Mbps. Each ports is independently selectable for
+  RS-232, V.35, RS-449, RS-530, and X.21
+
+  This driver may be built as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called synclinkmp.o.  If you want to do that, say M
+  here.
+
 Synchronous HDLC line discipline support
 CONFIG_N_HDLC
   Allows synchronous HDLC communications with tty device drivers that
@@ -17929,20 +18438,6 @@
   computer, say `Y' here to support its built-in watchdog timer
   feature.  See the help for CONFIG_WATCHDOG for discussion.
 
-W83877F Watchdog Timer
-CONFIG_W83877F_WDT
-  This is the driver for the hardware watchdog on the W83877F chipset
-  as used in EMACS PC-104 motherboards (and likely others).  This
-  watchdog simply watches your kernel to make sure it doesn't freeze,
-  and if it does, it reboots your computer after a certain amount of
-  time.
-
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module is called mixcomwd.o.  If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.  Most
-  people will say N.
-
 ALi M7101 Watchdog Timer
 CONFIG_ALIM7101_WDT
   This is the driver for the hardware watchdog on the ALi M7101 PMU
@@ -18187,9 +18682,10 @@
 CONFIG_NVRAM
   If you say Y here and create a character special file /dev/nvram
   with major number 10 and minor number 144 using mknod ("man mknod"),
-  you get read and write access to the 50 bytes of non-volatile memory
-  in the real time clock (RTC), which is contained in every PC and
-  most Ataris.
+  you get read and write access to the extra bytes of non-volatile
+  memory in the real time clock (RTC), which is contained in every PC
+  and most Ataris.  The actual number of bytes varies, depending on the
+  nvram in the system, but is usually 114 (128-14 for the RTC).
 
   This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
   on Ataris. /dev/nvram may be used to view settings there, or to
@@ -19406,6 +19902,12 @@
   Say Y or M if you have a sound system driven by ESS's Maestro 3
   PCI sound chip.
 
+ForteMedia FM801 driver
+CONFIG_SOUND_FORTE
+  Say Y or M if you want driver support for the ForteMedia FM801 PCI
+  audio controller (Abit AU10, Genius Sound Maker, HP Workstation
+  zx2000, and others).
+
 Adlib Cards
 CONFIG_SOUND_ADLIB
   Includes ASB 64 4D. Information on programming AdLib cards is
@@ -19581,16 +20083,6 @@
   hardware debugging with a logic analyzer and need to see all traffic
   on the bus.
 
-AU1000 serial console
-CONFIG_AU1000_SERIAL_CONSOLE
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use a console on a serial port, say Y.  Otherwise, say N.
-
-AU1000 serial support
-CONFIG_AU1000_UART
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use serial ports, say Y.  Otherwise, say N.
-
 AU1000 ethernet controller on SGI MIPS system
 CONFIG_MIPS_AU1000_ENET
   If you have an Alchemy Semi AU1000 ethernet controller
@@ -19671,6 +20163,11 @@
   method as well for this to be useful. Even if they don't support it,
   it is safe to say Y here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called isdn_bsdcomp.o.
+
 Support audio via ISDN
 CONFIG_ISDN_AUDIO
   If you say Y here, the modem-emulator will support a subset of the
@@ -19705,6 +20202,11 @@
 
   Please read the file <file:Documentation/isdn/README.diversion>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called dss1_divert.o.
+
 ICN 2B and 4B support
 CONFIG_ISDN_DRV_ICN
   This enables support for two kinds of ISDN-cards made by a German
@@ -19729,6 +20231,11 @@
   You need will need the loopctrl utility from the latest isdn4k-utils
   package to set up this driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called isdnloop.o.
+
 HiSax SiemensChipSet driver support
 CONFIG_ISDN_DRV_HISAX
   This is a driver supporting the Siemens chipset on various
@@ -20024,15 +20531,30 @@
   This enables the PCMCIA client driver for the Elsa PCMCIA MicroLink
   card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called elsa_cs.o.
+
 Sedlbauer PCMCIA cards
 CONFIG_HISAX_SEDLBAUER_CS
   This enables the PCMCIA client driver for the Sedlbauer Speed Star
   and Speed Star II cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sedlbauer_cs.o.
+
 CONFIG_HISAX_AVM_A1_CS
   This enables the PCMCIA client driver for the AVM A1 / Fritz!Card
   PCMCIA cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called avma1_cs.o.
+
 ST5481 USB ISDN modem
 CONFIG_HISAX_ST5481
   This enables the driver for ST5481 based USB ISDN adapters,
@@ -20074,6 +20596,11 @@
   Say Y here to use your Eicon active ISDN card with ISDN4Linux
   isdn module.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called eicon.o.
+
 Eicon PCI DIVA Server BRI/PRI/4BRI support
 CONFIG_ISDN_DRV_EICON_PCI
   Say Y here if you have an Eicon Diva Server (BRI/PRI/4BRI) ISDN
@@ -20096,6 +20623,11 @@
   cards and will provide its own IDI interface. You should say N
   here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called divas.o.
+
 Support AT-Fax Class 1 and 2 commands
 CONFIG_ISDN_TTY_FAX
   If you say Y here, the modem-emulator will support a subset of the
@@ -20124,6 +20656,11 @@
   standardized libcapi20 to access this functionality.  You should say
   Y/M here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called capi.o.
+
 CAPI2.0 Middleware support
 CONFIG_ISDN_CAPI_MIDDLEWARE
   This option will enhance the capabilities of the /dev/capi20
@@ -20146,12 +20683,22 @@
   supported by a CAPI driver, but still want to use old features like
   ippp interfaces or ttyI emulation, say Y/M here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called capidrv.o.
+
 AVM B1 ISA support
 CONFIG_ISDN_DRV_AVMB1_B1ISA
   Enable support for the ISA version of the AVM B1 card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called b1isa.o.
+
 AVM B1 PCI support
-CONFIG_ISDN_DRV_AVMB1_B1PCI
+CONFIG_ISDN_DRV_AVMB1_B1CICI
   Enable support for the PCI version of the AVM B1 card.
 
 AVM B1 PCI V4 support
@@ -20163,25 +20710,50 @@
   Enable support for the AVM T1 T1B card.
   Note: This is a PRI card and handle 30 B-channels.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called t1isa.o.
+
 AVM B1/M1/M2 PCMCIA support
 CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
   Enable support for the PCMCIA version of the AVM B1 card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called b1pcmcia.o.
+
 AVM B1/M1/M2 PCMCIA cs module
 CONFIG_ISDN_DRV_AVMB1_AVM_CS
   Enable the PCMCIA client driver for the AVM B1/M1/M2
   PCMCIA cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called avm_cs.o.
+
 AVM T1/T1-B PCI support
 CONFIG_ISDN_DRV_AVMB1_T1PCI
   Enable support for the AVM T1 T1B card.
   Note: This is a PRI card and handle 30 B-channels.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called t1pci.o.
+
 AVM C4/C2 support
 CONFIG_ISDN_DRV_AVMB1_C4
   Enable support for the AVM C4/C2 PCI cards.
   These cards handle 4/2 BRI ISDN lines (8/4 channels).
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called c4.o.
+
 Verbose reason code reporting (kernel size +=7K)
 CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
   If you say Y here, the AVM B1 driver will give verbose reasons for
@@ -20196,6 +20768,11 @@
   isdn4k-utils package. Please read the file
   <file:Documentation/isdn/README.act2000> for more information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called act2000.o.
+
 Auvertech TurboPAM support
 CONFIG_ISDN_DRV_TPAM
   This enables support for the Auvertech TurboPAM ISDN-card.
@@ -20217,6 +20794,11 @@
   Please read the file <file:Documentation/isdn/README.hysdn> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hysdn.o.
+
 HYSDN CAPI 2.0 support
 CONFIG_HYSDN_CAPI
   Say Y here if you like to use Hypercope's CAPI 2.0 interface.
@@ -20283,7 +20865,7 @@
 
 Kernel support for 32-bit ELF binaries
 CONFIG_BINFMT_ELF32
-  This allows you to run 32-bit Linux/ELF binaries on your Ultra.
+  This allows you to run 32-bit Linux/ELF binaries on your machine.
   Everybody wants this; say Y.
 
 Kernel support for 32-bit (ie. SunOS) a.out binaries
@@ -20369,7 +20951,7 @@
 DBRI Lowlevel Driver
 CONFIG_SPARCAUDIO_DBRI
   This driver supports the DBRI audio interface found on the SS10,
-  SS20, Sparcbook 3, and Voyager systems.
+  SS20, LX, Sparcbook 3, and Voyager systems.
 
 Dummy Lowlevel Driver
 CONFIG_SPARCAUDIO_DUMMY
@@ -20436,6 +21018,19 @@
   Say Y here to compile SCO support into the kernel or say M to
   compile it as module (sco.o).
 
+BNEP protocol support
+CONFIG_BLUEZ_BNEP
+  BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
+  emulation layer on top of Bluetooth. BNEP is required for Bluetooth
+  PAN (Personal Area Network).
+
+  To use BNEP, you will need user-space utilities provided in the 
+  BlueZ-PAN package.
+  For more information, see <http://bluez.sourceforge.net>.
+
+  Say Y here to compile BNEP support into the kernel or say M to
+  compile it as module (bnep.o).
+
 HCI UART driver
 CONFIG_BLUEZ_HCIUART
   Bluetooth HCI UART driver.
@@ -20464,18 +21059,9 @@
   Say Y here to compile support for Bluetooth USB devices into the
   kernel or say M to compile it as module (hci_usb.o).
 
-HCI USB firmware download support
-CONFIG_BLUEZ_USB_FW_LOAD
-  Firmware download support for Bluetooth USB devices.
-  This support is required for devices like Broadcom BCM2033.
-
-  HCI USB driver uses external firmware downloader program provided 
-  in BlueFW package.
-  For more information, see <http://bluez.sf.net/>.
-
 HCI USB zero packet support
 CONFIG_BLUEZ_USB_ZERO_PACKET
-  Support for USB zero packets. 
+  Support for USB zero packets.
   This option is provided only as a work around for buggy Bluetooth USB 
   devices. Do _not_ enable it unless you know for sure that your device 
   requires zero packets.
@@ -20494,11 +21080,37 @@
   Bluetooth HCI DTL1 (PC Card) driver.
   This driver provides support for Bluetooth PCMCIA devices with
   Nokia DTL1 interface:
-     Nokia Bluetooth PC Card, Socketcom Bluetooth CF module
+     Nokia Bluetooth Card
+     Socket Bluetooth CF Card
 
   Say Y here to compile support for HCI DTL1 devices into the
   kernel or say M to compile it as module (dtl1_cs.o).
 
+HCI BT3C (PC Card) device driver
+CONFIG_BLUEZ_HCIBT3C
+  Bluetooth HCI BT3C (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  3Com BT3C interface:
+     3Com Bluetooth Card (3CRWB6096)
+     HP Bluetooth Card
+
+  The HCI BT3C driver uses external firmware loader program provided in
+  the BlueFW package. For more information, see <http://bluez.sf.net>.
+
+  Say Y here to compile support for HCI BT3C devices into the
+  kernel or say M to compile it as module (bt3c_cs.o).
+
+HCI BlueCard (PC Card) device driver
+CONFIG_BLUEZ_HCIBLUECARD
+  Bluetooth HCI BlueCard (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  Anycom BlueCard interface:
+     Anycom Bluetooth PC Card
+     Anycom Bluetooth CF Card
+
+  Say Y here to compile support for HCI BlueCard devices into the
+  kernel or say M to compile it as module (bluecard_cs.o).
+
 # The following options are for Linux when running on the Hitachi
 # SuperH family of RISC microprocessors.
 
@@ -20931,12 +21543,6 @@
   Hades. This increases the SCSI transfer rates at least ten times
   compared to PIO transfers.
 
-Sun3 NCR5380 OBIO SCSI
-CONFIG_SUN3_SCSI
-  This option will enable support for the OBIO (onboard io) NCR5380
-  SCSI controller found in the Sun 3/50 and 3/60.  Note that this
-  driver does not provide support for VME SCSI boards.
-
 Sun3x ESP SCSI
 CONFIG_SUN3X_ESP
   This option will enable support for the ESP SCSI controller found
@@ -20990,11 +21596,6 @@
   General Linux information on the Sun 3 series (now discontinued)
   is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
-Sun3x ESP SCSI driver
-CONFIG_SUN3X_ESP
-  The ESP was an on-board SCSI controller used on Sun 3/80
-  machines.  Say Y here to compile in support for it.
-
 PCMCIA NE2000 and compatibles support
 CONFIG_APNE
   If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
@@ -21005,19 +21606,6 @@
   want). The module is called apne.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Sun3/Sun3x on-board LANCE support
-CONFIG_SUN3LANCE
-  This driver enables support for the on-board LANCE ethernet adapter
-  found on the Sun 3/50, 3/60, and 3/80 workstations.  If you have 
-  one of these workstations, and would like Ethernet, say Y. 
-  Otherwise, say N.
-
-Sun3 on-board Intel 82586 support
-CONFIG_SUN3_82586
-  This driver enables support for the on-board Intel 82586 based Ethernet
-  adapter found on Sun 3/1xx and 3/2xx motherboards.  Note that this driver
-  does not support 82586-based adapters on additional VME boards.
-
 Atari Lance support
 CONFIG_ATARILANCE
   Say Y to include support for several Atari Ethernet adapters based
@@ -22398,7 +22986,7 @@
   IPL device on another question, that pops up, when you select
   CONFIG_IPL.
 
-IPL from a /390 tape unit
+IPL from a S/390 tape unit
 CONFIG_IPL_TAPE
   Select this option if you want to IPL the image from a Tape.
 
@@ -22407,18 +22995,22 @@
   Select this option if you are running under VM/ESA and want 
   to IPL the image from the emulated card reader.
 
-Support for DASD hard disks
-CONFIG_DASD
-  Enable this option if you want to access DASDs directly utilizing
-  S/390s channel subsystem commands. This is necessary for running
-  natively on a single image or an LPAR.
+CONFIG_PFAULT
+  Select this option, if you want to use PFAULT pseudo page fault
+  handling under VM. If running native or in LPAR, this option
+  has no effect. If your VM does not support PFAULT, PAGEEX
+  pseudo page fault handling will be used.
+  Note that VM 4.2 supports PFAULT but has a bug in its
+  implementation that causes some problems.
+  Everybody who wants to run Linux under VM != VM4.2 should select
+  this option.
 
-Enable DASD fast write
-CONFIG_DASD_FAST_IO
-  Enable fast I/O for DASDs. That means that the next I/O command
-  is already issued at interrupt time, if an I/O request is pending.
-  This option gives significant speedup of I/O, because we don't
-  schedule the bottom-halves as often as Intel.
+CONFIG_SHARED_KERNEL
+  Select this option, if you want to share the text segment of the
+  Linux kernel between different VM guests. This reduces memory
+  usage with lots of guests but greatly increases kernel size.
+  You should only select this option if you know what you are
+  doing and want to exploit this feature.
 
 Support for IBM-style disk-labels (S/390)
 CONFIG_S390_PARTITION
@@ -22427,18 +23019,40 @@
   attached to another IBM mainframe operation system (OS/390, 
   VM/ESA, VSE/ESA).
 
+Support for DASD hard disks
+CONFIG_DASD
+  Enable this option if you want to access DASDs directly utilizing
+  S/390s channel subsystem commands. This is necessary for running
+  natively on a single image or an LPAR.
+
 Support for ECKD hard disks
 CONFIG_DASD_ECKD
-  ECKD devices are the most commonly used devices. You should enable
-  this option unless you are very sure you have no ECKD device.
+  ECKD (Extended Count Key Data) devices are the most commonly used 
+  devices on S/390s. You should enable this option unless you are 
+  very sure you have no ECKD device.
 
-CKD devices
-CONFIG_DASD_CKD
-  CKD devices are currently unsupported.
+ECKD demand loading
+CONFIG_DASD_AUTO_ECKD
+  This option enables demand loading of the ECKD module. 
 
 Support for FBA hard disks
 CONFIG_DASD_FBA
-  FBA devices are currently unsupported.
+  Select this option if you want to use FBA (Fixed Block) devices.
+  If you are not sure what it is, say "Y".
+
+FBA demand loading
+CONFIG_DASD_AUTO_FBA
+  This option enables demand loading of the FBA module. 
+
+Support for DIAG access to CMS reserved Disks
+CONFIG_DASD_DIAG
+  Select this option if you want to use CMS reserved Disks under VM
+  with the Diagnose250 command.  If you are not running under VM or
+  unsure what it is, say "N".
+
+DIAG demand loading
+CONFIG_DASD_AUTO_DIAG
+  This option enables demand loading of the DIAG module. 
 
 Merge some code into the kernel to make the image IPLable
 CONFIG_IPLABLE
@@ -22476,6 +23090,16 @@
   Include support for using an IBM HWC line-mode terminal as the Linux
   system console.
 
+Control Program Identification
+CONFIG_HWC_CPI
+  Allows for Control Program Identification via the HWC interface,
+  i.e. provides a mean to pass an OS instance name (system name)
+  to the machine.
+
+  This option should only be selected as a module since the
+  system name has to be passed as module parameter. The module
+  will be called hwc_cpi.o.
+
 S/390 tape device support
 CONFIG_S390_TAPE
   Select this option if you want to access channel-attached tape
@@ -22484,8 +23108,9 @@
   least one of the tape interface options and one of the tape
   hardware options in order to access a tape device.
   This option is also available as a module. The module will be
-  called tape390.o and include all selected interfaces and
-  hardware drivers.
+  called tape390.o and include all selected interfaces.
+  The hardware drivers will be seperate modules.
+  If unsure, say "Y".
 
 Support for tape character devices
 CONFIG_S390_TAPE_CHAR
@@ -22506,14 +23131,23 @@
 
 Support for 3490 tape hardware
 CONFIG_S390_TAPE_3490
-  Select this option if you want to access IBM 3480 magnetic
+  Select this option if you want to access IBM 3490 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3490.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
   It is safe to say "Y" here.
 
 Support for 3480 tape hardware
 CONFIG_S390_TAPE_3480
-  Select this option if you want to access IBM 3490 magnetic
+  Select this option if you want to access IBM 3480 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3480.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
+  It is safe to say "Y" here.
 
 CTC device support
 CONFIG_CTC
@@ -22524,12 +23158,6 @@
   available.  This option is also available as a module which will be
   called ctc.o.  If you do not know what it is, it's safe to say "Y".
 
-Support for DIAG access to CMS reserved Disks
-CONFIG_DASD_DIAG
-  Select this option if you want to use CMS reserved Disks under VM
-  with the Diagnose250 command.  If you are not running under VM or
-  unsure what it is, say "N".
-
 XPRAM disk support
 CONFIG_BLK_DEV_XPRAM
   Select this option if you want to use your expanded storage on S/390
@@ -22552,6 +23180,20 @@
   vehicle networking under VM or VIF.  This option is also available
   as a module which will be called iucv.o. If unsure, say "Y".
 
+Process warning machine checks
+CONFIG_MACHCHK_WARNING
+  Select this option if you want the machine check handler on IBM S/390 or 
+  zSeries to process warning machine checks (e.g. on power failures). 
+  If unsure, say "Y".
+
+Use chscs for Common I/O
+CONFIG_CHSC
+  Select this option if you want the s390 common I/O layer to use information
+  obtained by channel subsystem calls. This will enable Linux to process link
+  failures and resource accessibility events. Moreover, if you have procfs
+  enabled, you'll be able to toggle chpids logically offline and online. Even
+  if you don't understand what this means, you should say "Y".
+
 Kernel support for 31 bit ELF binaries
 CONFIG_S390_SUPPORT
   Select this option if you want to enable your system kernel to
@@ -23014,6 +23656,11 @@
   It is recommended to be used on a NetWinder, but it is not a
   necessity.
 
+Check for stack overflows
+CONFIG_DEBUG_STACKOVERFLOW
+  This option make do_IRQ() check for enough stack space beeing left.
+  This is safe to enable.
+
 Debug high memory support
 CONFIG_DEBUG_HIGHMEM
   This options enables addition error checking for high memory systems.
@@ -23222,13 +23869,24 @@
 
 SRM environment variables in procfs
 CONFIG_SRM_ENV
-  If you enable this option, a subdirectory called srm_environment
-  will give you access to the most important SRM environment
-  variables. If you've got an Alpha style system supporting
-  SRC, then it is a good idea to say Yes or Module to this driver.
+  If you enable this option, a subdirectory inside /proc called
+  /proc/srm_environment will give you access to the all important
+  SRM environment variables (those which have a name) and also
+  to all others (by their internal number).
+
+  SRM is something like a BIOS for Alpha machines. There are some
+  other such BIOSes, like AlphaBIOS, which this driver cannot
+  support (hey, that's not SRM!).
+
+  Despite the fact that this driver doesn't work on all Alphas (but
+  only on those which have SRM as their firmware), it's save to
+  build it even if your particular machine doesn't know about SRM
+  (or if you intend to compile a generic kernel). It will simply
+  not create those subdirectory in /proc (and give you some warning,
+  of course).
 
   This driver is also available as a module and will be called
-  srm_env.o if you build it as a module.
+  srm_env.o then.
 
 Footbridge internal watchdog
 CONFIG_21285_WATCHDOG
@@ -23449,6 +24107,11 @@
   This driver supports the use of zero copy on tx, checksum 
   validation on rx, and 64 bit addressing.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ns83820.o.
+
 Toshiba Type-O IR Port device driver
 CONFIG_TOSHIBA_FIR
   Say Y here if you want to build support for the Toshiba Type-O IR
@@ -23505,6 +24168,11 @@
   used by IrTTY.  To activate support for ESI dongles you will have to
   start irattach like this: "irattach -d esi".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called esi.o.
+
 ACTiSYS IR-220L and IR220L+ dongle
 CONFIG_ACTISYS_DONGLE
   Say Y here if you want to build support for the ACTiSYS IR-220L and
@@ -23515,6 +24183,11 @@
   dongles you will have to start irattach like this:
   "irattach -d actisys" or "irattach -d actisys+".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called actisys.o.
+
 Tekram IrMate 210B dongle
 CONFIG_TEKRAM_DONGLE
   Say Y here if you want to build support for the Tekram IrMate 210B
@@ -23524,6 +24197,11 @@
   by IrTTY.  To activate support for Tekram dongles you will have to
   start irattach like this: "irattach -d tekram".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called tekram.o.
+
 Greenwich GIrBIL dongle
 CONFIG_GIRBIL_DONGLE
   Say Y here if you want to build support for the Greenwich GIrBIL
@@ -23533,6 +24211,11 @@
   used by IrTTY.  To activate support for Greenwich dongles you will
   have to insert "irattach -d girbil" in the /etc/irda/drivers script.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called girbil.o.
+
 Parallax LiteLink dongle
 CONFIG_LITELINK_DONGLE
   Say Y here if you want to build support for the Parallax Litelink
@@ -23542,6 +24225,23 @@
   used by IrTTY.  To activate support for Parallax dongles you will
   have to start irattach like this "irattach -d litelink".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called litelink.o.
+
+Microchip MCP2120 dongle
+CONFIG_MCP2120_DONGLE
+  Say Y here if you want to build support for the Microchip MCP2120
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MCP2120 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY.  To activate support for MCP2120 dongles you will
+  have to insert "irattach -d mcp2120" in the /etc/irda/drivers script.
+
+  You must build this dongle yourself.  For more information see:
+  <http://www.eyetap.org/~tangf/irda_sir_linux.html>
+
 Old Belkin dongle
 CONFIG_OLD_BELKIN_DONGLE
   Say Y here if you want to build support for the Adaptec Airport 1000
@@ -23549,6 +24249,30 @@
   and read <file:Documentation/modules.txt>.  The module will be
   called old_belkin.o.  Some information is contained in the comments
   at the top of <file:drivers/net/irda/old_belkin.c>.
+ 
+ACTiSYS IR-200L dongle (Experimental)
+CONFIG_ACT200L_DONGLE
+  Say Y here if you want to build support for the ACTiSYS IR-200L
+  dongle. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The ACTiSYS IR-200L dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY. To activate support for ACTiSYS IR-200L dongles
+  you will have to start irattach like this: "irattach -d act200l".
+
+Mobile Action MA600 dongle (Experimental)
+CONFIG_MA600_DONGLE
+  Say Y here if you want to build support for the Mobile Action MA600
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MA600 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  tested on IrCOMM.  To activate support for MA600 dongles you will
+  have to insert "irattach -d ma600" in the /etc/irda/drivers script.
+  Note: irutils 0.9.15 requires no modification. irutils 0.9.9 needs
+  modification. For more information, download the following tar gzip
+  file.
+
+  There is a pre-compiled module on
+  <http://engsvr.ust.hk/~eetwl95/download/ma600-2.4.x.tar.gz>
 
 VME (Motorola and BVM) support
 CONFIG_VME
@@ -24400,15 +25124,19 @@
   As of the time of this writing, most hardware is DIG compliant,
   so the "DIG-compliant" option is usually the right choice.
 
-  HP-simulator   For the HP simulator
-                 (<http://software.hp.com/ia64linux/>).
+  HP-simulator   For the HP simulator (<http://software.hp.com/ia64linux/>).
+  HP-zx1	 For HP zx1 Platforms.
   SN1            For SGI SN1 Platforms.
   SN2            For SGI SN2 Platforms.
-  DIG-compliant  For DIG ("Developer's Interface Guide") compliant
-                 system.
+  DIG-compliant  For DIG ("Developer's Interface Guide") compliant systems.
 
   If you don't know what to do, choose "generic".
 
+CONFIG_IA64_HP_ZX1
+  Build a kernel that runs on HP zx1-based systems.  This adds support
+  for the zx1 IOMMU and makes root bus bridges appear in PCI config space
+  (required for zx1 agpgart support).
+
 CONFIG_IA64_SGI_SN_SIM
   Build a kernel that runs on both the SGI simulator AND on hardware.
   There is a very slight performance penalty on hardware for including this
@@ -24456,16 +25184,6 @@
   can select this option to disable the VHPT for debugging.  If you're
   unsure, answer N.
 
-Enable McKinley A-step specific code
-CONFIG_MCKINLEY_ASTEP_SPECIFIC
-  Select this option to build a kernel for an IA64 McKinley system
-  with any A-stepping CPU.
-
-Enable McKinley A0/A1-step specific code
-CONFIG_MCKINLEY_A0_SPECIFIC
-  Select this option to build a kernel for an IA64 McKinley system
-  with an A0 or A1 stepping CPU.
-
 Turn on compare-and-exchange bug checking (slow!)
 CONFIG_IA64_DEBUG_CMPXCHG
   Selecting this option turns on bug checking for the IA64
@@ -24490,9 +25208,7 @@
 CONFIG_IA64_PRINT_HAZARDS
   Selecting this option prints more information for Illegal Dependency
   Faults, that is, for Read after Write, Write after Write or Write
-  after Read violations.  This option is ignored if you are compiling
-  for an Itanium A step processor (CONFIG_ITANIUM_ASTEP_SPECIFIC).  If
-  you're unsure, select Y.
+  after Read violations.  If you're unsure, select Y.
 
 Performance monitor support
 CONFIG_PERFMON
@@ -24526,15 +25242,6 @@
   the IA32 instruction set.  Say Y here to build in kernel support for
   this.  If in doubt, say Y.
 
-/proc/efi/vars support
-CONFIG_EFI_VARS
-  If you say Y here, you are able to get EFI (Extensible Firmware
-  Interface) variable information in /proc/efi/vars.  You may read,
-  write, create, and destroy EFI variables through this interface.
-
-  To use this option, you have to check that the "/proc file system
-  support" (CONFIG_PROC_FS) is enabled, too.
-
 Physical memory granularity (16 MB)
 CONFIG_IA64_GRANULE_16MB
   IA64 identity-mapped regions use a large page size.  We'll call such
@@ -25020,14 +25727,6 @@
   <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
   board at <http://www.mvista.com/allies/semiconductor/ite.html>.
 
-Use chscs for Common I/O
-CONFIG_CHSC
-  Select this option if you want the s390 common I/O layer to use information
-  obtained by channel subsystem calls. This will enable Linux to process link
-  failures and resource accessibility events. Moreover, if you have procfs
-  enabled, you'll be able to toggle chpids logically offline and online. Even
-  if you don't understand what this means, you should say "Y".
-
 Support ARM926T processor
 CONFIG_CPU_ARM926T
   This is a variant of the ARM920.  It has slightly different
@@ -25047,21 +25746,6 @@
   written) to implement the policy. If you don't understand what this
   is all about, it's safe to say 'N'.
 
-Automatic activation of DIAG module
-CONFIG_DASD_AUTO_DIAG
-  Enable this option if you want your DIAG discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of ECKD module
-CONFIG_DASD_AUTO_ECKD
-  Enable this option if you want your ECKD discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of FBA  module
-CONFIG_DASD_AUTO_FBA
-  Enable this option if you want your FBA discipline module loaded
-  on DASD driver startup.
-
 SiS
 CONFIG_DRM_SIS
   Choose this option if you have a SIS graphics card. AGP support is
@@ -25155,16 +25839,6 @@
 
   When in doubt, say N.
 
-Control-Program Identification
-CONFIG_HWC_CPI
-  This option enables the hardware console interface for system
-  identification This is commonly used for workload management and
-  gives you a nice name for the system on the service element.
-  Please select this option as a module since built-in operation is
-  completely untested.
-  You should only select this option if you know what you are doing,
-  need this feature and intend to run your kernel in LPAR.
-
 Enable autotest (llsc). Option to run cache test instead of booting
 CONFIG_IA64_SGI_AUTOTEST
   Build a kernel used for hardware validation. If you include the
@@ -25240,37 +25914,12 @@
   Say Y here to support tuning the ITE8172's IDE interface.  This makes
   it possible to set DMA channel or PIO opration and the transfer rate.
 
-Process warning machine checks
-CONFIG_MACHCHK_WARNING
-  Select this option if you want the machine check handler on IBM S/390 or
-  zSeries to process warning machine checks (e.g. on power failures).
-  If unsure, say "Y".
-
-Pseudo page fault support
-CONFIG_PFAULT
-  Select this option, if you want to use PFAULT pseudo page fault
-  handling under VM. If running native or in LPAR, this option
-  has no effect. If your VM does not support PFAULT, PAGEEX
-  pseudo page fault handling will be used.
-  Note that VM 4.2 supports PFAULT but has a bug in its
-  implementation that causes some problems.
-  Everybody who wants to run Linux under VM != VM4.2 should select
-  this option.
-
 Enable protocol mode for the L1 console
 CONFIG_SERIAL_SGI_L1_PROTOCOL
   Uses protocol mode instead of raw mode for the level 1 console on the
   SGI SN (Scalable NUMA) platform for IA64.  If you are compiling for
   an SGI SN box then Y is the recommended value, otherwise say N.
 
-VM shared kernel support
-CONFIG_SHARED_KERNEL
-  Select this option, if you want to share the text segment of the
-  Linux kernel between different VM guests. This reduces memory
-  usage with lots of guests but greatly increases kernel size.
-  You should only select this option if you know what you are
-  doing and want to exploit this feature.
-
 New bus configuration (EXPERIMENTAL)  
 CONFIG_TULIP_MWI
   This configures your Tulip card specifically for the card and
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/Makefile linux-2.4.20/Documentation/DocBook/Makefile
--- linux-2.4.19/Documentation/DocBook/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/DocBook/Makefile	2002-10-04 00:41:20.000000000 +0000
@@ -1,7 +1,8 @@
 BOOKS	:= wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \
 	   kernel-api.sgml parportbook.sgml kernel-hacking.sgml \
 	   kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \
-	   deviceiobook.sgml procfs-guide.sgml tulip-user.sgml
+	   deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
+	   journal-api.sgml
 
 PS	:=	$(patsubst %.sgml, %.ps, $(BOOKS))
 PDF	:=	$(patsubst %.sgml, %.pdf, $(BOOKS))
@@ -138,6 +139,17 @@
 parportbook.sgml: parportbook.tmpl $(TOPDIR)/drivers/parport/init.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c <$< >$@
 
+
+JBDSOURCES :=  $(TOPDIR)/include/linux/jbd.h \
+	       $(TOPDIR)/fs/jbd/journal.c \
+	       $(TOPDIR)/fs/jbd/recovery.c \
+	       $(TOPDIR)/fs/jbd/transaction.c
+
+journal-api.sgml: journal-api.tmpl $(JBDSOURCES)
+	$(TOPDIR)/scripts/docgen   $(JBDSOURCES) \
+		<journal-api.tmpl >journal-api.sgml
+
+
 DVI	:=	$(patsubst %.sgml, %.dvi, $(BOOKS))
 AUX	:=	$(patsubst %.sgml, %.aux, $(BOOKS))
 TEX	:=	$(patsubst %.sgml, %.tex, $(BOOKS))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/journal-api.tmpl linux-2.4.20/Documentation/DocBook/journal-api.tmpl
--- linux-2.4.19/Documentation/DocBook/journal-api.tmpl	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/DocBook/journal-api.tmpl	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,297 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+<book id="LinuxJBDAPI">
+ <bookinfo>
+  <title>The Linux Journalling API</title>
+  <authorgroup>
+  <author>
+     <firstname>Roger</firstname>
+     <surname>Gammans</surname>
+     <affiliation>
+     <address>
+      <email>rgammans@computer-surgery.co.uk</email>
+     </address>
+    </affiliation>
+     </author> 
+  </authorgroup>
+  
+  <authorgroup>
+   <author>
+    <firstname>Stephen</firstname>
+    <surname>Tweedie</surname>
+    <affiliation>
+     <address>
+      <email>sct@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2002</year>
+   <holder>Roger Gammans</holder>
+  </copyright>
+
+<legalnotice>
+   <para>
+     This documentation 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.
+   </para>
+      
+   <para>
+     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.
+   </para>
+      
+   <para>
+     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., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+      
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="Overview">
+     <title>Overview</title>
+  <sect1>
+     <title>Details</title>
+<para>
+The journalling layer is  easy to use. You need to 
+first of all create a journal_t data structure. There are
+two calls to do this dependent on how you decide to allocate the physical
+media on which the journal resides. The journal_init_inode() call 
+is for journals stored in filesystem inodes, or the journal_init_dev()
+call can be use for journal stored on a raw device (in a continuous range 
+of blocks). A journal_t is a typedef for a struct pointer, so when
+you are finally finished make sure you call journal_destroy() on it
+to free up any used kernel memory.
+</para>
+
+<para>
+Once you have got your journal_t object you need to 'mount' or load the journal
+file, unless of course you haven't initialised it yet - in which case you
+need to call journal_create().
+</para>
+
+<para>
+Most of the time however your journal file will already have been created, but
+before you load it you must call journal_wipe() to empty the journal file.
+Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the 
+job of the client file system to detect this and skip the call to journal_wipe().
+</para>
+
+<para>
+In either case the next call should be to journal_load() which prepares the
+journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() 
+for you if it detects any outstanding transactions in the journal and similarly
+journal_load() will call journal_recover() if necessary.
+I would advise reading fs/ext3/super.c for examples on this stage.
+[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly 
+complicate the API. Or isn't a good idea for the journal layer to hide 
+dirty mounts from the client fs]
+</para>
+
+<para>
+Now you can go ahead and start modifying the underlying 
+filesystem. Almost.
+</para>
+
+
+<para>
+
+You still need to actually journal your filesystem changes, this
+is done by wrapping them into transactions. Additionally you
+also need to wrap the modification of each of the the buffers
+with calls to the journal layer, so it knows what the modifications
+you are actually making are. To do this use  journal_start() which
+returns a transaction handle.
+</para>
+
+<para>
+journal_start()
+and its counterpart journal_stop(), which indicates the end of a transaction
+are nestable calls, so you can reenter a transaction if necessary,
+but remember you must call journal_stop() the same number of times as
+journal_start() before the transaction is completed (or more accurately
+leaves the the update phase). Ext3/VFS makes use of this feature to simplify 
+quota support.
+</para>
+
+<para>
+Inside each transaction you need to wrap the modifications to the
+individual buffers (blocks). Before you start to modify a buffer you
+need to call journal_get_{create,write,undo}_access() as appropriate,
+this allows the journalling layer to copy the unmodified data if it
+needs to. After all the buffer may be part of a previously uncommitted
+transaction. 
+At this point you are at last ready to modify a buffer, and once
+you are have done so you need to call journal_dirty_{meta,}data().
+Or if you've asked for access to a buffer you now know is now longer 
+required to be pushed back on the device you can call journal_forget()
+in much the same way as you might have used bforget() in the past.
+
+</para>
+
+
+
+<para>
+A journal_flush() may be called at any time to commit and checkpoint
+all your transactions.
+</para>
+<para>
+
+Then at umount time , in your put_super() (2.4) or write_super() (2.5)
+you can then call journal_destroy() to clean up your in-core journal object.
+</para>
+
+
+<para>
+Unfortunately there a couple of ways the journal layer can cause a deadlock.
+The first thing to note is that each task can only have
+a single outstanding transaction at any one time, remember nothing
+commits until the outermost journal_stop(). This means
+you must complete the transaction at the end of each file/inode/address
+etc. operation you perform, so that the journalling system isn't re-entered
+on another journal. Since transactions can't be nested/batched 
+across differing journals, and another filesystem other than
+yours (say ext3) may be modified in a later syscall.
+</para>
+<para>
+
+The second case to bear in mind is that journal_start() can 
+block if there isn't enough space in the journal for your transaction 
+(based on the passed nblocks param) - when it blocks it merely(!) needs to
+wait for transactions to complete and be committed from other tasks, 
+so essentially we are waiting for journal_stop(). So to avoid 
+deadlocks you must treat journal_start/stop() as if they
+were semaphores and include them in your semaphore ordering rules to prevent 
+deadlocks. Note that journal_extend() has similar blocking behaviour to
+journal_start() so you can deadlock here just as easily as on journal_start().
+</para>
+<para>
+
+Try to reserve the right number of blocks the first time. ;-).
+</para>
+<para>
+Another wriggle to watch out for is your on-disk block allocation strategy.
+why? Because, if you undo a delete, you need to ensure you haven't reused any
+of the freed blocks in a later transaction. One simple way of doing this
+is make sure any blocks you allocate only have checkpointed transactions
+listed against them. Ext3 does this in ext3_test_allocatable(). 
+</para>
+
+<para>
+Lock is also providing through journal_{un,}lock_updates(),
+ext3 uses this when it wants a window with a clean and stable fs for a moment.
+eg. 
+<programlisting>
+
+	journal_lock_updates() //stop new stuff happening..
+	journal_flush()        // checkpoint everything.
+	..do stuff on stable fs
+	journal_unlock_updates() // carry on with filesystem use.
+</programlisting>
+
+The opportunities for abuse and DOS attacks with this should be obvious,
+if you allow unprivileged userspace to trigger codepaths containing these
+calls.
+
+<para>
+</sect1>
+<sect1>
+<title>Summary</title>
+<para>
+Using the journal is a matter of wrapping the different context changes,
+being each mount, each modification (transaction) and each changed buffer
+to tell the journalling layer about them.
+
+Here is a some pseudo code to give you an idea of how it works, as
+an example.
+<programlisting>
+  journal_t* my_jnrl = journal_create();
+  journal_init_{dev,inode}(jnrl,...)
+  if (clean) journal_wipe();
+  journal_load();
+
+   foreach(transaction) { /*transactions must be 
+                            completed before
+                            a syscall returns to 
+                            userspace*/
+
+          handle_t * xct=journal_start(my_jnrl);
+          foreach(bh) {
+                journal_get_{create,write,undo}_access(xact,bh);
+                if ( myfs_modify(bh) ) { /* returns true 
+                                        if makes changes */
+                           journal_dirty_{meta,}data(xact,bh);
+                } else {
+                           journal_forget(bh);
+                }
+          }
+          journal_stop(xct);
+   }
+   journal_destroy(my_jrnl);
+</programlisting>
+
+</chapter>
+
+  <chapter id="adt">
+     <title>Data Types</title>
+     <para>	
+	The journalling layer uses typedefs to 'hide' the concrete definitions
+	of the structures used. As a client of the JBD layer you can
+	just rely on the using the pointer as a magic cookie  of some sort.
+	
+	Obviously the hiding is not enforced as this is 'C'.
+	</para>
+	<sect1><title>Structures</title>
+!Iinclude/linux/jbd.h
+	</sect1>
+</chapter>
+
+  <chapter id="calls">
+     <title>Functions</title>
+     <para>	
+	The functions here are split into two groups those that
+	affect a journal as a whole, and those which are used to
+	manage transactions
+</para>
+	<sect1><title>Journal Level</title>
+!Efs/jbd/journal.c
+!Efs/jbd/recovery.c
+	</sect1>
+	<sect1><title>Transasction Level</title>
+!Efs/jbd/transaction.c	
+	</sect1>
+</chapter>
+<chapter>
+     <title>See also</title>
+	<para>
+	<citation>
+	   <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz">
+	   	Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie
+	   </ulink>
+	   </citation>
+	   </para>
+	   <para>
+	   <citation>
+	   <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
+	   	Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie
+	   </ulink>
+	   </citation>
+	   </para>
+</chapter>
+
+</book>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl linux-2.4.20/Documentation/DocBook/kernel-hacking.tmpl
--- linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/DocBook/kernel-hacking.tmpl	2002-10-04 00:41:21.000000000 +0000
@@ -1091,18 +1091,17 @@
    <title>Initializing structure members</title>
 
    <para>
-    The preferred method of initializing structures is to use the
-    gcc Labeled Elements extension, eg:
+    The preferred method of initializing structures is to use
+    designated initialisers, as defined by ISO C99, eg:
    </para>
    <programlisting>
 static struct block_device_operations opt_fops = {
-        open:                   opt_open,
-        release:                opt_release,
-        ioctl:                  opt_ioctl,
-        check_media_change:     opt_media_change,
+        .open               = opt_open,
+        .release            = opt_release,
+        .ioctl              = opt_ioctl,
+        .check_media_change = opt_media_change,
 };
    </programlisting>
-
    <para>
     This makes it easy to grep for, and makes it clear which
     structure fields are set.  You should do this because it looks
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/parportbook.tmpl linux-2.4.20/Documentation/DocBook/parportbook.tmpl
--- linux-2.4.19/Documentation/DocBook/parportbook.tmpl	2001-10-25 07:07:40.000000000 +0000
+++ linux-2.4.20/Documentation/DocBook/parportbook.tmpl	2002-10-04 00:41:10.000000000 +0000
@@ -595,7 +595,7 @@
    So, the first thing for the device driver to do is tell
    <literal>parport</literal> that it wants to know what parallel
    ports are on the system.  To do this, it uses the
-   <function>parport_register_device</function> function:
+   <function>parport_register_driver</function> function:
   </para>
 
   <funcsynopsis>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/SubmittingPatches linux-2.4.20/Documentation/SubmittingPatches
--- linux-2.4.19/Documentation/SubmittingPatches	2000-12-04 01:48:18.000000000 +0000
+++ linux-2.4.20/Documentation/SubmittingPatches	2002-10-04 00:41:10.000000000 +0000
@@ -161,7 +161,7 @@
 When sending patches to Linus, always follow step #6.
 
 Large changes are not appropriate for mailing lists, and some
-maintainers.  If your patch, uncompressed, exceeds 40Kb in size,
+maintainers.  If your patch, uncompressed, exceeds 40 kB in size,
 it is preferred that you store your patch on an Internet-accessible
 server, and provide instead a URL (link) pointing to your patch.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/cdrom/sonycd535 linux-2.4.20/Documentation/cdrom/sonycd535
--- linux-2.4.19/Documentation/cdrom/sonycd535	1998-05-21 01:54:34.000000000 +0000
+++ linux-2.4.20/Documentation/cdrom/sonycd535	2002-10-04 00:41:16.000000000 +0000
@@ -63,8 +63,8 @@
 Thanks also to Eberhard Moenkeberg (emoenke@gwdg.de) for prodding
 me to place this code into the mainstream Linux source tree
 (as of Linux version 1.1.91), as well as some patches to make
-it a better device citizen.  Further thanks to "S. Joel Katz"
-<stimpson@panix.com> for his MODULE patches (see details below),
+it a better device citizen.  Further thanks to Joel Katz
+<joelkatz@webchat.org> for his MODULE patches (see details below),
 Porfiri Claudio <C.Porfiri@nisms.tei.ericsson.se> for patches
 to make the driver work with the older CDU-510/515 series, and
 Heiko Eissfeldt <heiko@colossus.escape.de> for pointing out that
@@ -79,7 +79,7 @@
 ken@halcyon.com
 
 ------------------------------------------------------------------------------
-(The following is from Joel Katz <Stimpson@Panix.COM>.)
+(The following is from Joel Katz <joelkatz@webchat.org>.)
 
 	To build a version of sony535.o that can be installed as a module,
 use the following command:
@@ -103,7 +103,7 @@
 	I have an external drive, and I usually leave it powered off. I used
 to have to reboot if I needed to use the CDROM drive. Now I don't.
 
-	Even if you have an internal drive, why waste the 268K of memory
+	Even if you have an internal drive, why waste the 96K of memory
 (unswappable) that the driver uses if you use your CD-ROM drive infrequently?
 
 	This driver will not install (whether compiled in or loaded as a
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/00-INDEX linux-2.4.20/Documentation/filesystems/00-INDEX
--- linux-2.4.19/Documentation/filesystems/00-INDEX	2001-06-20 18:10:27.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/00-INDEX	2002-10-04 00:41:20.000000000 +0000
@@ -6,6 +6,8 @@
 	- info and mount options for the Acorn Advanced Disc Filing System.
 affs.txt
 	- info and mount options for the Amiga Fast File System.
+befs.txt
+	- info for the BeOS file system (BFS)
 bfs.txt
 	- info for the SCO UnixWare Boot Filesystem (BFS).
 coda.txt
@@ -22,6 +24,8 @@
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
 	- info and mount options for the ISO 9660 (CDROM) filesystem.
+jfs.txt
+	- info and mount options for the JFS filesystem.
 ncpfs.txt
 	- info on Novell Netware(tm) filesystem using NCP protocol.
 ntfs.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/Locking linux-2.4.20/Documentation/filesystems/Locking
--- linux-2.4.19/Documentation/filesystems/Locking	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/Locking	2002-10-04 00:41:15.000000000 +0000
@@ -45,6 +45,10 @@
 	int (*revalidate) (struct dentry *);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct dentry *, struct iattr *);
+	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
+	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+	int (*removexattr) (struct dentry *, const char *);
 
 locking rules:
 	all may block
@@ -61,9 +65,13 @@
 follow_link:	no	no		no
 truncate:	yes	yes		no		(see below)
 setattr:	yes	if ATTR_SIZE	no
-permssion:	yes	no		no
+permission:	yes	no		no
 getattr:						(see below)
 revalidate:	no					(see below)
+setxattr:	yes	yes		no
+getxattr:	yes	yes		no
+listxattr:	yes	yes		no
+removexattr:	yes	yes		no
 	Additionally, ->rmdir() has i_zombie on victim and so does ->rename()
 in case when target exists and is a directory.
 	->rename() on directories has (per-superblock) ->s_vfs_rename_sem.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/befs.txt linux-2.4.20/Documentation/filesystems/befs.txt
--- linux-2.4.19/Documentation/filesystems/befs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/befs.txt	2002-10-04 00:41:12.000000000 +0000
@@ -0,0 +1,111 @@
+BeOS filesystem for Linux
+
+Document last updated: Dec 6, 2001
+
+WARNING
+=======
+Make sure you understand that this is alpha software.  This means that the
+implementation is neither complete nor well-tested. 
+
+I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+
+LICENSE
+=====
+This software is covered by the GNU General Public License. 
+See the file COPYING for the complete text of the license.
+Or the GNU website: <http://www.gnu.org/licenses/licenses.html>
+
+AUTHOR
+=====
+Current maintainer: Will Dyson <will_dyson@pobox.com>
+Has been working on the code since Aug 13, 2001. See the changelog for details.
+
+Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+His orriginal code can still be found at: <http://hp.vector.co.jp/authors/VA008030/bfs/>
+Does anyone know of a more current email address for Makoto? He doesn't respond
+to the address given above...
+
+WHAT IS THIS DRIVER?
+==================
+This module implements the native filesystem of BeOS <http://www.be.com/>
+for the linux 2.4.1 and later kernels. Currently it is a read-only implementation.
+
+Which is it, BFS or BEFS?
+================
+Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
+But Unixware Boot Filesystem is called bfs, too. And they are already in the
+kernel.
+Because of this nameing conflict, on Linux the BeOS filesystem is called befs.
+
+HOW TO INSTALL
+==============
+step 1.  Install the BeFS  patch into the source code tree of linux.
+
+Apply the patchfile to your kernel source tree.
+Assuming that your kernel source is in /foo/bar/linux and the patchfile is called
+patch-befs-xxx, you would do the following:
+
+	cd /foo/bar/linux
+	patch -p1 < /path/to/patch-befs-xxx
+
+if the patching step fails (i.e. there are rejected hunks), you can try to
+figure it out yourself (it shouldn't be hard), or mail the maintainer 
+(Will Dyson <will_dyson@pobox.com>) for help.
+
+step 2.  Configuretion & make kernel
+
+The linux kernel has many compile-time options. Most of them are beyond the
+scope of this document. I suggest the Kernel-HOWTO document as a good general
+reference on this topic. <http://www.linux.com/howto/Kernel-HOWTO.html>
+
+However, to use the BeFS module, you must enable it at configure time.
+
+	cd /foo/bar/linux
+	make menuconfig (or xconfig)
+
+The BeFS module is not a standard part of the linux kernel, so you must first
+enable support for experimental code under the "Code maturity level" menu.
+
+Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)",
+or something like that. Enable that option (it is fine to make it a module).
+
+Save your kernel configuration and then build your kernel.
+
+step 3.  Install
+
+See the kernel howto <http://www.linux.com/howto/Kernel-HOWTO.html> for
+instructions on this critical step.
+
+USING BFS
+=========
+To use the BeOS filesystem, use filesystem type 'befs'.
+
+ex)
+    mount -t befs /dev/fd0 /beos
+
+MOUNT OPTIONS
+=============
+uid=nnn        All files in the partition will be owned by user id nnn.
+gid=nnn	       All files in the partition will be in group nnn.
+iocharset=xxx  Use xxx as the name of the NLS translation table.
+debug          The driver will output debugging information to the syslog.
+
+HOW TO GET LASTEST VERSION
+==========================
+
+The latest version is currently available at:
+<http://befs-driver.sourceforge.net/>
+
+ANY KNOWN BUGS?
+===========
+As of Jan 20, 2002:
+	
+	None
+
+SPECIAL THANKS
+==============
+Dominic Giampalo ... Writing "Practical file system design with Be filesystem"
+Hiroyuki Yamada  ... Testing LinuxPPC.
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/devfs/ChangeLog linux-2.4.20/Documentation/filesystems/devfs/ChangeLog
--- linux-2.4.19/Documentation/filesystems/devfs/ChangeLog	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/devfs/ChangeLog	2002-10-04 00:41:11.000000000 +0000
@@ -1936,3 +1936,17 @@
 
 - Protected <scan_dir_for_removable> and <get_removable_partition>
   from changing directory contents
+===============================================================================
+Changes for patch v199.15
+
+- Switched to ISO C structure field initialisers
+
+- Switch to set_current_state() and move before add_wait_queue()
+
+- Updated README from master HTML file
+
+- Fixed devfs entry leak in <devfs_readdir> when *readdir fails
+===============================================================================
+Changes for patch v199.16
+
+- Fixed module unload race in <devfs_open>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/devfs/README linux-2.4.20/Documentation/filesystems/devfs/README
--- linux-2.4.19/Documentation/filesystems/devfs/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/devfs/README	2002-10-04 00:41:17.000000000 +0000
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-7-APR-2002
+21-JUL-2002
 
 
 Document languages:
@@ -788,6 +788,9 @@
 make sure the kernel does not mount devfs at boot time
 
 
+make sure you have a correct /dev/console entry in your
+root file-system (where your disc-based /dev lives)
+
 create the /dev-state directory
 
 
@@ -1288,9 +1291,10 @@
 
 SCSI Generic Devices
 
-All SCSI CD-ROMs are placed under /dev/sg. A similar naming
-scheme is used as for SCSI discs. A SCSI generic device with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
+The generic (aka. raw) interface for all SCSI devices are placed under
+/dev/sg. A similar naming scheme is used as for SCSI discs. A
+SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
+as:
 
 	/dev/sg/c1b2t3u4
 
@@ -1605,6 +1609,23 @@
 do that.
 
 
+I have extra or incorrect entries in /dev
+
+You may have stale entries in your dev-state area. Check for a
+RESTORE configuration line in your devfsd configuration
+(typically /etc/devfsd.conf). If you have this line, check
+the contents of the specified directory for stale entries. Remove
+any entries which are incorrect, then reboot.
+
+
+I get "Unable to open initial console" messages at boot
+
+This usually happens when you don't have devfs automounted onto
+/dev at boot time, and there is no valid
+/dev/console entry on your root file-system. Create a valid
+/dev/console device node.
+
+
 
 
 
@@ -1756,7 +1777,7 @@
 First, remember that no naming scheme will please everybody. You hate
 the scheme, others love it. Who's to say who's right and who's wrong?
 Ultimately, the person who writes the code gets to choose, and what
-exists now is a combination of the the choices made by the
+exists now is a combination of the choices made by the
 devfs author and the
 kernel maintainer (Linus).
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/isofs.txt linux-2.4.20/Documentation/filesystems/isofs.txt
--- linux-2.4.19/Documentation/filesystems/isofs.txt	1999-05-26 17:01:43.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/isofs.txt	2002-10-04 00:41:11.000000000 +0000
@@ -29,3 +29,10 @@
   unhide        Show hidden files.
   session=x     Select number of session on multisession CD
   sbsector=xxx  Session begins from sector xxx
+
+Recommended documents about ISO 9660 standard are located at:
+http://www.y-adagio.com/public/standards/iso_cdromr/tocont.htm
+ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf
+Quoting from the PDF "This 2nd Edition of Standard ECMA-119 is technically 
+identical with ISO 9660.", so it is a valid and gratis substitute of the
+official ISO specification.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/jfs.txt linux-2.4.20/Documentation/filesystems/jfs.txt
--- linux-2.4.19/Documentation/filesystems/jfs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/jfs.txt	2002-10-04 00:41:21.000000000 +0000
@@ -0,0 +1,43 @@
+IBM's Journaled File System (JFS) for Linux
+
+JFS Homepage:  http://oss.software.ibm.com/jfs/
+
+Team members
+------------
+Steve Best         sbest@us.ibm.com
+Dave Kleikamp      shaggy@austin.ibm.com  
+Barry Arndt        barndt@us.ibm.com
+Christoph Hellwig  hch@infradead.org
+
+The following mount options are supported:
+
+iocharset=name	Character set to use for converting from Unicode to
+		ASCII.  The default is compiled into the kernel as
+		CONFIG_NLS_DEFAULT.  Use iocharset=utf8 for UTF8
+		translations.  This requires CONFIG_NLS_UTF8 to be set
+		in the kernel .config file.
+
+resize=value	Resize the volume to <value> blocks.  JFS only supports
+		growing a volume, not shrinking it.  This option is only
+		valid during a remount, when the volume is mounted
+		read-write.  The resize keyword with no value will grow
+		the volume to the full size of the partition.
+
+JFS TODO list:
+
+Plans for our near term development items
+
+   - enhance support for logfile on dedicated partition
+   - get access control list functionality operational
+   - get extended attributes functionality operational
+
+Longer term work items
+
+   - implement defrag utility, for online defragmenting
+   - add quota support
+   - add support for block sizes (512,1024,2048)
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled
+"Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/proc.txt linux-2.4.20/Documentation/filesystems/proc.txt
--- linux-2.4.19/Documentation/filesystems/proc.txt	2001-11-07 22:39:36.000000000 +0000
+++ linux-2.4.20/Documentation/filesystems/proc.txt	2002-10-04 00:41:14.000000000 +0000
@@ -708,36 +708,26 @@
 used ones  is  far  behind,  you've  encountered  a peak in your usage of file
 handles and you don't need to increase the maximum.
 
-inode-state, inode-nr and inode-max
------------------------------------
-
-As with  file  handles, the kernel allocates the inode structures dynamically,
-but can't free them yet.
-
-The value  in  inode-max  denotes  the  maximum number of inode handlers. This
-value should  be  3 to 4 times larger than the value in file-max, since stdin,
-stdout, and  network  sockets also need an inode struct to handle them. If you
-regularly run out of inodes, you should increase this value.
+inode-state and inode-nr
+------------------------
 
 The file inode-nr contains the first two items from inode-state, so we'll skip
 to that file...
 
-inode-state contains  three  actual numbers and four dummy values. The numbers
-are nr_inodes, nr_free_inodes, and preshrink (in order of appearance).
+inode-state contains  two  actual numbers and five dummy values. The numbers
+are nr_inodes and nr_free_inodes (in order of appearance).
 
 nr_inodes
 ~~~~~~~~~
 
-Denotes the  number  of  inodes the system has allocated. This can be slightly
-more than inode-max because Linux allocates them one pageful at a time.
+Denotes the  number  of  inodes the system has allocated. This number will
+grow and shrink dynamically.
 
 nr_free_inodes
 --------------
 
-Represents the  number  of free inodes and preshrink is nonzero when nr_inodes
-is greater than inode-max and the system needs to prune the inode list instead
-of allocating more.
-
+Represents the  number of free inodes. Ie. The number of inuse inodes is
+(nr_inodes - nr_free_inodes).
 
 super-nr and super-max
 ----------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/ide.txt linux-2.4.20/Documentation/ide.txt
--- linux-2.4.19/Documentation/ide.txt	2001-09-07 16:28:38.000000000 +0000
+++ linux-2.4.20/Documentation/ide.txt	2002-10-04 00:41:11.000000000 +0000
@@ -306,6 +306,9 @@
  "idex=serialize"	: do not overlap operations on idex and ide(x^1)
  "idex=reset"		: reset interface after probe
  "idex=dma"		: automatically configure/use DMA if possible.
+ "idex=nohighio"	: don't use i/o to high memory addresses on this
+			 	interface. i/o to memory locations higher
+				than ~860MiB will be bounced.
 
  The following are valid ONLY on ide0,
  and the defaults for the base,ctl ports must not be altered.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/initrd.txt linux-2.4.20/Documentation/initrd.txt
--- linux-2.4.19/Documentation/initrd.txt	2000-12-04 01:48:18.000000000 +0000
+++ linux-2.4.20/Documentation/initrd.txt	2002-10-04 00:41:22.000000000 +0000
@@ -115,8 +115,12 @@
  1) make sure loopback block devices are configured into the kernel
  2) create an empty file system of the appropriate size, e.g.
     # dd if=/dev/zero of=initrd bs=300k count=1
-    # mke2fs -F -m0 initrd
+    # mke2fs -F -m0 -b 1024 initrd
     (if space is critical, you may want to use the Minix FS instead of Ext2)
+    (Note that due to a problem elsewhere in the kernel, you _must_ use a
+     1024-byte blocksize when creating your file system.  If any other
+     value is used, the kernel will be unable to mount the initrd at boot
+     time, causing a kernel panic.)
  3) mount the file system, e.g.
     # mount -t ext2 -o loop initrd /mnt
  4) create the console device (not necessary if using devfs, but it can't
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/isapnp.txt linux-2.4.20/Documentation/isapnp.txt
--- linux-2.4.19/Documentation/isapnp.txt	2001-04-18 18:49:11.000000000 +0000
+++ linux-2.4.20/Documentation/isapnp.txt	2002-10-04 00:41:30.000000000 +0000
@@ -29,6 +29,7 @@
 poke <reg> <value>	- poke configuration byte to selected register
 pokew <reg> <value>	- poke configuration word to selected register
 poked <reg> <value>	- poke configuration dword to selected register
+allow_dma0 <value>	- allow dma channel 0 during auto activation: 0=off, 1=on
 
 Explanation:
 	- variable <idx> begins with zero
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/isdn/README.HiSax linux-2.4.20/Documentation/isdn/README.HiSax
--- linux-2.4.19/Documentation/isdn/README.HiSax	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/isdn/README.HiSax	2002-10-04 00:41:11.000000000 +0000
@@ -41,9 +41,10 @@
 ELSA Quickstep 3000PCI
 ELSA PCMCIA
 ITK ix1-micro Rev.2
-Eicon.Diehl Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
-Eicon.Diehl Diva 2.01 ISA and PCI
-Eicon.Diehl Diva Piccola
+Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
+Eicon Diva 2.01 ISA and PCI
+Eicon Diva 2.02 PCI
+Eicon Diva Piccola
 ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D)
 Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
 PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink)
@@ -67,13 +68,14 @@
 HFC-PCI based cards
 Winbond W6692 based cards
 HFC-S+, HFC-SP/PCMCIA cards
+formula-n enternow
+Gerdes Power ISDN
 
 Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
       PCC-8: not tested yet
       Eicon.Diehl Diva U interface not tested
 
 If you know other passive cards with the Siemens chipset, please let me know.
-To use the PNP cards you need the isapnptools.
 You can combine any card, if there is no conflict between the resources
 (io, mem, irq).
 
@@ -89,8 +91,15 @@
 modules. It is included in the normal "make [menu]config" target at the
 kernel. Don't forget it, especially to select the right D-channel protocol.
 
-Please note: All PnP cards need to be configured with isapnp and will work
-only with the HiSax driver used as a module.
+Please note: In older versions of the HiSax driver, all PnP cards
+needed to be configured with isapnp and worked only with the HiSax
+driver used as a module.
+
+In the current version, HiSax will automatically use the in-kernel
+ISAPnP support, provided you selected it during kernel configuration
+(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters.
+
+The affected card types are: 4,7,12,14,19,27-30
 
 a) when built as a module
 -------------------------
@@ -191,6 +200,8 @@
    37	HFC 2BDS0 S+, SP         irq,io 
    38	NETspider U PCI card     none
    39	HFC 2BDS0 SP/PCMCIA      irq,io (set with cardmgr)
+   40   hotplug interface
+   41   Formula-n enter:now PCI  none
 
 At the moment IRQ sharing is only possible with PCI cards. Please make sure
 that your IRQ is free and enabled for ISA use.
@@ -216,6 +227,13 @@
                    (IO 1 (BASE 0x0180))
    modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180
 
+   In the current version of HiSax, you can instead simply use
+
+   modprobe hisax type=4 protocol=2
+
+   if you configured your kernel for ISAPnP. Don't run isapnp in
+   this case!
+
 6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and
    Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex
    modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000
@@ -296,7 +314,9 @@
    36	W6692 based PCI cards   none
    37	HFC 2BDS0 S+,SP/PCMCIA  ONLY WORKS AS A MODULE !
    38	NETspider U PCI card    none
-
+   39	HFC 2BDS0 SP/PCMCIA     ONLY WORKS AS A MODULE !
+   40   hotplug interface	ONLY WORKS AS A MODULE !
+   41   Formula-n enter:now PCI none
 
 Running the driver
 ------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/ldm.txt linux-2.4.20/Documentation/ldm.txt
--- linux-2.4.19/Documentation/ldm.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/ldm.txt	2002-10-04 00:41:17.000000000 +0000
@@ -0,0 +1,102 @@
+
+            LDM - Logical Disk Manager (Dynamic Disks)
+            ------------------------------------------
+
+Overview
+--------
+
+Windows 2000 and XP use a new partitioning scheme.  It is a complete
+replacement for the MSDOS style partitions.  It stores its information in a
+1MiB journalled database at the end of the physical disk.  The size of
+partitions is limited only by disk space.  The maximum number of partitions is
+nearly 2000.
+
+Any partitions created under the LDM are called "Dynamic Disks".  There are no
+longer any primary or extended partitions.  Normal MSDOS style partitions are
+now known as Basic Disks.
+
+If you wish to use Spanned, Striped, Mirrored or RAID 5 Volumes, you must use
+Dynamic Disks.  The journalling allows Windows to make changes to these
+partitions and filesystems without the need to reboot.
+
+Once the LDM driver has divided up the disk, you can use the MD driver to
+assemble any multi-partition volumes, e.g.  Stripes, RAID5.
+
+To prevent legacy applications from repartitioning the disk, the LDM creates a
+dummy MSDOS partition containing one disk-sized partition.
+
+
+Example
+-------
+
+Below we have a 50MiB disk, divided into seven partitions.
+N.B.  The missing 1MiB at the end of the disk is where the LDM database is
+      stored.
+
+  Device | Offset Bytes  Sectors  MiB | Size   Bytes  Sectors  MiB
+  -------+----------------------------+---------------------------
+  hda    |            0        0    0 |     52428800   102400   50
+  hda1   |     51380224   100352   49 |      1048576     2048    1
+  hda2   |        16384       32    0 |      6979584    13632    6
+  hda3   |      6995968    13664    6 |     10485760    20480   10
+  hda4   |     17481728    34144   16 |      4194304     8192    4
+  hda5   |     21676032    42336   20 |      5242880    10240    5
+  hda6   |     26918912    52576   25 |     10485760    20480   10
+  hda7   |     37404672    73056   35 |     13959168    27264   13
+
+The LDM Database may not store the partitions in the order that they appear on
+disk, but the driver will sort them.
+
+When Linux boots, you will see something like:
+
+Partition check:
+  hda: [LDM] hda1 hda2 hda3 hda4 hda5 hda6 hda7
+
+
+Compiling LDM Support
+---------------------
+
+To enable LDM, choose the following two options: 
+
+  "Advanced partition selection" CONFIG_PARTITION_ADVANCED
+  "Windows Logical Disk Manager (Dynamic Disk) support" CONFIG_LDM_PARTITION
+
+If you believe the driver isn't working as it should, you can enable the extra
+debugging code.  This will produce a LOT of output.  The option is:
+
+  "Windows LDM extra logging" CONFIG_LDM_DEBUG
+
+N.B. The partition code cannot be compiled as a module.
+
+As with all the partition code, if the driver doesn't see signs of its type of
+partition, it will pass control to another driver, so there is no harm in
+enabling it.
+
+If you have Dynamic Disks but don't enable the driver, then all you will see
+is a dummy MSDOS partition filling the whole disk.  You won't be able to mount
+any of the volumes on the disk.
+
+
+Booting
+-------
+
+If you enable LDM support, then lilo is capable of booting from any of the
+discovered partitions.  However, grub does not understand the LDM partitioning
+and cannot boot from a Dynamic Disk.
+
+
+More Documentation
+------------------
+
+There is an Overview of the LDM online together with complete Technical
+Documentation.  It can also be downloaded in html.
+
+  http://linux-ntfs.sourceforge.net/ldm/index.html
+  http://linux-ntfs.sourceforge.net/downloads.html
+
+If you have any LDM questions that aren't answered on the website, email me.
+
+Cheers,
+    FlatCap - Richard Russon
+    ldm@flatcap.org
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/00-INDEX linux-2.4.20/Documentation/networking/00-INDEX
--- linux-2.4.19/Documentation/networking/00-INDEX	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.20/Documentation/networking/00-INDEX	2002-10-04 00:41:13.000000000 +0000
@@ -44,6 +44,10 @@
 	- the Digi International RightSwitch SE-X Ethernet driver
 dmfe.txt
 	- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
+e100.txt
+	- info on Intel's EtherExpress PRO/100 line of 10/100 boards
+e1000.txt
+	- info on Intel's E1000 line of gigabit ethernet boards
 eql.txt
 	- serial IP load balancing
 ethertap.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/8139too.txt linux-2.4.20/Documentation/networking/8139too.txt
--- linux-2.4.19/Documentation/networking/8139too.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/networking/8139too.txt	2002-10-04 00:41:10.000000000 +0000
@@ -185,9 +185,22 @@
 Change History
 --------------
 
-Version 0.9.23 - January 16, 2002
+Version 0.9.26 - August 9, 2002
 
-* New, compile-time conditional for testing better RX reset
+* Fix MII ioctl phy id corruption.
+* Fix big-endian multicast bug.
+* Support register dumps via ethtool.
+* Fix several uses of 'len' after potential skb free, in dev->hard_start_xmit
+* Replace several "magic numbers" with their proper representation
+  constants in linux/mii.h.
+* Support ethtool media interface via generic kernel MII API
+* Export NIC-specific statistics via ethtool.
+* Proper support for RTL8139 rev K. (can be disabled via
+  compile-time conditional)
+* Add PCI ids for new 8139 boards.
+* Use ethernet crc via generic linux/crc32.h kernel API.
+* Better RX reset.  Old rx-reset method still available via
+  a compile-time conditional.
 * Only account specific RX errors if rx_status is !OK
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt linux-2.4.20/Documentation/networking/NAPI_HOWTO.txt
--- linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/networking/NAPI_HOWTO.txt	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,749 @@
+HISTORY:
+February 16/2002 -- revision 0.2.1:
+COR typo corrected
+February 10/2002 -- revision 0.2:
+some spell checking ;->
+January 12/2002 -- revision 0.1
+This is still work in progress so may change.
+To keep up to date please watch this space.
+
+Introduction to NAPI
+====================
+
+NAPI is a proven (www.cyberus.ca/~hadi/usenix-paper.tgz) technique
+to improve network performance on Linux. For more details please
+read that paper.
+NAPI provides a "inherent mitigation" which is bound by system capacity
+as can be seen from the following data collected by Robert on Gigabit 
+ethernet (e1000):
+
+ Psize    Ipps       Tput     Rxint     Txint    Done     Ndone
+ ---------------------------------------------------------------
+   60    890000     409362        17     27622        7     6823
+  128    758150     464364        21      9301       10     7738
+  256    445632     774646        42     15507       21    12906
+  512    232666     994445    241292     19147   241192     1062
+ 1024    119061    1000003    872519     19258   872511        0
+ 1440     85193    1000003    946576     19505   946569        0
+ 
+
+Legend:
+"Ipps" stands for input packets per second. 
+"Tput" == packets out of total 1M that made it out.
+"txint" == transmit completion interrupts seen
+"Done" == The number of times that the poll() managed to pull all
+packets out of the rx ring. Note from this that the lower the
+load the more we could clean up the rxring
+"Ndone" == is the converse of "Done". Note again, that the higher
+the load the more times we couldnt clean up the rxring.
+
+Observe that:
+when the NIC receives 890Kpackets/sec only 17 rx interrupts are generated. 
+The system cant handle the processing at 1 interrupt/packet at that load level. 
+At lower rates on the other hand, rx interrupts go up and therefore the
+interrupt/packet ratio goes up (as observable from that table). So there is
+possibility that under low enough input, you get one poll call for each
+input packet caused by a single interrupt each time. And if the system 
+cant handle interrupt per packet ratio of 1, then it will just have to 
+chug along ....
+
+
+0) Prerequisites:
+==================
+A driver MAY continue using the old 2.4 technique for interfacing
+to the network stack and not benefit from the NAPI changes.
+NAPI additions to the kernel do not break backward compatibility.
+NAPI, however, requires the following features to be available:
+
+A) DMA ring or enough RAM to store packets in software devices.
+
+B) Ability to turn off interrupts or maybe events that send packets up 
+the stack.
+
+NAPI processes packet events in what is known as dev->poll() method.
+Typically, only packet receive events are processed in dev->poll(). 
+The rest of the events MAY be processed by the regular interrupt handler 
+to reduce processing latency (justified also because there are not that 
+many of them).
+Note, however, NAPI does not enforce that dev->poll() only processes 
+receive events. 
+Tests with the tulip driver indicated slightly increased latency if
+all of the interrupt handler is moved to dev->poll(). Also MII handling
+gets a little trickier.
+The example used in this document is to move the receive processing only
+to dev->poll(); this is shown with the patch for the tulip driver.
+For an example of code that moves all the interrupt driver to 
+dev->poll() look at the ported e1000 code.
+
+There are caveats that might force you to go with moving everything to 
+dev->poll(). Different NICs work differently depending on their status/event 
+acknowledgement setup. 
+There are two types of event register ACK mechanisms.
+	I)  what is known as Clear-on-read (COR).
+	when you read the status/event register, it clears everything!
+	The natsemi and sunbmac NICs are known to do this.
+	In this case your only choice is to move all to dev->poll()
+
+	II) Clear-on-write (COW)
+	 i) you clear the status by writting a 1 in the bit-location you want.
+		These are the majority of the NICs and work the best with NAPI.
+		Put only receive events in dev->poll(); leave the rest in
+		the old interrupt handler.
+	 ii) whatever you write in the status register clears every thing ;->
+		Cant seem to find any supported by Linux which do this. If
+		someone knows such a chip email us please.
+		Move all to dev->poll()
+
+C) Ability to detect new work correctly.
+NAPI works by shutting down event interrupts when theres work and
+turning them on when theres none. 
+New packets might show up in the small window while interrupts were being 
+re-enabled (refer to appendix 2).  A packet might sneak in during the period 
+we are enabling interrupts. We only get to know about such a packet when the 
+next new packet arrives and generates an interrupt. 
+Essentially, there is a small window of opportunity for a race condition
+which for clarity we'll refer to as the "rotting packet".
+
+This is a very important topic and appendix 2 is dedicated for more 
+discussion.
+
+Locking rules and environmental guarantees
+==========================================
+
+-Guarantee: Only one CPU at any time can call dev->poll(); this is because
+only one CPU can pick the initial interrupt and hence the initial
+netif_rx_schedule(dev);
+- The core layer invokes devices to send packets in a round robin format.
+This implies receive is totaly lockless because of the guarantee only that 
+one CPU is executing it.
+-  contention can only be the result of some other CPU accessing the rx
+ring. This happens only in close() and suspend() (when these methods
+try to clean the rx ring); 
+****guarantee: driver authors need not worry about this; synchronization 
+is taken care for them by the top net layer.
+-local interrupts are enabled (if you dont move all to dev->poll()). For 
+example link/MII and txcomplete continue functioning just same old way. 
+This improves the latency of processing these events. It is also assumed that 
+the receive interrupt is the largest cause of noise. Note this might not 
+always be true. 
+[according to Manfred Spraul, the winbond insists on sending one 
+txmitcomplete interrupt for each packet (although this can be mitigated)].
+For these broken drivers, move all to dev->poll().
+
+For the rest of this text, we'll assume that dev->poll() only
+processes receive events.
+
+new methods introduce by NAPI
+=============================
+
+a) netif_rx_schedule(dev)
+Called by an IRQ handler to schedule a poll for device
+
+b) netif_rx_schedule_prep(dev)
+puts the device in a state which allows for it to be added to the
+CPU polling list if it is up and running. You can look at this as
+the first half of  netif_rx_schedule(dev) above; the second half
+being c) below.
+
+c) __netif_rx_schedule(dev)
+Add device to the poll list for this CPU; assuming that _prep above
+has already been called and returned 1.
+
+d) netif_rx_reschedule(dev, undo)
+Called to reschedule polling for device specifically for some
+deficient hardware. Read Appendix 2 for more details.
+
+e) netif_rx_complete(dev)
+
+Remove interface from the CPU poll list: it must be in the poll list
+on current cpu. This primitive is called by dev->poll(), when
+it completes its work. The device cannot be out of poll list at this
+call, if it is then clearly it is a BUG(). You'll know ;->
+
+All these above nethods are used below. So keep reading for clarity.
+
+Device driver changes to be made when porting NAPI
+==================================================
+
+Below we describe what kind of changes are required for NAPI to work.
+
+1) introduction of dev->poll() method 
+=====================================
+
+This is the method that is invoked by the network core when it requests
+for new packets from the driver. A driver is allowed to send upto
+dev->quota packets by the current CPU before yielding to the network
+subsystem (so other devices can also get opportunity to send to the stack).
+
+dev->poll() prototype looks as follows:
+int my_poll(struct net_device *dev, int *budget)
+
+budget is the remaining number of packets the network subsystem on the
+current CPU can send up the stack before yielding to other system tasks.
+*Each driver is responsible for decrementing budget by the total number of
+packets sent.
+	Total number of packets cannot exceed dev->quota.
+
+dev->poll() method is invoked by the top layer, the driver just sends if it 
+can to the stack the packet quantity requested.
+
+more on dev->poll() below after the interrupt changes are explained.
+
+2) registering dev->poll() method
+===================================
+
+dev->poll should be set in the dev->probe() method. 
+e.g:
+dev->open = my_open;
+.
+.
+/* two new additions */
+/* first register my poll method */
+dev->poll = my_poll;
+/* next register my weight/quanta; can be overriden in /proc */
+dev->weight = 16;
+.
+.
+dev->stop = my_close;
+
+
+
+3) scheduling dev->poll()
+=============================
+This involves modifying the interrupt handler and the code
+path which takes the packet off the NIC and sends them to the 
+stack.
+
+it's important at this point to introduce the classical D Becker 
+interrupt processor:
+
+------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+	int work_count = my_work_count;
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling()
+        
+	do {
+		acknowledge_ints_ASAP();
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+		
+		if (status & rx_interrupt) {
+			receive_packets(dev);
+		}
+
+		if (status & rx_nobufs) {
+			make_rx_buffs_avail();
+		}
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+	} while (!(status & error) || more_work_to_be_done);
+
+}
+
+----------------------------------------------------------------------
+
+We now change this to what is shown below to NAPI-enable it:
+
+----------------------------------------------------------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling();
+        
+	do {
+/************************ start note *********************************/		
+		acknowledge_ints_ASAP();  // dont ack rx and rxnobuff here
+/************************ end note *********************************/		
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+/************************ start note *********************************/		
+		if (status & rx_interrupt || (status & rx_nobuffs)) {
+			if (netif_rx_schedule_prep(dev)) {
+
+				/* disable interrupts caused 
+			         *	by arriving packets */
+				disable_rx_and_rxnobuff_ints();
+				/* tell system we have work to be done. */
+				__netif_rx_schedule(dev);
+			} else {
+				printk("driver bug! interrupt while in poll\n");
+				/* FIX by disabling interrupts  */
+				disable_rx_and_rxnobuff_ints();
+			}
+		}
+/************************ end note note *********************************/		
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+/************************ start note *********************************/		
+	} while (!(status & error) || more_work_to_be_done(status));
+/************************ end note note *********************************/		
+
+}
+
+---------------------------------------------------------------------
+
+
+We note several things from above:
+
+I) Any interrupt source which is caused by arriving packets is now
+turned off when it occurs. Depending on the hardware, there could be
+several reasons that arriving packets would cause interrupts; these are the
+interrupt sources we wish to avoid. The two common ones are a) a packet 
+arriving (rxint) b) a packet arriving and finding no DMA buffers available
+(rxnobuff) .
+This means also acknowledge_ints_ASAP() will not clear the status
+register for those two items above; clearing is done in the place where 
+proper work is done within NAPI; at the poll() and refill_rx_ring() 
+discussed further below.
+netif_rx_schedule_prep() returns 1 if device is in running state and
+gets successfully added to the core poll list. If we get a zero value
+we can _almost_ assume are already added to the list (instead of not running. 
+Logic based on the fact that you shouldnt get interrupt if not running)
+We rectify this by disabling rx and rxnobuf interrupts.
+
+II) that receive_packets(dev) and make_rx_buffs_avail() may have dissapeared.
+These functionalities are still around actually......
+
+infact, receive_packets(dev) is very close to my_poll() and 
+make_rx_buffs_avail() is invoked from my_poll()
+
+4) converting receive_packets() to dev->poll()
+===============================================
+
+We need to convert the classical D Becker receive_packets(dev) to my_poll()
+
+First the typical receive_packets() below:
+-------------------------------------------------------------------
+
+/* this is called by interrupt handler */
+static void receive_packets (struct net_device *dev)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_RING_SIZE;
+	int received = 0;
+	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+                if (--rx_work_limit < 0)
+                        break;
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+			netif_rx (skb);
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... some just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring();
+	.
+	.
+
+}
+-------------------------------------------------------------------
+We change it to a new one below; note the additional parameter in
+the call.
+
+-------------------------------------------------------------------
+
+/* this is called by the network core */
+static void my_poll (struct net_device *dev, int *budget)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_BUF_LEN;
+	/* maximum packets to send to the stack */
+/************************ note note *********************************/		
+	int rx_work_limit = dev->quota;
+
+/************************ end note note *********************************/		
+    do {  // outer beggining loop starts here
+
+	clear_rx_status_register_bit();
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+/************************ note note *********************************/		
+                if (--rx_work_limit < 0) { /* we got packets, but no quota */
+			/* store current ring pointer state */
+			tp->cur_rx = cur_rx;
+
+			/* Refill the Rx ring buffers if they are needed */
+			refill_rx_ring(dev);
+                        goto not_done;
+		}
+/**********************  end note **********************************/
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+/************************ note note *********************************/		
+			netif_receive_skb (skb);
+/**********************  end note **********************************/
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... common is just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring(dev);
+	
+	/* no packets on ring; but new ones can arrive since we last 
+	   checked  */
+	status = read_interrupt_status_reg();
+	if (rx status is not set) {
+                        /* If something arrives in this narrow window,
+			an interrupt will be generated */
+                        goto done;
+	}
+	/* done! at least thats what it looks like ;->
+	if new packets came in after our last check on status bits
+	they'll be caught by the while check and we go back and clear them 
+	since we havent exceeded our quota */
+    } while (rx_status_is_set); 
+
+done:
+
+/************************ note note *********************************/		
+        dev->quota -= received;
+        *budget -= received;
+
+        /* If RX ring is not full we are out of memory. */
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                goto oom;
+
+	/* we are happy/done, no more packets on ring; put us back
+	to where we can start processing interrupts again */
+        netif_rx_complete(dev);
+	enable_rx_and_rxnobuf_ints();
+
+       /* The last op happens after poll completion. Which means the following:
+        * 1. it can race with disabling irqs in irq handler (which are done to 
+	* schedule polls)
+        * 2. it can race with dis/enabling irqs in other poll threads
+        * 3. if an irq raised after the begining of the outer  beginning 
+        * loop(marked in the code above), it will be immediately
+        * triggered here.
+        *
+        * Summarizing: the logic may results in some redundant irqs both
+        * due to races in masking and due to too late acking of already
+        * processed irqs. The good news: no events are ever lost.
+        */
+
+        return 0;   /* done */
+
+not_done:
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                refill_rx_ring(dev);
+
+        if (!received) {
+                printk("received==0\n");
+                received = 1;
+        }
+        dev->quota -= received;
+        *budget -= received;
+        return 1;  /* not_done */
+
+oom:
+        /* Start timer, stop polling, but do not enable rx interrupts. */
+	start_poll_timer(dev);
+        return 0;  /* we'll take it from here so tell core "done"*/
+
+/************************ End note note *********************************/		
+}
+-------------------------------------------------------------------
+
+From above we note that:
+0) rx_work_limit = dev->quota 
+1) refill_rx_ring() is in charge of clearing the bit for rxnobuff when
+it does the work.
+2) We have a done and not_done state.
+3) instead of netif_rx() we call netif_receive_skb() to pass the skb.
+4) we have a new way of handling oom condition
+5) A new outer for (;;) loop has been added. This serves the purpose of
+ensuring that if a new packet has come in, after we are all set and done,
+and we have not exceeded our quota that we continue sending packets up.
+ 
+
+-----------------------------------------------------------
+Poll timer code will need to do the following:
+
+a) 
+
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) 
+                refill_rx_ring(dev);
+
+        /* If RX ring is not full we are still out of memory.
+	   Restart the timer again. Else we re-add ourselves 
+           to the master poll list.
+         */
+
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                restart_timer();
+
+	else netif_rx_schedule(dev);  /* we are back on the poll list */
+	
+5) dev->close() and dev->suspend() issues
+==========================================
+The driver writter neednt worry about this. The top net layer takes
+care of it.
+
+6) Adding new Stats to /proc 
+=============================
+In order to debug some of the new features, we introduce new stats
+that need to be collected.
+TODO: Fill this later.
+
+APPENDIX 1: discussion on using ethernet HW FC
+==============================================
+Most chips with FC only send a pause packet when they run out of Rx buffers.
+Since packets are pulled off the DMA ring by a softirq in NAPI,
+if the system is slow in grabbing them and we have a high input
+rate (faster than the system's capacity to remove packets), then theoretically
+there will only be one rx interrupt for all packets during a given packetstorm.
+Under low load, we might have a single interrupt per packet.
+FC should be programmed to apply in the case when the system cant pull out
+packets fast enough i.e send a pause only when you run out of rx buffers.
+Note FC in itself is a good solution but we have found it to not be
+much of a commodity feature (both in NICs and switches) and hence falls
+under the same category as using NIC based mitigation. Also experiments
+indicate that its much harder to resolve the resource allocation
+issue (aka lazy receiving that NAPI offers) and hence quantify its usefullness
+proved harder. In any case, FC works even better with NAPI but is not
+necessary.
+
+
+APPENDIX 2: the "rotting packet" race-window avoidance scheme 
+=============================================================
+
+There are two types of associations seen here
+
+1) status/int which honors level triggered IRQ
+
+If a status bit for receive or rxnobuff is set and the corresponding 
+interrupt-enable bit is not on, then no interrupts will be generated. However, 
+as soon as the "interrupt-enable" bit is unmasked, an immediate interrupt is 
+generated.  [assuming the status bit was not turned off].
+Generally the concept of level triggered IRQs in association with a status and
+interrupt-enable CSR register set is used to avoid the race.
+
+If we take the example of the tulip:
+"pending work" is indicated by the status bit(CSR5 in tulip).
+the corresponding interrupt bit (CSR7 in tulip) might be turned off (but
+the CSR5 will continue to be turned on with new packet arrivals even if
+we clear it the first time)
+Very important is the fact that if we turn on the interrupt bit on when
+status is set that an immediate irq is triggered.
+ 
+If we cleared the rx ring and proclaimed there was "no more work
+to be done" and then went on to do a few other things;  then when we enable
+interrupts, there is a possibility that a new packet might sneak in during
+this phase. It helps to look at the pseudo code for the tulip poll
+routine:
+
+--------------------------
+        do {
+                ACK;
+                while (ring_is_not_empty()) {
+                        work-work-work
+                        if quota is exceeded: exit, no touching irq status/mask
+                }
+                /* No packets, but new can arrive while we are doing this*/
+                CSR5 := read
+                if (CSR5 is not set) {
+                        /* If something arrives in this narrow window here,
+                        *  where the comments are ;-> irq will be generated */
+                        unmask irqs;
+                        exit poll;
+                }
+        } while (rx_status_is_set);
+------------------------
+
+CSR5 bit of interest is only the rx status. 
+If you look at the last if statement: 
+you just finished grabbing all the packets from the rx ring .. you check if
+status bit says theres more packets just in ... it says none; you then
+enable rx interrupts again; if a new packet just came in during this check,
+we are counting that CSR5 will be set in that small window of opportunity
+and that by re-enabling interrupts, we would actually triger an interrupt
+to register the new packet for processing.
+
+[The above description nay be very verbose, if you have better wording 
+that will make this more understandable, please suggest it.]
+
+2) non-capable hardware
+
+These do not generally respect level triggered IRQs. Normally,
+irqs may be lost while being masked and the only way to leave poll is to do
+a double check for new input after netif_rx_complete() is invoked
+and re-enable polling (after seeing this new input).
+
+Sample code:
+
+---------
+	.
+	.
+restart_poll:
+	while (ring_is_not_empty()) {
+		work-work-work
+		if quota is exceeded: exit, not touching irq status/mask
+	}
+	.
+	.
+	.
+	enable_rx_interrupts()
+	netif_rx_complete(dev);
+	if (ring_has_new_packet() && netif_rx_reschedule(dev, received)) {
+		disable_rx_and_rxnobufs()
+		goto restart_poll
+	} while (rx_status_is_set);
+---------
+		
+Basically netif_rx_complete() removes us from the poll list, but because a
+new packet which will never be caught due to the possibility of a race
+might come in, we attempt to re-add ourselves to the poll list. 
+
+
+
+--------------------------------------------------------------------
+
+relevant sites:
+==================
+ftp://robur.slu.se/pub/Linux/net-development/NAPI/
+
+
+--------------------------------------------------------------------
+TODO: Write net-skeleton.c driver.
+-------------------------------------------------------------
+
+Authors:
+========
+Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Jamal Hadi Salim <hadi@cyberus.ca>
+Robert Olsson <Robert.Olsson@data.slu.se>
+
+Acknowledgements:
+================
+People who made this document better:
+
+Lennert Buytenhek <buytenh@gnu.org>
+Andrew Morton  <akpm@zip.com.au>
+Manfred Spraul <manfred@colorfullife.com>
+Donald Becker <becker@scyld.com>
+Jeff Garzik 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/dl2k.txt linux-2.4.20/Documentation/networking/dl2k.txt
--- linux-2.4.19/Documentation/networking/dl2k.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/networking/dl2k.txt	2002-10-04 00:41:11.000000000 +0000
@@ -1,7 +1,7 @@
 
     D-Link DL2000-based Gigabit Ethernet Adapter Installation
     for Linux
-    Jan 29, 2002
+    May 23, 2002
 
 Contents
 ========
@@ -202,7 +202,7 @@
 				  1000mbps_fd and 1000mbps_hd types are only
 				  available for fiber adapter.
 
-vlan=[0|1]			- Specifies the VLAN ID. If vlan=0, the
+vlan=n				- Specifies the VLAN ID. If vlan=0, the
 				  Virtual Local Area Network (VLAN) function is
 				  disable.
 
@@ -211,24 +211,34 @@
 				  function is disabled.
 				  Jumbo frame usually improve the performance
 				  int gigabit.
+				  This feature need jumbo frame compatible 
+				  remote.
 				  
-rx_coalesce=n			- Rx frame count each interrupt.
-rx_timeout=n			- Rx DMA wait time for an interrupt. Proper 
-				  values of rx_coalesce and rx_timeout bring 
-				  a conspicuous performance in the fast machine.
-				  Ex. rx_coalesce=5 and rx_timeout=750 
-
-tx_coalesce=n			- Tx transmit count each TxComp interrupt.
-				  Setting value larger than 1 will improve 
-				  performance, but this is possible to lower 
-				  stability in slow UP machines. By default, 
-				  tx_coalesce=1. (dl2k)
+rx_coalesce=m			- Number of rx frame handled each interrupt.
+rx_timeout=n			- Rx DMA wait time for an interrupt. 
+				  If set rx_coalesce > 0, hardware only assert 
+				  an interrupt for m frames. Hardware won't 
+				  assert rx interrupt until m frames received or
+				  reach timeout of n * 640 nano seconds. 
+				  Set proper rx_coalesce and rx_timeout can 
+				  reduce congestion collapse and overload which
+				  has been a bottlenect for high speed network.
 				  
-tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=1, 
-				  the Tx flow control enable.
+				  For example, rx_coalesce=10 rx_timeout=800.
+				  that is, hardware assert only 1 interrupt 
+				  for 10 frames received or timeout of 512 us. 
+
+tx_coalesce=n			- Number of tx frame handled each interrupt.
+				  Set n > 1 can reduce the interrupts 
+				  congestion usually lower performance of
+				  high speed network card. Default is 16.
 				  
-rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=1, 
-				  the Rx flow control enable.
+tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=0, 
+				  the Tx flow control disable else driver
+				  autodetect.
+rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=0, 
+				  the Rx flow control enable else driver
+				  autodetect.
 
 
 Configuration Script Sample
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e100.txt linux-2.4.20/Documentation/networking/e100.txt
--- linux-2.4.19/Documentation/networking/e100.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/networking/e100.txt	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,272 @@
+Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
+==============================================================
+
+April 9, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- CPU Cycle Saver
+- Additional Configurations
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
+Adapters, version 2.0.x.  This driver includes support for Itanium(TM)-based 
+systems.
+
+New for this release:
+
+   - Additional ethtool functionality, including link status test and EEPROM 
+     read/write. A third-party application can use the ethtool interface to 
+     get and set driver parameters.
+
+   - Support for Zero copy on 82550-based adapters. This feature provides 
+     faster data throughput and significant CPU usage improvement in systems 
+     that use the relevant system call (sendfile(2)).
+
+   - Support for large MTU-enabling interface (1504 bytes) with kernel's 
+     VLAN module
+
+   - Support for polling on RX
+
+   - Support for Wake On LAN* on 82550 and 82559-based adapters
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers 
+in this release:
+
+Controller  Adapter Name                            Board IDs
+----------  ------------                            ---------
+
+82558       PRO/100+ PCI Adapter                    668081-xxx, 689661-xxx
+
+82558       PRO/100+ Management Adapter             691334-xxx, 701738-xxx,
+                                                    721383-xxx
+
+82558       PRO/100+ Dual Port Server Adapter       714303-xxx, 711269-xxx, 
+                                                    A28276-xxx
+
+82558       PRO/100+ PCI Server Adapter             710550-xxx
+
+82550       PRO/100 S Server Adapter                752438-xxx (82550)
+82559                                               A56831-xxx, A10563-xxx,
+                                                    A12171-xxx, A12321-xxx, 
+                                                    A12320-xxx, A12170-xxx
+                                                    748568-xxx (82559)
+                                                    748565-xxx (82559)
+
+
+82550       PRO/100 S Desktop Adapter               751767-xxx (82550)
+82559                                               748592-xxx, A12167-xxx, 
+                                                    A12318-xxx, A12317-xxx, 
+                                                    A12165-xxx
+                                                    748569-xxx (82559)
+
+
+
+82559       PRO/100+ Server Adapter                 729757-xxx
+
+82559       PRO/100 S Management Adapter            748566-xxx, 748564-xxx
+
+82550       PRO/100 S Dual Port Server Adapter      A56831-xxx
+
+82551       PRO/100 M Desktop Adapter               A80897-xxx
+
+            PRO/100 S Advanced Management Adapter   747842-xxx, 745171-xxx
+
+CNR         PRO/100 VE Desktop Adapter              A10386-xxx, A10725-xxx, 
+                                                    A23801-xxx, A19716-xxx
+
+
+            PRO/100 VM Desktop Adapter              A14323-xxx, A19725-xxx, 
+                                                    A23801-xxx, A22220-xxx, 
+                                                    A23796-xxx
+   
+
+To verify that your adapter is supported, find the board ID number on the 
+adapter. Look for a label that has a barcode and a number in the format 
+123456-001 (six digits hyphen three digits). Match this to the list of 
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter & 
+Driver ID Guide at:
+
+  http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel PRO/100 network driver for Linux, see:
+
+  http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+The following parameters are used by entering them on the command line with 
+the modprobe or insmod command. For example, with two Intel PRO/100 PCI 
+adapters, entering:
+	
+     modprobe e100 TxDescriptors=32,128
+
+loads the e100 driver with 32 TX resources for the first adapter and 128 TX 
+resources for the second adapter. This configuration favors the second 
+adapter. The driver supports up to 16 network adapters concurrently.
+
+NOTE: Giving any command line option the value "-1" causes the driver to use 
+      the appropriate default value for that option, as if no value was 
+      specified.
+
+
+BundleMax
+Valid Range: 0x1-0xFFFF
+Default Value: 6
+   This parameter holds the maximum number of packets in a bundle. Suggested 
+   values range from 2 to 10. See "CPU Cycle Saver."
+
+BundleSmallFr
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   The value 1 (on) causes small packets (less than 128 bytes) to be bundled. 
+   See "CPU Cycle Saver."
+
+e100_speed_duplex
+Valid Range: 0-4 (1=10half;2=10full;3=100half;4=100full)
+Default Value: 0
+   The default value of 0 is set to auto-negotiate if the link partner is set
+   to auto-negotiate. If the link partner is forced, e100_speed_duplex 
+   defaults to half-duplex. 
+   Example usage: insmod e100.o e100_speed_duplex=4,4 (for two adapters)
+
+flow_control
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   This parameter controls the automatic generation(Tx) and response(Rx) to 
+   Ethernet PAUSE frames. flow_control should NOT be set to 1 when the e100 
+   adapter is connected to an interface that does not support Ethernet PAUSE 
+   frames and when the e100_speed_duplex parameter is NOT set to zero. 
+
+IntDelay
+Valid Range: 0-0xFFFF (0=off)
+Default Value: 1536
+   This parameter holds the number of time units (in adapter terminology)
+   until the adapter generates an interrupt. The recommended value for 
+   IntDelay is 0x600 (upon initialization). Suggested values range from 
+   0x200h to 0x800. See "CPU Cycle Saver."
+
+IFS
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+  Inter Frame Spacing (IFS) aims to reduce the number of Ethernet frame
+  collisions by altering the time between frame transmissions. When IFS is 
+  enabled the driver tries to find an optimal IFS value. However, some 
+  switches function better when IFS is disabled.
+
+PollingMaxWork
+Valid Range: 1-1024 (max number of RxDescriptors)
+Default Value: Specified number of RxDescriptors
+  This value specifies the maximum number of receive packets that are 
+  processed on a single polling call. This parameter is invalid if 
+  RxCongestionControl is set to 0.
+
+RxCongestionControl
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+  1 enables polling mode. When the link is congested, the driver can decide 
+  to handle received packets by polling them, instead of waiting until 
+  interrupts occur.
+
+RxDescriptors
+Valid Range: 8-1024
+Default Value: 64
+   This parameter defines the number of receive descriptors allocated by 
+   the driver. Increasing this value allows the driver to buffer more 
+   incoming packets before the driver is required to service an interrupt. 
+   The maximum value for Itanium-based systems is 64.
+
+TxDescriptors
+Valid Range: 19-1024
+Default Value: 64
+   This value is the number of transmit descriptors allocated by the driver. 
+   Increasing this value allows the protocol stack to queue more transmits at
+   the driver level. The maximum value for Itanium-based systems is 64.
+
+ucode (not available for 82557-based adapters)
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0 for 82558-based adapters
+               1 for 82559(and higher)-based adapters
+   On uploads the micro code to the adapter, which enables CPU Cycle Saver. 
+   See the section "CPU Cycle Saver" below.
+   Example usage: insmod e100.o ucode=0  (does not reduce CPU usage)
+
+XsumRX
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+   On allows Rx checksum offloading for TCP/UDP packets. Requires that the 
+   hardware support this feature.
+
+
+CPU Cycle Saver
+================
+
+CPU Cycle Saver reduces CPU utilization by reducing the number of interrupts 
+that the adapter generates.
+
+When CPU Cycle Saver is turned off, the adapter generates one interrupt for 
+every frame that is received. This means that the operating system stops what
+it is doing and switches to the network driver in order to process the 
+receive.
+
+When CPU Cycle Saver is on, the adapter does not generate an interrupt for 
+every frame it receives. Instead, it waits until it receives several frames 
+before generating an interrupt. This reduces the amount of time spent 
+switching to and from the driver. 
+
+CPU Cycle Saver consists of these arguments: IntDelay, BundleMax and 
+BundleSmallFr. When IntDelay is increased, the adapter waits longer for 
+frames to arrive before generating the interrupt. By increasing BundleMax, 
+the network adapter waits for the number of frames specified to arrive before 
+generating the interrupt. When BundleSmallFr is disabled, the adapter does 
+not bundle packets that are smaller than 128 bytes. Such small packets are 
+often, but not always, control packets that are better served immediately.
+
+For most users, it is recommended that CPU Cycle Saver be used with the 
+default values specified in the Command Line Parameters section. However, in 
+some cases, performance problems may occur with CPU Cycle Saver. If such 
+problems are observed, we recommend turning off this feature by setting 
+ucode=0.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to 
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement 
+between you ('Licensee') and Intel. Do not use or load this software or any 
+associated materials (collectively, the 'Software') until you have carefully 
+read the full terms and conditions of the LICENSE located in this software 
+package. By loading or using the Software, you agree to the terms of this 
+Agreement. If you do not agree with the terms of this Agreement, do not 
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e1000.txt linux-2.4.20/Documentation/networking/e1000.txt
--- linux-2.4.19/Documentation/networking/e1000.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/networking/e1000.txt	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,304 @@
+Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
+===============================================================
+
+August 6, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- Speed and Duplex Configuration
+- Additional Configurations
+- Known Issues
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
+of Adapters, version 4.3.x.  This driver includes support for 
+Itanium(TM)-based systems.
+
+This release version includes the following:
+
+   - Support for the ethtool 1.6 interface. A third-party application can use
+     the ethtool interface to get and set driver parameters.
+
+   - Zero copy. This feature provides faster data throughput. Enabled by
+     default in supporting kernels. It is not supported on the Intel(R)
+     PRO/1000 Gigabit Server Adapter.
+
+New features include:
+
+   - Support for the 82545 and 82546-based adapters listed below
+
+   - Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
+     based adapters
+
+   - Adaptive IFS for increased performance at half duplex
+
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers in this
+release:
+
+   Controller  Adapter Name                         Board IDs
+   ----------  ------------                         ---------
+
+   82542       PRO/1000 Gigabit Server Adapter      700262-xxx, 717037-xxx
+
+   82543       PRO/1000 F Server Adapter            738640-xxx, A38888-xxx
+
+   82543       PRO/1000 T Server Adapter            A19845-xxx, A33948-xxx
+
+   82544       PRO/1000 XT Server Adapter           A51580-xxx
+
+   82544       PRO/1000 XF Server Adapter           A50484-xxx
+
+   82544       PRO/1000 T Desktop Adapter           A62947-xxx
+
+   82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+
+   82545       PRO/1000 MT Server Adapter           A92165-xxx
+
+   82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
+
+   82545       PRO/1000 MF Server Adapter           A91622-xxx
+
+   82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
+
+   82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
+
+
+To verify your Intel adapter is supported, find the board ID number on the
+adapter. Look for a label that has a barcode and a number in the format of
+123456-001 (six digits hyphen three digits). Match this to the list of
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+    http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel network drivers for Linux, go to:
+
+    http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+If the driver is built as a module, the following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command. 
+For example, with two PRO/1000 PCI adapters, entering:
+
+    insmod e1000 TxDescriptors=80,128
+
+loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
+resources for the second adapter.
+
+For more information about the AutoNeg, Duplex, and Speed parameters, see the
+"Speed and Duplex Configuration" section in this document.
+
+
+AutoNeg (adapters using copper connections only)
+Valid Range: 0x01-0x0F, 0x20-0x2F
+Default Value: 0x2F
+    This parameter is a bit mask that specifies which speed and duplex
+    settings the board advertises. When this parameter is used, the Speed and
+    Duplex parameters must not be specified.  
+
+Duplex (adapters using copper connections only)
+Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
+Default Value: 0
+    Defines the direction in which data is allowed to flow. Can by either one 
+    or two-directional. If both Duplex and the link partner are set to auto-
+    negotiate, the board auto-detects the correct duplex. If the link partner
+    is forced (either full or half), Duplex defaults to half-duplex.
+
+FlowControl
+Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
+Default: Read flow control settings from the EEPROM
+    This parameter controls the automatic generation(Tx) and response(Rx) to 
+    Ethernet PAUSE frames.
+
+RxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 80
+    This value is the number of receive descriptors allocated by the driver. 
+    Increasing this value allows the driver to buffer more incoming packets. 
+    Each descriptor is 16 bytes.  A receive buffer is also allocated for each
+    descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending 
+    on the MTU setting. The maximum MTU size is 16110.
+
+    NOTE: MTU designates the frame size. It only needs to be set for Jumbo 
+          Frames.
+
+RxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 0 (82542, 82543, and 82544-based adapters)
+               128 (82540, 82545, and 82546-based adapters)
+    This value delays the generation of receive interrupts in units of 1.024 
+    microseconds.  Receive interrupt reduction can improve CPU efficiency if 
+    properly tuned for specific network traffic. Increasing this value adds 
+    extra latency to frame reception and can end up decreasing the throughput 
+    of TCP traffic. If the system is reporting dropped receives, this value 
+    may be set too high, causing the driver to run out of available receive 
+    descriptors.
+
+    CAUTION: When setting RxIntDelay to a value other than 0, adapters based 
+             on the Intel 82543 and 82544 LAN controllers may hang (stop 
+             transmitting) under certain network conditions. If this occurs a
+             message is logged in the system event log. In addition, the 
+             controller is automatically reset, restoring the network 
+             connection. To eliminate the potential for the hang ensure that 
+             RxIntDelay is set to 0.
+
+RxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+Valid Range: 0-65535 (0=off)
+Default Value: 128
+    This value, in units of 1.024 microseconds, limits the delay in which a 
+    transmit interrupt is generated. Useful only if RxIntDelay is non-zero, 
+    this value ensures that an interrupt is generated after the initial 
+    packet is received within the set amount of time.  Proper tuning,
+    along with RxIntDelay, may improve traffic throughput in specific network
+    conditions.
+
+Speed (adapters using copper connections only)
+Valid Settings: 0, 10, 100, 1000
+Default Value: 0 (auto-negotiate at all supported speeds)
+    Speed forces the line speed to the specified value in megabits per second
+    (Mbps). If this parameter is not specified or is set to 0 and the link 
+    partner is set to auto-negotiate, the board will auto-detect the correct 
+    speed. Duplex must also be set when Speed is set to either 10 or 100.
+
+TxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 256
+    This value is the number of transmit descriptors allocated by the driver.
+    Increasing this value allows the driver to queue more transmits. Each 
+    descriptor is 16 bytes.
+
+TxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+    This value delays the generation of transmit interrupts in units of 
+    1.024 microseconds.  Transmit interrupt reduction can improve CPU
+    efficiency if properly tuned for specific network traffic. If the
+    system is reporting dropped transmits, this value may be set too high
+    causing the driver to run out of available transmit descriptors.
+
+TxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+    This value, in units of 1.024 microseconds, limits the delay in which a 
+    transmit interrupt is generated. Useful only if TxIntDelay is non-zero, 
+    this value ensures that an interrupt is generated after the initial 
+    packet is sent on the wire within the set amount of time.  Proper tuning,
+    along with TxIntDelay, may improve traffic throughput in specific 
+    network conditions.
+
+XsumRX (not available on the PRO/1000 Gigabit Server Adapter)
+Valid Range: 0-1
+Default Value: 1
+    A value of '1' indicates that the driver should enable IP checksum
+    offload for received packets (both UDP and TCP) to the adapter hardware.
+
+
+Speed and Duplex Configuration
+==============================
+
+Three keywords are used to control the speed and duplex configuration. These
+keywords are Speed, Duplex, and AutoNeg.
+
+If the board uses a fiber interface, these keywords are ignored, and the
+fiber interface board only links at 1000 Mbps full-duplex.
+
+For copper-based boards, the keywords interact as follows:
+
+  The default operation is auto-negotiate. The board advertises all supported
+  speed and duplex combinations, and it links at the highest common speed and
+  duplex mode IF the link partner is set to auto-negotiate.
+
+  If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
+  advertised (The 1000BaseT spec requires auto-negotiation.)
+
+  If Speed = 10 or 100, then both Speed and Duplex must be set. Auto-
+  negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST
+  also be forced.
+
+The AutoNeg parameter is used when more control is required over the auto-
+negotiation process.  When this parameter is used, Speed and Duplex must not
+be specified.  This parameter is a bitmap that specifies which speed and
+duplex settings are advertised to the link partner.
+
+Bit            7      6      5       4       3      2      1       0
+Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
+Duplex                       Full            Full   Half   Full    Half
+
+Note that setting AutoNeg does not guarantee that the board will link at the
+highest specified speed or duplex mode, but the board will link at the
+highest possible speed/duplex of the link partner IF the link partner is also
+set to auto-negotiate. If the link partner is forced speed/duplex, the
+adapter MUST be forced to the same speed/duplex.
+
+
+Additional Configurations
+=========================
+
+  Jumbo Frames
+  ------------
+
+  The driver supports Jumbo Frames for all adapters except 82542-based
+  adapters.  Jumbo Frames support is enabled by changing the MTU to a value
+  larger than the default of 1500.  Use the ifconfig command to increase the
+  MTU size. For example:
+
+        ifconfig ethx mtu 9000 up
+
+
+Known Issues
+============
+
+  Jumbo Frames System Requirement
+  -------------------------------
+
+  Memory allocation failures have been observed on Linux systems with 64 MB
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo
+  Frames, your system may require more than the advertised minimum
+  requirement of 64 MB of system memory.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement
+between you ('Licensee') and Intel. Do not use or load this software or any
+associated materials (collectively, the 'Software') until you have carefully
+read the full terms and conditions of the LICENSE located in this software
+package. By loading or using the Software, you agree to the terms of this
+Agreement. If you do not agree with the terms of this Agreement, do not
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/khttpd.txt linux-2.4.20/Documentation/networking/khttpd.txt
--- linux-2.4.19/Documentation/networking/khttpd.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/networking/khttpd.txt	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1 @@
+See net/khttpd/README for documentation on khttpd, the kernel http server.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/pktgen.txt linux-2.4.20/Documentation/networking/pktgen.txt
--- linux-2.4.19/Documentation/networking/pktgen.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/networking/pktgen.txt	2002-10-04 00:41:29.000000000 +0000
@@ -4,6 +4,9 @@
    in the place where insmod may find it.
 2. Cut script "ipg" (see below).
 3. Edit script to set preferred device and destination IP address.
+3a.  Create more scripts for different interfaces.  Up to thirty-two
+     pktgen processes can be configured and run at once by using the
+     32 /proc/net/pg* files.
 4. Run in shell: ". ipg"
 5. After this two commands are defined:
    A. "pg" to start generator and to get results.
@@ -12,12 +15,33 @@
       pgset "multiskb 0"      use single SKB for all transmits
       pgset "pkt_size 9014"   sets packet size to 9014
       pgset "frags 5"         packet will consist of 5 fragments
-      pgset "count 200000"    sets number of packets to send
+      pgset "count 200000"    sets number of packets to send, set to zero
+                              for continious sends untill explicitly
+                              stopped.
       pgset "ipg 5000"        sets artificial gap inserted between packets
                               to 5000 nanoseconds
       pgset "dst 10.0.0.1"    sets IP destination address
                               (BEWARE! This generator is very aggressive!)
+      pgset "dst_min 10.0.0.1"            Same as dst
+      pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
+      pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
+      pgset "src_max 10.0.0.254"          Set the maximum source IP.
       pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+      pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
+      pgset "src_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with srcmac.
+      pgset "dst_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with dstmac.
+      pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
+                              are: IPSRC_RND #IP Source is random (between min/max),
+                                   IPDST_RND, UDPSRC_RND,
+                                   UDPDST_RND, MACSRC_RND, MACDST_RND 
+      pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
+                              cycle through the port range.
+      pgset "udp_src_max 9"   set UDP source port max.
+      pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
+                              cycle through the port range.
+      pgset "udp_dst_max 9"   set UDP destination port max.
       pgset stop    	      aborts injection
       
   Also, ^C aborts generator.
@@ -26,22 +50,24 @@
 
 #! /bin/sh
 
-modprobe pktgen.o
+modprobe pktgen
+
+PGDEV=/proc/net/pg/pg0
 
 function pgset() {
     local result
 
-    echo $1 > /proc/net/pg
+    echo $1 > $PGDEV
 
-    result=`cat /proc/net/pg | fgrep "Result: OK:"`
+    result=`cat $PGDEV | fgrep "Result: OK:"`
     if [ "$result" = "" ]; then
-         cat /proc/net/pg | fgrep Result:
+         cat $PGDEV | fgrep Result:
     fi
 }
 
 function pg() {
-    echo inject > /proc/net/pg
-    cat /proc/net/pg
+    echo inject > $PGDEV
+    cat $PGDEV
 }
 
 pgset "odev eth0"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/tuntap.txt linux-2.4.20/Documentation/networking/tuntap.txt
--- linux-2.4.19/Documentation/networking/tuntap.txt	2001-04-25 21:59:56.000000000 +0000
+++ linux-2.4.20/Documentation/networking/tuntap.txt	2002-10-04 00:41:16.000000000 +0000
@@ -7,43 +7,71 @@
   FreeBSD TAP driver 
   Copyright (c) 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
 
+  Revision of this document 2002 by Florian Thiel <florian.thiel@gmx.net>
+
 1. Description
   TUN/TAP provides packet reception and transmission for user space programs. 
-  It can be viewed as a simple Point-to-Point or Ethernet device, which 
-  instead of receiving packets from a physical media, receives them from 
+  It can be seen as a simple Point-to-Point or Ethernet device, which,
+  instead of receiving packets from physical media, receives them from 
   user space program and instead of sending packets via physical media 
   writes them to the user space program. 
 
-  When a program opens /dev/net/tun, driver creates and registers corresponding
-  net device tunX or tapX. After a program closed above devices, driver will 
-  automatically delete tunXX or tapXX device and all routes corresponding to it.
-
-  This package(http://vtun.sourceforge.net/tun) contains two simple example 
-  programs how to use tun and tap devices. Both programs works like 
-  bridge between two network interfaces.
+  In order to use the driver a program has to open /dev/net/tun and issue a
+  corresponding ioctl() to register a network device with the kernel. A network
+  device will appear as tunXX or tapXX, depending on the options chosen. When
+  the program closes the file descriptor, the network device and all
+  corresponding routes will disappear.
+
+  Depending on the type of device chosen the userspace program has to read/write
+  IP packets (with tun) or ethernet frames (with tap). Which one is being used
+  depends on the flags given with the ioctl().
+
+  The package from http://vtun.sourceforge.net/tun contains two simple examples
+  for how to use tun and tap devices. Both programs work like a bridge between
+  two network interfaces.
   br_select.c - bridge based on select system call.
   br_sigio.c  - bridge based on async io and SIGIO signal.
-  However the best example is VTun http://vtun.sourceforge.net :))  
+  However, the best example is VTun http://vtun.sourceforge.net :))
 
 2. Configuration 
   Create device node:
+     mkdir /dev/net (if it doesn't exist already)
      mknod /dev/net/tun c 10 200
+  
+  Set permissions:
+     e.g. chmod 0700 /dev/net/tun
+     if you want the device only accesible by root. Giving regular users the
+     right to assign network devices is NOT a good idea. Users could assign
+     bogus network interfaces to trick firewalls or administrators.
 
   Driver module autoloading
      Make sure that "Kernel module loader" - module auto-loading support is enabled 
      in your kernel. 
 
-     Add following line to the /etc/modules.conf:
+     Add the following line to the /etc/modules.conf:
 	alias char-major-10-200 tun
-     
-     Run:
+     and run
         depmod -a 
-
-     Driver will be automatically loaded when application access /dev/net/tun.
+  
+  Manual loading 
+     insert the module by hand:
+        modprobe tun
+
+  If you do it the latter way, you have to load the module every time you
+  need it, if you do it the other way it will be automatically loaded when
+  /dev/net/tun is being opened.
 
 3. Program interface 
   3.1 Network device allocation:
 
+  char *dev should be the name of the device with a format string (e.g.
+  "tun%d"), but (as far as I can see) this can be any valid network device name.
+  Note that the character pointer becomes overwritten with the real device name
+  (e.g. "tun0")
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
   int tun_alloc(char *dev)
   {
       struct ifreq ifr;
@@ -79,65 +107,44 @@
 
 Universal TUN/TAP device driver Frequently Asked Question.
    
-1. What is the TUN ?
-The TUN is Virtual Point-to-Point network device.
-TUN driver was designed as low level kernel support for
-IP tunneling. It provides to userland application
-two interfaces:
-  - /dev/tunX	- character device;
-  - tunX	- virtual Point-to-Point interface.
-
-Userland application can write IP frame to /dev/tunX
-and kernel will receive this frame from tunX interface. 
-In the same time every frame that kernel writes to tunX 
-interface can be read by userland application from /dev/tunX
-device.
-
-2. What is the TAP ?
-The TAP is a Virtual Ethernet network device.
-TAP driver was designed as low level kernel support for
-Ethernet tunneling. It provides to userland application
-two interfaces:
-  - /dev/tapX	- character device;
-  - tapX	- virtual Ethernet interface.
-
-Userland application can write Ethernet frame to /dev/tapX
-and kernel will receive this frame from tapX interface. 
-In the same time every frame that kernel writes to tapX 
-interface can be read by userland application from /dev/tapX
-device.
-
-3. What platforms are supported by TUN/TAP driver ?
+1. What platforms are supported by TUN/TAP driver ?
 Currently driver has been written for 3 Unices:
    Linux kernels 2.2.x, 2.4.x 
    FreeBSD 3.x, 4.x, 5.x
    Solaris 2.6, 7.0, 8.0
 
-4. What is TUN/TAP driver used for?
+2. What is TUN/TAP driver used for?
 As mentioned above, main purpose of TUN/TAP driver is tunneling. 
 It is used by VTun (http://vtun.sourceforge.net).
 
-5. How does Virtual network device actually work ? 
+Another interesting application using TUN/TAP is pipsecd
+(http://perso.enst.fr/~beyssac/pipsec/), an userspace IPSec
+implementation that can use complete kernel routing (unlike FreeS/WAN).
+
+3. How does Virtual network device actually work ? 
 Virtual network device can be viewed as a simple Point-to-Point or
 Ethernet device, which instead of receiving packets from a physical 
 media, receives them from user space program and instead of sending 
 packets via physical media sends them to the user space program. 
 
 Let's say that you configured IPX on the tap0, then whenever 
-kernel sends any IPX packet to tap0, it is passed to the application
-(VTun for example). Application encrypts, compresses and sends it to 
-the other side over TCP or UDP. Application on other side decompress 
-and decrypts them and write packet to the TAP device, kernel handles 
-the packet like it came from real physical device.
+the kernel sends an IPX packet to tap0, it is passed to the application
+(VTun for example). The application encrypts, compresses and sends it to 
+the other side over TCP or UDP. The application on the other side decompresses
+and decrypts the data received and writes the packet to the TAP device, 
+the kernel handles the packet like it came from real physical device.
 
-6. What is the difference between TUN driver and TAP driver?
+4. What is the difference between TUN driver and TAP driver?
 TUN works with IP frames. TAP works with Ethernet frames.
 
-7. What is the difference between BPF and TUN/TAP driver?
-BFP is a advanced packet filter. It can be attached to existing
-network interface. It does not provide virtual network interface.
-TUN/TAP driver does provide virtual network interface and it is possible
+This means that you have to read/write IP packets when you are using tun and
+ethernet frames when using tap.
+
+5. What is the difference between BPF and TUN/TAP driver?
+BFP is an advanced packet filter. It can be attached to existing
+network interface. It does not provide a virtual network interface.
+A TUN/TAP driver does provide a virtual network interface and it is possible
 to attach BPF to this interface.
 
-8. Does TAP driver support kernel Ethernet bridging?
+6. Does TAP driver support kernel Ethernet bridging?
 Yes. Linux and FreeBSD drivers support Ethernet bridging. 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/00-INDEX linux-2.4.20/Documentation/parisc/00-INDEX
--- linux-2.4.19/Documentation/parisc/00-INDEX	2000-12-05 20:29:38.000000000 +0000
+++ linux-2.4.20/Documentation/parisc/00-INDEX	2002-10-04 00:41:22.000000000 +0000
@@ -1,10 +1,10 @@
 00-INDEX
 	- this file.
 IODC.txt
-	- Documentation IODC
+	- Documentation for IODC
 debugging
 	- some debugging hints for real-mode code
-mm
-	- Documentation on parisc mm status
+unwritten
+	- list of unwritten / incomplete functions
 registers
 	- current/planned usage of registers
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/registers linux-2.4.20/Documentation/parisc/registers
--- linux-2.4.19/Documentation/parisc/registers	2001-09-14 21:04:06.000000000 +0000
+++ linux-2.4.20/Documentation/parisc/registers	2002-10-04 00:41:09.000000000 +0000
@@ -25,8 +25,8 @@
 CR27 (TR 3)			Thread descriptor pointer
 CR28 (TR 4)			not used
 CR29 (TR 5)			not used
-CR30 (TR 6)			current / 0
-CR31 (TR 7)			Temporary register, used in various places
+CR30 (TR 6)			current
+CR31 (TR 7)			interrupt stack base
 
 	Space Registers (kernel mode)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sound/Maestro3 linux-2.4.20/Documentation/sound/Maestro3
--- linux-2.4.19/Documentation/sound/Maestro3	2001-02-04 18:05:29.000000000 +0000
+++ linux-2.4.20/Documentation/sound/Maestro3	2002-10-04 00:41:14.000000000 +0000
@@ -71,10 +71,18 @@
 tell the driver to print minimal debugging information as it runs.  This
 can be collected with 'dmesg' or through the klogd daemon.
 
-The other is 'external_amp', which tells the driver to attempt to enable
+One is 'external_amp', which tells the driver to attempt to enable
 an external amplifier.  This defaults to '1', you can tell the driver
 not to bother enabling such an amplifier by setting it to '0'.
 
+And the last is 'gpio_pin', which tells the driver which GPIO pin number
+the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
+If everything loads correctly and seems to be working but you get no sound, 
+try tweaking this value. 
+
+Systems known to need a different value
+        Panasonic ToughBook CF-72: gpio_pin=13 
+
 Power Management
 ----------------
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sound/forte linux-2.4.20/Documentation/sound/forte
--- linux-2.4.19/Documentation/sound/forte	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/sound/forte	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,41 @@
+
+     forte - an OSS/Lite driver for FortéMedia FM801 sound chips
+     ===========================================================
+
+This is a driver for cards using the FortéMedia FM801 audio
+controller.  The Genius Sound Maker Live card and the onboard audio in
+HP Workstation zx2000 has been tested.
+
+Both IA-32 and IA-64 architectures are supported, but the driver
+should work on any platform.
+
+The FM801 controller supports a variety of AC'97 codecs.  This driver
+lets the OSS core code figure the codec out, and should thus support
+any codec with support in the Linux kernel.
+
+The driver supports /dev/mixer and /dev/dsp for generic OSS audio
+support.  In general it adheres to the OSS spec to the extent it can
+be done with the way the hardware works.  The FM801 controller doesn't
+support scatter-gather, so if the application sets fragment size too
+low, it puts strict requirements on interrupt processing speed.  The
+driver tries to compensate by enforcing bigger buffers than requested
+by the application if the fragment size is low.
+
+The forte driver includes both standard read()/write() and the
+unsupported mmap() interface used by Quake.  mmap() is only supported
+in playback mode.
+
+U8 and S16 audio formats are supported, mono/stereo, as well as most
+all sample rates implemented by the chip.  Default is 48 KHz, 16-bit,
+mono.
+
+MIDI, FM audio, and the gameport controller are not currently
+supported.
+
+
+The latest version of this driver can be found at:
+
+    http://mkp.net/forte/
+
+
+Martin K. Petersen, July 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sysctl/vm.txt linux-2.4.20/Documentation/sysctl/vm.txt
--- linux-2.4.19/Documentation/sysctl/vm.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/sysctl/vm.txt	2002-10-04 00:41:29.000000000 +0000
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/vm/*	kernel version 2.2.10
+Documentation for /proc/sys/vm/*	kernel version 2.4.19
 	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
 
 For general info and legal blurb, please look in README.
@@ -6,7 +6,7 @@
 ==============================================================
 
 This file contains the documentation for the sysctl files in
-/proc/sys/vm and is valid for Linux kernel version 2.2.
+/proc/sys/vm and is valid for Linux kernel version 2.4.
 
 The files in this directory can be used to tune the operation
 of the virtual memory (VM) subsystem of the Linux kernel, and
@@ -34,26 +34,27 @@
 This file controls the operation of the bdflush kernel
 daemon. The source code to this struct can be found in
 linux/fs/buffer.c. It currently contains 9 integer values,
-of which 4 are actually used by the kernel.
+of which 6 are actually used by the kernel.
 
 From linux/fs/buffer.c:
 --------------------------------------------------------------
 union bdflush_param {
 	struct {
-		int nfract;	/* Percentage of buffer cache dirty to 
+		int nfract;	/* Percentage of buffer cache dirty to
 				   activate bdflush */
-		int dummy1;	/* old "ndirty" */
+		int ndirty;	/* Maximum number of dirty blocks to write out per
+				   wake-cycle */
 		int dummy2;	/* old "nrefill" */
 		int dummy3;	/* unused */
 		int interval;	/* jiffies delay between kupdate flushes */
-		int age_buffer;	/* Time for normal buffer to age */
-		int nfract_sync;/* Percentage of buffer cache dirty to 
+		int age_buffer;	/* Time for normal buffer to age before we flush it */
+		int nfract_sync;/* Percentage of buffer cache dirty to
 				   activate bdflush synchronously */
-		int dummy4;	/* unused */
+		int nfract_stop_bdflush; /* Percentage of buffer cache dirty to stop bdflush */
 		int dummy5;	/* unused */
 	} b_un;
 	unsigned int data[N_PARAM];
-} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}};
+} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
 --------------------------------------------------------------
 
 int nfract:
@@ -68,6 +69,13 @@
 more frequent I/O operations.  The default value is 30%,
 the minimum is 0%, and the maximum is 100%.
 
+int ndirty:
+The second parameter (ndirty) gives the maximum number of
+dirty buffers that bdflush can write to the disk in one time.
+A high value will mean delayed, bursty I/O, while a small
+value can lead to memory shortage when bdflush isn't woken
+up often enough.
+
 int interval:
 The fifth parameter, interval, is the minimum rate at
 which kupdate will wake and flush.  The value is expressed in
@@ -88,7 +96,11 @@
 synchronously.  This can be viewed as the hard limit before
 bdflush forces buffers to disk.  The default is 60%, the
 minimum is 0%, and the maximum is 100%.
- 
+
+int nfract_stop_bdflush:
+The eighth parameter, nfract_stop_bdflush, governs the percentage
+of buffer cache that is dirty which will stop bdflush.
+The default is 20%, the miniumum is 0%, and the maxiumum is 100%.
 ==============================================================
 buffermem:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/auerswald.txt linux-2.4.20/Documentation/usb/auerswald.txt
--- linux-2.4.19/Documentation/usb/auerswald.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/usb/auerswald.txt	2002-10-04 00:41:20.000000000 +0000
@@ -27,4 +27,4 @@
 ============
 - Connection to ISDN4LINUX (the hisax interface)
 
-The maintainer of this driver is wmues@nexgo.de
+The maintainer of this driver is wolfgang@iksw-muees.de
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/ov511.txt linux-2.4.20/Documentation/usb/ov511.txt
--- linux-2.4.19/Documentation/usb/ov511.txt	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.20/Documentation/usb/ov511.txt	2002-10-04 00:41:11.000000000 +0000
@@ -128,16 +128,6 @@
         programs that expect RGB data (e.g. gqcam) to work with this driver. If
         your colors look VERY wrong, you may want to change this.
 
-  NAME: buf_timeout
-  TYPE: integer
-  DEFAULT: 5 (seconds)
-  DESC: Number of seconds before unused frame buffers are deallocated.
-        Previously, memory was allocated upon open() and deallocated upon
-        close(). Deallocation now occurs only if the driver is closed and this
-        timeout is reached. If you are capturing frames less frequently than
-        the default timeout, increase this. This will not make any difference
-        with programs that capture multiple frames during an open/close cycle.
-
   NAME: cams
   TYPE: integer (1-4 for OV511, 1-31 for OV511+)
   DEFAULT: 1
@@ -161,13 +151,6 @@
   DESC: This configures the camera's sensor to transmit a colored test-pattern
         instead of an image. This does not work correctly yet.
 
-  NAME: sensor_gbr (*** TEMPORARILY DISABLED ***)
-  TYPE: integer (Boolean)
-  DEFAULT: 0
-  DESC: This makes the sensor output GBR422 instead of YUV420. This saves the
-        driver the trouble of converting YUV to RGB, but it currently does not
-        work very well (the colors are not quite right)
-
   NAME: dumppix
   TYPE: integer (0-2)
   DEFAULT: 0
@@ -182,9 +165,9 @@
   DEFAULT: 1 (Always on)
   DESC: Controls whether the LED (the little light) on the front of the camera
 	is always off (0), always on (1), or only on when driver is open (2).
-	This is only supported with the OV511+ chipset, and even then only on
-	some cameras (ones that actually have the LED wired to the control pin,
-	and not just hardwired to be on all the time).
+	This is not supported with the OV511, and might only work with certain
+	cameras (ones that actually have the LED wired to the control pin, and
+	not just hard-wired to be on all the time).
 
   NAME: dump_bridge
   TYPE: integer (Boolean)
@@ -259,14 +242,6 @@
 		13  VIDEO_PALETTE_YUV422P   (YUV 4:2:2 Planar)
 		15  VIDEO_PALETTE_YUV420P   (YUV 4:2:0 Planar, same as 10)
 
-  NAME: tuner
-  TYPE: integer
-  DEFAULT: -1 (autodetect)
-  DESC: This sets the exact type of the tuner module in a device. This is set
-	automatically based on the custom ID of the OV511 device. In cases
-	where this fails, you can override this auto-detection. Please see
-	linux/drivers/media/video/tuner.h for a complete list.
-
   NAME: backlight
   TYPE: integer (Boolean)
   DEFAULT: 0 (off)
@@ -293,7 +268,14 @@
 	will compensate for the blocks of corruption that can appear when the
 	camera cannot keep up with the speed of the USB bus (eg. at low frame
 	resolutions). This feature is always enabled when compression is on.
- 
+
+  NAME: mirror
+  TYPE: integer (Boolean)
+  DEFAULT: 0 (off)
+  DESC: Setting this to 1 will reverse ("mirror") the image horizontally. This
+	might be necessary if your camera has a custom lens assembly. This has
+	no effect with video capture devices.
+
 WORKING FEATURES:
  o Color streaming/capture at most widths and heights that are multiples of 8.
  o RGB24, RGB565, YUV420/YUV420P, YUV422/YUYV, and YUV422P color
@@ -304,22 +286,9 @@
  o SAA7111A video capture support at 320x240 and 640x480
  o Compression support
 
-EXPERIMENTAL FEATURES:
- o OV6630 sensor support
- o Banding filter
- o SMP compatibility
-
-TO-DO:
- o V4L2 support (This will be done after the next kernel patch release)
- o Setting of hue not working with OV7620
- o Setting of contrast and hue not working with OV7620AE
- o OV8600 sensor support (Not used in anything yet)
- o OV518/OV518+ support (all that's needed is the decompressor)
- o cams >= 3 not working
-
 HOW TO CONTACT ME:
 
-You can email me at mmcclell@bigfoot.com . Please prefix the subject line
+You can email me at mark@alpha.dyndns.org . Please prefix the subject line
 with "OV511: " so that I am certain to notice your message.
 
 CREDITS:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/silverlink.txt linux-2.4.20/Documentation/usb/silverlink.txt
--- linux-2.4.19/Documentation/usb/silverlink.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/usb/silverlink.txt	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,76 @@
+-------------------------------------------------------------------------
+Readme for Linux device driver for the Texas Instruments SilverLink cable
+-------------------------------------------------------------------------
+
+Author: Romain Liévin & Julien Blache
+Homepage: http://lpg.ticalc.org/prj_usb
+
+INTRODUCTION:
+
+This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable 
+designed by TI for connecting their TI8x/9x calculators to a computer 
+(PC or Mac usually).
+
+If you need more information, please visit the 'SilverLink drivers' homepage 
+at the above URL.
+
+WHAT YOU NEED:
+
+A TI calculator of course and a program capable to communicate with your 
+calculator.
+TiLP will work for sure (since I am his developer !). yal92 may be able to use
+it by changing tidev for tiglusb (may require some hacking...).
+
+HOW TO USE IT:
+
+You must have first compiled USB support, support for your specific USB host
+controller (UHCI or OHCI).
+
+Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX):
+
+       insmod usb/usbcore.o
+       insmod usb/usb-uhci.o  <OR>  insmod usb/ohci-hcd.o
+       insmod tiglusb.o
+
+If it is not already there (it usually is), create the device:
+
+       mknod /dev/tiglusb0 c 115 16
+
+You will have to set permissions on this device to allow you to read/write
+from it:
+
+       chmod 666 /dev/tiglusb0
+       
+Now you are ready to run a linking program such as TiLP. Be sure to configure 
+it properly (RTFM).
+       
+MODULE PARAMETERS:
+
+  You can set these with:  insmod tiglusb NAME=VALUE
+  There is currently no way to set these on a per-cable basis.
+
+  NAME: timeout
+  TYPE: integer
+  DEFAULT: 15
+  DESC: Timeout value in tenth of seconds. If no data is available once this 
+       time has expired then the driver will return with a timeout error.
+
+QUIRKS:
+
+The following problem seems to be specific to the link cable since it appears 
+on all platforms (Linux, Windows, Mac OS-X). 
+
+In some very particular cases, the driver returns with success but
+without any data. The application should retry a read operation at least once.
+
+HOW TO CONTACT US:
+
+You can email me at roms@lpg.ticalc.org. Please prefix the subject line
+with "TIGLUSB: " so that I am certain to notice your message.
+You can also mail JB at jb@jblache.org: he has written the first release of 
+this driver but he better knows the Mac OS-X driver.
+
+CREDITS:
+
+The code is based on dabusb.c, printer.c and scanner.c !
+The driver has been developed independantly of Texas Instruments.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/CARDLIST linux-2.4.20/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.19/Documentation/video4linux/bttv/CARDLIST	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/CARDLIST	2002-10-04 00:41:11.000000000 +0000
@@ -3,41 +3,41 @@
   card=1 - MIRO PCTV
   card=2 - Hauppauge (bt848)
   card=3 - STB
-  card=4 - Intel
+  card=4 - Intel Create and Share PCI/ Smart Video Recorder III
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - FlyVideo II (Bt848) LR26
-  card=9 - IXMicro TurboTV
+  card=8 - Lifeview FlyVideo II (Bt848) LR26
+  card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
-  card=12 - ADS Technologies Channel Surfer TV
+  card=12 - ADS Technologies Channel Surfer TV (bt848)
   card=13 - AVerMedia TVCapture 98
   card=14 - Aimslab Video Highway Xtreme (VHX)
   card=15 - Zoltrix TV-Max
-  card=16 - Pixelview PlayTV (bt878)
+  card=16 - Prolink Pixelview PlayTV (bt878)
   card=17 - Leadtek WinView 601
   card=18 - AVEC Intercapture
-  card=19 - LifeView FlyKit w/o Tuner
+  card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
   card=20 - CEI Raffles Card
-  card=21 - Lucky Star Image World ConferenceTV
-  card=22 - Phoebe Tv Master + FM (CPH050)
+  card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
+  card=22 - Askey CPH050/ Phoebe Tv Master + FM
   card=23 - Modular Technology MM205 PCTV, bt878
-  card=24 - [many vendors] CPH05X/06X (bt878)
-  card=25 - Terratec/Vobis TV-Boostar
-  card=26 - Newer Hauppauge WinCam (bt878)
-  card=27 - MAXI TV Video PCI2
+  card=24 - Askey CPH05X/06X (bt878) [many vendors]
+  card=25 - Terratec Terra TV+ Version 1.0 (Bt848)/Vobis TV-Boostar
+  card=26 - Hauppauge WinCam newer (bt878)
+  card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
   card=28 - Terratec TerraTV+
   card=29 - Imagenation PXC200
-  card=30 - FlyVideo 98
-  card=31 - iProTV
-  card=32 - Intel Create and Share PCI
+  card=30 - Lifeview FlyVideo 98 LR50
+  card=31 - Formac iProTV
+  card=32 - Intel Create and Share PCI/ Smart Video Recorder III
   card=33 - Terratec TerraTValue
   card=34 - Leadtek WinFast 2000
-  card=35 - Flyvideo 98 (LR50Q) / Chronos Video Shuttle II
-  card=36 - Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner
-  card=37 - PixelView PlayTV pro
-  card=38 - TView99 CPH06X
+  card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
+  card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
+  card=37 - Prolink PixelView PlayTV pro
+  card=38 - Askey CPH06X TView99
   card=39 - Pinnacle PCTV Studio/Rave
   card=40 - STB2
   card=41 - AVerMedia TVPhone 98
@@ -47,45 +47,47 @@
   card=45 - MATRIX-Vision MV-Delta 2
   card=46 - Zoltrix Genie TV/FM
   card=47 - Terratec TV/Radio+
-  card=48 - Dynalink Magic TView 
-  card=49 - GV-BCTV3
+  card=48 - Askey CPH03x/ Dynalink Magic TView
+  card=49 - IODATA GV-BCTV3/PCI
   card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
   card=51 - Eagle Wireless Capricorn2 (bt878A)
   card=52 - Pinnacle PCTV Studio Pro
   card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
-  card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
-  card=55 - BESTBUY Easy TV (CPH031)
-  card=56 - FlyVideo '98/FM
+  card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
+  card=55 - Askey CPH031/ BESTBUY Easy TV
+  card=56 - Lifeview FlyVideo 98FM LR50
   card=57 - GrandTec 'Grand Video Capture' (Bt848)
-  card=58 - Phoebe TV Master Only (No FM) CPH060
-  card=59 - TV Capturer (CPH03X)
+  card=58 - Askey CPH060/ Phoebe TV Master Only (No FM)
+  card=59 - Askey CPH03x TV Capturer
   card=60 - Modular Technology MM100PCTV
   card=61 - AG Electronics GMV1
-  card=62 - BESTBUY Easy TV (bt878)
+  card=62 - Askey CPH061/ BESTBUY Easy TV (bt878)
   card=63 - ATI TV-Wonder
   card=64 - ATI TV-Wonder VE
-  card=65 - FlyVideo 2000S
+  card=65 - Lifeview FlyVideo 2000S LR90
   card=66 - Terratec TValueRadio
-  card=67 - GV-BCTV4/PCI
+  card=67 - IODATA GV-BCTV4/PCI
   card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
   card=69 - Active Imaging AIMMS
-  card=70 - PV-BT878P+
-  card=71 - Flyvideo 98EZ (capture only)
-  card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
+  card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C)
+  card=71 - Lifeview FlyVideo 98EZ (capture only) LR51
+  card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
   card=73 - Sensoray 311
   card=74 - RemoteVision MX (RV605)
   card=75 - Powercolor MTV878/ MTV878R/ MTV878F
   card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
   card=77 - GrandTec Multi Capture Card (Bt878)
-  card=78 - AOPEN VA1000
+  card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
+  card=79 - DSP Design TCVIDEO
+  card=80 - Hauppauge WinTV PVR
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
-  type=1 - Philips PAL_I
-  type=2 - Philips NTSC
-  type=3 - Philips SECAM
+  type=1 - Philips PAL_I (FI1246 and compatibles)
+  type=2 - Philips NTSC (FI1236 and compatibles)
+  type=3 - Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)
   type=4 - NoTuner
-  type=5 - Philips PAL
+  type=5 - Philips PAL_BG (FI1216 and compatibles)
   type=6 - Temic NTSC (4032 FY5)
   type=7 - Temic PAL_I (4062 FY5)
   type=8 - Temic NTSC (4036 FY5)
@@ -103,7 +105,7 @@
   type=20 - Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
   type=21 - Temic NTSC (4039 FR5)
   type=22 - Temic PAL/SECAM multi (4046 FM5)
-  type=23 - Philips PAL_DK
+  type=23 - Philips PAL_DK (FI1256 and compatibles)
   type=24 - Philips PAL/SECAM multi (FQ1216ME)
   type=25 - LG PAL_I+FM (TAPC-I001D)
   type=26 - LG PAL_I (TAPC-I701D)
@@ -118,3 +120,5 @@
   type=35 - Temic PAL_DK/SECAM_L (4012 FY5)
   type=36 - Temic NTSC (4136 FY5)
   type=37 - LG PAL (newer TAPC series)
+  type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
+  type=39 - LG NTSC (newer TAPC series)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Cards linux-2.4.20/Documentation/video4linux/bttv/Cards
--- linux-2.4.19/Documentation/video4linux/bttv/Cards	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/Cards	2002-10-04 00:41:13.000000000 +0000
@@ -1,3 +1,8 @@
+
+Gunther Mayer's bttv card gallery (graphical version of this text file :-)
+is available at: http://mayerg.gmxhome.de/bttv/bttv-gallery.html
+
+
 Suppported cards:
 
 
@@ -91,10 +96,9 @@
 - sound decoder: TDA9800, MSP34xx (stereo cards) 
 
 
-CPH-Series (CPH050, ...)
-------------------------
-Developed by TelSignal(?), OEMed by many vendors (Askey, Typhoon, 
-  Anubis, Dynalink)
+Askey CPH-Series
+----------------
+Developed by TelSignal(?), OEMed by many vendors (Typhoon, Anubis, Dynalink)
 
   Card series:
     CPH01x: BT848 capture only
@@ -149,9 +153,13 @@
       LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
            Rev.W = Flyvideo 98 (no eeprom)
       LR51 Rev.E = Flyvideo 98 EZ (capture only)
-      LR90       = Flyvideo 2000 series
+      LR90       = Flyvideo 2000 (Bt878)
+		   Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
       LR91       = Stereo daughter card for LR90
       LR97       = Flyvideo DVBS
+      LR99 Rev.E = Low profile card for OEM integration (only internal audio!) bt878
+      LR136	 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
+      LR137      = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
       LR138 Rev.C= Flyvideo 2000 (SAA7130)
 	        or Flyvideo 3000 (SAA7134) w/Stereo TV
 		   These exist in variations w/FM and w/Remote sometimes denoted
@@ -162,15 +170,14 @@
       Their Bt8x8 cards are listed as discontinued.
       Flyvideo 2000S was probably sold as Flyvideo 3000 in some contries(Europe?).
       The new Flyvideo 2000/3000 are SAA7130/SAA7134 based. 
-      Flyvideo 2100/3100 are half-sized cards (for system integrators etc.)
 
   "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
   this name is re-used for LR50 Rev.W.
   The Lifeview website mentioned Flyvideo III at some time, but such a card
-  has never been seen. 
+  has not yet been seen (perhaps it was the german name for LR90 [stereo]).
   These cards are sold by many OEMs too.
 
-  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821)
+  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821) {Germany}
 
 
 Typhoon TV card series:
@@ -190,7 +197,12 @@
   50686 "TV Tuner"                       = KNC1 TV Station
   50687 "TV Tuner stereo"                = KNC1 TV Station pro
   50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
+  50689  TV SAT DVB-S CARD CI PCI (SAA7146AH)
   50692 "TV/FM Tuner" (small PCB)
+  50694  TV TUNER CARD RDS (PHILIPS CHIPSET SAA7134HL)
+  50696  TV TUNER STEREO (PHILIPS CHIPSET SAA7134HL, MK3ME Tuner)
+  50804  PC-SAT TV/Audio Karte = Techni-PC-Sat (ZORAN 36120PQC, Tuner:Alps)
+  50866  TVIEW SAT RECEIVER+ADR
   50868 "TV/FM Tuner Pal I" (variant of 50682)
   50999 "TV/FM Tuner Secam" (variant of 50682)
 
@@ -207,16 +219,31 @@
 
 Prolink
 -------
-   Pixelview Play TV Pro:
-     PV-BT878P+rev.9B (Play TV Pro w/FM w/NICAM)
-     PV-BT878P+rev.8X 
-     PV-BT878P+rev.4C (Play TV Pro) 
-     PV-BT878P+rev.4E (Play TV Pak) 
-     PV-BT878P+rev.2F 
-     PV-BT878TV 
-
-   PixelView Play TV 
-     PV-BT848P+
+   TV cards:
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 8E)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 9D)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 4C / 8D / 10A )
+   PixelView Play TV - (Model: PV-BT848P+)
+   878TV - (Model: PV-BT878TV)
+
+   Multimedia TV packages (card + software pack):
+   PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
+   PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
+   PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A ) 
+   PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
+   PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
+   PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
+
+   Further Cards:
+   PV-BT878P+rev.9B (Play TV Pro, opt. w/FM w/NICAM)
+   PV-BT878P+rev.2F
+   PV-BT878P Rev.1D (bt878, capture only)
+   
+   Video Conferencing:
+   PixelView Meeting PAK - (Model: PV-BT878P)
+   PixelView Meeting PAK Lite - (Model: PV-BT878P)
+   PixelView Meeting PAK plus - (Model: PV-BT878P+rev 4C/8D/10A)
+   PixelView Capture - (Model: PV-BT848P)
 
 Dynalink
 --------
@@ -235,7 +262,7 @@
 Tekram
 ------
    VideoCap C205 (Bt848)
-   VideoCap C210 (Zoran ZR36120 +Philips)
+   VideoCap C210 (zr36120 +Philips)
    CaptureTV M200 (ISA)
    CaptureTV M205 (Bt848)
 
@@ -257,8 +284,10 @@
    TV-Station FM (+Radio)
    TV-Station RDS (+RDS)
 
-PV951 cards:
-------------
+   newer Cards have saa7134, but model name stayed the same?
+
+Provideo PV951 
+--------------
   These are sold as:
    Boeder TV-FM Video Capture Card
    Titanmedia Supervision TV-2400
@@ -270,12 +299,14 @@
 Highscreen
 ----------
    TV Karte = LR50 Rev.S
-   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, TDA9821) "ceb105.pcb"
+   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, tda9821) "ceb105.pcb"
 
 Zoltrix
 -------
+   Face to Face Capture (Bt848 capture only) (PCB "VP-2848")
    Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
    Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
+   Genie Wonder Pro
 
 AVerMedia
 ---------
@@ -302,21 +333,24 @@
 
 Aimslab
 -------
+   Video Highway or "Video Highway TR200" (ISA)
    Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
 
-IXMicro
+IXMicro (former: IMS=Integrated Micro Solutions)
 -------
    IXTV BT848
    IXTV BT878
    TurboTV (Bt848)
 
 Lifetec/Medion/Tevion/Aldi
--------
-   LT9415/MD9415 = LR90 Rev. F
+--------------------------
+   LT9306/MD9306 = CPH061
+   LT9415/MD9415 = LR90 Rev.F or Rev.G
           MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+          MD9717 = KNC One (Rev D4, saa7134)
 
 Modular Technologies (www.modulartech.com) UK
---------------------
+---------------------------------------------
    MM100 PCTV (Bt848)
    MM205 PCTV (Bt878)
    MM210 PCTV (Bt878) (Galaxy TV)
@@ -326,19 +360,28 @@
    Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
    Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
    Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
-   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB, i
+   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
 				     "CPH010-E83" on the back, SAA6588T, TDA9873H
    Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB, 
 				     "CPH011-D83" on back
    Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
+   Terra Active Radio Upgrade (tea5757h, saa6588t)
 
    LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
 
+   Cinergy 400 (saa7134), "E877 11(S)", "PM820092D" printed on PCB
 
 Technisat
 ---------
-   Mediafocus I (ZR36120/ZR36125)
-   Mediafocus II (SAA7146)
+   Discos ADR PC-Karte ISA (no TV!)
+   Discos ADR PC-Karte PCI (probably no TV?)
+   Techni-PC-Sat (Sat. analog)
+         Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
+   Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
+   Mediafocus II (saa7146, Sat. analog)
+         SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
+   SkyStar 1 DVB  (AV7110)
+   SkyStar 2 DVB  (B2C2) (=Sky2PC)
 
 Siemens
 -------
@@ -359,34 +402,262 @@
    Mirovideo PCTV (Bt848)
    Mirovideo PCTV SE (Bt848)
    Mirovideo PCTV Pro (Bt848 + Daughterboard)
-   Studio PCTV Rave (Bt878 w/o infrared)
-   Studio PCTV
-   Studio PCTV Pro (Bt878 stereo w/ FM)
+   Studio PCTV Rave (Bt878 package w/o infrared)
+   Studio PCTV      (Bt878)
+   Studio PCTV Pro  (Bt878 stereo w/ FM)
 
+   M(J)PEG capture and playback:
    DC1+ (ISA)
-   DC10  (zr36057 + zr36060 + saa7110 + adv7176)
-   DC10+ (zr36067 + zr36060 + saa7110 + adv7176)
-   DC20
-   DC30
-   DC30+ (zr36067 + zr36050 + zr36016 + vpx3220 + adv7176)
+   DC10  (zr36057,     zr36060,      saa7110, adv7176)
+   DC10+ (zr36067,     zr36060,      saa7110, adv7176)
+   DC20  (ql16x24b,zr36050, zr36016, saa7110, saa7187 ...)
+   DC30  (zr36057, zr36050, zr36016, vpx3220, adv7176, ad1843, tea6415, miro FST97A1)
+   DC30+ (zr36067, zr36050, zr36016, vpx3220, adv7176)
+   DC50  (zr36067, zr36050, zr36016, saa7112, adv7176 (2 pcs.?), ad1843, miro FST97A1, Lattice ???)
 
 Lenco
 -----
    MXR-9565 (=Technisat Mediafocus?)
-   MXR-9571 (Bt848)
+   MXR-9571 (Bt848) (=CPH031?)
    MXR-9575
-   MXR-9477 (Bt878)
-   MXTV-9578CP (= Prolink PV-BT878P+4E)
+   MXR-9577 (Bt878) (=Prolink 878TV Rev.3x)
+   MXTV-9578CP (Bt878) (= Prolink PV-BT878P+4E)
 
 Iomega
 ------
-   Buz (Zoran zr36067 + zr36060 + SAA7111 + SAA7185)
+   Buz (zr36067, zr36060, saa7111, saa7185)
 
 LML
 ---
-   LML33 (zr36067 + zr36060 + bt819+ bt856)
+   LML33 (zr36067, zr36060, bt819, bt856)
 
 Grandtec
 --------
    Grand Video Capture (Bt848)
    Multi Capture Card  (Bt878)
+
+Koutech
+-------
+   KW-606 (Bt848)
+   KW-607 (Bt848 capture only)
+   KW-606RSF
+   KW-607A (capture only)
+   KW-608 (Zoran capture only)
+ 
+IODATA (jp)
+------
+   GV-BCTV/PCI
+   GV-BCTV2/PCI
+   GV-BCTV3/PCI
+   GV-BCTV4/PCI
+   GV-VCP/PCI (capture only)
+   GV-VCP2/PCI (capture only)
+
+Canopus (jp)
+-------
+   WinDVR	= Kworld "KW-TVL878RF"
+
+www.sigmacom.co.kr 
+------------------
+   Sigma Cyber TV II 
+
+www.sasem.co.kr
+---------------
+   Litte OnAir TV
+
+hama 
+----
+   TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
+
+Sigma Designs
+-------------
+   Hollywood plus (em8300, em9010, adv7175), (PCB "M340-10") MPEG DVD decoder
+
+Formac
+------
+   iProTV (Card for iMac Mezzanine slot, Bt848+SCSI)
+   ProTV (Bt848)
+   ProTV II = ProTV Stereo (Bt878)
+
+ATI
+---
+   TV-Wonder
+   TV-Wonder VE
+
+Diamond Multimedia
+------------------
+   DTV2000 (Bt848, tda9875)
+
+Aopen
+-----
+   VA1000 Plus (w/ Stereo)
+   VA1000 Lite
+   VA1000 (=LR90)
+
+Intel
+-----
+   Smart Video Recorder (ISA full-length)
+   Smart Video Recorder pro (ISA half-length)
+   Smart Video Recorder III (Bt848)
+
+STB
+---
+   TV PCI (Temic4032FY5, tda9850??)
+   other variants?
+
+Videologic
+----------
+   Captivator Pro/TV (ISA?)
+   Captivator PCI/VC (Bt848 bundled with camera) (capture only)
+
+Technotrend
+------------
+   TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
+   TT-DVB-Sat
+   TT-DVB-C PCI
+
+Teles
+-----
+   DVB-s (Rev. 2.2, BSRV2-301A, data only?)
+
+Remote Vision
+-------------
+   MX RV605 (Bt848 capture only)
+
+Boeder
+------
+   PC ChatCam (Model 68252) (Bt848 capture only)
+   Tv/Fm Capture Card  (Model 68404) = PV951
+
+Media-Surfer  (esc-kathrein.de)
+-------------------------------
+   Sat-Surfer (ISA)
+   Sat-Surfer PCI = Techni-PC-Sat
+   Cable-Surfer 1
+   Cable-Surfer 2
+   Cable-Surfer PCI (zr36120)
+   Audio-Surfer (ISA Radio card)
+
+Jetway (www.jetway.com.tw)
+--------------------------
+   JW-TV 878M 
+   JW-TV 878  = KWorld KW-TV878RF
+
+Galaxis
+-------
+   Galaxis DVB Card S CI
+   Galaxis DVB Card C CI
+   Galaxis DVB Card S
+   Galaxis DVB Card C
+
+Hauppauge
+---------
+   many many WinTV models ...
+   WinTV DVBs
+   WinTV NOVA
+   WinTV NOVA-CI
+   WinTV-Nexus-s
+
+Matrix-Vision
+-------------
+   MATRIX-Vision MV-Delta
+   MATRIX-Vision MV-Delta 2
+   MVsigma-SLC (Bt848)
+
+Conceptronic (.net)
+------------
+   TVCON FM,  TV card w/ FM = CPH05x
+
+BestData
+--------
+   HCC100 = VCC100rev1 + camera
+   VCC100 rev1 (bt848)
+   VCC100 rev2 (bt878)
+
+Gallant  (www.gallantcom.com) www.minton.com.tw
+-----------------------------------------------
+   Intervision IV-510 (capture only bt8x8)
+   Intervision IV-550 (bt8x8)
+   Intervision IV-100 (zoran)
+   Intervision IV-1000 (bt8x8)
+   
+Asonic (www.asonic.com.cn) (website down)
+-----------------------------------------
+   SkyEye tv 878
+
+Hoontech
+--------
+   878TV/FM
+
+Teppro (www.itcteppro.com.tw)
+-----------------------------
+   ITC PCITV (Card Ver 1.0) "Teppro TV1/TVFM1 Card"
+   ITC PCITV (Card Ver 2.0)
+   ITC PCITV (Card Ver 3.0) = "PV-BT878P+ (REV.9D)"
+   ITC PCITV (Card Ver 4.0)
+   TEPPRO IV-550 (For BT848 Main Chip)
+   ITC DSTTV (bt878, satellite)
+   ITC VideoMaker (saa7146, StreamMachine sm2110, tvtuner) "PV-SM2210P+ (REV:1C)"
+
+Kworld (www.kworld.com.tw)
+--------------------------
+   KWORLD KW-TV878RF-Pro TV Capture with FM Radio
+   KWORLD KW-TV878R-Pro TV
+   KWORLD KW-TVL878RF  (low profile)
+   KWORLD KW-TV878R TV Capture (No FM Radio)
+   KWORLD KW-TV878RF TV
+
+JTT/ Justy Corp.http://www.justy.co.jp/ (www.jtt.com.jp website down)
+---------------------------------------------------------------------
+   JTT-02 (JTT TV) "TV watchmate pro" (bt848) 
+
+ADS www.adstech.com
+-------------------
+   Channel Surfer TV ( CHX-950 ) 
+   Channel Surfer TV+FM ( CHX-960FM )
+
+AVEC www.prochips.com
+---------------------
+   AVEC Intercapture (bt848, tea6320)
+
+NoBrand
+-------
+   TV Excel = Australian Name for "PV-BT878P+ 8E" or so
+
+Mach www.machspeed.com
+----
+   Mach TV 878
+
+Eline www.eline-net.com/
+-----
+   Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26  (bt878)
+   Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x)
+
+Spirit http://www.spiritmodems.com.au/
+------
+   Spirit TV Tuner/Video Capture Card (bt848)
+
+Boser www.boser.com.tw
+-----
+   HS-878 Mini PCI Capture Add-on Card
+   HS-879 Mini PCI 3D Audio and Capture Add-on Card (w/ ES1938 Solo-1)
+
+Satelco
+-------
+   TV-FM =KNC1 saa7134
+
+Sensoray www.sensoray.com
+--------
+   Sensoray 311 (PC/104 bus)
+   Sensoray 611 (PCI)
+
+CEI (Chartered Electronics Industries Pte Ltd [CEI] [FCC ID HBY])
+---
+  TV Tuner  -  HBY-33A-RAFFLES  Brooktree Bt848KPF + Philips
+  TV Tuner MG9910  -  HBY33A-TVO  CEI + Philips SAA7110 + OKI M548262 + ST STV8438CV
+  Primetime TV (ISA)
+   acquired by Singapore Technologies
+   now operating as Chartered Semiconductor Manufacturing
+   Manufacturer of video cards is listed as:
+   Cogent Electronics Industries [CEI]
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Insmod-options linux-2.4.20/Documentation/video4linux/bttv/Insmod-options
--- linux-2.4.19/Documentation/video4linux/bttv/Insmod-options	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/Insmod-options	2002-10-04 00:41:11.000000000 +0000
@@ -29,7 +29,7 @@
 		irq_debug=0/1	irq handler debug messages.
 				default is 0 (off).
 		gbuffers=2-32	number of capture buffers for mmap'ed capture.
-				default is 2.
+				default is 4.
 		gbufsize=	size of capture buffers. default and
 				maximum value is 0x208000 (~2MB)
 		no_overlay=0	Enable overlay on broken hardware.  There
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README linux-2.4.20/Documentation/video4linux/bttv/README
--- linux-2.4.19/Documentation/video4linux/bttv/README	2001-08-05 20:15:05.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/README	2002-10-04 00:41:10.000000000 +0000
@@ -58,6 +58,9 @@
 		the helper modules.
 MAKEDEV:	a script to create the special files for v4l
 CARDLIST:	List of all supported cards
+Cards:		more detailed descriptions of known TV cards:
+		OEM name variants, used i2c chips, ...
+		also includes non-bttv cards.
 
 Loading just the bttv modules isn't enouth for most cards.  The
 drivers for the i2c tuner/sound chips must also be loaded.  bttv tries
@@ -73,6 +76,12 @@
 video but no sound you've very likely specified the wrong (or no)
 card type.  A list of supported cards is in CARDLIST.
 
+For the WinTV/PVR you need one firmware file from the driver CD:
+hcwamc.rbf.  The file is in the pvr45xxx.exe archive (self-extracting
+zip file, unzip can unpack it).  Put it into the /etc/pvr directory or
+use the firm_altera=<path> insmod option to point the driver to the
+location of the file.
+
 If your card isn't listed in CARDLIST or if you have trouble making
 audio work, you should read the Sound-FAQ.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README.freeze linux-2.4.20/Documentation/video4linux/bttv/README.freeze
--- linux-2.4.19/Documentation/video4linux/bttv/README.freeze	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/README.freeze	2002-10-04 00:41:14.000000000 +0000
@@ -46,6 +46,11 @@
 the PCI bus. The bt848/878 chips have a few workarounds for known
 incompatibilities, see README.quirks.
 
+Some folks report that increasing the pci latency helps too,
+althrought I'm not sure whenever this really fixes the problems or
+only makes it less likely to happen.  Both bttv and btaudio have a
+insmod option to set the PCI latency of the device.
+
 Some mainboard have problems to deal correctly with multiple devices
 doing DMA at the same time.  bttv + ide seems to cause this sometimes,
 if this is the case you likely see freezes only with video and hard disk
@@ -56,6 +61,9 @@
 other
 -----
 
+If you use some binary-only yunk (like nvidia module) try to reproduce
+the problem without.
+
 IRQ sharing is known to cause problems in some cases.  It works just
 fine in theory and many configurations.  Neverless it might be worth a
 try to shuffle around the PCI cards to give bttv another IRQ or make
@@ -63,3 +71,4 @@
 VGA cards seems to cause trouble sometimes.  I've also seen funny
 effects with bttv sharing the IRQ with the ACPI bridge (and
 apci-enabled kernel).
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Tuners linux-2.4.20/Documentation/video4linux/bttv/Tuners
--- linux-2.4.19/Documentation/video4linux/bttv/Tuners	2001-10-17 21:19:20.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/bttv/Tuners	2002-10-04 00:41:09.000000000 +0000
@@ -1,3 +1,16 @@
+1) Tuner Programming
+====================
+There are some flavors of Tuner programming APIs.
+These differ mainly by the bandswitch byte.
+
+    L= LG_API       (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+    P= PHILIPS_API  (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+    T= TEMIC_API    (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+    A= ALPS_API     (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
+    M= PHILIPS_MK3  (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
+
+2) Tuner Manufacturers
+======================
 
 SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
   TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
@@ -10,6 +23,7 @@
    M= BG+I+DK
    N= NTSC 
    Q= BG+I+DK+LL
+ [89]: ?
  [125]:
    2: No FM
    5: With FM
@@ -23,43 +37,49 @@
  [ABCD]:
    3-wire/I2C tuning, 2-band/3-band
 
+ These Tuners are PHILIPS_API compatible.
+
 Philips Tuner identification: (e.g. FM1216MF)
-  F[IRMQ]12[1345]{MF|ME|MP}
-  [IRMQ]:
-   I: Tuner Series
-   R: Tuner + Radio IF
-   M: Tuner + FM
-   Q,MR: specials
+  F[IRMQ]12[1345]6{MF|ME|MP}
+  F[IRMQ]:
+   FI12x6: Tuner Series
+   FR12x6: Tuner + Radio IF
+   FM12x6: Tuner + FM
+   FQ12x6: special
+   FMR12x6: special
    TD15xx: Digital Tuner ATSC
-  [1345]
-   1: PAL BG
-   3: NTSC
-   4: PAL I
-   5: Pal DK
+  12[1345]6:
+   1216: PAL BG
+   1236: NTSC
+   1246: PAL I
+   1256: Pal DK
   {MF|ME|MP}
-   MF: w/ Secam
-   ME: BD DK I LL
-   MP: BG DK I
+   MF: BG LL w/ Secam (Multi France)
+   ME: BG DK I LL   (Multi Europe)
+   MP: BG DK I      (Multi PAL)
    MR: BG DK M (?)
    MG: BG DKI M (?)
+  MK2 series PHILIPS_API, most tuners are compatible to this one !
+  MK3 series introduced in 2002 w/ PHILIPS_MK3_API
 
 Temic Tuner identification: (.e.g 4006FH5)
    4[01][0136][269]F[HYNR]5
-    40x2: Tuner (5V/33V), different I2C programming from Philips !
+    40x2: Tuner (5V/33V), TEMIC_API.
     40x6: Tuner 5V
     41xx: Tuner compact
     40x9: Tuner+FM compact
    [0136]
-    0: PAL BG
-    1: Pal DK, Secam LL
-    3: NTSC
-    6: PAL I
+    xx0x: PAL BG
+    xx1x: Pal DK, Secam LL
+    xx3x: NTSC
+    xx6x: PAL I
    F[HYNR]5
     FH5: Pal BG
     FY5: others
     FN5: multistandard
     FR5: w/ FM radio
    3X xxxx: order number with specific connector
+  Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
 
 LG Innotek Tuner:
   TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
@@ -76,13 +96,20 @@
   TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
   TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
   TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
-
-  (API,Lo-Hi-takeover/Hi-UHF-takeover)
-   I2C APIs:
-    L= LG programming (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
-    P= Philips progr. (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
-    T= Temic progr.   (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
   Suffix: 
     P= Standard phono female socket
     D= IEC female socket
     F= F-connector
+
+Other Tuners:
+TCL2002MB-1 : PAL BG + DK       =TUNER_LG_PAL_NEW_TAPC
+TCL2002MB-1F: PAL BG + DK w/FM  =PHILIPS_PAL
+TCL2002MI-2 : PAL I		= ??
+
+ALPS Tuners:
+   Most are LG_API compatible
+   TSCH6 has ALPS_API (TSCH5 ?)
+   TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:(1)
+
+Lit.
+(1) conexant100029b-PCI-Decoder-ApplicationNote.pdf
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/meye.txt linux-2.4.20/Documentation/video4linux/meye.txt
--- linux-2.4.19/Documentation/video4linux/meye.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/Documentation/video4linux/meye.txt	2002-10-04 00:41:13.000000000 +0000
@@ -86,7 +86,7 @@
 
 	MEYEIOC_SYNC
 		Takes as an argument the buffer number you want to sync.
-		This ioctl blocks untils the buffer is filled and ready
+		This ioctl blocks until the buffer is filled and ready
 		for the application to use. It returns the buffer size.
 
 	MEYEIOC_STILLCAPT
@@ -106,7 +106,7 @@
 		
 	- mjpeg hardware playback doesn't work (depends on overlay...)
 
-	- rewrite the driver to use some commun video4linux API for snapshot
+	- rewrite the driver to use some common video4linux API for snapshot
 	  and mjpeg capture. Unfortunately, video4linux1 does not permit it,
 	  the BUZ API seems to be targeted to TV cards only. The video4linux 2
 	  API may be an option, if it goes into the kernel (maybe 2.5 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/BUGS linux-2.4.20/Documentation/x86_64/BUGS
--- linux-2.4.19/Documentation/x86_64/BUGS	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/x86_64/BUGS	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,10 @@
+Some known problems:
+
+-- Compiling the kernel with -j for parallel makes is not completely safe
+due to missing dependencies with offset.h. Usually it is safe when it 
+already exists, but not always.
+
+Current hack is to rerun make depend manually when you change anything
+that would touch offset.h (see arch/x86-64/tools/offset.c on what that is).
+Do not use -j with depend. 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/mm.txt linux-2.4.20/Documentation/x86_64/mm.txt
--- linux-2.4.19/Documentation/x86_64/mm.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/Documentation/x86_64/mm.txt	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,194 @@
+The paging design used on the x86-64 linux kernel port in 2.4.x provides:
+
+o	per process virtual address space limit of 512 Gigabytes
+o	top of userspace stack located at address 0x0000007fffffffff
+o	PAGE_OFFSET = 0xffff800000000000
+o	start of the kernel mapping =  0x0000010000000000
+o	global RAM per system 508*512GB=254 Terabytes
+o	no need of any common code change
+o       512GB of vmalloc/ioremap space
+
+Description:
+        x86-64 has a 4 level page structure, similar to ia32 PSE but with
+        some extensions. Each level consits of a 4K page with 512 64bit
+        entries. The levels are named in Linux PML4, PGD, PMD, PTE; AMD calls them
+        PML4E, PDPE, PDE, PTE respectively. For direct and kernel mapping
+        only 3 levels are used with the PMD pointing to 2MB pages.
+          
+	Userspace is able to modify and it sees only the 3rd/2nd/1st level
+	pagetables (pgd_offset() implicitly walks the 1st slot of the 4th
+	level pagetable and it returns an entry into the 3rd level pagetable).
+	This is where the per-process 512 Gigabytes limit cames from.
+
+	The common code pgd is the PDPE, the pmd is the PDE, the
+	pte is the PTE. The PML4 remains invisible to the common
+	code.
+
+	Since the per-process limit is 512 Gigabytes (due to kernel common
+	code 3 level pagetable limitation), the higher virtual address mapped
+	into userspace is 0x7fffffffff and it makes sense to use it
+	as the top of the userspace stack to allow the stack to grow as
+	much as possible.
+
+	The kernel mapping and the direct memory mapping are split. Direct memory
+	mapping starts directly after userspace after a 512GB gap, while 
+	kernel mapping is at the end of (negative) virtual address space to exploit 
+	the kernel code model. There is no support for discontig memory, this
+	implies that kernel mapping/vmalloc/ioremap/module mapping are not 
+	represented in their "real" mapping in mem_map, but only with their
+	direct mapped (but normally not used) alias.
+	
+Future:
+
+	During 2.5.x we can break the 512 Gigabytes per-process limit
+	possibly by removing from the common code any knowledge about the
+	architectural dependent physical layout of the virtual to physical
+	mapping.
+
+	Once the 512 Gigabytes limit will be removed the kernel stack will
+	be moved (most probably to virtual address 0x00007fffffffffff).
+	Nothing	will break in userspace due that move, as nothing breaks
+	in IA32 compiling the kernel with CONFIG_2G.
+
+Linus agreed on not breaking common code and to live with the 512 Gigabytes
+per-process limitation for the 2.4.x timeframe and he has given me and Andi
+some very useful hints... (thanks! :)
+
+Thanks also to H. Peter Anvin for his interesting and useful suggestions on
+the x86-64-discuss lists!
+
+Current PML4 Layout:
+	Each CPU has an PML4 page that never changes. 
+	Each slot is 512GB of virtual memory. 
+ 
+        0    user space pgd or 40MB low mapping at bootup.  Changed at context switch.
+        1    unmapped
+        2    __PAGE_OFFSET - start of direct mapping of physical memory
+        ...  direct mapping in further slots as needed.
+        510  vmalloc and ioremap space
+	511  kernel code mapping, fixmaps and modules.  
+
+Other memory management related issues follows:
+
+PAGE_SIZE:
+
+	If somebody is wondering why these days we still have a so small
+	4k pagesize (16 or 32 kbytes would be much better for performance
+	of course), the PAGE_SIZE have to remain 4k for 32bit apps to
+	provide 100% backwards compatible IA32 API (we can't allow silent
+	fs corruption or as best a loss of coherency with the page cache
+	by allocating MAP_SHARED areas in MAP_ANONYMOUS memory with a
+	do_mmap_fake). I think it could be possible to have a dynamic page
+	size between 32bit and 64bit apps but it would need extremely
+	intrusive changes in the common code as first for page cache and
+	we sure don't want to depend on them right now even if the
+	hardware would support that.
+
+PAGETABLE SIZE:
+
+	In turn we can't afford to have pagetables larger than 4k because
+	we could not be able to allocate them due physical memory
+	fragmentation, and failing to allocate the kernel stack is a minor
+	issue compared to failing the allocation of a pagetable. If we
+	fail the allocation of a pagetable the only thing we can do is to
+	sched_yield polling the freelist (deadlock prone) or to segfault
+	the task (not even the sighandler would be sure to run).
+
+KERNEL STACK:
+
+	1st stage:
+
+	The kernel stack will be at first allocated with an order 2 allocation
+	(16k) (the utilization of the stack for a 64bit platform really
+	isn't exactly the double of a 32bit platform because the local
+	variables may not be all 64bit wide, but not much less). This will
+	make things even worse than they are right now on IA32 with
+	respect of failing fork/clone due memory fragmentation.
+
+	2nd stage:
+
+	We'll benchmark if reserving one register as task_struct
+	pointer will improve performance of the kernel (instead of
+	recalculating the task_struct pointer starting from the stack
+	pointer each time). My guess is that recalculating will be faster
+	but it worth a try.
+
+		If reserving one register for the task_struct pointer
+		will be faster we can as well split task_struct and kernel
+		stack. task_struct can be a slab allocation or a
+		PAGE_SIZEd allocation, and the kernel stack can then be
+		allocated in a order 1 allocation. Really this is risky,
+		since 8k on a 64bit platform is going to be less than 7k
+		on a 32bit platform but we could try it out. This would
+		reduce the fragmentation problem of an order of magnitude
+		making it equal to the current IA32.
+
+		We must also consider the x86-64 seems to provide in hardware a
+		per-irq stack that could allow us to remove the irq handler
+		footprint from the regular per-process-stack, so it could allow
+		us to live with a smaller kernel stack compared to the other
+		linux architectures.
+
+	3rd stage:
+
+	Before going into production if we still have the order 2
+	allocation we can add a sysctl that allows the kernel stack to be
+	allocated with vmalloc during memory fragmentation. This have to
+	remain turned off during benchmarks :) but it should be ok in real
+	life.
+
+Order of PAGE_CACHE_SIZE and other allocations:
+
+	On the long run we can increase the PAGE_CACHE_SIZE to be
+	an order 2 allocations and also the slab/buffercache etc.ec..
+	could be all done with order 2 allocations. To make the above
+	to work we should change lots of common code thus it can be done
+	only once the basic port will be in a production state. Having
+	a working PAGE_CACHE_SIZE would be a benefit also for
+	IA32 and other architectures of course.
+
+vmalloc:
+	vmalloc should be outside the first 512GB to keep that space free
+	for the user space. It needs an own pgd to work on in common code. 
+	It currently gets an own pgd in the 510th slot of the per CPU PML4.
+	
+PML4: 
+        Each CPU as an own PML4 (=top level of the 4 level page hierarchy). On 
+        context switch the first slot is rewritten to the pgd of the new process 
+        and CR3 is flushed.
+    
+Modules: 
+	Modules need to be in the same 4GB range as the core kernel. Otherwise
+	a GOT would be needed. Modules are currently at 0xffffffffa0000000
+        to 0xffffffffafffffff. This is inbetween the kernel text and the 
+        vsyscall/fixmap mappings.
+
+Vsyscalls: 
+        Vsyscalls have a reserved space near the end of user space that is 
+        acessible by user space. This address is part of the ABI and cannot be
+        changed. They have ffffffffff600000 to ffffffffffe00000 (but only 
+        some small space at the beginning is allocated and known to user space 
+        currently). See vsyscall.c for more details. 
+
+Fixmaps: 
+        Fixed mappings set up at boot. Used to access IO APIC and some other hardware. 
+        These are at the end of vsyscall space (ffffffffffe00000) downwards, 
+        but are not accessible by user space of course.
+
+Early mapping:
+        On a 120TB memory system bootmem could use upto 3.5GB
+        of memory for its bootmem bitmap. To avoid having to map 3.5GB by hand
+        for bootmem's purposes the full direct mapping is created before bootmem
+        is initialized. The direct mapping needs some memory for its page tables,
+        these are directly taken from the physical memory after the kernel. To
+        access these pages they need to be mapped, this is done by a temporary 
+        mapping with a few spare static 2MB PMD entries.
+
+Unsolved issues: 
+	 2MB pages for user space - may need to add a highmem zone for that again to 
+	 avoid fragmentation.
+  
+Andrea <andrea@suse.de> SuSE
+Andi Kleen <ak@suse.de> SuSE
+
+$Id$
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/MAINTAINERS linux-2.4.20/MAINTAINERS
--- linux-2.4.19/MAINTAINERS	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/MAINTAINERS	2002-10-04 00:41:10.000000000 +0000
@@ -1,3 +1,4 @@
+	
 	List of maintainers and how to submit kernel changes
 
 Please try to follow the guidelines below.  This will make things
@@ -241,6 +242,12 @@
 W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
 S:	Maintained
 
+BEFS FILE SYSTEM
+P:	Will Dyson
+M:	will@cs.earlham.edu
+W:	http://cs.earlham.edu/~will/software/linux/kernel/BeFS.html
+S:	Maintained
+
 BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
 P:	Kenji Hollis
 M:	kenji@bitgate.com
@@ -266,6 +273,12 @@
 W:	http://bluez.sf.net
 S:	Maintained
 
+BLUETOOTH SUBSYSTEM (PC Card Drivers)
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
 BTTV VIDEO4LINUX DRIVER
 P:	Gerd Knorr
 M:	kraxel@bytesex.org
@@ -626,8 +639,8 @@
 S:	Maintained
 
 HFS FILESYSTEM
-P:      Adrian Sun
-M:      asun@cobaltnet.com
+P:      Oliver Neukum
+M:      oliver@neukum.org
 L:      linux-kernel@vger.kernel.org
 S:      Maintained
 
@@ -704,8 +717,10 @@
 S:	Maintained
 
 IBM ServeRAID RAID DRIVER
-P:      Keith Mitchell
-M:      ipslinux@us.ibm.com
+P:      Jack Hammer
+M:      ipslinux@adaptec.com
+P:      David Jeffery
+M:      ipslinux@adaptec.com
 W:      http://www.developer.ibm.com/welcome/netfinity/serveraid.html
 S:      Supported 
 
@@ -796,7 +811,7 @@
 IOC3 DRIVER
 P:	Ralf Baechle
 M:	ralf@oss.sgi.com
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 S:	Maintained
 
 IP MASQUERADING:
@@ -852,6 +867,13 @@
 W:	http://sources.redhat.com/jffs2/
 S:	Maintained
 
+JFS FILESYSTEM
+P:	Dave Kleikamp
+M:	shaggy@austin.ibm.com
+L:	jfs-discussion@oss.software.ibm.com
+W:	http://oss.software.ibm.com/developerworks/opensource/jfs/
+S:	Supported
+
 JOYSTICK DRIVER
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1001,7 +1023,7 @@
 P:	Ralf Baechle
 M:	ralf@gnu.org
 W:	http://oss.sgi.com/mips/mips-howto.html
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 S:	Maintained
 
 MISCELLANEOUS MCA-SUPPORT
@@ -1056,20 +1078,17 @@
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-NETFILTER
+NETFILTER/IPTABLES
 P:	Rusty Russell
-M:	rusty@rustcorp.com.au
 P:	Marc Boucher
-M:	marc@mbsi.ca
 P:	James Morris
-M:	jamesm@intercode.com.au
 P:	Harald Welte
-M:	laforge@gnumonks.org
 P:	Jozsef Kadlecsik
-M:	kadlec@blackhole.kfki.hu
+M:	coreteam@netfilter.org
 W:	http://www.netfilter.org/
 W:	http://www.iptables.org/
-L:	netfilter@lists.samba.org
+L:	netfilter@lists.netfilter.org
+L:	netfilter-devel@lists.netfilter.org
 S:	Supported
 
 NETROM NETWORK LAYER
@@ -1095,14 +1114,11 @@
 P:	Networking Team
 M:	netdev@oss.sgi.com
 L:	linux-net@vger.kernel.org
-W:	http://www.uk.linux.org/NetNews.html (2.0 only)
 S:	Maintained
 
 NETWORKING [IPv4/IPv6]
 P:	David S. Miller
 M:	davem@redhat.com
-P:	Andi Kleen
-M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
 P:	Pekka Savola (ipv6)
@@ -1257,7 +1273,7 @@
 PHILIPS NINO PALM PC
 P:	Steven Hill
 M:	sjhill@realitydiluted.com
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 W:	http://www.realitydiluted.com/projects/nino
 S:	Maintained
 
@@ -1353,10 +1369,10 @@
 S:	Maintained
 
 RME96XX MULTICHANNEL SOUND DRIVER
-P:      Guenter Geiger
-M:      geiger@epy.co.at  
-L:      linux-kernel@vger.kernel.org
-S:      Maintained
+P:	Guenter Geiger
+M:	geiger@epy.co.at  
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
 
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
@@ -1541,6 +1557,20 @@
 M:	hch@infradead.org
 S:	Maintained
 
+TI GRAPH LINK USB (SilverLink) CABLE DRIVER
+P:      Romain Lievin
+M:      roms@lpg.ticalc.org
+P:      Julien Blache
+M:      jb@technologeek.org
+S:      Maintained
+
+TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
+P:	Stephane Dalton
+M:	sdalton@videotron.ca
+P:	Stéphane Doyon
+M:	s.doyon@videotron.ca
+S:	Maintained
+
 TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
 P:	Stephane Dalton
 M:	sdalton@videotron.ca
@@ -1635,7 +1665,7 @@
 
 USB AUERSWALD DRIVER
 P:	Wolfgang Muees
-M:	wmues@nexgo.de
+M:	wolfgang@iksw-muees.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
@@ -1856,6 +1886,13 @@
 M:	mingo@redhat.com
 S:	Maintained
 
+X86-64 port
+P:	Andi Kleen
+M:	ak@suse.de
+L:	discuss@x86-64.org
+W:	http://www.x86-64.org
+S:	Maintained
+
 YAM DRIVER FOR AX.25
 P:	Jean-Paul Roubelat
 M:	jpr@f6fbb.org
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Makefile linux-2.4.20/Makefile
--- linux-2.4.19/Makefile	2002-08-03 00:39:46.000000000 +0000
+++ linux-2.4.20/Makefile	2002-10-04 00:41:11.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 19
-EXTRAVERSION =
+SUBLEVEL = 20
+EXTRAVERSION = -pre9
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -170,7 +170,7 @@
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
 DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o
+DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
@@ -180,11 +180,13 @@
 DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
 DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
 DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
+DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
 DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
 DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
 DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
 DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
+DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
@@ -258,7 +260,7 @@
 # 'kbuild_2_4_nostdinc :=' or -I/usr/include for kernel code and you are not UML
 # then your code is broken!  KAO.
 
-kbuild_2_4_nostdinc	:= -nostdinc $(shell $(CC) -print-search-dirs | sed -ne 's/install: \(.*\)/-I \1include/gp')
+kbuild_2_4_nostdinc	:= -nostdinc -iwithprefix include
 export kbuild_2_4_nostdinc
 
 export	CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
@@ -369,7 +371,7 @@
 TAGS: dummy
 	{ find include/asm-${ARCH} -name '*.h' -print ; \
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
-	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
+	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | grep -v '\.svn' | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
@@ -487,7 +489,7 @@
 
 dep-files: scripts/mkdep archdep include/linux/version.h
 	scripts/mkdep -- init/*.c > .depend
-	scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
+	scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
 	$(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
 ifdef CONFIG_MODVERSIONS
 	$(MAKE) update-modverfile
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/config.in linux-2.4.20/arch/alpha/config.in
--- linux-2.4.19/arch/alpha/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/alpha/config.in	2002-10-04 00:41:13.000000000 +0000
@@ -250,9 +250,9 @@
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   bool 'Discontiguous Memory Support (EXPERIMENTAL)' CONFIG_DISCONTIGMEM
    if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
-      bool ' NUMA Support' CONFIG_NUMA
+      bool ' NUMA Support (EXPERIMENTAL)' CONFIG_NUMA
    fi
 fi
 
@@ -360,7 +360,7 @@
 mainmenu_option next_comment
 comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+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
@@ -423,3 +423,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/pci.c linux-2.4.20/arch/alpha/kernel/pci.c
--- linux-2.4.19/arch/alpha/kernel/pci.c	2001-11-03 01:39:20.000000000 +0000
+++ linux-2.4.20/arch/alpha/kernel/pci.c	2002-10-04 00:41:10.000000000 +0000
@@ -128,7 +128,8 @@
 #define GB			(1024*MB)
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 	struct pci_controller *hose = dev->sysdata;
@@ -168,7 +169,7 @@
 		 */
 
 		/* Align to multiple of size of minimum base.  */
-		alignto = MAX(0x1000, size);
+		alignto = MAX(0x1000, align);
 		start = ALIGN(start, alignto);
 		if (hose->sparse_mem_base && size <= 7 * 16*MB) {
 			if (((start / (16*MB)) & 0x7) == 0) {
@@ -245,25 +246,6 @@
 		/* Root bus */
 		bus->resource[0] = hose->io_space;
 		bus->resource[1] = hose->mem_space;
-	} else {
-		/* This is a bridge. Do not care how it's initialized,
-		   just link its resources to the bus ones */
-		int i;
-
-		for(i=0; i<3; i++) {
-			bus->resource[i] =
-				&dev->resource[PCI_BRIDGE_RESOURCES+i];
-			bus->resource[i]->name = bus->name;
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-		/* For now, propogate hose limits to the bus;
-		   we'll adjust them later. */
-		bus->resource[0]->end = hose->io_space->end;
-		bus->resource[1]->end = hose->mem_space->end;
-		/* Turn off downstream PF memory address range by default */
-		bus->resource[2]->start = 1024*1024;
-		bus->resource[2]->end = bus->resource[2]->start - 1;
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -348,10 +330,14 @@
 	ranges->io_end -= hose->io_space->start;
 	ranges->mem_start -= hose->mem_space->start;
 	ranges->mem_end -= hose->mem_space->start;
+/* FIXME: On older alphas we could use dense memory space
+	  to access prefetchable resources. */
+	ranges->prefetch_start -= hose->mem_space->start;
+	ranges->prefetch_end -= hose->mem_space->start;
 }
 
 int
-pcibios_enable_device(struct pci_dev *dev)
+pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	/* Nothing to do, since we enable all devices at startup.  */
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/srm_env.c linux-2.4.20/arch/alpha/kernel/srm_env.c
--- linux-2.4.19/arch/alpha/kernel/srm_env.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/alpha/kernel/srm_env.c	2002-10-04 00:41:11.000000000 +0000
@@ -33,6 +33,15 @@
  * Changelog
  * ~~~~~~~~~
  *
+ * Thu, 22 Aug 2002 15:10:43 +0200
+ * 	- Update Config.help entry. I got a number of emails asking
+ * 	  me to tell their senders if they could make use of this
+ * 	  piece of code... So: "SRM is something like BIOS for your
+ * 	  Alpha"
+ * 	- Update code formatting a bit to better conform CodingStyle
+ * 	  rules.
+ * 	- So this is v0.0.5, with no changes (except formatting)
+ * 	
  * Wed, 22 May 2002 00:11:21 +0200
  * 	- Fix typo on comment (SRC -> SRM)
  * 	- Call this "Version 0.0.4"
@@ -59,13 +68,12 @@
 #define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
 #define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
 #define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
-#define VERSION		"0.0.4"			/* Module version		*/
+#define VERSION		"0.0.5"			/* Module version		*/
 #define NAME		"srm_env"		/* Module name			*/
 
 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
 MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
 MODULE_LICENSE("GPL");
-EXPORT_NO_SYMBOLS;
 
 typedef struct _srm_env {
 	char			*name;
@@ -98,9 +106,12 @@
 };
 static srm_env_t	srm_numbered_entries[256];
 
+
+
 static int
 srm_env_read(char *page, char **start, off_t off, int count, int *eof,
-		void *data) {
+		void *data)
+{
 	int		nbytes;
 	unsigned long	ret;
 	srm_env_t	*entry;
@@ -112,11 +123,11 @@
 		return -EFAULT;
 	}
 
-	entry	= (srm_env_t *)data;
+	entry	= (srm_env_t *) data;
 	ret	= callback_getenv(entry->id, page, count);
 
 	if((ret >> 61) == 0)
-		nbytes = (int)ret;
+		nbytes = (int) ret;
 	else
 		nbytes = -EFAULT;
 
@@ -125,9 +136,11 @@
 	return nbytes;
 }
 
+
 static int
 srm_env_write(struct file *file, const char *buffer, unsigned long count,
-		void *data) {
+		void *data)
+{
 #define BUFLEN	512
 	int		nbytes;
 	srm_env_t	*entry;
@@ -157,7 +170,7 @@
 		do 
 			ret2 = callback_save_env();
 		while((ret2 >> 61) == 1);
-		nbytes = (int)ret1;
+		nbytes = (int) ret1;
 	} else
 		nbytes = -EFAULT;
 
@@ -166,8 +179,10 @@
 	return nbytes;
 }
 
+
 static void
-srm_env_cleanup(void) {
+srm_env_cleanup(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -211,8 +226,10 @@
 	return;
 }
 
+
 static int __init
-srm_env_init(void) {
+srm_env_init(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -221,7 +238,9 @@
 	 */
 	if(!alpha_using_srm) {
 		printk(KERN_INFO "%s: This Alpha system doesn't "
-				"know about SRM...\n", __FUNCTION__);
+				"know about SRM (or you've booted "
+				"SRM->MILO->Linux, which gets "
+				"misdetected)...\n", __FUNCTION__);
 		return -ENODEV;
 	}
 
@@ -275,7 +294,7 @@
 		if(entry->proc_entry == NULL)
 			goto cleanup;
 
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -296,7 +315,7 @@
 			goto cleanup;
 
 		entry->id			= var_num;
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -304,20 +323,26 @@
 
 	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
 			VERSION);
+
 	return 0;
 
 cleanup:
 	srm_env_cleanup();
+
 	return -ENOMEM;
 }
 
+
 static void __exit
-srm_env_exit(void) {
+srm_env_exit(void)
+{
 	srm_env_cleanup();
 	printk(KERN_INFO "%s: unloaded successfully\n", NAME);
+
 	return;
 }
 
+
 module_init(srm_env_init);
 module_exit(srm_env_exit);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/traps.c linux-2.4.20/arch/alpha/kernel/traps.c
--- linux-2.4.19/arch/alpha/kernel/traps.c	2001-11-20 23:49:31.000000000 +0000
+++ linux-2.4.20/arch/alpha/kernel/traps.c	2002-10-04 00:41:14.000000000 +0000
@@ -167,6 +167,11 @@
 	dik_show_trace(sp);
 }
 
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
+
 void
 die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/lib/stxncpy.S linux-2.4.20/arch/alpha/lib/stxncpy.S
--- linux-2.4.19/arch/alpha/lib/stxncpy.S	2000-12-11 21:46:26.000000000 +0000
+++ linux-2.4.20/arch/alpha/lib/stxncpy.S	2002-10-04 00:41:30.000000000 +0000
@@ -164,26 +164,29 @@
 	or	t0, t6, t6	# e1    : mask original data for zero test
 	cmpbge	zero, t6, t8	# e0    :
 	beq	a2, $u_eocfin	# .. e1 :
-	bne	t8, $u_final	# e1    :
+	lda	t6, -1		# e0    :
+	bne	t8, $u_final	# .. e1 :
 
-	lda	t6, -1			# e1    : mask out the bits we have
-	mskql	t6, a1, t6		# e0    :   already seen
-	stq_u	t0, 0(a0)		# e0    : store first output word
-	or      t6, t2, t2		# .. e1 :
-	cmpbge	zero, t2, t8		# e0    : find nulls in second partial
-	addq	a0, 8, a0		# .. e1 :
-	subq	a2, 1, a2		# e0    :
+	mskql	t6, a1, t6	# e0    : mask out bits already seen
+	nop			# .. e1 :
+	stq_u	t0, 0(a0)	# e0    : store first output word
+	or      t6, t2, t2	# .. e1 :
+	cmpbge	zero, t2, t8	# e0    : find nulls in second partial
+	addq	a0, 8, a0	# .. e1 :
+	subq	a2, 1, a2	# e0    :
 	bne	t8, $u_late_head_exit	# .. e1 :
 
 	/* Finally, we've got all the stupid leading edge cases taken care
 	   of and we can set up to enter the main loop.  */
 
 	extql	t2, a1, t1	# e0    : position hi-bits of lo word
-	ldq_u	t2, 8(a1)	# .. e1 : read next high-order source word
-	addq	a1, 8, a1	# e0    :
-	cmpbge	zero, t2, t8	# e1 (stall)
-	beq	a2, $u_eoc	# e1    :
-	bne	t8, $u_eos	# e1    :
+	beq	a2, $u_eoc	# .. e1 :
+	ldq_u	t2, 8(a1)	# e0    : read next high-order source word
+	addq	a1, 8, a1	# .. e1 :
+	extqh	t2, a1, t0	# e0    : position lo-bits of hi word (stall)
+	cmpbge	zero, t2, t8	# .. e1 :
+	nop			# e0    :
+	bne	t8, $u_eos	# .. e1 :
 
 	/* Unaligned copy main loop.  In order to avoid reading too much,
 	   the loop is structured to detect zeros in aligned source words.
@@ -193,6 +196,7 @@
 	   to run as fast as possible.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word
 
@@ -200,18 +204,18 @@
 
 	.align 3
 $u_loop:
-	extqh	t2, a1, t0	# e0    : extract high bits for current word
-	addq	a1, 8, a1	# .. e1 :
-	extql	t2, a1, t3	# e0    : extract low bits for next time
-	addq	a0, 8, a0	# .. e1 :
 	or	t0, t1, t0	# e0    : current dst word now complete
-	ldq_u	t2, 0(a1)	# .. e1 : load high word for next time
-	stq_u	t0, -8(a0)	# e0    : save the current word
-	mov	t3, t1		# .. e1 :
-	subq	a2, 1, a2	# e0    :
-	cmpbge	zero, t2, t8	# .. e1 : test new word for eos
-	beq	a2, $u_eoc	# e1    :
-	beq	t8, $u_loop	# e1    :
+	subq	a2, 1, a2	# .. e1 : decrement word count
+	stq_u	t0, 0(a0)	# e0    : save the current word
+	addq	a0, 8, a0	# .. e1 :
+	extql	t2, a1, t1	# e0    : extract high bits for next time
+	beq	a2, $u_eoc	# .. e1 :
+	ldq_u	t2, 0(a1)	# e0    : load high word for next time
+	addq	a1, 8, a1	# .. e1 :
+	nop			# e0    :
+	cmpbge	zero, t2, t8	# e1    : test new word for eos (stall)
+	extqh	t2, a1, t0	# e0    : extract low bits for current word
+	beq	t8, $u_loop	# .. e1 :
 
 	/* We've found a zero somewhere in the source word we just read.
 	   If it resides in the lower half, we have one (probably partial)
@@ -219,12 +223,12 @@
 	   have one full and one partial word left to write out.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word.  */
 $u_eos:
-	extqh	t2, a1, t0	# e0    :
-	or	t0, t1, t0	# e1    : first (partial) source word complete
-
+	or	t0, t1, t0	# e0    : first (partial) source word complete
+	nop			# .. e1 :
 	cmpbge	zero, t0, t8	# e0    : is the null in this first bit?
 	bne	t8, $u_final	# .. e1 (zdb)
 
@@ -260,10 +264,22 @@
 1:	stq_u	t0, 0(a0)	# e0    :
 	ret	(t9)		# .. e1 :
 
-$u_eoc:				# end-of-count
-	extqh	t2, a1, t0
-	or	t0, t1, t0
-	cmpbge	zero, t0, t8
+	/* Got to end-of-count before end of string.  
+	   On entry to this basic block:
+	   t1 == the shifted high-order bits from the previous source word  */
+$u_eoc:
+	and	a1, 7, t6	# e1    :
+	sll	t12, t6, t6	# e0    :
+	and	t6, 0xff, t6	# e0    :
+	bne	t6, 1f		# .. e1 :
+
+	ldq_u	t2, 8(a1)	# e0    : load final src word
+	nop			# .. e1 :
+	extqh	t2, a1, t0	# e0    : extract low bits for last word
+	or	t1, t0, t1	# e1    :
+
+1:	cmpbge	zero, t1, t7
+	mov	t1, t0
 
 $u_eocfin:			# end-of-count, final word
 	or	t10, t8, t8
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/mm/fault.c linux-2.4.20/arch/alpha/mm/fault.c
--- linux-2.4.19/arch/alpha/mm/fault.c	2001-09-17 23:15:02.000000000 +0000
+++ linux-2.4.20/arch/alpha/mm/fault.c	2002-10-04 00:41:14.000000000 +0000
@@ -88,6 +88,7 @@
 	struct mm_struct *mm = current->mm;
 	unsigned int fixup;
 	int fault;
+	siginfo_t info;
 
 	/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
 	   (or is suppressed by the PALcode).  Support that for older CPUs
@@ -108,6 +109,8 @@
 	if (!mm || in_interrupt())
 		goto no_context;
 
+	info.si_code = SEGV_MAPERR;
+
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 	if (address >= TASK_SIZE)
 		goto vmalloc_fault;
@@ -128,6 +131,7 @@
  * we can handle it..
  */
 good_area:
+	info.si_code = SEGV_ACCERR;
 	if (cause < 0) {
 		if (!(vma->vm_flags & VM_EXEC))
 			goto bad_area;
@@ -147,13 +151,12 @@
 	 * the fault.
 	 */
 	fault = handle_mm_fault(mm, vma, address, cause > 0);
-	up_read(&mm->mmap_sem);
-
 	if (fault < 0)
 		goto out_of_memory;
 	if (fault == 0)
 		goto do_sigbus;
 
+	up_read(&mm->mmap_sem);
 	return;
 
 /*
@@ -164,7 +167,12 @@
 	up_read(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+			
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *)address;
+		force_sig_info(SIGSEGV,&info,current);
 		return;
 	}
 
@@ -196,11 +204,10 @@
  */
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk(KERN_ALERT "VM: killing process %s(%d)\n",
 	       current->comm, current->pid);
 	if (!user_mode(regs))
@@ -208,11 +215,17 @@
 	do_exit(SIGKILL);
 
 do_sigbus:
+	up_read(&mm->mmap_sem);
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	force_sig(SIGBUS, current);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	/* not sure si_code value here  */
+	info.si_code =  BUS_ADRERR;
+	info.si_addr = (void *)address;
+	force_sig_info(SIGBUS,&info,current);
 	if (!user_mode(regs))
 		goto no_context;
 	return;
@@ -220,7 +233,11 @@
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 vmalloc_fault:
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *)address;
+		force_sig_info(SIGSEGV,&info,current);
 		return;
 	} else {
 		/* Synchronize this task's top level page-table
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/config.in linux-2.4.20/arch/arm/config.in
--- linux-2.4.19/arch/arm/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/arm/config.in	2002-10-04 00:41:13.000000000 +0000
@@ -417,7 +417,7 @@
 fi
 
 source drivers/pci/Config.in
-bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
 if [ "$CONFIG_HOTPLUG" = "y" ]; then
    source drivers/pcmcia/Config.in
 else
@@ -503,7 +503,7 @@
    mainmenu_option next_comment
    comment 'Network device support'
 
-   bool 'Network device support?' CONFIG_NETDEVICES
+   bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
    fi
@@ -530,7 +530,7 @@
 mainmenu_option next_comment
 comment 'SCSI support'
 
-tristate 'SCSI support?' CONFIG_SCSI
+tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
    source drivers/scsi/Config.in
@@ -618,7 +618,7 @@
    mainmenu_option next_comment
    comment 'Sound'
 
-   tristate 'Sound support' CONFIG_SOUND
+   tristate 'Sound card support' CONFIG_SOUND
    if [ "$CONFIG_SOUND" != "n" ]; then
       source drivers/sound/Config.in
    fi
@@ -655,3 +655,5 @@
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/kernel/bios32.c linux-2.4.20/arch/arm/kernel/bios32.c
--- linux-2.4.19/arch/arm/kernel/bios32.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/arm/kernel/bios32.c	2002-10-04 00:41:16.000000000 +0000
@@ -354,25 +354,7 @@
 	struct pci_dev *dev = bus->self;
 	int i;
 
-	if (dev) {
-		for (i = 0; i < 3; i++) {
-			if(root->resource[i]) {
-				bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-				bus->resource[i]->end  = root->resource[i]->end;
-				bus->resource[i]->name = bus->name;
-			}
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-
-		if (root->resource[2])
-			bus->resource[2]->flags = root->resource[2]->flags;
-		else {
-			/* no prefetchable memory region - disable it */
-			bus->resource[2]->start = 1024*1024;
-			bus->resource[2]->end   = bus->resource[2]->start - 1;
-		}
-	} else {
+	if (!dev) {
 		/*
 		 * Assign root bus resources.
 		 */
@@ -587,7 +569,8 @@
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-integrator/cpu.c linux-2.4.20/arch/arm/mach-integrator/cpu.c
--- linux-2.4.19/arch/arm/mach-integrator/cpu.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.20/arch/arm/mach-integrator/cpu.c	2002-10-04 00:41:20.000000000 +0000
@@ -121,7 +121,7 @@
 	cpu_freq_khz = vco_to_freq(vco, 1);
 
 #ifdef CONFIG_CPU_FREQ
-	cpufreq_init(cpu_freq_khz);
+	cpufreq_init(cpu_freq_khz, 1000, 0);
 	cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-sa1100/generic.c linux-2.4.20/arch/arm/mach-sa1100/generic.c
--- linux-2.4.19/arch/arm/mach-sa1100/generic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/arm/mach-sa1100/generic.c	2002-10-04 00:41:14.000000000 +0000
@@ -86,7 +86,7 @@
 
 static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mm/fault-common.c linux-2.4.20/arch/arm/mm/fault-common.c
--- linux-2.4.19/arch/arm/mm/fault-common.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/arm/mm/fault-common.c	2002-10-04 00:41:10.000000000 +0000
@@ -225,8 +225,7 @@
 	 * If we are out of memory for pid1,
 	 * sleep for a while and retry
 	 */
-	tsk->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	goto survive;
 
 check_stack:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/config.in linux-2.4.20/arch/cris/config.in
--- linux-2.4.19/arch/cris/config.in	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.20/arch/cris/config.in	2002-10-04 00:41:10.000000000 +0000
@@ -39,6 +39,8 @@
 	bool 'Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
 fi
 
+bool 'Enable ETRAX fast timer API' CONFIG_ETRAX_FAST_TIMER
+
 endmenu
 
 mainmenu_option next_comment
@@ -253,4 +255,6 @@
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
+
+source lib/Config.in
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Config.in linux-2.4.20/arch/cris/drivers/Config.in
--- linux-2.4.19/arch/cris/drivers/Config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/Config.in	2002-10-04 00:41:13.000000000 +0000
@@ -23,8 +23,7 @@
 
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
-#  bool '  Use fast timers for DMA flush and RS-485 timing' CONFIG_ETRAX_SERIAL_FAST_TIMER n
-  define_bool CONFIG_ETRAX_SERIAL_FAST_TIMER n
+  bool '  Use fast timers for serial DMA flush (experimental)' CONFIG_ETRAX_SERIAL_FAST_TIMER
   if [ "$CONFIG_ETRAX_SERIAL_FAST_TIMER" = "n" ]; then
     bool '  Fast serial port DMA flush' CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
     if [ "$CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST" = "n" ]; then
@@ -156,6 +155,11 @@
 # this is true for most products since PB-I2C seems to be somewhat
 # flawed.. 
 	bool 'I2C uses PB not PB-I2C' CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+
+	if [ "$CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C" = "y" ]; then
+          int '  I2C SDA bit number' CONFIG_ETRAX_I2C_DATA_PORT 0
+          int '  I2C SCL bit number' CONFIG_ETRAX_I2C_CLK_PORT 1
+	fi
 fi
 
 bool 'I2C EEPROM (non-volatile RAM) support' CONFIG_ETRAX_I2C_EEPROM
@@ -182,6 +186,8 @@
 
 fi
 
+bool 'VIRTEX FPGA support' CONFIG_ETRAX_VIRTEX_FPGA
+
 bool 'USB host' CONFIG_ETRAX_USB_HOST
 if [ "$CONFIG_ETRAX_USB_HOST" = "y" ]; then
 	define_bool CONFIG_USB y
@@ -191,7 +197,13 @@
 	define_bool CONFIG_USB n
 fi
 
-bool 'DS1302 Real Time Clock support' CONFIG_ETRAX_DS1302
+bool 'Real Time Clock support' CONFIG_ETRAX_RTC
+if [ "$CONFIG_ETRAX_RTC" = "y" ]; then
+  choice '  RTC chip' \
+    "DS1302 CONFIG_ETRAX_DS1302 \
+     PCF8563  CONFIG_ETRAX_PCF8563" DS1302
+fi
+
 if [ "$CONFIG_ETRAX_DS1302" = "y" ]; then
   bool '  DS1302 RST on Generic Port' CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
   int '  DS1302 RST bit number' CONFIG_ETRAX_DS1302_RSTBIT 2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Makefile linux-2.4.20/arch/cris/drivers/Makefile
--- linux-2.4.19/arch/cris/drivers/Makefile	2001-07-04 18:50:38.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/Makefile	2002-10-04 00:41:09.000000000 +0000
@@ -6,7 +6,7 @@
 
 obj-y :=
 
-
+obj-$(CONFIG_ETRAX_VIRTEX_FPGA)         += virtex.o
 obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
 obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
 obj-$(CONFIG_ETRAX_IDE)                 += ide.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/ds1302.c linux-2.4.20/arch/cris/drivers/ds1302.c
--- linux-2.4.19/arch/cris/drivers/ds1302.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/ds1302.c	2002-10-04 00:41:29.000000000 +0000
@@ -7,6 +7,9 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.13  2002/05/29 15:16:08  johana
+*! Removed unused variables.
+*!
 *! Revision 1.12  2002/04/10 15:35:25  johana
 *! Moved probe function closer to init function and marked it __init.
 *!
@@ -85,7 +88,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.12 2002/04/10 15:35:25 johana Exp $
+*! $Id: ds1302.c,v 1.13 2002/05/29 15:16:08 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -322,7 +325,6 @@
 		{
 			struct rtc_time rtc_tm;
 			unsigned char mon, day, hrs, min, sec, leap_yr;
-			unsigned char save_control, save_freq_select;
 			unsigned int yrs;
 
 			if (!capable(CAP_SYS_TIME))
@@ -386,7 +388,6 @@
 		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
 			int tcs_val;                        
-			unsigned char save_control, save_freq_select;
 
 			if (!capable(CAP_SYS_TIME))
 				return -EPERM;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/gpio.c linux-2.4.20/arch/cris/drivers/gpio.c
--- linux-2.4.19/arch/cris/drivers/gpio.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/gpio.c	2002-10-04 00:41:09.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.15 2002/05/06 13:19:13 johana Exp $
+/* $Id: gpio.c,v 1.17 2002/06/17 15:53:01 johana Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,18 @@
  *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.17  2002/06/17 15:53:01  johana
+ * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
+ * that take a pointer as argument and thus can handle 32 bit ports (G)
+ * correctly.
+ * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
+ * (especially if Port G bit 31 is used)
+ *
+ * Revision 1.16  2002/06/17 09:59:51  johana
+ * Returning 32 bit values in the ioctl return value doesn't work if bit
+ * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
+ * A new set of ioctl's will be added.
+ *
  * Revision 1.15  2002/05/06 13:19:13  johana
  * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
  *
@@ -330,6 +342,107 @@
  * set alarms to wait for using a subsequent select().
  */
 
+unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
+{
+	/* Set direction 0=unchanged 1=input, 
+	 * return mask with 1=input 
+	 */
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow &= 
+		~((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return ~(*priv->dir_shadow);
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */
+		if (((arg & dir_g_in_bits) != arg) && 
+		    (arg & changeable_dir_g)) {
+			arg &= changeable_dir_g;
+			/* Clear bits in genconfig to set to input */
+			if (arg & (1<<0)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_in_bits |= (1<<0);
+				dir_g_out_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_in_bits |= 0x0000FF00;
+				dir_g_out_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_in_bits |= 0x00FF0000;
+				dir_g_out_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_in_bits |= (1<<24);
+				dir_g_out_bits &= ~(1<<24);
+			}
+			printk("gpio: SETINPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+				
+		}
+		return dir_g_in_bits;
+	}
+	return 0;
+} /* setget_input */
+
+unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
+{
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow |= 
+		  ((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return *priv->dir_shadow;
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */			
+		if (((arg & dir_g_out_bits) != arg) &&
+		    (arg & changeable_dir_g)) {
+			/* Set bits in genconfig to set to output */
+			if (arg & (1<<0)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_out_bits |= (1<<0);
+				dir_g_in_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_out_bits |= 0x0000FF00;
+				dir_g_in_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_out_bits |= 0x00FF0000;
+				dir_g_in_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_out_bits |= (1<<24);
+				dir_g_in_bits &= ~(1<<24);
+			}
+			printk("gpio: SETOUTPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+		}
+		return dir_g_out_bits & 0x7FFFFFFF;
+	}
+	return 0;
+} /* setget_output */
+
 static int
 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
 
@@ -338,18 +451,19 @@
 	   unsigned int cmd, unsigned long arg)
 {
 	unsigned long flags;
+	unsigned long val;
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
 		return -EINVAL;
 	}
 
 	switch (_IOC_NR(cmd)) {
-	case IO_READBITS:
+	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
 		// read the port
 		if (USE_PORTS(priv)) {
 			return *priv->port;
 		} else if (priv->minor == GPIO_MINOR_G) {
-			return *R_PORT_G_DATA;
+			return (*R_PORT_G_DATA) & 0x7FFFFFFF;
 		}
 		break;
 	case IO_SETBITS:
@@ -387,113 +501,28 @@
 		priv->highalarm &= ~arg;
 		priv->lowalarm  &= ~arg;
 		break;
-	case IO_READDIR:
+	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
 		/* Read direction 0=input 1=output */
 		if (USE_PORTS(priv)) {
 			return *priv->dir_shadow;
 		} else if (priv->minor == GPIO_MINOR_G) {
 			/* Note: Some bits are both in and out,
-			 * Those that are dual is set hare as well.
+			 * Those that are dual is set here as well.
 			 */
-			return dir_g_shadow | dir_g_out_bits;
+			return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
 		}
-	case IO_SETINPUT:
+	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
 		/* Set direction 0=unchanged 1=input, 
 		 * return mask with 1=input 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow &= 
-			~((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return ~(*priv->dir_shadow);
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */
-			if (((arg & dir_g_in_bits) != arg) && 
-			    (arg & changeable_dir_g)) {
-				arg &= changeable_dir_g;
-				/* Clear bits in genconfig to set to input */
-				if (arg & (1<<0)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_in_bits |= (1<<0);
-					dir_g_out_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_in_bits |= 0x0000FF00;
-					dir_g_out_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_in_bits |= 0x00FF0000;
-					dir_g_out_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_in_bits |= (1<<24);
-					dir_g_out_bits &= ~(1<<24);
-				}
-				printk("gpio: SETINPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-				
-			}
-			return dir_g_in_bits;
-		}
-		return 0;
-
-	case IO_SETOUTPUT:
+		return setget_input(priv, arg) & 0x7FFFFFFF;
+		break;
+	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
 		/* Set direction 0=unchanged 1=output, 
 		 * return mask with 1=output 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow |= 
-			  ((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return *priv->dir_shadow;
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */			
-			if (((arg & dir_g_out_bits) != arg) &&
-			    (arg & changeable_dir_g)) {
-				/* Set bits in genconfig to set to output */
-				if (arg & (1<<0)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_out_bits |= (1<<0);
-					dir_g_in_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_out_bits |= 0x0000FF00;
-					dir_g_in_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_out_bits |= 0x00FF0000;
-					dir_g_in_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_out_bits |= (1<<24);
-					dir_g_in_bits &= ~(1<<24);
-				}
-				printk("gpio: SETOUTPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-			}
-			return dir_g_out_bits;
-		}
-		return 0;
+		return setget_output(priv, arg) & 0x7FFFFFFF;
+
 	case IO_SHUTDOWN:
 		SOFT_SHUTDOWN();
 		break;
@@ -521,6 +550,47 @@
 			return -EPERM;
 		}
 		break;
+	case IO_READ_INBITS: 
+		/* *arg is result of reading the input pins */
+		if (USE_PORTS(priv)) {
+			val = *priv->port;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = *R_PORT_G_DATA;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		return 0;
+		break;
+	case IO_READ_OUTBITS:
+		 /* *arg is result of reading the output shadow */
+		if (USE_PORTS(priv)) {
+			val = *priv->shadow;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = port_g_data_shadow;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_INPUT: 
+		/* bits set in *arg is set to input,
+		 * *arg updated with current input pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_input(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_OUTPUT:
+		/* bits set in *arg is set to output,
+		 * *arg updated with current output pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_output(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
 	default:
 		if (priv->minor == GPIO_MINOR_LEDS)
 			return gpio_leds_ioctl(cmd, arg);
@@ -690,7 +760,7 @@
 
 #endif
 	gpio_init_port_g();
-	printk("ETRAX 100LX GPIO driver v2.3, (c) 2001, 2002 Axis Communications AB\n");
+	printk("ETRAX 100LX GPIO driver v2.4, (c) 2001, 2002 Axis Communications AB\n");
 
 	return res;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/i2c.c linux-2.4.20/arch/cris/drivers/i2c.c
--- linux-2.4.19/arch/cris/drivers/i2c.c	2001-05-20 00:43:05.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/i2c.c	2002-10-04 00:41:10.000000000 +0000
@@ -12,6 +12,10 @@
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
 *! $Log: i2c.c,v $
+*! Revision 1.8  2002/08/13 06:31:53  starvik
+*! Made SDA and SCL line configurable
+*! Modified i2c_inbyte to work with PCF8563
+*!
 *! Revision 1.7  2001/04/04 13:11:36  markusl
 *! Updated according to review remarks
 *!
@@ -40,10 +44,10 @@
 *!
 *! ---------------------------------------------------------------------------
 *!
-*! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
+*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.7 2001/04/04 13:11:36 markusl Exp $ */
+/* $Id: i2c.c,v 1.8 2002/08/13 06:31:53 starvik Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -93,8 +97,15 @@
 
 #ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
 /* Use PB and not PB_I2C */
-#define SDABIT 0
-#define SCLBIT 1
+#ifndef CONFIG_ETRAX_I2C_DATA_PORT
+#define CONFIG_ETRAX_I2C_DATA_PORT 0
+#endif
+#ifndef CONFIG_ETRAX_I2C_CLK_PORT
+#define CONFIG_ETRAX_I2C_CLK_PORT 1
+#endif
+
+#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
+#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
 #define i2c_enable() 
 #define i2c_disable() 
 
@@ -114,7 +125,7 @@
 
 /* read a bit from the i2c interface */
 
-#define i2c_getbit() (*R_PORT_PB_READ & (1 << SDABIT))
+#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
 
 #else
 /* enable or disable the i2c interface */
@@ -206,7 +217,7 @@
 i2c_outbyte(unsigned char x)
 {
 	int i;
-	
+
 	i2c_dir_out();
 
 	for (i = 0; i < 8; i++) {
@@ -238,65 +249,44 @@
 {
 	unsigned char aBitByte = 0;
 	int i;
-	int iaa;
 
-	/*
-	 * enable output
-	 */
-	i2c_dir_out();
-	/*
-	 * Release data bus by setting
-	 * data high
-	 */
-	i2c_data(I2C_DATA_HIGH);
-	/*
-	 * enable input
-	 */
+	/* Switch off I2C to get bit */
+	i2c_disable();
 	i2c_dir_in();
-	/*
-	 * Use PORT PB instead of I2C
-	 * for input. (I2C not working)
-	 */
-	i2c_clk(1);
-	i2c_data(1);
-	/*
-	 * get bits
-	 */
-	for (i = 0; i < 8; i++) {
-		i2c_delay(CLOCK_LOW_TIME/2);
-		/*
-		 * low clock period
-		 */
+	i2c_delay(CLOCK_HIGH_TIME/2);
+
+	/* Get bit */
+	aBitByte |= i2c_getbit();
+
+	/* Enable I2C */
+	i2c_enable();
+	i2c_dir_out();
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	for (i = 1; i < 8; i++) {
+		aBitByte <<= 1;
+		/* Clock pulse */
 		i2c_clk(I2C_CLOCK_HIGH);
-		/*
-		 * switch off I2C
-		 */
-		i2c_data(1);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+
+		/* Switch off I2C to get bit */
 		i2c_disable();
 		i2c_dir_in();
-		/*
-		 * wait before getting bit
-		 */
-		i2c_delay(CLOCK_HIGH_TIME/2);
-		aBitByte = (aBitByte << 1);
-		iaa = i2c_getbit();
-		aBitByte = aBitByte | iaa ;
-		/*
-		 * wait
-		 */
 		i2c_delay(CLOCK_HIGH_TIME/2);
-		/*
-		 * end clock puls
-		 */
+
+		/* Get bit */
+		aBitByte |= i2c_getbit();
+
+		/* Enable I2C */
 		i2c_enable();
 		i2c_dir_out();
-		i2c_clk(I2C_CLOCK_LOW);
-		/*
-		 * low clock period
-		 */
 		i2c_delay(CLOCK_LOW_TIME/2);
 	}
-	i2c_dir_out();
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
 	return aBitByte;
 }
 
@@ -421,7 +411,7 @@
 *#
 *#--------------------------------------------------------------------------*/
 int
-i2c_writereg(unsigned char theSlave, unsigned char theReg,
+i2c_writereg(unsigned char theSlave, unsigned char theReg, 
 	     unsigned char theValue)
 {
 	int error, cntr = 3;
@@ -434,31 +424,12 @@
 		 */
 		save_flags(flags);
 		cli();
-		/*
-		 * generate start condition
-		 */
-		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
 
 		i2c_start();
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
@@ -493,7 +464,7 @@
 		restore_flags(flags);
 		
 	} while(error && cntr--);
-	
+
 	i2c_delay(CLOCK_LOW_TIME);
 	
 	return -error;
@@ -512,7 +483,7 @@
 	unsigned char b = 0;
 	int error, cntr = 3;
 	unsigned long flags;
-		
+
 	do {
 		error = 0;
 		/*
@@ -524,28 +495,11 @@
 		 * generate start condition
 		 */
 		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-    
-		i2c_start();
     
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/pcf8563.c linux-2.4.20/arch/cris/drivers/pcf8563.c
--- linux-2.4.19/arch/cris/drivers/pcf8563.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/pcf8563.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,258 @@
+/*
+ * PCF8563 RTC
+ *
+ * From Phillips' datasheet:
+ *
+ * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
+ * consumption. A programmable clock output, interupt output and voltage
+ * low detector are also provided. All address and data are transferred
+ * serially via two-line bidirectional I2C-bus. Maximum bus speed is
+ * 400 kbits/s. The built-in word address register is incremented
+ * automatically after each written or read bute.
+ *
+ * Copyright (c) 2002, Axis Communications AB
+ * All rights reserved.
+ *
+ * Author: Tobias Anderberg <tobiasa@axis.com>.
+ *
+ * $Id: pcf8563.c,v 1.1 2002/08/12 13:46:02 starvik Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/svinto.h>
+#include <asm/rtc.h>
+#include "i2c.h"
+
+#define PCF8563_MAJOR 121		/* Local major number. */
+#define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
+#define PCF8563_NAME "PCF8563"
+#define DRIVER_VERSION "$Rev$"
+
+/* Two simple wrapper macros, saves a few keystrokes. */
+#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
+#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+	
+static const unsigned char days_in_month[] =
+	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int pcf8563_open(struct inode *, struct file *);
+int pcf8563_release(struct inode *, struct file *);
+
+static struct file_operations pcf8563_fops = {
+	owner: THIS_MODULE,
+	ioctl: pcf8563_ioctl,
+	open: pcf8563_open,
+	release: pcf8563_release,
+};
+
+void
+get_rtc_time(struct rtc_time *tm)
+{
+	unsigned long flags;
+	
+	tm->tm_sec = rtc_read(RTC_SECONDS);
+	tm->tm_min = rtc_read(RTC_MINUTES);
+	tm->tm_hour = rtc_read(RTC_HOURS);
+	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
+	tm->tm_mon = rtc_read(RTC_MONTH);
+	tm->tm_year = rtc_read(RTC_YEAR);
+
+	if (tm->tm_sec & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+
+        tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
+	tm->tm_sec &= 0x7f;
+	tm->tm_min &= 0x7f;
+	tm->tm_hour &= 0x3f;
+	tm->tm_mday &= 0x3f;
+	tm->tm_mon &= 0x1f;
+
+	BCD_TO_BIN(tm->tm_sec);
+	BCD_TO_BIN(tm->tm_min);
+	BCD_TO_BIN(tm->tm_hour);
+	BCD_TO_BIN(tm->tm_mday);
+	BCD_TO_BIN(tm->tm_mon);
+	tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
+}
+
+int __init
+pcf8563_init(void)
+{
+	unsigned char ret;
+        struct rtc_time tm;
+        
+	/*
+	 * First of all we need to reset the chip. This is done by
+	 * clearing control1, control2 and clk freq, clear the 
+	 * Voltage Low bit, and resetting all alarms.
+	 */
+	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CONTROL2, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
+		goto err;
+
+	/* Clear the VL bit in the seconds register. */
+	ret = rtc_read(RTC_SECONDS);
+	
+	if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
+		goto err;
+		
+	/* Reset the alarms. */
+	if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
+		goto err;
+
+	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
+		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", 
+		       PCF8563_NAME, PCF8563_MAJOR);
+		return -1;
+	}
+
+	printk(KERN_INFO "%s Real-Time Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
+        
+	/* Check for low voltage, and warn about it.. */
+	if (rtc_read(RTC_SECONDS) & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+	
+	return 0;
+
+err:
+	printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
+	return -1;
+}
+
+void __exit
+pcf8563_exit(void)
+{
+	if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
+		printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
+	}
+}
+
+/*
+ * ioctl calls for this driver. Why return -ENOTTY upon error? Because
+ * POSIX says so!
+ */
+int
+pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	/* Some sanity checks. */
+	if (_IOC_TYPE(cmd) != PCF8563_MAGIC)
+		return -ENOTTY;
+
+	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
+		return -ENOTTY;
+
+	switch (cmd) {
+		case RTC_RD_TIME:
+			{
+				struct rtc_time tm;
+
+				get_rtc_time(&tm);
+
+				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
+					return -EFAULT;
+				}
+
+				return 0;
+			}
+			break;
+		case RTC_SET_TIME:
+			{
+				int leap;
+				int century;
+				unsigned long flags;
+				struct rtc_time tm;
+
+				if (!capable(CAP_SYS_TIME))
+					return -EPERM;
+
+				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
+					return -EFAULT;
+
+				/* Convert from struct tm to struct rtc_time. */
+				tm.tm_year += 1900;
+				tm.tm_mon += 1;
+				
+				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
+
+				/* Perform some sanity checks. */
+				if ((tm.tm_year < 1970) ||
+				    (tm.tm_mon > 12) ||
+				    (tm.tm_mday == 0) ||
+				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+				    (tm.tm_hour >= 24) ||
+				    (tm.tm_min >= 60) ||
+				    (tm.tm_sec >= 60))
+					return -EINVAL;
+
+				century = (tm.tm_year >= 2000) ? 0x80 : 0;
+				tm.tm_year = tm.tm_year % 100;
+
+				BIN_TO_BCD(tm.tm_year);
+				BIN_TO_BCD(tm.tm_mday);
+				BIN_TO_BCD(tm.tm_hour);
+				BIN_TO_BCD(tm.tm_min);
+				BIN_TO_BCD(tm.tm_sec);
+				tm.tm_mon |= century;
+				
+				rtc_write(RTC_YEAR, tm.tm_year);
+				rtc_write(RTC_MONTH, tm.tm_mon);
+				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+				rtc_write(RTC_HOURS, tm.tm_hour);
+				rtc_write(RTC_MINUTES, tm.tm_min);
+				rtc_write(RTC_SECONDS, tm.tm_sec);
+
+				return 0;
+			}
+			break;
+		default:
+				return -ENOTTY;
+	}
+
+	return 0;
+}
+
+int 
+pcf8563_open(struct inode *inode, struct file *filp)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+int
+pcf8563_release(struct inode *inode, struct file *filp)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+EXPORT_NO_SYMBOLS;
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/serial.c linux-2.4.20/arch/cris/drivers/serial.c
--- linux-2.4.19/arch/cris/drivers/serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/serial.c	2002-10-04 00:41:11.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.32 2002/05/22 13:58:00 johana Exp $
+/* $Id: serial.c,v 1.37 2002/08/13 13:02:37 bjornw Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,24 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.37  2002/08/13 13:02:37  bjornw
+ * Removed some warnings because of unused code
+ *
+ * Revision 1.36  2002/08/08 12:50:01  starvik
+ * Serial interrupt is shared with synchronous serial port driver
+ *
+ * Revision 1.35  2002/06/03 10:40:49  starvik
+ * Increased RS-485 RTS toggle timer to 2 characters
+ *
+ * Revision 1.34  2002/05/28 18:59:36  johana
+ * Whitespace and comment fixing to be more like etrax100ser.c 1.71.
+ *
+ * Revision 1.33  2002/05/28 17:55:43  johana
+ * RS-485 uses FAST_TIMER if enabled, and starts a short (one char time)
+ * timer from tranismit_chars (interrupt context).
+ * The timer toggles RTS in interrupt context when expired giving minimum
+ * latencies.
+ *
  * Revision 1.32  2002/05/22 13:58:00  johana
  * Renamed rs_write() to raw_write() and made it inline.
  * New rs_write() handles RS-485 if configured and enabled
@@ -303,7 +321,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.32 $";
+static char *serial_version = "$Revision: 1.37 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -342,7 +360,16 @@
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
 #include "serial.h"
+#include <asm/fasttimer.h>
 
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
+#error "Disable SERIAL_FLUSH_DMA_FAST to use SERIAL_FAST_TIMER"
+#endif
+#ifndef CONFIG_ETRAX_FAST_TIMER
+#error "Enable FAST_TIMER to use SERIAL_FAST_TIMER"
+#endif
+#endif
 /*
  * All of the compatibilty code so we can compile serial.c against
  * older kernels is hidden in serial_compat.h
@@ -404,8 +431,10 @@
                     const unsigned char *buf, int count);
 static inline int raw_write(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#ifdef CONFIG_ETRAX_RS485
 static int e100_write_rs485(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#endif
 static int 
 get_lsr_info(struct e100_serial * info, unsigned int *value);
 
@@ -519,6 +548,9 @@
 static struct tty_struct *serial_table[NR_PORTS]; 
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+static struct fast_timer fast_timers[NR_PORTS];
+#endif
 
 #ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY
 #define PROCSTAT(x) x
@@ -538,7 +570,7 @@
 
 static struct ser_statistics_type ser_stat[NR_PORTS];
 
-#else 
+#else
 
 #define PROCSTAT(x)
 
@@ -546,6 +578,9 @@
 
 /* RS-485 */
 #if defined(CONFIG_ETRAX_RS485)
+#ifdef CONFIG_ETRAX_FAST_TIMER
+static struct fast_timer fast_timers_rs485[NR_PORTS];
+#endif
 #if defined(CONFIG_ETRAX_RS485_ON_PA)
 static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT;
 #endif
@@ -578,7 +613,7 @@
 	volatile unsigned char *port;
 	volatile unsigned char *shadow;
 	volatile unsigned char *dir_shadow;
-	
+
 	unsigned char dtr_bit;
 	unsigned char ri_bit;
 	unsigned char dsr_bit;
@@ -872,11 +907,6 @@
 		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
 		restore_flags(flags);
 	}
-#if 0
-	REG_SHADOW_SET(e100_modem_pins[info->line].port,
-		       *e100_modem_pins[info->line].shadow,
-		       e100_modem_pins[info->line].ri_bit, !set);
-#endif
 #endif
 }
 static inline void 
@@ -895,11 +925,6 @@
 		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
 		restore_flags(flags);
 	}
-#if 0
-	REG_SHADOW_SET(e100_modem_pins[info->line].port,
-		       *e100_modem_pins[info->line].shadow,
-		       e100_modem_pins[info->line].cd_bit, !set);
-#endif
 #endif
 }
 
@@ -1014,7 +1039,7 @@
 }
 
 static int
-e100_write_rs485(struct tty_struct *tty, int from_user, 
+e100_write_rs485(struct tty_struct *tty, int from_user,
                  const unsigned char *buf, int count)
 {
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
@@ -1031,7 +1056,22 @@
 	info->rs485.enabled = old_enabled;
 	return count;
 }
+
+#ifdef CONFIG_ETRAX_FAST_TIMER
+/* Timer function to toggle RTS when using FAST_TIMER */
+static void rs485_toggle_rts_timer_function(unsigned long data)
+{
+	struct e100_serial *info = (struct e100_serial *)data;
+
+	fast_timers_rs485[info->line].function = NULL;
+	e100_rts(info, info->rs485.rts_after_sent);
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
+	e100_enable_rx(info);
+	e100_enable_rxdma_irq(info);
+#endif
+}
 #endif
+#endif /* CONFIG_ETRAX_RS485 */
 
 /*
  * ------------------------------------------------------------
@@ -1174,6 +1214,16 @@
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
 
+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
+		if (info->rs485.enabled) {
+			/* Set a short timer to toggle RTS */
+			start_one_shot_timer(&fast_timers_rs485[info->line],
+			                     rs485_toggle_rts_timer_function,
+			                     (unsigned long)info,
+			                     info->char_time_usec*2,
+			                     "RS-485");
+		}
+#endif /* RS485 */
 		return;
 	}
 
@@ -1189,7 +1239,7 @@
 	*info->ocmdadr = 1;       /* dma command start -> R_DMAx_CMD */
 	
 	/* DMA is now running (hopefully) */
-}
+} /* transmit_chars */
 
 static void 
 start_transmit(struct e100_serial *info)
@@ -1205,7 +1255,7 @@
 	info->tr_running = 1;
 
 	transmit_chars(info);
-}
+} /* start_transmit */
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 static int serial_fast_timer_started = 0;
@@ -1461,7 +1511,7 @@
 #endif
 
 	/* reset the input dma channel to be sure it works */
-	
+
 	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
 	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
@@ -1636,7 +1686,7 @@
 	cli();
 
 	length = tty->flip.count;
-	
+
 	while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) {
 		unsigned int count = buffer->length;
 
@@ -1889,7 +1939,7 @@
 			}
 			info->break_detected_cnt = 0;
 			DEBUG_LOG(info->line, "#iERR s d %04X\n",
-				  ((rstat & SER_ERROR_MASK) << 8) | data);
+			          ((rstat & SER_ERROR_MASK) << 8) | data);
 		}
 		PROCSTAT(ser_stat[info->line].early_errors_cnt++);
 	} else { /* It was a valid byte, now let the DMA do the rest */
@@ -1903,8 +1953,8 @@
 			 * previous interrupt we should discard it.
 			 */
 			long elapsed_usec = 
-				(curr_time - info->last_rx_active) * (1000000/HZ) + 
-				curr_time_u - info->last_rx_active_usec;
+			  (curr_time - info->last_rx_active) * (1000000/HZ) + 
+			  curr_time_u - info->last_rx_active_usec;
 			if (elapsed_usec < 2*info->char_time_usec) {
 				DEBUG_LOG(info->line, "FBRK %i\n", info->line);
 				/* Report as BREAK (error) and let
@@ -1942,7 +1992,7 @@
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
 
-		if (!info->uses_dma) 
+		if (!info->enabled || !info->uses_dma) 
 			continue; 
 
 		/* Which line caused the irq? */
@@ -1992,28 +2042,6 @@
 	}
 }
 
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred.  The path of
- * hangup processing is:
- *
- * 	serial interrupt routine -> (scheduler tqueue) ->
- * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
- * 
- */
-static void 
-do_serial_hangup(void *private_)
-{
-	struct e100_serial	*info = (struct e100_serial *) private_;
-	struct tty_struct	*tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-	
-	tty_hangup(tty);
-}
-
 static int 
 startup(struct e100_serial * info)
 {
@@ -2025,7 +2053,8 @@
 	if (!xmit_page)
 		return -ENOMEM;
 
-	save_flags(flags); cli();
+	save_flags(flags); 
+	cli();
 
 	/* if it was already initialized, skip this */
 
@@ -2322,7 +2351,7 @@
 
 static inline int 
 raw_write(struct tty_struct * tty, int from_user,
-	 const unsigned char *buf, int count)
+	  const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
@@ -2435,6 +2464,11 @@
 		/* If we are in RS-485 mode, we need to toggle RTS and disable
 		 * the receiver before initiating a DMA transfer
 		 */
+#ifdef CONFIG_ETRAX_FAST_TIMER
+		/* Abort any started timer */
+		fast_timers_rs485[info->line].function = NULL;
+		del_fast_timer(&fast_timers_rs485[info->line]);
+#endif
 		e100_rts(info, info->rs485.rts_on_send);
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 		e100_disable_rx(info);
@@ -2482,7 +2516,7 @@
 #endif /* CONFIG_ETRAX_RS485 */
 
 	return count;
-}
+} /* rs_write */
 
 
 /* how much space is available in the xmit buffer? */
@@ -2563,16 +2597,16 @@
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
-	
+
 	if (I_IXOFF(tty))
 		info->x_char = STOP_CHAR(tty);
-	
+
 	/* Turn off RTS line (do this atomic) should here be an else ?? */
-	
+
 	save_flags(flags); 
 	cli();
 	e100_rts(info, 0);
@@ -2586,20 +2620,20 @@
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
-	
+
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
 		else
 			info->x_char = START_CHAR(tty);
 	}
-	
+
 	/* Assert RTS line (do this atomic) */
-	
+
 	save_flags(flags); 
 	cli();
 	e100_rts(info, 1);
@@ -2722,8 +2756,8 @@
 #ifdef SERIAL_DEBUG_IO 
 struct state_str
 {
-  int state;
-  const char *str;
+	int state;
+	const char *str;
 };
 
 const struct state_str control_state_str[] = {
@@ -3678,6 +3712,15 @@
 			       serial_driver.name, info->line, (unsigned int)info->port);
 		}
 	}
+#ifdef CONFIG_ETRAX_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+	memset(fast_timers, 0, sizeof(fast_timers));
+#endif
+#ifdef CONFIG_ETRAX_RS485
+	memset(fast_timers_rs485, 0, sizeof(fast_timers_rs485));
+#endif
+	fast_timer_init();
+#endif
 
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
@@ -3689,7 +3732,7 @@
 		panic("irq23");
 #endif
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/sync_serial.c linux-2.4.20/arch/cris/drivers/sync_serial.c
--- linux-2.4.19/arch/cris/drivers/sync_serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/sync_serial.c	2002-10-04 00:41:11.000000000 +0000
@@ -227,7 +227,7 @@
 #else
 	ports[0].use_dma = 0;
 	initialize_port(0);
-	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[0]))
+	if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[0]))
 		panic("Can't allocate sync serial manual irq");
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
 #endif
@@ -258,9 +258,9 @@
 #else
 	ports[1].use_dma = 0;	
 	initialize_port(1);
-	if (port[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
+	if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
 	{
-		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[1]))
+		if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
 			panic("Can't allocate sync serial manual irq");
 	}
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);	 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/usb-host.c linux-2.4.20/arch/cris/drivers/usb-host.c
--- linux-2.4.19/arch/cris/drivers/usb-host.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/usb-host.c	2002-10-04 00:41:15.000000000 +0000
@@ -193,17 +193,17 @@
 static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
 static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
 
-static urb_t *URB_List[NBR_OF_EP_DESC];
+static struct urb *URB_List[NBR_OF_EP_DESC];
 static kmem_cache_t *usb_desc_cache;
 static struct usb_bus *etrax_usb_bus;
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb (purb_t purb);
+static void dump_urb (struct urb *urb);
 #endif
 static void init_rx_buffers(void);
-static int etrax_rh_unlink_urb (urb_t *urb);
-static void etrax_rh_send_irq(urb_t *urb);
-static void etrax_rh_init_int_timer(urb_t *urb);
+static int etrax_rh_unlink_urb (struct urb *urb);
+static void etrax_rh_send_irq(struct urb *urb);
+static void etrax_rh_init_int_timer(struct urb *urb);
 static void etrax_rh_int_timer_do(unsigned long ptr);
 
 static void etrax_usb_setup_epid(int epid, char devnum, char endpoint,
@@ -214,13 +214,13 @@
 static void etrax_usb_free_epid(int epid);
 static void cleanup_sb(USB_SB_Desc_t *sb);
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen);
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen);
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen);
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen);
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb);
+static int etrax_usb_submit_ctrl_urb(struct urb *urb);
 
-static int etrax_usb_submit_urb(urb_t *urb);
-static int etrax_usb_unlink_urb(urb_t *urb);
+static int etrax_usb_submit_urb(struct urb *urb);
+static int etrax_usb_unlink_urb(struct urb *urb);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
 static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
@@ -229,7 +229,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
 static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs);
 
-static int etrax_rh_submit_urb (urb_t *urb);
+static int etrax_rh_submit_urb (struct urb *urb);
 
 static int etrax_usb_hc_init(void);
 static void etrax_usb_hc_cleanup(void);
@@ -244,24 +244,24 @@
 };
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb(purb_t purb)
+static void dump_urb(struct urb *urb)
 {
-	printk("\nurb                   :0x%08X\n", purb);
-	printk("next                  :0x%08X\n", purb->next);
-	printk("dev                   :0x%08X\n", purb->dev);
-	printk("pipe                  :0x%08X\n", purb->pipe);
-	printk("status                :%d\n", purb->status);
-	printk("transfer_flags        :0x%08X\n", purb->transfer_flags);
-	printk("transfer_buffer       :0x%08X\n", purb->transfer_buffer);
-	printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("actual_length         :%d\n", purb->actual_length);
-	printk("setup_packet          :0x%08X\n", purb->setup_packet);
-	printk("start_frame           :%d\n", purb->start_frame);
-	printk("number_of_packets     :%d\n", purb->number_of_packets);
-	printk("interval              :%d\n", purb->interval);
-	printk("error_count           :%d\n", purb->error_count);
-	printk("context               :0x%08X\n", purb->context);
-	printk("complete              :0x%08X\n\n", purb->complete);
+	printk("\nurb                   :0x%08X\n", urb);
+	printk("next                  :0x%08X\n", urb->next);
+	printk("dev                   :0x%08X\n", urb->dev);
+	printk("pipe                  :0x%08X\n", urb->pipe);
+	printk("status                :%d\n", urb->status);
+	printk("transfer_flags        :0x%08X\n", urb->transfer_flags);
+	printk("transfer_buffer       :0x%08X\n", urb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
+	printk("actual_length         :%d\n", urb->actual_length);
+	printk("setup_packet          :0x%08X\n", urb->setup_packet);
+	printk("start_frame           :%d\n", urb->start_frame);
+	printk("number_of_packets     :%d\n", urb->number_of_packets);
+	printk("interval              :%d\n", urb->interval);
+	printk("error_count           :%d\n", urb->error_count);
+	printk("context               :0x%08X\n", urb->context);
+	printk("complete              :0x%08X\n\n", urb->complete);
 }
 
 static void dump_in_desc(USB_IN_Desc_t *in)
@@ -425,7 +425,7 @@
 }
 
 
-static int etrax_usb_unlink_intr_urb(urb_t *urb)
+static int etrax_usb_unlink_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -511,7 +511,7 @@
 	} while (tmp_ep != first_ep);
 }
 
-static int etrax_usb_submit_intr_urb(urb_t *urb)
+static int etrax_usb_submit_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -641,7 +641,7 @@
 
 static void handle_intr_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 
 	DBFENTER;
 
@@ -694,7 +694,7 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_unlink_urb (urb_t *urb)
+static int etrax_rh_unlink_urb (struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -711,7 +711,7 @@
 	return 0;
 }
 
-static void etrax_rh_send_irq(urb_t *urb)
+static void etrax_rh_send_irq(struct urb *urb)
 {
 	__u16 data = 0;
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
@@ -744,7 +744,7 @@
 /*	DBFEXIT; */
 }
 
-static void etrax_rh_init_int_timer(urb_t *urb)
+static void etrax_rh_init_int_timer(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -763,12 +763,12 @@
 
 static void etrax_rh_int_timer_do(unsigned long ptr)
 {
-	urb_t *urb;
+	struct urb *urb;
 	etrax_hc_t *hc;
 	
 /*	DBFENTER; */
 	
-	urb = (urb_t*)ptr;
+	urb = (struct urb*)ptr;
 	hc = urb->dev->bus->hcpriv;
 	
 	if (hc->rh.send) {
@@ -910,7 +910,7 @@
 	return -1;
 }
 
-static int etrax_usb_submit_bulk_urb(urb_t *urb)
+static int etrax_usb_submit_bulk_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -919,7 +919,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -969,7 +969,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 
@@ -1086,7 +1086,7 @@
 
 static void handle_bulk_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;
 	unsigned long flags;
 
@@ -1166,7 +1166,7 @@
 
 /* ---------------------------------------------------------------------------- */
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb)
+static int etrax_usb_submit_ctrl_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -1175,7 +1175,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -1225,7 +1225,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 	USB_SB_Desc_t *sb_desc_2;
@@ -1364,7 +1364,7 @@
 	DBFEXIT;
 }
 
-static int etrax_usb_submit_urb(urb_t *urb)
+static int etrax_usb_submit_urb(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	int rval = -EINVAL;
@@ -1411,7 +1411,7 @@
 	return rval;
 }
 
-static int etrax_usb_unlink_urb(urb_t *urb)
+static int etrax_usb_unlink_urb(struct urb *urb)
 {
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
 	int epid;
@@ -1455,8 +1455,8 @@
 	cli();
 	
 	for (epid = 0; epid < 32; epid++) {
-		urb_t *u = URB_List[epid];
-		urb_t *prev = NULL;
+		struct urb *u = URB_List[epid];
+		struct urb *prev = NULL;
 		int pos = 0;
 
 		for (; u; u = u->next) {
@@ -1557,7 +1557,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
 {
 	int epid = 0;
-	urb_t *urb;
+	struct urb *urb;
 	etrax_urb_priv_t *urb_priv;
 		
 	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
@@ -1655,7 +1655,7 @@
 
 static void handle_control_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;	
 
 	DBFENTER;
@@ -1981,12 +1981,12 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_submit_urb(urb_t *urb)
+static int etrax_rh_submit_urb(struct urb *urb)
 {
 	struct usb_device *usb_dev = urb->dev;
 	etrax_hc_t *hc = usb_dev->bus->hcpriv;
 	unsigned int pipe = urb->pipe;
-	devrequest *cmd = (devrequest *) urb->setup_packet;
+	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
 	void *data = urb->transfer_buffer;
 	int leni = urb->transfer_buffer_length;
 	int len = 0;
@@ -2010,10 +2010,10 @@
 		return 0;
 	}
 
-	bmRType_bReq = cmd->requesttype | cmd->request << 8;
-	wValue = le16_to_cpu(cmd->value);
-	wIndex = le16_to_cpu(cmd->index);
-	wLength = le16_to_cpu(cmd->length);
+	bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8;
+	wValue = le16_to_cpu(cmd->wValue);
+	wIndex = le16_to_cpu(cmd->wIndex);
+	wLength = le16_to_cpu(cmd->wLength);
 
 	dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq);
 	dbg_rh("wValue       : 0x%04X (%d)", wValue, wValue);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.c linux-2.4.20/arch/cris/drivers/virtex.c
--- linux-2.4.19/arch/cris/drivers/virtex.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/virtex.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,405 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : vertex.c
+*!
+*! DESCRIPTION: Implements an interface towards virtex FPGA (mounted on one of our
+*!              evaluation boards) from userspace using ioctl()'s
+*!
+*!              The FPGA can be programmed by copying the bit-file to /dev/fpga.
+*!
+*!                cp fpga.bit > /dev/fpga
+*!
+*!                Kernel log should look like:
+*!                  69900 bytes written
+*!                  FPGA-configuration completed, no errors
+*!
+*!              Number of bytes written depends on the FPGA
+*!
+*!                From Xilinx data sheet:
+*!                XCV50    559,200 bits
+*!                XCV100   781,216 bits
+*!                XCV800 4,715,616 bits
+*!
+*!              Accepted file type is the design.bit generated by Alliance
+*!              Design Manager.
+*!              This software just sends the bitfile into the device without
+*!              checking device type etc.
+*!
+*!              Sync-header 0xff 0xff 0xff 0xff defines the start for the
+*!              byte stream, everything from that position is written to the FPGA.
+*!
+*!  
+*! Jul 19 2002  Stefan Lundberg    Initial version.
+*! $Log: virtex.c,v $
+*! Revision 1.1  2002/06/25 09:58:58  stefanl
+*! New FPGA driver for Platoon
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN
+*!
+*!***************************************************************************/
+/* $Id: virtex.c,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <linux/hdreg.h>
+#include <linux/mm.h>
+
+#include <asm/etraxvirtex.h>
+
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include "virtex.h"
+
+/******************* VIRTEX DEFINITION SECTION **************************/
+
+#define VIRTEX_DEBUG(x)
+
+#define VIRTEX_MAJOR 246  /* EXPERIMENTAL */
+
+static const char virtex_name[] = "virtex";
+
+/****************** FUNCTION DEFINITION SECTION *************************/
+
+
+
+//
+// Read register interface for FPGA programming:
+//
+//   FPGA_DONE is connected to S1CD_N G28
+//   FPGA_INIT_N is connected to S1IO_N G27
+//
+
+// Write register interface for FPGA programming:
+//
+//  Bit:       15         14      13    12      9   8   7   0
+//        ____________________________________________________
+//       | fpga_write | program | cclk | reserved | cs | data |
+//       |____________|_________|______|__________|____|______|
+//
+
+
+// csp0 = cs_fpga1 = FPGA programming interface
+// csr0 = cs_fpga2 = register interface towards FPGA construction
+
+static volatile short *port_csp0_word_addr;
+static volatile short *port_csr0_word_addr;
+
+static volatile unsigned char open_count;
+static volatile unsigned char bytes_written;
+static volatile unsigned long bytes_written_cnt;
+static volatile unsigned char sync_found;
+static volatile unsigned char sync_count;
+static volatile unsigned char sync_ff_count;
+
+#define WRITE_FPGA_PROG_REG(data) *port_csp0_word_addr=(data)
+#define SET_PROGRAM_BIT(data) (data)|(1<<14)
+
+#define SET_WRITE_BIT(data) (data)|(1<<15)
+#define CLR_WRITE_BIT(data) (data)&(~(1<<15))
+
+#define SET_CS_BIT(data) (data)|(1<<8)
+#define CLR_CS_BIT(data) (data)&(~(1<<8))
+
+#define SET_CCLK_BIT(data) (data)|(1<<13)
+#define CLR_CCLK_BIT(data) (data)&(~(1<<13))
+
+// Bit in read port G (always inputs)
+#define READ_INIT  (*R_PORT_G_DATA)&(1<<27)
+#define READ_DONE  (*R_PORT_G_DATA)&(1<<28)
+
+
+void start_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  printk("Start writing to FPGA\n");
+  reg_data = SET_CS_BIT(reg_data); // FPGA unselected
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  while(!READ_INIT); // Wait for init
+  
+  reg_data = SET_WRITE_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_CS_BIT(reg_data); // FPGA selected, CS is active low
+  WRITE_FPGA_PROG_REG(reg_data);
+  return;
+}
+
+// According to datasheet, bytes should be reversed, it is unknown to me why.
+unsigned char bit_reverse(unsigned char data) 
+{
+  unsigned char in=data;
+  unsigned short out=0;
+  unsigned int i=0;
+
+  for(i=0;i<8;i++) {
+    if(in&0x1) {
+      out|=0x1;
+    }
+    in=in>>1;
+    out=out<<1;
+  }
+
+  return(out>>1);
+  
+}
+
+void virtex_program(char* ptr,size_t count)
+{
+  int c;
+  char *p;
+  unsigned char data;  
+  unsigned short reg_data=0;
+//  short tmp_cnt;
+  
+  c=count;
+  p=ptr;
+
+  if(!sync_found) {
+    c=count;
+    p=ptr;
+    while(c--) {
+      data=(unsigned char)*p++;
+      sync_count++;
+
+      if(sync_count>=256) {
+        printk("Sync not found, aborting\n");
+        return;
+      }
+
+      if(data==0xff) {
+        sync_ff_count++;
+      } else {
+        sync_ff_count=0;
+      }
+      if(sync_ff_count==4) {
+        sync_found=1;
+        VIRTEX_DEBUG(printk("Sync found at offset %d\n",sync_count));
+        p--;p--;p--;p--;
+        c++;c++;c++;c++;
+        break;
+      }
+    }
+  }
+
+  if(sync_found) {
+    if(bytes_written==0) {
+      start_virtex_program();
+    }
+    bytes_written=1;
+  
+    reg_data = SET_PROGRAM_BIT(reg_data);
+    reg_data = SET_WRITE_BIT(reg_data);
+    reg_data = CLR_CS_BIT(reg_data);
+  
+//    tmp_cnt=0;
+    
+    printk("*");
+    while(c--) {
+      data=(unsigned char)*p++;
+      data=bit_reverse(data);
+
+/* debug
+      tmp_cnt++;
+      if(tmp_cnt<=32 || c<=32 ) {
+        printk("0x%x ",data); 
+      }
+      if(tmp_cnt==32 || c==0 ) {
+        printk("\n"); 
+      }
+*/
+      bytes_written_cnt++;
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = SET_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+  
+    }
+  }
+   
+  return;
+}
+
+void stop_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  reg_data = SET_WRITE_BIT(reg_data);
+  reg_data = CLR_CCLK_BIT(reg_data);
+
+  reg_data = SET_CS_BIT(reg_data); // release CS
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_WRITE_BIT(reg_data); // release write, important to do!
+  WRITE_FPGA_PROG_REG(reg_data);
+  printk("%d bytes written\n",bytes_written_cnt);
+  if(READ_DONE) {
+    printk("FPGA-configuration completed, no errors\n");
+  } else {
+    printk("Error, FPGA-configuration failed\n");
+  }
+  return;
+}
+
+static int
+virtex_open(struct inode *inode, struct file *filp)
+{
+  port_csp0_word_addr = port_csp0_addr;
+  if(open_count>=1) {
+    printk("FPGA Device busy, aborting\n");
+    return(-EBUSY);
+  }
+  open_count++;
+  bytes_written=0;
+  sync_found=0;
+  sync_count=0;
+  sync_ff_count=0;
+  bytes_written_cnt=0;
+  return(0);
+}
+
+static int
+virtex_release(struct inode *inode, struct file *filp)
+{
+  open_count--;
+  if(bytes_written!=0)stop_virtex_program();
+  return 0;
+}
+
+// FPGA programming interface
+
+static ssize_t virtex_write(struct file * file, const char * buf, 
+                                 size_t count, loff_t *ppos)
+{
+  char *ptr;
+  VIRTEX_DEBUG(printk("Write FPGA count %d\n", count));
+  
+  ptr=kmalloc(count, GFP_KERNEL);
+  if(!ptr) {
+    printk("FPGA device, kernel malloc failed (%d) bytes\n",count);
+    return -EFAULT;
+  }
+  if(copy_from_user(ptr, buf, count)) {
+    printk("copy_from_user failed\n");
+    return -EFAULT;
+  }
+  
+  virtex_program(ptr,count);
+  
+  kfree(ptr);
+  return count;
+}
+
+/* Main device API. ioctl's to write or read to/from registers.
+ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue)
+{
+  port_csr0_word_addr[theReg]=theValue;
+  return(0);
+}
+
+unsigned short virtex_readreg(unsigned short theReg)
+{
+  return(port_csr0_word_addr[theReg]);
+}
+
+
+static int
+virtex_ioctl(struct inode *inode, struct file *file,
+	  unsigned int cmd, unsigned long arg)
+{
+  if(_IOC_TYPE(cmd) != ETRAXVIRTEX_FPGA_IOCTYPE) {
+    return -EINVAL;
+  }
+  
+  switch (_IOC_NR(cmd)) {
+    case VIRTEX_FPGA_WRITEREG:
+      /* write to an FPGA register */
+      VIRTEX_DEBUG(printk("virtex wr %d %d\n", 
+               VIRTEX_FPGA_ARGREG(arg),
+               VIRTEX_FPGA_ARGVALUE(arg)));
+      
+      return virtex_writereg(VIRTEX_FPGA_ARGREG(arg),
+                             VIRTEX_FPGA_ARGVALUE(arg));
+    case VIRTEX_FPGA_READREG:
+    {
+      unsigned char val;
+      /* read from an FPGA register */
+      VIRTEX_DEBUG(printk("virtex rd %d ", 
+              VIRTEX_FPGA_ARGREG(arg)));
+      val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg));
+      VIRTEX_DEBUG(printk("= %d\n", val));
+      return val;
+    }					    
+    default:
+      return -EINVAL;
+    }
+
+return 0;
+}
+
+static struct file_operations virtex_fops = {
+	owner:    THIS_MODULE,
+	ioctl:    virtex_ioctl,
+	open:     virtex_open,
+        write:    virtex_write,
+	release:  virtex_release,
+};
+
+static int __init
+virtex_init(void)
+{
+  int res;
+  
+  /* register char device */
+  res = register_chrdev(VIRTEX_MAJOR, virtex_name, &virtex_fops);
+  if(res < 0) {
+          printk(KERN_ERR "virtex: couldn't get a major number.\n");
+          return res;
+  }
+  
+  port_csr0_word_addr = (volatile unsigned short *) 
+                        ioremap((unsigned long)(MEM_CSR0_START |
+                                                MEM_NON_CACHEABLE), 16);
+     
+// see ~/platoon/rel2/platoon/os/linux/arch/cris/mm/init.c
+//              port_csp0_addr = (volatile unsigned long *)
+//                 ioremap((unsigned long)(MEM_CSP0_START |
+//                                         MEM_NON_CACHEABLE), 16);
+  
+  open_count=0;
+  
+  printk("VIRTEX(TM) FPGA driver v1.0, (c) 2002 Axis Communications AB\n");
+  
+  return 0;
+}
+
+/* this makes sure that virtex_init is called during boot */
+
+module_init(virtex_init);
+
+/****************** END OF FILE virtex.c ********************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.h linux-2.4.20/arch/cris/drivers/virtex.h
--- linux-2.4.19/arch/cris/drivers/virtex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/cris/drivers/virtex.h	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,7 @@
+/* $Id: virtex.h,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue);
+unsigned short virtex_readreg(unsigned short theReg);
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/Makefile linux-2.4.20/arch/cris/kernel/Makefile
--- linux-2.4.19/arch/cris/kernel/Makefile	2001-11-09 21:58:02.000000000 +0000
+++ linux-2.4.20/arch/cris/kernel/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 2001/10/22 13:10:21 pkj Exp $
+# $Id: Makefile,v 1.10 2002/05/27 15:41:40 johana Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -25,6 +25,7 @@
 
 obj-$(CONFIG_MODULES)    += ksyms.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
+obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
 
 # This dependency isn't caught by mkdep.  See entry.S.
 entry.o: entryoffsets.s
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/fasttimer.c linux-2.4.20/arch/cris/kernel/fasttimer.c
--- linux-2.4.19/arch/cris/kernel/fasttimer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/cris/kernel/fasttimer.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,974 @@
+/* $Id: fasttimer.c,v 1.4 2002/05/28 17:47:59 johana Exp $
+ * linux/arch/cris/kernel/fasttimer.c
+ *
+ * Fast timers for ETRAX100/ETRAX100LX
+ * This may be useful in other OS than Linux so use 2 space indentation...
+ *
+ * $Log: fasttimer.c,v $
+ * Revision 1.4  2002/05/28 17:47:59  johana
+ * Added del_fast_timer()
+ *
+ * Revision 1.3  2002/05/28 16:16:07  johana
+ * Handle empty fast_timer_list
+ *
+ * Revision 1.2  2002/05/27 15:38:42  johana
+ * Made it compile without warnings on Linux 2.4.
+ * (includes, wait_queue, PROC_FS and snprintf)
+ *
+ * Revision 1.1  2002/05/27 15:32:25  johana
+ * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
+ *
+ * Revision 1.8  2001/11/27 13:50:40  pkj
+ * Disable interrupts while stopping the timer and while modifying the
+ * list of active timers in timer1_handler() as it may be interrupted
+ * by other interrupts (e.g., the serial interrupt) which may add fast
+ * timers.
+ *
+ * Revision 1.7  2001/11/22 11:50:32  pkj
+ * * Only store information about the last 16 timers.
+ * * proc_fasttimer_read() now uses an allocated buffer, since it
+ *   requires more space than just a page even for only writing the
+ *   last 16 timers. The buffer is only allocated on request, so
+ *   unless /proc/fasttimer is read, it is never allocated.
+ * * Renamed fast_timer_started to fast_timers_started to match
+ *   fast_timers_added and fast_timers_expired.
+ * * Some clean-up.
+ *
+ * Revision 1.6  2000/12/13 14:02:08  johana
+ * Removed volatile for fast_timer_list
+ *
+ * Revision 1.5  2000/12/13 13:55:35  johana
+ * Added DEBUG_LOG, added som cli() and cleanup
+ *
+ * Revision 1.4  2000/12/05 13:48:50  johana
+ * Added range check when writing proc file, modified timer int handling
+ *
+ * Revision 1.3  2000/11/23 10:10:20  johana
+ * More debug/logging possibilities.
+ * Moved GET_JIFFIES_USEC() to timex.h and time.c
+ *
+ * Revision 1.2  2000/11/01 13:41:04  johana
+ * Clean up and bugfixes.
+ * Created new do_gettimeofday_fast() that gets a timeval struct
+ * with time based on jiffies and *R_TIMER0_DATA, uses a table
+ * for fast conversion of timer value to microseconds.
+ * (Much faster the standard do_gettimeofday() and we don't really
+ * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * when we change the time.
+ * TODO: Add efficient support for continuous timers as well.
+ *
+ * Revision 1.1  2000/10/26 15:49:16  johana
+ * Added fasttimer, highresolution timers.
+ *
+ * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
+ */
+
+#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 <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/rtc.h>
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <asm/svinto.h>
+#include <asm/fasttimer.h>
+#include <linux/proc_fs.h>
+
+
+#define DEBUG_LOG_INCLUDED
+#define FAST_TIMER_LOG
+//#define FAST_TIMER_TEST
+
+#define FAST_TIMER_SANITY_CHECKS
+
+#ifdef FAST_TIMER_SANITY_CHECKS
+#define SANITYCHECK(x) x
+static int sanity_failed = 0;
+#else
+#define SANITYCHECK(x)
+#endif
+
+#define D1(x)
+#define D2(x)
+#define DP(x)
+
+#define __INLINE__ inline
+
+static int fast_timer_running = 0;
+static int fast_timers_added = 0;
+static int fast_timers_started = 0;
+static int fast_timers_expired = 0;
+static int fast_timers_deleted = 0;
+static int fast_timer_is_init = 0;
+static int fast_timer_ints = 0;
+
+static struct fast_timer *fast_timer_list = NULL;
+
+#ifdef DEBUG_LOG_INCLUDED
+#define DEBUG_LOG_MAX 128
+static const char * debug_log_string[DEBUG_LOG_MAX];
+static unsigned long debug_log_value[DEBUG_LOG_MAX];
+static int debug_log_cnt = 0;
+static int debug_log_cnt_wrapped = 0;
+
+#define DEBUG_LOG(string, value) \
+{ \
+  unsigned long log_flags; \
+  save_flags(log_flags); \
+  cli(); \
+  debug_log_string[debug_log_cnt] = (string); \
+  debug_log_value[debug_log_cnt] = (unsigned long)(value); \
+  if (++debug_log_cnt >= DEBUG_LOG_MAX) \
+  { \
+    debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
+    debug_log_cnt_wrapped = 1; \
+  } \
+  restore_flags(log_flags); \
+}
+#else
+#define DEBUG_LOG(string, value)
+#endif
+
+
+/* The frequencies for index = clkselx number in R_TIMER_CTRL */
+#define NUM_TIMER_FREQ 15
+#define MAX_USABLE_TIMER_FREQ 7
+#define MAX_DELAY_US  853333L
+const unsigned long timer_freq_100[NUM_TIMER_FREQ] =
+{
+  3,   /* 0 3333 - 853333 us */
+  6,   /* 1 1666 - 426666 us */
+  12,  /* 2  833 - 213333 us */
+  24,  /* 3  416 - 106666 us */
+  48,  /* 4  208 -  53333 us */
+  96,  /* 5  104 -  26666 us */
+  192, /* 6   52 -  13333 us */
+  384, /* 7   26 -   6666 us */
+  576,
+  1152,
+  2304,
+  4608,
+  9216,
+  18432,
+  62500,
+  /* 15 = cascade */
+};
+#define NUM_TIMER_STATS 16
+#ifdef FAST_TIMER_LOG
+struct fast_timer timer_added_log[NUM_TIMER_STATS];
+struct fast_timer timer_started_log[NUM_TIMER_STATS];
+struct fast_timer timer_expired_log[NUM_TIMER_STATS];
+#endif
+
+int timer_div_settings[NUM_TIMER_STATS];
+int timer_freq_settings[NUM_TIMER_STATS];
+int timer_delay_settings[NUM_TIMER_STATS];
+
+/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
+void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
+{
+  unsigned long sec = jiffies;
+  unsigned long usec = GET_JIFFIES_USEC();
+
+  usec += (sec % HZ) * (1000000 / HZ);
+  sec = sec / HZ;
+
+  if (usec > 1000000)
+  {
+    usec -= 1000000;
+    sec++;
+  }
+  tv->tv_sec = sec;
+  tv->tv_usec = usec;
+}
+
+int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
+{
+  if (t0->tv_sec < t1->tv_sec)
+  {
+    return -1;
+  }
+  else if (t0->tv_sec > t1->tv_sec)
+  {
+    return 1;
+  }
+  if (t0->tv_usec < t1->tv_usec)
+  {
+    return -1;
+  }
+  else if (t0->tv_usec > t1->tv_usec)
+  {
+    return 1;
+  }
+  return 0;
+}
+
+void __INLINE__ start_timer1(unsigned long delay_us)
+{
+  int freq_index = 0; /* This is the lowest resolution */
+  unsigned long upper_limit = MAX_DELAY_US;
+
+  unsigned long div;
+  /* Start/Restart the timer to the new shorter value */
+  /* t = 1/freq = 1/19200 = 53us
+   * T=div*t,  div = T/t = delay_us*freq/1000000
+   */
+#if 1 /* Adaptive timer settings */
+  while (delay_us < upper_limit && freq_index < MAX_USABLE_TIMER_FREQ)
+  {
+    freq_index++;
+    upper_limit >>= 1; /* Divide by 2 using shift */
+  }
+  if (freq_index > 0)
+  {
+    freq_index--;
+  }
+#else
+  freq_index = 6;
+#endif
+  div = delay_us * timer_freq_100[freq_index]/10000;
+  if (div < 2)
+  {
+    /* Maybe increase timer freq? */
+    div = 2;
+  }
+  if (div > 255)
+  {
+    div = 0; /* This means 256, the max the timer takes */
+    /* If a longer timeout than the timer can handle is used,
+     * then we must restart it when it goes off.
+     */
+  }
+
+  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = div;
+  timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
+  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
+
+  D1(printk("start_timer1 : %d us freq: %i div: %i\n",
+            delay_us, freq_index, div));
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* Set timer values */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow &
+     ~IO_MASK(R_TIMER_CTRL, timerdiv1) &
+     ~IO_MASK(R_TIMER_CTRL, tm1) &
+     ~IO_MASK(R_TIMER_CTRL, clksel1)) |
+    IO_FIELD(R_TIMER_CTRL, timerdiv1, div) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
+    IO_FIELD(R_TIMER_CTRL, clksel1, freq_index ); /* 6=c19k2Hz */
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow |
+    IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  /* Start timer */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+    IO_STATE(R_TIMER_CTRL, tm1, run);
+
+  /* Enable timer1 irq */
+  *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
+  fast_timers_started++;
+  fast_timer_running = 1;
+}
+
+/* In version 1.4 this function takes 27 - 50 us */
+void start_one_shot_timer(struct fast_timer *t,
+                          fast_timer_function_type *function,
+                          unsigned long data,
+                          unsigned long delay_us,
+                          const char *name)
+{
+  unsigned long flags;
+  struct fast_timer *tmp;
+
+  D1(printk("sft %s %d us\n", name, delay_us));
+
+  save_flags(flags);
+  cli();
+
+  do_gettimeofday_fast(&t->tv_set);
+  tmp = fast_timer_list;
+
+  SANITYCHECK({ /* Check so this is not in the list already... */
+    while (tmp != NULL)
+    {
+      if (tmp == t)
+      {
+        printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
+        sanity_failed++;
+        return;
+      }
+      else
+      {
+        tmp = tmp->next;
+      }
+    }
+    tmp = fast_timer_list;
+  });
+
+  t->delay_us = delay_us;
+  t->function = function;
+  t->data = data;
+  t->name = name;
+
+  t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
+  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
+  if (t->tv_expires.tv_usec > 1000000)
+  {
+    t->tv_expires.tv_usec -= 1000000;
+    t->tv_expires.tv_sec++;
+  }
+#ifdef FAST_TIMER_LOG
+  timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
+#endif
+  fast_timers_added++;
+
+  /* Check if this should timeout before anything else */
+  if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
+  {
+    /* Put first in list and modify the timer value */
+    t->prev = NULL;
+    t->next = fast_timer_list;
+    if (fast_timer_list)
+    {
+      fast_timer_list->prev = t;
+    }
+    fast_timer_list = t;
+#ifdef FAST_TIMER_LOG
+    timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+    start_timer1(delay_us);
+  } else {
+    /* Put in correct place in list */
+    while (tmp->next &&
+           timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
+    {
+      tmp = tmp->next;
+    }
+    /* Insert t after tmp */
+    t->prev = tmp;
+    t->next = tmp->next;
+    if (tmp->next)
+    {
+      tmp->next->prev = t;
+    }
+    tmp->next = t;
+  }
+
+  D2(printk("start_one_shot_timer: %d us done\n", delay_us));
+
+  restore_flags(flags);
+} /* start_one_shot_timer */
+
+static inline int fast_timer_pending (const struct fast_timer * t)
+{
+  return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
+}
+
+static inline int detach_fast_timer (struct fast_timer *t)
+{
+  struct fast_timer *next, *prev;
+  if (!fast_timer_pending(t))
+    return 0;
+  next = t->next;
+  prev = t->prev;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  else
+    fast_timer_list = next;
+  fast_timers_deleted++;
+  return 1;
+}
+
+int del_fast_timer(struct fast_timer * t)
+{
+  unsigned long flags;
+  int ret;
+  
+  save_flags(flags);
+  cli();
+  ret = detach_fast_timer(t);
+  t->next = t->prev = NULL;
+  restore_flags(flags);
+  return ret;
+} /* del_fast_timer */
+
+
+/* Interrupt routines or functions called in interrupt context */
+
+/* Timer 1 interrupt handler */
+
+static void
+timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct fast_timer *t;
+  unsigned long flags;
+
+  save_flags(flags);
+  cli();
+
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* First stop timer, then ack interrupt */
+  /* Stop timer */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld);
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  fast_timer_running = 0;
+  fast_timer_ints++;
+
+  restore_flags(flags);
+
+  t = fast_timer_list;
+  while (t)
+  {
+    struct timeval tv;
+
+    /* Has it really expired? */
+    do_gettimeofday_fast(&tv);
+    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
+
+    if (timeval_cmp(&t->tv_expires, &tv) <= 0)
+    {
+      /* Yes it has expired */
+#ifdef FAST_TIMER_LOG
+      timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
+#endif
+      fast_timers_expired++;
+
+      /* Remove this timer before call, since it may reuse the timer */
+      save_flags(flags);
+      cli();
+      if (t->prev)
+      {
+        t->prev->next = t->next;
+      }
+      else
+      {
+        fast_timer_list = t->next;
+      }
+      if (t->next)
+      {
+        t->next->prev = t->prev;
+      }
+      t->prev = NULL;
+      t->next = NULL;
+      restore_flags(flags);
+
+      if (t->function != NULL)
+      {
+        t->function(t->data);
+      }
+      else
+      {
+        DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
+      }
+    }
+    else
+    {
+      /* Timer is to early, let's set it again using the normal routines */
+      D1(printk(".\n"));
+    }
+
+    save_flags(flags);
+    cli();
+    if ((t = fast_timer_list) != NULL)
+    {
+      /* Start next timer.. */
+      long us;
+      struct timeval tv;
+
+      do_gettimeofday_fast(&tv);
+      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
+            t->tv_expires.tv_usec - tv.tv_usec);
+      if (us > 0)
+      {
+        if (!fast_timer_running)
+        {
+#ifdef FAST_TIMER_LOG
+          timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+          start_timer1(us);
+        }
+        restore_flags(flags);
+        break;
+      }
+      else
+      {
+        /* Timer already expired, let's handle it better late than never.
+         * The normal loop handles it
+         */
+        D1(printk("e! %d\n", us));
+      }
+    }
+    restore_flags(flags);
+  }
+
+  if (!t)
+  {
+    D1(printk("t1 stop!\n"));
+  }
+}
+
+static void wake_up_func(unsigned long data)
+{
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t  *sleep_wait_p = (wait_queue_head_t*)data;
+#else
+  struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
+#endif
+  wake_up(sleep_wait_p);
+}
+
+
+/* Useful API */
+
+void schedule_usleep(unsigned long us)
+{
+  struct fast_timer t;
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t sleep_wait;
+  DECLARE_WAITQUEUE(wait, current);
+#else
+  struct wait_queue *sleep_wait = NULL;
+  struct wait_queue wait = { current, NULL };
+#endif
+
+  D1(printk("schedule_usleep(%d)\n", us));
+  add_wait_queue(&sleep_wait, &wait);
+  set_current_state(TASK_INTERRUPTIBLE);
+  start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
+                       "usleep");
+  schedule();
+  set_current_state(TASK_RUNNING);
+  remove_wait_queue(&sleep_wait, &wait);
+  D1(printk("done schedule_usleep(%d)\n", us));
+}
+
+#ifdef CONFIG_PROC_FS
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               );
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static struct proc_dir_entry *fasttimer_proc_entry;
+#else
+static struct proc_dir_entry fasttimer_proc_entry =
+{
+  0, 9, "fasttimer",
+  S_IFREG | S_IRUGO, 1, 0, 0,
+  0, NULL /* ops -- default to array */,
+  &proc_fasttimer_read /* get_info */,
+};
+#endif
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_PROC_FS
+
+/* This value is very much based on testing */
+#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
+
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               )
+{
+  unsigned long flags;
+  int i = 0;
+  int num_to_show;
+  struct timeval tv;
+  struct fast_timer *t, *nextt;
+  static char *bigbuf = NULL;
+  static unsigned long used;
+
+  if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
+  {
+    used = 0;
+    bigbuf[0] = '\0';
+    return 0;
+  }
+
+  if (!offset || !used)
+  {
+    do_gettimeofday_fast(&tv);
+
+    used = 0;
+    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
+                    fast_timers_added);
+    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
+                    fast_timers_started);
+    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
+                    fast_timer_ints);
+    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
+                    fast_timers_expired);
+    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
+                    fast_timers_deleted);
+    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
+                    fast_timer_running ? "yes" : "no");
+    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
+                    (unsigned long)tv.tv_sec,
+                    (unsigned long)tv.tv_usec);
+#ifdef FAST_TIMER_SANITY_CHECKS
+    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
+                    sanity_failed);
+#endif
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef DEBUG_LOG_INCLUDED
+    {
+      int end_i = debug_log_cnt;
+      i = 0;
+
+      if (debug_log_cnt_wrapped)
+      {
+        i = debug_log_cnt;
+      }
+
+      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
+             used+100 < BIG_BUF_SIZE)
+      {
+        used += sprintf(bigbuf + used, debug_log_string[i],
+                        debug_log_value[i]);
+        i = (i+1) % DEBUG_LOG_MAX;
+      }
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
+    {
+      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+
+#if 1 //ndef FAST_TIMER_LOG
+      used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i"
+                      "\n",
+                      timer_div_settings[cur],
+                      timer_freq_settings[cur],
+                      timer_delay_settings[cur]
+                      );
+#endif
+#ifdef FAST_TIMER_LOG
+      t = &timer_started_log[cur];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+#endif
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef FAST_TIMER_LOG
+    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    used += sprintf(bigbuf + used, "Active timers:\n");
+    save_flags(flags);
+    cli();
+    t = fast_timer_list;
+    while (t != NULL && (used+100 < BIG_BUF_SIZE))
+    {
+      nextt = t->next;
+      restore_flags(flags);
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+/*                      " func: 0x%08lX" */
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+/*                      , t->function */
+                      );
+      cli();
+      if (t->next != nextt)
+      {
+        printk("timer removed!\n");
+      }
+      t = nextt;
+    }
+    restore_flags(flags);
+  }
+
+  if (used - offset < len)
+  {
+    len = used - offset;
+  }
+
+  memcpy(buf, bigbuf + offset, len);
+  *start = buf;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  *eof = 1;
+#endif
+
+  return len;
+}
+#endif /* PROC_FS */
+
+#ifdef FAST_TIMER_TEST
+static volatile unsigned long i = 0;
+static volatile int num_test_timeout = 0;
+static struct fast_timer tr[10];
+static int exp_num[10];
+
+static struct timeval tv_exp[100];
+
+static void test_timeout(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+
+  num_test_timeout++;
+}
+
+static void test_timeout1(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+  if (data < 7)
+  {
+    start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
+    i++;
+  }
+  num_test_timeout++;
+}
+
+DP(
+static char buf0[2000];
+static char buf1[2000];
+static char buf2[2000];
+static char buf3[2000];
+static char buf4[2000];
+);
+
+static char buf5[6000];
+static int j_u[1000];
+
+static void fast_timer_test(void)
+{
+  int prev_num;
+  int j;
+
+  struct timeval tv, tv0, tv1, tv2;
+
+  printk("fast_timer_test() start\n");
+  do_gettimeofday_fast(&tv);
+
+  for (j = 0; j < 1000; j++)
+  {
+    j_u[j] = GET_JIFFIES_USEC();
+  }
+  for (j = 0; j < 100; j++)
+  {
+    do_gettimeofday_fast(&tv_exp[j]);
+  }
+  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
+
+  for (j = 0; j < 1000; j++)
+  {
+    printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
+    j += 4;
+  }
+  for (j = 0; j < 100; j++)
+  {
+    printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
+           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
+           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
+           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
+           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
+           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
+    j += 4;
+  }
+  do_gettimeofday_fast(&tv0);
+  start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
+  DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
+  DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
+  DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
+  DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
+  DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
+  i++;
+  do_gettimeofday_fast(&tv1);
+
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+
+  prev_num = num_test_timeout;
+  while (num_test_timeout < i)
+  {
+    if (num_test_timeout != prev_num)
+    {
+      prev_num = num_test_timeout;
+    }
+  }
+  do_gettimeofday_fast(&tv2);
+  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
+  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
+  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
+  DP(printk("buf0:\n");
+     printk(buf0);
+     printk("buf1:\n");
+     printk(buf1);
+     printk("buf2:\n");
+     printk(buf2);
+     printk("buf3:\n");
+     printk(buf3);
+     printk("buf4:\n");
+     printk(buf4);
+  );
+  printk("buf5:\n");
+  printk(buf5);
+
+  printk("timers set:\n");
+  for(j = 0; j<i; j++)
+  {
+    struct fast_timer *t = &tr[j];
+    printk("%-10s set: %6is %06ius exp: %6is %06ius "
+           "data: 0x%08X func: 0x%08X\n",
+           t->name,
+           t->tv_set.tv_sec,
+           t->tv_set.tv_usec,
+           t->tv_expires.tv_sec,
+           t->tv_expires.tv_usec,
+           t->data,
+           t->function
+           );
+
+    printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
+           t->delay_us,
+           tv_exp[j].tv_sec,
+           tv_exp[j].tv_usec,
+           exp_num[j],
+           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
+  }
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+  printk("buf5 after all done:\n");
+  printk(buf5);
+  printk("fast_timer_test() done\n");
+}
+#endif
+
+
+void fast_timer_init(void)
+{
+  /* For some reason, request_irq() hangs when called froom time_init() */
+  if (!fast_timer_is_init)
+  {
+#if 0 && defined(FAST_TIMER_TEST)
+    int i;
+#endif
+
+    printk("fast_timer_init()\n");
+
+#if 0 && defined(FAST_TIMER_TEST)
+    for (i = 0; i <= TIMER0_DIV; i++)
+    {
+      /* We must be careful not to get overflow... */
+      printk("%3i %6u\n", i, timer0_value_us[i]);
+    }
+#endif
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+   if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
+     fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+#else
+    proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
+#endif
+#endif /* PROC_FS */
+    if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
+                   "fast timer int", NULL))
+    {
+      printk("err: timer1 irq\n");
+    }
+    fast_timer_is_init = 1;
+#ifdef FAST_TIMER_TEST
+    printk("do test\n");
+    fast_timer_test();
+#endif
+  }
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/kgdb.c linux-2.4.20/arch/cris/kernel/kgdb.c
--- linux-2.4.19/arch/cris/kernel/kgdb.c	2001-11-09 21:58:02.000000000 +0000
+++ linux-2.4.20/arch/cris/kernel/kgdb.c	2002-10-04 00:41:30.000000000 +0000
@@ -18,6 +18,9 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.7  2002/07/12 09:14:56  bjornw
+*! Corrected typo
+*!
 *! Revision 1.6  2001/10/09 13:10:03  matsfg
 *! Added $ on registers and removed some underscores
 *!
@@ -55,7 +58,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.6 2001/10/09 13:10:03 matsfg Exp $
+*! $Id: kgdb.c,v 1.7 2002/07/12 09:14:56 bjornw Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -1064,7 +1067,7 @@
 					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
 					int status;
 #ifdef PROCESS_SUPPORT
-					if (current_thread_g =! executing_task)
+					if (current_thread_g != executing_task)
 						status = write_stack_register (current_thread_g, regno, suffix+1);
 					else
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/setup.c linux-2.4.20/arch/cris/kernel/setup.c
--- linux-2.4.19/arch/cris/kernel/setup.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.20/arch/cris/kernel/setup.c	2002-10-04 00:41:29.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.24 2001/12/07 17:03:19 bjornw Exp $
+/* $Id: setup.c,v 1.26 2002/06/04 07:57:56 jonashg Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -169,20 +169,18 @@
 
 	*cmdline_p = command_line;
 
-	if (romfs_in_flash) {
-		strncpy(command_line, "root=", COMMAND_LINE_SIZE);
-		strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
+	strncpy(command_line, "root=", COMMAND_LINE_SIZE);
+	strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
 			COMMAND_LINE_SIZE-5);
 
-		/* Save command line copy for /proc/cmdline */
-
-		memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
-		saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-	}
+	/* Save command line copy for /proc/cmdline */
+	
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	/* give credit for the CRIS port */
 
-	printk("Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n");
+	printk("Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n");
 
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/traps.c linux-2.4.20/arch/cris/kernel/traps.c
--- linux-2.4.19/arch/cris/kernel/traps.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.20/arch/cris/kernel/traps.c	2002-10-04 00:41:29.000000000 +0000
@@ -230,8 +230,12 @@
 #endif	
 }
 
-/* This is normally the 'Oops' routine */
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
 
+/* This is normally the 'Oops' routine */
 void 
 die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/dram_init.S linux-2.4.20/arch/cris/lib/dram_init.S
--- linux-2.4.19/arch/cris/lib/dram_init.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.20/arch/cris/lib/dram_init.S	2002-10-04 00:41:15.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.10 2001/10/04 12:00:21 martinnn Exp $
+/* $Id: dram_init.S,v 1.12 2002/08/09 11:37:37 orjanf Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,12 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.12  2002/08/09 11:37:37  orjanf
+ * Added double initialization work-around for Samsung SDRAMs.
+ *
+ * Revision 1.11  2002/06/04 11:43:21  starvik
+ * Check if mrs_data is specified in kernelconfig (necessary for MCM)
+ *
  * Revision 1.10  2001/10/04 12:00:21  martinnn
  * Added missing underscores.
  *
@@ -70,7 +76,11 @@
 
 	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
 	move.d   $r0, [R_DRAM_TIMING]
-#else	
+#else
+	;; Samsung SDRAMs seem to require to be initialized twice to work properly.
+	moveq    2, $r6	
+_sdram_init:
+	
 	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
 	
 	; Bank configuration
@@ -82,6 +92,12 @@
 	; CAS latency = 3 && bus_width = 32 => 0x60
 	; CAS latency = 2 && bus_width = 16 => 0x20
 	; CAS latency = 3 && bus_width = 16 => 0x30
+
+	; Check if value is already supplied in kernel config
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2
+	and.d    0x00ff0000, $r2
+	bne	 _set_timing
+	lsrq     16, $r2
 	
 	move.d   0x40, $r2       ; Assume 32 bits and CAS latency = 2
 	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
@@ -142,6 +158,9 @@
 	bne      1b
 	nop
 	move.d   $r5, [R_SDRAM_TIMING]
+	subq     1, $r6
+	bne      _sdram_init
+	nop
 	ba       _sdram_commands_end
 	nop
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/hw_settings.S linux-2.4.20/arch/cris/lib/hw_settings.S
--- linux-2.4.19/arch/cris/lib/hw_settings.S	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/cris/lib/hw_settings.S	2002-10-04 00:41:19.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: hw_settings.S,v 1.3 2001/04/21 17:02:46 bjornw Exp $
+ * $Id: hw_settings.S,v 1.4 2002/07/04 16:58:56 pkj Exp $
  * 
  * This table is used by some tools to extract hardware parameters.
  * The table should be included in the kernel and the decompressor.
@@ -16,8 +16,8 @@
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
 	
-	.ascii "HW_PARAM_MAGIC" ; Magic number
-	.dword 0xc0004000	; Kernel start address
+	.ascii "HW_PARAM_MAGIC"					; Magic number
+	.dword CONFIG_ETRAX_DRAM_VIRTUAL_BASE | 0x80004000	; Kernel start address
 
 	; Debug port
 #ifdef CONFIG_ETRAX_DEBUG_PORT0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/mm/fault.c linux-2.4.20/arch/cris/mm/fault.c
--- linux-2.4.19/arch/cris/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/cris/mm/fault.c	2002-10-04 00:41:15.000000000 +0000
@@ -6,6 +6,9 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.21  2002/05/28 14:24:56  bjornw
+ *  Corrected typo
+ *
  *  Revision 1.20  2001/11/22 13:34:06  bjornw
  *  * Bug workaround (LX TR89): force a rerun of the whole of an interrupted
  *    unaligned write, because the second half of the write will be corrupted
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/boot/compressed/misc.c linux-2.4.20/arch/i386/boot/compressed/misc.c
--- linux-2.4.19/arch/i386/boot/compressed/misc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/boot/compressed/misc.c	2002-10-04 00:41:21.000000000 +0000
@@ -9,6 +9,8 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
+#define STANDALONE
+
 #include <linux/linkage.h>
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
@@ -124,10 +126,6 @@
 static int vidport;
 static int lines, cols;
 
-#ifdef CONFIG_MULTIQUAD
-static void * const xquad_portio = NULL;
-#endif
-
 #include "../../../../lib/inflate.c"
 
 static void *malloc(int size)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/config.in linux-2.4.20/arch/i386/config.in
--- linux-2.4.19/arch/i386/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/config.in	2002-10-04 00:41:15.000000000 +0000
@@ -5,7 +5,6 @@
 mainmenu_name "Linux Kernel Configuration"
 
 define_bool CONFIG_X86 y
-define_bool CONFIG_ISA y
 define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
@@ -54,6 +53,7 @@
    define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
    define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 else
    define_bool CONFIG_X86_WP_WORKS_OK y
    define_bool CONFIG_X86_INVLPG y
@@ -69,99 +69,112 @@
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586TSC" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586MMX" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M686" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUM4" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 7
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MK6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
 fi
 if [ "$CONFIG_MK7" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 6
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MELAN" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 4
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MCYRIXIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
 fi
 if [ "$CONFIG_MCRUSOE" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIPC6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP2" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP3D" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 
 bool 'Machine Check Exception' CONFIG_X86_MCE
@@ -177,14 +190,19 @@
 	"off    CONFIG_NOHIGHMEM \
 	 4GB    CONFIG_HIGHMEM4G \
 	 64GB   CONFIG_HIGHMEM64G" off
-if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
+if [ "$CONFIG_HIGHMEM4G" = "y" -o "$CONFIG_HIGHMEM64G" = "y" ]; then
    define_bool CONFIG_HIGHMEM y
+else
+   define_bool CONFIG_HIGHMEM n
 fi
 if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
-   define_bool CONFIG_HIGHMEM y
    define_bool CONFIG_X86_PAE y
 fi
 
+if [ "$CONFIG_HIGHMEM" = "y" ]; then
+   bool 'HIGHMEM I/O support' CONFIG_HIGHIO
+fi
+
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -201,6 +219,11 @@
    bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
+bool 'Unsynced TSC support' CONFIG_X86_TSC_DISABLE
+if [ "$CONFIG_X86_TSC_DISABLE" != "y" -a "$CONFIG_X86_HAS_TSC" = "y" ]; then
+   define_bool CONFIG_X86_TSC y
+fi
+
 if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
    define_bool CONFIG_HAVE_DEC_LOCK y
 fi
@@ -218,6 +241,7 @@
    define_bool CONFIG_X86_VISWS_APIC y
    define_bool CONFIG_X86_LOCAL_APIC y
    define_bool CONFIG_PCI y
+   define_bool CONFIG_ISA n
 else
    if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
@@ -236,6 +260,7 @@
          define_bool CONFIG_PCI_DIRECT y
       fi
    fi
+   bool 'ISA bus support' CONFIG_ISA
 fi
 
 source drivers/pci/Config.in
@@ -366,14 +391,16 @@
 fi
 endmenu
 
-mainmenu_option next_comment
-comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-
-bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-   source drivers/cdrom/Config.in
+if [ "$CONFIG_ISA" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+    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
+    endmenu
 fi
-endmenu
 
 #
 # input before char - char/joystick depends on it. As does USB.
@@ -417,6 +444,7 @@
 
 bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
 if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+   bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
    bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
@@ -426,3 +454,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/defconfig linux-2.4.20/arch/i386/defconfig
--- linux-2.4.19/arch/i386/defconfig	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/defconfig	2002-10-04 00:41:11.000000000 +0000
@@ -617,7 +617,8 @@
 CONFIG_DRM_TDFX=y
 # CONFIG_DRM_R128 is not set
 CONFIG_DRM_RADEON=y
-# CONFIG_DRM_I810 is not set
+CONFIG_DRM_I810=y
+CONFIG_DRM_I810_XFREE_41=y
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/Makefile linux-2.4.20/arch/i386/kernel/Makefile
--- linux-2.4.19/arch/i386/kernel/Makefile	2001-11-09 22:21:21.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/Makefile	2002-10-04 00:41:12.000000000 +0000
@@ -14,7 +14,7 @@
 
 O_TARGET := kernel.o
 
-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o
+export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apic.c linux-2.4.20/arch/i386/kernel/apic.c
--- linux-2.4.19/arch/i386/kernel/apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/apic.c	2002-10-04 00:41:20.000000000 +0000
@@ -1050,7 +1050,7 @@
 /*
  * Local APIC timer interrupt. This is the most natural way for doing
  * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesnt support APIC timers]
+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
  *
  * [ if a single-CPU system runs an SMP kernel then we call the local
  *   interrupt as well. Thus we cannot inline the local irq ... ]
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apm.c linux-2.4.20/arch/i386/kernel/apm.c
--- linux-2.4.19/arch/i386/kernel/apm.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/apm.c	2002-10-04 00:41:10.000000000 +0000
@@ -847,6 +847,7 @@
 			case 1: apm_idle_done = 1;
 				break;
 			default: /* BIOS refused */
+				break;
 			}
 		}
 		if (original_pm_idle)
@@ -862,14 +863,6 @@
 		apm_do_busy();
 }
 
-#ifdef CONFIG_SMP
-static int apm_magic(void * unused)
-{
-	while (1)
-		schedule();
-}
-#endif
-
 /**
  *	apm_power_off	-	ask the BIOS to power off
  *
@@ -897,10 +890,11 @@
 	 */
 #ifdef CONFIG_SMP
 	/* Some bioses don't like being called from CPU != 0 */
-	while (cpu_number_map(smp_processor_id()) != 0) {
-		kernel_thread(apm_magic, NULL,
-			CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
 		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
 	}
 #endif
 	if (apm_info.realmode_power_off)
@@ -1661,6 +1655,21 @@
 	strcpy(current->comm, "kapmd");
 	sigfillset(&current->blocked);
 
+#ifdef CONFIG_SMP
+	/* 2002/08/01 - WT
+	 * This is to avoid random crashes at boot time during initialization
+	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
+	 * Some bioses don't like being called from CPU != 0.
+	 * Method suggested by Ingo Molnar.
+	 */
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
+		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
+	}
+#endif
+	
 	if (apm_info.connection_version == 0) {
 		apm_info.connection_version = apm_info.bios.version;
 		if (apm_info.connection_version > 0x100) {
@@ -1707,7 +1716,7 @@
 		}
 	}
 
-	if (debug && (smp_num_cpus == 1)) {
+	if (debug) {
 		error = apm_get_power_status(&bx, &cx, &dx);
 		if (error)
 			printk(KERN_INFO "apm: power status not available\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/dmi_scan.c linux-2.4.20/arch/i386/kernel/dmi_scan.c
--- linux-2.4.19/arch/i386/kernel/dmi_scan.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/dmi_scan.c	2002-10-04 00:41:16.000000000 +0000
@@ -190,7 +190,6 @@
  *	KT7 series. On these it seems the newer BIOS has fixed them. The
  *	rule needs to be improved to match specific BIOS revisions with
  *	corruption problems
- */ 
  
 static __init int disable_ide_dma(struct dmi_blacklist *d)
 {
@@ -204,6 +203,7 @@
 #endif	
 	return 0;
 }
+ */ 
 
 /* 
  * Reboot options and system auto-detection code provided by
@@ -564,6 +564,17 @@
 			MATCH(DMI_BIOS_VERSION, "Version1.01"),
 			NO_MATCH, NO_MATCH,
 			} },
+	{ apm_is_horked, "Intel D850MD", { /* APM crashes */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
+			MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_is_horked, "Dell XPS-Z", { /* APM crashes */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
+			MATCH(DMI_BIOS_VERSION, "A11"),
+			MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
+			NO_MATCH,
+			} },
 	{ apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */
 			MATCH(DMI_SYS_VENDOR, "SHARP"),
 			MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
@@ -635,6 +646,12 @@
 			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
 			} },
 	
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "WXP01Z3"),
+			MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
+			} },
+	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-F104K */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0204K2"),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/entry.S linux-2.4.20/arch/i386/kernel/entry.S
--- linux-2.4.19/arch/i386/kernel/entry.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/entry.S	2002-10-04 00:41:14.000000000 +0000
@@ -622,23 +622,33 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
 	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_readahead)	/* 225 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for setxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lsetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fsetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for getxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 230 reserved for lgetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fgetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for listxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for llistxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for flistxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 235 reserved for removexattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lremovexattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fremovexattr */
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
  	.long SYMBOL_NAME(sys_tkill)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sendfile64 */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_get_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 245 sys_io_setup */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_destroy */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_getevents */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_submit */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_cancel */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 250 sys_alloc_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/io_apic.c linux-2.4.20/arch/i386/kernel/io_apic.c
--- linux-2.4.19/arch/i386/kernel/io_apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/io_apic.c	2002-10-04 00:41:15.000000000 +0000
@@ -716,7 +716,7 @@
 	entry.vector = vector;
 
 	/*
-	 * The timer IRQ doesnt have to know that behind the
+	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
 	irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -1586,7 +1586,7 @@
 	printk(" failed.\n");
 
 	if (nmi_watchdog) {
-		printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
 		nmi_watchdog = 0;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/irq.c linux-2.4.20/arch/i386/kernel/irq.c
--- linux-2.4.19/arch/i386/kernel/irq.c	2001-10-25 20:53:46.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/irq.c	2002-10-04 00:41:10.000000000 +0000
@@ -577,6 +577,20 @@
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
 	unsigned int status;
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	long esp;
+
+	/* Debugging check for stack overflow: is there less than 1KB free? */
+	__asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
+	if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
+		extern void show_stack(unsigned long *);
+
+		printk("do_IRQ: stack overflow: %ld\n",
+			esp - sizeof(struct task_struct));
+		__asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
+		show_stack((void *)esp);
+	}
+#endif
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/mpparse.c linux-2.4.20/arch/i386/kernel/mpparse.c
--- linux-2.4.19/arch/i386/kernel/mpparse.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/mpparse.c	2002-10-04 00:41:15.000000000 +0000
@@ -115,6 +115,8 @@
 		case 0x0F:
 			if (model == 0x00)
 				return("Pentium 4(tm)");
+			if (model == 0x02)
+				return("Pentium 4(tm) XEON(tm)");
 			if (model == 0x0F)
 				return("Special controller");
 	}
@@ -815,7 +817,7 @@
 
 /*
  * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
+ * sense, but it doesn't have a BIOS(-configuration table).
  * No problem for Linux.
  */
 void __init find_visws_smp(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-dma.c linux-2.4.20/arch/i386/kernel/pci-dma.c
--- linux-2.4.19/arch/i386/kernel/pci-dma.c	2000-02-14 23:34:21.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/pci-dma.c	2002-10-04 00:41:13.000000000 +0000
@@ -19,7 +19,7 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+	if (hwdev == NULL || ((u32)hwdev->dma_mask != 0xffffffff))
 		gfp |= GFP_DMA;
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.c linux-2.4.20/arch/i386/kernel/pci-i386.c
--- linux-2.4.19/arch/i386/kernel/pci-i386.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/pci-i386.c	2002-10-04 00:41:14.000000000 +0000
@@ -136,7 +136,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
@@ -303,7 +304,7 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_resources(struct pci_dev *dev)
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -312,6 +313,10 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+			
 		r = &dev->resource[idx];
 		if (!r->start && r->end) {
 			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
@@ -347,7 +352,7 @@
 		lat = pcibios_max_latency;
 	else
 		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.h linux-2.4.20/arch/i386/kernel/pci-i386.h
--- linux-2.4.19/arch/i386/kernel/pci-i386.h	2001-11-11 18:09:32.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/pci-i386.h	2002-10-04 00:41:10.000000000 +0000
@@ -29,7 +29,7 @@
 extern unsigned int pcibios_max_latency;
 
 void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *);
+int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-pc.c */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-pc.c linux-2.4.20/arch/i386/kernel/pci-pc.c
--- linux-2.4.19/arch/i386/kernel/pci-pc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/pci-pc.c	2002-10-04 00:41:16.000000000 +0000
@@ -54,11 +54,11 @@
 #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
 	(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
 
-static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */
+static int pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -82,11 +82,11 @@
 	return 0;
 }
 
-static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */
+static int pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -110,7 +110,69 @@
 	return 0;
 }
 
-#else /* !CONFIG_MULTIQUAD */
+static int pci_conf1_read_mq_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	int result; 
+	u32 data;
+
+	result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8)data;
+
+	return result;
+}
+
+static int pci_conf1_read_mq_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	int result; 
+	u32 data;
+
+	result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16)data;
+
+	return result;
+}
+
+static int pci_conf1_read_mq_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	if (!value) 
+		return -EINVAL;
+
+	return pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static int pci_conf1_write_mq_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
+}
+
+static int pci_conf1_write_mq_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
+}
+
+static int pci_conf1_write_mq_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static struct pci_ops pci_direct_mq_conf1 = {
+	pci_conf1_read_mq_config_byte,
+	pci_conf1_read_mq_config_word,
+	pci_conf1_read_mq_config_dword,
+	pci_conf1_write_mq_config_byte,
+	pci_conf1_write_mq_config_word,
+	pci_conf1_write_mq_config_dword
+};
+
+#endif /* !CONFIG_MULTIQUAD */
 #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
 	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
 
@@ -118,7 +180,7 @@
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -146,7 +208,7 @@
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -170,8 +232,6 @@
 	return 0;
 }
 
-#endif /* CONFIG_MULTIQUAD */
-
 #undef PCI_CONF1_ADDRESS
 
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
@@ -179,9 +239,6 @@
 	int result; 
 	u32 data;
 
-	if (!value) 
-		return -EINVAL;
-
 	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 1, &data);
 
@@ -195,9 +252,6 @@
 	int result; 
 	u32 data;
 
-	if (!value) 
-		return -EINVAL;
-
 	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 2, &data);
 
@@ -208,9 +262,6 @@
 
 static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	if (!value) 
-		return -EINVAL;
-
 	return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 4, value);
 }
@@ -253,7 +304,7 @@
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	if (dev & 0x10) 
@@ -287,7 +338,7 @@
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	if (dev & 0x10) 
@@ -423,6 +474,12 @@
 			__restore_flags(flags);
 			printk(KERN_INFO "PCI: Using configuration type 1\n");
 			request_region(0xCF8, 8, "PCI conf1");
+
+#ifdef CONFIG_MULTIQUAD			
+			/* Multi-Quad has an extended PCI Conf1 */
+			if(clustered_apic_mode)
+				return &pci_direct_mq_conf1;
+#endif				
 			return &pci_direct_conf1;
 		}
 		outl (tmp, 0xCF8);
@@ -640,7 +697,7 @@
 	unsigned long flags;
 	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -695,7 +752,7 @@
 	unsigned long flags;
 	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -750,7 +807,7 @@
 	u32 data;
 
 	if (!value) 
-		return -EINVAL;
+		BUG();
 
 	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 1, &data);
@@ -766,7 +823,7 @@
 	u32 data;
 
 	if (!value) 
-		return -EINVAL;
+		BUG();
 
 	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 2, &data);
@@ -779,7 +836,7 @@
 static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
 	if (!value) 
-		return -EINVAL;
+		BUG();
 	
 	return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 4, value);
@@ -1227,6 +1284,11 @@
 	pci_read_config_byte(d, PCI_REVISION_ID, &revision);
 	
 	if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
+		/* fix pci bus latency issues resulted by NB bios error
+		   it appears on bug free^Wreduced kt266x's bios forces
+		   NB latency to zero */
+		pci_write_config_byte(d, PCI_LATENCY_TIMER, 0);
+
 		where = 0x95; /* the memory write queue timer register is 
 				 different for the KT266x's: 0x95 not 0x55 */
 	} else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
@@ -1245,6 +1307,22 @@
 	}
 }
 
+/*
+ * For some reasons Intel decided that certain parts of their
+ * 815, 845 and some other chipsets must look like PCI-to-PCI bridges
+ * while they are obviously not. The 82801 family (AA, AB, BAM/CAM,
+ * BA/CA/DB and E) PCI bridges are actually HUB-to-PCI ones, according
+ * to Intel terminology. These devices do forward all addresses from
+ * system to PCI bus no matter what are their window settings, so they are
+ * "transparent" (or subtractive decoding) from programmers point of view.
+ */
+static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
+{
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+	    (dev->device & 0xff00) == 0x2400)
+		dev->transparent = 1;
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82451NX,	pci_fixup_i450nx },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454GX,	pci_fixup_i450gx },
@@ -1259,6 +1337,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,	        pci_fixup_via_northbridge_bug },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8367_0,	pci_fixup_via_northbridge_bug },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	pci_fixup_ncr53c810 },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_ANY_ID,			pci_fixup_transparent_bridge },
 	{ 0 }
 };
 
@@ -1281,6 +1360,11 @@
 	 * both PCI BIOS and direct access, with a preference for direct.
 	 */
 
+#ifdef CONFIG_PCI_DIRECT
+	struct pci_ops *tmp = NULL;
+#endif
+
+
 #ifdef CONFIG_PCI_BIOS
 	if ((pci_probe & PCI_PROBE_BIOS) 
 		&& ((pci_root_ops = pci_find_bios()))) {
@@ -1293,7 +1377,8 @@
 
 #ifdef CONFIG_PCI_DIRECT
 	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
-		&& (pci_root_ops = pci_check_direct())) {
+		&& (tmp = pci_check_direct())) {
+		pci_root_ops = tmp;
 		if (pci_root_ops == &pci_direct_conf1) {
 			pci_config_read = pci_conf1_read;
 			pci_config_write = pci_conf1_write;
@@ -1393,11 +1478,11 @@
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
 
-	if ((err = pcibios_enable_resources(dev)) < 0)
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 	pcibios_enable_irq(dev);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-visws.c linux-2.4.20/arch/i386/kernel/pci-visws.c
--- linux-2.4.19/arch/i386/kernel/pci-visws.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/pci-visws.c	2002-10-04 00:41:13.000000000 +0000
@@ -131,9 +131,9 @@
 	return str;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	return pcibios_enable_resources(dev);
+	return pcibios_enable_resources(dev, mask);
 }
 
 void __init pcibios_penalize_isa_irq(irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/semaphore.c linux-2.4.20/arch/i386/kernel/semaphore.c
--- linux-2.4.19/arch/i386/kernel/semaphore.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/semaphore.c	2002-10-04 00:41:17.000000000 +0000
@@ -262,31 +262,30 @@
  */
 #if defined(CONFIG_SMP)
 asm(
-"
-.align	4
-.globl	__write_lock_failed
-__write_lock_failed:
-	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)
-1:	rep; nop
-	cmpl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jne	1b
-
-	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jnz	__write_lock_failed
-	ret
-
-
-.align	4
-.globl	__read_lock_failed
-__read_lock_failed:
-	lock ; incl	(%eax)
-1:	rep; nop
-	cmpl	$1,(%eax)
-	js	1b
+".text\n"
+".align	4\n"
+".globl	__write_lock_failed\n"
+"__write_lock_failed:\n\t"
+	LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jne	1b\n\t"
+	LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jnz	__write_lock_failed\n\t"
+	"ret"
+);
 
-	lock ; decl	(%eax)
-	js	__read_lock_failed
-	ret
-"
+asm(
+".text\n"
+".align	4\n"
+".globl	__read_lock_failed\n"
+"__read_lock_failed:\n\t"
+	LOCK "incl	(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$1,(%eax)\n\t"
+	"js	1b\n\t"
+	LOCK "decl	(%eax)\n\t"
+	"js	__read_lock_failed\n\t"
+	"ret"
 );
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/setup.c linux-2.4.20/arch/i386/kernel/setup.c
--- linux-2.4.19/arch/i386/kernel/setup.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/setup.c	2002-10-04 00:41:20.000000000 +0000
@@ -71,13 +71,6 @@
  *  CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
  *  Dave Jones <davej@suse.de>, September, October 2001.
  *
- *  Short-term fix for a conflicting cache attribute bug in the kernel
- *  that is exposed by advanced speculative caching on new AMD Athlon
- *  processors.
- *  Richard Brunner <richard.brunner@amd.com> and Mark Langsdorf
- *  <mark.langsdorf@amd.com>, June 2002 
- *  Adapted to work with uniprocessor APIC by Bryan O'Sullivan
- *  <bos@serpentine.com>, June 2002.
  */
 
 /*
@@ -171,18 +164,15 @@
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 
+static int have_cpuid_p(void) __init;
+
 static int disable_x86_serial_nr __initdata = 1;
-static int disable_x86_fxsr __initdata = 0;
 static int disable_x86_ht __initdata = 0;
+static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 };
+extern int blk_nohighio;
 
 int enable_acpi_smp_table;
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-int disable_adv_spec_cache __initdata = 1;
-#else
-int disable_adv_spec_cache __initdata = 0;
-#endif /* CONFIG_AGP */
-
 /*
  * This is set up by the setup-routine at boot-time
  */
@@ -741,41 +731,6 @@
 } /* setup_memory_region */
 
 
-int __init amd_adv_spec_cache_feature(void)
-{
-	char vendor_id[16];
-	int ident;
-	int family, model;
- 
-	/* Must have CPUID */
-	if(!have_cpuid_p())
-		goto donthave;
-	if(cpuid_eax(0)<1)
-		goto donthave;
-	
-	/* Must be x86 architecture */
-	cpuid(0, &ident,  
-		(int *)&vendor_id[0],
-		(int *)&vendor_id[8],
-		(int *)&vendor_id[4]);
-
-	if (memcmp(vendor_id, "AuthenticAMD", 12)) 
-	       goto donthave;
-
-	ident = cpuid_eax(1);
-	family = (ident >> 8) & 0xf;
-	model  = (ident >> 4) & 0xf;
-	if (((family == 6)  && (model >= 6)) || (family == 15)) {
-		printk(KERN_INFO "Advanced speculative caching feature present\n");
-		return 1;
-	}
-
-donthave:
-	printk(KERN_INFO "Advanced speculative caching feature not present\n");
-	return 0;
-}
-
-
 static void __init parse_cmdline_early (char ** cmdline_p)
 {
 	char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -802,6 +757,7 @@
 			if (!memcmp(from+4, "nopentium", 9)) {
 				from += 9+4;
 				clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
+				set_bit(X86_FEATURE_PSE, &disabled_x86_caps);
 			} else if (!memcmp(from+4, "exactmap", 8)) {
 				from += 8+4;
 				e820.nr_map = 0;
@@ -827,8 +783,10 @@
 		}
 
 		/* "noht" disables HyperThreading (2 logical cpus per Xeon) */
-		else if (!memcmp(from, "noht", 4))
+		else if (!memcmp(from, "noht", 4)) { 
 			disable_x86_ht = 1;
+			set_bit(X86_FEATURE_HT, disabled_x86_caps);
+		}
 
 		/* "acpismp=force" forces parsing and use of the ACPI SMP table */
 		else if (!memcmp(from, "acpismp=force", 13))
@@ -841,17 +799,6 @@
 		 */
 		else if (!memcmp(from, "highmem=", 8))
 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
-		/*
-		 * unsafe-gart-alias overrides the short-term fix for a
-		 * conflicting cache attribute bug in the kernel that is
-		 * exposed by advanced speculative caching in newer AMD
-		 * Athlon processors.  Overriding the fix will allow
-		 * higher performance but the kernel bug can cause system
-		 * lock-ups if the system uses an AGP card.  unsafe-gart-alias
-		 * can be turned on for higher performance in servers.
-		 */
-		else if (!memcmp(from, "unsafe-gart-alias", 17))
-			disable_adv_spec_cache = 0;
 nextchar:
 		c = *(from++);
 		if (!c)
@@ -868,49 +815,6 @@
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
-{
-	unsigned long bootmap_size, low_mem_size;
-	unsigned long start_pfn, max_pfn, max_low_pfn;
-	int i;
-
-#ifdef CONFIG_VISWS
-	visws_get_board_type_and_rev();
-#endif
-
- 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
- 	drive_info = DRIVE_INFO;
- 	screen_info = SCREEN_INFO;
-	apm_info.bios = APM_BIOS_INFO;
-	if( SYS_DESC_TABLE.length != 0 ) {
-		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
-		machine_id = SYS_DESC_TABLE.table[0];
-		machine_submodel_id = SYS_DESC_TABLE.table[1];
-		BIOS_revision = SYS_DESC_TABLE.table[2];
-	}
-	aux_device_present = AUX_DEVICE_INFO;
-
-#ifdef CONFIG_BLK_DEV_RAM
-	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
-	setup_memory_region();
-
-	if (!MOUNT_ROOT_RDONLY)
-		root_mountflags &= ~MS_RDONLY;
-	init_mm.start_code = (unsigned long) &_text;
-	init_mm.end_code = (unsigned long) &_etext;
-	init_mm.end_data = (unsigned long) &_edata;
-	init_mm.brk = (unsigned long) &_end;
-
-	code_resource.start = virt_to_bus(&_text);
-	code_resource.end = virt_to_bus(&_etext)-1;
-	data_resource.start = virt_to_bus(&_etext);
-	data_resource.end = virt_to_bus(&_edata)-1;
-
-	parse_cmdline_early(cmdline_p);
-
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
@@ -921,15 +825,13 @@
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
 #define MAX_NONPAE_PFN	(1 << 20)
 
-	/*
-	 * partially used pages are not usable - thus
-	 * we are rounding upwards:
-	 */
-	start_pfn = PFN_UP(__pa(&_end));
+/*
+ * Find the highest page frame number we have available
+ */
+static void __init find_max_pfn(void)
+{
+	int i;
 
-	/*
-	 * Find the highest page frame number we have available
-	 */
 	max_pfn = 0;
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long start, end;
@@ -943,10 +845,15 @@
 		if (end > max_pfn)
 			max_pfn = end;
 	}
+}
+
+/*
+ * Determine low and high memory ranges:
+ */
+static unsigned long __init find_max_low_pfn(void)
+{
+	unsigned long max_low_pfn;
 
-	/*
-	 * Determine low and high memory ranges:
-	 */
 	max_low_pfn = max_pfn;
 	if (max_low_pfn > MAXMEM_PFN) {
 		if (highmem_pages == -1)
@@ -996,27 +903,19 @@
 #endif
 	}
 
-#ifdef CONFIG_HIGHMEM
-	highstart_pfn = highend_pfn = max_pfn;
-	if (max_pfn > max_low_pfn) {
-		highstart_pfn = max_low_pfn;
-	}
-	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-		pages_to_mb(highend_pfn - highstart_pfn));
-#endif
-	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
-			pages_to_mb(max_low_pfn));
-	/*
-	 * Initialize the boot-time allocator (with low memory only):
-	 */
-	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+	return max_low_pfn;
+}
+
+/*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
+{
+	int i;
 
-	/*
-	 * Register fully available low RAM pages with the bootmem allocator.
-	 */
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long curr_pfn, last_pfn, size;
- 		/*
+		/*
 		 * Reserve usable low memory
 		 */
 		if (e820.map[i].type != E820_RAM)
@@ -1045,6 +944,39 @@
 		size = last_pfn - curr_pfn;
 		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
 	}
+}
+
+static unsigned long __init setup_memory(void)
+{
+	unsigned long bootmap_size, start_pfn, max_low_pfn;
+
+	/*
+	 * partially used pages are not usable - thus
+	 * we are rounding upwards:
+	 */
+	start_pfn = PFN_UP(__pa(&_end));
+
+	find_max_pfn();
+
+	max_low_pfn = find_max_low_pfn();
+
+#ifdef CONFIG_HIGHMEM
+	highstart_pfn = highend_pfn = max_pfn;
+	if (max_pfn > max_low_pfn) {
+		highstart_pfn = max_low_pfn;
+	}
+	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+		pages_to_mb(highend_pfn - highstart_pfn));
+#endif
+	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
+			pages_to_mb(max_low_pfn));
+	/*
+	 * Initialize the boot-time allocator (with low memory only):
+	 */
+	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+
+	register_bootmem_low_pages(max_low_pfn);
+
 	/*
 	 * Reserve the bootmem bitmap itself as well. We do this in two
 	 * steps (first step was init_bootmem()) because this catches
@@ -1093,51 +1025,18 @@
 	}
 #endif
 
-	/*
-	 * If enable_acpi_smp_table and HT feature present, acpitable.c
-	 * will find all logical cpus despite disable_x86_ht: so if both
-	 * "noht" and "acpismp=force" are specified, let "noht" override
-	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
-	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
-	 */
-	if (disable_x86_ht) {
-		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
-		enable_acpi_smp_table = 0;
-	}
-	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
-		enable_acpi_smp_table = 1;
-	
-
-	/*
-	 * NOTE: before this point _nobody_ is allowed to allocate
-	 * any memory using the bootmem allocator.
-	 */
-
-#ifdef CONFIG_SMP
-	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
-#endif
-	/*
-	 * short-term fix for a conflicting cache attribute bug in the 
-	 * kernel that is exposed by advanced speculative caching on
-	 * newer AMD Athlon processors.
-	 */
-	if (disable_adv_spec_cache && amd_adv_spec_cache_feature())
-		clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
-
-	paging_init();
-#ifdef CONFIG_X86_LOCAL_APIC
-	/*
-	 * get boot-time SMP configuration:
-	 */
-	if (smp_found_config)
-		get_smp_config();
-#endif
-
+	return max_low_pfn;
+}
+ 
+/*
+ * Request address space for all standard RAM and ROM resources
+ * and also for regions reported as reserved by the e820.
+ */
+static void __init register_memory(unsigned long max_low_pfn)
+{
+	unsigned long low_mem_size;
+	int i;
 
-	/*
-	 * Request address space for all standard RAM and ROM resources
-	 * and also for regions reported as reserved by the e820.
-	 */
 	probe_roms();
 	for (i = 0; i < e820.nr_map; i++) {
 		struct resource *res;
@@ -1174,6 +1073,89 @@
 	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
 	if (low_mem_size > pci_mem_start)
 		pci_mem_start = low_mem_size;
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	unsigned long max_low_pfn;
+
+#ifdef CONFIG_VISWS
+	visws_get_board_type_and_rev();
+#endif
+
+#ifndef CONFIG_HIGHIO
+	blk_nohighio = 1;
+#endif
+
+ 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+ 	drive_info = DRIVE_INFO;
+ 	screen_info = SCREEN_INFO;
+	apm_info.bios = APM_BIOS_INFO;
+	if( SYS_DESC_TABLE.length != 0 ) {
+		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
+		machine_id = SYS_DESC_TABLE.table[0];
+		machine_submodel_id = SYS_DESC_TABLE.table[1];
+		BIOS_revision = SYS_DESC_TABLE.table[2];
+	}
+	aux_device_present = AUX_DEVICE_INFO;
+
+#ifdef CONFIG_BLK_DEV_RAM
+	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+#endif
+	setup_memory_region();
+
+	if (!MOUNT_ROOT_RDONLY)
+		root_mountflags &= ~MS_RDONLY;
+	init_mm.start_code = (unsigned long) &_text;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_end;
+
+	code_resource.start = virt_to_bus(&_text);
+	code_resource.end = virt_to_bus(&_etext)-1;
+	data_resource.start = virt_to_bus(&_etext);
+	data_resource.end = virt_to_bus(&_edata)-1;
+
+	parse_cmdline_early(cmdline_p);
+
+	max_low_pfn = setup_memory();
+
+	/*
+	 * If enable_acpi_smp_table and HT feature present, acpitable.c
+	 * will find all logical cpus despite disable_x86_ht: so if both
+	 * "noht" and "acpismp=force" are specified, let "noht" override
+	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
+	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
+	 */
+	if (disable_x86_ht) {
+		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
+		set_bit(X86_FEATURE_HT, disabled_x86_caps);
+		enable_acpi_smp_table = 0;
+	}
+	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
+		enable_acpi_smp_table = 1;
+	
+
+	/*
+	 * NOTE: before this point _nobody_ is allowed to allocate
+	 * any memory using the bootmem allocator.
+	 */
+
+#ifdef CONFIG_SMP
+	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+#endif
+	paging_init();
+#ifdef CONFIG_X86_LOCAL_APIC
+	/*
+	 * get boot-time SMP configuration:
+	 */
+	if (smp_found_config)
+		get_smp_config();
+#endif
+
+	register_memory(max_low_pfn);
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -1197,14 +1179,27 @@
 #ifndef CONFIG_X86_TSC
 static int tsc_disable __initdata = 0;
 
-static int __init tsc_setup(char *str)
+static int __init notsc_setup(char *str)
 {
 	tsc_disable = 1;
 	return 1;
 }
-
-__setup("notsc", tsc_setup);
+#else
+static int __init notsc_setup(char *str)
+{
+	printk("notsc: Kernel compiled with CONFIG_X86_TSC, cannot disable TSC.\n");
+	return 1;
+}
 #endif
+__setup("notsc", notsc_setup);
+
+static int __init highio_setup(char *str)
+{
+	printk("i386: disabling HIGHMEM block I/O\n");
+	blk_nohighio = 1;
+	return 1;
+}
+__setup("nohighio", highio_setup);
 
 static int __init get_model_name(struct cpuinfo_x86 *c)
 {
@@ -1292,31 +1287,6 @@
 	       l2size, ecx & 0xFF);
 }
 
-
-/*=======================================================================
- * amd_adv_spec_cache_disable
- * Setting a special MSR big that disables a small part of advanced
- * speculative caching as part of a short-term fix for a conflicting cache
- * attribute bug in the kernel that is exposed by advanced speculative
- * caching in newer AMD Athlon processors.
- =======================================================================*/
-static void amd_adv_spec_cache_disable(void)
-{
-	printk(KERN_INFO "Disabling advanced speculative caching\n");
-
-	__asm__ __volatile__ (
-		" movl	 $0x9c5a203a,%%edi   \n" /* msr enable */
-		" movl	 $0xc0011022,%%ecx   \n" /* msr addr	 */
-		" rdmsr			     \n" /* get reg val	 */
-		" orl	 $0x00010000,%%eax   \n" /* set bit 16	 */
-		" wrmsr			     \n" /* put it back	 */
-		" xorl	%%edi, %%edi	     \n" /* clear msr enable */
-		: /* no outputs */
-		: /* no inputs, either */
-		: "%eax","%ecx","%edx","%edi" /* clobbered regs */ );
-}
-
-
 /*
  *	B step AMD K6 before B 9730xxxx have hardware bugs that can cause
  *	misexecution of code under Linux. Owners of such processors should
@@ -1450,21 +1420,10 @@
  			 * to enable SSE on Palomino/Morgan CPU's.
 			 * If the BIOS didn't enable it already, enable it
 			 * here.
-			 *
-			 * Avoiding the use of 4MB/2MB pages along with
-			 * setting a special MSR bit that disables a small
-			 * part of advanced speculative caching as part of a
-			 * short-term fix for a conflicting cache attribute
-			 * bug in the kernel that is exposed by advanced
-			 * speculative caching in newer AMD Atlon processors.
-			 *
-			 * If we cleared the PSE bit earlier as part
-			 * of the workaround for this problem, we need
-			 * to clear it again, as our caller may have
-			 * clobbered it if uniprocessor APIC is enabled.
 			 */
-			if (c->x86_model >= 6) {
-				if (!cpu_has_xmm) {
+			if (c->x86_model == 6 || c->x86_model == 7) {
+				if (!test_bit(X86_FEATURE_XMM,
+					      &c->x86_capability)) {
 					printk(KERN_INFO
 					       "Enabling Disabled K7/SSE Support...\n");
 					rdmsr(MSR_K7_HWCR, l, h);
@@ -1473,18 +1432,6 @@
 					set_bit(X86_FEATURE_XMM,
                                                 &c->x86_capability);
 				}
-				if (disable_adv_spec_cache &&
-				    amd_adv_spec_cache_feature()) {
-					clear_bit(X86_FEATURE_PSE,
-						  &c->x86_capability);
-					amd_adv_spec_cache_disable();
-				}
-			}
-			break;
-		case 15: 
-			if (disable_adv_spec_cache && amd_adv_spec_cache_feature()) {
-				clear_bit(X86_FEATURE_PSE, &c->x86_capability);
-				amd_adv_spec_cache_disable();
 			}
 			break;
 
@@ -1534,7 +1481,7 @@
  * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
  * order to identify the Cyrix CPU model after we're out of setup.c
  *
- * Actually since bugs.h doesnt even reference this perhaps someone should
+ * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
 static unsigned char Cx86_dir0_msb __initdata = 0;
@@ -2198,6 +2145,11 @@
 	wrmsr(0x80860004, ~0, uk);
 	c->x86_capability[0] = cpuid_edx(0x00000001);
 	wrmsr(0x80860004, cap_mask, uk);
+
+	/* If we can run i686 user-space code, call us an i686 */
+#define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV)
+	if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 )
+	     c->x86 = 6;
 }
 
 
@@ -2227,31 +2179,69 @@
 
 extern void trap_init_f00f_bug(void);
 
+#define LVL_1_INST      1
+#define LVL_1_DATA      2
+#define LVL_2           3
+#define LVL_3           4
+
+struct _cache_table
+{
+        unsigned char descriptor;
+        char cache_type;
+        short size;
+};
+
+/* all the cache descriptor types we care about (no TLB or trace cache entries) */
+static struct _cache_table cache_table[] __initdata =
+{
+	{ 0x06, LVL_1_INST, 8 },
+	{ 0x08, LVL_1_INST, 16 },
+	{ 0x0A, LVL_1_DATA, 8 },
+	{ 0x0C, LVL_1_DATA, 16 },
+	{ 0x22, LVL_3,      512 },
+	{ 0x23, LVL_3,      1024 },
+	{ 0x25, LVL_3,      2048 },
+	{ 0x29, LVL_3,      4096 },
+	{ 0x41, LVL_2,      128 },
+	{ 0x42, LVL_2,      256 },
+	{ 0x43, LVL_2,      512 },
+	{ 0x44, LVL_2,      1024 },
+	{ 0x45, LVL_2,      2048 },
+	{ 0x66, LVL_1_DATA, 8 },
+	{ 0x67, LVL_1_DATA, 16 },
+	{ 0x68, LVL_1_DATA, 32 },
+	{ 0x79, LVL_2,      128 },
+	{ 0x7A, LVL_2,      256 },
+	{ 0x7B, LVL_2,      512 },
+	{ 0x7C, LVL_2,      1024 },
+	{ 0x82, LVL_2,      256 },
+	{ 0x84, LVL_2,      1024 },
+	{ 0x85, LVL_2,      2048 },
+	{ 0x00, 0, 0}
+};
+
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
-#ifndef CONFIG_M686
-	static int f00f_workaround_enabled = 0;
-#endif
-	char *p = NULL;
 	unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+	char *p = NULL;
+#ifndef CONFIG_X86_F00F_WORKS_OK
+	static int f00f_workaround_enabled = 0;
 
-#ifndef CONFIG_M686
 	/*
 	 * All current models of Pentium and Pentium with MMX technology CPUs
 	 * have the F0 0F bug, which lets nonpriviledged users lock up the system.
 	 * Note that the workaround only should be initialized once...
 	 */
 	c->f00f_bug = 0;
-	if ( c->x86 == 5 ) {
+	if (c->x86 == 5) {
 		c->f00f_bug = 1;
-		if ( !f00f_workaround_enabled ) {
+		if (!f00f_workaround_enabled) {
 			trap_init_f00f_bug();
 			printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
 			f00f_workaround_enabled = 1;
 		}
 	}
-#endif
-
+#endif /* CONFIG_X86_F00F_WORKS_OK */
 
 	if (c->cpuid_level > 1) {
 		/* supports eax=2  call */
@@ -2273,83 +2263,31 @@
 			/* Byte 0 is level count, not a descriptor */
 			for ( j = 1 ; j < 16 ; j++ ) {
 				unsigned char des = dp[j];
-				unsigned char dl, dh;
-				unsigned int cs;
-
-				dh = des >> 4;
-				dl = des & 0x0F;
+				unsigned char k = 0;
 
-				/* Black magic... */
-
-				switch ( dh )
+				/* look up this descriptor in the table */
+				while (cache_table[k].descriptor != 0)
 				{
-				case 0:
-					switch ( dl ) {
-					case 6:
-						/* L1 I cache */
-						l1i += 8;
-						break;
-					case 8:
-						/* L1 I cache */
-						l1i += 16;
-						break;
-					case 10:
-						/* L1 D cache */
-						l1d += 8;
-						break;
-					case 12:
-						/* L1 D cache */
-						l1d += 16;
-						break;
-					default:;
-						/* TLB, or unknown */
-					}
-					break;
-				case 2:
-					if ( dl ) {
-						/* L3 cache */
-						cs = (dl-1) << 9;
-						l3 += cs;
-					}
-					break;
-				case 4:
-					if ( c->x86 > 6 && dl ) {
-						/* P4 family */
-						/* L3 cache */
-						cs = 128 << (dl-1);
-						l3 += cs;
+					if (cache_table[k].descriptor == des) {
+						switch (cache_table[k].cache_type) {
+						case LVL_1_INST:
+							l1i += cache_table[k].size;
+							break;
+						case LVL_1_DATA:
+							l1d += cache_table[k].size;
+							break;
+						case LVL_2:
+							l2 += cache_table[k].size;
+							break;
+						case LVL_3:
+							l3 += cache_table[k].size;
+							break;
+						}
+
 						break;
 					}
-					/* else same as 8 - fall through */
-				case 8:
-					if ( dl ) {
-						/* L2 cache */
-						cs = 128 << (dl-1);
-						l2 += cs;
-					}
-					break;
-				case 6:
-					if (dl > 5) {
-						/* L1 D cache */
-						cs = 8<<(dl-6);
-						l1d += cs;
-					}
-					break;
-				case 7:
-					if ( dl >= 8 ) 
-					{
-						/* L2 cache */
-						cs = 64<<(dl-8);
-						l2 += cs;
-					} else {
-						/* L0 I cache, count as L1 */
-						cs = dl ? (16 << (dl-1)) : 12;
-						l1i += cs;
-					}
-					break;
-				default:
-					/* TLB, or something else we don't know about */
-					break;
+
+					k++;
 				}
 			}
 		}
@@ -2426,7 +2364,7 @@
 			if (smp_num_siblings != NR_SIBLINGS) {
 				printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
 				smp_num_siblings = 1;
-				goto too_many_siblings;
+				return;
 			}
 			tmp = smp_num_siblings;
 			while ((tmp & 1) == 0) {
@@ -2448,7 +2386,6 @@
 		}
 
 	}
-too_many_siblings:
 #endif
 }
 
@@ -2596,7 +2533,8 @@
 
 static int __init x86_fxsr_setup(char * s)
 {
-	disable_x86_fxsr = 1;
+	set_bit(X86_FEATURE_XMM, disabled_x86_caps); 
+	set_bit(X86_FEATURE_FXSR, disabled_x86_caps);
 	return 1;
 }
 __setup("nofxsr", x86_fxsr_setup);
@@ -2749,12 +2687,6 @@
 			      &c->x86_capability[0]);
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
-			if ( (c->x86_vendor == X86_VENDOR_AMD) &&
-				(c->x86 == 0xf)) {
-				/* AMD Extended Family and Model Values */
-				c->x86 += (tfms >> 20) & 0xff;
-				c->x86_model += (tfms >> 12) & 0xf0;
-			}
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */
@@ -2778,12 +2710,6 @@
 		}
 	}
 
-	printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n",
-	       c->x86_capability[0],
-	       c->x86_capability[1],
-	       c->x86_capability[2],
-	       c->x86_vendor);
-
 	/*
 	 * Vendor-specific initialization.  In this section we
 	 * canonicalize the feature flags, meaning if there are
@@ -2842,12 +2768,6 @@
 		break;
 	}
 
-	printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
-	       c->x86_capability[0],
-	       c->x86_capability[1],
-	       c->x86_capability[2],
-	       c->x86_capability[3]);
-
 	/*
 	 * The vendor-specific functions might have changed features.  Now
 	 * we do "generic changes."
@@ -2859,14 +2779,9 @@
 		clear_bit(X86_FEATURE_TSC, &c->x86_capability);
 #endif
 
-	/* HT disabled? */
-	if (disable_x86_ht)
-		clear_bit(X86_FEATURE_HT, &c->x86_capability);
-
-	/* FXSR disabled? */
-	if (disable_x86_fxsr) {
-		clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
-		clear_bit(X86_FEATURE_XMM, &c->x86_capability);
+	/* check for caps that have been disabled earlier */ 
+	for (i = 0; i < NCAPINTS; i++) { 
+	     c->x86_capability[i] &= ~disabled_x86_caps[i];
 	}
 
 	/* Disable the PN if appropriate */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/smp.c linux-2.4.20/arch/i386/kernel/smp.c
--- linux-2.4.19/arch/i386/kernel/smp.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/smp.c	2002-10-04 00:41:11.000000000 +0000
@@ -66,7 +66,7 @@
  *	an L1cache=Writethrough or L1cache=off option.
  *
  *		B stepping CPUs may hang. There are hardware work arounds
- *	for this. We warn about it in case your board doesnt have the work
+ *	for this. We warn about it in case your board doesn't have the work
  *	arounds. Basically thats so I can tell anyone with a B stepping
  *	CPU and SMP problems "tough".
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/time.c linux-2.4.20/arch/i386/kernel/time.c
--- linux-2.4.19/arch/i386/kernel/time.c	2002-02-25 19:37:53.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/time.c	2002-10-04 00:41:20.000000000 +0000
@@ -31,6 +31,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
@@ -116,6 +117,8 @@
 
 spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
 
+EXPORT_SYMBOL(i8253_lock);
+
 extern spinlock_t i8259A_lock;
 
 #ifndef CONFIG_X86_TSC
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/trampoline.S linux-2.4.20/arch/i386/kernel/trampoline.S
--- linux-2.4.19/arch/i386/kernel/trampoline.S	2001-10-05 01:42:54.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/trampoline.S	2002-10-04 00:41:16.000000000 +0000
@@ -36,9 +36,7 @@
 
 ENTRY(trampoline_data)
 r_base = .
-#ifdef CONFIG_MULTIQUAD
-	wbinvd
-#endif /* CONFIG_MULTIQUAD */
+	wbinvd			# Needed for NUMA-Q should be harmless for others
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/traps.c linux-2.4.20/arch/i386/kernel/traps.c
--- linux-2.4.19/arch/i386/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/kernel/traps.c	2002-10-04 00:41:12.000000000 +0000
@@ -40,9 +40,9 @@
 
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
+#include <asm/fixmap.h>
 
 #ifdef CONFIG_X86_VISWS_APIC
-#include <asm/fixmap.h>
 #include <asm/cobalt.h>
 #include <asm/lithium.h>
 #endif
@@ -186,6 +186,14 @@
 	show_trace(esp);
 }
 
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
 void show_registers(struct pt_regs *regs)
 {
 	int i;
@@ -305,8 +313,13 @@
 static void inline do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
-	if (vm86 && regs->eflags & VM_MASK)
-		goto vm86_trap;
+	if (regs->eflags & VM_MASK) {
+		if (vm86)
+			goto vm86_trap;
+		else
+			goto trap_signal;
+	}
+
 	if (!(regs->xcs & 3))
 		goto kernel_trap;
 
@@ -514,10 +527,15 @@
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
+	unsigned long eip = regs->eip;
 	siginfo_t info;
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* If the user set TF, it's simplest to clear it right away. */
+	if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
+		goto clear_TF;
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
@@ -758,35 +776,17 @@
 
 #endif /* CONFIG_MATH_EMULATION */
 
-#ifndef CONFIG_M686
+#ifndef CONFIG_X86_F00F_WORKS_OK
 void __init trap_init_f00f_bug(void)
 {
-	unsigned long page;
-	pgd_t * pgd;
-	pmd_t * pmd;
-	pte_t * pte;
-
-	/*
-	 * Allocate a new page in virtual address space, 
-	 * move the IDT into it and write protect this page.
-	 */
-	page = (unsigned long) vmalloc(PAGE_SIZE);
-	pgd = pgd_offset(&init_mm, page);
-	pmd = pmd_offset(pgd, page);
-	pte = pte_offset(pmd, page);
-	__free_page(pte_page(*pte));
-	*pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
-	/*
-	 * Not that any PGE-capable kernel should have the f00f bug ...
-	 */
-	__flush_tlb_all();
-
 	/*
 	 * "idt" is magic - it overlaps the idt_descr
 	 * variable so that updating idt will automatically
 	 * update the idt descriptor..
 	 */
-	idt = (struct desc_struct *)page;
+	__set_fixmap(FIX_F00F, __pa(&idt_table), PAGE_KERNEL_RO);
+	idt = (struct desc_struct *)__fix_to_virt(FIX_F00F);
+
 	__asm__ __volatile__("lidt %0": "=m" (idt_descr));
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/lib/checksum.S linux-2.4.20/arch/i386/lib/checksum.S
--- linux-2.4.19/arch/i386/lib/checksum.S	2000-09-05 21:01:35.000000000 +0000
+++ linux-2.4.20/arch/i386/lib/checksum.S	2002-10-04 00:41:14.000000000 +0000
@@ -55,8 +55,21 @@
 	movl 20(%esp),%eax	# Function arg: unsigned int sum
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg: unsigned char *buff
-	testl $2, %esi		# Check alignment.
+	testl $3, %esi		# Check alignment.
 	jz 2f			# Jump if alignment is ok.
+	testl $1, %esi		# Check alignment.
+	jz 10f			# Jump if alignment is boundary of 2bytes.
+
+	# buf is odd
+	dec %ecx
+	jl 8f
+	movzbl (%esi), %ebx
+	adcl %ebx, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 2f
+10:
 	subl $2, %ecx		# Alignment uses up two bytes.
 	jae 1f			# Jump if we had at least two bytes.
 	addl $2, %ecx		# ecx was < 2.  Deal with it.
@@ -111,6 +124,10 @@
 6:	addl %ecx,%eax
 	adcl $0, %eax 
 7:	
+	testl $1, 12(%esp)
+	jz 8f
+	roll $8, %eax
+8:
 	popl %ebx
 	popl %esi
 	ret
@@ -126,8 +143,8 @@
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg:	const unsigned char *buf
 
-	testl $2, %esi         
-	jnz 30f                 
+	testl $3, %esi         
+	jnz 25f                 
 10:
 	movl %ecx, %edx
 	movl %ecx, %ebx
@@ -145,10 +162,25 @@
 	lea 2(%esi), %esi
 	adcl $0, %eax
 	jmp 10b
+25:
+	testl $1, %esi         
+	jz 30f                 
+	# buf is odd
+	dec %ecx
+	jl 90f
+	movzbl (%esi), %ebx
+	addl %ebx, %eax
+	adcl $0, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 10b
 
 30:	subl $2, %ecx          
 	ja 20b                 
 	je 32f
+	addl $2, %ecx
+	jz 80f
 	movzbl (%esi),%ebx	# csumming 1 byte, 2-aligned
 	addl %ebx, %eax
 	adcl $0, %eax
@@ -209,6 +241,10 @@
 	addl %ebx,%eax
 	adcl $0,%eax
 80: 
+	testl $1, 12(%esp)
+	jz 90f
+	roll $8, %eax
+90: 
 	popl %ebx
 	popl %esi
 	ret
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/Makefile linux-2.4.20/arch/i386/mm/Makefile
--- linux-2.4.19/arch/i386/mm/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux-2.4.20/arch/i386/mm/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -9,6 +9,7 @@
 
 O_TARGET := mm.o
 
-obj-y	 := init.o fault.o ioremap.o extable.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+export-objs := pageattr.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/fault.c linux-2.4.20/arch/i386/mm/fault.c
--- linux-2.4.19/arch/i386/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/mm/fault.c	2002-10-04 00:41:09.000000000 +0000
@@ -86,8 +86,7 @@
 
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		goto survive;
 	}
 	goto bad_area;
@@ -334,13 +333,11 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (error_code & 4)
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/init.c linux-2.4.20/arch/i386/mm/init.c
--- linux-2.4.19/arch/i386/mm/init.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/i386/mm/init.c	2002-10-04 00:41:13.000000000 +0000
@@ -320,6 +320,27 @@
 	flush_tlb_all();
 }
 
+static void __init zone_sizes_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned int max_dma, high, low;
+
+	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	low = max_low_pfn;
+	high = highend_pfn;
+
+	if (low < max_dma)
+		zones_size[ZONE_DMA] = low;
+	else {
+		zones_size[ZONE_DMA] = max_dma;
+		zones_size[ZONE_NORMAL] = low - max_dma;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = high - low;
+#endif
+	}
+	free_area_init(zones_size);
+}
+
 /*
  * paging_init() sets up the page tables - note that the first 8MB are
  * already mapped by head.S.
@@ -347,26 +368,7 @@
 #ifdef CONFIG_HIGHMEM
 	kmap_init();
 #endif
-	{
-		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-		unsigned int max_dma, high, low;
-
-		max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-		low = max_low_pfn;
-		high = highend_pfn;
-
-		if (low < max_dma)
-			zones_size[ZONE_DMA] = low;
-		else {
-			zones_size[ZONE_DMA] = max_dma;
-			zones_size[ZONE_NORMAL] = low - max_dma;
-#ifdef CONFIG_HIGHMEM
-			zones_size[ZONE_HIGHMEM] = high - low;
-#endif
-		}
-		free_area_init(zones_size);
-	}
-	return;
+	zone_sizes_init();
 }
 
 /*
@@ -443,62 +445,81 @@
 		return 1;
 	return 0;
 }
-	
-void __init mem_init(void)
-{
-	extern int ppro_with_ram_bug(void);
-	int codesize, reservedpages, datasize, initsize;
-	int tmp;
-	int bad_ppro;
 
-	if (!mem_map)
-		BUG();
+#ifdef CONFIG_HIGHMEM
+void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+{
+	if (!page_is_ram(pfn)) {
+		SetPageReserved(page);
+		return;
+	}
 	
-	bad_ppro = ppro_with_ram_bug();
+	if (bad_ppro && page_kills_ppro(pfn)) {
+		SetPageReserved(page);
+		return;
+	}
+	
+	ClearPageReserved(page);
+	set_bit(PG_highmem, &page->flags);
+	atomic_set(&page->count, 1);
+	__free_page(page);
+	totalhigh_pages++;
+}
+#endif /* CONFIG_HIGHMEM */
 
+static void __init set_max_mapnr_init(void)
+{
 #ifdef CONFIG_HIGHMEM
-	highmem_start_page = mem_map + highstart_pfn;
-	max_mapnr = num_physpages = highend_pfn;
-	num_mappedpages = max_low_pfn;
+        highmem_start_page = mem_map + highstart_pfn;
+        max_mapnr = num_physpages = highend_pfn;
+        num_mappedpages = max_low_pfn;
 #else
-	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+        max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
 #endif
-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+}
 
-	/* clear the zero-page */
-	memset(empty_zero_page, 0, PAGE_SIZE);
+static int __init free_pages_init(void)
+{
+	extern int ppro_with_ram_bug(void);
+	int bad_ppro, reservedpages, pfn;
+
+	bad_ppro = ppro_with_ram_bug();
 
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
 	reservedpages = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
+	for (pfn = 0; pfn < max_low_pfn; pfn++) {
 		/*
 		 * Only count reserved RAM pages
 		 */
-		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+		if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
 			reservedpages++;
-#ifdef CONFIG_HIGHMEM
-	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-		struct page *page = mem_map + tmp;
-
-		if (!page_is_ram(tmp)) {
-			SetPageReserved(page);
-			continue;
-		}
-		if (bad_ppro && page_kills_ppro(tmp))
-		{
-			SetPageReserved(page);
-			continue;
-		}
-		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
-		atomic_set(&page->count, 1);
-		__free_page(page);
-		totalhigh_pages++;
 	}
+#ifdef CONFIG_HIGHMEM
+	for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
+		one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
 	totalram_pages += totalhigh_pages;
 #endif
+	return reservedpages;
+}
+
+void __init mem_init(void)
+{
+	int codesize, reservedpages, datasize, initsize;
+
+	if (!mem_map)
+		BUG();
+	
+	set_max_mapnr_init();
+
+	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+
+	/* clear the zero-page */
+	memset(empty_zero_page, 0, PAGE_SIZE);
+
+	reservedpages = free_pages_init();
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/pageattr.c linux-2.4.20/arch/i386/mm/pageattr.c
--- linux-2.4.19/arch/i386/mm/pageattr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/i386/mm/pageattr.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,175 @@
+/* 
+ * Copyright 2002 Andi Kleen, SuSE Labs. 
+ * Thanks to Ben LaHaise for precious feedback.
+ */ 
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+
+/* Should move most of this stuff into the appropiate includes */
+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+
+static inline pte_t *lookup_address(unsigned long address) 
+{ 
+	pmd_t *pmd;	
+	pgd_t *pgd = pgd_offset(&init_mm, address); 
+
+	if (pgd_none(*pgd))
+		return NULL; 
+	if (pgd_val(*pgd) & _PAGE_PSE)
+		return (pte_t *)pgd; 
+	pmd = pmd_offset(pgd, address); 	       
+	if (pmd_none(*pmd))
+		return NULL; 
+	if (pmd_val(*pmd) & _PAGE_PSE) 
+		return (pte_t *)pmd; 
+    return pte_offset(pmd, address);
+} 
+
+static struct page *split_large_page(unsigned long address, pgprot_t prot)
+{ 
+	int i; 
+	unsigned long addr;
+	struct page *base = alloc_pages(GFP_KERNEL, 0);
+	pte_t *pbase;
+	if (!base) 
+		return NULL;
+	address = __pa(address);
+	addr = address & LARGE_PAGE_MASK; 
+	pbase = (pte_t *)page_address(base);
+	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+		pbase[i] = mk_pte_phys(addr, 
+				      addr == address ? prot : PAGE_KERNEL);
+	}
+	return base;
+} 
+
+static void flush_kernel_map(void * address) 
+{ 
+	if (!test_bit(X86_FEATURE_SELFSNOOP, boot_cpu_data.x86_capability)) {
+		/* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */
+		if (boot_cpu_data.x86_model >= 4) 
+			asm volatile("wbinvd":::"memory"); 	
+	} 
+
+	/* Do global flush here to work around large page flushing errata 
+	   in some early Athlons */
+	__flush_tlb_all(); 	
+}
+
+static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) 
+{ 
+	set_pte_atomic(kpte, pte); 	/* change init_mm */
+#ifndef CONFIG_X86_PAE
+	{
+		struct list_head *l;
+		spin_lock(&mmlist_lock);
+		list_for_each(l, &init_mm.mmlist) { 
+			struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
+			pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
+			set_pte_atomic((pte_t *)pmd, pte);
+		} 
+		spin_unlock(&mmlist_lock);
+	}
+#endif
+}
+
+/* no more special protections in this 2/4MB area - revert to a
+   large page again. */
+static inline void revert_page(struct page *kpte_page, unsigned long address)
+{
+	pte_t *linear = (pte_t *) 
+		pmd_offset(pgd_offset(&init_mm, address), address);
+	set_pmd_pte(linear,  address,
+		mk_pte_phys(__pa(address & LARGE_PAGE_MASK),
+			    MAKE_GLOBAL(_KERNPG_TABLE|_PAGE_PSE)));
+}	
+ 
+/*
+ * Change the page attributes of an page in the linear mapping.
+ *
+ * This should be used when a page is mapped with a different caching policy
+ * than write-back somewhere - some CPUs do not like it when mappings with
+ * different caching policies exist. This changes the page attributes of the
+ * in kernel linear mapping too.
+ * 
+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
+ * This function only deals with the kernel linear map.
+ * When page is in highmem it must never be kmap'ed.
+ */
+static int 
+__change_page_attr(struct page *page, pgprot_t prot, struct page **oldpage) 
+{ 
+	pte_t *kpte; 
+	unsigned long address;
+	struct page *kpte_page;
+
+#ifdef CONFIG_HIGHMEM
+	if (page >= highmem_start_page) 
+		BUG(); 
+#endif
+	address = (unsigned long)page_address(page);
+	kpte = lookup_address(address);
+	if (!kpte) 
+		return -EINVAL; 
+	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+	if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
+		if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
+			pte_t old = *kpte;
+			pte_t standard = mk_pte(page, PAGE_KERNEL); 
+
+			set_pte_atomic(kpte, mk_pte(page, prot)); 
+			if (pte_same(old,standard))
+				atomic_inc(&kpte_page->count);
+		} else {
+			struct page *split = split_large_page(address, prot); 
+			if (!split)
+				return -ENOMEM;
+			atomic_inc(&kpte_page->count); 	
+			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+		}	
+	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
+		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
+		atomic_dec(&kpte_page->count); 
+	}
+
+	if (cpu_has_pse && (atomic_read(&kpte_page->count) == 1)) { 
+		*oldpage = kpte_page;
+		revert_page(kpte_page, address);
+	} 
+	return 0;
+} 
+
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+	int err = 0; 
+	struct page *fpage; 
+	int i; 
+
+	down_write(&init_mm.mmap_sem);
+	for (i = 0; i < numpages; i++, page++) { 
+		fpage = NULL;
+		err = __change_page_attr(page, prot, &fpage); 
+		if (err) 
+			break; 
+		if (fpage || i == numpages-1) { 
+			void *address = page_address(page);
+#ifdef CONFIG_SMP 
+			smp_call_function(flush_kernel_map, address, 1, 1);
+#endif	
+			flush_kernel_map(address);
+			if (fpage)
+				__free_page(fpage);
+		} 
+	} 	
+	up_write(&init_mm.mmap_sem); 
+	return err;
+}
+
+EXPORT_SYMBOL(change_page_attr);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/Makefile linux-2.4.20/arch/ia64/Makefile
--- linux-2.4.19/arch/ia64/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -22,10 +22,10 @@
 # -ffunction-sections
 CFLAGS_KERNEL := -mconstant-gp
 
-GCC_VERSION=$(shell $(CROSS_COMPILE)$(HOSTCC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
+GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
 ifneq ($(GCC_VERSION),2)
-	CFLAGS += -frename-registers --param max-inline-insns=2000
+	CFLAGS += -frename-registers --param max-inline-insns=5000
 endif
 
 ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y)
@@ -33,16 +33,11 @@
 endif
 
 ifdef CONFIG_IA64_GENERIC
-	CORE_FILES      :=      arch/$(ARCH)/hp/hp.a	\
-				arch/$(ARCH)/sn/sn.o	\
-				arch/$(ARCH)/dig/dig.a	\
-				arch/$(ARCH)/sn/io/sgiio.o \
+	CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
+				arch/$(ARCH)/dig/dig.a			\
 				$(CORE_FILES)
 	SUBDIRS		:=	arch/$(ARCH)/hp		\
-				arch/$(ARCH)/sn/sn1	\
-				arch/$(ARCH)/sn		\
 				arch/$(ARCH)/dig	\
-				arch/$(ARCH)/sn/io	\
 				$(SUBDIRS)
 
 else # !GENERIC
@@ -50,7 +45,16 @@
 ifdef CONFIG_IA64_HP_SIM
         SUBDIRS         :=      arch/$(ARCH)/hp		\
                                 $(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/hp/hp.a	\
+        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o	\
+                                $(CORE_FILES)
+endif
+
+ifdef CONFIG_IA64_HP_ZX1
+        SUBDIRS         :=      arch/$(ARCH)/hp				\
+				arch/$(ARCH)/dig			\
+                                $(SUBDIRS)
+        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
+				arch/$(ARCH)/dig/dig.a			\
                                 $(CORE_FILES)
 endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/boot/Makefile linux-2.4.20/arch/ia64/boot/Makefile
--- linux-2.4.19/arch/ia64/boot/Makefile	2001-01-04 20:50:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/boot/Makefile	2002-10-04 00:41:21.000000000 +0000
@@ -27,6 +27,6 @@
 	-o bootloader
 
 clean:
-	rm -f $(TARGETS)
+	rm -f $(targets-y) $(OBJECTS)
 
 dep:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/config.in linux-2.4.20/arch/ia64/config.in
--- linux-2.4.19/arch/ia64/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/config.in	2002-10-04 00:41:20.000000000 +0000
@@ -26,29 +26,32 @@
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
 
-if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
-  define_bool CONFIG_ACPI y
-  define_bool CONFIG_ACPI_EFI y
-  define_bool CONFIG_ACPI_INTERPRETER y
-  define_bool CONFIG_ACPI_KERNEL_CONFIG y
-fi
-
 choice 'IA-64 processor type' \
-	"Itanium			CONFIG_ITANIUM \
-	 McKinley			CONFIG_MCKINLEY" Itanium
+	"Itanium		CONFIG_ITANIUM \
+	 Itanium-2		CONFIG_MCKINLEY" Itanium
 
 choice 'IA-64 system type'					\
 	"generic		CONFIG_IA64_GENERIC		\
 	 DIG-compliant		CONFIG_IA64_DIG			\
 	 HP-simulator		CONFIG_IA64_HP_SIM		\
+	 HP-zx1			CONFIG_IA64_HP_ZX1		\
 	 SGI-SN1		CONFIG_IA64_SGI_SN1		\
 	 SGI-SN2		CONFIG_IA64_SGI_SN2" generic
 
-choice 'Kernel page size'						\
+if [ "$CONFIG_ITANIUM" = "y" ]; then
+  choice 'Kernel page size'						\
+	"4KB			CONFIG_IA64_PAGE_SIZE_4KB		\
+	 8KB			CONFIG_IA64_PAGE_SIZE_8KB		\
+	 16KB			CONFIG_IA64_PAGE_SIZE_16KB" 16KB
+else
+  choice 'Kernel page size'						\
 	"4KB			CONFIG_IA64_PAGE_SIZE_4KB		\
 	 8KB			CONFIG_IA64_PAGE_SIZE_8KB		\
 	 16KB			CONFIG_IA64_PAGE_SIZE_16KB		\
 	 64KB			CONFIG_IA64_PAGE_SIZE_64KB" 16KB
+fi
+
+bool 'Virtually mapped mem_map?' CONFIG_VIRTUAL_MEM_MAP n
 
 if [ "$CONFIG_ITANIUM" = "y" ]; then
 	define_bool CONFIG_IA64_BRL_EMU y
@@ -68,22 +71,18 @@
 	fi
 fi
 
-if [ "$CONFIG_IA64_DIG" = "y" ]; then
+if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ]; then
 	bool '  Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
 	define_bool CONFIG_PM y
 fi
 
-if [ "$CONFIG_IA64_SGI_SN1" = "y" ] || [ "$CONFIG_IA64_SGI_SN2" = "y" ]; then
+if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then
 	define_bool CONFIG_IA64_SGI_SN y
-	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG n
+	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG
 	bool '  Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN_SIM
 	bool '  Enable autotest (llsc). Option to run cache test instead of booting' \
-			CONFIG_IA64_SGI_AUTOTEST n
-	define_bool CONFIG_DEVFS_FS y
-	if [ "$CONFIG_DEVFS_FS" = "y" ]; then
-	  bool '    Enable DEVFS Debug Code' CONFIG_DEVFS_DEBUG n
-	fi
-	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL y
+			CONFIG_IA64_SGI_AUTOTEST
+	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL
 	define_bool CONFIG_DISCONTIGMEM y
 	define_bool CONFIG_IA64_MCA y
 	define_bool CONFIG_NUMA y
@@ -107,21 +106,25 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  define_bool CONFIG_ACPI y
+  define_bool CONFIG_ACPI_EFI y
+  define_bool CONFIG_ACPI_INTERPRETER y
+  define_bool CONFIG_ACPI_KERNEL_CONFIG y
 
-source drivers/acpi/Config.in
-
-bool 'PCI support' CONFIG_PCI
-source drivers/pci/Config.in
+  source drivers/acpi/Config.in
 
-bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
-if [ "$CONFIG_HOTPLUG" = "y" ]; then
-   source drivers/pcmcia/Config.in
-else
-   define_bool CONFIG_PCMCIA n
-fi
+  bool 'PCI support' CONFIG_PCI
+  source drivers/pci/Config.in
 
-source drivers/parport/Config.in
+  bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+  if [ "$CONFIG_HOTPLUG" = "y" ]; then
+     source drivers/hotplug/Config.in
+     source drivers/pcmcia/Config.in
+  else
+     define_bool CONFIG_PCMCIA n
+  fi
 
+  source drivers/parport/Config.in
 fi # !HP_SIM
 
 endmenu
@@ -131,28 +134,38 @@
 fi
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  source drivers/mtd/Config.in
+  source drivers/pnp/Config.in
+  source drivers/block/Config.in
+  source drivers/ieee1394/Config.in
+  source drivers/message/i2o/Config.in
+  source drivers/md/Config.in
+  source drivers/message/fusion/Config.in
 
-source drivers/mtd/Config.in
-source drivers/pnp/Config.in
-source drivers/block/Config.in
-source drivers/ieee1394/Config.in
-source drivers/message/i2o/Config.in
-source drivers/md/Config.in
-
-mainmenu_option next_comment
-comment 'ATA/IDE/MFM/RLL support'
-
-tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+  mainmenu_option next_comment
+  comment 'ATA/IDE/MFM/RLL support'
 
-if [ "$CONFIG_IDE" != "n" ]; then
-  source drivers/ide/Config.in
-else
-  define_bool CONFIG_BLK_DEV_IDE_MODES n
-  define_bool CONFIG_BLK_DEV_HD n
-fi
-endmenu
+  tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
 
-fi # !HP_SIM
+  if [ "$CONFIG_IDE" != "n" ]; then
+    source drivers/ide/Config.in
+  else
+    define_bool CONFIG_BLK_DEV_IDE_MODES n
+    define_bool CONFIG_BLK_DEV_HD n
+  fi
+  endmenu
+else # HP_SIM
+  mainmenu_option next_comment
+  comment 'Block devices'
+  tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+  dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
+
+  tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+  if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
+    int '  Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
+  fi
+  endmenu
+fi # HP_SIM
 
 mainmenu_option next_comment
 comment 'SCSI support'
@@ -164,43 +177,37 @@
 fi
 endmenu
 
-if [ "$CONFIG_PCI" = "y" ]; then
-  source drivers/message/fusion/Config.in
-fi
-
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  if [ "$CONFIG_NET" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'Network device support'
+
+    bool 'Network device support' CONFIG_NETDEVICES
+    if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+    fi
+    endmenu
+  fi
+
+  source net/ax25/Config.in
 
-if [ "$CONFIG_NET" = "y" ]; then
   mainmenu_option next_comment
-  comment 'Network device support'
+  comment 'ISDN subsystem'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
+  tristate 'ISDN support' CONFIG_ISDN
+  if [ "$CONFIG_ISDN" != "n" ]; then
+    source drivers/isdn/Config.in
   fi
   endmenu
-fi
-
-source net/ax25/Config.in
-
-mainmenu_option next_comment
-comment 'ISDN subsystem'
-
-tristate 'ISDN support' CONFIG_ISDN
-if [ "$CONFIG_ISDN" != "n" ]; then
-  source drivers/isdn/Config.in
-fi
-endmenu
 
-mainmenu_option next_comment
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
-
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-  source drivers/cdrom/Config.in
-fi
-endmenu
+  mainmenu_option next_comment
+  comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
 
+  bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+  if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+    source drivers/cdrom/Config.in
+  fi
+  endmenu
 fi # !HP_SIM
 
 #
@@ -227,22 +234,22 @@
 fi
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  mainmenu_option next_comment
+  comment 'Sound'
 
-mainmenu_option next_comment
-comment 'Sound'
-
-tristate 'Sound card support' CONFIG_SOUND
-if [ "$CONFIG_SOUND" != "n" ]; then
-  source drivers/sound/Config.in
-fi
-endmenu
+  tristate 'Sound card support' CONFIG_SOUND
+  if [ "$CONFIG_SOUND" != "n" ]; then
+    source drivers/sound/Config.in
+  fi
+  endmenu
 
-source drivers/usb/Config.in
+  source drivers/usb/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+  source lib/Config.in
 
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+     source net/bluetooth/Config.in
+  fi
 fi # !HP_SIM
 
 if [ "$CONFIG_IA64_HP_SIM" != "n" -o "$CONFIG_IA64_GENERIC" != "n" ]; then
@@ -271,7 +278,14 @@
    bool '  Disable VHPT' CONFIG_DISABLE_VHPT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
 
-   bool '  Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
+   bool '  Early printk support' CONFIG_IA64_EARLY_PRINTK
+   if [ "$CONFIG_IA64_EARLY_PRINTK" != "n" ]; then
+      bool '    Early printk on MMIO serial port' CONFIG_IA64_EARLY_PRINTK_UART
+      if [ "$CONFIG_IA64_EARLY_PRINTK_UART" != "n" ]; then
+         hex '      UART MMIO base address' CONFIG_IA64_EARLY_PRINTK_UART_BASE 0
+      fi
+      bool '    Early printk on VGA' CONFIG_IA64_EARLY_PRINTK_VGA
+   fi
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
    bool '  Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/defconfig linux-2.4.20/arch/ia64/defconfig
--- linux-2.4.19/arch/ia64/defconfig	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/defconfig	2002-10-04 00:41:11.000000000 +0000
@@ -24,21 +24,18 @@
 # CONFIG_SBUS is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_ACPI=y
-CONFIG_ACPI_EFI=y
-CONFIG_ACPI_INTERPRETER=y
-CONFIG_ACPI_KERNEL_CONFIG=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
-# CONFIG_IA64_GENERIC is not set
-CONFIG_IA64_DIG=y
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_HP_ZX1 is not set
 # CONFIG_IA64_SGI_SN1 is not set
 # CONFIG_IA64_SGI_SN2 is not set
 # CONFIG_IA64_PAGE_SIZE_4KB is not set
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
-# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_IA64_BRL_EMU=y
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
@@ -56,15 +53,27 @@
 CONFIG_SYSCTL=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_ACPI_DEBUG is not set
-# CONFIG_ACPI_BUSMGR is not set
-# CONFIG_ACPI_SYS is not set
-# CONFIG_ACPI_CPU is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+
+#
+# ACPI Support
+#
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
 # CONFIG_ACPI_BUTTON is not set
-# CONFIG_ACPI_AC is not set
-# CONFIG_ACPI_EC is not set
-# CONFIG_ACPI_CMBATT is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_PROCESSOR is not set
 # CONFIG_ACPI_THERMAL is not set
+# CONFIG_ACPI_DEBUG is not set
 CONFIG_PCI=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
@@ -80,7 +89,7 @@
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 CONFIG_FILTER=y
 CONFIG_UNIX=y
@@ -90,6 +99,7 @@
 # CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -102,6 +112,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -119,6 +134,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -137,13 +157,20 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
 
 #
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
 # I2O device support
 #
 # CONFIG_I2O is not set
@@ -166,6 +193,15 @@
 # CONFIG_BLK_DEV_LVM is not set
 
 #
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_BOOT=y
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
 # ATA/IDE/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -182,6 +218,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -196,6 +233,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -207,12 +245,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
@@ -220,6 +261,7 @@
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
@@ -278,8 +320,12 @@
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -299,9 +345,11 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -331,6 +379,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -340,7 +389,6 @@
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -353,7 +401,10 @@
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
+CONFIG_TULIP=y
+# CONFIG_TC35815 is not set
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
@@ -369,6 +420,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -382,12 +434,15 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_NET_BROADCOM is not set
 # CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+CONFIG_E1000=y
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+CONFIG_TIGON3=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -445,8 +500,9 @@
 CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_ACPI is not set
+CONFIG_SERIAL_HCDP=y
 # CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_ACPI is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -464,6 +520,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -519,16 +576,20 @@
 # CONFIG_FTAPE is not set
 CONFIG_AGP=y
 # CONFIG_AGP_INTEL is not set
-CONFIG_AGP_I460=y
 # CONFIG_AGP_I810 is not set
 # CONFIG_AGP_VIA is not set
 # CONFIG_AGP_AMD is not set
 # CONFIG_AGP_SIS is not set
 # CONFIG_AGP_ALI is not set
 # CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_I460=y
+CONFIG_AGP_HP_ZX1=y
 CONFIG_DRM=y
-# CONFIG_DRM_NEW is not set
 CONFIG_DRM_OLD=y
+
+#
+# DRM 4.0 drivers
+#
 CONFIG_DRM40_TDFX=y
 # CONFIG_DRM40_GAMMA is not set
 # CONFIG_DRM40_R128 is not set
@@ -607,7 +668,7 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -671,12 +732,11 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_DEVFS_GUID is not set
 # CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+CONFIG_EFI_PARTITION=y
 # CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
@@ -705,6 +765,7 @@
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
@@ -737,6 +798,7 @@
 CONFIG_SOUND=y
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_EMU10K1 is not set
 # CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
@@ -771,8 +833,9 @@
 # CONFIG_USB_LONG_TIMEOUT is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_UHCI=m
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
@@ -781,6 +844,7 @@
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -798,6 +862,7 @@
 # USB Human Interface Devices (HID)
 #
 CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_KBD=m
 CONFIG_USB_MOUSE=m
@@ -819,6 +884,8 @@
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_PWC is not set
 # CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
 # CONFIG_USB_DSBR is not set
 # CONFIG_USB_DABUSB is not set
 
@@ -826,6 +893,7 @@
 # USB Network adaptors
 #
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_CDCETHER is not set
@@ -847,6 +915,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 # CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
 # CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
@@ -860,6 +929,7 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -869,6 +939,8 @@
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -876,6 +948,13 @@
 # CONFIG_BLUEZ is not set
 
 #
+# Simulated drivers
+#
+# CONFIG_SIMETH is not set
+# CONFIG_SIM_SERIAL is not set
+# CONFIG_SCSI_SIM is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_IA64_GRANULE_16MB is not set
@@ -885,6 +964,9 @@
 # CONFIG_DISABLE_VHPT is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_IA64_EARLY_PRINTK=y
+CONFIG_IA64_EARLY_PRINTK_UART=y
+CONFIG_IA64_EARLY_PRINTK_UART_BASE=0
+# CONFIG_IA64_EARLY_PRINTK_VGA is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_IA64_DEBUG_CMPXCHG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/dig/setup.c linux-2.4.20/arch/ia64/dig/setup.c
--- linux-2.4.19/arch/ia64/dig/setup.c	2001-04-05 19:51:47.000000000 +0000
+++ linux-2.4.20/arch/ia64/dig/setup.c	2002-10-04 00:41:14.000000000 +0000
@@ -33,8 +33,7 @@
  * is sufficient (the IDE driver will autodetect the drive geometry).
  */
 char drive_info[4*16];
-
-unsigned char aux_device_present = 0xaa;	/* XXX remove this when legacy I/O is gone */
+extern int pcat_compat;
 
 void __init
 dig_setup (char **cmdline_p)
@@ -81,13 +80,7 @@
 	screen_info.orig_video_ega_bx = 3;	/* XXX fake */
 }
 
-void
+void __init
 dig_irq_init (void)
 {
-	/*
-	 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
-	 * enabled.
-	 */
-	outb(0xff, 0xA1);
-	outb(0xff, 0x21);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/Makefile linux-2.4.20/arch/ia64/hp/Makefile
--- linux-2.4.19/arch/ia64/hp/Makefile	2001-01-04 20:50:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/Makefile	2002-10-04 00:41:21.000000000 +0000
@@ -1,17 +1,15 @@
-#
-# ia64/platform/hp/Makefile
-#
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
+# arch/ia64/hp/Makefile
+# Copyright (c) 2002 Matthew Wilcox for Hewlett Packard
 
-all: hp.a
+ALL_SUB_DIRS := sim zx1 common
 
-O_TARGET := hp.a
+O_TARGET := hp.o
 
-obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
-obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
+subdir-$(CONFIG_IA64_GENERIC) += $(ALL_SUB_DIRS)
+subdir-$(CONFIG_IA64_HP_SIM) += sim
+subdir-$(CONFIG_IA64_HP_ZX1) += zx1 common
 
-clean::
+SUB_DIRS := $(subdir-y)
+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/common/Makefile linux-2.4.20/arch/ia64/hp/common/Makefile
--- linux-2.4.19/arch/ia64/hp/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/common/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,14 @@
+#
+# ia64/platform/hp/common/Makefile
+#
+# Copyright (C) 2002 Hewlett Packard
+# Copyright (C) Alex Williamson (alex_williamson@hp.com)
+#
+
+O_TARGET := common.o
+
+export-objs := sba_iommu.o
+
+obj-y := sba_iommu.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/common/sba_iommu.c linux-2.4.20/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.19/arch/ia64/hp/common/sba_iommu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/common/sba_iommu.c	2002-10-04 00:41:21.000000000 +0000
@@ -0,0 +1,1867 @@
+/*
+**  IA64 System Bus Adapter (SBA) I/O MMU manager
+**
+**	(c) Copyright 2002 Alex Williamson
+**	(c) Copyright 2002 Hewlett-Packard Company
+**
+**	Portions (c) 2000 Grant Grundler (from parisc I/O MMU code)
+**	Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
+**
+**	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 module initializes the IOC (I/O Controller) found on HP
+** McKinley machines and their successors.
+**
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+
+#include <asm/delay.h>		/* ia64_get_itc() */
+#include <asm/io.h>
+#include <asm/page.h>		/* PAGE_OFFSET */
+
+
+#define PFX "IOC: "
+
+#define ALLOW_IOV_BYPASS
+#define ENABLE_MARK_CLEAN
+/*
+** The number of debug flags is a clue - this code is fragile.
+*/
+#undef DEBUG_SBA_INIT
+#undef DEBUG_SBA_RUN
+#undef DEBUG_SBA_RUN_SG
+#undef DEBUG_SBA_RESOURCE
+#undef ASSERT_PDIR_SANITY
+#undef DEBUG_LARGE_SG_ENTRIES
+#undef DEBUG_BYPASS
+
+#define SBA_INLINE	__inline__
+/* #define SBA_INLINE */
+
+#ifdef DEBUG_SBA_INIT
+#define DBG_INIT(x...)	printk(x)
+#else
+#define DBG_INIT(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN
+#define DBG_RUN(x...)	printk(x)
+#else
+#define DBG_RUN(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN_SG
+#define DBG_RUN_SG(x...)	printk(x)
+#else
+#define DBG_RUN_SG(x...)
+#endif
+
+
+#ifdef DEBUG_SBA_RESOURCE
+#define DBG_RES(x...)	printk(x)
+#else
+#define DBG_RES(x...)
+#endif
+
+#ifdef DEBUG_BYPASS
+#define DBG_BYPASS(x...)	printk(x)
+#else
+#define DBG_BYPASS(x...)
+#endif
+
+#ifdef ASSERT_PDIR_SANITY
+#define ASSERT(expr) \
+        if(!(expr)) { \
+                printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+                panic(#expr); \
+        }
+#else
+#define ASSERT(expr)
+#endif
+
+/*
+** The number of pdir entries to "free" before issueing
+** a read to PCOM register to flush out PCOM writes.
+** Interacts with allocation granularity (ie 4 or 8 entries
+** allocated and free'd/purged at a time might make this
+** less interesting).
+*/
+#define DELAYED_RESOURCE_CNT	16
+
+#define DEFAULT_DMA_HINT_REG	0
+
+#define ZX1_IOC_ID	((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
+#define REO_IOC_ID	((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
+
+#define ZX1_IOC_OFFSET	0x1000	/* ACPI reports SBA, we want IOC */
+
+#define IOC_FUNC_ID	0x000
+#define IOC_FCLASS	0x008	/* function class, bist, header, rev... */
+#define IOC_IBASE	0x300	/* IO TLB */
+#define IOC_IMASK	0x308
+#define IOC_PCOM	0x310
+#define IOC_TCNFG	0x318
+#define IOC_PDIR_BASE	0x320
+
+/* AGP GART driver looks for this */
+#define ZX1_SBA_IOMMU_COOKIE	0x0000badbadc0ffeeUL
+
+/*
+** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
+** It's safer (avoid memory corruption) to keep DMA page mappings
+** equivalently sized to VM PAGE_SIZE.
+**
+** We really can't avoid generating a new mapping for each
+** page since the Virtual Coherence Index has to be generated
+** and updated for each page.
+**
+** IOVP_SIZE could only be greater than PAGE_SIZE if we are
+** confident the drivers really only touch the next physical
+** page iff that driver instance owns it.
+*/
+#define IOVP_SIZE	PAGE_SIZE
+#define IOVP_SHIFT	PAGE_SHIFT
+#define IOVP_MASK	PAGE_MASK
+
+struct ioc {
+	void		*ioc_hpa;	/* I/O MMU base address */
+	char		*res_map;	/* resource map, bit == pdir entry */
+	u64		*pdir_base;	/* physical base address */
+	unsigned long	ibase;		/* pdir IOV Space base */
+	unsigned long	imask;		/* pdir IOV Space mask */
+
+	unsigned long	*res_hint;	/* next avail IOVP - circular search */
+	spinlock_t	res_lock;
+	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
+	unsigned int	res_bitshift;	/* from the RIGHT! */
+	unsigned int	res_size;	/* size of resource map in bytes */
+	unsigned int	hint_shift_pdir;
+	unsigned long	dma_mask;
+#if DELAYED_RESOURCE_CNT > 0
+	int saved_cnt;
+	struct sba_dma_pair {
+		dma_addr_t	iova;
+		size_t		size;
+	} saved[DELAYED_RESOURCE_CNT];
+#endif
+
+#ifdef CONFIG_PROC_FS
+#define SBA_SEARCH_SAMPLE	0x100
+	unsigned long avg_search[SBA_SEARCH_SAMPLE];
+	unsigned long avg_idx;	/* current index into avg_search */
+	unsigned long used_pages;
+	unsigned long msingle_calls;
+	unsigned long msingle_pages;
+	unsigned long msg_calls;
+	unsigned long msg_pages;
+	unsigned long usingle_calls;
+	unsigned long usingle_pages;
+	unsigned long usg_calls;
+	unsigned long usg_pages;
+#ifdef ALLOW_IOV_BYPASS
+	unsigned long msingle_bypass;
+	unsigned long usingle_bypass;
+	unsigned long msg_bypass;
+#endif
+#endif
+
+	/* Stuff we don't need in performance path */
+	struct ioc	*next;		/* list of IOC's in system */
+	acpi_handle	handle;		/* for multiple IOC's */
+	const char 	*name;
+	unsigned int	func_id;
+	unsigned int	rev;		/* HW revision of chip */
+	u32		iov_size;
+	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
+	struct pci_dev	*sac_only_dev;
+};
+
+static struct ioc *ioc_list;
+static int reserve_sba_gart = 1;
+
+#define sba_sg_iova(sg) (sg->address)
+#define sba_sg_len(sg) (sg->length)
+#define sba_sg_buffer(sg) (sg->orig_address)
+
+#define GET_IOC(dev)	((struct ioc *) PCI_CONTROLLER(dev)->iommu)
+
+/*
+** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
+** (or rather not merge) DMA's into managable chunks.
+** On parisc, this is more of the software/tuning constraint
+** rather than the HW. I/O MMU allocation alogorithms can be
+** faster with smaller size is (to some degree).
+*/
+#define DMA_CHUNK_SIZE  (BITS_PER_LONG*PAGE_SIZE)
+
+#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
+
+/************************************
+** SBA register read and write support
+**
+** BE WARNED: register writes are posted.
+**  (ie follow writes which must reach HW with a read)
+**
+*/
+#define READ_REG(addr)       __raw_readq(addr)
+#define WRITE_REG(val, addr) __raw_writeq(val, addr)
+
+#ifdef DEBUG_SBA_INIT
+
+/**
+ * sba_dump_tlb - debugging only - print IOMMU operating parameters
+ * @hpa: base address of the IOMMU
+ *
+ * Print the size/location of the IO MMU PDIR.
+ */
+static void
+sba_dump_tlb(char *hpa)
+{
+	DBG_INIT("IO TLB at 0x%p\n", (void *)hpa);
+	DBG_INIT("IOC_IBASE    : %016lx\n", READ_REG(hpa+IOC_IBASE));
+	DBG_INIT("IOC_IMASK    : %016lx\n", READ_REG(hpa+IOC_IMASK));
+	DBG_INIT("IOC_TCNFG    : %016lx\n", READ_REG(hpa+IOC_TCNFG));
+	DBG_INIT("IOC_PDIR_BASE: %016lx\n", READ_REG(hpa+IOC_PDIR_BASE));
+	DBG_INIT("\n");
+}
+#endif
+
+
+#ifdef ASSERT_PDIR_SANITY
+
+/**
+ * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ * @pide: pdir index.
+ *
+ * Print one entry of the IO MMU PDIR in human readable form.
+ */
+static void
+sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
+{
+	/* start printing from lowest pde in rval */
+	u64 *ptr = &(ioc->pdir_base[pide  & ~(BITS_PER_LONG - 1)]);
+	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
+	uint rcnt;
+
+	/* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */
+	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
+		 msg, rptr, pide & (BITS_PER_LONG - 1), *rptr);
+
+	rcnt = 0;
+	while (rcnt < BITS_PER_LONG) {
+		printk("%s %2d %p %016Lx\n",
+			(rcnt == (pide & (BITS_PER_LONG - 1)))
+				? "    -->" : "       ",
+			rcnt, ptr, *ptr );
+		rcnt++;
+		ptr++;
+	}
+	printk("%s", msg);
+}
+
+
+/**
+ * sba_check_pdir - debugging only - consistency checker
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ *
+ * Verify the resource map and pdir state is consistent
+ */
+static int
+sba_check_pdir(struct ioc *ioc, char *msg)
+{
+	u64 *rptr_end = (u64 *) &(ioc->res_map[ioc->res_size]);
+	u64 *rptr = (u64 *) ioc->res_map;	/* resource map ptr */
+	u64 *pptr = ioc->pdir_base;	/* pdir ptr */
+	uint pide = 0;
+
+	while (rptr < rptr_end) {
+		u64 rval;
+		int rcnt; /* number of bits we might check */
+
+		rval = *rptr;
+		rcnt = 64;
+
+		while (rcnt) {
+			/* Get last byte and highest bit from that */
+			u32 pde = ((u32)((*pptr >> (63)) & 0x1));
+			if ((rval & 0x1) ^ pde)
+			{
+				/*
+				** BUMMER!  -- res_map != pdir --
+				** Dump rval and matching pdir entries
+				*/
+				sba_dump_pdir_entry(ioc, msg, pide);
+				return(1);
+			}
+			rcnt--;
+			rval >>= 1;	/* try the next bit */
+			pptr++;
+			pide++;
+		}
+		rptr++;	/* look at next word of res_map */
+	}
+	/* It'd be nice if we always got here :^) */
+	return 0;
+}
+
+
+/**
+ * sba_dump_sg - debugging only - print Scatter-Gather list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg: head of the SG list
+ * @nents: number of entries in SG list
+ *
+ * print the SG list so we can verify it's correct by hand.
+ */
+static void
+sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
+{
+	while (nents-- > 0) {
+		printk(" %d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg),
+				sba_sg_len(startsg),
+				sba_sg_buffer(startsg));
+		startsg++;
+	}
+}
+static void
+sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
+{
+	struct scatterlist *the_sg = startsg;
+	int the_nents = nents;
+
+	while (the_nents-- > 0) {
+		if (sba_sg_buffer(the_sg) == 0x0UL)
+			sba_dump_sg(NULL, startsg, nents);
+		the_sg++;
+	}
+}
+
+#endif /* ASSERT_PDIR_SANITY */
+
+
+
+
+/**************************************************************
+*
+*   I/O Pdir Resource Management
+*
+*   Bits set in the resource map are in use.
+*   Each bit can represent a number of pages.
+*   LSbs represent lower addresses (IOVA's).
+*
+***************************************************************/
+#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
+
+/* Convert from IOVP to IOVA and vice versa. */
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
+#define SBA_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase))
+
+/* FIXME : review these macros to verify correctness and usage */
+#define PDIR_INDEX(iovp)   ((iovp)>>IOVP_SHIFT)
+
+#define RESMAP_MASK(n)    ~(~0UL << (n))
+#define RESMAP_IDX_MASK   (sizeof(unsigned long) - 1)
+
+
+/**
+ * sba_search_bitmap - find free space in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @bits_wanted: number of entries we need.
+ *
+ * Find consecutive free bits in resource bitmap.
+ * Each bit represents one entry in the IO Pdir.
+ * Cool perf optimization: search for log2(size) bits at a time.
+ */
+static SBA_INLINE unsigned long
+sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
+{
+	unsigned long *res_ptr = ioc->res_hint;
+	unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
+	unsigned long pide = ~0UL;
+
+	ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
+	ASSERT(res_ptr < res_end);
+	if (bits_wanted > (BITS_PER_LONG/2)) {
+		/* Search word at a time - no mask needed */
+		for(; res_ptr < res_end; ++res_ptr) {
+			if (*res_ptr == 0) {
+				*res_ptr = RESMAP_MASK(bits_wanted);
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				break;
+			}
+		}
+		/* point to the next word on next pass */
+		res_ptr++;
+		ioc->res_bitshift = 0;
+	} else {
+		/*
+		** Search the resource bit map on well-aligned values.
+		** "o" is the alignment.
+		** We need the alignment to invalidate I/O TLB using
+		** SBA HW features in the unmap path.
+		*/
+		unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT);
+		uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
+		unsigned long mask;
+
+		if (bitshiftcnt >= BITS_PER_LONG) {
+			bitshiftcnt = 0;
+			res_ptr++;
+		}
+		mask = RESMAP_MASK(bits_wanted) << bitshiftcnt;
+
+		DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
+		while(res_ptr < res_end)
+		{ 
+			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
+			ASSERT(0 != mask);
+			if(0 == ((*res_ptr) & mask)) {
+				*res_ptr |= mask;     /* mark resources busy! */
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				pide += bitshiftcnt;
+				break;
+			}
+			mask <<= o;
+			bitshiftcnt += o;
+			if (0 == mask) {
+				mask = RESMAP_MASK(bits_wanted);
+				bitshiftcnt=0;
+				res_ptr++;
+			}
+		}
+		/* look in the same word on the next pass */
+		ioc->res_bitshift = bitshiftcnt + bits_wanted;
+	}
+
+	/* wrapped ? */
+	if (res_end <= res_ptr) {
+		ioc->res_hint = (unsigned long *) ioc->res_map;
+		ioc->res_bitshift = 0;
+	} else {
+		ioc->res_hint = res_ptr;
+	}
+	return (pide);
+}
+
+
+/**
+ * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @size: number of bytes to create a mapping for
+ *
+ * Given a size, find consecutive unmarked and then mark those bits in the
+ * resource bit map.
+ */
+static int
+sba_alloc_range(struct ioc *ioc, size_t size)
+{
+	unsigned int pages_needed = size >> IOVP_SHIFT;
+#ifdef CONFIG_PROC_FS
+	unsigned long itc_start = ia64_get_itc();
+#endif
+	unsigned long pide;
+
+	ASSERT(pages_needed);
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
+	ASSERT(0 == (size & ~IOVP_MASK));
+
+	/*
+	** "seek and ye shall find"...praying never hurts either...
+	*/
+
+	pide = sba_search_bitmap(ioc, pages_needed);
+	if (pide >= (ioc->res_size << 3)) {
+		pide = sba_search_bitmap(ioc, pages_needed);
+		if (pide >= (ioc->res_size << 3))
+			panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+	}
+
+#ifdef ASSERT_PDIR_SANITY
+	/* verify the first enable bit is clear */
+	if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) {
+		sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
+	}
+#endif
+
+	DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
+		__FUNCTION__, size, pages_needed, pide,
+		(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
+		ioc->res_bitshift );
+
+#ifdef CONFIG_PROC_FS
+	{
+		unsigned long itc_end = ia64_get_itc();
+		unsigned long tmp = itc_end - itc_start;
+		/* check for roll over */
+		itc_start = (itc_end < itc_start) ?  -(tmp) : (tmp);
+	}
+	ioc->avg_search[ioc->avg_idx++] = itc_start;
+	ioc->avg_idx &= SBA_SEARCH_SAMPLE - 1;
+
+	ioc->used_pages += pages_needed;
+#endif
+
+	return (pide);
+}
+
+
+/**
+ * sba_free_range - unmark bits in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova: IO virtual address which was previously allocated.
+ * @size: number of bytes to create a mapping for
+ *
+ * clear bits in the ioc's resource map
+ */
+static SBA_INLINE void
+sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
+{
+	unsigned long iovp = SBA_IOVP(ioc, iova);
+	unsigned int pide = PDIR_INDEX(iovp);
+	unsigned int ridx = pide >> 3;	/* convert bit to byte address */
+	unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
+
+	int bits_not_wanted = size >> IOVP_SHIFT;
+
+	/* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
+	unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
+
+	DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n",
+		__FUNCTION__, (uint) iova, size,
+		bits_not_wanted, m, pide, res_ptr, *res_ptr);
+
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= bits_not_wanted;
+#endif
+
+	ASSERT(m != 0);
+	ASSERT(bits_not_wanted);
+	ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(bits_not_wanted <= BITS_PER_LONG);
+	ASSERT((*res_ptr & m) == m); /* verify same bits are set */
+	*res_ptr &= ~m;
+}
+
+
+/**************************************************************
+*
+*   "Dynamic DMA Mapping" support (aka "Coherent I/O")
+*
+***************************************************************/
+
+#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
+
+
+/**
+ * sba_io_pdir_entry - fill in one IO PDIR entry
+ * @pdir_ptr:  pointer to IO PDIR entry
+ * @vba: Virtual CPU address of buffer to map
+ *
+ * SBA Mapping Routine
+ *
+ * Given a virtual address (vba, arg1) sba_io_pdir_entry()
+ * loads the I/O PDIR entry pointed to by pdir_ptr (arg0).
+ * Each IO Pdir entry consists of 8 bytes as shown below
+ * (LSB == bit 0):
+ *
+ *  63                    40                                 11    7        0
+ * +-+---------------------+----------------------------------+----+--------+
+ * |V|        U            |            PPN[39:12]            | U  |   FF   |
+ * +-+---------------------+----------------------------------+----+--------+
+ *
+ *  V  == Valid Bit
+ *  U  == Unused
+ * PPN == Physical Page Number
+ *
+ * The physical address fields are filled with the results of virt_to_phys()
+ * on the vba.
+ */
+
+#if 1
+#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x8000000000000000ULL)
+#else
+void SBA_INLINE
+sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba)
+{
+	*pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x80000000000000FFULL);
+}
+#endif
+
+#ifdef ENABLE_MARK_CLEAN
+/**
+ * Since DMA is i-cache coherent, any (complete) pages that were written via
+ * DMA can be marked as "clean" so that update_mmu_cache() doesn't have to
+ * flush them when they get mapped into an executable vm-area.
+ */
+static void
+mark_clean (void *addr, size_t size)
+{
+	unsigned long pg_addr, end;
+
+	pg_addr = PAGE_ALIGN((unsigned long) addr);
+	end = (unsigned long) addr + size;
+	while (pg_addr + PAGE_SIZE <= end) {
+		struct page *page = virt_to_page(pg_addr);
+		set_bit(PG_arch_1, &page->flags);
+		pg_addr += PAGE_SIZE;
+	}
+}
+#endif
+
+/**
+ * sba_mark_invalid - invalidate one or more IO PDIR entries
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova:  IO Virtual Address mapped earlier
+ * @byte_cnt:  number of bytes this mapping covers.
+ *
+ * Marking the IO PDIR entry(ies) as Invalid and invalidate
+ * corresponding IO TLB entry. The PCOM (Purge Command Register)
+ * is to purge stale entries in the IO TLB when unmapping entries.
+ *
+ * The PCOM register supports purging of multiple pages, with a minium
+ * of 1 page and a maximum of 2GB. Hardware requires the address be
+ * aligned to the size of the range being purged. The size of the range
+ * must be a power of 2. The "Cool perf optimization" in the
+ * allocation routine helps keep that true.
+ */
+static SBA_INLINE void
+sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
+{
+	u32 iovp = (u32) SBA_IOVP(ioc,iova);
+
+	int off = PDIR_INDEX(iovp);
+
+	/* Must be non-zero and rounded up */
+	ASSERT(byte_cnt > 0);
+	ASSERT(0 == (byte_cnt & ~IOVP_MASK));
+
+#ifdef ASSERT_PDIR_SANITY
+	/* Assert first pdir entry is set */
+	if (!(ioc->pdir_base[off] >> 60)) {
+		sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
+	}
+#endif
+
+	if (byte_cnt <= IOVP_SIZE)
+	{
+		ASSERT(off < ioc->pdir_size);
+
+		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
+
+		/*
+		** clear I/O PDIR entry "valid" bit
+		** Do NOT clear the rest - save it for debugging.
+		** We should only clear bits that have previously
+		** been enabled.
+		*/
+		ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
+	} else {
+		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
+
+		iovp |= t;
+		ASSERT(t <= 31);   /* 2GB! Max value of "size" field */
+
+		do {
+			/* verify this pdir entry is enabled */
+			ASSERT(ioc->pdir_base[off]  >> 63);
+			/* clear I/O Pdir entry "valid" bit first */
+			ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
+			off++;
+			byte_cnt -= IOVP_SIZE;
+		} while (byte_cnt > 0);
+	}
+
+	WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
+}
+
+/**
+ * sba_map_single - map one buffer and return IOVA for DMA
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @addr:  driver buffer to map.
+ * @size:  number of bytes to map in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+dma_addr_t
+sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+{
+	struct ioc *ioc;
+	unsigned long flags; 
+	dma_addr_t iovp;
+	dma_addr_t offset;
+	u64 *pdir_start;
+	int pide;
+#ifdef ALLOW_IOV_BYPASS
+	unsigned long pci_addr = virt_to_phys(addr);
+#endif
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	/*
+ 	** Check if the PCI device can DMA to ptr... if so, just return ptr
+ 	*/
+	if ((pci_addr & ~dev->dma_mask) == 0) {
+		/*
+ 		** Device is bit capable of DMA'ing to the buffer...
+		** just return the PCI address of ptr
+ 		*/
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->msingle_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		DBG_BYPASS("sba_map_single() bypass mask/addr: 0x%lx/0x%lx\n",
+		           dev->dma_mask, pci_addr);
+		return pci_addr;
+	}
+#endif
+
+	ASSERT(size > 0);
+	ASSERT(size <= DMA_CHUNK_SIZE);
+
+	/* save offset bits */
+	offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
+
+	/* round up to nearest IOVP_SIZE */
+	size = (size + offset + ~IOVP_MASK) & IOVP_MASK;
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check before sba_map_single()"))
+		panic("Sanity check failed");
+#endif
+
+#ifdef CONFIG_PROC_FS
+	ioc->msingle_calls++;
+	ioc->msingle_pages += size >> IOVP_SHIFT;
+#endif
+	pide = sba_alloc_range(ioc, size);
+	iovp = (dma_addr_t) pide << IOVP_SHIFT;
+
+	DBG_RUN("%s() 0x%p -> 0x%lx\n",
+		__FUNCTION__, addr, (long) iovp | offset);
+
+	pdir_start = &(ioc->pdir_base[pide]);
+
+	while (size > 0) {
+		ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
+		sba_io_pdir_entry(pdir_start, (unsigned long) addr);
+
+		DBG_RUN("     pdir 0x%p %lx\n", pdir_start, *pdir_start);
+
+		addr += IOVP_SIZE;
+		size -= IOVP_SIZE;
+		pdir_start++;
+	}
+	/* form complete address */
+#ifdef ASSERT_PDIR_SANITY
+	sba_check_pdir(ioc,"Check after sba_map_single()");
+#endif
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+	return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
+}
+
+/**
+ * sba_unmap_single - unmap one IOVA and free resources
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @iova:  IOVA of driver buffer previously mapped.
+ * @size:  number of bytes mapped in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size,
+		int direction)
+{
+	struct ioc *ioc;
+#if DELAYED_RESOURCE_CNT > 0
+	struct sba_dma_pair *d;
+#endif
+	unsigned long flags; 
+	dma_addr_t offset;
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	if ((iova & ioc->imask) != ioc->ibase) {
+		/*
+		** Address does not fall w/in IOVA, must be bypassing
+		*/
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->usingle_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova);
+
+#ifdef ENABLE_MARK_CLEAN
+		if (direction == PCI_DMA_FROMDEVICE) {
+			mark_clean(phys_to_virt(iova), size);
+		}
+#endif
+		return;
+	}
+#endif
+	offset = iova & ~IOVP_MASK;
+
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long) iova, size);
+
+	iova ^= offset;        /* clear offset bits */
+	size += offset;
+	size = ROUNDUP(size, IOVP_SIZE);
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
+#endif
+
+#if DELAYED_RESOURCE_CNT > 0
+	d = &(ioc->saved[ioc->saved_cnt]);
+	d->iova = iova;
+	d->size = size;
+	if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
+		int cnt = ioc->saved_cnt;
+		while (cnt--) {
+			sba_mark_invalid(ioc, d->iova, d->size);
+			sba_free_range(ioc, d->iova, d->size);
+			d--;
+		}
+		ioc->saved_cnt = 0;
+		READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+	}
+#else /* DELAYED_RESOURCE_CNT == 0 */
+	sba_mark_invalid(ioc, iova, size);
+	sba_free_range(ioc, iova, size);
+	READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+#endif /* DELAYED_RESOURCE_CNT == 0 */
+#ifdef ENABLE_MARK_CLEAN
+	if (direction == PCI_DMA_FROMDEVICE) {
+		u32 iovp = (u32) SBA_IOVP(ioc,iova);
+		int off = PDIR_INDEX(iovp);
+		void *addr;
+
+		if (size <= IOVP_SIZE) {
+			addr = phys_to_virt(ioc->pdir_base[off] &
+					    ~0xE000000000000FFFULL);
+			mark_clean(addr, size);
+		} else {
+			size_t byte_cnt = size;
+
+			do {
+				addr = phys_to_virt(ioc->pdir_base[off] &
+				                    ~0xE000000000000FFFULL);
+				mark_clean(addr, min(byte_cnt, IOVP_SIZE));
+				off++;
+				byte_cnt -= IOVP_SIZE;
+
+			   } while (byte_cnt > 0);
+		}
+	}
+#endif
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
+	** For Astro based systems this isn't a big deal WRT performance.
+	** As long as 2.4 kernels copyin/copyout data from/to userspace,
+	** we don't need the syncdma. The issue here is I/O MMU cachelines
+	** are *not* coherent in all cases.  May be hwrev dependent.
+	** Need to investigate more.
+	asm volatile("syncdma");	
+	*/
+}
+
+
+/**
+ * sba_alloc_consistent - allocate/map shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @dma_handle:  IOVA of new buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void *
+sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+	struct ioc *ioc;
+	void *ret;
+
+	if (!hwdev) {
+		/* only support PCI */
+		*dma_handle = 0;
+		return 0;
+	}
+
+        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (ret) {
+		memset(ret, 0, size);
+		/*
+		 * REVISIT: if sba_map_single starts needing more
+		 * than dma_mask from the device, this needs to be
+		 * updated.
+		 */
+		ioc = GET_IOC(hwdev);
+		*dma_handle = sba_map_single(ioc->sac_only_dev, ret, size, 0);
+	}
+
+	return ret;
+}
+
+
+/**
+ * sba_free_consistent - free/unmap shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @vaddr:  virtual address IOVA of "consistent" buffer.
+ * @dma_handler:  IO virtual address of "consistent" buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
+		dma_addr_t dma_handle)
+{
+	sba_unmap_single(hwdev, dma_handle, size, 0);
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+
+/*
+** Since 0 is a valid pdir_base index value, can't use that
+** to determine if a value is valid or not. Use a flag to indicate
+** the SG list entry contains a valid pdir index.
+*/
+#define PIDE_FLAG 0x1UL
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+int dump_run_sg = 0;
+#endif
+
+
+/**
+ * sba_fill_pdir - write allocated SG entries into IO PDIR
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * Take preprocessed SG list and write corresponding entries
+ * in the IO PDIR.
+ */
+
+static SBA_INLINE int
+sba_fill_pdir(
+	struct ioc *ioc,
+	struct scatterlist *startsg,
+	int nents)
+{
+	struct scatterlist *dma_sg = startsg;	/* pointer to current DMA */
+	int n_mappings = 0;
+	u64 *pdirp = 0;
+	unsigned long dma_offset = 0;
+
+	dma_sg--;
+	while (nents-- > 0) {
+		int     cnt = sba_sg_len(startsg);
+		sba_sg_len(startsg) = 0;
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+		if (dump_run_sg)
+			printk(" %2d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg), cnt,
+				sba_sg_buffer(startsg)
+		);
+#else
+		DBG_RUN_SG(" %d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg), cnt,
+				sba_sg_buffer(startsg)
+		);
+#endif
+		/*
+		** Look for the start of a new DMA stream
+		*/
+		if ((u64)sba_sg_iova(startsg) & PIDE_FLAG) {
+			u32 pide = (u64)sba_sg_iova(startsg) & ~PIDE_FLAG;
+			dma_offset = (unsigned long) pide & ~IOVP_MASK;
+			sba_sg_iova(startsg) = 0;
+			dma_sg++;
+			sba_sg_iova(dma_sg) = (char *)(pide | ioc->ibase);
+			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
+			n_mappings++;
+		}
+
+		/*
+		** Look for a VCONTIG chunk
+		*/
+		if (cnt) {
+			unsigned long vaddr = (unsigned long) sba_sg_buffer(startsg);
+			ASSERT(pdirp);
+
+			/* Since multiple Vcontig blocks could make up
+			** one DMA stream, *add* cnt to dma_len.
+			*/
+			sba_sg_len(dma_sg) += cnt;
+			cnt += dma_offset;
+			dma_offset=0;	/* only want offset on first chunk */
+			cnt = ROUNDUP(cnt, IOVP_SIZE);
+#ifdef CONFIG_PROC_FS
+			ioc->msg_pages += cnt >> IOVP_SHIFT;
+#endif
+			do {
+				sba_io_pdir_entry(pdirp, vaddr);
+				vaddr += IOVP_SIZE;
+				cnt -= IOVP_SIZE;
+				pdirp++;
+			} while (cnt > 0);
+		}
+		startsg++;
+	}
+#ifdef DEBUG_LARGE_SG_ENTRIES
+	dump_run_sg = 0;
+#endif
+	return(n_mappings);
+}
+
+
+/*
+** Two address ranges are DMA contiguous *iff* "end of prev" and
+** "start of next" are both on a page boundry.
+**
+** (shift left is a quick trick to mask off upper bits)
+*/
+#define DMA_CONTIG(__X, __Y) \
+	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
+
+
+/**
+ * sba_coalesce_chunks - preprocess the SG list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * First pass is to walk the SG list and determine where the breaks are
+ * in the DMA stream. Allocates PDIR entries but does not fill them.
+ * Returns the number of DMA chunks.
+ *
+ * Doing the fill seperate from the coalescing/allocation keeps the
+ * code simpler. Future enhancement could make one pass through
+ * the sglist do both.
+ */
+static SBA_INLINE int
+sba_coalesce_chunks( struct ioc *ioc,
+	struct scatterlist *startsg,
+	int nents)
+{
+	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */
+	unsigned long vcontig_len;         /* len of VCONTIG chunk */
+	unsigned long vcontig_end;
+	struct scatterlist *dma_sg;        /* next DMA stream head */
+	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
+	int n_mappings = 0;
+
+	while (nents > 0) {
+		unsigned long vaddr = (unsigned long) (startsg->address); 
+
+		/*
+		** Prepare for first/next DMA stream
+		*/
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = sba_sg_len(startsg);
+		vcontig_end +=  vaddr;
+		dma_offset = vaddr & ~IOVP_MASK;
+
+		/* PARANOID: clear entries */
+		sba_sg_buffer(startsg) = sba_sg_iova(startsg);
+		sba_sg_iova(startsg) = 0;
+		sba_sg_len(startsg) = 0;
+
+		/*
+		** This loop terminates one iteration "early" since
+		** it's always looking one "ahead".
+		*/
+		while (--nents > 0) {
+			unsigned long vaddr;	/* tmp */
+
+			startsg++;
+
+			/* catch brokenness in SCSI layer */
+			ASSERT(startsg->length <= DMA_CHUNK_SIZE);
+
+			/*
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
+			*/
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+				break;
+
+			/*
+			** Then look for virtually contiguous blocks.
+			**
+			** append the next transaction?
+			*/
+			vaddr = (unsigned long) sba_sg_iova(startsg);
+			if  (vcontig_end == vaddr)
+			{
+				vcontig_len += sba_sg_len(startsg);
+				vcontig_end += sba_sg_len(startsg);
+				dma_len     += sba_sg_len(startsg);
+				sba_sg_buffer(startsg) = (char *)vaddr;
+				sba_sg_iova(startsg) = 0;
+				sba_sg_len(startsg) = 0;
+				continue;
+			}
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+			dump_run_sg = (vcontig_len > IOVP_SIZE);
+#endif
+
+			/*
+			** Not virtually contigous.
+			** Terminate prev chunk.
+			** Start a new chunk.
+			**
+			** Once we start a new VCONTIG chunk, dma_offset
+			** can't change. And we need the offset from the first
+			** chunk - not the last one. Ergo Successive chunks
+			** must start on page boundaries and dove tail
+			** with it's predecessor.
+			*/
+			sba_sg_len(vcontig_sg) = vcontig_len;
+
+			vcontig_sg = startsg;
+			vcontig_len = sba_sg_len(startsg);
+
+			/*
+			** 3) do the entries end/start on page boundaries?
+			**    Don't update vcontig_end until we've checked.
+			*/
+			if (DMA_CONTIG(vcontig_end, vaddr))
+			{
+				vcontig_end = vcontig_len + vaddr;
+				dma_len += vcontig_len;
+				sba_sg_buffer(startsg) = (char *)vaddr;
+				sba_sg_iova(startsg) = 0;
+				continue;
+			} else {
+				break;
+			}
+		}
+
+		/*
+		** End of DMA Stream
+		** Terminate last VCONTIG block.
+		** Allocate space for DMA stream.
+		*/
+		sba_sg_len(vcontig_sg) = vcontig_len;
+		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
+		ASSERT(dma_len <= DMA_CHUNK_SIZE);
+		sba_sg_iova(dma_sg) = (char *) (PIDE_FLAG 
+			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
+			| dma_offset);
+		n_mappings++;
+	}
+
+	return n_mappings;
+}
+
+
+/**
+ * sba_map_sg - map Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+		int direction)
+{
+	struct ioc *ioc;
+	int coalesced, filled = 0;
+	unsigned long flags;
+#ifdef ALLOW_IOV_BYPASS
+	struct scatterlist *sg;
+#endif
+
+	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	if (dev->dma_mask >= ioc->dma_mask) {
+		for (sg = sglist ; filled < nents ; filled++, sg++){
+			sba_sg_buffer(sg) = sba_sg_iova(sg);
+			sba_sg_iova(sg) = (char *)virt_to_phys(sba_sg_buffer(sg));
+		}
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->msg_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		return filled;
+	}
+#endif
+	/* Fast path single entry scatterlists. */
+	if (nents == 1) {
+		sba_sg_buffer(sglist) = sba_sg_iova(sglist);
+		sba_sg_iova(sglist) = (char *)sba_map_single(dev,
+						sba_sg_buffer(sglist),
+						sba_sg_len(sglist), direction);
+#ifdef CONFIG_PROC_FS
+		/*
+		** Should probably do some stats counting, but trying to
+		** be precise quickly starts wasting CPU time.
+		*/
+#endif
+		return 1;
+	}
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check before sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check before sba_map_sg()");
+	}
+#endif
+
+#ifdef CONFIG_PROC_FS
+	ioc->msg_calls++;
+#endif
+
+	/*
+	** First coalesce the chunks and allocate I/O pdir space
+	**
+	** If this is one DMA stream, we can properly map using the
+	** correct virtual address associated with each DMA page.
+	** w/o this association, we wouldn't have coherent DMA!
+	** Access to the virtual address is what forces a two pass algorithm.
+	*/
+	coalesced = sba_coalesce_chunks(ioc, sglist, nents);
+ 
+	/*
+	** Program the I/O Pdir
+	**
+	** map the virtual addresses to the I/O Pdir
+	** o dma_address will contain the pdir index
+	** o dma_len will contain the number of bytes to map 
+	** o address contains the virtual address.
+	*/
+	filled = sba_fill_pdir(ioc, sglist, nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check after sba_map_sg()\n");
+	}
+#endif
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	ASSERT(coalesced == filled);
+	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+	return filled;
+}
+
+
+/**
+ * sba_unmap_sg - unmap Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+		int direction)
+{
+	struct ioc *ioc;
+#ifdef ASSERT_PDIR_SANITY
+	unsigned long flags;
+#endif
+
+	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
+		__FUNCTION__, nents, sba_sg_buffer(sglist), sglist->length);
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usg_calls++;
+#endif
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check before sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+	while (sba_sg_len(sglist) && nents--) {
+
+		sba_unmap_single(dev, (dma_addr_t)sba_sg_iova(sglist),
+		                 sba_sg_len(sglist), direction);
+#ifdef CONFIG_PROC_FS
+		/*
+		** This leaves inconsistent data in the stats, but we can't
+		** tell which sg lists were mapped by map_single and which
+		** were coalesced to a single entry.  The stats are fun,
+		** but speed is more important.
+		*/
+		ioc->usg_pages += (((u64)sba_sg_iova(sglist) & ~IOVP_MASK) + sba_sg_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
+#endif
+		++sglist;
+	}
+
+	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__,  nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check after sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+}
+
+unsigned long
+sba_dma_address (struct scatterlist *sg)
+{
+	return ((unsigned long)sba_sg_iova(sg));
+}
+
+int
+sba_dma_supported (struct pci_dev *dev, u64 mask)
+{
+	return 1;
+}
+
+/**************************************************************
+*
+*   Initialization and claim
+*
+***************************************************************/
+
+static void __init
+ioc_iova_init(struct ioc *ioc)
+{
+	u32 iova_space_mask;
+	int iov_order, tcnfg;
+	int agp_found = 0;
+	struct pci_dev *device;
+
+	/*
+	** Firmware programs the base and size of a "safe IOVA space"
+	** (one that doesn't overlap memory or LMMIO space) in the
+	** IBASE and IMASK registers.
+	*/
+	ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL;
+	ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;
+
+	if (ioc->ibase == 0) {
+		if (((unsigned long) ioc->ioc_hpa & 0x3000UL) == 0x2000)
+			ioc->ibase = 0xc0000000;
+		else
+			ioc->ibase = 0x80000000;
+		printk("WARNING: IBASE is zero; setting to 0x%lx\n", ioc->ibase);
+	}
+
+	if (ioc->ibase < 0xfed00000UL && ioc->ibase + ioc->iov_size >= 0xfee00000UL) {
+		printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");
+		ioc->iov_size /= 2;
+	}
+
+	/*
+	** iov_order is always based on a 1GB IOVA space since we want to
+	** turn on the other half for AGP GART.
+	*/
+	iov_order = get_order(ioc->iov_size >> (IOVP_SHIFT - PAGE_SHIFT));
+	ioc->pdir_size = (ioc->iov_size / IOVP_SIZE) * sizeof(u64);
+
+	DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits) PDIR size 0x%0x\n",
+		__FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20,
+		iov_order + PAGE_SHIFT, ioc->pdir_size);
+
+	/* FIXME : DMA HINTs not used */
+	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+
+	ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,
+						   get_order(ioc->pdir_size));
+	if (!ioc->pdir_base)
+		panic(PFX "Couldn't allocate I/O Page Table\n");
+
+	memset(ioc->pdir_base, 0, ioc->pdir_size);
+
+	DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
+		__FUNCTION__, ioc->pdir_base, ioc->pdir_size,
+		ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+
+	ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+	WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+	DBG_INIT(" base %p\n", ioc->pdir_base);
+
+	/* build IMASK for IOC and Elroy */
+	iova_space_mask =  0xffffffff;
+	iova_space_mask <<= (iov_order + PAGE_SHIFT);
+	ioc->imask = iova_space_mask;
+
+	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
+		__FUNCTION__, ioc->ibase, ioc->imask);
+
+	/*
+	** FIXME: Hint registers are programmed with default hint
+	** values during boot, so hints should be sane even if we
+	** can't reprogram them the way drivers want.
+	*/
+	WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
+
+	/*
+	** Setting the upper bits makes checking for bypass addresses
+	** a little faster later on.
+	*/
+	ioc->imask |= 0xFFFFFFFF00000000UL;
+
+	/* Set I/O PDIR Page size to system page size */
+	switch (PAGE_SHIFT) {
+		case 12: tcnfg = 0; break;	/*  4K */
+		case 13: tcnfg = 1; break;	/*  8K */
+		case 14: tcnfg = 2; break;	/* 16K */
+		case 16: tcnfg = 3; break;	/* 64K */
+		default:
+			panic(PFX "Unsupported system page size %d",
+				1 << PAGE_SHIFT);
+			break;
+	}
+	WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);
+
+	/*
+	** Program the IOC's ibase and enable IOVA translation
+	** Bit zero == enable bit.
+	*/
+	WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);
+
+	/*
+	** Clear I/O TLB of any possible entries.
+	** (Yes. This is a bit paranoid...but so what)
+	*/
+	WRITE_REG(0 | 31, ioc->ioc_hpa + IOC_PCOM);
+
+	/*
+	** If an AGP device is present, only use half of the IOV space
+	** for PCI DMA.  Unfortunately we can't know ahead of time
+	** whether GART support will actually be used, for now we
+	** can just key on an AGP device found in the system.
+	** We program the next pdir index after we stop w/ a key for
+	** the GART code to handshake on.
+	*/
+	pci_for_each_dev(device)
+		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
+
+	if (agp_found && reserve_sba_gart) {
+		DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", __FUNCTION__);
+		ioc->pdir_size /= 2;
+		((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE;
+	}
+}
+
+static void __init
+ioc_resource_init(struct ioc *ioc)
+{
+	spin_lock_init(&ioc->res_lock);
+
+	/* resource map size dictated by pdir_size */
+	ioc->res_size = ioc->pdir_size / sizeof(u64); /* entries */
+	ioc->res_size >>= 3;  /* convert bit count to byte count */
+	DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+
+	ioc->res_map = (char *) __get_free_pages(GFP_KERNEL,
+						 get_order(ioc->res_size));
+	if (!ioc->res_map)
+		panic(PFX "Couldn't allocate resource map\n");
+
+	memset(ioc->res_map, 0, ioc->res_size);
+	/* next available IOVP - circular search */
+	ioc->res_hint = (unsigned long *) ioc->res_map;
+
+#ifdef ASSERT_PDIR_SANITY
+	/* Mark first bit busy - ie no IOVA 0 */
+	ioc->res_map[0] = 0x1;
+	ioc->pdir_base[0] = 0x8000000000000000ULL | ZX1_SBA_IOMMU_COOKIE;
+#endif
+
+	DBG_INIT("%s() res_map %x %p\n", __FUNCTION__,
+		 ioc->res_size, (void *) ioc->res_map);
+}
+
+static void __init
+ioc_sac_init(struct ioc *ioc)
+{
+	struct pci_dev *sac = NULL;
+	struct pci_controller *controller = NULL;
+
+	/*
+	 * pci_alloc_consistent() must return a DMA address which is
+	 * SAC (single address cycle) addressable, so allocate a
+	 * pseudo-device to enforce that.
+	 */
+	sac = kmalloc(sizeof(*sac), GFP_KERNEL);
+	if (!sac)
+		panic(PFX "Couldn't allocate struct pci_dev");
+	memset(sac, 0, sizeof(*sac));
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		panic(PFX "Couldn't allocate struct pci_controller");
+	memset(controller, 0, sizeof(*controller));
+
+	controller->iommu = ioc;
+	sac->sysdata = controller;
+	sac->dma_mask = 0xFFFFFFFFUL;
+	ioc->sac_only_dev = sac;
+}
+
+static void __init
+ioc_zx1_init(struct ioc *ioc)
+{
+	if (ioc->rev < 0x20)
+		panic(PFX "IOC 2.0 or later required for IOMMU support\n");
+
+	ioc->dma_mask = 0xFFFFFFFFFFUL;
+}
+
+typedef void (initfunc)(struct ioc *);
+
+struct ioc_iommu {
+	u32 func_id;
+	char *name;
+	initfunc *init;
+};
+
+static struct ioc_iommu ioc_iommu_info[] __initdata = {
+	{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
+	{ REO_IOC_ID, "REO" },
+};
+
+static struct ioc * __init
+ioc_init(u64 hpa, void *handle)
+{
+	struct ioc *ioc;
+	struct ioc_iommu *info;
+
+	ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
+	if (!ioc)
+		return NULL;
+
+	memset(ioc, 0, sizeof(*ioc));
+
+	ioc->next = ioc_list;
+	ioc_list = ioc;
+
+	ioc->handle = handle;
+	ioc->ioc_hpa = ioremap(hpa, 0x1000);
+
+	ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
+	ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL;
+	ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL;	/* conservative */
+
+	for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) {
+		if (ioc->func_id == info->func_id) {
+			ioc->name = info->name;
+			if (info->init)
+				(info->init)(ioc);
+		}
+	}
+	if (!ioc->name)
+		ioc->name = "Unknown";
+
+	ioc_iova_init(ioc);
+	ioc_resource_init(ioc);
+	ioc_sac_init(ioc);
+
+	printk(KERN_INFO PFX
+		"Found %s IOC %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
+		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
+		hpa, ioc->iov_size >> 20, ioc->ibase);
+
+	return ioc;
+}
+
+
+
+/**************************************************************************
+**
+**   SBA initialization code (HW and SW)
+**
+**   o identify SBA chip itself
+**   o FIXME: initialize DMA hints for reasonable defaults
+**
+**************************************************************************/
+
+#ifdef CONFIG_PROC_FS
+static int
+sba_proc_info_one(char *buf, struct ioc *ioc)
+{
+	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
+	unsigned long i = 0, avg = 0, min, max;
+
+	sprintf(buf, "Hewlett Packard %s IOC rev %d.%d\n",
+		ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF));
+	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
+		buf,
+		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
+		total_pages);
+
+	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+		total_pages - ioc->used_pages, ioc->used_pages,
+		(int) (ioc->used_pages * 100 / total_pages));
+	
+	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+		buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
+
+	min = max = ioc->avg_search[0];
+	for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
+		avg += ioc->avg_search[i];
+		if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
+		if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
+	}
+	avg /= SBA_SEARCH_SAMPLE;
+	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+		buf, min, avg, max);
+
+	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msingle_calls, ioc->msingle_pages,
+		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_map_single(): %12ld bypasses\n",
+	        buf, ioc->msingle_bypass);
+#endif
+
+	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->usingle_calls, ioc->usingle_pages,
+		(int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_unmap_single: %12ld bypasses\n",
+	        buf, ioc->usingle_bypass);
+#endif
+
+	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msg_calls, ioc->msg_pages,
+		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_map_sg()    : %12ld bypasses\n",
+	        buf, ioc->msg_bypass);
+#endif
+
+	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->usg_calls, ioc->usg_pages,
+		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
+
+	return strlen(buf);
+}
+
+static int
+sba_proc_info(char *buf, char **start, off_t offset, int len)
+{
+	struct ioc *ioc;
+	char *base = buf;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next) {
+		buf += sba_proc_info_one(buf, ioc);
+	}
+
+	return strlen(base);
+}
+
+static int
+sba_resource_map_one(char *buf, struct ioc *ioc)
+{
+	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
+	int i;
+
+	buf[0] = '\0';
+	for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) {
+		if ((i & 7) == 0)
+		    strcat(buf,"\n   ");
+		sprintf(buf, "%s %08x", buf, *res_ptr);
+	}
+	strcat(buf, "\n");
+
+	return strlen(buf);
+}
+
+static int
+sba_resource_map(char *buf, char **start, off_t offset, int len)
+{
+	struct ioc *ioc;
+	char *base = buf;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next) {
+		buf += sba_resource_map_one(buf, ioc);
+	}
+
+	return strlen(base);
+}
+#endif
+
+void
+sba_enable_device(struct pci_dev *dev)
+{
+	acpi_handle handle, parent;
+	acpi_status status;
+	struct ioc *ioc;
+
+	handle = PCI_CONTROLLER(dev)->acpi_handle;
+	if (!handle)
+		return;
+
+	/*
+	 * The IOC scope encloses PCI root bridges in the ACPI
+	 * namespace, so work our way out until we find an IOC we
+	 * claimed previously.
+	 */
+	do {
+		for (ioc = ioc_list; ioc; ioc = ioc->next)
+			if (ioc->handle == handle) {
+				PCI_CONTROLLER(dev)->iommu = ioc;
+				return;
+			}
+
+		status = acpi_get_parent(handle, &parent);
+		handle = parent;
+	} while (ACPI_SUCCESS(status));
+
+	printk("No IOC for %s in ACPI\n", dev->slot_name);
+}
+
+static int __init
+acpi_sba_ioc_add(struct acpi_device *device)
+{
+	struct ioc *ioc;
+	acpi_status status;
+	u64 hpa, length;
+
+	/*
+	 * Only SBA appears in ACPI namespace.  It encloses the PCI
+	 * root bridges, and its CSR space includes the IOC function.
+	 */
+	status = acpi_hp_csr_space(device->handle, &hpa, &length);
+	if (ACPI_FAILURE(status))
+		return 1;
+	ioc = ioc_init(hpa + ZX1_IOC_OFFSET, device->handle);
+	if (!ioc)
+		return 1;
+
+	return 0;
+}
+
+static int __init
+acpi_ioc_add(struct acpi_device *device)
+{
+	struct ioc *ioc;
+	acpi_status status;
+	u64 hpa, length;
+
+	status = acpi_hp_csr_space(device->handle, &hpa, &length);
+	if (ACPI_FAILURE(status))
+		return 1;
+	ioc = ioc_init(hpa, device->handle);
+	if (!ioc)
+		return 1;
+
+	return 0;
+}
+
+static struct acpi_driver acpi_sba_ioc_driver = {
+	name:		"IOC IOMMU Driver",
+	ids:		"HWP0001",
+	ops: {
+		add:	acpi_sba_ioc_add,
+     },
+};
+
+static struct acpi_driver acpi_ioc_driver = {
+	name:		"IOC IOMMU Driver",
+	ids:		"HWP0004",
+	ops: {
+		add:	acpi_ioc_add,
+     },
+};
+
+void __init
+ioc_acpi_init(void)
+{
+	acpi_bus_register_driver(&acpi_sba_ioc_driver);
+	acpi_bus_register_driver(&acpi_ioc_driver);
+}
+
+void __init
+sba_init(void)
+{
+	ioc_acpi_init();
+
+#ifdef CONFIG_PROC_FS
+	if (ioc_list) {
+		struct proc_dir_entry * proc_mckinley_root;
+
+		proc_mckinley_root = proc_mkdir("bus/mckinley",0);
+		create_proc_info_entry(ioc_list->name, 0, proc_mckinley_root, sba_proc_info);
+		create_proc_info_entry("bitmap", 0, proc_mckinley_root, sba_resource_map);
+	}
+#endif
+}
+
+static int __init
+nosbagart(char *str)
+{
+	reserve_sba_gart = 0;
+	return 1;
+}
+
+__setup("nosbagart", nosbagart);
+
+EXPORT_SYMBOL(sba_init);
+EXPORT_SYMBOL(sba_map_single);
+EXPORT_SYMBOL(sba_unmap_single);
+EXPORT_SYMBOL(sba_map_sg);
+EXPORT_SYMBOL(sba_unmap_sg);
+EXPORT_SYMBOL(sba_dma_address);
+EXPORT_SYMBOL(sba_dma_supported);
+EXPORT_SYMBOL(sba_alloc_consistent);
+EXPORT_SYMBOL(sba_free_consistent);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_console.c linux-2.4.20/arch/ia64/hp/hpsim_console.c
--- linux-2.4.19/arch/ia64/hp/hpsim_console.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/hpsim_console.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-
-#include "hpsim_ssc.h"
-
-static int simcons_init (struct console *, char *);
-static void simcons_write (struct console *, const char *, unsigned);
-static kdev_t simcons_console_device (struct console *);
-
-struct console hpsim_cons = {
-	name:		"simcons",
-	write:		simcons_write,
-	device:		simcons_console_device,
-	setup:		simcons_init,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-static int
-simcons_init (struct console *cons, char *options)
-{
-	return 0;
-}
-
-static void
-simcons_write (struct console *cons, const char *buf, unsigned count)
-{
-	unsigned long ch;
-
-	while (count-- > 0) {
-		ch = *buf++;
-		ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
-		if (ch == '\n')
-		  ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
-	}
-}
-
-static kdev_t
-simcons_console_device (struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_irq.c linux-2.4.20/arch/ia64/hp/hpsim_irq.c
--- linux-2.4.19/arch/ia64/hp/hpsim_irq.c	2001-04-05 19:51:47.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/hpsim_irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,46 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/irq.h>
-
-static unsigned int
-hpsim_irq_startup (unsigned int irq)
-{
-	return 0;
-}
-
-static void
-hpsim_irq_noop (unsigned int irq)
-{
-}
-
-static struct hw_interrupt_type irq_type_hp_sim = {
-	typename:	"hpsim",
-	startup:	hpsim_irq_startup,
-	shutdown:	hpsim_irq_noop,
-	enable:		hpsim_irq_noop,
-	disable:	hpsim_irq_noop,
-	ack:		hpsim_irq_noop,
-	end:		hpsim_irq_noop,
-	set_affinity:	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
-};
-
-void __init
-hpsim_irq_init (void)
-{
-	irq_desc_t *idesc;
-	int i;
-
-	for (i = 0; i < NR_IRQS; ++i) {
-		idesc = irq_desc(i);
-		if (idesc->handler == &no_irq_type)
-			idesc->handler = &irq_type_hp_sim;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_machvec.c linux-2.4.20/arch/ia64/hp/hpsim_machvec.c
--- linux-2.4.19/arch/ia64/hp/hpsim_machvec.c	2000-08-12 02:09:06.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/hpsim_machvec.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,2 +0,0 @@
-#define MACHVEC_PLATFORM_NAME	hpsim
-#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_setup.c linux-2.4.20/arch/ia64/hp/hpsim_setup.c
--- linux-2.4.19/arch/ia64/hp/hpsim_setup.c	2001-07-31 17:30:08.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/hpsim_setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-
-#include "hpsim_ssc.h"
-
-extern struct console hpsim_cons;
-
-/*
- * Simulator system call.
- */
-asm (".text\n"
-     ".align 32\n"
-     ".global ia64_ssc\n"
-     ".proc ia64_ssc\n"
-     "ia64_ssc:\n"
-     "mov r15=r36\n"
-     "break 0x80001\n"
-     "br.ret.sptk.many rp\n"
-     ".endp\n");
-
-void
-ia64_ssc_connect_irq (long intr, long irq)
-{
-	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
-}
-
-void
-ia64_ctl_trace (long on)
-{
-	ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
-}
-
-void __init
-hpsim_setup (char **cmdline_p)
-{
-	ROOT_DEV = to_kdev_t(0x0801);		/* default to first SCSI drive */
-
-	register_console (&hpsim_cons);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_ssc.h linux-2.4.20/arch/ia64/hp/hpsim_ssc.h
--- linux-2.4.19/arch/ia64/hp/hpsim_ssc.h	2000-02-07 02:42:40.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/hpsim_ssc.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#ifndef _IA64_PLATFORM_HPSIM_SSC_H
-#define _IA64_PLATFORM_HPSIM_SSC_H
-
-/* Simulator system calls: */
-
-#define SSC_CONSOLE_INIT		20
-#define SSC_GETCHAR			21
-#define SSC_PUTCHAR			31
-#define SSC_CONNECT_INTERRUPT		58
-#define SSC_GENERATE_INTERRUPT		59
-#define SSC_SET_PERIODIC_INTERRUPT	60
-#define SSC_GET_RTC			65
-#define SSC_EXIT			66
-#define SSC_LOAD_SYMBOLS		69
-#define SSC_GET_TOD			74
-#define SSC_CTL_TRACE			76
-
-#define SSC_NETDEV_PROBE		100
-#define SSC_NETDEV_SEND			101
-#define SSC_NETDEV_RECV			102
-#define SSC_NETDEV_ATTACH		103
-#define SSC_NETDEV_DETACH		104
-
-/*
- * Simulator system call.
- */
-extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
-
-#endif /* _IA64_PLATFORM_HPSIM_SSC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/Makefile linux-2.4.20/arch/ia64/hp/sim/Makefile
--- linux-2.4.19/arch/ia64/hp/sim/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/Makefile	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,13 @@
+#
+# ia64/platform/hp/sim/Makefile
+#
+# Copyright (C) 1999 Silicon Graphics, Inc.
+# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
+#
+
+O_TARGET := sim.o
+
+obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
+obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_console.c linux-2.4.20/arch/ia64/hp/sim/hpsim_console.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_console.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/hpsim_console.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,62 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pal.h>
+#include <asm/machvec.h>
+#include <asm/pgtable.h>
+#include <asm/sal.h>
+
+#include "hpsim_ssc.h"
+
+static int simcons_init (struct console *, char *);
+static void simcons_write (struct console *, const char *, unsigned);
+static int simcons_wait_key (struct console *);
+static kdev_t simcons_console_device (struct console *);
+
+struct console hpsim_cons = {
+	name:		"simcons",
+	write:		simcons_write,
+	device:		simcons_console_device,
+	setup:		simcons_init,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+static int
+simcons_init (struct console *cons, char *options)
+{
+	return 0;
+}
+
+static void
+simcons_write (struct console *cons, const char *buf, unsigned count)
+{
+	unsigned long ch;
+
+	while (count-- > 0) {
+		ch = *buf++;
+		ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
+		if (ch == '\n')
+		  ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
+	}
+}
+
+static kdev_t
+simcons_console_device (struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_irq.c linux-2.4.20/arch/ia64/hp/sim/hpsim_irq.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/hpsim_irq.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,46 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/irq.h>
+
+static unsigned int
+hpsim_irq_startup (unsigned int irq)
+{
+	return 0;
+}
+
+static void
+hpsim_irq_noop (unsigned int irq)
+{
+}
+
+static struct hw_interrupt_type irq_type_hp_sim = {
+	typename:	"hpsim",
+	startup:	hpsim_irq_startup,
+	shutdown:	hpsim_irq_noop,
+	enable:		hpsim_irq_noop,
+	disable:	hpsim_irq_noop,
+	ack:		hpsim_irq_noop,
+	end:		hpsim_irq_noop,
+	set_affinity:	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
+};
+
+void __init
+hpsim_irq_init (void)
+{
+	irq_desc_t *idesc;
+	int i;
+
+	for (i = 0; i < NR_IRQS; ++i) {
+		idesc = irq_desc(i);
+		if (idesc->handler == &no_irq_type)
+			idesc->handler = &irq_type_hp_sim;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_machvec.c linux-2.4.20/arch/ia64/hp/sim/hpsim_machvec.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_machvec.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/hpsim_machvec.c	2002-10-04 00:41:21.000000000 +0000
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpsim
+#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_setup.c linux-2.4.20/arch/ia64/hp/sim/hpsim_setup.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/hpsim_setup.c	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,58 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pal.h>
+#include <asm/machvec.h>
+#include <asm/pgtable.h>
+#include <asm/sal.h>
+
+#include "hpsim_ssc.h"
+
+extern struct console hpsim_cons;
+
+/*
+ * Simulator system call.
+ */
+asm (".text\n"
+     ".align 32\n"
+     ".global ia64_ssc\n"
+     ".proc ia64_ssc\n"
+     "ia64_ssc:\n"
+     "mov r15=r36\n"
+     "break 0x80001\n"
+     "br.ret.sptk.many rp\n"
+     ".endp\n");
+
+void
+ia64_ssc_connect_irq (long intr, long irq)
+{
+	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
+}
+
+void
+ia64_ctl_trace (long on)
+{
+	ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
+}
+
+void __init
+hpsim_setup (char **cmdline_p)
+{
+	ROOT_DEV = to_kdev_t(0x0801);		/* default to first SCSI drive */
+
+	register_console (&hpsim_cons);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_ssc.h linux-2.4.20/arch/ia64/hp/sim/hpsim_ssc.h
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_ssc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/sim/hpsim_ssc.h	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#ifndef _IA64_PLATFORM_HPSIM_SSC_H
+#define _IA64_PLATFORM_HPSIM_SSC_H
+
+/* Simulator system calls: */
+
+#define SSC_CONSOLE_INIT		20
+#define SSC_GETCHAR			21
+#define SSC_PUTCHAR			31
+#define SSC_CONNECT_INTERRUPT		58
+#define SSC_GENERATE_INTERRUPT		59
+#define SSC_SET_PERIODIC_INTERRUPT	60
+#define SSC_GET_RTC			65
+#define SSC_EXIT			66
+#define SSC_LOAD_SYMBOLS		69
+#define SSC_GET_TOD			74
+#define SSC_CTL_TRACE			76
+
+#define SSC_NETDEV_PROBE		100
+#define SSC_NETDEV_SEND			101
+#define SSC_NETDEV_RECV			102
+#define SSC_NETDEV_ATTACH		103
+#define SSC_NETDEV_DETACH		104
+
+/*
+ * Simulator system call.
+ */
+extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
+
+#endif /* _IA64_PLATFORM_HPSIM_SSC_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/Makefile linux-2.4.20/arch/ia64/hp/zx1/Makefile
--- linux-2.4.19/arch/ia64/hp/zx1/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/zx1/Makefile	2002-10-04 00:41:19.000000000 +0000
@@ -0,0 +1,13 @@
+#
+# ia64/platform/hp/zx1/Makefile
+#
+# Copyright (C) 2002 Hewlett Packard
+# Copyright (C) Alex Williamson (alex_williamson@hp.com)
+#
+
+O_TARGET := zx1.o
+
+obj-y := hpzx1_misc.o
+obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.20/arch/ia64/hp/zx1/hpzx1_machvec.c
--- linux-2.4.19/arch/ia64/hp/zx1/hpzx1_machvec.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/zx1/hpzx1_machvec.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpzx1
+#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/hpzx1_misc.c linux-2.4.20/arch/ia64/hp/zx1/hpzx1_misc.c
--- linux-2.4.19/arch/ia64/hp/zx1/hpzx1_misc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/hp/zx1/hpzx1_misc.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,308 @@
+/*
+ * Misc. support for HP zx1 chipset support
+ *
+ * Copyright (C) 2002 Hewlett-Packard Co
+ * Copyright (C) 2002 Alex Williamson <alex_williamson@hp.com>
+ * Copyright (C) 2002 Bjorn Helgaas <bjorn_helgaas@hp.com>
+ */
+
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+
+#include <asm/dma.h>
+#include <asm/iosapic.h>
+
+extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, unsigned long *);
+
+#define PFX "hpzx1: "
+
+static int hpzx1_devices;
+
+struct fake_pci_dev {
+	unsigned long csr_base;
+	unsigned long csr_size;
+	unsigned long mapped_csrs;	// ioremapped
+	int sizing;			// in middle of BAR sizing operation?
+};
+
+#define PCI_FAKE_DEV(dev)	((struct fake_pci_dev *) \
+					PCI_CONTROLLER(dev)->platform_data)
+
+static struct pci_ops *orig_pci_ops;
+
+#define HP_CFG_RD(sz, bits, name) \
+static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
+{ \
+	struct fake_pci_dev *fake_dev; \
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
+		return orig_pci_ops->name(dev, where, value); \
+	\
+	if (where == PCI_BASE_ADDRESS_0) { \
+		if (fake_dev->sizing) \
+			*value = ~(fake_dev->csr_size - 1); \
+		else \
+			*value = (fake_dev->csr_base & \
+				    PCI_BASE_ADDRESS_MEM_MASK) | \
+				PCI_BASE_ADDRESS_SPACE_MEMORY; \
+		fake_dev->sizing = 0; \
+		return PCIBIOS_SUCCESSFUL; \
+	} \
+	*value = read##sz(fake_dev->mapped_csrs + where); \
+	if (where == PCI_COMMAND) \
+		*value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \
+	return PCIBIOS_SUCCESSFUL; \
+}
+
+#define HP_CFG_WR(sz, bits, name) \
+static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
+{ \
+	struct fake_pci_dev *fake_dev; \
+	\
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
+		return orig_pci_ops->name(dev, where, value); \
+	\
+	if (where == PCI_BASE_ADDRESS_0) { \
+		if (value == (u##bits) ~0) \
+			fake_dev->sizing = 1; \
+		return PCIBIOS_SUCCESSFUL; \
+	} else \
+		write##sz(value, fake_dev->mapped_csrs + where); \
+	return PCIBIOS_SUCCESSFUL; \
+}
+
+HP_CFG_RD(b,  8, read_byte)
+HP_CFG_RD(w, 16, read_word)
+HP_CFG_RD(l, 32, read_dword)
+HP_CFG_WR(b,  8, write_byte)
+HP_CFG_WR(w, 16, write_word)
+HP_CFG_WR(l, 32, write_dword)
+
+static struct pci_ops hp_pci_conf = {
+	hp_cfg_readb,
+	hp_cfg_readw,
+	hp_cfg_readl,
+	hp_cfg_writeb,
+	hp_cfg_writew,
+	hp_cfg_writel,
+};
+
+static void
+hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size)
+{
+	struct pci_controller *controller;
+	struct fake_pci_dev *fake;
+	int slot;
+	struct pci_dev *dev;
+	struct pci_bus *b, *bus = NULL;
+	u8 hdr;
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
+			(void *) addr);
+		return;
+	}
+	memset(controller, 0, sizeof(*controller));
+
+        fake = kmalloc(sizeof(*fake), GFP_KERNEL);
+	if (!fake) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
+			(void *) addr);
+		kfree(controller);
+		return;
+	}
+
+	memset(fake, 0, sizeof(*fake));
+	fake->csr_base = addr;
+	fake->csr_size = size;
+	fake->mapped_csrs = (unsigned long) ioremap(addr, size);
+	fake->sizing = 0;
+	controller->platform_data = fake;
+
+	pci_for_each_bus(b)
+		if (busnum == b->number) {
+			bus = b;
+			break;
+		}
+
+	if (!bus) {
+		printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n",
+			busnum, name, (void *) addr);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+	for (slot = 0x1e; slot; slot--)
+		if (!pci_find_slot(busnum, PCI_DEVFN(slot, 0)))
+			break;
+
+	if (slot < 0) {
+		printk(KERN_ERR PFX "No space for %s (0x%p) on bus 0x%02x\n",
+			name, (void *) addr, busnum);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+        dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name,
+			(void *) addr);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+	bus->ops = &hp_pci_conf;	// replace pci ops for this bus
+
+	memset(dev, 0, sizeof(*dev));
+	dev->bus = bus;
+	dev->sysdata = controller;
+	dev->devfn = PCI_DEVFN(slot, 0);
+	pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
+	pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr);
+	dev->hdr_type = hdr & 0x7f;
+
+	pci_setup_device(dev);
+
+	// pci_insert_device() without running /sbin/hotplug
+	list_add_tail(&dev->bus_list, &bus->devices);
+	list_add_tail(&dev->global_list, &pci_devices);
+
+	printk(KERN_INFO PFX "%s at 0x%lx; pci dev %s\n", name, addr,
+		dev->slot_name);
+
+	hpzx1_devices++;
+}
+
+static acpi_status
+hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
+{
+	u64 csr_base = 0, csr_length = 0;
+	acpi_status status;
+	char *name = context;
+	char fullname[16];
+
+	status = acpi_hp_csr_space(obj, &csr_base, &csr_length);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	/*
+	 * Only SBA shows up in ACPI namespace, so its CSR space
+	 * includes both SBA and IOC.  Make SBA and IOC show up
+	 * separately in PCI space.
+	 */
+	sprintf(fullname, "%s SBA", name);
+	hpzx1_fake_pci_dev(fullname, 0, csr_base, 0x1000);
+	sprintf(fullname, "%s IOC", name);
+	hpzx1_fake_pci_dev(fullname, 0, csr_base + 0x1000, 0x1000);
+
+	return AE_OK;
+}
+
+static acpi_status
+hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
+{
+	u64 csr_base = 0, csr_length = 0;
+	acpi_status status;
+	NATIVE_UINT busnum;
+	char *name = context;
+	char fullname[32];
+
+	status = acpi_hp_csr_space(obj, &csr_base, &csr_length);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING PFX "evaluate _BBN fail=0x%x\n", status);
+		busnum = 0;	// no _BBN; stick it on bus 0
+	}
+
+	sprintf(fullname, "%s _BBN 0x%02x", name, (unsigned int) busnum);
+	hpzx1_fake_pci_dev(fullname, busnum, csr_base, csr_length);
+
+	return AE_OK;
+}
+
+static void
+hpzx1_acpi_dev_init(void)
+{
+	extern struct pci_ops *pci_root_ops;
+
+	orig_pci_ops = pci_root_ops;
+
+	/*
+	 * Make fake PCI devices for the following hardware in the
+	 * ACPI namespace.  This makes it more convenient for drivers
+	 * because they can claim these devices based on PCI
+	 * information, rather than needing to know about ACPI.  The
+	 * 64-bit "HPA" space for this hardware is available as BAR
+	 * 0/1.
+	 *
+	 * HWP0001: Single IOC SBA w/o IOC in namespace
+	 * HWP0002: LBA device
+	 * HWP0003: AGP LBA device
+	 */
+	acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL);
+#ifdef CONFIG_IA64_HP_PROTO
+	if (hpzx1_devices) {
+#endif
+	acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002 PCI LBA", NULL);
+	acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003 AGP LBA", NULL);
+
+#ifdef CONFIG_IA64_HP_PROTO
+	}
+
+#define ZX1_FUNC_ID_VALUE    (PCI_DEVICE_ID_HP_ZX1_SBA << 16) | PCI_VENDOR_ID_HP
+	/*
+	 * Early protos don't have bridges in the ACPI namespace, so
+	 * if we didn't find anything, add the things we know are
+	 * there.
+	 */
+	if (hpzx1_devices == 0) {
+		u64 hpa, csr_base;
+
+		csr_base = 0xfed00000UL;
+		hpa = (u64) ioremap(csr_base, 0x2000);
+		if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) {
+			hpzx1_fake_pci_dev("HWP0001 SBA", 0, csr_base, 0x1000);
+			hpzx1_fake_pci_dev("HWP0001 IOC", 0, csr_base + 0x1000,
+					    0x1000);
+
+			csr_base = 0xfed24000UL;
+			iounmap(hpa);
+			hpa = (u64) ioremap(csr_base, 0x1000);
+			hpzx1_fake_pci_dev("HWP0003 AGP LBA", 0x40, csr_base,
+					    0x1000);
+		}
+		iounmap(hpa);
+	}
+#endif
+}
+
+extern void sba_init(void);
+
+void
+hpzx1_pci_fixup (int phase)
+{
+	iosapic_pci_fixup(phase);
+	switch (phase) {
+	      case 0:
+		/* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */
+		MAX_DMA_ADDRESS = ~0UL;
+		break;
+
+	      case 1:
+		hpzx1_acpi_dev_init();
+		sba_init();
+		break;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/ia32/binfmt_elf32.c linux-2.4.20/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.19/arch/ia64/ia32/binfmt_elf32.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/ia32/binfmt_elf32.c	2002-10-04 00:41:30.000000000 +0000
@@ -47,6 +47,8 @@
 #define ELF_PLAT_INIT(_r)		ia64_elf32_init(_r)
 #define setup_arg_pages(bprm)		ia32_setup_arg_pages(bprm)
 #define elf_map				elf32_map
+
+#undef SET_PERSONALITY
 #define SET_PERSONALITY(ex, ibcs2)	elf32_set_personality()
 
 /* Ugly but avoids duplication */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/ia32/ia32_traps.c linux-2.4.20/arch/ia64/ia32/ia32_traps.c
--- linux-2.4.19/arch/ia64/ia32/ia32_traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/ia32/ia32_traps.c	2002-10-04 00:41:15.000000000 +0000
@@ -20,7 +20,7 @@
 {
 	switch ((isr >> 16) & 0xff) {
 	      case 0:	/* Instruction intercept fault */
-	      case 3:	/* Locked Data reference fault */
+	      case 4:	/* Locked Data reference fault */
 	      case 1:	/* Gate intercept trap */
 		return -1;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/Makefile linux-2.4.20/arch/ia64/kernel/Makefile
--- linux-2.4.19/arch/ia64/kernel/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/Makefile	2002-10-04 00:41:19.000000000 +0000
@@ -17,6 +17,7 @@
 	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o salinfo.o semaphore.o setup.o	 \
 	 signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
 obj-$(CONFIG_IA64_GENERIC) += iosapic.o
+obj-$(CONFIG_IA64_HP_ZX1) += iosapic.o
 obj-$(CONFIG_IA64_DIG) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/acpi.c linux-2.4.20/arch/ia64/kernel/acpi.c
--- linux-2.4.19/arch/ia64/kernel/acpi.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/acpi.c	2002-10-04 00:41:20.000000000 +0000
@@ -1,21 +1,34 @@
 /*
- * Advanced Configuration and Power Interface
+ *  acpi.c - Architecture-Specific Low-Level ACPI Support
  *
- * Based on 'ACPI Specification 1.0b' February 2, 1999 and
- * 'IA-64 Extensions to ACPI Specification' Revision 0.6
+ *  Copyright (C) 1999 VA Linux Systems
+ *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
+ *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *  Copyright (C) 2000 Intel Corp.
+ *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
+ *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000 Hewlett-Packard Co.
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000 Intel Corp.
- * Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
- *      ACPI based kernel configuration manager.
- *      ACPI 2.0 & IA64 ext 0.71
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
 #include <linux/config.h>
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -23,657 +36,801 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/irq.h>
-#ifdef CONFIG_SERIAL_ACPI
-#include <linux/acpi_serial.h>
-#endif
-
-#include <asm/acpi-ext.h>
-#include <asm/acpikcfg.h>
-#include <asm/efi.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
 #include <asm/machvec.h>
 #include <asm/page.h>
+#include <asm/system.h>
 
-#undef ACPI_DEBUG		/* Guess what this does? */
 
-/* global array to record platform interrupt vectors for generic int routing */
-int platform_irq_list[ACPI_MAX_PLATFORM_IRQS];
+#define PREFIX			"ACPI: "
 
-/* These are ugly but will be reclaimed by the kernel */
-int __initdata available_cpus;
-int __initdata total_cpus;
+asm (".weak iosapic_register_intr");
+asm (".weak iosapic_override_isa_irq");
+asm (".weak iosapic_register_platform_intr");
+asm (".weak iosapic_init");
+asm (".weak iosapic_version");
 
 void (*pm_idle) (void);
 void (*pm_power_off) (void);
 
-asm (".weak iosapic_register_irq");
-asm (".weak iosapic_register_legacy_irq");
-asm (".weak iosapic_register_platform_irq");
-asm (".weak iosapic_init");
-asm (".weak iosapic_version");
+unsigned char acpi_kbd_controller_present = 1;
 
 const char *
 acpi_get_sysname (void)
 {
-	/* the following should go away once we have an ACPI parser: */
 #ifdef CONFIG_IA64_GENERIC
-	return "hpsim";
+	unsigned long rsdp_phys;
+	struct acpi20_table_rsdp *rsdp;
+	struct acpi_table_xsdt *xsdt;
+	struct acpi_table_header *hdr;
+
+	rsdp_phys = acpi_find_rsdp();
+	if (!rsdp_phys) {
+		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");
+		return "dig";
+	}
+
+	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
+	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
+		printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
+		return "dig";
+	}
+
+	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
+	hdr = &xsdt->header;
+	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
+		printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
+		return "dig";
+	}
+
+	if (!strcmp(hdr->oem_id, "HP")) {
+		return "hpzx1";
+	}
+
+	return "dig";
 #else
 # if defined (CONFIG_IA64_HP_SIM)
 	return "hpsim";
+# elif defined (CONFIG_IA64_HP_ZX1)
+	return "hpzx1";
 # elif defined (CONFIG_IA64_SGI_SN1)
 	return "sn1";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
 	return "dig";
+# elif defined (CONFIG_IA64_HP_ZX1)
+	return "hpzx1";
 # else
 #	error Unknown platform.  Fix acpi.c.
 # endif
 #endif
+}
+
+#ifdef CONFIG_ACPI
+
+/**
+ * acpi_get_crs - Return the current resource settings for a device
+ * obj: A handle for this device
+ * buf: A buffer to be populated by this call.
+ *
+ * Pass a valid handle, typically obtained by walking the namespace and a
+ * pointer to an allocated buffer, and this function will fill in the buffer
+ * with a list of acpi_resource structures.
+ */
+acpi_status
+acpi_get_crs (acpi_handle obj, acpi_buffer *buf)
+{
+	acpi_status result;
+	buf->length = 0;
+	buf->pointer = NULL;
+
+	result = acpi_get_current_resources(obj, buf);
+	if (result != AE_BUFFER_OVERFLOW)
+		return result;
+	buf->pointer = kmalloc(buf->length, GFP_KERNEL);
+	if (!buf->pointer)
+		return -ENOMEM;
+
+	return acpi_get_current_resources(obj, buf);
+}
+
+acpi_resource *
+acpi_get_crs_next (acpi_buffer *buf, int *offset)
+{
+	acpi_resource *res;
+
+	if (*offset >= buf->length)
+		return NULL;
+
+	res = buf->pointer + *offset;
+	*offset += res->length;
+	return res;
+}
+
+acpi_resource_data *
+acpi_get_crs_type (acpi_buffer *buf, int *offset, int type)
+{
+	for (;;) {
+		acpi_resource *res = acpi_get_crs_next(buf, offset);
+		if (!res)
+			return NULL;
+		if (res->id == type)
+			return &res->data;
+	}
+}
+
+void
+acpi_dispose_crs (acpi_buffer *buf)
+{
+	kfree(buf->pointer);
+}
+
+static void
+acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra)
+{
+	int offset = 0;
+	acpi_resource_address16 *addr16;
+	acpi_resource_address32 *addr32;
+	acpi_resource_address64 *addr64;
+
+	for (;;) {
+		acpi_resource *res = acpi_get_crs_next(buf, &offset);
+		if (!res)
+			return;
+		switch (res->id) {
+			case ACPI_RSTYPE_ADDRESS16:
+				addr16 = (acpi_resource_address16 *) &res->data;
+
+				if (type == addr16->resource_type) {
+					*base = addr16->min_address_range;
+					*length = addr16->address_length;
+					*tra = addr16->address_translation_offset;
+					return;
+				}
+				break;
+			case ACPI_RSTYPE_ADDRESS32:
+				addr32 = (acpi_resource_address32 *) &res->data;
+				if (type == addr32->resource_type) {
+					*base = addr32->min_address_range;
+					*length = addr32->address_length;
+					*tra = addr32->address_translation_offset;
+					return;
+				}
+				break;
+			case ACPI_RSTYPE_ADDRESS64:
+				addr64 = (acpi_resource_address64 *) &res->data;
+				if (type == addr64->resource_type) {
+					*base = addr64->min_address_range;
+					*length = addr64->address_length;
+					*tra = addr64->address_translation_offset;
+					return;
+				}
+				break;
+		}
+	}
+}
+
+acpi_status
+acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra)
+{
+	acpi_status status;
+	acpi_buffer buf;
+
+	*base = 0;
+	*length = 0;
+	*tra = 0;
+
+	status = acpi_get_crs(obj, &buf);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
+		return status;
+	}
+
+	acpi_get_crs_addr(&buf, type, base, length, tra);
+
+	acpi_dispose_crs(&buf);
+
+	return AE_OK;
+}
+
+typedef struct {
+	u8	guid_id;
+	u8	guid[16];
+	u8	csr_base[8];
+	u8	csr_length[8];
+} acpi_hp_vendor_long;
+
+#define HP_CCSR_LENGTH 0x21
+#define HP_CCSR_TYPE 0x2
+#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \
+			      0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
+
+acpi_status
+acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
+{
+	int i, offset = 0;
+	acpi_status status;
+	acpi_buffer buf;
+	acpi_resource_vendor *res;
+	acpi_hp_vendor_long *hp_res;
+	efi_guid_t vendor_guid;
+
+	*csr_base = 0;
+	*csr_length = 0;
 
+	status = acpi_get_crs(obj, &buf);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
+		return status;
+	}
+
+	res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
+	if (!res) {
+		printk(KERN_ERR PREFIX "Failed to find config space for device\n");
+		acpi_dispose_crs(&buf);
+		return AE_NOT_FOUND;
+	}
+
+	hp_res = (acpi_hp_vendor_long *)(res->reserved);
+
+	if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {
+		printk(KERN_ERR PREFIX "Unknown Vendor data\n");
+		acpi_dispose_crs(&buf);
+		return AE_TYPE; /* Revisit error? */
+	}
+
+	memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t));
+	if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) {
+		printk(KERN_ERR PREFIX "Vendor GUID does not match\n");
+		acpi_dispose_crs(&buf);
+		return AE_TYPE; /* Revisit error? */
+	}
+
+	for (i = 0 ; i < 8 ; i++) {
+		*csr_base |= ((u64)(hp_res->csr_base[i]) << (i * 8));
+		*csr_length |= ((u64)(hp_res->csr_length[i]) << (i * 8));
+	}
+
+	acpi_dispose_crs(&buf);
+
+	return AE_OK;
 }
+#endif /* CONFIG_ACPI */
+
+#ifdef CONFIG_ACPI_BOOT
+
+#define ACPI_MAX_PLATFORM_INTERRUPTS	256
+
+/* Array to record platform interrupt vectors for generic interrupt routing. */
+int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 };
+
+enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
 
 /*
- * Interrupt routing API for device drivers.
- * Provides the interrupt vector for a generic platform event
- * (currently only CPEI implemented)
+ * Interrupt routing API for device drivers.  Provides interrupt vector for
+ * a generic platform event.  Currently only CPEI is implemented.
  */
 int
-acpi_request_vector(u32 int_type)
+acpi_request_vector (u32 int_type)
 {
 	int vector = -1;
 
-	if (int_type < ACPI_MAX_PLATFORM_IRQS) {
+	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
 		/* correctable platform error interrupt */
-		vector = platform_irq_list[int_type];
+		vector = platform_intr_list[int_type];
 	} else
 		printk("acpi_request_vector(): invalid interrupt type\n");
 
 	return vector;
 }
 
-/*
- * Configure legacy IRQ information.
- */
-static void __init
-acpi_legacy_irq (char *p)
+char *
+__acpi_map_table (unsigned long phys_addr, unsigned long size)
 {
-	acpi_entry_int_override_t *legacy = (acpi_entry_int_override_t *) p;
-	unsigned long polarity = 0, edge_triggered = 0;
+	return __va(phys_addr);
+}
 
-	/*
-	 * If the platform we're running doesn't define
-	 * iosapic_register_legacy_irq(), we ignore this info...
-	 */
-	if (!iosapic_register_legacy_irq)
-		return;
+/* --------------------------------------------------------------------------
+                            Boot-time Table Parsing
+   -------------------------------------------------------------------------- */
 
-	switch (legacy->flags) {
-	      case 0x5:	polarity = 1; edge_triggered = 1; break;
-	      case 0x7: polarity = 0; edge_triggered = 1; break;
-	      case 0xd: polarity = 1; edge_triggered = 0; break;
-	      case 0xf: polarity = 0; edge_triggered = 0; break;
-	      default:
-		printk("    ACPI Legacy IRQ 0x%02x: Unknown flags 0x%x\n", legacy->isa_irq,
-		       legacy->flags);
-		break;
-	}
-	iosapic_register_legacy_irq(legacy->isa_irq, legacy->pin, polarity, edge_triggered);
-}
+static int			total_cpus __initdata;
+static int			available_cpus __initdata;
+struct acpi_table_madt *	acpi_madt __initdata;
+static u8			has_8259;
 
-/*
- * ACPI 2.0 tables parsing functions
- */
 
-static unsigned long
-readl_unaligned(void *p)
+static int __init
+acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
 {
-	unsigned long ret;
+	struct acpi_table_lapic_addr_ovr *lapic;
+
+	lapic = (struct acpi_table_lapic_addr_ovr *) header;
+	if (!lapic)
+		return -EINVAL;
 
-	memcpy(&ret, p, sizeof(long));
-	return ret;
+	acpi_table_print_madt_entry(header);
+
+	if (lapic->address) {
+		iounmap((void *) ipi_base_addr);
+		ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
+	}
+
+	return 0;
 }
 
-/*
- * Identify usable CPU's and remember them for SMP bringup later.
- */
-static void __init
-acpi20_lsapic (char *p)
+
+static int __init
+acpi_parse_lsapic (acpi_table_entry_header *header)
 {
-	int add = 1;
+	struct acpi_table_lsapic *lsapic;
 
-	acpi20_entry_lsapic_t *lsapic = (acpi20_entry_lsapic_t *) p;
-	printk("      CPU %.04x:%.04x: ", lsapic->eid, lsapic->id);
+	lsapic = (struct acpi_table_lsapic *) header;
+	if (!lsapic)
+		return -EINVAL;
 
-	if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
-		printk("disabled.\n");
-		add = 0;
-	}
+	acpi_table_print_madt_entry(header);
 
-#ifdef CONFIG_SMP
-	smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
-	if (add) {
+	printk("CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
+
+	if (lsapic->flags.enabled) {
 		available_cpus++;
-		printk("available");
+		printk(" enabled");
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
 		if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
 			printk(" (BSP)");
 #endif
-		printk(".\n");
 	}
+	else {
+		printk(" disabled");
+#ifdef CONFIG_SMP
+		smp_boot_data.cpu_phys_id[total_cpus] = -1;
+#endif
+	}
+
+	printk("\n");
+
 	total_cpus++;
+	return 0;
 }
 
-/*
- * Extract iosapic info from madt (again) to determine which iosapic
- * this platform interrupt resides in
- */
+
+static int __init
+acpi_parse_lapic_nmi (acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_nmi *lacpi_nmi;
+
+	lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
+	if (!lacpi_nmi)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	/* TBD: Support lapic_nmi entries */
+
+	return 0;
+}
+
+
 static int __init
-acpi20_which_iosapic (int global_vector, acpi_madt_t *madt, u32 *irq_base, char **iosapic_address)
+acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address)
 {
-	acpi_entry_iosapic_t *iosapic;
-	char *p, *end;
-	int ver, max_pin;
+	struct acpi_table_iosapic *iosapic;
+	int ver;
+	int max_pin;
+	char *p;
+	char *end;
+
+	if (!gsi_base || !iosapic_address)
+		return -ENODEV;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	p = (char *) (acpi_madt + 1);
+	end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));
 
 	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_IO_SAPIC:
-			/* collect IOSAPIC info for platform int use later */
-			iosapic = (acpi_entry_iosapic_t *)p;
-			*irq_base = iosapic->irq_base;
+		if (*p == ACPI_MADT_IOSAPIC) {
+			iosapic = (struct acpi_table_iosapic *) p;
+
+			*gsi_base = iosapic->global_irq_base;
 			*iosapic_address = ioremap(iosapic->address, 0);
-			/* is this the iosapic we're looking for? */
+
 			ver = iosapic_version(*iosapic_address);
 			max_pin = (ver >> 16) & 0xff;
-			if ((global_vector - *irq_base) <= max_pin)
-				return 0;		/* found it! */
-			break;
-		      default:
-			break;
+
+			if ((gsi - *gsi_base) <= max_pin)
+				return 0;	/* Found it! */
 		}
 		p += p[1];
 	}
-	return 1;
+	return -ENODEV;
 }
 
-/*
- * Info on platform interrupt sources: NMI, PMI, INIT, etc.
- */
-static void __init
-acpi20_platform (char *p, acpi_madt_t *madt)
+
+static int __init
+acpi_parse_iosapic (acpi_table_entry_header *header)
 {
+	struct acpi_table_iosapic *iosapic;
+
+	iosapic = (struct acpi_table_iosapic *) header;
+	if (!iosapic)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (iosapic_init) {
+#ifndef CONFIG_ITANIUM
+		/* PCAT_COMPAT flag indicates dual-8259 setup */
+		iosapic_init(iosapic->address, iosapic->global_irq_base,
+			     acpi_madt->flags.pcat_compat);
+#else
+		/* Firmware on old Itanium systems is broken */
+		iosapic_init(iosapic->address, iosapic->global_irq_base, 1);
+#endif
+	}
+	return 0;
+}
+
+
+static int __init
+acpi_parse_plat_int_src (acpi_table_entry_header *header)
+{
+	struct acpi_table_plat_int_src *plintsrc;
 	int vector;
-	u32 irq_base;
+	u32 gsi_base;
 	char *iosapic_address;
-	unsigned long polarity = 0, trigger = 0;
-	acpi20_entry_platform_src_t *plat = (acpi20_entry_platform_src_t *) p;
 
-	printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n",
-	       plat->iosapic_vector, plat->global_vector, plat->eid, plat->id);
+	plintsrc = (struct acpi_table_plat_int_src *) header;
+	if (!plintsrc)
+		return -EINVAL;
 
-	/* record platform interrupt vectors for generic int routing code */
+	acpi_table_print_madt_entry(header);
 
-	if (!iosapic_register_platform_irq) {
-		printk("acpi20_platform(): no ACPI platform IRQ support\n");
-		return;
-	}
-
-	/* extract polarity and trigger info from flags */
-	switch (plat->flags) {
-	      case 0x5: polarity = 1; trigger = 1; break;
-	      case 0x7: polarity = 0; trigger = 1; break;
-	      case 0xd: polarity = 1; trigger = 0; break;
-	      case 0xf: polarity = 0; trigger = 0; break;
-	      default:
-		printk("acpi20_platform(): unknown flags 0x%x\n", plat->flags);
-		break;
-	}
-
-	/* which iosapic does this IRQ belong to? */
-	if (acpi20_which_iosapic(plat->global_vector, madt, &irq_base, &iosapic_address)) {
-		printk("acpi20_platform(): I/O SAPIC not found!\n");
-		return;
+	if (!iosapic_register_platform_intr) {
+		printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n");
+		return -ENODEV;
+	}
+
+	if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) {
+		printk(KERN_WARNING PREFIX "IOSAPIC not found\n");
+		return -ENODEV;
 	}
 
 	/*
-	 * get vector assignment for this IRQ, set attributes, and program the IOSAPIC
-	 * routing table
+	 * Get vector assignment for this interrupt, set attributes,
+	 * and program the IOSAPIC routing table.
 	 */
-	vector = iosapic_register_platform_irq(plat->int_type,
-					       plat->global_vector,
-					       plat->iosapic_vector,
-					       plat->eid,
-					       plat->id,
-					       polarity,
-					       trigger,
-					       irq_base,
-					       iosapic_address);
-	platform_irq_list[plat->int_type] = vector;
+	vector = iosapic_register_platform_intr(plintsrc->type,
+						plintsrc->global_irq,
+						plintsrc->iosapic_vector,
+						plintsrc->eid,
+						plintsrc->id,
+						(plintsrc->flags.polarity == 1) ? 1 : 0,
+						(plintsrc->flags.trigger == 1) ? 1 : 0,
+						gsi_base,
+						iosapic_address);
+
+	platform_intr_list[plintsrc->type] = vector;
+	return 0;
 }
 
-/*
- * Override the physical address of the local APIC in the MADT stable header.
- */
-static void __init
-acpi20_lapic_addr_override (char *p)
+
+static int __init
+acpi_parse_int_src_ovr (acpi_table_entry_header *header)
 {
-	acpi20_entry_lapic_addr_override_t * lapic = (acpi20_entry_lapic_addr_override_t *) p;
+	struct acpi_table_int_src_ovr *p;
 
-	if (lapic->lapic_address) {
-		iounmap((void *)ipi_base_addr);
-		ipi_base_addr = (unsigned long) ioremap(lapic->lapic_address, 0);
+	p = (struct acpi_table_int_src_ovr *) header;
+	if (!p)
+		return -EINVAL;
 
-		printk("LOCAL ACPI override to 0x%lx(p=0x%lx)\n",
-		       ipi_base_addr, lapic->lapic_address);
-	}
+	acpi_table_print_madt_entry(header);
+
+	/* Ignore if the platform doesn't support overrides */
+	if (!iosapic_override_isa_irq)
+		return 0;
+
+	iosapic_override_isa_irq(p->bus_irq, p->global_irq,
+				 (p->flags.polarity == 1) ? 1 : 0,
+				 (p->flags.trigger == 1) ? 1 : 0);
+
+	return 0;
 }
 
-/*
- * Parse the ACPI Multiple APIC Description Table
- */
-static void __init
-acpi20_parse_madt (acpi_madt_t *madt)
+
+static int __init
+acpi_parse_nmi_src (acpi_table_entry_header *header)
 {
-	acpi_entry_iosapic_t *iosapic = NULL;
-	acpi20_entry_lsapic_t *lsapic = NULL;
-	char *p, *end;
-	int i;
-
-	/* Base address of IPI Message Block */
-	if (madt->lapic_address) {
-		ipi_base_addr = (unsigned long) ioremap(madt->lapic_address, 0);
-		printk("Lapic address set to 0x%lx\n", ipi_base_addr);
-	} else
-		printk("Lapic address set to default 0x%lx\n", ipi_base_addr);
+	struct acpi_table_nmi_src *nmi_src;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	nmi_src = (struct acpi_table_nmi_src*) header;
+	if (!nmi_src)
+		return -EINVAL;
 
-	/* Initialize platform interrupt vector array */
-	for (i = 0; i < ACPI_MAX_PLATFORM_IRQS; i++)
-		platform_irq_list[i] = -1;
+	acpi_table_print_madt_entry(header);
 
-	/*
-	 * Split-up entry parsing to ensure ordering.
-	 */
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE:
-			printk("ACPI 2.0 MADT: LOCAL APIC Override\n");
-			acpi20_lapic_addr_override(p);
-			break;
-
-		      case ACPI20_ENTRY_LOCAL_SAPIC:
-			printk("ACPI 2.0 MADT: LOCAL SAPIC\n");
-			lsapic = (acpi20_entry_lsapic_t *) p;
-			acpi20_lsapic(p);
-			break;
-
-		      case ACPI20_ENTRY_IO_SAPIC:
-			iosapic = (acpi_entry_iosapic_t *) p;
-			if (iosapic_init)
-				/*
-				 * The PCAT_COMPAT flag indicates that the system has a
-				 * dual-8259 compatible setup.
-				 */
-				iosapic_init(iosapic->address, iosapic->irq_base,
-#ifdef CONFIG_ITANIUM
-					     1 /* fw on some Itanium systems is broken... */
-#else
-					     (madt->flags & MADT_PCAT_COMPAT)
-#endif
-					);
-			break;
+	/* TBD: Support nimsrc entries */
 
-		      case ACPI20_ENTRY_PLATFORM_INT_SOURCE:
-			printk("ACPI 2.0 MADT: PLATFORM INT SOURCE\n");
-			acpi20_platform(p, madt);
-			break;
-
-		      case ACPI20_ENTRY_LOCAL_APIC:
-			printk("ACPI 2.0 MADT: LOCAL APIC entry\n"); break;
-		      case ACPI20_ENTRY_IO_APIC:
-			printk("ACPI 2.0 MADT: IO APIC entry\n"); break;
-		      case ACPI20_ENTRY_NMI_SOURCE:
-			printk("ACPI 2.0 MADT: NMI SOURCE entry\n"); break;
-		      case ACPI20_ENTRY_LOCAL_APIC_NMI:
-			printk("ACPI 2.0 MADT: LOCAL APIC NMI entry\n"); break;
-		      case ACPI20_ENTRY_INT_SRC_OVERRIDE:
-			break;
-		      default:
-			printk("ACPI 2.0 MADT: unknown entry skip\n"); break;
-			break;
-		}
-		p += p[1];
-	}
+	return 0;
+}
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_LOCAL_APIC:
-			if (lsapic) break;
-			printk("ACPI 2.0 MADT: LOCAL APIC entry\n");
-			/* parse local apic if there's no local Sapic */
-			break;
-		      case ACPI20_ENTRY_IO_APIC:
-			if (iosapic) break;
-			printk("ACPI 2.0 MADT: IO APIC entry\n");
-			/* parse ioapic if there's no ioSapic */
-			break;
-		      default:
-			break;
-		}
-		p += p[1];
-	}
+static int __init
+acpi_parse_madt (unsigned long phys_addr, unsigned long size)
+{
+	if (!phys_addr || !size)
+		return -EINVAL;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_INT_SRC_OVERRIDE:
-			printk("ACPI 2.0 MADT: INT SOURCE Override\n");
-			acpi_legacy_irq(p);
-			break;
-		      default:
-			break;
-		}
-		p += p[1];
-	}
+	/* remember the value for reference after free_initmem() */
+	has_8259 = acpi_madt->flags.pcat_compat;
+
+	/* Get base address of IPI Message Block */
 
-	/* Make bootup pretty */
-	printk("      %d CPUs available, %d CPUs total\n",
-		available_cpus, total_cpus);
+	if (acpi_madt->lapic_address)
+		ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
+
+	printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
+	return 0;
 }
 
-int __init
-acpi20_parse (acpi20_rsdp_t *rsdp20)
+
+static int __init
+acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
 {
-# ifdef CONFIG_ACPI
-	acpi_xsdt_t *xsdt;
-	acpi_desc_table_hdr_t *hdrp;
-	acpi_madt_t *madt = NULL;
-	int tables, i;
+	struct acpi_table_header *fadt_header;
+	fadt_descriptor_rev2 *fadt;
+	u32 sci_irq, gsi_base;
+	char *iosapic_address;
 
-	if (strncmp(rsdp20->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) {
-		printk("ACPI 2.0 RSDP signature incorrect!\n");
-		return 0;
-	} else {
-		printk("ACPI 2.0 Root System Description Ptr at 0x%lx\n",
-			(unsigned long)rsdp20);
-	}
+	if (!phys_addr || !size)
+		return -EINVAL;
 
-	xsdt = __va(rsdp20->xsdt);
-	hdrp = &xsdt->header;
-	if (strncmp(hdrp->signature,
-		ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN)) {
-		printk("ACPI 2.0 XSDT signature incorrect. Trying RSDT\n");
-		/* RSDT parsing here */
-		return 0;
-	} else {
-		printk("ACPI 2.0 XSDT at 0x%lx (p=0x%lx)\n",
-		(unsigned long)xsdt, (unsigned long)rsdp20->xsdt);
-	}
+	fadt_header = (struct acpi_table_header *) __va(phys_addr);
 
-	printk("ACPI 2.0: %.6s %.8s %d.%d\n",
-		hdrp->oem_id,
-		hdrp->oem_table_id,
-		hdrp->oem_revision >> 16,
-		hdrp->oem_revision & 0xffff);
+	if (fadt_header->revision != 3)
+		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */
 
-	acpi_cf_init((void *)rsdp20);
+	fadt = (fadt_descriptor_rev2 *) fadt_header;
 
-	tables =(hdrp->length -sizeof(acpi_desc_table_hdr_t))>>3;
+	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
+		acpi_kbd_controller_present = 0;
 
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(readl_unaligned(&xsdt->entry_ptrs[i]));
-		printk("        :table %4.4s found\n", hdrp->signature);
+	sci_irq = fadt->sci_int;
 
-		/* Only interested int the MADT table for now ... */
-		if (strncmp(hdrp->signature,
-			ACPI_MADT_SIG, ACPI_MADT_SIG_LEN) != 0)
-			continue;
+	if (has_8259 && sci_irq < 16)
+		return 0;	/* legacy, no setup required */
+
+	if (!iosapic_register_intr)
+		return -ENODEV;
+
+	if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address))
+		iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address);
+
+	return 0;
+}
 
-		/* Save MADT pointer for later */
-		madt = (acpi_madt_t *) hdrp;
-		acpi20_parse_madt(madt);
-	}
 
 #ifdef CONFIG_SERIAL_ACPI
+
+#include <linux/acpi_serial.h>
+
+static int __init
+acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
+{
+	acpi_ser_t *spcr;
+	u32 gsi, gsi_base;
+	char *iosapic_address;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	if (!iosapic_register_intr)
+		return -ENODEV;
+
 	/*
-	 * Now we're interested in other tables.  We want the iosapics already
-	 * initialized, so we do it in a separate loop.
+	 * ACPI is able to describe serial ports that live at non-standard
+	 * memory addresses and use non-standard interrupts, either via
+	 * direct SAPIC mappings or via PCI interrupts.  We handle interrupt
+	 * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing
+	 * for PCI devices will be handled when processing the PCI Interrupt
+	 * Routing Table (PRT).
 	 */
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(readl_unaligned(&xsdt->entry_ptrs[i]));
-		/*
-		 * search for SPCR and DBGP table entries so we can enable
-		 * non-pci interrupts to IO-SAPICs.
-		 */
-		if (!strncmp(hdrp->signature, ACPI_SPCRT_SIG, ACPI_SPCRT_SIG_LEN) ||
-		    !strncmp(hdrp->signature, ACPI_DBGPT_SIG, ACPI_DBGPT_SIG_LEN))
-		{
-			acpi_ser_t *spcr = (void *)hdrp;
-			unsigned long global_int;
-
-			setup_serial_acpi(hdrp);
-
-			/*
-			 * ACPI is able to describe serial ports that live at non-standard
-			 * memory space addresses and use SAPIC interrupts.  If not also
-			 * PCI devices, there would be no interrupt vector information for
-			 * them.  This checks for and fixes that situation.
-			 */
-			if (spcr->length < sizeof(acpi_ser_t))
-				/* table is not long enough for full info, thus no int */
-				break;
 
-			/*
-			 * If the device is not in PCI space, but uses a SAPIC interrupt,
-			 * we need to program the SAPIC so that serial can autoprobe for
-			 * the IA64 interrupt vector later on.  If the device is in PCI
-			 * space, it should already be setup via the PCI vectors
-			 */
-			if (spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE &&
-			    spcr->int_type == ACPI_SERIAL_INT_SAPIC)
-			{
-				u32 irq_base;
-				char *iosapic_address;
-				int vector;
-
-				/* We have a UART in memory space with a SAPIC interrupt */
-				global_int = (  (spcr->global_int[3] << 24)
-					      | (spcr->global_int[2] << 16)
-					      | (spcr->global_int[1] << 8)
-					      | spcr->global_int[0]);
-
-				if (!iosapic_register_irq)
-					continue;
-
-				/* which iosapic does this IRQ belong to? */
-				if (acpi20_which_iosapic(global_int, madt, &irq_base,
-							 &iosapic_address) == 0)
-				{
-					vector = iosapic_register_irq(global_int,
-					                              1, /* active high polarity */
-					                              1, /* edge triggered */
-					                              irq_base,
-					                              iosapic_address);
-				}
-			}
-		}
-	}
-#endif
-	acpi_cf_terminate();
+	spcr = (acpi_ser_t *) __va(phys_addr);
+	setup_serial_acpi(spcr);
 
-#  ifdef CONFIG_SMP
-	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
-		available_cpus = 1; /* We've got at least one of these, no? */
+	if (spcr->length < sizeof(acpi_ser_t))
+		/* Table not long enough for full info, thus no interrupt */
+		return -ENODEV;
+
+	if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&
+	    (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) {
+
+		/* We have a UART in memory space with an SAPIC interrupt */
+
+		gsi = (spcr->global_int[3] << 24) |
+		      (spcr->global_int[2] << 16) |
+		      (spcr->global_int[1] << 8)  |
+		      (spcr->global_int[0]);
+
+		if (!acpi_find_iosapic(gsi, &gsi_base, &iosapic_address))
+			iosapic_register_intr(gsi, 1, 1,
+					      gsi_base, iosapic_address);
 	}
-	smp_boot_data.cpu_count = total_cpus;
-#  endif
-# endif /* CONFIG_ACPI */
-	return 1;
+	return 0;
 }
-/*
- * ACPI 1.0b with 0.71 IA64 extensions functions; should be removed once all
- * platforms start supporting ACPI 2.0
- */
 
-/*
- * Identify usable CPU's and remember them for SMP bringup later.
- */
-static void __init
-acpi_lsapic (char *p)
+#endif /*CONFIG_SERIAL_ACPI*/
+
+
+unsigned long __init
+acpi_find_rsdp (void)
 {
-	int add = 1;
+	unsigned long rsdp_phys = 0;
 
-	acpi_entry_lsapic_t *lsapic = (acpi_entry_lsapic_t *) p;
+	if (efi.acpi20)
+		rsdp_phys = __pa(efi.acpi20);
+	else if (efi.acpi)
+		printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
 
-	if ((lsapic->flags & LSAPIC_PRESENT) == 0)
-		return;
+	return rsdp_phys;
+}
 
-	printk("      CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
 
-	if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
-		printk("Disabled.\n");
-		add = 0;
-	} else if (lsapic->flags & LSAPIC_PERFORMANCE_RESTRICTED) {
-		printk("Performance Restricted; ignoring.\n");
-		add = 0;
-	}
+int __init
+acpi_boot_init (char *cmdline)
+{
+	int result;
 
-#ifdef CONFIG_SMP
-	smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
-	if (add) {
-		printk("Available.\n");
-		available_cpus++;
-#ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
-#endif /* CONFIG_SMP */
+	/* Initialize the ACPI boot-time table parser */
+	result = acpi_table_init(cmdline);
+	if (result)
+		return result;
+
+	/*
+	 * MADT
+	 * ----
+	 * Parse the Multiple APIC Description Table (MADT), if exists.
+	 * Note that this table provides platform SMP configuration
+	 * information -- the successor to MPS tables.
+	 */
+
+	if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
+		printk(KERN_ERR PREFIX "Can't find MADT\n");
+		goto skip_madt;
 	}
-	total_cpus++;
-}
 
-/*
- * Info on platform interrupt sources: NMI. PMI, INIT, etc.
- */
-static void __init
-acpi_platform (char *p)
-{
-	acpi_entry_platform_src_t *plat = (acpi_entry_platform_src_t *) p;
+	/* Local APIC */
 
-	printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n",
-	       plat->iosapic_vector, plat->global_vector, plat->eid, plat->id);
-}
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
+				  acpi_parse_lapic_addr_ovr) < 0)
+		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
-/*
- * Parse the ACPI Multiple SAPIC Table
- */
-static void __init
-acpi_parse_msapic (acpi_sapic_t *msapic)
-{
-	acpi_entry_iosapic_t *iosapic;
-	char *p, *end;
+	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC,
+				  acpi_parse_lsapic) < 1)
+		printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
 
-	/* Base address of IPI Message Block */
-	ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0);
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI,
+				  acpi_parse_lapic_nmi) < 0)
+		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 
-	p = (char *) (msapic + 1);
-	end = p + (msapic->header.length - sizeof(acpi_sapic_t));
+	/* I/O APIC */
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI_ENTRY_LOCAL_SAPIC:
-			acpi_lsapic(p);
-			break;
-
-		      case ACPI_ENTRY_IO_SAPIC:
-			iosapic = (acpi_entry_iosapic_t *) p;
-			if (iosapic_init)
-				/*
-				 * The ACPI I/O SAPIC table doesn't have a PCAT_COMPAT
-				 * flag like the MADT table, but we can safely assume that
-				 * ACPI 1.0b systems have a dual-8259 setup.
-				 */
-				iosapic_init(iosapic->address, iosapic->irq_base, 1);
-			break;
-
-		      case ACPI_ENTRY_INT_SRC_OVERRIDE:
-			acpi_legacy_irq(p);
-			break;
-
-		      case ACPI_ENTRY_PLATFORM_INT_SOURCE:
-			acpi_platform(p);
-			break;
+	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC,
+				  acpi_parse_iosapic) < 1)
+		printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n");
 
-		      default:
-			break;
-		}
+	/* System-Level Interrupt Routing */
 
-		/* Move to next table entry. */
-		p += p[1];
-	}
+	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
+				  acpi_parse_plat_int_src) < 0)
+		printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
+
+	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR,
+				  acpi_parse_int_src_ovr) < 0)
+		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
 
-	/* Make bootup pretty */
-	printk("      %d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC,
+				  acpi_parse_nmi_src) < 0)
+		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
+skip_madt:
+
+	/*
+	 * The FADT table contains an SCI_INT line, by which the system
+	 * gets interrupts such as power and sleep buttons.  If it's not
+	 * on a Legacy interrupt, it needs to be setup.
+	 */
+	if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
+		printk(KERN_ERR PREFIX "Can't find FADT\n");
+
+#ifdef CONFIG_SERIAL_ACPI
+	acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);
+#endif
+
+#ifdef CONFIG_SMP
+	if (available_cpus == 0) {
+		printk("ACPI: Found 0 CPUS; assuming 1\n");
+		available_cpus = 1; /* We've got at least one of these, no? */
+	}
+	smp_boot_data.cpu_count = total_cpus;
+#endif
+	/* Make boot-up look pretty */
+	printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	return 0;
 }
 
+
+/* --------------------------------------------------------------------------
+                             PCI Interrupt Routing
+   -------------------------------------------------------------------------- */
+
 int __init
-acpi_parse (acpi_rsdp_t *rsdp)
+acpi_get_prt (struct pci_vector_struct **vectors, int *count)
 {
-# ifdef CONFIG_ACPI
-	acpi_rsdt_t *rsdt;
-	acpi_desc_table_hdr_t *hdrp;
-	long tables, i;
+	struct pci_vector_struct *vector;
+	struct list_head *node;
+	struct acpi_prt_entry *entry;
+	int i = 0;
 
-	if (strncmp(rsdp->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) {
-		printk("Uh-oh, ACPI RSDP signature incorrect!\n");
-		return 0;
-	}
+	if (!vectors || !count)
+		return -EINVAL;
 
-	rsdt = __va(rsdp->rsdt);
-	if (strncmp(rsdt->header.signature, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN)) {
-		printk("Uh-oh, ACPI RDST signature incorrect!\n");
-		return 0;
+	*vectors = NULL;
+	*count = 0;
+
+	if (acpi_prt.count < 0) {
+		printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n");
+		return -ENODEV;
 	}
 
-	printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id,
-	       rsdt->header.oem_revision >> 16, rsdt->header.oem_revision & 0xffff);
+	/* Allocate vectors */
 
-	acpi_cf_init(rsdp);
+	*vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);
+	if (!(*vectors))
+		return -ENOMEM;
 
-	tables = (rsdt->header.length - sizeof(acpi_desc_table_hdr_t)) / 8;
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(rsdt->entry_ptrs[i]);
+	/* Convert PRT entries to IOSAPIC PCI vectors */
 
-		/* Only interested int the MSAPIC table for now ... */
-		if (strncmp(hdrp->signature, ACPI_SAPIC_SIG, ACPI_SAPIC_SIG_LEN) != 0)
-			continue;
+	vector = *vectors;
 
-		acpi_parse_msapic((acpi_sapic_t *) hdrp);
+	list_for_each(node, &acpi_prt.entries) {
+		entry = (struct acpi_prt_entry *)node;
+		vector[i].segment = entry->id.segment;
+		vector[i].bus    = entry->id.bus;
+		vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
+		vector[i].pin    = entry->pin;
+		vector[i].irq    = entry->link.index;
+		i++;
 	}
+	*count = acpi_prt.count;
+	return 0;
+}
 
-	acpi_cf_terminate();
+/* Assume IA64 always use I/O SAPIC */
 
-#  ifdef CONFIG_SMP
-	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
-		available_cpus = 1; /* We've got at least one of these, no? */
-	}
-	smp_boot_data.cpu_count = total_cpus;
-#  endif
-# endif /* CONFIG_ACPI */
-	return 1;
+int __init
+acpi_get_interrupt_model (int *type)
+{
+        if (!type)
+                return -EINVAL;
+
+	*type = ACPI_IRQ_MODEL_IOSAPIC;
+        return 0;
+}
+
+int
+acpi_irq_to_vector (u32 irq)
+{
+	if (has_8259 && irq < 16)
+		return isa_irq_to_vector(irq);
+
+	return gsi_to_vector(irq);
 }
+
+#endif /* CONFIG_ACPI_BOOT */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efi.c linux-2.4.20/arch/ia64/kernel/efi.c
--- linux-2.4.19/arch/ia64/kernel/efi.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/efi.c	2002-10-04 00:41:10.000000000 +0000
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2001 Hewlett-Packard Co.
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -24,8 +24,8 @@
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/proc_fs.h>
+#include <linux/efi.h>
 
-#include <asm/efi.h>
 #include <asm/io.h>
 #include <asm/kregs.h>
 #include <asm/pgtable.h>
@@ -125,9 +125,79 @@
 	tv->tv_usec = tm.nanosecond / 1000;
 }
 
+static int
+is_available_memory (efi_memory_desc_t *md)
+{
+	if (!(md->attribute & EFI_MEMORY_WB))
+		return 0;
+
+	switch (md->type) {
+	      case EFI_LOADER_CODE:
+	      case EFI_LOADER_DATA:
+	      case EFI_BOOT_SERVICES_CODE:
+	      case EFI_BOOT_SERVICES_DATA:
+	      case EFI_CONVENTIONAL_MEMORY:
+		return 1;
+	}
+	return 0;
+}
+
 /*
- * Walks the EFI memory map and calls CALLBACK once for each EFI
- * memory descriptor that has memory that is available for OS use.
+ * Trim descriptor MD so its starts at address START_ADDR.  If the descriptor covers
+ * memory that is normally available to the kernel, issue a warning that some memory
+ * is being ignored.
+ */
+static void
+trim_bottom (efi_memory_desc_t *md, u64 start_addr)
+{
+	u64 num_skipped_pages;
+
+	if (md->phys_addr >= start_addr || !md->num_pages)
+		return;
+
+	num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
+	if (num_skipped_pages > md->num_pages)
+		num_skipped_pages = md->num_pages;
+
+	if (is_available_memory(md))
+		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+		       "at 0x%lx\n", __FUNCTION__,
+		       (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
+		       md->phys_addr, start_addr - IA64_GRANULE_SIZE);
+	/*
+	 * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
+	 * descriptor list to become unsorted.  In such a case, md->num_pages will be
+	 * zero, so the Right Thing will happen.
+	 */
+	md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
+	md->num_pages -= num_skipped_pages;
+}
+
+static void
+trim_top (efi_memory_desc_t *md, u64 end_addr)
+{
+	u64 num_dropped_pages, md_end_addr;
+
+	md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+	if (md_end_addr <= end_addr || !md->num_pages)
+		return;
+
+	num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
+	if (num_dropped_pages > md->num_pages)
+		num_dropped_pages = md->num_pages;
+
+	if (is_available_memory(md))
+		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+		       "at 0x%lx\n", __FUNCTION__,
+		       (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
+		       md->phys_addr, end_addr);
+	md->num_pages -= num_dropped_pages;
+}
+
+/*
+ * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
+ * has memory that is available for OS use.
  */
 void
 efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
@@ -137,9 +207,9 @@
 		u64 start;
 		u64 end;
 	} prev, curr;
-	void *efi_map_start, *efi_map_end, *p;
-	efi_memory_desc_t *md;
-	u64 efi_desc_size, start, end;
+	void *efi_map_start, *efi_map_end, *p, *q;
+	efi_memory_desc_t *md, *check_md;
+	u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0;
 
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
 	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -147,27 +217,59 @@
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
 		md = p;
-		switch (md->type) {
-		      case EFI_LOADER_CODE:
-		      case EFI_LOADER_DATA:
-		      case EFI_BOOT_SERVICES_CODE:
-		      case EFI_BOOT_SERVICES_DATA:
-		      case EFI_CONVENTIONAL_MEMORY:
-			if (!(md->attribute & EFI_MEMORY_WB))
-				continue;
-			if (md->phys_addr + (md->num_pages << 12) > mem_limit) {
+
+		/* skip over non-WB memory descriptors; that's all we're interested in... */
+		if (!(md->attribute & EFI_MEMORY_WB))
+			continue;
+
+		if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) {
+			/*
+			 * Search for the next run of contiguous WB memory.  Start search
+			 * at first granule boundary covered by md.
+			 */
+			granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1)
+					& -IA64_GRANULE_SIZE);
+			first_non_wb_addr = granule_addr;
+			for (q = p; q < efi_map_end; q += efi_desc_size) {
+				check_md = q;
+
+				if (check_md->attribute & EFI_MEMORY_WB)
+					trim_bottom(md, granule_addr);
+
+				if (check_md->phys_addr < granule_addr)
+					continue;
+
+				if (!(check_md->attribute & EFI_MEMORY_WB))
+					break;	/* hit a non-WB region; stop search */
+
+				if (check_md->phys_addr != first_non_wb_addr)
+					break;	/* hit a memory hole; stop search */
+
+				first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
+			}
+			/* round it down to the previous granule-boundary: */
+			first_non_wb_addr &= -IA64_GRANULE_SIZE;
+
+			if (!(first_non_wb_addr > granule_addr))
+				continue;	/* couldn't find enough contiguous memory */
+		}
+
+		/* BUG_ON((md->phys_addr >> IA64_GRANULE_SHIFT) < first_non_wb_addr); */
+
+		trim_top(md, first_non_wb_addr);
+
+		if (is_available_memory(md)) {
+			if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
 				if (md->phys_addr > mem_limit)
 					continue;
-				md->num_pages = (mem_limit - md->phys_addr) >> 12;
+				md->num_pages = (mem_limit - md->phys_addr) >> EFI_PAGE_SHIFT;
 			}
-			if (md->num_pages == 0) {
-				printk("efi_memmap_walk: ignoring empty region at 0x%lx",
-				       md->phys_addr);
+
+			if (md->num_pages == 0)
 				continue;
-			}
 
 			curr.start = PAGE_OFFSET + md->phys_addr;
-			curr.end   = curr.start + (md->num_pages << 12);
+			curr.end   = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
 
 			if (!prev_valid) {
 				prev = curr;
@@ -187,10 +289,6 @@
 					prev = curr;
 				}
 			}
-			break;
-
-		      default:
-			continue;
 		}
 	}
 	if (prev_valid) {
@@ -212,8 +310,8 @@
 	void *efi_map_start, *efi_map_end, *p;
 	efi_memory_desc_t *md;
 	u64 efi_desc_size;
-	int pal_code_count=0;
-	u64 mask, flags;
+	int pal_code_count = 0;
+	u64 mask, psr;
 	u64 vaddr;
 
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
@@ -250,25 +348,26 @@
 		 * dedicated ITR for the PAL code.
 		 */
 		if ((vaddr & mask) == (KERNEL_START & mask)) {
-			printk(__FUNCTION__ ": no need to install ITR for PAL code\n");
+			printk("%s: no need to install ITR for PAL code\n", __FUNCTION__);
 			continue;
 		}
 
-		if (md->num_pages << 12 > IA64_GRANULE_SIZE)
+		if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE)
 			panic("Woah!  PAL code size bigger than a granule!");
 
 		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
 		printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
-		       smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << 12),
+		       smp_processor_id(), md->phys_addr,
+		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
 
 		/*
 		 * Cannot write to CRx with PSR.ic=1
 		 */
-		ia64_clear_ic(flags);
+		psr = ia64_clear_ic();
 		ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
 			 pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), IA64_GRANULE_SHIFT);
-		local_irq_restore(flags);
+		ia64_set_psr(psr);		/* restore psr */
 		ia64_srlz_i();
 	}
 }
@@ -378,7 +477,8 @@
 			md = p;
 			printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
 			       i, md->type, md->attribute, md->phys_addr,
-			       md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
+			       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
+			       md->num_pages >> (20 - EFI_PAGE_SHIFT));
 		}
 	}
 #endif
@@ -485,8 +585,50 @@
 	return 0;
 }
 
+u32
+efi_mem_type (unsigned long phys_addr)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+
+		if ((md->phys_addr <= phys_addr) && (phys_addr <=
+		    (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1)))
+			 return md->type;
+	}
+	return 0;
+}
+
+u64
+efi_mem_attributes (unsigned long phys_addr)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+
+		if ((md->phys_addr <= phys_addr) && (phys_addr <=
+		    (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1)))
+			return md->attribute;
+	}
+	return 0;
+}
+
 static void __exit
-efivars_exit(void)
+efivars_exit (void)
 {
 #ifdef CONFIG_PROC_FS
  	remove_proc_entry(efi_dir->name, NULL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efi_stub.S linux-2.4.20/arch/ia64/kernel/efi_stub.S
--- linux-2.4.19/arch/ia64/kernel/efi_stub.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/efi_stub.S	2002-10-04 00:41:09.000000000 +0000
@@ -53,23 +53,21 @@
 	mov loc4=ar.rsc			// save RSE configuration
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	;;
-
 	ld8 gp=[in0]			// load EFI function's global pointer
-	mov out0=in1
-	mov out1=in2
 	movl r16=PSR_BITS_TO_CLEAR
-
 	mov loc3=psr			// save processor status word
 	movl r17=PSR_BITS_TO_SET
 	;;
-	mov out2=in3
 	or loc3=loc3,r17
 	mov b6=r2
 	;;
 	andcm r16=loc3,r16		// get psr with IT, DT, and RT bits cleared
-	mov out3=in4
 	br.call.sptk.many rp=ia64_switch_mode
 .ret0:	mov out4=in5
+	mov out0=in1
+	mov out1=in2
+	mov out2=in3
+	mov out3=in4
 	mov out5=in6
 	mov out6=in7
 	br.call.sptk.many rp=b6		// call the EFI function
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efivars.c linux-2.4.20/arch/ia64/kernel/efivars.c
--- linux-2.4.19/arch/ia64/kernel/efivars.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/efivars.c	2002-10-04 00:41:19.000000000 +0000
@@ -29,6 +29,9 @@
  *
  * Changelog:
  *
+ *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
+ *
  *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
  *   use list_for_each_safe when deleting vars.
  *   remove ifdef CONFIG_SMP around include <linux/smp.h>
@@ -62,15 +65,15 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/smp.h>
+#include <linux/efi.h>
 
-#include <asm/efi.h>
 #include <asm/uaccess.h>
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 MODULE_DESCRIPTION("/proc interface to EFI Variables");
 MODULE_LICENSE("GPL");
 
-#define EFIVARS_VERSION "0.04 2002-Feb-12"
+#define EFIVARS_VERSION "0.05 2002-Mar-26"
 
 static int
 efivar_read(char *page, char **start, off_t off,
@@ -141,20 +144,6 @@
 	return len;
 }
 
-
-static void
-uuid_unparse(efi_guid_t *guid, char *out)
-{
-	sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-		guid->data1, guid->data2, guid->data3,
-		guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3],
-		guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
-}
-
-
-
-
-
 /*
  * efivar_create_proc_entry()
  * Requires:
@@ -197,7 +186,7 @@
 	   private variables from another's.         */
 
 	*(short_name + strlen(short_name)) = '-';
-	uuid_unparse(vendor_guid, short_name + strlen(short_name));
+	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
 
 
 	/* Create the entry in proc */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/entry.S linux-2.4.20/arch/ia64/kernel/entry.S
--- linux-2.4.19/arch/ia64/kernel/entry.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/entry.S	2002-10-04 00:41:14.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * Kernel entry points.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -667,23 +667,38 @@
 	/*
 	 * To prevent leaking bits between the kernel and user-space,
 	 * we must clear the stacked registers in the "invalid" partition here.
-	 * Not pretty, but at least it's fast (3.34 registers/cycle).
-	 * Architecturally, this loop could go at 4.67 registers/cycle, but that would
-	 * oversubscribe Itanium.
+	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
+	 * 5 registers/cycle on McKinley).
 	 */
 #	define pRecurse	p6
 #	define pReturn	p7
+#ifdef CONFIG_ITANIUM
 #	define Nregs	10
+#else
+#	define Nregs	14
+#endif
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
 	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
 	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
 	;;
+#if 1
+	.align 32		// see comment below about gas bug...
+#endif
 	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
 	shladd in0=loc1,3,r17
 	mov in1=0
+#if 0
+	// gas-2.11.90 is unable to generate a stop bit after .align, which is bad,
+	// because alloc must be at the beginning of an insn-group.
+	.align 32
+#else
+	nop 0
+	nop 0
+	nop 0
+#endif
 	;;
-//	.align 32	// gas-2.11.90 is unable to generate a stop bit after .align
 rse_clear_invalid:
+#ifdef CONFIG_ITANIUM
 	// cycle 0
  { .mii
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
@@ -712,9 +727,31 @@
 	mov loc7=0
 (pReturn) br.ret.sptk.many b6
 }
+#else /* !CONFIG_ITANIUM */
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
+	add out0=-Nregs*8,in0
+	add out1=1,in1			// increment recursion count
+	mov loc1=0
+	mov loc2=0
+	;;
+	mov loc3=0
+	mov loc4=0
+	mov loc9=0
+	mov loc5=0
+	mov loc6=0
+(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+	;;
+	mov loc7=0
+	mov loc8=0
+	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
+	mov loc10=0
+	mov loc11=0
+(pReturn) br.ret.sptk.many b6
+#endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
-
+	;;
 	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
 	;;
 	loadrs
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/fw-emu.c linux-2.4.20/arch/ia64/kernel/fw-emu.c
--- linux-2.4.19/arch/ia64/kernel/fw-emu.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/fw-emu.c	2002-10-04 00:41:10.000000000 +0000
@@ -13,14 +13,16 @@
 # include <linux/pci.h>
 #endif
 
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/io.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
 
 #define MB	(1024*1024UL)
+#define GB	(1024*MB)
+#define TB	(1024*GB)
 
-#define NUM_MEM_DESCS	3
+#define NUM_MEM_DESCS	4
 
 static char fw_mem[(  sizeof(struct ia64_boot_param)
 		    + sizeof(efi_system_table_t)
@@ -471,7 +473,7 @@
 	md->phys_addr = 0*MB;
 	md->virt_addr = 0;
 	md->num_pages = (1*MB) >> 12;	/* 1MB (in 4KB pages) */
-	md->attribute = EFI_MEMORY_WB;
+	md->attribute = EFI_MEMORY_WB | EFI_MEMORY_WC | EFI_MEMORY_UC;
 
 	/* fill in a memory descriptor: */
 	md = &efi_memmap[1];
@@ -489,23 +491,16 @@
 	md->phys_addr = 1*MB;
 	md->virt_addr = 1*MB;
 	md->num_pages = (1*MB) >> 12;	/* 1MB (in 4KB pages) */
-	md->attribute = EFI_MEMORY_WB;
-
-#if 0
-	/*
-	 * XXX bootmem is broken for now... (remember to NUM_MEM_DESCS
-	 * if you re-enable this!)
-	 */
+	md->attribute = EFI_MEMORY_WB | EFI_MEMORY_WC | EFI_MEMORY_UC;
 
-	/* descriptor for high memory (>4GB): */
+	/* descriptor for high memory (>4TB): */
 	md = &efi_memmap[3];
 	md->type = EFI_CONVENTIONAL_MEMORY;
 	md->pad = 0;
-	md->phys_addr = 4096*MB;
+	md->phys_addr = 4*TB;
 	md->virt_addr = 0;
-	md->num_pages = (32*MB) >> 12;	/* 32MB (in 4KB pages) */
+	md->num_pages = (64*MB) >> 12;	/* 64MB (in 4KB pages) */
 	md->attribute = EFI_MEMORY_WB;
-#endif
 
 	bp->efi_systab = __pa(&fw_mem);
 	bp->efi_memmap = __pa(efi_memmap);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/gate.S linux-2.4.20/arch/ia64/kernel/gate.S
--- linux-2.4.19/arch/ia64/kernel/gate.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/gate.S	2002-10-04 00:41:14.000000000 +0000
@@ -29,7 +29,7 @@
 #	define UNAT_OFF		IA64_SIGCONTEXT_AR_UNAT_OFFSET
 #	define FPSR_OFF		IA64_SIGCONTEXT_AR_FPSR_OFFSET
 #	define PR_OFF		IA64_SIGCONTEXT_PR_OFFSET
-#	define RP_OFF		IA64_SIGCONTEXT_B0_OFFSET
+#	define RP_OFF		IA64_SIGCONTEXT_IP_OFFSET
 #	define SP_OFF		IA64_SIGCONTEXT_R12_OFFSET
 #	define RBS_BASE_OFF	IA64_SIGCONTEXT_RBS_BASE_OFFSET
 #	define LOADRS_OFF	IA64_SIGCONTEXT_LOADRS_OFFSET
@@ -108,7 +108,7 @@
 	dep r8=0,r8,38,26			// clear EC0, CPL0 and reserved bits
 	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
 	;;
-	.spillsp ar.pfs, CFM_OFF
+	.spillsp ar.pfs, CFM_OFF+SIGCONTEXT_OFF
 	st8 [base0]=r8				// save CFM0
 	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
 	;;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/head.S linux-2.4.20/arch/ia64/kernel/head.S
--- linux-2.4.19/arch/ia64/kernel/head.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/head.S	2002-10-04 00:41:22.000000000 +0000
@@ -562,137 +562,114 @@
 END(__ia64_load_fpu)
 
 GLOBAL_ENTRY(__ia64_init_fpu)
-	alloc r2=ar.pfs,0,0,0,0
-	stf.spill [sp]=f0
-	mov      f32=f0
-	;;
-	ldf.fill f33=[sp]
-	ldf.fill f34=[sp]
-	mov      f35=f0
-	;;
-	ldf.fill f36=[sp]
-	ldf.fill f37=[sp]
-	mov      f38=f0
-	;;
-	ldf.fill f39=[sp]
-	ldf.fill f40=[sp]
-	mov      f41=f0
-	;;
-	ldf.fill f42=[sp]
-	ldf.fill f43=[sp]
-	mov      f44=f0
-	;;
-	ldf.fill f45=[sp]
-	ldf.fill f46=[sp]
-	mov      f47=f0
-	;;
-	ldf.fill f48=[sp]
-	ldf.fill f49=[sp]
-	mov      f50=f0
-	;;
-	ldf.fill f51=[sp]
-	ldf.fill f52=[sp]
-	mov      f53=f0
-	;;
-	ldf.fill f54=[sp]
-	ldf.fill f55=[sp]
-	mov      f56=f0
-	;;
-	ldf.fill f57=[sp]
-	ldf.fill f58=[sp]
-	mov      f59=f0
-	;;
-	ldf.fill f60=[sp]
-	ldf.fill f61=[sp]
-	mov      f62=f0
-	;;
-	ldf.fill f63=[sp]
-	ldf.fill f64=[sp]
-	mov      f65=f0
-	;;
-	ldf.fill f66=[sp]
-	ldf.fill f67=[sp]
-	mov      f68=f0
-	;;
-	ldf.fill f69=[sp]
-	ldf.fill f70=[sp]
-	mov      f71=f0
-	;;
-	ldf.fill f72=[sp]
-	ldf.fill f73=[sp]
-	mov      f74=f0
-	;;
-	ldf.fill f75=[sp]
-	ldf.fill f76=[sp]
-	mov      f77=f0
-	;;
-	ldf.fill f78=[sp]
-	ldf.fill f79=[sp]
-	mov      f80=f0
-	;;
-	ldf.fill f81=[sp]
-	ldf.fill f82=[sp]
-	mov      f83=f0
-	;;
-	ldf.fill f84=[sp]
-	ldf.fill f85=[sp]
-	mov      f86=f0
-	;;
-	ldf.fill f87=[sp]
-	ldf.fill f88=[sp]
-	mov      f89=f0
-	;;
-	ldf.fill f90=[sp]
-	ldf.fill f91=[sp]
-	mov      f92=f0
-	;;
-	ldf.fill f93=[sp]
-	ldf.fill f94=[sp]
-	mov      f95=f0
-	;;
-	ldf.fill f96=[sp]
-	ldf.fill f97=[sp]
-	mov      f98=f0
-	;;
-	ldf.fill f99=[sp]
-	ldf.fill f100=[sp]
-	mov      f101=f0
-	;;
-	ldf.fill f102=[sp]
-	ldf.fill f103=[sp]
-	mov      f104=f0
-	;;
-	ldf.fill f105=[sp]
-	ldf.fill f106=[sp]
-	mov      f107=f0
-	;;
-	ldf.fill f108=[sp]
-	ldf.fill f109=[sp]
-	mov      f110=f0
-	;;
-	ldf.fill f111=[sp]
-	ldf.fill f112=[sp]
-	mov      f113=f0
-	;;
-	ldf.fill f114=[sp]
-	ldf.fill f115=[sp]
-	mov      f116=f0
-	;;
-	ldf.fill f117=[sp]
-	ldf.fill f118=[sp]
-	mov      f119=f0
-	;;
-	ldf.fill f120=[sp]
-	ldf.fill f121=[sp]
-	mov      f122=f0
-	;;
-	ldf.fill f123=[sp]
-	ldf.fill f124=[sp]
-	mov      f125=f0
-	;;
-	ldf.fill f126=[sp]
-	mov      f127=f0
-	br.ret.sptk.many rp
+	stf.spill [sp]=f0		// M3
+	mov	 f32=f0			// F
+	nop.b	 0
+
+	ldfps	 f33,f34=[sp]		// M0
+	ldfps	 f35,f36=[sp]		// M1
+	mov      f37=f0			// F
+	;;
+
+	setf.s	 f38=r0			// M2
+	setf.s	 f39=r0			// M3
+	mov      f40=f0			// F
+
+	ldfps	 f41,f42=[sp]		// M0
+	ldfps	 f43,f44=[sp]		// M1
+	mov      f45=f0			// F
+
+	setf.s	 f46=r0			// M2
+	setf.s	 f47=r0			// M3
+	mov      f48=f0			// F
+
+	ldfps	 f49,f50=[sp]		// M0
+	ldfps	 f51,f52=[sp]		// M1
+	mov      f53=f0			// F
+
+	setf.s	 f54=r0			// M2
+	setf.s	 f55=r0			// M3
+	mov      f56=f0			// F
+
+	ldfps	 f57,f58=[sp]		// M0
+	ldfps	 f59,f60=[sp]		// M1
+	mov      f61=f0			// F
+
+	setf.s	 f62=r0			// M2
+	setf.s	 f63=r0			// M3
+	mov      f64=f0			// F
+
+	ldfps	 f65,f66=[sp]		// M0
+	ldfps	 f67,f68=[sp]		// M1
+	mov      f69=f0			// F
+
+	setf.s	 f70=r0			// M2
+	setf.s	 f71=r0			// M3
+	mov      f72=f0			// F
+
+	ldfps	 f73,f74=[sp]		// M0
+	ldfps	 f75,f76=[sp]		// M1
+	mov      f77=f0			// F
+
+	setf.s	 f78=r0			// M2
+	setf.s	 f79=r0			// M3
+	mov      f80=f0			// F
+
+	ldfps	 f81,f82=[sp]		// M0
+	ldfps	 f83,f84=[sp]		// M1
+	mov      f85=f0			// F
+
+	setf.s	 f86=r0			// M2
+	setf.s	 f87=r0			// M3
+	mov      f88=f0			// F
+
+	/*
+	 * When the instructions are cached, it would be faster to initialize
+	 * the remaining registers with simply mov instructions (F-unit).
+	 * This gets the time down to ~29 cycles.  However, this would use up
+	 * 33 bundles, whereas continuing with the above pattern yields
+	 * 10 bundles and ~30 cycles.
+	 */
+
+	ldfps	 f89,f90=[sp]		// M0
+	ldfps	 f91,f92=[sp]		// M1
+	mov      f93=f0			// F
+
+	setf.s	 f94=r0			// M2
+	setf.s	 f95=r0			// M3
+	mov      f96=f0			// F
+
+	ldfps	 f97,f98=[sp]		// M0
+	ldfps	 f99,f100=[sp]		// M1
+	mov      f101=f0		// F
+
+	setf.s	 f102=r0		// M2
+	setf.s	 f103=r0		// M3
+	mov      f104=f0		// F
+
+	ldfps	 f105,f106=[sp]		// M0
+	ldfps	 f107,f108=[sp]		// M1
+	mov      f109=f0		// F
+
+	setf.s	 f110=r0		// M2
+	setf.s	 f111=r0		// M3
+	mov      f112=f0		// F
+
+	ldfps	 f113,f114=[sp]		// M0
+	ldfps	 f115,f116=[sp]		// M1
+	mov      f117=f0		// F
+
+	setf.s	 f118=r0		// M2
+	setf.s	 f119=r0		// M3
+	mov      f120=f0		// F
+
+	ldfps	 f121,f122=[sp]		// M0
+	ldfps	 f123,f124=[sp]		// M1
+	mov      f125=f0		// F
+
+	setf.s	 f126=r0		// M2
+	setf.s	 f127=r0		// M3
+	br.ret.sptk.many rp		// F
 END(__ia64_init_fpu)
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/ia64_ksyms.c linux-2.4.20/arch/ia64/kernel/ia64_ksyms.c
--- linux-2.4.19/arch/ia64/kernel/ia64_ksyms.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/ia64_ksyms.c	2002-10-04 00:41:19.000000000 +0000
@@ -1,11 +1,11 @@
 /*
  * Architecture-specific kernel symbols
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/string.h>
+
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcmp);
@@ -148,3 +148,10 @@
 #include <linux/proc_fs.h>
 extern struct proc_dir_entry *efi_dir;
 EXPORT_SYMBOL(efi_dir);
+
+#include <asm/machvec.h>
+#ifdef CONFIG_IA64_GENERIC
+EXPORT_SYMBOL(ia64_mv);
+#endif
+EXPORT_SYMBOL(machvec_noop);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/iosapic.c linux-2.4.20/arch/ia64/kernel/iosapic.c
--- linux-2.4.19/arch/ia64/kernel/iosapic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/iosapic.c	2002-10-04 00:41:19.000000000 +0000
@@ -22,30 +22,44 @@
  * 02/01/07     E. Focht        <efocht@ess.nec.de> Redirectable interrupt vectors in
  *                              iosapic_set_affinity(), initializations for
  *                              /proc/irq/#/smp_affinity
+ * 02/04/02	P. Diefenbaugh	Cleaned up ACPI PCI IRQ routing.
+ * 02/04/18	J.I. Lee	bug fix in iosapic_init_pci_irq
+ * 02/04/30	J.I. Lee	bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping error
+ * 02/07/29	T. Kochi	Allocate interrupt vectors dynamically
+ * 02/08/04	T. Kochi	Cleaned up terminology (irq, global system interrupt, vector, etc.)
+ * 02/08/13	B. Helgaas	Support PCI segments
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
  *
  * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD).  The
- *     device is uniquely identified by its bus--, and slot-number (the function
+ *     device is uniquely identified by its segment--, bus--, and slot-number (the function
  *     number does not matter here because all functions share the same interrupt
  *     lines).
  *
  * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller.
  *     Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level
- *     triggered and use the same polarity).  Each interrupt line has a unique IOSAPIC
- *     irq number which can be calculated as the sum of the controller's base irq number
- *     and the IOSAPIC pin number to which the line connects.
+ *     triggered and use the same polarity).  Each interrupt line has a unique Global
+ *     System Interrupt (GSI) number which can be calculated as the sum of the controller's
+ *     base GSI number and the IOSAPIC pin number to which the line connects.
  *
- * (3) The IOSAPIC uses an internal table to map the IOSAPIC pin into the IA-64 interrupt
- *     vector.  This interrupt vector is then sent to the CPU.
+ * (3) The IOSAPIC uses internal routing table entries (RTEs) to map the IOSAPIC pin
+ *     to the IA-64 interrupt vector.  This interrupt vector is then sent to the CPU.
  *
- * In other words, there are two levels of indirections involved:
+ * (4) The kernel recognizes an interrupt as an IRQ.  The IRQ interface
+ *     is an architecture-independent interrupt handling mechanism in
+ *     Linux.  An IRQ is a number, so we need a mapping between IRQ
+ *     numbers and IA-64 vectors.  The platform_irq_to_vector(irq) and
+ *     platform_local_vector_to_irq(vector) APIs can define platform-
+ *     specific mappings.
  *
- *	pci pin -> iosapic irq -> IA-64 vector
+ * To sum up, there are three levels of mappings involved:
  *
- * Note: outside this module, IA-64 vectors are called "irqs".  This is because that's
- * the traditional name Linux uses for interrupt vectors.
+ *	PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
+ *
+ * Note: The term "IRQ" is loosely used everywhere in the Linux kernel
+ * to describe interrupts.  In this module, "IRQ" refers only to Linux
+ * IRQ numbers ("isa_irq" is an exception to this rule).
  */
 #include <linux/config.h>
 
@@ -56,9 +70,8 @@
 #include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/irq.h>
+#include <linux/acpi.h>
 
-#include <asm/acpi-ext.h>
-#include <asm/acpikcfg.h>
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
 #include <asm/io.h>
@@ -69,80 +82,103 @@
 #include <asm/system.h>
 
 
-#undef DEBUG_IRQ_ROUTING
-#undef	OVERRIDE_DEBUG
+#undef DEBUG_INTERRUPT_ROUTING
+#undef OVERRIDE_DEBUG
+
+#ifdef DEBUG_INTERRUPT_ROUTING
+#define DBG(fmt...)	printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
 
 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
-/* PCI pin to IOSAPIC irq routing information.  This info typically comes from ACPI. */
+/* PCI pin to GSI routing information.  This info typically comes from ACPI. */
 
 static struct {
 	int num_routes;
 	struct pci_vector_struct *route;
 } pci_irq;
 
-/* This tables maps IA-64 vectors to the IOSAPIC pin that generates this vector. */
+/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
+
+static struct iosapic_intr_info {
+	char		*addr;		/* base address of IOSAPIC */
+	unsigned int	gsi_base;	/* first GSI assigned to this IOSAPIC */
+	char		rte_index;	/* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
+	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
+	unsigned char 	polarity: 1;	/* interrupt polarity (see iosapic.h) */
+	unsigned char	trigger	: 1;	/* trigger mode (see iosapic.h) */
+} iosapic_intr_info[IA64_NUM_VECTORS];
+
+static struct iosapic {
+	char		*addr;		/* base address of IOSAPIC */
+	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
+	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
+	unsigned char	pcat_compat;	/* 8259 compatibility flag */
+} iosapic_lists[256] __devinitdata;
+
+static int __devinitdata num_iosapic = 0;
 
-static struct iosapic_irq {
-	char *addr;			/* base address of IOSAPIC */
-	unsigned char base_irq;		/* first irq assigned to this IOSAPIC */
-	char pin;			/* IOSAPIC pin (-1 => not an IOSAPIC irq) */
-	unsigned char dmode	: 3;	/* delivery mode (see iosapic.h) */
-	unsigned char polarity	: 1;	/* interrupt polarity (see iosapic.h) */
-	unsigned char trigger	: 1;	/* trigger mode (see iosapic.h) */
-} iosapic_irq[IA64_NUM_VECTORS];
 
 /*
- * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector.  If no
- * entry exists, return -1.
+ * Find an IOSAPIC associated with a GSI
  */
-int
-iosapic_irq_to_vector (int irq)
+static inline int __devinit
+find_iosapic (unsigned int gsi)
 {
-	int vector;
+	int i;
 
-	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-		if (iosapic_irq[vector].base_irq + iosapic_irq[vector].pin == irq)
-			return vector;
+	for (i = 0; i < num_iosapic; i++)
+		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
+			return i;
 	return -1;
 }
 
 /*
- * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
- * return -1.
+ * Translate GSI number to the corresponding IA-64 interrupt vector.  If no
+ * entry exists, return -1.
  */
-static int
-pci_pin_to_vector (int bus, int slot, int pci_pin)
+int
+gsi_to_vector (unsigned int gsi)
 {
-	struct pci_vector_struct *r;
+	int vector;
 
-	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; ++r)
-		if (r->bus == bus && (r->pci_id >> 16) == slot && r->pin == pci_pin)
-			return iosapic_irq_to_vector(r->irq);
+	for (vector = 0; vector < IA64_NUM_VECTORS; vector++)
+		if (iosapic_intr_info[vector].gsi_base + iosapic_intr_info[vector].rte_index == gsi)
+			return vector;
 	return -1;
 }
 
 static void
-set_rte (unsigned int vector, unsigned long dest)
+set_rte (unsigned int vector, unsigned int dest)
 {
 	unsigned long pol, trigger, dmode;
 	u32 low32, high32;
 	char *addr;
-	int pin;
+	int rte_index;
 	char redir;
 
-	pin = iosapic_irq[vector].pin;
-	if (pin < 0)
+	rte_index = iosapic_intr_info[vector].rte_index;
+	if (rte_index < 0)
 		return;		/* not an IOSAPIC interrupt */
 
-	addr    = iosapic_irq[vector].addr;
-	pol     = iosapic_irq[vector].polarity;
-	trigger = iosapic_irq[vector].trigger;
-	dmode   = iosapic_irq[vector].dmode;
+	addr    = iosapic_intr_info[vector].addr;
+	pol     = iosapic_intr_info[vector].polarity;
+	trigger = iosapic_intr_info[vector].trigger;
+	dmode   = iosapic_intr_info[vector].dmode;
 
 	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
 #ifdef CONFIG_SMP
-	set_irq_affinity_info(vector, (int)(dest & 0xffff), redir);
+	{
+		int irq;
+
+		for (irq = 0; irq < NR_IRQS; ++irq)
+			if (irq_to_vector(irq) == vector) {
+				set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
+				break;
+			}
+	}
 #endif
 
 	low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
@@ -153,9 +189,9 @@
 	/* dest contains both id and eid */
 	high32 = (dest << IOSAPIC_DEST_SHIFT);
 
-	writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
+	writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
 	writel(high32, addr + IOSAPIC_WINDOW);
-	writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+	writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 	writel(low32, addr + IOSAPIC_WINDOW);
 }
 
@@ -171,18 +207,18 @@
 	unsigned long flags;
 	char *addr;
 	u32 low32;
-	int pin;
+	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vec].addr;
-	pin = iosapic_irq[vec].pin;
+	addr = iosapic_intr_info[vec].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
 
-	if (pin < 0)
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 |= (1 << IOSAPIC_MASK_SHIFT);    /* set only the mask bit */
@@ -197,17 +233,17 @@
 	unsigned long flags;
 	char *addr;
 	u32 low32;
-	int pin;
+	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vec].addr;
-	pin = iosapic_irq[vec].pin;
-	if (pin < 0)
+	addr = iosapic_intr_info[vec].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 &= ~(1 << IOSAPIC_MASK_SHIFT);    /* clear only the mask bit */
@@ -223,24 +259,28 @@
 #ifdef CONFIG_SMP
 	unsigned long flags;
 	u32 high32, low32;
-	int dest, pin;
+	int dest, rte_index;
 	char *addr;
-	int redir = (irq & (1<<31)) ? 1 : 0;
+	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
+	ia64_vector vec;
+
+	irq &= (~IA64_IRQ_REDIRECTED);
+	vec = irq_to_vector(irq);
 
 	mask &= (1UL << smp_num_cpus) - 1;
 
-	if (!mask || irq >= IA64_NUM_VECTORS)
+	if (!mask || vec >= IA64_NUM_VECTORS)
 		return;
 
 	dest = cpu_physical_id(ffz(~mask));
 
-	pin = iosapic_irq[irq].pin;
-	addr = iosapic_irq[irq].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
+	addr = iosapic_intr_info[vec].addr;
 
-	if (pin < 0)
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt */
 
-	set_irq_affinity_info(irq,dest,redir);
+	set_irq_affinity_info(irq, dest, redir);
 
 	/* dest contains both id and eid */
 	high32 = dest << IOSAPIC_DEST_SHIFT;
@@ -248,7 +288,7 @@
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
 		/* get current delivery mode by reading the low32 */
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT);
@@ -259,9 +299,9 @@
 		        /* change delivery mode to fixed */
 			low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
 
-		writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
 		writel(high32, addr + IOSAPIC_WINDOW);
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		writel(low32, addr + IOSAPIC_WINDOW);
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
@@ -284,7 +324,7 @@
 {
 	ia64_vector vec = irq_to_vector(irq);
 
-	writel(vec, iosapic_irq[vec].addr + IOSAPIC_EOI);
+	writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI);
 }
 
 #define iosapic_shutdown_level_irq	mask_irq
@@ -355,7 +395,7 @@
 	 * {
 	 *	unsigned int version   : 8;
 	 *	unsigned int reserved1 : 8;
-	 *	unsigned int pins      : 8;
+	 *	unsigned int max_redir : 8;
 	 *	unsigned int reserved2 : 8;
 	 * }
 	 */
@@ -372,69 +412,72 @@
 {
 	int new_vector;
 
-	if (iosapic_irq[vector].pin >= 0 || iosapic_irq[vector].addr
-	    || iosapic_irq[vector].base_irq || iosapic_irq[vector].dmode
-	    || iosapic_irq[vector].polarity || iosapic_irq[vector].trigger)
+	if (iosapic_intr_info[vector].rte_index >= 0 || iosapic_intr_info[vector].addr
+	    || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode
+	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
 	{
-		new_vector = ia64_alloc_irq();
-		printk("Reassigning Vector 0x%x to 0x%x\n", vector, new_vector);
-		memcpy (&iosapic_irq[new_vector], &iosapic_irq[vector],
-			sizeof(struct iosapic_irq));
-		memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq));
-		iosapic_irq[vector].pin = -1;
+		new_vector = ia64_alloc_vector();
+		printk("Reassigning Vector %d to %d\n", vector, new_vector);
+		memcpy (&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
+			sizeof(struct iosapic_intr_info));
+		memset (&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
+		iosapic_intr_info[vector].rte_index = -1;
 	}
 }
 
 static void
-register_irq (u32 global_vector, int vector, int pin, unsigned char delivery,
-	      unsigned long polarity, unsigned long edge_triggered,
-	      u32 base_irq, char *iosapic_address)
+register_intr (unsigned int gsi, int vector, unsigned char delivery,
+	       unsigned long polarity, unsigned long edge_triggered,
+	       unsigned int gsi_base, char *iosapic_address)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
+	int rte_index;
 
-	iosapic_irq[vector].pin	= pin;
-	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-	iosapic_irq[vector].dmode    = delivery;
+	rte_index = gsi - gsi_base;
+	iosapic_intr_info[vector].rte_index = rte_index;
+	iosapic_intr_info[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
+	iosapic_intr_info[vector].dmode    = delivery;
 
 	/*
-	 * In override, it does not provide addr/base_irq.  global_vector is enough to
-	 * locate iosapic addr, base_irq and pin by examining base_irq and max_pin of
-	 * registered iosapics (tbd)
+	 * In override, it may not provide addr/gsi_base.  GSI is enough to
+	 * locate iosapic addr, gsi_base and rte_index by examining
+	 * gsi_base and num_rte of registered iosapics (tbd)
 	 */
 #ifndef	OVERRIDE_DEBUG
 	if (iosapic_address) {
-		iosapic_irq[vector].addr = iosapic_address;
-		iosapic_irq[vector].base_irq = base_irq;
+		iosapic_intr_info[vector].addr = iosapic_address;
+		iosapic_intr_info[vector].gsi_base = gsi_base;
 	}
 #else
 	if (iosapic_address) {
-		if (iosapic_irq[vector].addr && (iosapic_irq[vector].addr != iosapic_address))
-			printk("WARN: register_irq: diff IOSAPIC ADDRESS for gv %x, v %x\n",
-			       global_vector, vector);
-		iosapic_irq[vector].addr = iosapic_address;
-		if (iosapic_irq[vector].base_irq && (iosapic_irq[vector].base_irq != base_irq)) {
-			printk("WARN: register_irq: diff BASE IRQ %x for gv %x, v %x\n",
-			       base_irq, global_vector, vector);
+		if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address))
+			printk("WARN: %s: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n",
+			       __FUNCTION__, gsi, vector);
+		iosapic_intr_info[vector].addr = iosapic_address;
+		if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) {
+			printk("WARN: %s: diff GSI base 0x%x for GSI 0x%x, vector %d\n",
+			       __FUNCTION__, gsi_base, gsi, vector);
 		}
-		iosapic_irq[vector].base_irq = base_irq;
-	} else if (!iosapic_irq[vector].addr)
-		printk("WARN: register_irq: invalid override for gv %x, v %x\n",
-		       global_vector, vector);
+		iosapic_intr_info[vector].gsi_base = gsi_base;
+	} else if (!iosapic_intr_info[vector].addr)
+		printk("WARN: %s: invalid override for GSI 0x%x, vector %d\n",
+		       __FUNCTION__, gsi, vector);
 #endif
 	if (edge_triggered) {
-		iosapic_irq[vector].trigger = IOSAPIC_EDGE;
+		iosapic_intr_info[vector].trigger = IOSAPIC_EDGE;
 		irq_type = &irq_type_iosapic_edge;
 	} else {
-		iosapic_irq[vector].trigger = IOSAPIC_LEVEL;
+		iosapic_intr_info[vector].trigger = IOSAPIC_LEVEL;
 		irq_type = &irq_type_iosapic_level;
 	}
 
 	idesc = irq_desc(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
-			printk("register_irq(): changing vector 0x%02x from "
-			       "%s to %s\n", vector, idesc->handler->typename, irq_type->typename);
+			printk("%s: changing vector %d from %s to %s\n",
+			       __FUNCTION__, vector, idesc->handler->typename,
+			       irq_type->typename);
 		idesc->handler = irq_type;
 	}
 }
@@ -445,24 +488,26 @@
  * program the IOSAPIC RTE.
  */
 int
-iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long
-                      edge_triggered, u32 base_irq, char *iosapic_address)
+iosapic_register_intr (unsigned int gsi,
+		       unsigned long polarity, unsigned long edge_triggered,
+		       unsigned int gsi_base, char *iosapic_address)
 {
 	int vector;
+	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
-	vector = iosapic_irq_to_vector(global_vector);
+	vector = gsi_to_vector(gsi);
 	if (vector < 0)
-		vector = ia64_alloc_irq();
+		vector = ia64_alloc_vector();
 
-	register_irq (global_vector, vector, global_vector - base_irq,
-			IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
-			base_irq, iosapic_address);
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+		      polarity, edge_triggered, gsi_base, iosapic_address);
 
-	printk("IOSAPIC 0x%x(%s,%s) -> Vector 0x%x\n", global_vector,
-	       (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), vector);
+	printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       gsi, (polarity ? "high" : "low"),
+	       (edge_triggered ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+	set_rte(vector, dest);
 	return vector;
 }
 
@@ -471,15 +516,17 @@
  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
  */
 int
-iosapic_register_platform_irq (u32 int_type, u32 global_vector,
-			       u32 iosapic_vector, u16 eid, u16 id, unsigned long polarity,
-			       unsigned long edge_triggered, u32 base_irq, char *iosapic_address)
+iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
+				int iosapic_vector, u16 eid, u16 id,
+				unsigned long polarity, unsigned long edge_triggered,
+				unsigned int gsi_base, char *iosapic_address)
 {
 	unsigned char delivery;
 	int vector;
+	unsigned int dest = ((id << 8) | eid) & 0xffff;
 
 	switch (int_type) {
-	case ACPI20_ENTRY_PIS_PMI:
+	      case ACPI_INTERRUPT_PMI:
 		vector = iosapic_vector;
 		/*
 		 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
@@ -488,223 +535,320 @@
 		iosapic_reassign_vector(vector);
 		delivery = IOSAPIC_PMI;
 		break;
-	case ACPI20_ENTRY_PIS_CPEI:
+	      case ACPI_INTERRUPT_INIT:
+		vector = ia64_alloc_vector();
+		delivery = IOSAPIC_INIT;
+		break;
+	      case ACPI_INTERRUPT_CPEI:
 		vector = IA64_PCE_VECTOR;
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
-	case ACPI20_ENTRY_PIS_INIT:
-		vector = ia64_alloc_irq();
-		delivery = IOSAPIC_INIT;
-		break;
-	default:
-		printk("iosapic_register_platform_irq(): invalid int type\n");
+	      default:
+		printk("%s: invalid interrupt type (%d)\n", __FUNCTION__,
+			int_type);
 		return -1;
 	}
 
-	register_irq(global_vector, vector, global_vector - base_irq, delivery, polarity,
-		     edge_triggered, base_irq, iosapic_address);
+	register_intr(gsi, vector, delivery, polarity,
+		      edge_triggered, gsi_base, iosapic_address);
 
-	printk("PLATFORM int 0x%x: IOSAPIC 0x%x(%s,%s) -> Vector 0x%x CPU %.02u:%.02u\n",
-	       int_type, global_vector, (polarity ? "high" : "low"),
-	       (edge_triggered ? "edge" : "level"), vector, eid, id);
+	printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       int_type, gsi, (polarity ? "high" : "low"),
+	       (edge_triggered ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, ((id << 8) | eid) & 0xffff);
+	set_rte(vector, dest);
 	return vector;
 }
 
 
 /*
- * ACPI calls this when it finds an entry for a legacy ISA interrupt.
- * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
+ * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
+ * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
  */
 void
-iosapic_register_legacy_irq (unsigned long irq,
-			     unsigned long pin, unsigned long polarity,
-			     unsigned long edge_triggered)
-{
-	int vector = isa_irq_to_vector(irq);
-
-	register_irq(irq, vector, (int)pin, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
-		     0, NULL);		/* ignored for override */
-
-#ifdef DEBUG_IRQ_ROUTING
-	printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (%s, %s) -> vector %02x\n",
-	       (unsigned) irq, (unsigned) pin,
-	       polarity ? "high" : "low", edge_triggered ? "edge" : "level",
-	       vector);
-#endif
+iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
+			  unsigned long polarity, unsigned long edge_triggered)
+{
+	int index, vector;
+	unsigned int gsi_base;
+	char *addr;
+	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
+
+	index = find_iosapic(gsi);
+
+	if (index < 0) {
+		printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi);
+		return;
+	}
+
+	vector = isa_irq_to_vector(isa_irq);
+	addr = iosapic_lists[index].addr;
+	gsi_base = iosapic_lists[index].gsi_base;
+
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
+		      gsi_base, addr);
+
+	DBG("ISA: IRQ %u -> GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	    isa_irq, global_vector,
+	    polarity ? "high" : "low", edge_triggered ? "edge" : "level",
+	    dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+	set_rte(vector, dest);
 }
 
-void __init
-iosapic_init (unsigned long phys_addr, unsigned int base_irq, int pcat_compat)
+/*
+ * Map PCI pin to the corresponding GSI.
+ * If no such mapping exists, return -1.
+ */
+static int
+pci_pin_to_gsi (int segment, int bus, int slot, int pci_pin, unsigned int *gsi)
 {
-	int i, irq, max_pin, vector, pin;
-	unsigned int ver;
+	struct pci_vector_struct *r;
+
+	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; r++)
+		if (r->segment == segment && r->bus == bus &&
+		    (r->pci_id >> 16) == slot && r->pin == pci_pin) {
+			*gsi = r->irq;
+			return 0;
+		}
+
+	return -1;
+}
+
+/*
+ * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
+ * try to allocate a new vector.  If it fails, return -1.
+ */
+static int
+pci_pin_to_vector (int segment, int bus, int slot, int pci_pin)
+{
+	int index, vector;
+	int gsi_base, pcat_compat;
+	char *addr;
+	unsigned int gsi;
+
+	if (pci_pin_to_gsi(segment, bus, slot, pci_pin, &gsi) < 0) {
+		printk("PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
+			segment, bus, slot, 'A' + pci_pin);
+		return -1;
+	}
+
+	vector = gsi_to_vector(gsi);
+
+	if (vector < 0) {
+		/* we should allocate a vector for this interrupt line */
+
+		index = find_iosapic(gsi);
+
+		if (index < 0) {
+			printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi);
+			return -1;
+		}
+
+		addr = iosapic_lists[index].addr;
+		gsi_base = iosapic_lists[index].gsi_base;
+		pcat_compat = iosapic_lists[index].pcat_compat;
+
+		if (pcat_compat && (gsi < 16))
+			vector = isa_irq_to_vector(gsi);
+		else {
+			/* new GSI; allocate a vector for it */
+			vector = ia64_alloc_vector();
+		}
+
+		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+			      0, 0, gsi_base, addr);
+
+		DBG("PCI: (%02x:%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
+		    segment, bus, slot, 'A' + pci_pin, gsi, vector);
+	}
+
+	return vector;
+}
+
+void __devinit
+iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
+{
+	int num_rte, vector;
+	unsigned int isa_irq, ver;
 	char *addr;
 	static int first_time = 1;
 
 	if (first_time) {
 		first_time = 0;
-
 		for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-			iosapic_irq[vector].pin = -1;	/* mark as unused */
+			iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
+	}
 
+	if (pcat_compat) {
 		/*
-		 * Fetch the PCI interrupt routing table:
+		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
+		 * enabled.
 		 */
-		acpi_cf_get_pci_vectors(&pci_irq.route, &pci_irq.num_routes);
+		printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
+		outb(0xff, 0xA1);
+		outb(0xff, 0x21);
 	}
 
 	addr = ioremap(phys_addr, 0);
 	ver = iosapic_version(addr);
-	max_pin = (ver >> 16) & 0xff;
 
-	printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n",
-	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, base_irq, base_irq + max_pin);
+	/*
+	 * The MAX_REDIR register holds the highest input pin
+	 * number (starting from 0).
+	 * We add 1 so that we can use it for number of pins (= RTEs)
+	 */
+	num_rte = ((ver >> 16) & 0xff) + 1;
+
+	iosapic_lists[num_iosapic].addr = addr;
+	iosapic_lists[num_iosapic].pcat_compat = pcat_compat;
+	iosapic_lists[num_iosapic].gsi_base = gsi_base;
+	iosapic_lists[num_iosapic].num_rte = num_rte;
+	num_iosapic++;
+
+	printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
+	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
+
+	if ((gsi_base == 0) && pcat_compat) {
+		unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
-	if ((base_irq == 0) && pcat_compat)
 		/*
 		 * Map the legacy ISA devices into the IOSAPIC data.  Some of these may
 		 * get reprogrammed later on with data from the ACPI Interrupt Source
 		 * Override table.
 		 */
-		for (irq = 0; irq < 16; ++irq) {
-			vector = isa_irq_to_vector(irq);
-			if ((pin = iosapic_irq[vector].pin) == -1)
-				pin = irq;
+		for (isa_irq = 0; isa_irq < 16; ++isa_irq) {
+			vector = isa_irq_to_vector(isa_irq);
 
-			register_irq(irq, vector, pin,
+			register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY,
 				     /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */
-				     IOSAPIC_LOWEST_PRIORITY, 1, 1, base_irq, addr);
+				     1, 1, gsi_base, addr);
 
-#ifdef DEBUG_IRQ_ROUTING
-			printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (high, edge) -> vector 0x%02x\n",
-			       irq, iosapic_irq[vector].base_irq + iosapic_irq[vector].pin,
-			       vector);
-#endif
+			DBG("ISA: IRQ %u -> GSI 0x%x (high,edge) -> CPU 0x%04x vector %d\n",
+			    isa_irq, isa_irq, dest, vector);
 
 			/* program the IOSAPIC routing table: */
-			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+			set_rte(vector, dest);
 		}
+	}
+}
 
-	for (i = 0; i < pci_irq.num_routes; i++) {
-		irq = pci_irq.route[i].irq;
 
-		if ((irq < (int)base_irq) || (irq > (int)(base_irq + max_pin)))
-			/* the interrupt route is for another controller... */
-			continue;
+/*
+ * Set allocated interrupt vector to dev->irq and
+ * program IOSAPIC to deliver interrupts
+ */
+void
+iosapic_fixup_pci_interrupt (struct pci_dev *dev)
+{
+	int segment;
+	unsigned char pci_pin;
+	int vector;
+	unsigned int dest;
+	struct hw_interrupt_type *irq_type;
+	irq_desc_t *idesc;
 
-		if (pcat_compat && (irq < 16))
-			vector = isa_irq_to_vector(irq);
-		else {
-			vector = iosapic_irq_to_vector(irq);
-			if (vector < 0)
-				/* new iosapic irq: allocate a vector for it */
-				vector = ia64_alloc_irq();
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pci_pin);
+	if (pci_pin) {
+		pci_pin--; /* interrupt pins are numberd starting from 1 */
+
+		segment = PCI_SEGMENT(dev);
+		vector = pci_pin_to_vector(segment, dev->bus->number, PCI_SLOT(dev->devfn), pci_pin);
+
+		if (vector < 0 && dev->bus->parent) {
+			/* go back to the bridge */
+			struct pci_dev *bridge = dev->bus->self;
+
+			if (bridge) {
+				/* allow for multiple bridges on an adapter */
+				do {
+					/* do the bridge swizzle... */
+					pci_pin = (pci_pin + PCI_SLOT(dev->devfn)) % 4;
+					vector = pci_pin_to_vector(segment,
+								   bridge->bus->number,
+								   PCI_SLOT(bridge->devfn),
+								   pci_pin);
+				} while (vector < 0 && (bridge = bridge->bus->self));
+			}
+			if (vector >= 0)
+				printk(KERN_WARNING
+				       "PCI: using PPB (%s INT%c) to get vector %d\n",
+				       dev->slot_name, 'A' + pci_pin,
+				       vector);
+			else
+				printk(KERN_WARNING
+				       "PCI: Couldn't map irq for (%s INT%c)\n",
+				       dev->slot_name, 'A' + pci_pin);
 		}
 
-		register_irq(irq, vector, irq - base_irq,
-			     /* IOSAPIC_POL_LOW, IOSAPIC_LEVEL */
-			     IOSAPIC_LOWEST_PRIORITY, 0, 0, base_irq, addr);
-
-# ifdef DEBUG_IRQ_ROUTING
-		printk("PCI: (B%d,I%d,P%d) -> IOSAPIC irq 0x%02x -> vector 0x%02x\n",
-		       pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin,
-		       iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector);
-# endif
+		if (vector >= 0) {
+			dev->irq = vector;
 
-			/* program the IOSAPIC routing table: */
-			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+			irq_type = &irq_type_iosapic_level;
+			idesc = irq_desc(vector);
+			if (idesc->handler != irq_type) {
+				if (idesc->handler != &no_irq_type)
+					printk("%s: changing vector %d from %s to %s\n",
+					       __FUNCTION__, vector,
+					       idesc->handler->typename,
+					       irq_type->typename);
+				idesc->handler = irq_type;
+			}
+#ifdef CONFIG_SMP
+			/*
+			 * For platforms that do not support interrupt redirect
+			 * via the XTP interface, we can round-robin the PCI
+			 * device interrupts to the processors
+			 */
+			if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
+				static int cpu_index = 0;
+
+				dest = cpu_physical_id(cpu_index) & 0xffff;
+
+				cpu_index++;
+				if (cpu_index >= smp_num_cpus)
+					cpu_index = 0;
+			} else {
+				/*
+				 * Direct the interrupt vector to the current cpu,
+				 * platform redirection will distribute them.
+				 */
+				dest = (ia64_get_lid() >> 16) & 0xffff;
+			}
+#else
+			/* direct the interrupt vector to the running cpu id */
+			dest = (ia64_get_lid() >> 16) & 0xffff;
+#endif
+
+			printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
+			       dev->slot_name, 'A' + pci_pin, dest, vector);
+			set_rte(vector, dest);
+		}
 	}
 }
 
+
 void
 iosapic_pci_fixup (int phase)
 {
 	struct	pci_dev	*dev;
-	unsigned char pin;
-	int vector;
-	struct hw_interrupt_type *irq_type;
-	irq_desc_t *idesc;
+
+	if (phase == 0) {
+		if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
+			printk("%s: acpi_get_prt failed\n", __FUNCTION__);
+		}
+		return;
+	}
 
 	if (phase != 1)
 		return;
 
 	pci_for_each_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (pin) {
-			pin--;          /* interrupt pins are numbered starting from 1 */
-			vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-			if (vector < 0 && dev->bus->parent) {
-				/* go back to the bridge */
-				struct pci_dev *bridge = dev->bus->self;
-
-				if (bridge) {
-					/* allow for multiple bridges on an adapter */
-					do {
-						/* do the bridge swizzle... */
-						pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-						vector = pci_pin_to_vector(bridge->bus->number,
-									   PCI_SLOT(bridge->devfn),
-									   pin);
-					} while (vector < 0 && (bridge = bridge->bus->self));
-				}
-				if (vector >= 0)
-					printk(KERN_WARNING
-					       "PCI: using PPB(B%d,I%d,P%d) to get vector %02x\n",
-					       dev->bus->number, PCI_SLOT(dev->devfn),
-					       pin, vector);
-				else
-					printk(KERN_WARNING
-					       "PCI: Couldn't map irq for (B%d,I%d,P%d)\n",
-					       dev->bus->number, PCI_SLOT(dev->devfn), pin);
-			}
-			if (vector >= 0) {
-				printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> 0x%02x\n",
-				       dev->bus->number, PCI_SLOT(dev->devfn), pin, vector);
-				dev->irq = vector;
-
-				irq_type = &irq_type_iosapic_level;
-				idesc = irq_desc(vector);
-				if (idesc->handler != irq_type){
-					if (idesc->handler != &no_irq_type)
-						printk("iosapic_pci_fixup: changing vector 0x%02x "
-						       "from %s to %s\n", vector,
-						       idesc->handler->typename,
-						       irq_type->typename);
-					idesc->handler = irq_type;
-				}
-#ifdef CONFIG_SMP
-				/*
-				 * For platforms that do not support interrupt redirect
-				 * via the XTP interface, we can round-robin the PCI
-				 * device interrupts to the processors
-				 */
-				if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
-					static int cpu_index = 0;
+		/* fixup dev->irq and program IOSAPIC */
+		iosapic_fixup_pci_interrupt(dev);
 
-					set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
-
-					cpu_index++;
-					if (cpu_index >= smp_num_cpus)
-						cpu_index = 0;
-				} else {
-					/*
-					 * Direct the interrupt vector to the current cpu,
-					 * platform redirection will distribute them.
-					 */
-					set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
-				}
-#else
-				/* direct the interrupt vector to the running cpu id */
-				set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
-#endif
-			}
-		}
 		/*
 		 * Nothing to fixup
 		 * Fix out-of-range IRQ numbers
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/irq.c linux-2.4.20/arch/ia64/kernel/irq.c
--- linux-2.4.19/arch/ia64/kernel/irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/irq.c	2002-10-04 00:41:15.000000000 +0000
@@ -67,6 +67,27 @@
 irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { IRQ_DISABLED, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+#ifdef CONFIG_IA64_GENERIC
+struct irq_desc *
+__ia64_irq_desc (unsigned int irq)
+{
+	return _irq_desc + irq;
+}
+
+ia64_vector
+__ia64_irq_to_vector (unsigned int irq)
+{
+	return (ia64_vector) irq;
+}
+
+unsigned int
+__ia64_local_vector_to_irq (ia64_vector vec)
+{
+	return (unsigned int) vec;
+}
+
+#endif
+
 static void register_irq_proc (unsigned int irq);
 
 /*
@@ -1144,7 +1165,7 @@
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
 
-	irq_desc(irq)->handler->set_affinity(irq | (redir?(1<<31):0), new_value);
+	irq_desc(irq)->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED :0), new_value);
 
 	return full_count;
 }
@@ -1180,7 +1201,7 @@
 {
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type))
+	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type) || irq_dir[irq])
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/irq_ia64.c linux-2.4.20/arch/ia64/kernel/irq_ia64.c
--- linux-2.4.19/arch/ia64/kernel/irq_ia64.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/irq_ia64.c	2002-10-04 00:41:16.000000000 +0000
@@ -36,6 +36,10 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_PERFMON
+# include <asm/perfmon.h>
+#endif
+
 #define IRQ_DEBUG	0
 
 /* default base addr of IPI table */
@@ -51,14 +55,14 @@
 };
 
 int
-ia64_alloc_irq (void)
+ia64_alloc_vector (void)
 {
-	static int next_irq = IA64_FIRST_DEVICE_VECTOR;
+	static int next_vector = IA64_FIRST_DEVICE_VECTOR;
 
-	if (next_irq > IA64_LAST_DEVICE_VECTOR)
+	if (next_vector > IA64_LAST_DEVICE_VECTOR)
 		/* XXX could look for sharable vectors instead of panic'ing... */
-		panic("ia64_alloc_irq: out of interrupt vectors!");
-	return next_irq++;
+		panic("%s: out of interrupt vectors!", __FUNCTION__);
+	return next_vector++;
 }
 
 extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
@@ -173,6 +177,9 @@
 #ifdef CONFIG_SMP
 	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
 #endif
+#ifdef CONFIG_PERFMON
+	perfmon_init_percpu();
+#endif
 	platform_irq_init();
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/ivt.S linux-2.4.20/arch/ia64/kernel/ivt.S
--- linux-2.4.19/arch/ia64/kernel/ivt.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/ivt.S	2002-10-04 00:41:12.000000000 +0000
@@ -126,7 +126,7 @@
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
 	srlz.d					// ensure "rsm psr.dt" has taken effect
-(p6)	movl r19=__pa(SWAPPER_PGD_ADDR)		// region 5 is rooted at swapper_pg_dir
+(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
@@ -329,12 +329,15 @@
 (p8)	br.cond.dptk dtlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
+	and r22=IA64_ISR_CODE_MASK,r20		// get the isr.code field
 	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
-	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
-	shr.u r18=r16,57	// move address bit 61 to bit 4
+	shr.u r18=r16,57			// move address bit 61 to bit 4
+	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
+	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
 	;;
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	cmp.ne p8,p0=r0,r23
+(p9)	cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22	// check isr.code field
 (p8)	br.cond.spnt page_fault
 
 	dep r21=-1,r21,IA64_PSR_ED_BIT,1
@@ -412,7 +415,7 @@
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
 	srlz.d
-(p6)	movl r19=__pa(SWAPPER_PGD_ADDR)		// region 5 is rooted at swapper_pg_dir
+(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/mca.c linux-2.4.20/arch/ia64/kernel/mca.c
--- linux-2.4.19/arch/ia64/kernel/mca.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/mca.c	2002-10-04 00:41:20.000000000 +0000
@@ -3,6 +3,9 @@
  * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
+ * Copyright (C) 2002 Dell Computer Corporation
+ * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
+ *
  * Copyright (C) 2002 Intel
  * Copyright (C) Jenna Hall (jenna.s.hall@intel.com)
  *
@@ -15,6 +18,8 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
+ * 02/03/25 M. Domsch	GUID cleanups
+ *
  * 02/01/04 J. Hall	Aligned MCA stack to 16 bytes, added platform vs. CPU
  *			error flag, set SAL default return values, changed
  *			error record structure to linked list, added init call
@@ -36,6 +41,7 @@
 #include <linux/irq.h>
 #include <linux/smp_lock.h>
 #include <linux/bootmem.h>
+#include <linux/acpi.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -46,7 +52,6 @@
 
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
-#include <asm/acpi-ext.h>
 
 #undef MCA_PRT_XTRA_DATA
 
@@ -348,17 +353,15 @@
 verify_guid (efi_guid_t *test, efi_guid_t *target)
 {
 	int     rc;
+#ifdef IA64_MCA_DEBUG_INFO
+	char out[40];
+#endif
 
-	if ((rc = memcmp((void *)test, (void *)target, sizeof(efi_guid_t)))) {
-		IA64_MCA_DEBUG("ia64_mca_print: invalid guid = "
-			       "{ %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
-			       "%#02x, %#02x, %#02x, %#02x, } } \n ",
-			       test->data1, test->data2, test->data3, test->data4[0],
-			       test->data4[1], test->data4[2], test->data4[3],
-			       test->data4[4], test->data4[5], test->data4[6],
-			       test->data4[7]);
+	if ((rc = efi_guidcmp(*test, *target))) {
+		IA64_MCA_DEBUG(KERN_DEBUG
+			       "verify_guid: invalid GUID = %s\n",
+			       efi_guid_unparse(test, out));
 	}
-
 	return rc;
 }
 
@@ -496,7 +499,7 @@
 	{
 		irq_desc_t *desc;
 		unsigned int irq;
-		int cpev = acpi_request_vector(ACPI20_ENTRY_PIS_CPEI);
+		int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI);
 
 		if (cpev >= 0) {
 			for (irq = 0; irq < NR_IRQS; ++irq)
@@ -856,11 +859,8 @@
 void
 ia64_log_prt_guid (efi_guid_t *p_guid, prfunc_t prfunc)
 {
-	printk("GUID = { %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
-	       "%#02x, %#02x, %#02x, %#02x, } } \n ", p_guid->data1,
-	       p_guid->data2, p_guid->data3, p_guid->data4[0], p_guid->data4[1],
-	       p_guid->data4[2], p_guid->data4[3], p_guid->data4[4],
-	       p_guid->data4[5], p_guid->data4[6], p_guid->data4[7]);
+	char out[40];
+	printk(KERN_DEBUG "GUID = %s\n", efi_guid_unparse(p_guid, out));
 }
 
 static void
@@ -1754,7 +1754,7 @@
 		ia64_log_prt_section_header(slsh, prfunc);
 #endif  // MCA_PRT_XTRA_DATA for test only @FVL
 
-		if (verify_guid((void *)&slsh->guid, (void *)&(SAL_PROC_DEV_ERR_SECT_GUID))) {
+		if (verify_guid(&slsh->guid, &(SAL_PROC_DEV_ERR_SECT_GUID))) {
 			IA64_MCA_DEBUG("ia64_mca_log_print: unsupported record section\n");
 			continue;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/mca_asm.S linux-2.4.20/arch/ia64/kernel/mca_asm.S
--- linux-2.4.19/arch/ia64/kernel/mca_asm.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/mca_asm.S	2002-10-04 00:41:15.000000000 +0000
@@ -684,9 +684,9 @@
 	movl	r3=SAL_GET_STATE_INFO;;
 	DATA_VA_TO_PA(r7);;		// convert to physical address
 	ld8	r8=[r7],8;;		// get pdesc function pointer
-	DATA_VA_TO_PA(r8)		// convert to physical address
+	dep	r8=0,r8,61,3;;		// convert SAL VA to PA
 	ld8	r1=[r7];;		// set new (ia64_sal) gp
-	DATA_VA_TO_PA(r1)		// convert to physical address
+	dep	r1=0,r1,61,3;;		// convert SAL VA to PA
 	mov	b6=r8
 
 	alloc	r5=ar.pfs,8,0,8,0;;	// allocate stack frame for SAL call
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/minstate.h linux-2.4.20/arch/ia64/kernel/minstate.h
--- linux-2.4.19/arch/ia64/kernel/minstate.h	2001-07-31 17:30:08.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/minstate.h	2002-10-04 00:41:15.000000000 +0000
@@ -92,7 +92,6 @@
  *
  * Assumed state upon entry:
  *	psr.ic: off
- *	psr.dt: off
  *	r31:	contains saved predicates (pr)
  *
  * Upon exit, the state is as follows:
@@ -186,7 +185,6 @@
  *
  * Assumed state upon entry:
  *	psr.ic: on
- *	psr.dt: on
  *	r2:	points to &pt_regs.r16
  *	r3:	points to &pt_regs.r17
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/pal.S linux-2.4.20/arch/ia64/kernel/pal.S
--- linux-2.4.19/arch/ia64/kernel/pal.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/pal.S	2002-10-04 00:41:30.000000000 +0000
@@ -114,7 +114,7 @@
 	;;
 	rsm psr.i
 	mov b7 = loc2
-	;; 
+	;;
 	br.call.sptk.many rp=b7		// now make the call
 .ret0:	mov psr.l  = loc3
 	mov ar.pfs = loc1
@@ -161,7 +161,7 @@
 	;;
 	mov loc3 = psr			// save psr
 	adds r8  = 1f-1b,r8		// calculate return address for call
-	;; 
+	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	dep.z r8=r8,0,61		// convert rp to physical
@@ -216,7 +216,7 @@
 	mov out3 = in3		// copy arg3
 	;;
 	mov loc3 = psr		// save psr
-	;; 
+	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	;;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/palinfo.c linux-2.4.20/arch/ia64/kernel/palinfo.c
--- linux-2.4.19/arch/ia64/kernel/palinfo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/palinfo.c	2002-10-04 00:41:09.000000000 +0000
@@ -21,10 +21,10 @@
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/efi.h>
 
 #include <asm/pal.h>
 #include <asm/sal.h>
-#include <asm/efi.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #ifdef CONFIG_SMP
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/pci.c linux-2.4.20/arch/ia64/kernel/pci.c
--- linux-2.4.19/arch/ia64/kernel/pci.c	2001-12-21 17:41:53.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/pci.c	2002-10-04 00:41:18.000000000 +0000
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/acpi.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -42,104 +43,256 @@
 extern void ia64_mca_check_errors( void );
 #endif
 
+struct pci_fixup pcibios_fixups[1];
+
+struct pci_ops *pci_root_ops;
+
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
+
+
 /*
- * This interrupt-safe spinlock protects all accesses to PCI
- * configuration space.
+ * Low-level SAL-based PCI configuration access functions. Note that SAL
+ * calls are already serialized (via sal_lock), so we don't need another
+ * synchronization mechanism here.
  */
-static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
 
-struct pci_fixup pcibios_fixups[] = {
-	{ 0 }
-};
+#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \
+	((u64)(seg << 24) | (u64)(bus << 16) | \
+	 (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
 
-/* Macro to build a PCI configuration address to be passed as a parameter to SAL. */
+static int
+pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	int result = 0;
+	u64 data = 0;
+
+	if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
 
-#define PCI_CONFIG_ADDRESS(dev, where) \
-	(((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff))
+	result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
+
+	*value = (u32) data;
+
+	return result;
+}
 
 static int
-pci_conf_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
 {
-	s64 status;
-	u64 lval;
+	if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 1, &lval);
-	*value = lval;
-	return status;
+	return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
 }
 
+
 static int
-pci_conf_read_config_word(struct pci_dev *dev, int where, u16 *value)
+pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
 {
-	s64 status;
-	u64 lval;
+	int result = 0;
+	u32 data = 0;
+
+	if (!value)
+		return -EINVAL;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 2, &lval);
-	*value = lval;
-	return status;
+	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			      PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8) data;
+
+	return result;
 }
 
 static int
-pci_conf_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+pci_sal_read_config_word (struct pci_dev *dev, int where, u16 *value)
 {
-	s64 status;
-	u64 lval;
+	int result = 0;
+	u32 data = 0;
+
+	if (!value)
+		return -EINVAL;
+
+	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			      PCI_FUNC(dev->devfn), where, 2, &data);
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 4, &lval);
-	*value = lval;
-	return status;
+	*value = (u16) data;
+
+	return result;
+}
+
+static int
+pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
+{
+	if (!value)
+		return -EINVAL;
+
+	return pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			    PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int
-pci_conf_write_config_byte (struct pci_dev *dev, int where, u8 value)
+pci_sal_write_config_byte (struct pci_dev *dev, int where, u8 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 1, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int
-pci_conf_write_config_word (struct pci_dev *dev, int where, u16 value)
+pci_sal_write_config_word (struct pci_dev *dev, int where, u16 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 2, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int
-pci_conf_write_config_dword (struct pci_dev *dev, int where, u32 value)
+pci_sal_write_config_dword (struct pci_dev *dev, int where, u32 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 4, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-struct pci_ops pci_conf = {
-      pci_conf_read_config_byte,
-      pci_conf_read_config_word,
-      pci_conf_read_config_dword,
-      pci_conf_write_config_byte,
-      pci_conf_write_config_word,
-      pci_conf_write_config_dword
+struct pci_ops pci_sal_ops = {
+	pci_sal_read_config_byte,
+	pci_sal_read_config_word,
+	pci_sal_read_config_dword,
+	pci_sal_write_config_byte,
+	pci_sal_write_config_word,
+	pci_sal_write_config_dword
 };
 
+
 /*
  * Initialization. Uses the SAL interface
  */
+
+static struct pci_controller *
+alloc_pci_controller(int seg)
+{
+	struct pci_controller *controller;
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return NULL;
+
+	memset(controller, 0, sizeof(*controller));
+	controller->segment = seg;
+	return controller;
+}
+
+static struct pci_bus *
+scan_root_bus(int bus, struct pci_ops *ops, void *sysdata)
+{
+	struct pci_bus *b;
+
+	/*
+	 * We know this is a new root bus we haven't seen before, so
+	 * scan it, even if we've seen the same bus number in a different
+	 * segment.
+	 */
+	b = kmalloc(sizeof(*b), GFP_KERNEL);
+	if (!b)
+		return NULL;
+
+	memset(b, 0, sizeof(*b));
+	INIT_LIST_HEAD(&b->children);
+	INIT_LIST_HEAD(&b->devices);
+
+	list_add_tail(&b->node, &pci_root_buses);
+
+	b->number = b->secondary = bus;
+	b->resource[0] = &ioport_resource;
+	b->resource[1] = &iomem_resource;
+
+	b->sysdata = sysdata;
+	b->ops = ops;
+	b->subordinate = pci_do_scan_bus(b);
+
+	return b;
+}
+
+struct pci_bus *
+pcibios_scan_root(void *handle, int seg, int bus)
+{
+	struct pci_controller *controller;
+	u64 base, size, offset;
+
+	printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus);
+
+	controller = alloc_pci_controller(seg);
+	if (!controller)
+		return NULL;
+
+	controller->acpi_handle = handle;
+
+	acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
+	controller->mem_offset = offset;
+
+	return scan_root_bus(bus, pci_root_ops, controller);
+}
+
+void __init
+pcibios_config_init (void)
+{
+	if (pci_root_ops)
+		return;
+
+	printk("PCI: Using SAL to access configuration space\n");
+
+	pci_root_ops = &pci_sal_ops;
+	pci_config_read = pci_sal_read;
+	pci_config_write = pci_sal_write;
+
+	return;
+}
+
 void __init
 pcibios_init (void)
 {
 #	define PCI_BUSES_TO_SCAN 255
-	int i;
+	int i = 0;
+	struct pci_controller *controller;
 
 #ifdef CONFIG_IA64_MCA
 	ia64_mca_check_errors();    /* For post-failure MCA error logging */
 #endif
 
-	platform_pci_fixup(0);	/* phase 0 initialization (before PCI bus has been scanned) */
+	pcibios_config_init();
+
+	platform_pci_fixup(0);	/* phase 0 fixups (before buses scanned) */
 
 	printk("PCI: Probing PCI hardware\n");
-	for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
-		pci_scan_bus(i, &pci_conf, NULL);
+	controller = alloc_pci_controller(0);
+	if (controller)
+		for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
+			pci_scan_bus(i, pci_root_ops, controller);
+
+	platform_pci_fixup(1);	/* phase 1 fixups (after buses scanned) */
 
-	platform_pci_fixup(1);	/* phase 1 initialization (after PCI bus has been scanned) */
 	return;
 }
 
+static void __init
+pcibios_fixup_resource(struct resource *res, u64 offset)
+{
+	res->start += offset;
+	res->end += offset;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (!dev->resource[i].start)
+			continue;
+		if (dev->resource[i].flags & IORESOURCE_MEM)
+			pcibios_fixup_resource(&dev->resource[i],
+				PCI_CONTROLLER(dev)->mem_offset);
+	}
+}
+
 /*
  *  Called after each bus is probed, but before its children
  *  are examined.
@@ -147,7 +300,10 @@
 void __init
 pcibios_fixup_bus (struct pci_bus *b)
 {
-	return;
+	struct list_head *ln;
+
+	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
+		pcibios_fixup_device_resources(pci_dev_b(ln), b);
 }
 
 void __init
@@ -186,12 +342,45 @@
 int
 pcibios_enable_device (struct pci_dev *dev)
 {
-	/* Not needed, since we enable all devices at startup.  */
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	if (!dev)
+		return -EINVAL;
+
+ 	platform_pci_enable_device(dev);
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because of resource collisions\n",
+			       dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+
+	printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
+
 	return 0;
 }
 
 void
-pcibios_align_resource (void *data, struct resource *res, unsigned long size)
+pcibios_align_resource (void *data, struct resource *res,
+		        unsigned long size, unsigned long align)
 {
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon.c linux-2.4.20/arch/ia64/kernel/perfmon.c
--- linux-2.4.19/arch/ia64/kernel/perfmon.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/perfmon.c	2002-10-04 00:41:16.000000000 +0000
@@ -23,6 +23,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wrapper.h>
 #include <linux/mm.h>
+#include <linux/sysctl.h>
 
 #include <asm/bitops.h>
 #include <asm/errno.h>
@@ -42,7 +43,7 @@
  * you must enable the following flag to activate the support for
  * accessing the registers via the perfmonctl() interface.
  */
-#ifdef CONFIG_ITANIUM
+#if defined(CONFIG_ITANIUM) || defined(CONFIG_MCKINLEY)
 #define PFM_PMU_USES_DBR	1
 #endif
 
@@ -68,26 +69,27 @@
 #define PMC_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_soft_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
 #define PFM_FL_INHERIT_MASK	(PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)
 
+/* i assume unsigned */
 #define PMC_IS_IMPL(i)	  (i<pmu_conf.num_pmcs && pmu_conf.impl_regs[i>>6] & (1UL<< (i) %64))
 #define PMD_IS_IMPL(i)	  (i<pmu_conf.num_pmds &&  pmu_conf.impl_regs[4+(i>>6)] & (1UL<<(i) % 64))
 
-#define PMD_IS_COUNTING(i) (i >=0  && i < 256 && pmu_conf.counter_pmds[i>>6] & (1UL <<(i) % 64))
-#define PMC_IS_COUNTING(i) PMD_IS_COUNTING(i)
+/* XXX: these three assume that register i is implemented */
+#define PMD_IS_COUNTING(i) (pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING)
+#define PMC_IS_COUNTING(i) (pmu_conf.pmc_desc[i].type == PFM_REG_COUNTING)
+#define PMC_IS_MONITOR(c)  (pmu_conf.pmc_desc[i].type == PFM_REG_MONITOR)
 
+/* k assume unsigned */
 #define IBR_IS_IMPL(k)	  (k<pmu_conf.num_ibrs)
 #define DBR_IS_IMPL(k)	  (k<pmu_conf.num_dbrs)
 
-#define PMC_IS_BTB(a)	  (((pfm_monitor_t *)(a))->pmc_es == PMU_BTB_EVENT)
-
-#define LSHIFT(x)		(1UL<<(x))
-#define PMM(x)			LSHIFT(x)
-#define PMC_IS_MONITOR(c)	((pmu_conf.monitor_pmcs[0] & PMM((c))) != 0)
-
 #define CTX_IS_ENABLED(c) 	((c)->ctx_flags.state == PFM_CTX_ENABLED)
 #define CTX_OVFL_NOBLOCK(c)	((c)->ctx_fl_block == 0)
 #define CTX_INHERIT_MODE(c)	((c)->ctx_fl_inherit)
 #define CTX_HAS_SMPL(c)		((c)->ctx_psb != NULL)
-#define CTX_USED_PMD(ctx,n) 	(ctx)->ctx_used_pmds[(n)>>6] |= 1UL<< ((n) % 64)
+/* XXX: does not support more than 64 PMDs */
+#define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask)
+#define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL)
+
 
 #define CTX_USED_IBR(ctx,n) 	(ctx)->ctx_used_ibrs[(n)>>6] |= 1UL<< ((n) % 64)
 #define CTX_USED_DBR(ctx,n) 	(ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
@@ -104,17 +106,29 @@
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
+#ifdef CONFIG_SMP
+#define cpu_is_online(i) (cpu_online_map & (1UL << i))
+#else
+#define cpu_is_online(i)        (i==0)
+#endif
+
 /*
  * debugging
  */
 #define DBprintk(a) \
 	do { \
-		if (pfm_debug_mode >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+		if (pfm_sysctl.debug >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+	} while (0)
+
+#define DBprintk_ovfl(a) \
+	do { \
+		if (pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
 	} while (0)
 
 
+
 /* 
- * These are some helpful architected PMC and IBR/DBR register layouts
+ * Architected PMC structure
  */
 typedef struct {
 	unsigned long pmc_plm:4;	/* privilege level mask */
@@ -139,41 +153,40 @@
 typedef struct _pfm_smpl_buffer_desc {
 	spinlock_t		psb_lock;	/* protection lock */
 	unsigned long		psb_refcnt;	/* how many users for the buffer */
-	int			psb_flags;	/* bitvector of flags */
+	int			psb_flags;	/* bitvector of flags (not yet used) */
 
 	void			*psb_addr;	/* points to location of first entry */
 	unsigned long		psb_entries;	/* maximum number of entries */
 	unsigned long		psb_size;	/* aligned size of buffer */
 	unsigned long		psb_index;	/* next free entry slot XXX: must use the one in buffer */
 	unsigned long		psb_entry_size;	/* size of each entry including entry header */
+
 	perfmon_smpl_hdr_t	*psb_hdr;	/* points to sampling buffer header */
 
 	struct _pfm_smpl_buffer_desc *psb_next;	/* next psb, used for rvfreeing of psb_hdr */
 
 } pfm_smpl_buffer_desc_t;
 
+/*
+ * psb_flags
+ */
+#define PSB_HAS_VMA	0x1		/* a virtual mapping for the buffer exists */
+
 #define LOCK_PSB(p)	spin_lock(&(p)->psb_lock)
 #define UNLOCK_PSB(p)	spin_unlock(&(p)->psb_lock)
 
-#define PFM_PSB_VMA	0x1			/* a VMA is describing the buffer */
-
 /*
- * This structure is initialized at boot time and contains
- * a description of the PMU main characteristic as indicated
- * by PAL
+ * The possible type of a PMU register
  */
-typedef struct {
-	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
-	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
-	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
-	unsigned long num_pmcs ;	/* highest PMC implemented (may have holes) */
-	unsigned long num_pmds;		/* highest PMD implemented (may have holes) */
-	unsigned long impl_regs[16];	/* buffer used to hold implememted PMC/PMD mask */
-	unsigned long num_ibrs;		/* number of instruction debug registers */
-	unsigned long num_dbrs;		/* number of data debug registers */
-	unsigned long monitor_pmcs[4];	/* which pmc are controlling monitors */
-	unsigned long counter_pmds[4];	/* which pmd are used as counters */
-} pmu_config_t;
+typedef enum { 
+	PFM_REG_NOTIMPL, /* not implemented */
+	PFM_REG_NONE, 	 /* end marker */
+	PFM_REG_MONITOR, /* a PMC with a pmc.pm field only */
+	PFM_REG_COUNTING,/* a PMC with a pmc.pm AND pmc.oi, a PMD used as a counter */
+	PFM_REG_CONTROL, /* PMU control register */
+	PFM_REG_CONFIG,  /* refine configuration */
+	PFM_REG_BUFFER	 /* PMD used as buffer */
+} pfm_pmu_reg_type_t;
 
 /*
  * 64-bit software counter structure
@@ -221,9 +234,11 @@
 
 	struct semaphore	ctx_restart_sem;   	/* use for blocking notification mode */
 
-	unsigned long		ctx_used_pmds[4];	/* bitmask of used PMD (speedup ctxsw) */
-	unsigned long		ctx_saved_pmcs[4];	/* bitmask of PMC to save on ctxsw */
-	unsigned long		ctx_reload_pmcs[4];	/* bitmask of PMC to reload on ctxsw (SMP) */
+	unsigned long		ctx_used_pmds[4];	/* bitmask of PMD used                 */
+	unsigned long		ctx_reload_pmds[4];	/* bitmask of PMD to reload on ctxsw   */
+
+	unsigned long		ctx_used_pmcs[4];	/* bitmask PMC used by context         */
+	unsigned long		ctx_reload_pmcs[4];	/* bitmask of PMC to reload on ctxsw   */
 
 	unsigned long		ctx_used_ibrs[4];	/* bitmask of used IBR (speedup ctxsw) */
 	unsigned long		ctx_used_dbrs[4];	/* bitmask of used DBR (speedup ctxsw) */
@@ -235,6 +250,7 @@
 	unsigned long		ctx_cpu;		/* cpu to which perfmon is applied (system wide) */
 
 	atomic_t		ctx_saving_in_progress;	/* flag indicating actual save in progress */
+	atomic_t		ctx_is_busy;		/* context accessed by overflow handler */
 	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
 } pfm_context_t;
 
@@ -250,16 +266,54 @@
  * mostly used to synchronize between system wide and per-process
  */
 typedef struct {
-	spinlock_t		pfs_lock;		/* lock the structure */
+	spinlock_t		pfs_lock;		   /* lock the structure */
 
-	unsigned long		pfs_task_sessions;	/* number of per task sessions */
-	unsigned long		pfs_sys_sessions;	/* number of per system wide sessions */
-	unsigned long   	pfs_sys_use_dbregs;	  	/* incremented when a system wide session uses debug regs */
-	unsigned long   	pfs_ptrace_use_dbregs;	  /* incremented when a process uses debug regs */
-	struct task_struct	*pfs_sys_session[NR_CPUS];  /* point to task owning a system-wide session */
+	unsigned long		pfs_task_sessions;	   /* number of per task sessions */
+	unsigned long		pfs_sys_sessions;	   /* number of per system wide sessions */
+	unsigned long   	pfs_sys_use_dbregs;	   /* incremented when a system wide session uses debug regs */
+	unsigned long   	pfs_ptrace_use_dbregs;	   /* incremented when a process uses debug regs */
+	struct task_struct	*pfs_sys_session[NR_CPUS]; /* point to task owning a system-wide session */
 } pfm_session_t;
 
 /*
+ * information about a PMC or PMD.
+ * dep_pmd[]: a bitmask of dependent PMD registers 
+ * dep_pmc[]: a bitmask of dependent PMC registers
+ */
+typedef struct {
+	pfm_pmu_reg_type_t	type;
+	int			pm_pos;
+	int			(*read_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	int			(*write_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	unsigned long		dep_pmd[4];
+	unsigned long		dep_pmc[4];
+} pfm_reg_desc_t;
+/* assume cnum is a valid monitor */
+#define PMC_PM(cnum, val)	(((val) >> (pmu_conf.pmc_desc[cnum].pm_pos)) & 0x1)
+#define PMC_WR_FUNC(cnum)	(pmu_conf.pmc_desc[cnum].write_check)
+#define PMD_WR_FUNC(cnum)	(pmu_conf.pmd_desc[cnum].write_check)
+#define PMD_RD_FUNC(cnum)	(pmu_conf.pmd_desc[cnum].read_check)
+
+/*
+ * This structure is initialized at boot time and contains
+ * a description of the PMU main characteristic as indicated
+ * by PAL along with a list of inter-registers dependencies and configurations.
+ */
+typedef struct {
+	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
+	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
+	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
+	unsigned long num_pmcs ;	/* highest PMC implemented (may have holes) */
+	unsigned long num_pmds;		/* highest PMD implemented (may have holes) */
+	unsigned long impl_regs[16];	/* buffer used to hold implememted PMC/PMD mask */
+	unsigned long num_ibrs;		/* number of instruction debug registers */
+	unsigned long num_dbrs;		/* number of data debug registers */
+	pfm_reg_desc_t *pmc_desc;	/* detailed PMC register descriptions */
+	pfm_reg_desc_t *pmd_desc;	/* detailed PMD register descriptions */
+} pmu_config_t;
+
+
+/*
  * structure used to pass argument to/from remote CPU 
  * using IPI to check and possibly save the PMU context on SMP systems.
  *
@@ -301,22 +355,50 @@
 #define PFM_CMD_NARG(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_narg)
 #define PFM_CMD_ARG_SIZE(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_argsize)
 
+typedef struct {
+	int	debug;		/* turn on/off debugging via syslog */
+	int	debug_ovfl;	/* turn on/off debug printk in overflow handler */
+	int	fastctxsw;	/* turn on/off fast (unsecure) ctxsw */
+} pfm_sysctl_t;
+
+typedef struct {
+	unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
+	unsigned long pfm_ovfl_intr_count; /* keep track of ovfl interrupts */
+	unsigned long pfm_recorded_samples_count;
+	unsigned long pfm_full_smpl_buffer_count; /* how many times the sampling buffer was full */
+} pfm_stats_t;
 
 /*
  * perfmon internal variables
  */
 static pmu_config_t	pmu_conf; 	/* PMU configuration */
-static int		pfm_debug_mode;	/* 0= nodebug, >0= debug output on */
 static pfm_session_t	pfm_sessions;	/* global sessions information */
 static struct proc_dir_entry *perfmon_dir; /* for debug only */
-static unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
-static unsigned long pfm_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
-static unsigned long pfm_recorded_samples_count;
+static pfm_stats_t	pfm_stats;
 
+/* sysctl() controls */
+static pfm_sysctl_t pfm_sysctl;
+
+static ctl_table pfm_ctl_table[]={
+	{1, "debug", &pfm_sysctl.debug, sizeof(int), 0666, NULL, &proc_dointvec, NULL,},
+	{2, "debug_ovfl", &pfm_sysctl.debug_ovfl, sizeof(int), 0666, NULL, &proc_dointvec, NULL,},
+	{3, "fastctxsw", &pfm_sysctl.fastctxsw, sizeof(int), 0600, NULL, &proc_dointvec, NULL,},
+	{ 0, },
+};
+static ctl_table pfm_sysctl_dir[] = {
+	{1, "perfmon", NULL, 0, 0755, pfm_ctl_table, },
+ 	{0,},
+};
+static ctl_table pfm_sysctl_root[] = {
+	{1, "kernel", NULL, 0, 0755, pfm_sysctl_dir, },
+ 	{0,},
+};
+static struct ctl_table_header *pfm_sysctl_header;
 
 static unsigned long reset_pmcs[IA64_NUM_PMC_REGS];	/* contains PAL reset values for PMCS */
 
 static void pfm_vm_close(struct vm_area_struct * area);
+
 static struct vm_operations_struct pfm_vm_ops={
 	close: pfm_vm_close
 };
@@ -339,6 +421,14 @@
 #endif
 static void pfm_lazy_save_regs (struct task_struct *ta);
 
+#if   defined(CONFIG_ITANIUM)
+#include "perfmon_itanium.h"
+#elif defined(CONFIG_MCKINLEY)
+#include "perfmon_mckinley.h"
+#else
+#include "perfmon_generic.h"
+#endif
+
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
 {
@@ -353,7 +443,7 @@
 	 * writing to unimplemented part is ignore, so we do not need to
 	 * mask off top part
 	 */
-	ia64_set_pmd(i, val);
+	ia64_set_pmd(i, val & pmu_conf.perf_ovfl_val);
 }
 
 /*
@@ -424,7 +514,6 @@
 	return pa;
 }
 
-
 static void *
 pfm_rvmalloc(unsigned long size)
 {
@@ -500,7 +589,7 @@
 	 *
 	 * This function cannot remove the buffer from here, because exit_mmap() must first
 	 * complete. Given that there is no other vma related callback in the generic code,
-	 * we have created on own with the linked list of sampling buffer to free which
+	 * we have created our own with the linked list of sampling buffers to free. The list
 	 * is part of the thread structure. In release_thread() we check if the list is
 	 * empty. If not we call into perfmon to free the buffer and psb. That is the only
 	 * way to ensure a safe deallocation of the sampling buffer which works when
@@ -516,16 +605,15 @@
 		psb->psb_next = current->thread.pfm_smpl_buf_list;
 		current->thread.pfm_smpl_buf_list = psb;
 
-		DBprintk(("psb for [%d] smpl @%p size %ld inserted into list\n", 
-			current->pid, psb->psb_hdr, psb->psb_size));
+		DBprintk(("[%d] add smpl @%p size %lu to smpl_buf_list psb_flags=0x%x\n", 
+			current->pid, psb->psb_hdr, psb->psb_size, psb->psb_flags));
 	}
-	DBprintk(("psb vma flag cleared for [%d] smpl @%p size %ld inserted into list\n", 
-			current->pid, psb->psb_hdr, psb->psb_size));
-
+	DBprintk(("[%d] clearing psb_flags=0x%x smpl @%p size %lu\n", 
+			current->pid, psb->psb_flags, psb->psb_hdr, psb->psb_size));
 	/*
-	 * indicate to pfm_context_exit() that the vma has been removed. 
+	 * decrement the number vma for the buffer
 	 */
-	psb->psb_flags &= ~PFM_PSB_VMA;
+	psb->psb_flags &= ~PSB_HAS_VMA;
 
 	UNLOCK_PSB(psb);
 }
@@ -548,7 +636,7 @@
 		printk("perfmon: invalid context mm=%p\n", task->mm);
 		return -1;
 	}
-	psb = ctx->ctx_psb;	
+	psb = ctx->ctx_psb;
 
 	down_write(&task->mm->mmap_sem);
 
@@ -559,14 +647,9 @@
 		printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", 
 				task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
 	}
-	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d\n", 
-		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r));
 
-	/* 
-	 * make sure we suppress all traces of this buffer
-	 * (important for pfm_inherit)
-	 */
-	ctx->ctx_smpl_vaddr = 0;
+	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", 
+		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags));
 
 	return 0;
 }
@@ -599,7 +682,7 @@
 	while (size > 0) {
 		page = pfm_kvirt_to_pa(buf);
 
-		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_SHARED)) return -ENOMEM;
+		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
 		
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
@@ -638,17 +721,25 @@
 	void *smpl_buf;
 	pfm_smpl_buffer_desc_t *psb;
 
-	regcount = pfm_smpl_entry_size(which_pmds, 1);
 
 	/* note that regcount might be 0, in this case only the header for each
 	 * entry will be recorded.
 	 */
+	regcount = pfm_smpl_entry_size(which_pmds, 1);
+
+	if ((sizeof(perfmon_smpl_hdr_t)+ entries*sizeof(perfmon_smpl_entry_t)) <= entries) {
+		DBprintk(("requested entries %lu is too big\n", entries));
+		return -EINVAL;
+	}
 
 	/*
 	 * 1 buffer hdr and for each entry a header + regcount PMDs to save
 	 */
 	size = PAGE_ALIGN(  sizeof(perfmon_smpl_hdr_t)
 			  + entries * (sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64)));
+
+	DBprintk(("sampling buffer size=%lu bytes\n", size));
+
 	/*
 	 * check requested size to avoid Denial-of-service attacks
 	 * XXX: may have to refine this test	
@@ -688,9 +779,13 @@
 	}
 	/*
 	 * partially initialize the vma for the sampling buffer
+	 *
+	 * The VM_DONTCOPY flag is very important as it ensures that the mapping
+	 * will never be inherited for any child process (via fork()) which is always 
+	 * what we want.
 	 */
 	vma->vm_mm	     = mm;
-	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED;
+	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED|VM_DONTCOPY;
 	vma->vm_page_prot    = PAGE_READONLY; /* XXX may need to change */
 	vma->vm_ops	     = &pfm_vm_ops; /* necesarry to get the close() callback */
 	vma->vm_pgoff	     = 0;
@@ -708,8 +803,8 @@
 	psb->psb_size    = size; /* aligned size */
 	psb->psb_index   = 0;
 	psb->psb_entries = entries;
-	psb->psb_flags   = PFM_PSB_VMA; /* remember that there is a vma describing the buffer */
 	psb->psb_refcnt  = 1;
+	psb->psb_flags   = PSB_HAS_VMA;
 
 	spin_lock_init(&psb->psb_lock);
 
@@ -719,9 +814,9 @@
 	 */
 	psb->psb_entry_size = sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64);
 
-	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p\n", 
+	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p refcnt=%lu psb_flags=0x%x\n", 
 		  (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, 
-		  (void *)psb->psb_addr));
+		  (void *)psb->psb_addr, psb->psb_refcnt, psb->psb_flags));
 
 	/* initialize some of the fields of user visible buffer header */
 	psb->psb_hdr->hdr_version    = PFM_SMPL_VERSION;
@@ -797,7 +892,6 @@
 	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
 }
 
-
 static int
 pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
 {
@@ -813,6 +907,11 @@
 	}
 	ctx_flags = pfx->ctx_flags;
 
+	if ((ctx_flags & PFM_FL_INHERIT_MASK) == (PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)) {
+		DBprintk(("invalid inherit mask 0x%x\n",ctx_flags & PFM_FL_INHERIT_MASK));
+		return -EINVAL;
+	}
+
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
 		DBprintk(("cpu_mask=0x%lx\n", pfx->ctx_cpu_mask));
 		/*
@@ -832,8 +931,8 @@
 		/*
 		 * and it must be a valid CPU
 		 */
-		cpu = ffs(pfx->ctx_cpu_mask);
-		if (cpu > smp_num_cpus) {
+		cpu = ffz(~pfx->ctx_cpu_mask);
+		if (cpu_is_online(cpu) == 0) {
 			DBprintk(("CPU%d is not online\n", cpu));
 			return -EINVAL;
 		}
@@ -851,7 +950,16 @@
 		 * must provide a target for the signal in blocking mode even when
 		 * no counter is configured with PFM_FL_REG_OVFL_NOTIFY
 		 */
-		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == 0) return -EINVAL;
+		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == 0) {
+			DBprintk(("must have notify_pid when blocking for [%d]\n", task->pid));
+			return -EINVAL;
+		}
+#if 0
+		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == task->pid) {
+			DBprintk(("cannot notify self when blocking for [%d]\n", task->pid));
+			return -EINVAL;
+		}
+#endif
 	}
 	/* probably more to add here */
 
@@ -859,7 +967,7 @@
 }
 
 static int
-pfm_create_context(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
+pfm_context_create(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
 		   struct pt_regs *regs)
 {
 	pfarg_context_t tmp;
@@ -890,7 +998,7 @@
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
 
 		/* at this point, we know there is at least one bit set */
-		cpu = ffs(tmp.ctx_cpu_mask) - 1;
+		cpu = ffz(~tmp.ctx_cpu_mask);
 
 		DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id()));
 
@@ -984,7 +1092,7 @@
 	}
 
 	if (tmp.ctx_smpl_entries) {
-		DBprintk(("sampling entries=%ld\n",tmp.ctx_smpl_entries));
+		DBprintk(("sampling entries=%lu\n",tmp.ctx_smpl_entries));
 
 		ret = pfm_smpl_buffer_alloc(ctx, tmp.ctx_smpl_regs, 
 						 tmp.ctx_smpl_entries, &uaddr);
@@ -1010,20 +1118,12 @@
 
 	atomic_set(&ctx->ctx_last_cpu,-1); /* SMP only, means no CPU */
 
-	/* 
-	 * Keep track of the pmds we want to sample
-	 * XXX: may be we don't need to save/restore the DEAR/IEAR pmds
-	 * but we do need the BTB for sure. This is because of a hardware
-	 * buffer of 1 only for non-BTB pmds.
-	 *
-	 * We ignore the unimplemented pmds specified by the user
-	 */
-	ctx->ctx_used_pmds[0]  = tmp.ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
-	ctx->ctx_saved_pmcs[0] = 1; /* always save/restore PMC[0] */
+	/* may be redudant with memset() but at least it's easier to remember */
+	atomic_set(&ctx->ctx_saving_in_progress, 0); 
+	atomic_set(&ctx->ctx_is_busy, 0); 
 
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
-
 	if (copy_to_user(req, &tmp, sizeof(tmp))) {
 		ret = -EFAULT;
 		goto buffer_error;
@@ -1126,21 +1226,22 @@
 			  	current->pid, 
 				flag == PFM_RELOAD_LONG_RESET ? "long" : "short", i, val));
 	}
+	ia64_srlz_d();
 	/* just in case ! */
 	ctx->ctx_ovfl_regs[0] = 0UL;
 }
 
 static int
-pfm_write_pmcs(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmcs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &ta->thread;
+	struct thread_struct *th = &task->thread;
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	unsigned int cnum;
 	int i;
 	int ret = 0, reg_retval = 0;
 
 	/* we don't quite support this right now */
-	if (ta != current) return -EINVAL;
+	if (task != current) return -EINVAL;
 
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
@@ -1169,30 +1270,30 @@
 		 * 	- per-task : user monitor
 		 * any other configuration is rejected.
 		 */
-		if (PMC_IS_MONITOR(cnum)) {
-			pfm_monitor_t *p = (pfm_monitor_t *)&tmp.reg_value;
-
-			DBprintk(("pmc[%u].pm = %d\n", cnum, p->pmc_pm));
+		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
+			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, tmp.reg_value))); 
 
-			if (ctx->ctx_fl_system ^ p->pmc_pm) {
-			//if ((ctx->ctx_fl_system == 1 && p->pmc_pm == 0)
-			 //  ||(ctx->ctx_fl_system == 0 && p->pmc_pm == 1)) {
+			if (ctx->ctx_fl_system ^ PMC_PM(cnum, tmp.reg_value)) {
+				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, tmp.reg_value), ctx->ctx_fl_system));
 				ret = -EINVAL;
 				goto abort_mission;
 			}
-			/*
-			 * enforce generation of overflow interrupt. Necessary on all
-			 * CPUs which do not implement 64-bit hardware counters.
-			 */
-			p->pmc_oi = 1;
 		}
 
 		if (PMC_IS_COUNTING(cnum)) {
+			pfm_monitor_t *p = (pfm_monitor_t *)&tmp.reg_value;
+			/*
+		 	 * enforce generation of overflow interrupt. Necessary on all
+		 	 * CPUs.
+		 	 */
+			p->pmc_oi = 1;
+
 			if (tmp.reg_flags & PFM_REGFL_OVFL_NOTIFY) {
 				/*
 				 * must have a target for the signal
 				 */
 				if (ctx->ctx_notify_task == NULL) {
+					DBprintk(("no notify_task && PFM_REGFL_OVFL_NOTIFY\n"));
 					ret = -EINVAL;
 					goto abort_mission;
 				}
@@ -1206,14 +1307,11 @@
 			ctx->ctx_soft_pmds[cnum].reset_pmds[1] = tmp.reg_reset_pmds[1];
 			ctx->ctx_soft_pmds[cnum].reset_pmds[2] = tmp.reg_reset_pmds[2];
 			ctx->ctx_soft_pmds[cnum].reset_pmds[3] = tmp.reg_reset_pmds[3];
-
-			/*
-			 * needed in case the user does not initialize the equivalent
-			 * PMD. Clearing is done in reset_pmu() so there is no possible
-			 * leak here.
-			 */
-			CTX_USED_PMD(ctx, cnum);
 		}
+		/*
+		 * execute write checker, if any
+		 */
+		if (PMC_WR_FUNC(cnum)) ret = PMC_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
 abort_mission:
 		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
 
@@ -1233,14 +1331,21 @@
 		 */
 		if (ret != 0) {
 			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
-				  ta->pid, cnum, tmp.reg_value, reg_retval));
+				  task->pid, cnum, tmp.reg_value, reg_retval));
 			break;
 		}
 
 		/* 
 		 * We can proceed with this register!
 		 */
-		
+
+		/*
+		 * Needed in case the user does not initialize the equivalent
+		 * PMD. Clearing is done in reset_pmu() so there is no possible
+		 * leak here.
+		 */
+		CTX_USED_PMD(ctx, pmu_conf.pmc_desc[cnum].dep_pmd[0]);
+
 		/* 
 		 * keep copy the pmc, used for register reload
 		 */
@@ -1248,17 +1353,17 @@
 
 		ia64_set_pmc(cnum, tmp.reg_value);
 
-		DBprintk(("[%d] pmc[%u]=0x%lx flags=0x%x save_pmcs=0%lx reload_pmcs=0x%lx\n", 
-			  ta->pid, cnum, tmp.reg_value, 
+		DBprintk(("[%d] pmc[%u]=0x%lx flags=0x%x used_pmds=0x%lx\n", 
+			  task->pid, cnum, tmp.reg_value, 
 			  ctx->ctx_soft_pmds[cnum].flags, 
-			  ctx->ctx_saved_pmcs[0], ctx->ctx_reload_pmcs[0]));
+			  ctx->ctx_used_pmds[0]));
 
 	}
 	return ret;
 }
 
 static int
-pfm_write_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	unsigned int cnum;
@@ -1266,7 +1371,7 @@
 	int ret = 0, reg_retval = 0;
 
 	/* we don't quite support this right now */
-	if (ta != current) return -EINVAL;
+	if (task != current) return -EINVAL;
 
 	/* 
 	 * Cannot do anything before PMU is enabled 
@@ -1281,7 +1386,6 @@
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
 		cnum = tmp.reg_num;
-
 		if (!PMD_IS_IMPL(cnum)) {
 			ret = -EINVAL;
 			goto abort_mission;
@@ -1295,6 +1399,10 @@
 			ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset;
 
 		}
+		/*
+		 * execute write checker, if any
+		 */
+		if (PMD_WR_FUNC(cnum)) ret = PMD_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
 abort_mission:
 		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
 
@@ -1311,21 +1419,24 @@
 		 */
 		if (ret != 0) {
 			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
-				  ta->pid, cnum, tmp.reg_value, reg_retval));
+				  task->pid, cnum, tmp.reg_value, reg_retval));
 			break;
 		}
 
 		/* keep track of what we use */
-		CTX_USED_PMD(ctx, cnum);
+		CTX_USED_PMD(ctx, pmu_conf.pmd_desc[(cnum)].dep_pmd[0]);
+		/* mark this register as used as well */
+		CTX_USED_PMD(ctx, RDEP(cnum));
 
 		/* writes to unimplemented part is ignored, so this is safe */
-		ia64_set_pmd(cnum, tmp.reg_value);
+		ia64_set_pmd(cnum, tmp.reg_value & pmu_conf.perf_ovfl_val);
 
 		/* to go away */
 		ia64_srlz_d();
+
 		DBprintk(("[%d] pmd[%u]: soft_pmd=0x%lx  short_reset=0x%lx "
 			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx\n",
-				ta->pid, cnum,
+				task->pid, cnum,
 				ctx->ctx_soft_pmds[cnum].val,
 				ctx->ctx_soft_pmds[cnum].short_reset,
 				ctx->ctx_soft_pmds[cnum].long_reset,
@@ -1338,12 +1449,13 @@
 }
 
 static int
-pfm_read_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &ta->thread;
+	struct thread_struct *th = &task->thread;
 	unsigned long val=0;
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
-	int i;
+	unsigned int cnum;
+	int i, ret = 0;
 
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
@@ -1356,14 +1468,25 @@
 
 	/* XXX: ctx locking may be required here */
 
-	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), ta->pid));
+	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
 
 	for (i = 0; i < count; i++, req++) {
-		unsigned long reg_val = ~0UL, ctx_val = ~0UL;
+		unsigned long ctx_val = ~0UL;
 
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		if (!PMD_IS_IMPL(tmp.reg_num)) goto abort_mission;
+		cnum = tmp.reg_num;
+
+		if (!PMD_IS_IMPL(cnum)) goto abort_mission;
+		/*
+		 * we can only read the register that we use. That includes
+		 * the one we explicitely initialize AND the one we want included
+		 * in the sampling buffer (smpl_regs).
+		 *
+		 * Having this restriction allows optimization in the ctxsw routine
+		 * without compromising security (leaks)
+		 */
+		if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission;
 
 		/*
 		 * If the task is not the current one, then we check if the
@@ -1372,8 +1495,8 @@
 		 */
 		if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){
 			ia64_srlz_d();
-			val = reg_val = ia64_get_pmd(tmp.reg_num);
-			DBprintk(("reading pmd[%u]=0x%lx from hw\n", tmp.reg_num, val));
+			val = ia64_get_pmd(cnum);
+			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
 #ifdef CONFIG_SMP
 			int cpu;
@@ -1389,30 +1512,35 @@
 			 */
 			cpu = atomic_read(&ctx->ctx_last_cpu);
 			if (cpu != -1) {
-				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, ta->pid));
-				pfm_fetch_regs(cpu, ta, ctx);
+				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid));
+				pfm_fetch_regs(cpu, task, ctx);
 			}
 #endif
 			/* context has been saved */
-			val = reg_val = th->pmd[tmp.reg_num];
+			val = th->pmd[cnum];
 		}
-		if (PMD_IS_COUNTING(tmp.reg_num)) {
+		if (PMD_IS_COUNTING(cnum)) {
 			/*
 			 * XXX: need to check for overflow
 			 */
 
 			val &= pmu_conf.perf_ovfl_val;
-			val += ctx_val = ctx->ctx_soft_pmds[tmp.reg_num].val;
-		} else {
+			val += ctx_val = ctx->ctx_soft_pmds[cnum].val;
+		} 
 
-			val = reg_val = ia64_get_pmd(tmp.reg_num);
-		}
-		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
 		tmp.reg_value = val;
 
-		DBprintk(("read pmd[%u] soft_pmd=0x%lx reg=0x%lx pmc=0x%lx\n", 
-					tmp.reg_num, ctx_val, reg_val, 
-					ia64_get_pmc(tmp.reg_num)));
+		/*
+		 * execute read checker, if any
+		 */
+		if (PMD_RD_FUNC(cnum)) {
+			ret = PMD_RD_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
+		}
+
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, ret);
+
+		DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n", 
+					cnum, ret, val, ia64_get_pmc(cnum)));
 
 		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
 	}
@@ -1420,7 +1548,7 @@
 abort_mission:
 	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
 	/* 
-	 * XXX: if this fails, we stick we the original failure, flag not updated!
+	 * XXX: if this fails, we stick with the original failure, flag not updated!
 	 */
 	copy_to_user(req, &tmp, sizeof(tmp));
 	return -EINVAL;
@@ -1455,15 +1583,11 @@
 	 */
 	if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1;
 
-	/*
-	 * XXX: not pretty
-	 */
 	LOCK_PFS();
 
 	/*
-	 * We only allow the use of debug registers when there is no system
-	 * wide monitoring 
-	 * XXX: we could relax this by 
+	 * We cannot allow setting breakpoints when system wide monitoring
+	 * sessions are using the debug registers.
 	 */
 	if (pfm_sessions.pfs_sys_use_dbregs> 0)
 		ret = -1;
@@ -1516,6 +1640,7 @@
 {
 	return 0;
 }
+
 int
 pfm_release_debug_registers(struct task_struct *task)
 {
@@ -1534,12 +1659,6 @@
 	 */
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
-
-	if (ctx->ctx_fl_frozen==0) {
-		printk("task %d without pmu_frozen set\n", task->pid);
-		return -EINVAL;
-	}
-
 	if (task == current) {
 		DBprintk(("restarting self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen));
 
@@ -1656,25 +1775,35 @@
 				current->pid,
 				ctx->ctx_fl_system, PMU_OWNER(),
 				current));
+
 	/* simply stop monitoring but not the PMU */
 	if (ctx->ctx_fl_system) {
 
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
-
 		/* disable dcr pp */
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
+		/* stop monitoring */
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+		ia64_srlz_i();
+
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_dcr_pp  = 0;
 #else
 		pfm_tasklist_toggle_pp(0);
 #endif
-
 		ia64_psr(regs)->pp = 0;
 
 	} else {
+
+		/* stop monitoring */
 		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
 
+		ia64_srlz_i();
+
+		/*
+		 * clear user level psr.up
+		 */
 		ia64_psr(regs)->up = 0;
 	}
 	return 0;
@@ -1701,7 +1830,7 @@
 		ia64_psr(regs)->up = 0;
 	}
 	/* 
-	 * goes back to default behavior 
+	 * goes back to default behavior: no user level control
 	 * no need to change live psr.sp because useless at the kernel level
 	 */
 	ia64_psr(regs)->sp = 1;
@@ -1713,10 +1842,8 @@
 	return 0;
 }
 
-
-
 static int
-pfm_destroy_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+pfm_context_destroy(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
 	/* we don't quite support this right now */
@@ -1742,15 +1869,14 @@
 		ia64_psr(regs)->up = 0;
 	}
 
-	/* restore security level */
-	ia64_psr(regs)->sp = 1;
-
 skipped_stop:
 	/*
 	 * remove sampling buffer mapping, if any
 	 */
-	if (ctx->ctx_smpl_vaddr) pfm_remove_smpl_mapping(task);
-
+	if (ctx->ctx_smpl_vaddr) {
+		pfm_remove_smpl_mapping(task);
+		ctx->ctx_smpl_vaddr = 0UL;
+	}
 	/* now free context and related state */
 	pfm_context_exit(task);
 
@@ -1761,7 +1887,7 @@
  * does nothing at the moment
  */
 static int
-pfm_unprotect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+pfm_context_unprotect(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
 	return 0;
@@ -1791,9 +1917,9 @@
 {
 	unsigned int mode = *(unsigned int *)arg;
 
-	pfm_debug_mode = mode == 0 ? 0 : 1;
+	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk("perfmon debugging %s\n", pfm_debug_mode ? "on" : "off");
+	printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
 
 	return 0;
 }
@@ -1863,8 +1989,8 @@
 	if (ctx->ctx_fl_system) {
 		/* we mark ourselves as owner  of the debug registers */
 		ctx->ctx_fl_using_dbreg = 1;
-	} else {
-       		if (ctx->ctx_fl_using_dbreg == 0) {
+		DBprintk(("system-wide setting fl_using_dbreg for [%d]\n", task->pid));
+	} else if (first_time) {
 			ret= -EBUSY;
 			if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) {
 				DBprintk(("debug registers already in use for [%d]\n", task->pid));
@@ -1873,6 +1999,7 @@
 			/* we mark ourselves as owner  of the debug registers */
 			ctx->ctx_fl_using_dbreg = 1;
 
+			DBprintk(("setting fl_using_dbreg for [%d]\n", task->pid));
 			/* 
 			 * Given debug registers cannot be used for both debugging 
 			 * and performance monitoring at the same time, we reuse
@@ -1880,18 +2007,27 @@
 			 */
 			memset(task->thread.dbr, 0, sizeof(task->thread.dbr));
 			memset(task->thread.ibr, 0, sizeof(task->thread.ibr));
+	}
 
-			/*
-			 * clear hardware registers to make sure we don't leak
-			 * information and pick up stale state
-			 */
-			for (i=0; i < pmu_conf.num_ibrs; i++) {
-				ia64_set_ibr(i, 0UL);
-			}
-			for (i=0; i < pmu_conf.num_dbrs; i++) {
-				ia64_set_dbr(i, 0UL);
-			}
+	if (first_time) {
+		DBprintk(("[%d] clearing ibrs,dbrs\n", task->pid));
+		/*
+	 	 * clear hardware registers to make sure we don't
+	 	 * pick up stale state. 
+		 *
+		 * for a system wide session, we do not use
+		 * thread.dbr, thread.ibr because this process
+		 * never leaves the current CPU and the state
+		 * is shared by all processes running on it
+	 	 */
+		for (i=0; i < pmu_conf.num_ibrs; i++) {
+			ia64_set_ibr(i, 0UL);
+		}
+		ia64_srlz_i();
+		for (i=0; i < pmu_conf.num_dbrs; i++) {
+			ia64_set_dbr(i, 0UL);
 		}
+		ia64_srlz_d();
 	}
 
 	ret = -EFAULT;
@@ -1951,6 +2087,7 @@
 			CTX_USED_IBR(ctx, rnum);
 
 			ia64_set_ibr(rnum, dbreg.val);
+			ia64_srlz_i();
 
 			thread->ibr[rnum] = dbreg.val;
 
@@ -1959,6 +2096,7 @@
 			CTX_USED_DBR(ctx, rnum);
 
 			ia64_set_dbr(rnum, dbreg.val);
+			ia64_srlz_d();
 
 			thread->dbr[rnum] = dbreg.val;
 
@@ -2058,27 +2196,35 @@
 
 	if (ctx->ctx_fl_system) {
 		
-		/* enable dcr pp */
-		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
-
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_dcr_pp  = 1;
 #else
 		pfm_tasklist_toggle_pp(1);
 #endif
+		/* set user level psr.pp */
 		ia64_psr(regs)->pp = 1;
 
+		/* start monitoring at kernel level */
 		__asm__ __volatile__ ("ssm psr.pp;;"::: "memory");
 
+		/* enable dcr pp */
+		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
+
+		ia64_srlz_i();
+
 	} else {
 		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
 			printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid);
 			return -EINVAL;
 		}
+		/* set user level psr.up */
 		ia64_psr(regs)->up = 1;
+
+		/* start monitoring at kernel level */
 		__asm__ __volatile__ ("sum psr.up;;"::: "memory");
+
+		ia64_srlz_i();
 	}
-	ia64_srlz_d();
 
 	return 0;
 }
@@ -2101,7 +2247,9 @@
 		ia64_psr(regs)->pp = 0;
 		ia64_psr(regs)->up = 0; /* just to make sure! */
 
+		/* make sure monitoring is stopped */
 		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+		ia64_srlz_i();
 
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_syst_wide = 1;
@@ -2116,21 +2264,21 @@
 		ia64_psr(regs)->pp = 0; /* just to make sure! */
 		ia64_psr(regs)->up = 0;
 
+		/* make sure monitoring is stopped */
 		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
-		/*
-		 * allow user control (user monitors only)
-		if (task  == ctx->ctx_owner) {
-		 */
-		{
-			DBprintk(("clearing psr.sp for [%d]\n", current->pid));
-			ia64_psr(regs)->sp = 0;
-		}
+		ia64_srlz_i();
+
+		DBprintk(("clearing psr.sp for [%d]\n", current->pid));
+
+		/* allow user level control  */
+		ia64_psr(regs)->sp = 0;
+
+		/* PMU state will be saved/restored on ctxsw */
 		task->thread.flags |= IA64_THREAD_PM_VALID;
 	}
 
 	SET_PMU_OWNER(task);
 
-
 	ctx->ctx_flags.state = PFM_CTX_ENABLED;
 	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
 
@@ -2141,6 +2289,40 @@
 	return 0;
 }
 
+static int
+pfm_get_pmc_reset(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	   struct pt_regs *regs)
+{
+	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	unsigned int cnum;
+	int i;
+
+	for (i = 0; i < count; i++, req++) {
+
+		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+
+		cnum = tmp.reg_num;
+
+		if (!PMC_IS_IMPL(cnum)) goto abort_mission;
+
+		tmp.reg_value = reset_pmcs[cnum];
+
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
+
+		DBprintk(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, tmp.reg_value)); 
+
+		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
+	}
+	return 0;
+abort_mission:
+	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
+	/* 
+	 * XXX: if this fails, we stick with the original failure, flag not updated!
+	 */
+	copy_to_user(req, &tmp, sizeof(tmp));
+	return -EINVAL;
+}
+
 /*
  * functions MUST be listed in the increasing order of their index (see permfon.h)
  */
@@ -2148,19 +2330,19 @@
 /* 0  */{ NULL, 0, 0, 0}, /* not used */
 /* 1  */{ pfm_write_pmcs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)}, 
 /* 2  */{ pfm_write_pmds, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
-/* 3  */{ pfm_read_pmds, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
+/* 3  */{ pfm_read_pmds,PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)}, 
 /* 4  */{ pfm_stop, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
 /* 5  */{ pfm_start, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
 /* 6  */{ pfm_enable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
 /* 7  */{ pfm_disable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 8  */{ pfm_create_context, PFM_CMD_ARG_READ, 1, sizeof(pfarg_context_t)},
-/* 9  */{ pfm_destroy_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 8  */{ pfm_context_create, PFM_CMD_PID|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, 1, sizeof(pfarg_context_t)},
+/* 9  */{ pfm_context_destroy, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
 /* 10 */{ pfm_restart, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_NOCHK, 0, 0},
 /* 11 */{ pfm_protect_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
 /* 12 */{ pfm_get_features, PFM_CMD_ARG_WRITE, 0, 0},
 /* 13 */{ pfm_debug, 0, 1, sizeof(unsigned int)},
-/* 14 */{ pfm_unprotect_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 15 */{ NULL, 0, 0, 0}, /* not used */
+/* 14 */{ pfm_context_unprotect, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 15 */{ pfm_get_pmc_reset, PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
 /* 16 */{ NULL, 0, 0, 0}, /* not used */
 /* 17 */{ NULL, 0, 0, 0}, /* not used */
 /* 18 */{ NULL, 0, 0, 0}, /* not used */
@@ -2222,9 +2404,9 @@
 {
 	struct pt_regs *regs = (struct pt_regs *)&stack;
 	struct task_struct *task = current;
-	pfm_context_t *ctx = task->thread.pfm_context;
+	pfm_context_t *ctx;
 	size_t sz;
-	int ret = -ESRCH, narg;
+	int ret, narg;
 
 	/* 
 	 * reject any call if perfmon was disabled at initialization time
@@ -2254,6 +2436,8 @@
 
 		if (pid != current->pid) {
 
+			ret = -ESRCH;
+
 			read_lock(&tasklist_lock);
 
 			task = find_task_by_pid(pid);
@@ -2268,10 +2452,11 @@
 				ret = check_task_state(task);
 				if (ret != 0) goto abort_call;
 			}
-			ctx = task->thread.pfm_context;
-		}
+		} 
 	} 
 
+	ctx = task->thread.pfm_context;
+
 	if (PFM_CMD_USE_CTX(cmd)) {
 		ret = -EINVAL;
 	       if (ctx == NULL) {
@@ -2387,9 +2572,9 @@
 	int j;
 
 
-pfm_recorded_samples_count++;
+
 	idx = ia64_fetch_and_add(1, &psb->psb_index);
-	DBprintk(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
+	DBprintk_ovfl(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
 
 	/*
 	* XXX: there is a small chance that we could run out on index before resetting
@@ -2409,7 +2594,7 @@
 	/*
 	 * initialize entry header
 	 */
-	h->pid  = task->pid;
+	h->pid  = current->pid;
 	h->cpu  = smp_processor_id();
 	h->rate = 0; /* XXX: add the sampling rate used here */
 	h->ip   = regs ? regs->cr_iip : 0x0;	/* where did the fault happened */
@@ -2437,24 +2622,27 @@
 		} else {
 			*e = ia64_get_pmd(j); /* slow */
 		}
-		DBprintk(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
+		DBprintk_ovfl(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
 		e++;
 	}
+	pfm_stats.pfm_recorded_samples_count++;
+
 	/*
 	 * make the new entry visible to user, needs to be atomic
 	 */
 	ia64_fetch_and_add(1, &psb->psb_hdr->hdr_count);
 
-	DBprintk(("index=%ld entries=%ld hdr_count=%ld\n", 
+	DBprintk_ovfl(("index=%ld entries=%ld hdr_count=%ld\n", 
 				idx, psb->psb_entries, psb->psb_hdr->hdr_count));
 	/* 
 	 * sampling buffer full ? 
 	 */
 	if (idx == (psb->psb_entries-1)) {
-		DBprintk(("sampling buffer full\n"));
+		DBprintk_ovfl(("sampling buffer full\n"));
 		/*
 		 * XXX: must reset buffer in blocking mode and lost notified
 		 */
+		pfm_stats.pfm_full_smpl_buffer_count++;
 		return 1;
 	}
 	return 0;
@@ -2467,15 +2655,13 @@
  *	new value of pmc[0]. if 0x0 then unfreeze, else keep frozen
  */
 static unsigned long
-pfm_overflow_handler(struct task_struct *task, u64 pmc0, struct pt_regs *regs)
+pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
 {
 	unsigned long mask;
 	struct thread_struct *t;
-	pfm_context_t *ctx;
 	unsigned long old_val;
 	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
 	int i;
-	int my_cpu = smp_processor_id();
 	int ret = 1;
 	struct siginfo si;
 	/*
@@ -2491,18 +2677,7 @@
 	 * valid one, i.e. the one that caused the interrupt.
 	 */
 
-	if (task == NULL) {
-		DBprintk(("owners[%d]=NULL\n", my_cpu));
-		return 0x1;
-	}
 	t   = &task->thread;
-	ctx = task->thread.pfm_context;
-
-	if (!ctx) {
-		printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
-			task->pid);
-		return 0;
-	}
 
 	/*
 	 * XXX: debug test
@@ -2524,12 +2699,12 @@
 
 	mask = pmc0 >> PMU_FIRST_COUNTER;
 
-	DBprintk(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
-		  " mode used_pmds=0x%lx save_pmcs=0x%lx reload_pmcs=0x%lx\n", 
+	DBprintk_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
+		  " mode used_pmds=0x%lx used_pmcs=0x%lx reload_pmcs=0x%lx\n", 
 			pmc0, task->pid, (regs ? regs->cr_iip : 0), 
 			CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
 			ctx->ctx_used_pmds[0],
-			ctx->ctx_saved_pmcs[0],
+			ctx->ctx_used_pmcs[0],
 			ctx->ctx_reload_pmcs[0]));
 
 	/*
@@ -2540,7 +2715,7 @@
 		/* skip pmd which did not overflow */
 		if ((mask & 0x1) == 0) continue;
 
-		DBprintk(("PMD[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
+		DBprintk_ovfl(("pmd[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
 			  i, ia64_get_pmd(i), ctx->ctx_soft_pmds[i].val));
 
 		/*
@@ -2552,8 +2727,7 @@
 		old_val = ctx->ctx_soft_pmds[i].val;
 		ctx->ctx_soft_pmds[i].val = 1 + pmu_conf.perf_ovfl_val + pfm_read_soft_counter(ctx, i);
 
-
-		DBprintk(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx\n", 
+		DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx\n", 
 			  i, ctx->ctx_soft_pmds[i].val, old_val, 
 			  ia64_get_pmd(i) & pmu_conf.perf_ovfl_val));
 
@@ -2570,7 +2744,7 @@
 
 			ovfl_pmds |= 1UL << i;
 
-			DBprintk(("soft_pmd[%d] overflowed flags=0x%x, ovfl=0x%lx\n", i, ctx->ctx_soft_pmds[i].flags, ovfl_pmds));
+			DBprintk_ovfl(("soft_pmd[%d] overflowed flags=0x%x, ovfl=0x%lx\n", i, ctx->ctx_soft_pmds[i].flags, ovfl_pmds));
 
 			if (PMC_OVFL_NOTIFY(ctx, i)) {
 				ovfl_notify |= 1UL << i;
@@ -2609,7 +2783,8 @@
 	 * No overflow requiring a user level notification
 	 */
 	if (ovfl_notify == 0UL) {
-		pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
+		if (ovfl_pmds) 
+			pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
 		return 0x0;
 	}
 
@@ -2684,7 +2859,7 @@
 	 	 * necessarily go to the signal handler (if any) when it goes back to
 	 	 * user mode.
 	 	 */
-		DBprintk(("[%d] sending notification to [%d]\n", 
+		DBprintk_ovfl(("[%d] sending notification to [%d]\n", 
 			  task->pid, ctx->ctx_notify_task->pid));
 
 
@@ -2717,7 +2892,7 @@
 		 * before, changing it to NULL will still maintain this invariant.
 		 * Of course, when it is equal to current it cannot change at this point.
 		 */
-		DBprintk(("block=%d notify [%d] current [%d]\n", 
+		DBprintk_ovfl(("block=%d notify [%d] current [%d]\n", 
 			ctx->ctx_fl_block,
 			ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
 			current->pid ));
@@ -2728,7 +2903,7 @@
 	} else {
 lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */
 
-		DBprintk(("notification task has disappeared !\n"));
+		DBprintk_ovfl(("notification task has disappeared !\n"));
 		/*
 		 * for a non-blocking context, we make sure we do not fall into the 
 		 * pfm_overflow_notify() trap. Also in the case of a blocking context with lost 
@@ -2750,7 +2925,7 @@
 	 */
 	ctx->ctx_fl_frozen = 1;
 
-	DBprintk(("reload pmc0=0x%x must_block=%ld\n",
+	DBprintk_ovfl(("return pmc0=0x%x must_block=%ld\n",
 				ctx->ctx_fl_frozen ? 0x1 : 0x0, t->pfm_ovfl_block_reset));
 
 	return ctx->ctx_fl_frozen ? 0x1 : 0x0;
@@ -2761,8 +2936,9 @@
 {
 	u64 pmc0;
 	struct task_struct *task;
+	pfm_context_t *ctx;
 
-	pfm_ovfl_intr_count++;
+	pfm_stats.pfm_ovfl_intr_count++;
 
 	/* 
 	 * srlz.d done before arriving here
@@ -2776,24 +2952,54 @@
 	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
 	 */
 	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
-
 		/* 
-		 * assumes, PMC[0].fr = 1 at this point 
-		 *
-		 * XXX: change protype to pass &pmc0
+		 * we assume that pmc0.fr is always set here
 		 */
-		pmc0 = pfm_overflow_handler(task, pmc0, regs);
+		ctx = task->thread.pfm_context;
 
-		/* we never explicitely freeze PMU here */
-		if (pmc0 == 0) {
-			ia64_set_pmc(0, 0);
-			ia64_srlz_d();
+		/* sanity check */
+		if (!ctx) {
+			printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
+				task->pid);
+			return;
 		}
+#ifdef CONFIG_SMP
+		/*
+		 * Because an IPI has higher priority than the PMU overflow interrupt, it is 
+		 * possible that the handler be interrupted by a request from another CPU to fetch 
+		 * the PMU state of the currently active context. The task may have just been 
+		 * migrated to another CPU which is trying to restore the context. If there was
+		 * a pending overflow interrupt when the task left this CPU, it is possible for
+		 * the handler to get interrupt by the IPI. In which case, we fetch request
+		 * MUST be postponed until the interrupt handler is done. The ctx_is_busy
+		 * flag indicates such a condition. The other CPU must busy wait until it's cleared.
+		 */
+		atomic_set(&ctx->ctx_is_busy, 1);
+#endif
+
+		/* 
+		 * assume PMC[0].fr = 1 at this point 
+		 */
+		pmc0 = pfm_overflow_handler(task, ctx, pmc0, regs);
+
+		/*
+		 * We always clear the overflow status bits and either unfreeze
+		 * or keep the PMU frozen.
+		 */
+		ia64_set_pmc(0, pmc0);
+		ia64_srlz_d();
+
+#ifdef CONFIG_SMP
+		/*
+		 * announce that we are doing with the context
+		 */
+		atomic_set(&ctx->ctx_is_busy, 0);
+#endif
 	} else {
-		pfm_spurious_ovfl_intr_count++;
+		pfm_stats.pfm_spurious_ovfl_intr_count++;
 
-		DBprintk(("perfmon: Spurious PMU overflow interrupt on CPU%d: pmc0=0x%lx owner=%p\n", 
-			smp_processor_id(), pmc0, (void *)PMU_OWNER()));
+		printk("perfmon: Spurious PMU overflow interrupt on CPU%d: pmc0=0x%lx owner=%p\n", 
+			smp_processor_id(), pmc0, (void *)PMU_OWNER());
 	}
 }
 
@@ -2801,33 +3007,31 @@
 static int
 perfmon_proc_info(char *page)
 {
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)        1
-#endif
 	char *p = page;
-	u64 pmc0 = ia64_get_pmc(0);
 	int i;
 
-	p += sprintf(p, "perfmon enabled: %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes");
-
-	p += sprintf(p, "monitors_pmcs0]=0x%lx\n", pmu_conf.monitor_pmcs[0]);
-	p += sprintf(p, "counter_pmcds[0]=0x%lx\n", pmu_conf.counter_pmds[0]);
-	p += sprintf(p, "overflow interrupts=%lu\n", pfm_ovfl_intr_count);
-	p += sprintf(p, "spurious overflow interrupts=%lu\n", pfm_spurious_ovfl_intr_count);
-	p += sprintf(p, "recorded samples=%lu\n", pfm_recorded_samples_count);
-
-	p += sprintf(p, "CPU%d.pmc[0]=%lx\nPerfmon debug: %s\n", 
-			smp_processor_id(), pmc0, pfm_debug_mode ? "On" : "Off");
+	p += sprintf(p, "enabled          : %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes");
+	p += sprintf(p, "fastctxsw        : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
+	p += sprintf(p, "ovfl_mask        : 0x%lx\n", pmu_conf.perf_ovfl_val);
+	p += sprintf(p, "overflow intrs   : %lu\n", pfm_stats.pfm_ovfl_intr_count);
+	p += sprintf(p, "spurious intrs   : %lu\n", pfm_stats.pfm_spurious_ovfl_intr_count);
+	p += sprintf(p, "recorded samples : %lu\n", pfm_stats.pfm_recorded_samples_count);
+	p += sprintf(p, "smpl buffer full : %lu\n", pfm_stats.pfm_full_smpl_buffer_count);
 
 #ifdef CONFIG_SMP
-	p += sprintf(p, "CPU%d cpu_data.pfm_syst_wide=%d cpu_data.dcr_pp=%d\n", 
-			smp_processor_id(), local_cpu_data->pfm_syst_wide, local_cpu_data->pfm_dcr_pp);
+	p += sprintf(p, "CPU%d syst_wide   : %d\n"
+			"CPU%d dcr_pp      : %d\n", 
+			smp_processor_id(), 
+			local_cpu_data->pfm_syst_wide, 
+			smp_processor_id(), 
+			local_cpu_data->pfm_dcr_pp);
 #endif
 
 	LOCK_PFS();
-	p += sprintf(p, "proc_sessions=%lu\nsys_sessions=%lu\nsys_use_dbregs=%lu\nptrace_use_dbregs=%lu\n", 
+	p += sprintf(p, "proc_sessions    : %lu\n"
+			"sys_sessions     : %lu\n"
+			"sys_use_dbregs   : %lu\n"
+			"ptrace_use_dbregs: %lu\n", 
 			pfm_sessions.pfs_task_sessions, 
 			pfm_sessions.pfs_sys_sessions,
 			pfm_sessions.pfs_sys_use_dbregs,
@@ -2837,12 +3041,28 @@
 
 	for(i=0; i < NR_CPUS; i++) {
 		if (cpu_is_online(i)) {
-			p += sprintf(p, "CPU%d.pmu_owner: %-6d\n",
+			p += sprintf(p, "CPU%d owner : %-6d\n",
 					i, 
 					pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
 		}
 	}
 
+	for(i=0; pmd_desc[i].type != PFM_REG_NONE; i++) {
+		p += sprintf(p, "PMD%-2d: %d 0x%lx 0x%lx\n", 
+				i,
+				pmd_desc[i].type, 
+				pmd_desc[i].dep_pmd[0], 
+				pmd_desc[i].dep_pmc[0]); 
+	}
+
+	for(i=0; pmc_desc[i].type != PFM_REG_NONE; i++) {
+		p += sprintf(p, "PMC%-2d: %d 0x%lx 0x%lx\n", 
+				i, 
+				pmc_desc[i].type, 
+				pmc_desc[i].dep_pmd[0], 
+				pmc_desc[i].dep_pmc[0]); 
+	}
+
 	return p - page;
 }
 
@@ -2901,6 +3121,7 @@
 	 * It will be restored from ipsr when going back to user level
 	 */
 	__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+	ia64_srlz_i();
 
 	ctx->ctx_saved_psr = psr;
 
@@ -2956,13 +3177,9 @@
 	for (i=0; mask; i++, mask>>=1) {
 		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
 	}
-	/*
-	 * XXX: simplify to pmc0 only
-	 */
-	mask = ctx->ctx_saved_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmc[i] = ia64_get_pmc(i);
-	}
+
+	/* save pmc0 */
+	t->pmc[0] = ia64_get_pmc(0);
 
 	/* not owned by this CPU */
 	atomic_set(&ctx->ctx_last_cpu, -1);
@@ -3000,6 +3217,12 @@
 		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
 		  atomic_read(&ctx->ctx_saving_in_progress)));
 
+	/* must wait until not busy before retrying whole request */
+	if (atomic_read(&ctx->ctx_is_busy)) {
+		arg->retval = 2;
+		return;
+	}
+
 	/* must wait if saving was interrupted */
 	if (atomic_read(&ctx->ctx_saving_in_progress)) {
 		arg->retval = 1;
@@ -3012,9 +3235,9 @@
 		return;
 	}
 
-	DBprintk(("saving state for [%d] save_pmcs=0x%lx all_pmcs=0x%lx used_pmds=0x%lx\n", 
+	DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", 
 		arg->task->pid,
-		ctx->ctx_saved_pmcs[0],
+		ctx->ctx_used_pmcs[0],
 		ctx->ctx_reload_pmcs[0],
 		ctx->ctx_used_pmds[0]));
 
@@ -3027,17 +3250,15 @@
 
 	/*
 	 * XXX needs further optimization.
-	 * Also must take holes into account
 	 */
 	mask = ctx->ctx_used_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
-	}
-	
-	mask = ctx->ctx_saved_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmc[i] = ia64_get_pmc(i);
+		if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i);
 	}
+
+	/* save pmc0 */
+	t->pmc[0] = ia64_get_pmc(0);
+
 	/* not owned by this CPU */
 	atomic_set(&ctx->ctx_last_cpu, -1);
 
@@ -3066,11 +3287,17 @@
 	arg.task   = task;
 	arg.retval = -1;
 
+	if (atomic_read(&ctx->ctx_is_busy)) {
+must_wait_busy:
+		while (atomic_read(&ctx->ctx_is_busy));
+	}
+
 	if (atomic_read(&ctx->ctx_saving_in_progress)) {
 		DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
-
+must_wait_saving:
 		/* busy wait */
 		while (atomic_read(&ctx->ctx_saving_in_progress));
+		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
 		return;
 	}
 	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
@@ -3090,11 +3317,8 @@
 	 * This is the case, where we interrupted the saving which started just at the time we sent the
 	 * IPI.
 	 */
-	if (arg.retval == 1) {
-		DBprintk(("must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
-		while (atomic_read(&ctx->ctx_saving_in_progress));
-		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
-	}
+	if (arg.retval == 1) goto must_wait_saving;
+	if (arg.retval == 2) goto must_wait_busy;
 }
 #endif /* CONFIG_SMP */
 
@@ -3113,6 +3337,30 @@
 
 	owner = PMU_OWNER();
 	ctx   = task->thread.pfm_context;
+	t     = &task->thread;
+
+	/*
+	 * we restore ALL the debug registers to avoid picking up 
+	 * stale state.
+	 *
+	 * This must be done even when the task is still the owner
+	 * as the registers may have been modified via ptrace()
+	 * (not perfmon) by the previous task. 
+	 *
+	 * XXX: dealing with this in a lazy fashion requires modifications
+	 * to the way the the debug registers are managed. This is will done
+	 * in the next version of perfmon.
+	 */
+	if (ctx->ctx_fl_using_dbreg) {
+		for (i=0; i < pmu_conf.num_ibrs; i++) {
+			ia64_set_ibr(i, t->ibr[i]);
+		}
+		ia64_srlz_i();
+		for (i=0; i < pmu_conf.num_dbrs; i++) {
+			ia64_set_dbr(i, t->dbr[i]);
+		}
+		ia64_srlz_d();
+	}
 
 	/*
 	 * if we were the last user, then nothing to do except restore psr
@@ -3148,55 +3396,37 @@
 		pfm_fetch_regs(cpu, task, ctx);
 	}
 #endif
-	t   = &task->thread;
 
 	/*
-	 * XXX: will be replaced by assembly routine
-	 * We clear all unused PMDs to avoid leaking information
+	 * To avoid leaking information to the user level when psr.sp=0,
+	 * we must reload ALL implemented pmds (even the ones we don't use).
+	 * In the kernel we only allow PFM_READ_PMDS on registers which
+	 * we initialized or requested (sampling) so there is no risk there.
+	 *
+	 * As an optimization, we will only reload the PMD that we use when 
+	 * the context is in protected mode, i.e. psr.sp=1 because then there
+	 * is no leak possible.
 	 */
-	mask = ctx->ctx_used_pmds[0];
+	mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) 
-			ia64_set_pmd(i, t->pmd[i]);
-		else
-			ia64_set_pmd(i, 0UL);
+		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.perf_ovfl_val);
 	}
-	/* XXX: will need to clear all unused pmd, for security */
 
 	/* 
-	 * skip pmc[0] to avoid side-effects, 
-	 * all PMCs are systematically reloaded, unsued get default value
-	 * to avoid picking up stale configuration
+	 * PMC0 is never set in the mask because it is always restored
+	 * separately.  
+	 *
+	 * ALL PMCs are systematically reloaded, unused registers
+	 * get their default (PAL reset) values to avoid picking up 
+	 * stale configuration.
 	 */	
-	mask = ctx->ctx_reload_pmcs[0]>>1;
-	for (i=1; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
-	}
-
-	/*
-	 * restore debug registers when used for range restrictions.
-	 * We must restore the unused registers to avoid picking up
-	 * stale information.
-	 */
-	mask = ctx->ctx_used_ibrs[0];
+	mask = ctx->ctx_reload_pmcs[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) 
-			ia64_set_ibr(i, t->ibr[i]);
-		else
-			ia64_set_ibr(i, 0UL);
-	}
-
-	mask = ctx->ctx_used_dbrs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) 
-			ia64_set_dbr(i, t->dbr[i]);
-		else
-			ia64_set_dbr(i, 0UL);
+		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
 	}
 
 	if (t->pmc[0] & ~0x1) {
-		ia64_srlz_d();
-		pfm_overflow_handler(task, t->pmc[0], NULL);
+		pfm_overflow_handler(task, ctx, t->pmc[0], NULL);
 	}
 
 	/*
@@ -3249,7 +3479,7 @@
 			 * When restoring context, we must restore ALL pmcs, even the ones 
 			 * that the task does not use to avoid leaks and possibly corruption
 			 * of the sesion because of configuration conflicts. So here, we 
-			 * initializaed the table used in the context switch restore routine.
+			 * initialize the entire set used in the context switch restore routine.
 	 		 */
 			t->pmc[i] = reset_pmcs[i];
 			DBprintk((" pmc[%d]=0x%lx\n", i, reset_pmcs[i]));
@@ -3258,39 +3488,61 @@
 	}
 	/*
 	 * clear reset values for PMD. 
-	 * XX: good up to 64 PMDS. Suppose that zero is a valid value.
+	 * XXX: good up to 64 PMDS. Suppose that zero is a valid value.
 	 */
 	mask = pmu_conf.impl_regs[4];
 	for(i=0; mask; mask>>=1, i++) {
 		if (mask & 0x1) ia64_set_pmd(i, 0UL);
+		t->pmd[i] = 0UL;
 	}
 
 	/*
-	 * On context switched restore, we must restore ALL pmc even
+	 * On context switched restore, we must restore ALL pmc and ALL pmd even
 	 * when they are not actively used by the task. In UP, the incoming process 
-	 * may otherwise pick up left over PMC state from the previous process.
+	 * may otherwise pick up left over PMC, PMD state from the previous process.
 	 * As opposed to PMD, stale PMC can cause harm to the incoming
 	 * process because they may change what is being measured. 
 	 * Therefore, we must systematically reinstall the entire
 	 * PMC state. In SMP, the same thing is possible on the 
-	 * same CPU but also on between 2 CPUs.
+	 * same CPU but also on between 2 CPUs. 
+	 *
+	 * The problem with PMD is information leaking especially
+	 * to user level when psr.sp=0
 	 *
 	 * There is unfortunately no easy way to avoid this problem
-	 * on either UP or SMP. This definitively slows down the 
-	 * pfm_load_regs(). 
+	 * on either UP or SMP. This definitively slows down the
+	 * pfm_load_regs() function. 
 	 */
 	
 	 /*
 	  * We must include all the PMC in this mask to make sure we don't
-	  * see any side effect of the stale state, such as opcode matching
+	  * see any side effect of a stale state, such as opcode matching
 	  * or range restrictions, for instance.
+	  *
+	  * We never directly restore PMC0 so we do not include it in the mask.
 	  */
-	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0];
+	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0] & ~0x1;
+	/*
+	 * We must include all the PMD in this mask to avoid picking
+	 * up stale value and leak information, especially directly
+	 * at the user level when psr.sp=0
+	 */
+	ctx->ctx_reload_pmds[0] = pmu_conf.impl_regs[4];
+
+	/* 
+	 * Keep track of the pmds we want to sample
+	 * XXX: may be we don't need to save/restore the DEAR/IEAR pmds
+	 * but we do need the BTB for sure. This is because of a hardware
+	 * buffer of 1 only for non-BTB pmds.
+	 *
+	 * We ignore the unimplemented pmds specified by the user
+	 */
+	ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
+	ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[0] */
 
 	/*
 	 * useful in case of re-enable after disable
 	 */
-	ctx->ctx_used_pmds[0] = 0UL;
 	ctx->ctx_used_ibrs[0] = 0UL;
 	ctx->ctx_used_dbrs[0] = 0UL;
 
@@ -3312,7 +3564,7 @@
 {
 	pfm_context_t *ctx;
 	u64 pmc0;
-	unsigned long mask, mask2, val;
+	unsigned long mask2, val;
 	int i;
 
 	ctx = task->thread.pfm_context;
@@ -3334,22 +3586,28 @@
 	 */
 	if (ctx->ctx_fl_system) {
 
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
 
 		/* disable dcr pp */
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
+		/* stop monitoring */
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+		ia64_srlz_i();
+
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_syst_wide = 0;
 		local_cpu_data->pfm_dcr_pp    = 0;
 #else
 		pfm_tasklist_toggle_pp(0);
 #endif
-
 	} else  {
 
+		/* stop monitoring */
 		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
 
+		ia64_srlz_i();
+
 		/* no more save/restore on ctxsw */
 		current->thread.flags &= ~IA64_THREAD_PM_VALID;
 	}
@@ -3383,7 +3641,7 @@
 	ia64_srlz_d();
 
 	/*
-	 * We don't need to restore psr, because we are on our way out anyway
+	 * We don't need to restore psr, because we are on our way out
 	 */
 
 	/*
@@ -3399,10 +3657,12 @@
 	if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) 
 		printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu));
 
-	mask  = pmc0 >> PMU_FIRST_COUNTER;
-	mask2 = ctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
-
-	for (i = PMU_FIRST_COUNTER; mask2; i++, mask>>=1, mask2>>=1) {
+	/*
+	 * we save all the used pmds
+	 * we take care of overflows for pmds used as counters
+	 */
+	mask2 = ctx->ctx_used_pmds[0];
+	for (i = 0; mask2; i++, mask2>>=1) {
 
 		/* skip non used pmds */
 		if ((mask2 & 0x1) == 0) continue;
@@ -3410,7 +3670,6 @@
 		val = ia64_get_pmd(i);
 
 		if (PMD_IS_COUNTING(i)) {
-
 			DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", task->pid, i, ctx->ctx_soft_pmds[i].val, val & pmu_conf.perf_ovfl_val));
 
 			/* collect latest results */
@@ -3423,15 +3682,19 @@
 			 */
 			task->thread.pmd[i] = 0;
 
-			/* take care of overflow inline */
-			if (mask & 0x1) {
+			/* 
+			 * take care of overflow inline
+			 */
+			if (pmc0 & (1UL << i)) {
 				ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
 				DBprintk(("[%d] pmd[%d] overflowed soft_pmd=0x%lx\n",
 					task->pid, i, ctx->ctx_soft_pmds[i].val));
 			}
 		} else {
 			DBprintk(("[%d] pmd[%d] hw_pmd=0x%lx\n", task->pid, i, val));
-			/* not a counter, just save value as is */
+			/* 
+			 * not a counter, just save value as is
+			 */
 			task->thread.pmd[i] = val;
 		}
 	}
@@ -3449,31 +3712,73 @@
 int
 pfm_inherit(struct task_struct *task, struct pt_regs *regs)
 {
-	pfm_context_t *ctx = current->thread.pfm_context;
+	pfm_context_t *ctx;
 	pfm_context_t *nctx;
-	struct thread_struct *th = &task->thread;
+	struct thread_struct *thread;
 	unsigned long m;
 	int i;
 
 	/*
+	 * the new task was copied from parent and therefore points
+	 * to the parent's context at this point
+	 */
+	ctx    = task->thread.pfm_context;
+	thread = &task->thread;
+
+	/*
 	 * make sure child cannot mess up the monitoring session
 	 */
 	 ia64_psr(regs)->sp = 1;
 	 DBprintk(("enabling psr.sp for [%d]\n", task->pid));
 
-	 /*
-	  * remove any sampling buffer mapping from child user 
-	  * address space. Must be done for all cases of inheritance.
-	  */
-	 if (ctx->ctx_smpl_vaddr) pfm_remove_smpl_mapping(task);
+
+	/*
+	 * if there was a virtual mapping for the sampling buffer
+	 * the mapping is NOT inherited across fork() (see VM_DONTCOPY), 
+	 * so we don't have to explicitely remove it here. 
+	 *
+	 *
+	 * Part of the clearing of fields is also done in
+	 * copy_thread() because the fiels are outside the
+	 * pfm_context structure and can affect tasks not
+	 * using perfmon.
+	 */
+
+	/* clear pending notification */
+	task->thread.pfm_ovfl_block_reset = 0;
+
+	/*
+	 * clear cpu pinning restriction for child
+	 */
+	if (ctx->ctx_fl_system) {
+		task->cpus_allowed = ctx->ctx_saved_cpus_allowed;
+		task->need_resched = 1;
+
+	 	DBprintk(("setting cpus_allowed for [%d] to 0x%lx from 0x%lx\n", 
+			task->pid,
+			ctx->ctx_saved_cpus_allowed, 
+			current->cpus_allowed));
+	}
 
 	/*
 	 * takes care of easiest case first
 	 */
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_NONE) {
+
 		DBprintk(("removing PFM context for [%d]\n", task->pid));
-		task->thread.pfm_context     = NULL;
-		task->thread.pfm_ovfl_block_reset  = 0;
+
+		task->thread.pfm_context = NULL;
+
+		/* 
+		 * we must clear psr.up because the new child does
+		 * not have a context and the PM_VALID flag is cleared
+		 * in copy_thread().
+		 *
+		 * we do not clear psr.pp because it is always
+		 * controlled by the system wide logic and we should
+		 * never be here when system wide is running anyway
+		 */
+	 	ia64_psr(regs)->up = 0;
 
 		/* copy_thread() clears IA64_THREAD_PM_VALID */
 		return 0;
@@ -3487,69 +3792,82 @@
 
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
 		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
-		atomic_set(&nctx->ctx_last_cpu, -1);
-
-		/*
-		 * task is not yet visible in the tasklist, so we do 
-		 * not need to lock the newly created context.
-		 * However, we must grab the tasklist_lock to ensure
-		 * that the ctx_owner or ctx_notify_task do not disappear
-		 * while we increment their check counters.
-		 */
-		read_lock(&tasklist_lock);
+		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
+	}
+	/*
+	 * task is not yet visible in the tasklist, so we do 
+	 * not need to lock the newly created context.
+	 * However, we must grab the tasklist_lock to ensure
+	 * that the ctx_owner or ctx_notify_task do not disappear
+	 * while we increment their check counters.
+	 */
+	read_lock(&tasklist_lock);
 
-		if (nctx->ctx_notify_task) 
-			atomic_inc(&nctx->ctx_notify_task->thread.pfm_notifiers_check);
+	if (nctx->ctx_notify_task) 
+		atomic_inc(&nctx->ctx_notify_task->thread.pfm_notifiers_check);
 
-		if (nctx->ctx_owner)
-			atomic_inc(&nctx->ctx_owner->thread.pfm_owners_check);
+	if (nctx->ctx_owner)
+		atomic_inc(&nctx->ctx_owner->thread.pfm_owners_check);
 
-		read_unlock(&tasklist_lock);
+	read_unlock(&tasklist_lock);
 
-		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
 
-		LOCK_PFS();
-		pfm_sessions.pfs_task_sessions++;
-		UNLOCK_PFS();
-	}
+	LOCK_PFS();
+	pfm_sessions.pfs_task_sessions++;
+	UNLOCK_PFS();
 
 	/* initialize counters in new context */
-	m = pmu_conf.counter_pmds[0] >> PMU_FIRST_COUNTER;
+	m = nctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
 	for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) {
-		if (m & 0x1) {
+		if ((m & 0x1) && pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING) {
 			nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].ival & ~pmu_conf.perf_ovfl_val;
-			th->pmd[i]	      	   = nctx->ctx_soft_pmds[i].ival & pmu_conf.perf_ovfl_val;
+			thread->pmd[i]	      	   = nctx->ctx_soft_pmds[i].ival & pmu_conf.perf_ovfl_val;
 		}
+		/* what about the other pmds? zero or keep as is */
 
 	}
-	/* clear BTB index register */
-	th->pmd[16] = 0;
+	/*
+	 * clear BTB index register
+	 * XXX: CPU-model specific knowledge!
+	 */
+	thread->pmd[16] = 0;
 
-	/* if sampling then increment number of users of buffer */
-	if (nctx->ctx_psb) {
 
-		/*
-		 * XXX: nopt very pretty!
-		 */
+	nctx->ctx_fl_frozen    = 0;
+	nctx->ctx_ovfl_regs[0] = 0UL;
+	atomic_set(&nctx->ctx_last_cpu, -1);
+
+	/*
+	 * here nctx->ctx_psb == ctx->ctx_psb
+	 *
+	 * increment reference count to sampling
+	 * buffer, if any. Note that this is independent
+	 * from the virtual mapping. The latter is never
+	 * inherited while the former will be if context
+	 * is setup to something different from PFM_FL_INHERIT_NONE
+	 */
+	if (nctx->ctx_psb) {
 		LOCK_PSB(nctx->ctx_psb);
+
 		nctx->ctx_psb->psb_refcnt++;
+
+	 	DBprintk(("updated smpl @ %p refcnt=%lu psb_flags=0x%x\n", 
+			ctx->ctx_psb->psb_hdr,
+			ctx->ctx_psb->psb_refcnt,
+			ctx->ctx_psb->psb_flags));
+
 		UNLOCK_PSB(nctx->ctx_psb);
+
 		/*
 	 	 * remove any pointer to sampling buffer mapping
 	 	 */
 		nctx->ctx_smpl_vaddr = 0;
 	}
 
-	nctx->ctx_fl_frozen = 0;
-	nctx->ctx_ovfl_regs[0] = 0UL;
-
 	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
 
-	/* clear pending notification */
-	th->pfm_ovfl_block_reset = 0;
-
 	/* link with new task */
-	th->pfm_context    = nctx;
+	thread->pfm_context = nctx;
 
 	DBprintk(("nctx=%p for process [%d]\n", (void *)nctx, task->pid));
 
@@ -3559,7 +3877,7 @@
 	 */
 	if (current->thread.flags & IA64_THREAD_PM_VALID) {
 		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
-		th->flags |= IA64_THREAD_PM_VALID;
+		thread->flags |= IA64_THREAD_PM_VALID;
 	}
 
 	return 0;
@@ -3588,9 +3906,9 @@
 
 		LOCK_PSB(psb);
 
-		DBprintk(("sampling buffer from [%d] @%p size %ld vma_flag=0x%x\n",
+		DBprintk(("sampling buffer from [%d] @%p size %ld refcnt=%lu psb_flags=0x%x\n",
 			task->pid,
-			psb->psb_hdr, psb->psb_size, psb->psb_flags));
+			psb->psb_hdr, psb->psb_size, psb->psb_refcnt, psb->psb_flags));
 
 		/*
 		 * in the case where we are the last user, we may be able to free
@@ -3613,7 +3931,7 @@
 			 *
 			 * See pfm_vm_close() and pfm_cleanup_smpl_buf() for more details.
 			 */
-			if ((psb->psb_flags & PFM_PSB_VMA) == 0) {
+			if ((psb->psb_flags & PSB_HAS_VMA) == 0) {
 
 				DBprintk(("cleaning sampling buffer from [%d] @%p size %ld\n",
 					task->pid,
@@ -3645,7 +3963,7 @@
 	 * direct pointer to a task structure thereby bypassing the tasklist. 
 	 * We must make sure that, if we have task!= NULL, the target task is still 
 	 * present and is identical to the initial task specified 
-	 * during pfm_create_context(). It may already be detached from the tasklist but 
+	 * during pfm_context_create(). It may already be detached from the tasklist but 
 	 * that's okay. Note that it is okay if we miss the deadline and the task scans 
 	 * the list for nothing, it will affect performance but not correctness. 
 	 * The correctness is ensured by using the ctx_lock which prevents the 
@@ -3683,7 +4001,8 @@
 		pfm_sessions.pfs_sys_session[ctx->ctx_cpu] = NULL;
 		pfm_sessions.pfs_sys_sessions--;
 		DBprintk(("freeing syswide session on CPU%ld\n", ctx->ctx_cpu));
-		/* update perfmon debug register counter */
+
+		/* update perfmon debug register usage counter */
 		if (ctx->ctx_fl_using_dbreg) {
 			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
 				printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid);
@@ -3795,6 +4114,8 @@
 		}
 	}
 	read_unlock(&tasklist_lock);
+
+	atomic_set(&task->thread.pfm_owners_check, 0);
 }
 
 
@@ -3852,6 +4173,8 @@
 		}
 	}
 	read_unlock(&tasklist_lock);
+
+	atomic_set(&task->thread.pfm_notifiers_check, 0);
 }
 
 static struct irqaction perfmon_irqaction = {
@@ -3870,6 +4193,12 @@
 		if (i >= pmu_conf.num_pmcs) break;
 		if (PMC_IS_IMPL(i)) reset_pmcs[i] = ia64_get_pmc(i);
 	}
+#ifdef CONFIG_MCKINLEY
+	/*
+	 * set the 'stupid' enable bit to power the PMU!
+	 */
+	reset_pmcs[4] |= 1UL << 23;
+#endif
 }
 
 /*
@@ -3881,11 +4210,6 @@
 	pal_perf_mon_info_u_t pm_info;
 	s64 status;
 
-	register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
-
-	ia64_set_pmv(IA64_PERFMON_VECTOR);
-	ia64_srlz_d();
-
 	pmu_conf.pfm_is_disabled = 1;
 
 	printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n", 
@@ -3937,23 +4261,12 @@
 	 */
 	pfm_pmu_snapshot();
 
-	/* 
-	 * list the pmc registers used to control monitors 
-	 * XXX: unfortunately this information is not provided by PAL
-	 *
-	 * We start with the architected minimum and then refine for each CPU model
-	 */
-	pmu_conf.monitor_pmcs[0] = PMM(4)|PMM(5)|PMM(6)|PMM(7);
-
 	/*
-	 * architected counters
+	 * setup the register configuration descriptions for the CPU
 	 */
-	pmu_conf.counter_pmds[0] |= PMM(4)|PMM(5)|PMM(6)|PMM(7);
+	pmu_conf.pmc_desc = pmc_desc;
+	pmu_conf.pmd_desc = pmd_desc;
 
-#ifdef CONFIG_ITANIUM
-	pmu_conf.monitor_pmcs[0] |= PMM(10)|PMM(11)|PMM(12);
-	/* Itanium does not add more counters */
-#endif
 	/* we are all set */
 	pmu_conf.pfm_is_disabled = 0;
 
@@ -3962,6 +4275,8 @@
 	 */
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
 
+	pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root, 0);
+
 	spin_lock_init(&pfm_sessions.pfs_lock);
 
 	return 0;
@@ -3972,11 +4287,13 @@
 void
 perfmon_init_percpu (void)
 {
+	if (smp_processor_id() == 0)
+		register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+
 	ia64_set_pmv(IA64_PERFMON_VECTOR);
 	ia64_srlz_d();
 }
 
-
 #else /* !CONFIG_PERFMON */
 
 asmlinkage int
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_generic.h linux-2.4.20/arch/ia64/kernel/perfmon_generic.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_generic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/perfmon_generic.h	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,29 @@
+#define RDEP(x)	(1UL<<(x))
+
+#ifdef CONFIG_ITANIUM
+#error "This file should not be used when CONFIG_ITANIUM is defined"
+#endif
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd1  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd2  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd3  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_itanium.h linux-2.4.20/arch/ia64/kernel/perfmon_itanium.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_itanium.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/perfmon_itanium.h	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * This file contains the Itanium PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright (C) 2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#define RDEP(x)	(1UL<<(x))
+
+#ifndef CONFIG_ITANIUM
+#error "This file is only valid when CONFIG_ITANIUM is defined"
+#endif
+
+static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, pfm_ita_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd1  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd2  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd3  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+/* pmd8  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd9  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static int
+pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+{
+	pfm_context_t *ctx = task->thread.pfm_context;
+	int ret;
+
+	/*
+	 * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+
+	/*
+	 * we must clear the (data) debug registers if pmc11.pt bit is cleared
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+	return 0;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_mckinley.h linux-2.4.20/arch/ia64/kernel/perfmon_mckinley.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_mckinley.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/perfmon_mckinley.h	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,134 @@
+/*
+ * This file contains the McKinley PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright (C) 2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#define RDEP(x)	(1UL<<(x))
+
+#ifndef CONFIG_MCKINLEY
+#error "This file is only valid when CONFIG_MCKINLEY is defined"
+#endif
+
+static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 6, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_MONITOR, 4, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc14 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc15 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd1  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd2  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd3  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+/* pmd8  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd9  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static int
+pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+{
+	struct thread_struct *th = &task->thread;
+	pfm_context_t *ctx = task->thread.pfm_context;
+	int ret = 0, check_case1 = 0;
+	unsigned long val8 = 0, val14 = 0, val13 = 0;
+
+	/*
+	 * we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled 
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+	/* 
+	 * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled 
+	 * before they are (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		if (ret) return ret;
+
+	}
+
+	switch(cnum) {
+		case  4: *val |= 1UL << 23; /* force power enable bit */
+			 break;
+		case  8: val8 = *val;
+			 val13 = th->pmc[13];
+			 val14 = th->pmc[14];
+			 check_case1 = 1;
+			 break;
+		case 13: val8  = th->pmc[8];
+			 val13 = *val;
+			 val14 = th->pmc[14];
+			 check_case1 = 1;
+			 break;
+		case 14: val8  = th->pmc[13];
+			 val13 = th->pmc[13];
+			 val14 = *val;
+			 check_case1 = 1;
+			 break;
+	}
+	/* check illegal configuration which can produce inconsistencies in tagging
+	 * i-side events in L1D and L2 caches
+	 */
+	if (check_case1) {
+		ret =   ((val13 >> 45) & 0xf) == 0 
+		   && ((val8 & 0x1) == 0)
+		   && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
+		       ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
+
+		if (ret) printk("perfmon: failure check_case1\n");
+	}
+
+	return ret ? -EINVAL : 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/process.c linux-2.4.20/arch/ia64/kernel/process.c
--- linux-2.4.19/arch/ia64/kernel/process.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/process.c	2002-10-04 00:41:20.000000000 +0000
@@ -18,9 +18,9 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/efi.h>
 
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/perfmon.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -174,8 +174,10 @@
 # endif
 #endif
 
+#ifdef CONFIG_IA32_SUPPORT
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_save_state(task);
+#endif
 }
 
 void
@@ -194,8 +196,10 @@
 # endif
 #endif
 
+#ifdef CONFIG_IA32_SUPPORT
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_load_state(task);
+#endif
 }
 
 /*
@@ -297,21 +301,24 @@
 
 	/* copy parts of thread_struct: */
 	p->thread.ksp = (unsigned long) child_stack - 16;
+
+	/* stop some PSR bits from being inherited: */
+	child_ptregs->cr_ipsr =  ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
+				  & ~IA64_PSR_BITS_TO_CLEAR);
+
 	/*
-	 * NOTE: The calling convention considers all floating point
-	 * registers in the high partition (fph) to be scratch.  Since
-	 * the only way to get to this point is through a system call,
-	 * we know that the values in fph are all dead.  Hence, there
-	 * is no need to inherit the fph state from the parent to the
-	 * child and all we have to do is to make sure that
-	 * IA64_THREAD_FPH_VALID is cleared in the child.
+	 * NOTE: The calling convention considers all floating point registers in the high
+	 * partition (fph) to be scratch.  Since the only way to get to this point is
+	 * through a system call, we know that the values in fph are all dead.  Hence,
+	 * there is no need to inherit the fph state from the parent to the child and all
+	 * we have to do is to make sure that IA64_THREAD_FPH_VALID is cleared in the
+	 * child.
 	 *
-	 * XXX We could push this optimization a bit further by
-	 * clearing IA64_THREAD_FPH_VALID on ANY system call.
-	 * However, it's not clear this is worth doing.  Also, it
-	 * would be a slight deviation from the normal Linux system
-	 * call behavior where scratch registers are preserved across
-	 * system calls (unless used by the system call itself).
+	 * XXX We could push this optimization a bit further by clearing
+	 * IA64_THREAD_FPH_VALID on ANY system call.  However, it's not clear this is
+	 * worth doing.  Also, it would be a slight deviation from the normal Linux system
+	 * call behavior where scratch registers are preserved across system calls (unless
+	 * used by the system call itself).
 	 */
 #	define THREAD_FLAGS_TO_CLEAR	(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
 					 | IA64_THREAD_PM_VALID)
@@ -333,8 +340,11 @@
 	 */
 	atomic_set(&p->thread.pfm_notifiers_check, 0);
 	atomic_set(&p->thread.pfm_owners_check, 0);
+	/* clear list of sampling buffer to free for new task */
+	p->thread.pfm_smpl_buf_list = NULL;
 
-	if (current->thread.pfm_context) retval = pfm_inherit(p, child_ptregs);
+	if (current->thread.pfm_context)
+		retval = pfm_inherit(p, child_ptregs);
 #endif
 	return retval;
 }
@@ -537,14 +547,13 @@
 		ia64_set_fpu_owner(0);
 #endif
 #ifdef CONFIG_PERFMON
-       /* if needed, stop monitoring and flush state to perfmon context */
-	if (current->thread.pfm_context) 
+       /* stop monitoring */
+	if (current->thread.pfm_context)
 		pfm_flush_regs(current);
 
 	/* free debug register resources */
-	if ((current->thread.flags & IA64_THREAD_DBG_VALID) != 0) {
+	if (current->thread.flags & IA64_THREAD_DBG_VALID)
 		pfm_release_debug_registers(current);
-	}
 #endif
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/salinfo.c linux-2.4.20/arch/ia64/kernel/salinfo.c
--- linux-2.4.19/arch/ia64/kernel/salinfo.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/salinfo.c	2002-10-04 00:41:18.000000000 +0000
@@ -0,0 +1,105 @@
+/*
+ * salinfo.c
+ *
+ * Creates entries in /proc/sal for various system features.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * 10/30/2001	jbarnes@sgi.com		copied much of Stephane's palinfo
+ *					code to create this file
+ */
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+
+#include <asm/sal.h>
+
+MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
+MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
+MODULE_LICENSE("GPL");
+
+static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+typedef struct {
+	const char		*name;		/* name of the proc entry */
+	unsigned long           feature;        /* feature bit */
+	struct proc_dir_entry	*entry;		/* registered entry (removal) */
+} salinfo_entry_t;
+
+/*
+ * List {name,feature} pairs for every entry in /proc/sal/<feature>
+ * that this module exports
+ */
+static salinfo_entry_t salinfo_entries[]={
+	{ "bus_lock",           IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, },
+	{ "irq_redirection",	IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, },
+	{ "ipi_redirection",	IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, },
+	{ "itc_drift",		IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, },
+};
+
+#define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t))
+
+/*
+ * One for each feature and one more for the directory entry...
+ */
+static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1];
+
+static int __init
+salinfo_init(void)
+{
+	struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */
+	struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
+	int i;
+
+	salinfo_dir = proc_mkdir("sal", NULL);
+
+	for (i=0; i < NR_SALINFO_ENTRIES; i++) {
+		/* pass the feature bit in question as misc data */
+		*sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
+						  salinfo_read, (void *)salinfo_entries[i].feature);
+	}
+	*sdir++ = salinfo_dir;
+
+	return 0;
+}
+
+static void __exit
+salinfo_exit(void)
+{
+	int i = 0;
+
+	for (i = 0; i < NR_SALINFO_ENTRIES ; i++) {
+		if (salinfo_proc_entries[i])
+			remove_proc_entry (salinfo_proc_entries[i]->name, NULL);
+	}
+}
+
+/*
+ * 'data' contains an integer that corresponds to the feature we're
+ * testing
+ */
+static int
+salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+
+	len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n");
+
+	if (len <= off+count) *eof = 1;
+
+	*start = page + off;
+	len   -= off;
+
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+module_init(salinfo_init);
+module_exit(salinfo_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/setup.c linux-2.4.20/arch/ia64/kernel/setup.c
--- linux-2.4.19/arch/ia64/kernel/setup.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/setup.c	2002-10-04 00:41:11.000000000 +0000
@@ -19,6 +19,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 
+#include <linux/acpi.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -28,15 +29,15 @@
 #include <linux/string.h>
 #include <linux/threads.h>
 #include <linux/console.h>
+#include <linux/ioport.h>
+#include <linux/efi.h>
 
-#include <asm/acpi-ext.h>
 #include <asm/ia32.h>
 #include <asm/page.h>
 #include <asm/machvec.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/system.h>
-#include <asm/efi.h>
 #include <asm/mca.h>
 #include <asm/smp.h>
 
@@ -65,6 +66,8 @@
 
 unsigned long ia64_iobase;	/* virtual address for I/O accesses */
 
+unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
+
 #define COMMAND_LINE_SIZE	512
 
 char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
@@ -283,6 +286,7 @@
 setup_arch (char **cmdline_p)
 {
 	extern unsigned long ia64_iobase;
+	unsigned long phys_iobase;
 
 	unw_init();
 
@@ -292,6 +296,7 @@
 
 	efi_init();
 
+	iomem_resource.end = ~0UL;	/* FIXME probably belongs elsewhere */
 	find_memory();
 
 #if 0
@@ -315,24 +320,23 @@
 #endif
 
 	/*
-	 *  Set `iobase' to the appropriate address in region 6
-	 *    (uncached access range)
+	 *  Set `iobase' to the appropriate address in region 6 (uncached access range).
 	 *
-	 *  The EFI memory map is the "prefered" location to get the I/O port
-	 *  space base, rather the relying on AR.KR0. This should become more
-	 *  clear in future SAL specs. We'll fall back to getting it out of
-	 *  AR.KR0 if no appropriate entry is found in the memory map.
+	 *  The EFI memory map is the "preferred" location to get the I/O port space base,
+	 *  rather the relying on AR.KR0. This should become more clear in future SAL
+	 *  specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
+	 *  found in the memory map.
 	 */
-	ia64_iobase = efi_get_iobase();
-	if (ia64_iobase)
+	phys_iobase = efi_get_iobase();
+	if (phys_iobase)
 		/* set AR.KR0 since this is all we use it for anyway */
-		ia64_set_kr(IA64_KR_IO_BASE, ia64_iobase);
+		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
 	else {
-		ia64_iobase = ia64_get_kr(IA64_KR_IO_BASE);
+		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
 		printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n");
-		printk("I/O port base = 0x%lx\n", ia64_iobase);
+		printk("I/O port base = 0x%lx\n", phys_iobase);
 	}
-	ia64_iobase = __IA64_UNCACHED_OFFSET | (ia64_iobase & ~PAGE_OFFSET);
+	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
 
 #ifdef CONFIG_SMP
 	cpu_physical_id(0) = hard_smp_processor_id();
@@ -340,24 +344,31 @@
 
 	cpu_init();	/* initialize the bootstrap CPU */
 
-	if (efi.acpi20) {
-		/* Parse the ACPI 2.0 tables */
-		acpi20_parse(efi.acpi20);
-	} else if (efi.acpi) {
-		/* Parse the ACPI tables */
-		acpi_parse(efi.acpi);
-	}
+#ifdef CONFIG_ACPI_BOOT
+	acpi_boot_init(*cmdline_p);
+#endif
+#ifdef CONFIG_SERIAL_HCDP
 	if (efi.hcdp) {
+		void setup_serial_hcdp(void *);
+
 		/* Setup the serial ports described by HCDP */
 		setup_serial_hcdp(efi.hcdp);
 	}
-
+#endif
 #ifdef CONFIG_VT
-# if defined(CONFIG_VGA_CONSOLE)
-	conswitchp = &vga_con;
-# elif defined(CONFIG_DUMMY_CONSOLE)
+# if defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
 # endif
+# if defined(CONFIG_VGA_CONSOLE)
+	/*
+	 * Non-legacy systems may route legacy VGA MMIO range to system
+	 * memory.  vga_con probes the MMIO hole, so memory looks like
+	 * a VGA device to it.  The EFI memory map can tell us if it's
+	 * memory so we can avoid this problem.
+	 */
+	if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY)
+		conswitchp = &vga_con;
+# endif
 #endif
 
 #ifdef CONFIG_IA64_MCA
@@ -392,7 +403,7 @@
 
 	switch (c->family) {
 	      case 0x07:	memcpy(family, "Itanium", 8); break;
-	      case 0x1f:	memcpy(family, "McKinley", 9); break;
+	      case 0x1f:	memcpy(family, "Itanium 2", 10); break;
 	      default:		sprintf(family, "%u", c->family); break;
 	}
 
@@ -433,7 +444,7 @@
 c_start (struct seq_file *m, loff_t *pos)
 {
 #ifdef CONFIG_SMP
-	while (*pos < NR_CPUS && !(cpu_online_map & (1 << *pos)))
+	while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
 		++*pos;
 #endif
 	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
@@ -570,6 +581,24 @@
 	 */
 	identify_cpu(my_cpu_data);
 
+#ifdef CONFIG_MCKINLEY
+	{
+#define FEATURE_SET 16
+		struct ia64_pal_retval iprv;
+
+		if (my_cpu_data->family == 0x1f) {
+
+			PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0);
+
+			if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80)) {
+
+				PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES,
+				              (iprv.v1 | 0x80), FEATURE_SET, 0);
+			}
+		}
+	}
+#endif
+
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
 
@@ -581,7 +610,7 @@
 	 * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
 	 * be fine).
 	 */
-	ia64_set_dcr(  IA64_DCR_DM | IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
+	ia64_set_dcr(  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
 		     | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC);
 #ifndef CONFIG_SMP
 	ia64_set_fpu_owner(0);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/signal.c linux-2.4.20/arch/ia64/kernel/signal.c
--- linux-2.4.19/arch/ia64/kernel/signal.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/signal.c	2002-10-04 00:41:21.000000000 +0000
@@ -143,9 +143,11 @@
 {
 	if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t)))
 		return -EFAULT;
-	if (from->si_code < 0)
-		return __copy_to_user(to, from, sizeof(siginfo_t));
-	else {
+	if (from->si_code < 0) {
+		if (__copy_to_user(to, from, sizeof(siginfo_t)))
+			return -EFAULT;
+		return 0;
+	} else {
 		int err;
 
 		/*
@@ -559,7 +561,7 @@
 				continue;
 
 			switch (signr) {
-			      case SIGCONT: case SIGCHLD: case SIGWINCH:
+			      case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			      case SIGTSTP: case SIGTTIN: case SIGTTOU:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/smp.c linux-2.4.20/arch/ia64/kernel/smp.c
--- linux-2.4.19/arch/ia64/kernel/smp.c	2001-12-21 17:41:53.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/smp.c	2002-10-04 00:41:30.000000000 +0000
@@ -31,12 +31,12 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/cache.h>
+#include <linux/efi.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/machvec.h>
 
 #include <asm/io.h>
@@ -90,7 +90,7 @@
 handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
 {
 	int this_cpu = smp_processor_id();
-	unsigned long *pending_ipis = &local_cpu_data->ipi_operation;
+	unsigned long *pending_ipis = &local_cpu_data->ipi.operation;
 	unsigned long ops;
 
 	/* Count this now; we may make a call that never returns. */
@@ -149,7 +149,7 @@
 static inline void
 send_IPI_single (int dest_cpu, int op)
 {
-	set_bit(op, &cpu_data(dest_cpu)->ipi_operation);
+	set_bit(op, &cpu_data(dest_cpu)->ipi.operation);
 	platform_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
@@ -212,7 +212,7 @@
 	int cpus = 1;
 
 	if (cpuid == smp_processor_id()) {
-		printk(__FUNCTION__" trying to call self\n");
+		printk("%s: trying to call self\n", __FUNCTION__);
 		return -EBUSY;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/smpboot.c linux-2.4.20/arch/ia64/kernel/smpboot.c
--- linux-2.4.19/arch/ia64/kernel/smpboot.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/smpboot.c	2002-10-04 00:41:14.000000000 +0000
@@ -23,13 +23,13 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/efi.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
 #include <asm/cache.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/machvec.h>
@@ -68,6 +68,7 @@
 
 extern void __init calibrate_delay(void);
 extern void start_ap(void);
+extern unsigned long ia64_iobase;
 
 int cpucount;
 
@@ -344,6 +345,11 @@
 	 */
 	ia64_init_itm();
 
+	/*
+	 * Set I/O port base per CPU
+	 */
+	ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
+
 #ifdef CONFIG_IA64_MCA
 	ia64_mca_cmc_vector_setup();	/* Setup vector on AP & enable */
 	ia64_mca_check_errors();	/* For post-failure MCA error logging */
@@ -528,11 +534,11 @@
 
 		printk("Before bogomips.\n");
 		if (!cpucount) {
-			printk(KERN_ERR "Error: only one processor found.\n");
+			printk(KERN_WARNING "Warning: only one processor found.\n");
 		} else {
 			unsigned long bogosum = 0;
   			for (cpu = 0; cpu < NR_CPUS; cpu++)
-				if (cpu_online_map & (1<<cpu))
+				if (cpu_online_map & (1UL << cpu))
 					bogosum += cpu_data(cpu)->loops_per_jiffy;
 
 			printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/sys_ia64.c linux-2.4.20/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.19/arch/ia64/kernel/sys_ia64.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/sys_ia64.c	2002-10-04 00:41:10.000000000 +0000
@@ -2,8 +2,8 @@
  * This file contains various system calls that have different calling
  * conventions on different platforms.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -201,15 +201,13 @@
 	if (len == 0)
 		goto out;
 
-	/* don't permit mappings into unmapped space or the virtual page table of a region: */
+	/*
+	 * Don't permit mappings into unmapped space, the virtual page table of a region,
+	 * or across a region boundary.  Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
+	 * (for some integer n <= 61) and len > 0.
+	 */
 	roff = rgn_offset(addr);
-	if ((len | roff | (roff + len)) >= RGN_MAP_LIMIT) {
-		addr = -EINVAL;
-		goto out;
-	}
-
-	/* don't permit mappings that would cross a region boundary: */
-	if (rgn_index(addr) != rgn_index(addr + len)) {
+	if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
 		addr = -EINVAL;
 		goto out;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/time.c linux-2.4.20/arch/ia64/kernel/time.c
--- linux-2.4.19/arch/ia64/kernel/time.c	2002-02-25 19:37:53.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/time.c	2002-10-04 00:41:13.000000000 +0000
@@ -15,9 +15,9 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
+#include <linux/efi.h>
 
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/hw_irq.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
@@ -39,21 +39,22 @@
 	extern unsigned long prof_cpu_mask;
 	extern char _stext;
 
+	if (!prof_buffer)
+		return;
+
 	if (!((1UL << smp_processor_id()) & prof_cpu_mask))
 		return;
 
-	if (prof_buffer && current->pid) {
-		ip -= (unsigned long) &_stext;
-		ip >>= prof_shift;
-		/*
-		 * Don't ignore out-of-bounds IP values silently, put them into the last
-		 * histogram slot, so if present, they will show up as a sharp peak.
-		 */
-		if (ip > prof_len - 1)
-			ip = prof_len - 1;
+	ip -= (unsigned long) &_stext;
+	ip >>= prof_shift;
+	/*
+	 * Don't ignore out-of-bounds IP values silently, put them into the last
+	 * histogram slot, so if present, they will show up as a sharp peak.
+	 */
+	if (ip > prof_len - 1)
+		ip = prof_len - 1;
 
-		atomic_inc((atomic_t *) &prof_buffer[ip]);
-	}
+	atomic_inc((atomic_t *) &prof_buffer[ip]);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/traps.c linux-2.4.20/arch/ia64/kernel/traps.c
--- linux-2.4.19/arch/ia64/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/traps.c	2002-10-04 00:41:30.000000000 +0000
@@ -48,10 +48,15 @@
 void __init
 trap_init (void)
 {
-	printk("fpswa interface at %lx\n", ia64_boot_param->fpswa);
-	if (ia64_boot_param->fpswa)
+	if (ia64_boot_param->fpswa) {
 		/* FPSWA fixup: make the interface pointer a kernel virtual address: */
 		fpswa_interface = __va(ia64_boot_param->fpswa);
+		printk("FPSWA interface at 0x%lx, revision %d.%d\n",
+			ia64_boot_param->fpswa,
+			fpswa_interface->revision >> 16,
+			fpswa_interface->revision & 0xffff);
+	} else
+		printk("No FPSWA interface\n");
 }
 
 /*
@@ -185,6 +190,10 @@
 		sig = SIGSEGV; code = __SEGV_PSTKOVF;
 		break;
 
+	      case 0x3f000 ... 0x3ffff:	/* bundle-update in progress */
+		sig = SIGILL; code = __ILL_BNDMOD;
+		break;
+
 	      default:
 		if (break_num < 0x40000 || break_num > 0x100000)
 			die_if_kernel("Bad break", regs, break_num);
@@ -213,7 +222,8 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 
-	printk("<sc%ld(%lx,%lx,%lx,%lx)>\n", regs->r15, arg0, arg1, arg2, arg3);
+	printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+	       regs->r15, arg0, arg1, arg2, arg3);
 	return -ENOSYS;
 }
 
@@ -242,9 +252,9 @@
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
 
-		ia64_set_fpu_owner(current);
 	}
 #endif /* !CONFIG_SMP */
+	ia64_set_fpu_owner(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 		__ia64_load_fpu(current->thread.fph);
 		psr->mfh = 0;
@@ -429,7 +439,7 @@
 	unsigned long code, error = isr;
 	struct siginfo siginfo;
 	char buf[128];
-	int result;
+	int result, sig;
 	static const char *reason[] = {
 		"IA-64 Illegal Operation fault",
 		"IA-64 Privileged Operation fault",
@@ -441,30 +451,14 @@
 		"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
 	};
 
-#if 0
-	/* this is for minimal trust debugging; yeah this kind of stuff is useful at times... */
-
-	if (vector != 25) {
-		static unsigned long last_time;
-		static char count;
-		unsigned long n = vector;
-		char buf[32], *cp;
-
-		if (jiffies - last_time > 5*HZ)
-			count = 0;
-
-		if (count++ < 5) {
-			last_time = jiffies;
-			cp = buf + sizeof(buf);
-			*--cp = '\0';
-			while (n) {
-				*--cp = "0123456789abcdef"[n & 0xf];
-				n >>= 4;
-			}
-			printk("<0x%s>", cp);
-		}
+	if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
+		/*
+		 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
+		 * the lfetch.
+		 */
+		ia64_psr(regs)->ed = 1;
+		return;
 	}
-#endif
 
 	switch (vector) {
 	      case 24: /* General Exception */
@@ -489,6 +483,30 @@
 		break;
 
 	      case 26: /* NaT Consumption */
+		if (user_mode(regs)) {
+			if (((isr >> 4) & 0xf) == 2) {
+				/* NaT page consumption */
+				sig = SIGSEGV;
+				code = SEGV_ACCERR;
+			} else {
+				/* register NaT consumption */
+				sig = SIGILL;
+				code = ILL_ILLOPN;
+			}
+			siginfo.si_signo = sig;
+			siginfo.si_code = code;
+			siginfo.si_errno = 0;
+			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+			siginfo.si_imm = vector;
+			siginfo.si_flags = __ISR_VALID;
+			siginfo.si_isr = isr;
+			force_sig_info(sig, &siginfo, current);
+			return;
+		} else if (done_with_exception(regs))
+			return;
+		sprintf(buf, "NaT consumption");
+		break;
+
 	      case 31: /* Unsupported Data Reference */
 		if (user_mode(regs)) {
 			siginfo.si_signo = SIGILL;
@@ -501,7 +519,7 @@
 			force_sig_info(SIGILL, &siginfo, current);
 			return;
 		}
-		sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference");
+		sprintf(buf, "Unsupported data reference");
 		break;
 
 	      case 29: /* Debug */
@@ -518,16 +536,15 @@
 			if (ia64_psr(regs)->is == 0)
 			  ifa = regs->cr_iip;
 #endif
-			siginfo.si_addr = (void *) ifa;
 			break;
-		      case 35: siginfo.si_code = TRAP_BRANCH; break;
-		      case 36: siginfo.si_code = TRAP_TRACE; break;
+		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
+		      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
 		}
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
 		siginfo.si_flags = 0;
 		siginfo.si_isr = 0;
-		siginfo.si_addr = 0;
+		siginfo.si_addr = (void *) ifa;
 		siginfo.si_imm = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 		return;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unaligned.c linux-2.4.20/arch/ia64/kernel/unaligned.c
--- linux-2.4.19/arch/ia64/kernel/unaligned.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/unaligned.c	2002-10-04 00:41:29.000000000 +0000
@@ -1304,11 +1304,7 @@
 	 * handler into reading an arbitrary kernel addresses...
 	 */
 	if (!user_mode(regs)) {
-#ifdef GAS_HAS_LOCAL_TAGS
-		fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
-#else
-		fix = search_exception_table(regs->cr_iip);
-#endif
+		fix = SEARCH_EXCEPTION_TABLE(regs);
 	}
 	if (user_mode(regs) || fix.cont) {
 		if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unwind.c linux-2.4.20/arch/ia64/kernel/unwind.c
--- linux-2.4.19/arch/ia64/kernel/unwind.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/unwind.c	2002-10-04 00:41:20.000000000 +0000
@@ -634,8 +634,8 @@
 	for (reg = hi; reg >= lo; --reg) {
 		if (reg->where == UNW_WHERE_SPILL_HOME) {
 			reg->where = UNW_WHERE_PSPREL;
-			reg->val = 0x10 - *offp;
-			*offp += regsize;
+			*offp -= regsize;
+			reg->val = *offp;
 		}
 	}
 }
@@ -814,7 +814,8 @@
 	}
 	for (i = 0; i < 20; ++i) {
 		if ((frmask & 1) != 0) {
-			set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
+			int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4;
+			set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
 				sr->region_start + sr->region_len - 1, 0);
 			sr->any_spills = 1;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unwind_i.h linux-2.4.20/arch/ia64/kernel/unwind_i.h
--- linux-2.4.19/arch/ia64/kernel/unwind_i.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/kernel/unwind_i.h	2002-10-04 00:41:17.000000000 +0000
@@ -103,7 +103,7 @@
 	unsigned int in_body : 1;	/* are we inside a body (as opposed to a prologue)? */
 	unsigned long flags;		/* see UNW_FLAG_* in unwind.h */
 
-	u8 *imask;			/* imask of of spill_mask record or NULL */
+	u8 *imask;			/* imask of spill_mask record or NULL */
 	unsigned long pr_val;		/* predicate values */
 	unsigned long pr_mask;		/* predicate mask */
 	long spill_offset;		/* psp-relative offset for spill base */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/Makefile linux-2.4.20/arch/ia64/lib/Makefile
--- linux-2.4.19/arch/ia64/lib/Makefile	2001-07-31 17:30:08.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -11,10 +11,13 @@
 
 obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o					\
 	__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o					\
-	checksum.o clear_page.o csum_partial_copy.o copy_page.o				\
-	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o	\
-	flush.o io.o do_csum.o								\
-	memcpy.o memset.o strlen.o swiotlb.o
+	checksum.o clear_page.o csum_partial_copy.o					\
+	clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o			\
+	flush.o ip_fast_csum.o io.o do_csum.o						\
+	memset.o strlen.o swiotlb.o
+
+obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
+obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
 
 IGNORE_FLAGS_OBJS =	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
 			__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/checksum.c linux-2.4.20/arch/ia64/lib/checksum.c
--- linux-2.4.19/arch/ia64/lib/checksum.c	2001-07-31 17:30:08.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/checksum.c	2002-10-04 00:41:15.000000000 +0000
@@ -66,15 +66,6 @@
 extern unsigned long do_csum (const unsigned char *, long);
 
 /*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- */
-unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
-{
-	return ~do_csum(iph, ihl*4);
-}
-
-/*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/clear_page.S linux-2.4.20/arch/ia64/lib/clear_page.S
--- linux-2.4.19/arch/ia64/lib/clear_page.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/clear_page.S	2002-10-04 00:41:10.000000000 +0000
@@ -1,51 +1,77 @@
 /*
- *
- * Optimized function to clear a page of memory.
- *
- * Inputs:
- *	in0:	address of page
- *
- * Output:
- * 	none
- *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
  *
  * 1/06/01 davidm	Tuned for Itanium.
+ * 2/12/02 kchen	Tuned for both Itanium and McKinley
+ * 3/08/02 davidm	Some more tweaking
  */
+#include <linux/config.h>
+
 #include <asm/asmmacro.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_ITANIUM
+# define L3_LINE_SIZE	64	// Itanium L3 line size
+# define PREFETCH_LINES	9	// magic number
+#else
+# define L3_LINE_SIZE	128	// McKinley L3 line size
+# define PREFETCH_LINES	12	// magic number
+#endif
+
 #define saved_lc	r2
-#define dst0		in0
+#define dst_fetch	r3
 #define dst1		r8
 #define dst2		r9
 #define dst3		r10
-#define dst_fetch	r11
+#define dst4		r11
+
+#define dst_last	r31
 
 GLOBAL_ENTRY(clear_page)
 	.prologue
 	.regstk 1,0,0,0
-	mov r16 = PAGE_SIZE/64-1	// -1 = repeat/until
-	;;
+	mov r16 = PAGE_SIZE/L3_LINE_SIZE-1	// main loop count, -1=repeat/until
 	.save ar.lc, saved_lc
 	mov saved_lc = ar.lc
+
 	.body
-	mov ar.lc = r16
-	adds dst1 = 16, dst0
-	adds dst2 = 32, dst0
-	adds dst3 = 48, dst0
-	adds dst_fetch = 512, dst0
+	mov ar.lc = (PREFETCH_LINES - 1)
+	mov dst_fetch = in0
+	adds dst1 = 16, in0
+	adds dst2 = 32, in0
+	;;
+.fetch:	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
+	adds dst3 = 48, in0		// executing this multiple times is harmless
+	br.cloop.sptk.few .fetch
+	;;
+	addl dst_last = (PAGE_SIZE - PREFETCH_LINES*L3_LINE_SIZE), dst_fetch
+	mov ar.lc = r16			// one L3 line per iteration
+	adds dst4 = 64, in0
+	;;
+#ifdef CONFIG_ITANIUM
+	// Optimized for Itanium
+1:	stf.spill.nta [dst1] = f0, 64
+	stf.spill.nta [dst2] = f0, 64
+	cmp.lt p8,p0=dst_fetch, dst_last
+	;;
+#else
+	// Optimized for McKinley
+1:	stf.spill.nta [dst1] = f0, 64
+	stf.spill.nta [dst2] = f0, 64
+	stf.spill.nta [dst3] = f0, 64
+	stf.spill.nta [dst4] = f0, 128
+	cmp.lt p8,p0=dst_fetch, dst_last
 	;;
-1:	stf.spill.nta [dst0] = f0, 64
 	stf.spill.nta [dst1] = f0, 64
 	stf.spill.nta [dst2] = f0, 64
+#endif
 	stf.spill.nta [dst3] = f0, 64
-
-	lfetch [dst_fetch], 64
-	br.cloop.dptk.few 1b
+(p8)	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
+	br.cloop.sptk.few 1b
 	;;
-	mov ar.lc = r2		// restore lc
+	mov ar.lc = saved_lc		// restore lc
 	br.ret.sptk.many rp
 END(clear_page)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_page.S linux-2.4.20/arch/ia64/lib/copy_page.S
--- linux-2.4.19/arch/ia64/lib/copy_page.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/copy_page.S	2002-10-04 00:41:30.000000000 +0000
@@ -30,6 +30,7 @@
 #define tgt2		r23
 #define srcf		r24
 #define tgtf		r25
+#define tgt_last	r26
 
 #define Nrot		((8*PIPE_DEPTH+7)&~7)
 
@@ -55,18 +56,21 @@
 
 	mov src1=in1
 	adds src2=8,in1
+	mov tgt_last = PAGE_SIZE
 	;;
 	adds tgt2=8,in0
 	add srcf=512,in1
 	mov ar.lc=lcount
 	mov tgt1=in0
 	add tgtf=512,in0
+	add tgt_last = tgt_last, in0
 	;;
 1:
 (p[0])	ld8 t1[0]=[src1],16
 (EPI)	st8 [tgt1]=t1[PIPE_DEPTH-1],16
 (p[0])	ld8 t2[0]=[src2],16
 (EPI)	st8 [tgt2]=t2[PIPE_DEPTH-1],16
+	cmp.ltu p6,p0 = tgtf, tgt_last
 	;;
 (p[0])	ld8 t3[0]=[src1],16
 (EPI)	st8 [tgt1]=t3[PIPE_DEPTH-1],16
@@ -83,8 +87,8 @@
 (p[0])	ld8 t8[0]=[src2],16
 (EPI)	st8 [tgt2]=t8[PIPE_DEPTH-1],16
 
-	lfetch [srcf], 64
-	lfetch [tgtf], 64
+(p6)	lfetch [srcf], 64
+(p6)	lfetch [tgtf], 64
 	br.ctop.sptk.few 1b
 	;;
 	mov pr=saved_pr,0xffffffffffff0000	// restore predicates
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_page_mck.S linux-2.4.20/arch/ia64/lib/copy_page_mck.S
--- linux-2.4.19/arch/ia64/lib/copy_page_mck.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/copy_page_mck.S	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,185 @@
+/*
+ * McKinley-optimized version of copy_page().
+ *
+ * Copyright (C) 2002 Hewlett-Packard Co
+ *	David Mosberger <davidm@hpl.hp.com>
+ *
+ * Inputs:
+ *	in0:	address of target page
+ *	in1:	address of source page
+ * Output:
+ *	no return value
+ *
+ * General idea:
+ *	- use regular loads and stores to prefetch data to avoid consuming M-slot just for
+ *	  lfetches => good for in-cache performance
+ *	- avoid l2 bank-conflicts by not storing into the same 16-byte bank within a single
+ *	  cycle
+ *
+ * Principle of operation:
+ *	First, note that L1 has a line-size of 64 bytes and L2 a line-size of 128 bytes.
+ *	To avoid secondary misses in L2, we prefetch both source and destination with a line-size
+ *	of 128 bytes.  When both of these lines are in the L2 and the first half of the
+ *	source line is in L1, we start copying the remaining words.  The second half of the
+ *	source line is prefetched in an earlier iteration, so that by the time we start
+ *	accessing it, it's also present in the L1.
+ *
+ *	We use a software-pipelined loop to control the overall operation.  The pipeline
+ *	has 2*PREFETCH_DIST+K stages.  The first PREFETCH_DIST stages are used for prefetching
+ *	source cache-lines.  The second PREFETCH_DIST stages are used for prefetching destination
+ *	cache-lines, the last K stages are used to copy the cache-line words not copied by
+ *	the prefetches.  The four relevant points in the pipelined are called A, B, C, D:
+ *	p[A] is TRUE if a source-line should be prefetched, p[B] is TRUE if a destination-line
+ *	should be prefetched, p[C] is TRUE if the second half of an L2 line should be brought
+ *	into L1D and p[D] is TRUE if a cacheline needs to be copied.
+ *
+ *	This all sounds very complicated, but thanks to the modulo-scheduled loop support,
+ *	the resulting code is very regular and quite easy to follow (once you get the idea).
+ *
+ *	As a secondary optimization, the first 2*PREFETCH_DIST iterations are implemented
+ *	as the separate .prefetch_loop.  Logically, this loop performs exactly like the
+ *	main-loop (.line_copy), but has all known-to-be-predicated-off instructions removed,
+ *	so that each loop iteration is faster (again, good for cached case).
+ *
+ *	When reading the code, it helps to keep the following picture in mind:
+ *
+ *	       word 0 word 1
+ *            +------+------+---
+ *	      |	v[x] | 	t1  | ^
+ *	      |	t2   |	t3  | |
+ *	      |	t4   |	t5  | |
+ *	      |	t6   |	t7  | | 128 bytes
+ *     	      |	n[y] | 	t9  | |	(L2 cache line)
+ *	      |	t10  | 	t11 | |
+ *	      |	t12  | 	t13 | |
+ *	      |	t14  | 	t15 | v
+ *	      +------+------+---
+ *
+ *	Here, v[x] is copied by the (memory) prefetch.  n[y] is loaded at p[C]
+ *	to fetch the second-half of the L2 cache line into L1, and the tX words are copied in
+ *	an order that avoids bank conflicts.
+ */
+#include <asm/asmmacro.h>
+#include <asm/page.h>
+
+#define PREFETCH_DIST	8		// McKinley sustains 16 outstanding L2 misses (8 ld, 8 st)
+
+#define src0		r2
+#define src1		r3
+#define dst0		r9
+#define dst1		r10
+#define src_pre_mem	r11
+#define dst_pre_mem	r14
+#define src_pre_l2	r15
+#define dst_pre_l2	r16
+#define t1		r17
+#define t2		r18
+#define t3		r19
+#define t4		r20
+#define t5		t1	// alias!
+#define t6		t2	// alias!
+#define t7		t3	// alias!
+#define t9		t5	// alias!
+#define t10		t4	// alias!
+#define t11		t7	// alias!
+#define t12		t6	// alias!
+#define t14		t10	// alias!
+#define t13		r21
+#define t15		r22
+
+#define saved_lc	r23
+#define saved_pr	r24
+
+#define	A	0
+#define B	(PREFETCH_DIST)
+#define C	(B + PREFETCH_DIST)
+#define D	(C + 3)
+#define N	(D + 1)
+#define Nrot	((N + 7) & ~7)
+
+GLOBAL_ENTRY(copy_page)
+	.prologue
+	alloc r8 = ar.pfs, 2, Nrot-2, 0, Nrot
+
+	.rotr v[2*PREFETCH_DIST], n[D-C+1]
+	.rotp p[N]
+
+	.save ar.lc, saved_lc
+	mov saved_lc = ar.lc
+	.save pr, saved_pr
+	mov saved_pr = pr
+	.body
+
+	mov src_pre_mem = in1
+	mov pr.rot = 0x10000
+	mov ar.ec = 1				// special unrolled loop
+
+	mov dst_pre_mem = in0
+	mov ar.lc = 2*PREFETCH_DIST - 1
+
+	add src_pre_l2 = 8*8, in1
+	add dst_pre_l2 = 8*8, in0
+	add src0 = 8, in1			// first t1 src
+	add src1 = 3*8, in1			// first t3 src
+	add dst0 = 8, in0			// first t1 dst
+	add dst1 = 3*8, in0			// first t3 dst
+	mov t1 = (PAGE_SIZE/128) - (2*PREFETCH_DIST) - 1
+	nop.m 0
+	nop.i 0
+	;;
+	// same as .line_copy loop, but with all predicated-off instructions removed:
+.prefetch_loop:
+(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0
+(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2
+	br.ctop.sptk .prefetch_loop
+	;;
+	cmp.eq p16, p0 = r0, r0			// reset p16 to 1 (br.ctop cleared it to zero)
+	mov ar.lc = t1				// with 64KB pages, t1 is too big to fit in 8 bits!
+	mov ar.ec = N				// # of stages in pipeline
+	;;
+.line_copy:
+(p[D])	ld8 t2 = [src0], 3*8			// M0
+(p[D])	ld8 t4 = [src1], 3*8			// M1
+(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2 prefetch dst from memory
+(p[D])	st8 [dst_pre_l2] = n[D-C], 128		// M3 prefetch dst from L2
+	;;
+(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0 prefetch src from memory
+(p[C])	ld8 n[0] = [src_pre_l2], 128		// M1 prefetch src from L2
+(p[D])	st8 [dst0] =  t1, 8			// M2
+(p[D])	st8 [dst1] =  t3, 8			// M3
+	;;
+(p[D])	ld8  t5 = [src0], 8
+(p[D])	ld8  t7 = [src1], 3*8
+(p[D])	st8 [dst0] =  t2, 3*8
+(p[D])	st8 [dst1] =  t4, 3*8
+	;;
+(p[D])	ld8  t6 = [src0], 3*8
+(p[D])	ld8 t10 = [src1], 8
+(p[D])	st8 [dst0] =  t5, 8
+(p[D])	st8 [dst1] =  t7, 3*8
+	;;
+(p[D])	ld8  t9 = [src0], 3*8
+(p[D])	ld8 t11 = [src1], 3*8
+(p[D])	st8 [dst0] =  t6, 3*8
+(p[D])	st8 [dst1] = t10, 8
+	;;
+(p[D])	ld8 t12 = [src0], 8
+(p[D])	ld8 t14 = [src1], 8
+(p[D])	st8 [dst0] =  t9, 3*8
+(p[D])	st8 [dst1] = t11, 3*8
+	;;
+(p[D])	ld8 t13 = [src0], 4*8
+(p[D])	ld8 t15 = [src1], 4*8
+(p[D])	st8 [dst0] = t12, 8
+(p[D])	st8 [dst1] = t14, 8
+	;;
+(p[D-1])ld8  t1 = [src0], 8
+(p[D-1])ld8  t3 = [src1], 8
+(p[D])	st8 [dst0] = t13, 4*8
+(p[D])	st8 [dst1] = t15, 4*8
+	br.ctop.sptk .line_copy
+	;;
+	mov ar.lc = saved_lc
+	mov pr = saved_pr, -1
+	br.ret.sptk.many rp
+END(copy_page)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_user.S linux-2.4.20/arch/ia64/lib/copy_user.S
--- linux-2.4.19/arch/ia64/lib/copy_user.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/copy_user.S	2002-10-04 00:41:12.000000000 +0000
@@ -237,15 +237,17 @@
 .copy_user_bit##rshift:						\
 1:								\
 	EX(.failure_out,(EPI) st8 [dst1]=tmp,8);		\
-(EPI_1) shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift;	\
-	EX(3f,(p16) ld8 val1[0]=[src1],8);			\
+(EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift;	\
+	EX(3f,(p16) ld8 val1[1]=[src1],8);			\
+(p16)	mov val1[0]=r0;						\
 	br.ctop.dptk 1b;					\
 	;;							\
 	br.cond.sptk.many .diff_align_do_tail;			\
 2:								\
 (EPI)	st8 [dst1]=tmp,8;					\
-(EPI_1)	shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift;	\
+(EPI_1)	shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift;	\
 3:								\
+(p16)	mov val1[1]=r0;						\
 (p16)	mov val1[0]=r0;						\
 	br.ctop.dptk 2b;					\
 	;;							\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/do_csum.S linux-2.4.20/arch/ia64/lib/do_csum.S
--- linux-2.4.19/arch/ia64/lib/do_csum.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/do_csum.S	2002-10-04 00:41:12.000000000 +0000
@@ -8,9 +8,14 @@
  *	in0: address of buffer to checksum (char *)
  *	in1: length of the buffer (int)
  *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
  *
+ * 02/04/22	Ken Chen <kenneth.w.chen@intel.com>
+ *		Data locality study on the checksum buffer.
+ *		More optimization cleanup - remove excessive stop bits.
+ * 02/04/08	David Mosberger <davidm@hpl.hp.com>
+ *		More cleanup and tuning.
  * 01/04/18	Jun Nakajima <jun.nakajima@intel.com>
  *		Clean up and optimize and the software pipeline, loading two
  *		back-to-back 8-byte words per loop. Clean up the initialization
@@ -71,8 +76,6 @@
 //	calculating the Internet checksum.
 //
 // NOT YET DONE:
-//	- use the lfetch instruction to augment the chances of the data being in
-//	  the cache when we need it.
 //	- Maybe another algorithm which would take care of the folding at the
 //	  end in a different manner
 //	- Work with people more knowledgeable than me on the network stack
@@ -80,6 +83,12 @@
 //	  type of packet or alignment we get. Like the ip_fast_csum() routine
 //	  where we know we have at least 20bytes worth of data to checksum.
 //	- Do a better job of handling small packets.
+//	- Note on prefetching: it was found that under various load, i.e. ftp read/write,
+//	  nfs read/write, the L1 cache hit rate is at 60% and L2 cache hit rate is at 99.8%
+//	  on the data that buffer points to (partly because the checksum is often preceded by
+//	  a copy_from_user()).  This finding indiate that lfetch will not be beneficial since
+//	  the data is already in the cache.
+//
 
 #define saved_pfs	r11
 #define hmask		r16
@@ -102,10 +111,6 @@
 #define buf		in0
 #define len		in1
 
-#ifndef CONFIG_IA64_LOAD_LATENCY
-#define CONFIG_IA64_LOAD_LATENCY	2
-#endif
-
 #define LOAD_LATENCY	2	// XXX fix me
 
 #if (LOAD_LATENCY != 1) && (LOAD_LATENCY != 2)
@@ -121,69 +126,70 @@
 GLOBAL_ENTRY(do_csum)
 	.prologue
 	.save ar.pfs, saved_pfs
-	alloc saved_pfs=ar.pfs,2,16,1,16
-	.rotr word1[4], word2[4],result1[4],result2[4]
-	.rotp p[PIPE_DEPTH]
+	alloc saved_pfs=ar.pfs,2,16,0,16
+	.rotr word1[4], word2[4],result1[LOAD_LATENCY+2],result2[LOAD_LATENCY+2]
+	.rotp p[PIPE_DEPTH], pC1[2], pC2[2]
 	mov ret0=r0		// in case we have zero length
 	cmp.lt p0,p6=r0,len	// check for zero length or negative (32bit len)
-	;;			// avoid WAW on CFM
-	mov tmp3=0x7		// a temporary mask/value
+	;;
 	add tmp1=buf,len	// last byte's address
-(p6)	br.ret.spnt.many rp	// return if true (hope we can avoid that)
+	.save pr, saved_pr
+	mov saved_pr=pr		// preserve predicates (rotation)
+(p6)	br.ret.spnt.many rp	// return if zero or negative length
 
-	and firstoff=7,buf	// how many bytes off for first1 element
-	tbit.nz p15,p0=buf,0	// is buf an odd address ?
 	mov hmask=-1		// intialize head mask
-	;;
-	andcm first1=buf,tmp3	// 8byte aligned down address of first1 element
+	tbit.nz p15,p0=buf,0	// is buf an odd address?
+	and first1=-8,buf	// 8-byte align down address of first1 element
+
+	and firstoff=7,buf	// how many bytes off for first1 element
 	mov tmask=-1		// initialize tail mask
-	adds tmp2=-1,tmp1	// last-1
+
 	;;
+	adds tmp2=-1,tmp1	// last-1
 	and lastoff=7,tmp1	// how many bytes off for last element
-	andcm last=tmp2,tmp3	// address of word containing last byte
-	.save pr, saved_pr
-	mov saved_pr=pr		// preserve predicates (rotation)
+	;;
+	sub tmp1=8,lastoff	// complement to lastoff
+	and last=-8,tmp2	// address of word containing last byte
 	;;
 	sub tmp3=last,first1	// tmp3=distance from first1 to last
+	.save ar.lc, saved_lc
+	mov saved_lc=ar.lc	// save lc
 	cmp.eq p8,p9=last,first1	// everything fits in one word ?
-	sub tmp1=8,lastoff	// complement to lastoff
-	ld8 firstval=[first1],8	// load,ahead of time, "first1" word
+
+	ld8 firstval=[first1],8	// load, ahead of time, "first1" word
+	and tmp1=7, tmp1	// make sure that if tmp1==8 -> tmp1=0
 	shl tmp2=firstoff,3	// number of bits
 	;;
-	and tmp1=7, tmp1	// make sure that if tmp1==8 -> tmp1=0
-(p9)	ld8 lastval=[last]	// load,ahead of time, "last" word, if needed
+(p9)	ld8 lastval=[last]	// load, ahead of time, "last" word, if needed
+	shl tmp1=tmp1,3		// number of bits
 (p9)	adds tmp3=-8,tmp3	// effectively loaded
 	;;
 (p8)	mov lastval=r0		// we don't need lastval if first1==last
-	shl tmp1=tmp1,3		// number of bits
 	shl hmask=hmask,tmp2	// build head mask, mask off [0,first1off[
-	;;
 	shr.u tmask=tmask,tmp1	// build tail mask, mask off ]8,lastoff]
-	.save ar.lc, saved_lc
-	mov saved_lc=ar.lc	// save lc
 	;;
 	.body
 #define count tmp3
 
 (p8)	and hmask=hmask,tmask	// apply tail mask to head mask if 1 word only
 (p9)	and word2[0]=lastval,tmask	// mask last it as appropriate
-	shr.u count=count,3	// we do 8 bytes per loop (count)
+	shr.u count=count,3	// how many 8-byte?
 	;;
 	// If count is odd, finish this 8-byte word so that we can
 	// load two back-to-back 8-byte words per loop thereafter.
-	tbit.nz p10,p11=count,0		// if (count is odd)
 	and word1[0]=firstval,hmask	// and mask it as appropriate
+	tbit.nz p10,p11=count,0		// if (count is odd)
 	;;
 (p8)	mov result1[0]=word1[0]
 (p9)	add result1[0]=word1[0],word2[0]
 	;;
 	cmp.ltu p6,p0=result1[0],word1[0]	// check the carry
+	cmp.eq.or.andcm p8,p0=0,count		// exit if zero 8-byte
 	;;
 (p6)	adds result1[0]=1,result1[0]
 (p8)	br.cond.dptk .do_csum_exit	// if (within an 8-byte word)
-	;;
 (p11)	br.cond.dptk .do_csum16		// if (count is even)
-	;;
+
 	// Here count is odd.
 	ld8 word1[1]=[first1],8		// load an 8-byte word
 	cmp.eq p9,p10=1,count		// if (count == 1)
@@ -194,58 +200,43 @@
 	cmp.ltu p6,p0=result1[0],word1[1]
 	;;
 (p6)	adds result1[0]=1,result1[0]
-	;;
 (p9)	br.cond.sptk .do_csum_exit	// if (count == 1) exit
 	// Fall through to caluculate the checksum, feeding result1[0] as
 	// the initial value in result1[0].
-	;;
 	//
 	// Calculate the checksum loading two 8-byte words per loop.
 	//
 .do_csum16:
-	mov saved_lc=ar.lc
+	add first2=8,first1
 	shr.u count=count,1	// we do 16 bytes per loop
 	;;
-	cmp.eq p9,p10=r0,count	// if (count == 0)
+	adds count=-1,count
+	mov carry1=r0
+	mov carry2=r0
 	brp.loop.imp 1f,2f
 	;;
-	adds count=-1,count
 	mov ar.ec=PIPE_DEPTH
-	;;
 	mov ar.lc=count	// set lc
-	;;
+	mov pr.rot=1<<16
 	// result1[0] must be initialized in advance.
 	mov result2[0]=r0
 	;;
-	mov pr.rot=1<<16
-	;;
-	mov carry1=r0
-	mov carry2=r0
-	;;
-	add first2=8,first1
-	;;
-(p9)	br.cond.sptk .do_csum_exit
-	;;
-	nop.m	0
-	nop.i	0
-	;;
 	.align 32
 1:
-(ELD_1)	cmp.ltu p31,p0=result1[LOAD_LATENCY],word1[LOAD_LATENCY+1]
-(p32)	adds carry1=1,carry1
-(ELD_1)	cmp.ltu p47,p0=result2[LOAD_LATENCY],word2[LOAD_LATENCY+1]
-(p48)	adds carry2=1,carry2
+(ELD_1)	cmp.ltu pC1[0],p0=result1[LOAD_LATENCY],word1[LOAD_LATENCY+1]
+(pC1[1])adds carry1=1,carry1
+(ELD_1)	cmp.ltu pC2[0],p0=result2[LOAD_LATENCY],word2[LOAD_LATENCY+1]
+(pC2[1])adds carry2=1,carry2
 (ELD)	add result1[LOAD_LATENCY-1]=result1[LOAD_LATENCY],word1[LOAD_LATENCY]
 (ELD)	add result2[LOAD_LATENCY-1]=result2[LOAD_LATENCY],word2[LOAD_LATENCY]
 2:
-(p16)	ld8 word1[0]=[first1],16
-(p16)	ld8 word2[0]=[first2],16
+(p[0])	ld8 word1[0]=[first1],16
+(p[0])	ld8 word2[0]=[first2],16
 	br.ctop.sptk 1b
 	;;
-	// Since len is a 32-bit value, carry cannot be larger than
-	// a 64-bit value.
-(p32)	adds carry1=1,carry1	// since we miss the last one
-(p48)	adds carry2=1,carry2
+	// Since len is a 32-bit value, carry cannot be larger than a 64-bit value.
+(pC1[1])adds carry1=1,carry1	// since we miss the last one
+(pC2[1])adds carry2=1,carry2
 	;;
 	add result1[LOAD_LATENCY+1]=result1[LOAD_LATENCY+1],carry1
 	add result2[LOAD_LATENCY+1]=result2[LOAD_LATENCY+1],carry2
@@ -263,18 +254,15 @@
 (p6)	adds result1[0]=1,result1[0]
 	;;
 .do_csum_exit:
-	movl tmp3=0xffffffff
-	;;
-	// XXX Fixme
 	//
 	// now fold 64 into 16 bits taking care of carry
 	// that's not very good because it has lots of sequentiality
 	//
-	and tmp1=result1[0],tmp3
+	mov tmp3=0xffff
+	zxt4 tmp1=result1[0]
 	shr.u tmp2=result1[0],32
 	;;
 	add result1[0]=tmp1,tmp2
-	shr.u tmp3=tmp3,16
 	;;
 	and tmp1=result1[0],tmp3
 	shr.u tmp2=result1[0],16
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/ip_fast_csum.S linux-2.4.20/arch/ia64/lib/ip_fast_csum.S
--- linux-2.4.19/arch/ia64/lib/ip_fast_csum.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/ip_fast_csum.S	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * Optmized version of the ip_fast_csum() function
+ * Used for calculating IP header checksum
+ *
+ * Return: 16bit checksum, complemented
+ *
+ * Inputs:
+ *      in0: address of buffer to checksum (char *)
+ *      in1: length of the buffer (int)
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
+ */
+
+#include <asm/asmmacro.h>
+
+/*
+ * Since we know that most likely this function is called with buf aligned
+ * on 4-byte boundary and 20 bytes in length, we can execution rather quickly
+ * versus calling generic version of do_csum, which has lots of overhead in
+ * handling various alignments and sizes.  However, due to lack of constrains
+ * put on the function input argument, cases with alignment not on 4-byte or
+ * size not equal to 20 bytes will be handled by the generic do_csum function.
+ */
+
+#define in0	r32
+#define in1	r33
+#define ret0	r8
+
+GLOBAL_ENTRY(ip_fast_csum)
+	.prologue
+	.body
+	cmp.ne	p6,p7=5,in1	// size other than 20 byte?
+	and	r14=3,in0	// is it aligned on 4-byte?
+	add	r15=4,in0	// second source pointer
+	;;
+	cmp.ne.or.andcm p6,p7=r14,r0
+	;;
+(p7)	ld4	r20=[in0],8
+(p7)	ld4	r21=[r15],8
+(p6)	br.spnt	.generic
+	;;
+	ld4	r22=[in0],8
+	ld4	r23=[r15],8
+	;;
+	ld4	r24=[in0]
+	add	r20=r20,r21
+	add	r22=r22,r23
+	;;
+	add	r20=r20,r22
+	;;
+	add	r20=r20,r24
+	;;
+	shr.u	ret0=r20,16	// now need to add the carry
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	shr.u	ret0=r20,16	// add carry again
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	shr.u	ret0=r20,16
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	andcm	ret0=-1,r20
+	.restore sp		// reset frame state
+	br.ret.sptk.many b0
+	;;
+
+.generic:
+	.prologue
+	.save ar.pfs, r35
+	alloc	r35=ar.pfs,2,2,2,0
+	.save rp, r34
+	mov	r34=b0
+	.body
+	dep.z	out1=in1,2,30
+	mov	out0=in0
+	;;
+	br.call.sptk.many b0=do_csum
+	;;
+	andcm	ret0=-1,ret0
+	mov	ar.pfs=r35
+	mov	b0=r34
+	br.ret.sptk.many b0
+END(ip_fast_csum)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/memcpy_mck.S linux-2.4.20/arch/ia64/lib/memcpy_mck.S
--- linux-2.4.19/arch/ia64/lib/memcpy_mck.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/memcpy_mck.S	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,675 @@
+/*
+ * Itanium 2-optimized version of memcpy and copy_user function
+ *
+ * Inputs:
+ * 	in0:	destination address
+ *	in1:	source address
+ *	in2:	number of bytes to copy
+ * Output:
+ * 	0 if success, or number of byte NOT copied if error occurred.
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
+ */
+#include <linux/config.h>
+#include <asm/asmmacro.h>
+#include <asm/page.h>
+
+#if __GNUC__ >= 3
+# define EK(y...)	EX(y)
+#else
+# define EK(y,x...)	x
+#endif
+
+GLOBAL_ENTRY(bcopy)
+	.regstk 3,0,0,0
+	mov r8=in0
+	mov in0=in1
+	;;
+	mov in1=r8
+	;;
+END(bcopy)
+
+/* McKinley specific optimization */
+
+#define retval		r8
+#define saved_pfs	r31
+#define saved_lc	r10
+#define saved_pr	r11
+#define saved_in0	r14
+#define saved_in1	r15
+#define saved_in2	r16
+
+#define src0		r2
+#define src1		r3
+#define dst0		r17
+#define dst1		r18
+#define cnt		r9
+
+/* r19-r30 are temp for each code section */
+#define PREFETCH_DIST	8
+#define src_pre_mem	r19
+#define dst_pre_mem	r20
+#define src_pre_l2	r21
+#define dst_pre_l2	r22
+#define t1		r23
+#define t2		r24
+#define t3		r25
+#define t4		r26
+#define t5		t1	// alias!
+#define t6		t2	// alias!
+#define t7		t3	// alias!
+#define n8		r27
+#define t9		t5	// alias!
+#define t10		t4	// alias!
+#define t11		t7	// alias!
+#define t12		t6	// alias!
+#define t14		t10	// alias!
+#define t13		r28
+#define t15		r29
+#define tmp		r30
+
+/* defines for long_copy block */
+#define	A	0
+#define B	(PREFETCH_DIST)
+#define C	(B + PREFETCH_DIST)
+#define D	(C + 1)
+#define N	(D + 1)
+#define Nrot	((N + 7) & ~7)
+
+/* alias */
+#define in0		r32
+#define in1		r33
+#define in2		r34
+
+GLOBAL_ENTRY(memcpy)
+	and	r28=0x7,in0
+	and	r29=0x7,in1
+	mov	f6=f0
+	br.cond.sptk .common_code
+	;;
+END(memcpy)
+GLOBAL_ENTRY(__copy_user)
+	.prologue
+// check dest alignment
+	and	r28=0x7,in0
+	and	r29=0x7,in1
+	mov	f6=f1
+	mov	saved_in0=in0	// save dest pointer
+	mov	saved_in1=in1	// save src pointer
+	mov	saved_in2=in2	// save len
+	;;
+.common_code:
+	cmp.gt	p15,p0=8,in2	// check for small size
+	cmp.ne	p13,p0=0,r28	// check dest alignment
+	cmp.ne	p14,p0=0,r29	// check src alignment
+	add	src0=0,in1
+	sub	r30=8,r28	// for .align_dest
+	mov	retval=r0	// initialize return value
+	;;
+	add	dst0=0,in0
+	add	dst1=1,in0	// dest odd index
+	cmp.le	p6,p0 = 1,r30	// for .align_dest
+(p15)	br.cond.dpnt .memcpy_short
+(p13)	br.cond.dpnt .align_dest
+(p14)	br.cond.dpnt .unaligned_src
+	;;
+
+// both dest and src are aligned on 8-byte boundary
+.aligned_src:
+	.save ar.pfs, saved_pfs
+	alloc	saved_pfs=ar.pfs,3,Nrot-3,0,Nrot
+	.save pr, saved_pr
+	mov	saved_pr=pr
+
+	shr.u	cnt=in2,7	// this much cache line
+	;;
+	cmp.lt	p6,p0=2*PREFETCH_DIST,cnt
+	cmp.lt	p7,p8=1,cnt
+	.save ar.lc, saved_lc
+	mov	saved_lc=ar.lc
+	.body
+	add	cnt=-1,cnt
+	add	src_pre_mem=0,in1	// prefetch src pointer
+	add	dst_pre_mem=0,in0	// prefetch dest pointer
+	;;
+(p7)	mov	ar.lc=cnt	// prefetch count
+(p8)	mov	ar.lc=r0
+(p6)	br.cond.dpnt .long_copy
+	;;
+
+.prefetch:
+	lfetch	  [src_pre_mem], 128
+	lfetch.excl [dst_pre_mem], 128
+	br.cloop.dptk.few .prefetch
+	;;
+
+.medium_copy:
+	and	tmp=31,in2	// copy length after iteration
+	shr.u	r29=in2,5	// number of 32-byte iteration
+	add	dst1=8,dst0	// 2nd dest pointer
+	;;
+	add	cnt=-1,r29	// ctop iteration adjustment
+	cmp.eq	p10,p0=r29,r0	// do we really need to loop?
+	add	src1=8,src0	// 2nd src pointer
+	cmp.le	p6,p0=8,tmp
+	;;
+	cmp.le	p7,p0=16,tmp
+	mov	ar.lc=cnt	// loop setup
+	cmp.eq	p16,p17 = r0,r0
+	mov	ar.ec=2
+(p10)	br.dpnt.few .aligned_src_tail
+	;;
+	.align 32
+1:
+EX(.ex_handler, (p16)	ld8	r34=[src0],16)
+EK(.ex_handler, (p16)	ld8	r38=[src1],16)
+EX(.ex_handler, (p17)	st8	[dst0]=r33,16)
+EK(.ex_handler, (p17)	st8	[dst1]=r37,16)
+	;;
+EX(.ex_handler, (p16)	ld8	r32=[src0],16)
+EK(.ex_handler, (p16)	ld8	r36=[src1],16)
+EX(.ex_handler, (p16)	st8	[dst0]=r34,16)
+EK(.ex_handler, (p16)	st8	[dst1]=r38,16)
+	br.ctop.dptk.few 1b
+	;;
+
+.aligned_src_tail:
+EX(.ex_handler, (p6)	ld8	t1=[src0])
+	mov	ar.lc=saved_lc
+	mov	ar.pfs=saved_pfs
+EX(.ex_hndlr_s, (p7)	ld8	t2=[src1],8)
+	cmp.le	p8,p0=24,tmp
+	and	r21=-8,tmp
+	;;
+EX(.ex_hndlr_s, (p8)	ld8	t3=[src1])
+EX(.ex_handler, (p6)	st8	[dst0]=t1)	// store byte 1
+	and	in2=7,tmp	// remaining length
+EX(.ex_hndlr_d, (p7)	st8	[dst1]=t2,8)	// store byte 2
+	add	src0=src0,r21	// setting up src pointer
+	add	dst0=dst0,r21	// setting up dest pointer
+	;;
+EX(.ex_handler, (p8)	st8	[dst1]=t3)	// store byte 3
+	mov	pr=saved_pr,-1
+	br.dptk.many .memcpy_short
+	;;
+
+/* code taken from copy_page_mck */
+.long_copy:
+	.rotr v[2*PREFETCH_DIST]
+	.rotp p[N]
+
+	mov src_pre_mem = src0
+	mov pr.rot = 0x10000
+	mov ar.ec = 1				// special unrolled loop
+
+	mov dst_pre_mem = dst0
+
+	add src_pre_l2 = 8*8, src0
+	add dst_pre_l2 = 8*8, dst0
+	;;
+	add src0 = 8, src_pre_mem		// first t1 src
+	mov ar.lc = 2*PREFETCH_DIST - 1
+	shr.u cnt=in2,7				// number of lines
+	add src1 = 3*8, src_pre_mem		// first t3 src
+	add dst0 = 8, dst_pre_mem		// first t1 dst
+	add dst1 = 3*8, dst_pre_mem		// first t3 dst
+	;;
+	and tmp=127,in2				// remaining bytes after this block
+	add cnt = -(2*PREFETCH_DIST) - 1, cnt
+	// same as .line_copy loop, but with all predicated-off instructions removed:
+.prefetch_loop:
+EX(.ex_hndlr_lcpy_1, (p[A])	ld8 v[A] = [src_pre_mem], 128)		// M0
+EK(.ex_hndlr_lcpy_1, (p[B])	st8 [dst_pre_mem] = v[B], 128)		// M2
+	br.ctop.sptk .prefetch_loop
+	;;
+	cmp.eq p16, p0 = r0, r0			// reset p16 to 1
+	mov ar.lc = cnt
+	mov ar.ec = N				// # of stages in pipeline
+	;;
+.line_copy:
+EX(.ex_handler,	(p[D])	ld8 t2 = [src0], 3*8)			// M0
+EK(.ex_handler,	(p[D])	ld8 t4 = [src1], 3*8)			// M1
+EX(.ex_handler_lcpy,	(p[B])	st8 [dst_pre_mem] = v[B], 128)		// M2 prefetch dst from memory
+EK(.ex_handler_lcpy,	(p[D])	st8 [dst_pre_l2] = n8, 128)		// M3 prefetch dst from L2
+	;;
+EX(.ex_handler_lcpy,	(p[A])	ld8 v[A] = [src_pre_mem], 128)		// M0 prefetch src from memory
+EK(.ex_handler_lcpy,	(p[C])	ld8 n8 = [src_pre_l2], 128)		// M1 prefetch src from L2
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t1, 8)			// M2
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t3, 8)			// M3
+	;;
+EX(.ex_handler,	(p[D])	ld8  t5 = [src0], 8)
+EK(.ex_handler,	(p[D])	ld8  t7 = [src1], 3*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t2, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t4, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8  t6 = [src0], 3*8)
+EK(.ex_handler,	(p[D])	ld8 t10 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t5, 8)
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t7, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8  t9 = [src0], 3*8)
+EK(.ex_handler,	(p[D])	ld8 t11 = [src1], 3*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t6, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t10, 8)
+	;;
+EX(.ex_handler,	(p[D])	ld8 t12 = [src0], 8)
+EK(.ex_handler,	(p[D])	ld8 t14 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t9, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t11, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8 t13 = [src0], 4*8)
+EK(.ex_handler,	(p[D])	ld8 t15 = [src1], 4*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] = t12, 8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t14, 8)
+	;;
+EX(.ex_handler,	(p[C])	ld8  t1 = [src0], 8)
+EK(.ex_handler,	(p[C])	ld8  t3 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] = t13, 4*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t15, 4*8)
+	br.ctop.sptk .line_copy
+	;;
+
+	add dst0=-8,dst0
+	add src0=-8,src0
+	mov in2=tmp
+	.restore sp
+	br.sptk.many .medium_copy
+	;;
+
+#define BLOCK_SIZE	128*32
+#define blocksize	r23
+#define curlen		r24
+
+// dest is on 8-byte boundary, src is not. We need to do
+// ld8-ld8, shrp, then st8.  Max 8 byte copy per cycle.
+.unaligned_src:
+	.prologue
+	.save ar.pfs, saved_pfs
+	alloc	saved_pfs=ar.pfs,3,5,0,8
+	.save ar.lc, saved_lc
+	mov	saved_lc=ar.lc
+	.save pr, saved_pr
+	mov	saved_pr=pr
+	.body
+.4k_block:
+	mov	saved_in0=dst0	// need to save all input arguments
+	mov	saved_in2=in2
+	mov	blocksize=BLOCK_SIZE
+	;;
+	cmp.lt	p6,p7=blocksize,in2
+	mov	saved_in1=src0
+	;;
+(p6)	mov	in2=blocksize
+	;;
+	shr.u	r21=in2,7	// this much cache line
+	shr.u	r22=in2,4	// number of 16-byte iteration
+	and	curlen=15,in2	// copy length after iteration
+	and	r30=7,src0	// source alignment
+	;;
+	cmp.lt	p7,p8=1,r21
+	add	cnt=-1,r21
+	;;
+
+	add	src_pre_mem=0,src0	// prefetch src pointer
+	add	dst_pre_mem=0,dst0	// prefetch dest pointer
+	and	src0=-8,src0		// 1st src pointer
+(p7)	mov	ar.lc = r21
+(p8)	mov	ar.lc = r0
+	;;
+	.align 32
+1:	lfetch	  [src_pre_mem], 128
+	lfetch.excl [dst_pre_mem], 128
+	br.cloop.dptk.few 1b
+	;;
+
+	shladd	dst1=r22,3,dst0	// 2nd dest pointer
+	shladd	src1=r22,3,src0	// 2nd src pointer
+	cmp.eq	p8,p9=r22,r0	// do we really need to loop?
+	cmp.le	p6,p7=8,curlen;	// have at least 8 byte remaining?
+	add	cnt=-1,r22	// ctop iteration adjustment
+	;;
+EX(.ex_handler, (p9)	ld8	r33=[src0],8)	// loop primer
+EK(.ex_handler, (p9)	ld8	r37=[src1],8)
+(p8)	br.dpnt.few .noloop
+	;;
+
+// The jump address is calculated based on src alignment. The COPYU
+// macro below need to confine its size to power of two, so an entry
+// can be caulated using shl instead of an expensive multiply. The
+// size is then hard coded by the following #define to match the
+// actual size.  This make it somewhat tedious when COPYU macro gets
+// changed and this need to be adjusted to match.
+#define LOOP_SIZE 6
+1:
+	mov	r29=ip		// jmp_table thread
+	mov	ar.lc=cnt
+	;;
+	add	r29=.jump_table - 1b - (.jmp1-.jump_table), r29
+	shl	r28=r30, LOOP_SIZE	// jmp_table thread
+	mov	ar.ec=2		// loop setup
+	;;
+	add	r29=r29,r28		// jmp_table thread
+	cmp.eq	p16,p17=r0,r0
+	;;
+	mov	b6=r29			// jmp_table thread
+	;;
+	br.cond.sptk.few b6
+
+// for 8-15 byte case
+// We will skip the loop, but need to replicate the side effect
+// that the loop produces.
+.noloop:
+EX(.ex_handler, (p6)	ld8	r37=[src1],8)
+	add	src0=8,src0
+(p6)	shl	r25=r30,3
+	;;
+EX(.ex_handler, (p6)	ld8	r27=[src1])
+(p6)	shr.u	r28=r37,r25
+(p6)	sub	r26=64,r25
+	;;
+(p6)	shl	r27=r27,r26
+	;;
+(p6)	or	r21=r28,r27
+
+.unaligned_src_tail:
+/* check if we have more than blocksize to copy, if so go back */
+	cmp.gt	p8,p0=saved_in2,blocksize
+	;;
+(p8)	add	dst0=saved_in0,blocksize
+(p8)	add	src0=saved_in1,blocksize
+(p8)	sub	in2=saved_in2,blocksize
+(p8)	br.dpnt	.4k_block
+	;;
+
+/* we have up to 15 byte to copy in the tail.
+ * part of work is already done in the jump table code
+ * we are at the following state.
+ * src side:
+ * 
+ *   xxxxxx xx                   <----- r21 has xxxxxxxx already
+ * -------- -------- --------
+ * 0        8        16
+ *          ^
+ *          |
+ *          src1
+ * 
+ * dst
+ * -------- -------- --------
+ * ^
+ * |
+ * dst1
+ */
+EX(.ex_handler, (p6)	st8	[dst1]=r21,8)	// more than 8 byte to copy
+(p6)	add	curlen=-8,curlen	// update length
+	mov	ar.pfs=saved_pfs
+	;;
+	mov	ar.lc=saved_lc
+	mov	pr=saved_pr,-1
+	mov	in2=curlen	// remaining length
+	mov	dst0=dst1	// dest pointer
+	add	src0=src1,r30	// forward by src alignment
+	;;
+
+// 7 byte or smaller.
+.memcpy_short:
+	cmp.le	p8,p9   = 1,in2
+	cmp.le	p10,p11 = 2,in2
+	cmp.le	p12,p13 = 3,in2
+	cmp.le	p14,p15 = 4,in2
+	add	src1=1,src0	// second src pointer
+	add	dst1=1,dst0	// second dest pointer
+	;;
+
+EX(.ex_handler_short, (p8)	ld1	t1=[src0],2)
+EK(.ex_handler_short, (p10)	ld1	t2=[src1],2)
+(p9)	br.ret.dpnt rp		// 0 byte copy
+	;;
+
+EX(.ex_handler_short, (p8)	st1	[dst0]=t1,2)
+EK(.ex_handler_short, (p10)	st1	[dst1]=t2,2)
+(p11)	br.ret.dpnt rp		// 1 byte copy
+
+EX(.ex_handler_short, (p12)	ld1	t3=[src0],2)
+EK(.ex_handler_short, (p14)	ld1	t4=[src1],2)
+(p13)	br.ret.dpnt rp		// 2 byte copy
+	;;
+
+	cmp.le	p6,p7   = 5,in2
+	cmp.le	p8,p9   = 6,in2
+	cmp.le	p10,p11 = 7,in2
+
+EX(.ex_handler_short, (p12)	st1	[dst0]=t3,2)
+EK(.ex_handler_short, (p14)	st1	[dst1]=t4,2)
+(p15)	br.ret.dpnt rp		// 3 byte copy
+	;;
+
+EX(.ex_handler_short, (p6)	ld1	t5=[src0],2)
+EK(.ex_handler_short, (p8)	ld1	t6=[src1],2)
+(p7)	br.ret.dpnt rp		// 4 byte copy
+	;;
+
+EX(.ex_handler_short, (p6)	st1	[dst0]=t5,2)
+EK(.ex_handler_short, (p8)	st1	[dst1]=t6,2)
+(p9)	br.ret.dptk rp		// 5 byte copy
+
+EX(.ex_handler_short, (p10)	ld1	t7=[src0],2)
+(p11)	br.ret.dptk rp		// 6 byte copy
+	;;
+
+EX(.ex_handler_short, (p10)	st1	[dst0]=t7,2)
+	br.ret.dptk rp		// done all cases
+
+
+/* Align dest to nearest 8-byte boundary. We know we have at
+ * least 7 bytes to copy, enough to crawl to 8-byte boundary.
+ * Actual number of byte to crawl depend on the dest alignment.
+ * 7 byte or less is taken care at .memcpy_short
+
+ * src0 - source even index
+ * src1 - source  odd index
+ * dst0 - dest even index
+ * dst1 - dest  odd index
+ * r30  - distance to 8-byte boundary
+ */
+
+.align_dest:
+	add	src1=1,in1	// source odd index
+	cmp.le	p7,p0 = 2,r30	// for .align_dest
+	cmp.le	p8,p0 = 3,r30	// for .align_dest
+EX(.ex_handler_short, (p6)	ld1	t1=[src0],2)
+	cmp.le	p9,p0 = 4,r30	// for .align_dest
+	cmp.le	p10,p0 = 5,r30
+	;;
+EX(.ex_handler_short, (p7)	ld1	t2=[src1],2)
+EK(.ex_handler_short, (p8)	ld1	t3=[src0],2)
+	cmp.le	p11,p0 = 6,r30
+EX(.ex_handler_short, (p6)	st1	[dst0] = t1,2)
+	cmp.le	p12,p0 = 7,r30
+	;;
+EX(.ex_handler_short, (p9)	ld1	t4=[src1],2)
+EK(.ex_handler_short, (p10)	ld1	t5=[src0],2)
+EX(.ex_handler_short, (p7)	st1	[dst1] = t2,2)
+EK(.ex_handler_short, (p8)	st1	[dst0] = t3,2)
+	;;
+EX(.ex_handler_short, (p11)	ld1	t6=[src1],2)
+EK(.ex_handler_short, (p12)	ld1	t7=[src0],2)
+	cmp.eq	p6,p7=r28,r29
+EX(.ex_handler_short, (p9)	st1	[dst1] = t4,2)
+EK(.ex_handler_short, (p10)	st1	[dst0] = t5,2)
+	sub	in2=in2,r30
+	;;
+EX(.ex_handler_short, (p11)	st1	[dst1] = t6,2)
+EK(.ex_handler_short, (p12)	st1	[dst0] = t7)
+	add	dst0=in0,r30	// setup arguments
+	add	src0=in1,r30
+(p6)	br.cond.dptk .aligned_src
+(p7)	br.cond.dpnt .unaligned_src
+	;;
+
+/* main loop body in jump table format */
+#define COPYU(shift)									\
+1:											\
+EX(.ex_handler,  (p16)	ld8	r32=[src0],8);		/* 1 */				\
+EK(.ex_handler,  (p16)	ld8	r36=[src1],8);						\
+		 (p17)	shrp	r35=r33,r34,shift;;	/* 1 */				\
+EX(.ex_handler,  (p6)	ld8	r22=[src1]);	/* common, prime for tail section */	\
+		 nop.m	0;								\
+		 (p16)	shrp	r38=r36,r37,shift;					\
+EX(.ex_handler,  (p17)	st8	[dst0]=r35,8);		/* 1 */				\
+EK(.ex_handler,  (p17)	st8	[dst1]=r39,8);						\
+		 br.ctop.dptk.few 1b;;							\
+		 (p7)	add	src1=-8,src1;	/* back out for <8 byte case */		\
+		 shrp	r21=r22,r38,shift;	/* speculative work */			\
+		 br.sptk.few .unaligned_src_tail /* branch out of jump table */		\
+		 ;;
+	.align 32
+.jump_table:
+	COPYU(8)	// unaligned cases
+.jmp1:
+	COPYU(16)
+	COPYU(24)
+	COPYU(32)
+	COPYU(40)
+	COPYU(48)
+	COPYU(56)
+
+#undef A
+#undef B
+#undef C
+#undef D
+END(memcpy)
+
+/*
+ * Due to lack of local tag support in gcc 2.x assembler, it is not clear which
+ * instruction failed in the bundle.  The exception algorithm is that we
+ * first figure out the faulting address, then detect if there is any
+ * progress made on the copy, if so, redo the copy from last known copied
+ * location up to the faulting address (exclusive). In the copy_from_user
+ * case, remaining byte in kernel buffer will be zeroed.
+ *
+ * Take copy_from_user as an example, in the code there are multiple loads
+ * in a bundle and those multiple loads could span over two pages, the
+ * faulting address is calculated as page_round_down(max(src0, src1)).
+ * This is based on knowledge that if we can access one byte in a page, we
+ * can access any byte in that page.
+ *
+ * predicate used in the exception handler:
+ * p6-p7: direction
+ * p10-p11: src faulting addr calculation
+ * p12-p13: dst faulting addr calculation
+ */
+
+#define A	r19
+#define B	r20
+#define C	r21
+#define D	r22
+#define F	r28
+
+#define memset_arg0	r32
+#define memset_arg2	r33
+
+#define saved_retval	loc0
+#define saved_rtlink	loc1
+#define saved_pfs_stack	loc2
+
+.ex_hndlr_s:
+	add	src0=8,src0
+	br.sptk .ex_handler
+	;;
+.ex_hndlr_d:
+	add	dst0=8,dst0
+	br.sptk .ex_handler
+	;;
+.ex_hndlr_lcpy_1:
+	mov	src1=src_pre_mem
+	mov	dst1=dst_pre_mem
+	cmp.gtu	p10,p11=src_pre_mem,saved_in1
+	cmp.gtu	p12,p13=dst_pre_mem,saved_in0
+	;;
+(p10)	add	src0=8,saved_in1
+(p11)	mov	src0=saved_in1
+(p12)	add	dst0=8,saved_in0
+(p13)	mov	dst0=saved_in0
+	br.sptk	.ex_handler
+.ex_handler_lcpy:
+	// in line_copy block, the preload addresses should always ahead
+	// of the other two src/dst pointers.  Furthermore, src1/dst1 should
+	// always ahead of src0/dst0.
+	mov	src1=src_pre_mem
+	mov	dst1=dst_pre_mem
+.ex_handler:
+	mov	pr=saved_pr,-1		// first restore pr, lc, and pfs
+	mov	ar.lc=saved_lc
+	mov	ar.pfs=saved_pfs
+	;;
+.ex_handler_short: // fault occurred in these sections didn't change pr, lc, pfs
+	cmp.ltu	p6,p7=saved_in0, saved_in1	// get the copy direction
+	cmp.ltu	p10,p11=src0,src1
+	cmp.ltu	p12,p13=dst0,dst1
+	fcmp.eq	p8,p0=f6,f0		// is it memcpy?
+	mov	tmp = dst0
+	;;
+(p11)	mov	src1 = src0		// pick the larger of the two
+(p13)	mov	dst0 = dst1		// make dst0 the smaller one
+(p13)	mov	dst1 = tmp		// and dst1 the larger one
+	;;
+(p6)	dep	F = r0,dst1,0,PAGE_SHIFT // usr dst round down to page boundary
+(p7)	dep	F = r0,src1,0,PAGE_SHIFT // usr src round down to page boundary
+	;;
+(p6)	cmp.le	p14,p0=dst0,saved_in0	// no progress has been made on store
+(p7)	cmp.le	p14,p0=src0,saved_in1	// no progress has been made on load
+	mov	retval=saved_in2
+(p8)	ld1	tmp=[src1]		// force an oops for memcpy call
+(p8)	st1	[dst1]=r0		// force an oops for memcpy call
+(p14)	br.ret.sptk.many rp
+
+/*
+ * The remaining byte to copy is calculated as:
+ *
+ * A =	(faulting_addr - orig_src)	-> len to faulting ld address
+ *	or 
+ * 	(faulting_addr - orig_dst)	-> len to faulting st address
+ * B =	(cur_dst - orig_dst)		-> len copied so far
+ * C =	A - B				-> len need to be copied
+ * D =	orig_len - A			-> len need to be zeroed
+ */
+(p6)	sub	A = F, saved_in0
+(p7)	sub	A = F, saved_in1
+	clrrrb
+	;;
+	alloc	saved_pfs_stack=ar.pfs,3,3,3,0
+	sub	B = dst0, saved_in0	// how many byte copied so far
+	;;
+	sub	C = A, B
+	sub	D = saved_in2, A
+	;;
+	cmp.gt	p8,p0=C,r0		// more than 1 byte?
+	add	memset_arg0=saved_in0, A
+(p6)	mov	memset_arg2=0		// copy_to_user should not call memset
+(p7)	mov	memset_arg2=D		// copy_from_user need to have kbuf zeroed
+	mov	r8=0
+	mov	saved_retval = D
+	mov	saved_rtlink = b0
+
+	add	out0=saved_in0, B
+	add	out1=saved_in1, B
+	mov	out2=C
+(p8)	br.call.sptk.few b0=__copy_user	// recursive call
+	;;
+
+	add	saved_retval=saved_retval,r8	// above might return non-zero value
+	cmp.gt	p8,p0=memset_arg2,r0	// more than 1 byte?
+	mov	out0=memset_arg0	// *s
+	mov	out1=r0			// c
+	mov	out2=memset_arg2	// n
+(p8)	br.call.sptk.few b0=memset
+	;;
+
+	mov	retval=saved_retval
+	mov	ar.pfs=saved_pfs_stack
+	mov	b0=saved_rtlink
+	br.ret.sptk.many rp
+
+/* end of McKinley specific optimization */
+END(__copy_user)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/memset.S linux-2.4.20/arch/ia64/lib/memset.S
--- linux-2.4.19/arch/ia64/lib/memset.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/memset.S	2002-10-04 00:41:20.000000000 +0000
@@ -1,108 +1,362 @@
-/*
- *
- * Optimized version of the standard memset() function
- *
- * Return: none
- *
- * Inputs:
- *	in0:	address of buffer
- * 	in1:	byte value to use for storing
- *	in2:	length of the buffer
- *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- */
+/* Optimized version of the standard memset() function.
+
+   Copyright (c) 2002 Hewlett-Packard Co/CERN
+	Sverre Jarp <Sverre.Jarp@cern.ch>
+
+   Return: dest
+
+   Inputs:
+        in0:    dest
+        in1:    value
+        in2:    count
+
+   The algorithm is fairly straightforward: set byte by byte until we
+   we get to a 16B-aligned address, then loop on 128 B chunks using an
+   early store as prefetching, then loop on 32B chucks, then clear remaining
+   words, finally clear remaining bytes.
+   Since a stf.spill f0 can store 16B in one go, we use this instruction
+   to get peak speed when value = 0.  */
 
 #include <asm/asmmacro.h>
+#undef ret
+
+#define dest		in0
+#define value		in1
+#define	cnt		in2
 
-// arguments
-//
-#define buf		r32
-#define val		r33
-#define len		r34
-
-//
-// local registers
-//
-#define saved_pfs	r14
-#define cnt		r18
-#define buf2		r19
-#define saved_lc	r20
-#define tmp		r21
+#define tmp		r31
+#define save_lc		r30
+#define ptr0		r29
+#define ptr1		r28
+#define ptr2		r27
+#define ptr3		r26
+#define ptr9 		r24
+#define	loopcnt		r23
+#define linecnt		r22
+#define bytecnt		r21
+
+#define fvalue		f6
+
+// This routine uses only scratch predicate registers (p6 - p15)
+#define p_scr		p6			// default register for same-cycle branches
+#define p_nz		p7
+#define p_zr		p8
+#define p_unalgn	p9
+#define p_y		p11
+#define p_n		p12
+#define p_yy		p13
+#define p_nn		p14
+
+#define MIN1		15
+#define MIN1P1HALF	8
+#define LINE_SIZE	128
+#define LSIZE_SH        7			// shift amount
+#define PREF_AHEAD	8
 
 GLOBAL_ENTRY(memset)
+{ .mmi
 	.prologue
-	.save ar.pfs, saved_pfs
- 	alloc saved_pfs=ar.pfs,3,0,0,0	// cnt is sink here
-	cmp.eq p8,p0=r0,len	// check for zero length
-	.save ar.lc, saved_lc
-	mov saved_lc=ar.lc	// preserve ar.lc (slow)
-	;;
-
+	alloc	tmp = ar.pfs, 3, 0, 0, 0
 	.body
+	lfetch.nt1 [dest]			//
+	.save   ar.lc, save_lc
+	mov.i	save_lc = ar.lc
+} { .mmi
+	mov	ret0 = dest			// return value
+	cmp.ne	p_nz, p_zr = value, r0		// use stf.spill if value is zero
+	cmp.eq	p_scr, p0 = cnt, r0
+;; }
+{ .mmi
+	and	ptr2 = -(MIN1+1), dest		// aligned address
+	and	tmp = MIN1, dest		// prepare to check for correct alignment
+	tbit.nz p_y, p_n = dest, 0		// Do we have an odd address? (M_B_U)
+} { .mib
+	mov	ptr1 = dest
+	mux1	value = value, @brcst		// create 8 identical bytes in word
+(p_scr)	br.ret.dpnt.many rp			// return immediately if count = 0
+;; }
+{ .mib
+	cmp.ne	p_unalgn, p0 = tmp, r0		//
+} { .mib
+	sub	bytecnt = (MIN1+1), tmp		// NB: # of bytes to move is 1 higher than loopcnt
+	cmp.gt	p_scr, p0 = 16, cnt		// is it a minimalistic task?
+(p_scr)	br.cond.dptk.many .move_bytes_unaligned	// go move just a few (M_B_U)
+;; }
+{ .mmi
+(p_unalgn) add	ptr1 = (MIN1+1), ptr2		// after alignment
+(p_unalgn) add	ptr2 = MIN1P1HALF, ptr2		// after alignment
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3	// should we do a st8 ?
+;; }
+{ .mib
+(p_y)	add	cnt = -8, cnt			//
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2	// should we do a st4 ?
+} { .mib
+(p_y)	st8	[ptr2] = value,-4		//
+(p_n)	add	ptr2 = 4, ptr2			//
+;; }
+{ .mib
+(p_yy)	add	cnt = -4, cnt			//
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1	// should we do a st2 ?
+} { .mib
+(p_yy)	st4	[ptr2] = value,-2		//
+(p_nn)	add	ptr2 = 2, ptr2			//
+;; }
+{ .mmi
+	mov	tmp = LINE_SIZE+1		// for compare
+(p_y)	add	cnt = -2, cnt			//
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0	// should we do a st1 ?
+} { .mmi
+	setf.sig fvalue=value			// transfer value to FLP side
+(p_y)	st2	[ptr2] = value,-1		//
+(p_n)	add	ptr2 = 1, ptr2			//
+;; }
+
+{ .mmi
+(p_yy)	st1	[ptr2] = value 			//
+  	cmp.gt	p_scr, p0 = tmp, cnt		// is it a minimalistic task?
+} { .mbb
+(p_yy)	add	cnt = -1, cnt			//
+(p_scr)	br.cond.dpnt.many .fraction_of_line	// go move just a few
+;; }
+
+{ .mib
+	nop.m 0
+	shr.u	linecnt = cnt, LSIZE_SH
+(p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
+;; }
+
+	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
+{ .mmi
+	and	tmp = -(LINE_SIZE), cnt		// compute end of range
+	mov	ptr9 = ptr1			// used for prefetching
+	and	cnt = (LINE_SIZE-1), cnt	// remainder
+} { .mmi
+	mov	loopcnt = PREF_AHEAD-1		// default prefetch loop
+	cmp.gt	p_scr, p0 = PREF_AHEAD, linecnt	// check against actual value
+;; }
+{ .mmi
+(p_scr)	add	loopcnt = -1, linecnt		//
+	add	ptr2 = 8, ptr1			// start of stores (beyond prefetch stores)
+	add	ptr1 = tmp, ptr1		// first address beyond total range
+;; }
+{ .mmi
+	add	tmp = -1, linecnt		// next loop count
+	mov.i	ar.lc = loopcnt			//
+;; }
+.pref_l1a:
+{ .mib
+	stf8 [ptr9] = fvalue, 128		// Do stores one cache line apart
+	nop.i	0
+	br.cloop.dptk.few .pref_l1a
+;; }
+{ .mmi
+	add	ptr0 = 16, ptr2			// Two stores in parallel
+	mov.i	ar.lc = tmp			//
+;; }
+.l1ax:
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 32
+ 	cmp.lt	p_scr, p0 = ptr9, ptr1		// do we need more prefetching?
+ ;; }
+{ .mmb
+	stf8 [ptr2] = fvalue, 24
+(p_scr)	stf8 [ptr9] = fvalue, 128
+	br.cloop.dptk.few .l1ax
+;; }
+{ .mbb
+	cmp.le  p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr) br.cond.dpnt.many  .fraction_of_line	// Branch no. 2
+	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
+;; }
+
+	.align 32
+.l1b:	// ------------------------------------ //  L1B: store ahead into cache lines; fill later
+{ .mmi
+	and	tmp = -(LINE_SIZE), cnt		// compute end of range
+	mov	ptr9 = ptr1			// used for prefetching
+	and	cnt = (LINE_SIZE-1), cnt	// remainder
+} { .mmi
+	mov	loopcnt = PREF_AHEAD-1		// default prefetch loop
+	cmp.gt	p_scr, p0 = PREF_AHEAD, linecnt	// check against actual value
+;; }
+{ .mmi
+(p_scr)	add	loopcnt = -1, linecnt
+	add	ptr2 = 16, ptr1			// start of stores (beyond prefetch stores)
+	add	ptr1 = tmp, ptr1		// first address beyond total range
+;; }
+{ .mmi
+	add	tmp = -1, linecnt		// next loop count
+	mov.i	ar.lc = loopcnt
+;; }
+.pref_l1b:
+{ .mib
+	stf.spill [ptr9] = f0, 128		// Do stores one cache line apart
+	nop.i   0
+	br.cloop.dptk.few .pref_l1b
+;; }
+{ .mmi
+	add	ptr0 = 16, ptr2			// Two stores in parallel
+	mov.i	ar.lc = tmp
+;; }
+.l1bx:
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 64
+ 	cmp.lt	p_scr, p0 = ptr9, ptr1		// do we need more prefetching?
+ ;; }
+{ .mmb
+	stf.spill [ptr2] = f0, 32
+(p_scr)	stf.spill [ptr9] = f0, 128
+	br.cloop.dptk.few .l1bx
+;; }
+{ .mib
+	cmp.gt  p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr)	br.cond.dpnt.many  .move_bytes_from_alignment	//
+;; }
+
+.fraction_of_line:
+{ .mib
+	add	ptr2 = 16, ptr1
+	shr.u	loopcnt = cnt, 5   		// loopcnt = cnt / 32
+;; }
+{ .mib
+	cmp.eq	p_scr, p0 = loopcnt, r0
+	add	loopcnt = -1, loopcnt
+(p_scr)	br.cond.dpnt.many .store_words
+;; }
+{ .mib
+	and	cnt = 0x1f, cnt			// compute the remaining cnt
+	mov.i   ar.lc = loopcnt
+;; }
+	.align 32
+.l2:	// ------------------------------------ //  L2A:  store 32B in 2 cycles
+{ .mmb
+	stf8	[ptr1] = fvalue, 8
+	stf8	[ptr2] = fvalue, 8
+;; } { .mmb
+	stf8	[ptr1] = fvalue, 24
+	stf8	[ptr2] = fvalue, 24
+	br.cloop.dptk.many .l2
+;; }
+.store_words:
+{ .mib
+	cmp.gt	p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr)	br.cond.dpnt.many .move_bytes_from_alignment	// Branch
+;; }
+
+{ .mmi
+	stf8	[ptr1] = fvalue, 8		// store
+	cmp.le	p_y, p_n = 16, cnt
+	add	cnt = -8, cnt			// subtract
+;; }
+{ .mmi
+(p_y)	stf8	[ptr1] = fvalue, 8		// store
+(p_y)	cmp.le.unc p_yy, p_nn = 16, cnt
+(p_y)	add	cnt = -8, cnt			// subtract
+;; }
+{ .mmi						// store
+(p_yy)	stf8	[ptr1] = fvalue, 8
+(p_yy)	add	cnt = -8, cnt			// subtract
+;; }
+
+.move_bytes_from_alignment:
+{ .mib
+	cmp.eq	p_scr, p0 = cnt, r0
+	tbit.nz.unc p_y, p0 = cnt, 2		// should we terminate with a st4 ?
+(p_scr)	br.cond.dpnt.few .restore_and_exit
+;; }
+{ .mib
+(p_y)	st4	[ptr1] = value,4
+	tbit.nz.unc p_yy, p0 = cnt, 1		// should we terminate with a st2 ?
+;; }
+{ .mib
+(p_yy)	st2	[ptr1] = value,2
+	tbit.nz.unc p_y, p0 = cnt, 0		// should we terminate with a st1 ?
+;; }
+
+{ .mib
+(p_y)	st1	[ptr1] = value
+;; }
+.restore_and_exit:
+{ .mib
+	nop.m	0
+	mov.i	ar.lc = save_lc
+	br.ret.sptk.many rp
+;; }
 
-	adds tmp=-1,len		// br.ctop is repeat/until
-	tbit.nz p6,p0=buf,0	// odd alignment
-(p8)	br.ret.spnt.many rp
-
-	cmp.lt p7,p0=16,len	// if len > 16 then long memset
-	mux1 val=val,@brcst	// prepare value
-(p7)	br.cond.dptk .long_memset
-	;;
-	mov ar.lc=tmp		// initialize lc for small count
-	;;			// avoid RAW and WAW on ar.lc
-1:				// worst case 15 cyles, avg 8 cycles
-	st1 [buf]=val,1
-	br.cloop.dptk.few 1b
-	;;				// avoid RAW on ar.lc
-	mov ar.lc=saved_lc
-	mov ar.pfs=saved_pfs
-	br.ret.sptk.many rp	// end of short memset
-
-	// at this point we know we have more than 16 bytes to copy
-	// so we focus on alignment
-.long_memset:
-(p6)	st1 [buf]=val,1		// 1-byte aligned
-(p6)	adds len=-1,len;;	// sync because buf is modified
-	tbit.nz p6,p0=buf,1
-	;;
-(p6)	st2 [buf]=val,2		// 2-byte aligned
-(p6)	adds len=-2,len;;
-	tbit.nz p6,p0=buf,2
-	;;
-(p6)	st4 [buf]=val,4		// 4-byte aligned
-(p6)	adds len=-4,len;;
-	tbit.nz p6,p0=buf,3
-	;;
-(p6)	st8 [buf]=val,8		// 8-byte aligned
-(p6)	adds len=-8,len;;
-	shr.u cnt=len,4		// number of 128-bit (2x64bit) words
-	;;
-	cmp.eq p6,p0=r0,cnt
-	adds tmp=-1,cnt
-(p6)	br.cond.dpnt .dotail	// we have less than 16 bytes left
-	;;
-	adds buf2=8,buf		// setup second base pointer
-	mov ar.lc=tmp
-	;;
-2:				// 16bytes/iteration
-	st8 [buf]=val,16
-	st8 [buf2]=val,16
-	br.cloop.dptk.few 2b
-	;;
-.dotail:			// tail correction based on len only
-	tbit.nz p6,p0=len,3
-	;;
-(p6)	st8 [buf]=val,8		// at least 8 bytes
-	tbit.nz p6,p0=len,2
-	;;
-(p6)	st4 [buf]=val,4		// at least 4 bytes
-	tbit.nz p6,p0=len,1
-	;;
-(p6)	st2 [buf]=val,2		// at least 2 bytes
-	tbit.nz p6,p0=len,0
-	mov ar.lc=saved_lc
-	;;
-(p6)	st1 [buf]=val		// only 1 byte left
+.move_bytes_unaligned:
+{ .mmi
+       .pred.rel "mutex",p_y, p_n
+       .pred.rel "mutex",p_yy, p_nn
+(p_n)	cmp.le  p_yy, p_nn = 4, cnt
+(p_y)	cmp.le  p_yy, p_nn = 5, cnt
+(p_n)	add	ptr2 = 2, ptr1
+} { .mmi
+(p_y)	add	ptr2 = 3, ptr1
+(p_y)	st1	[ptr1] = value, 1		// fill 1 (odd-aligned) byte [15, 14 (or less) left]
+(p_y)	add	cnt = -1, cnt
+;; }
+{ .mmi
+(p_yy)	cmp.le.unc p_y, p0 = 8, cnt
+	add	ptr3 = ptr1, cnt		// prepare last store
+	mov.i	ar.lc = save_lc
+} { .mmi
+(p_yy)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_yy)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [11, 10 (o less) left]
+(p_yy)	add	cnt = -4, cnt
+;; }
+{ .mmi
+(p_y)	cmp.le.unc p_yy, p0 = 8, cnt
+	add	ptr3 = -1, ptr3			// last store
+	tbit.nz p_scr, p0 = cnt, 1		// will there be a st2 at the end ?
+} { .mmi
+(p_y)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_y)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [7, 6 (or less) left]
+(p_y)	add	cnt = -4, cnt
+;; }
+{ .mmi
+(p_yy)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_yy)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [3, 2 (or less) left]
+	tbit.nz p_y, p0 = cnt, 0		// will there be a st1 at the end ?
+} { .mmi
+(p_yy)	add	cnt = -4, cnt
+;; }
+{ .mmb
+(p_scr)	st2	[ptr1] = value			// fill 2 (aligned) bytes
+(p_y)	st1	[ptr3] = value			// fill last byte (using ptr3)
 	br.ret.sptk.many rp
+}
 END(memset)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/swiotlb.c linux-2.4.20/arch/ia64/lib/swiotlb.c
--- linux-2.4.19/arch/ia64/lib/swiotlb.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/lib/swiotlb.c	2002-10-04 00:41:29.000000000 +0000
@@ -277,8 +277,11 @@
 	int gfp = GFP_ATOMIC;
 	void *ret;
 
-	if (!hwdev || hwdev->dma_mask <= 0xffffffff)
-		gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */
+	/*
+	 * Alloc_consistent() is defined to return memory < 4GB, no matter what the DMA
+	 * mask says.
+	 */
+	gfp |= GFP_DMA;	/* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (!ret)
 		return NULL;
@@ -486,6 +489,17 @@
 	return SG_ENT_PHYS_ADDRESS(sg);
 }
 
+/*
+ * Return whether the given PCI device DMA address mask can be supported properly.  For
+ * example, if your device can only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+int
+swiotlb_pci_dma_supported (struct pci_dev *hwdev, u64 mask)
+{
+	return 1;
+}
+
 EXPORT_SYMBOL(swiotlb_init);
 EXPORT_SYMBOL(swiotlb_map_single);
 EXPORT_SYMBOL(swiotlb_unmap_single);
@@ -496,3 +510,4 @@
 EXPORT_SYMBOL(swiotlb_dma_address);
 EXPORT_SYMBOL(swiotlb_alloc_consistent);
 EXPORT_SYMBOL(swiotlb_free_consistent);
+EXPORT_SYMBOL(swiotlb_pci_dma_supported);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/fault.c linux-2.4.20/arch/ia64/mm/fault.c
--- linux-2.4.19/arch/ia64/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/mm/fault.c	2002-10-04 00:41:30.000000000 +0000
@@ -49,7 +49,6 @@
 	int signal = SIGSEGV, code = SEGV_MAPERR;
 	struct vm_area_struct *vma, *prev_vma;
 	struct mm_struct *mm = current->mm;
-	struct exception_fixup fix;
 	struct siginfo si;
 	unsigned long mask;
 
@@ -59,6 +58,17 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+	/*
+	 * If fault is in region 5 and we are in the kernel, we may already
+         * have the mmap_sem (VALID_PAGE macro is called during mmap). There
+	 * should be no vma for region 5 addr's anyway, so skip getting the
+	 * semaphore and go directly to the code that handles a bad area.
+  	 */
+	if ((REGION_NUMBER(address) == 5) && !user_mode(regs))
+		goto bad_area_no_up;
+#endif
+
 	down_read(&mm->mmap_sem);
 
 	vma = find_vma_prev(mm, address, &prev_vma);
@@ -138,10 +148,16 @@
 
   bad_area:
 	up_read(&mm->mmap_sem);
-	if (isr & IA64_ISR_SP) {
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+  bad_area_no_up:
+#endif
+	if ((isr & IA64_ISR_SP)
+	    || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
+	{
 		/*
-		 * This fault was due to a speculative load set the "ed" bit in the psr to
-		 * ensure forward progress (target register will get a NaT).
+		 * This fault was due to a speculative load or lfetch.fault, set the "ed"
+		 * bit in the psr to ensure forward progress.  (Target register will get a
+		 * NaT for ld.s, lfetch will be canceled.)
 		 */
 		ia64_psr(regs)->ed = 1;
 		return;
@@ -167,15 +183,8 @@
 		return;
 	}
 
-#ifdef GAS_HAS_LOCAL_TAGS
-	fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
-#else
-	fix = search_exception_table(regs->cr_iip);
-#endif
-	if (fix.cont) {
-		handle_exception(regs, fix);
+	if (done_with_exception(regs))
 		return;
-	}
 
 	/*
 	 * Oops. The kernel tried to access some bad page. We'll have to terminate things
@@ -194,13 +203,11 @@
 	return;
 
   out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/init.c linux-2.4.20/arch/ia64/mm/init.c
--- linux-2.4.19/arch/ia64/mm/init.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/mm/init.c	2002-10-04 00:41:17.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * Initialize MMU support.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -10,13 +10,14 @@
 
 #include <linux/bootmem.h>
 #include <linux/mm.h>
+#include <linux/personality.h>
 #include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
+#include <linux/efi.h>
 
 #include <asm/bitops.h>
 #include <asm/dma.h>
-#include <asm/efi.h>
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -37,6 +38,13 @@
 
 static unsigned long totalram_pages;
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+unsigned long vmalloc_end = VMALLOC_END_INIT;
+
+static struct page *vmem_map;
+static unsigned long num_dma_physpages;
+#endif
+
 int
 do_check_pgt_cache (int low, int high)
 {
@@ -67,10 +75,9 @@
 	struct vm_area_struct *vma;
 
 	/*
-	 * If we're out of memory and kmem_cache_alloc() returns NULL,
-	 * we simply ignore the problem.  When the process attempts to
-	 * write to the register backing store for the first time, it
-	 * will get a SEGFAULT in this case.
+	 * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
+	 * the problem.  When the process attempts to write to the register backing store
+	 * for the first time, it will get a SEGFAULT in this case.
 	 */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (vma) {
@@ -85,6 +92,19 @@
 		vma->vm_private_data = NULL;
 		insert_vm_struct(current->mm, vma);
 	}
+
+	/* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
+	if (!(current->personality & MMAP_PAGE_ZERO)) {
+		vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+		if (vma) {
+			memset(vma, 0, sizeof(*vma));
+			vma->vm_mm = current->mm;
+			vma->vm_end = PAGE_SIZE;
+			vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
+			vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
+			insert_vm_struct(current->mm, vma);
+		}
+	}
 }
 
 void
@@ -99,7 +119,7 @@
 		free_page(addr);
 		++totalram_pages;
 	}
-	printk (KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -141,7 +161,7 @@
 	end = end & PAGE_MASK;
 
 	if (start < end)
-		printk (KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
+		printk(KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
 
 	for (; start < end; start += PAGE_SIZE) {
 		if (!VALID_PAGE(virt_to_page(start)))
@@ -204,6 +224,8 @@
 	printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	i = max_mapnr;
 	while (i-- > 0) {
+		if (!VALID_PAGE(mem_map + i))
+			continue;
 		total++;
 		if (PageReserved(mem_map+i))
 			reserved++;
@@ -261,7 +283,7 @@
 void __init
 ia64_mmu_init (void *my_cpu_data)
 {
-	unsigned long flags, rid, pta, impl_va_bits;
+	unsigned long psr, rid, pta, impl_va_bits;
 	extern void __init tlb_init (void);
 #ifdef CONFIG_DISABLE_VHPT
 #	define VHPT_ENABLE_BIT	0
@@ -273,7 +295,7 @@
 	 * Set up the kernel identity mapping for regions 6 and 5.  The mapping for region
 	 * 7 is setup up in _start().
 	 */
-	ia64_clear_ic(flags);
+	psr = ia64_clear_ic();
 
 	rid = ia64_rid(IA64_REGION_ID_KERNEL, __IA64_UNCACHED_OFFSET);
 	ia64_set_rr(__IA64_UNCACHED_OFFSET, (rid << 8) | (IA64_GRANULE_SHIFT << 2));
@@ -287,7 +309,7 @@
 	ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
 		 pte_val(mk_pte_phys(__pa(my_cpu_data), PAGE_KERNEL)), PAGE_SHIFT);
 
-	__restore_flags(flags);
+	ia64_set_psr(psr);
 	ia64_srlz_i();
 
 	/*
@@ -335,6 +357,135 @@
 	ia64_tlb_init();
 }
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+
+#include <asm/pgtable.h>
+
+static int
+create_mem_map_page_table (u64 start, u64 end, void *arg)
+{
+	unsigned long address, start_page, end_page;
+	struct page *map_start, *map_end;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	/* should we use platform_map_nr here? */
+
+	map_start = vmem_map + MAP_NR_DENSE(start);
+	map_end   = vmem_map + MAP_NR_DENSE(end);
+
+	start_page = (unsigned long) map_start & PAGE_MASK;
+	end_page = PAGE_ALIGN((unsigned long) map_end);
+
+	for (address = start_page; address < end_page; address += PAGE_SIZE) {
+		pgd = pgd_offset_k(address);
+		if (pgd_none(*pgd))
+			pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE));
+		pmd = pmd_offset(pgd, address);
+
+		if (pmd_none(*pmd))
+			pmd_populate(&init_mm, pmd, alloc_bootmem_pages(PAGE_SIZE));
+		pte = pte_offset(pmd, address);
+
+		if (pte_none(*pte))
+			set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages(PAGE_SIZE)),
+						 PAGE_KERNEL));
+ 	}
+ 	return 0;
+}
+
+struct memmap_init_callback_data {
+	memmap_init_callback_t *memmap_init;
+	struct page *start;
+	struct page *end;
+	int zone;
+	int highmem;
+};
+
+static int
+virtual_memmap_init (u64 start, u64 end, void *arg)
+{
+	struct memmap_init_callback_data *args;
+	struct page *map_start, *map_end;
+
+	args = (struct memmap_init_callback_data *) arg;
+
+	/* Should we use platform_map_nr here? */
+
+	map_start = vmem_map + MAP_NR_DENSE(start);
+	map_end   = vmem_map + MAP_NR_DENSE(end);
+
+	if (map_start < args->start)
+		map_start = args->start;
+	if (map_end > args->end)
+		map_end = args->end;
+
+	/*
+	 * We have to initialize "out of bounds" struct page elements
+	 * that fit completely on the same pages that were allocated
+	 * for the "in bounds" elements because they may be referenced
+	 * later (and found to be "reserved").
+	 */
+	map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1))
+			/ sizeof(struct page);
+	map_end += ((PAGE_ALIGN((unsigned long) map_end) -
+				(unsigned long) map_end)
+			/ sizeof(struct page));
+
+	if (map_start < map_end)
+		(*args->memmap_init)(map_start, map_end, args->zone,
+				     page_to_phys(map_start), args->highmem);
+
+	return 0;
+}
+
+unsigned long
+arch_memmap_init (memmap_init_callback_t *memmap_init, struct page *start,
+	struct page *end, int zone, unsigned long start_paddr, int highmem)
+{
+	struct memmap_init_callback_data args;
+
+	args.memmap_init = memmap_init;
+	args.start = start;
+	args.end = end;
+	args.zone = zone;
+	args.highmem = highmem;
+
+	efi_memmap_walk(virtual_memmap_init, &args);
+
+	return page_to_phys(end);
+}
+
+static int
+count_dma_pages (u64 start, u64 end, void *arg)
+{
+	unsigned long *count = arg;
+
+	if (end <= MAX_DMA_ADDRESS)
+		*count += (end - start) >> PAGE_SHIFT;
+	return 0;
+}
+
+int
+ia64_page_valid (struct page *page)
+{
+	char byte;
+
+	return __get_user(byte, (char *) page) == 0;
+}
+
+#endif /* CONFIG_VIRTUAL_MEM_MAP */
+
+static int
+count_pages (u64 start, u64 end, void *arg)
+{
+	unsigned long *count = arg;
+
+	*count += (end - start) >> PAGE_SHIFT;
+	return 0;
+}
+
 /*
  * Set up the page tables.
  */
@@ -343,13 +494,49 @@
 {
 	unsigned long max_dma, zones_size[MAX_NR_ZONES];
 
-	clear_page((void *) ZERO_PAGE_ADDR);
-
 	/* initialize mem_map[] */
 
 	memset(zones_size, 0, sizeof(zones_size));
 
+	num_physpages = 0;
+	efi_memmap_walk(count_pages, &num_physpages);
+
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+	{
+		unsigned long zholes_size[MAX_NR_ZONES];
+		unsigned long map_size;
+
+		memset(zholes_size, 0, sizeof(zholes_size));
+
+		num_dma_physpages = 0;
+		efi_memmap_walk(count_dma_pages, &num_dma_physpages);
+
+		if (max_low_pfn < max_dma) {
+			zones_size[ZONE_DMA] = max_low_pfn;
+			zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
+		} else {
+			zones_size[ZONE_DMA] = max_dma;
+			zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
+			if (num_physpages > num_dma_physpages) {
+				zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
+				zholes_size[ZONE_NORMAL] = ((max_low_pfn - max_dma)
+							    - (num_physpages - num_dma_physpages));
+			}
+		}
+
+		/* allocate virtual mem_map: */
+
+		map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
+		vmalloc_end -= map_size;
+		vmem_map = (struct page *) vmalloc_end;
+		efi_memmap_walk(create_mem_map_page_table, 0);
+
+		free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size);
+		printk("Virtual mem_map starts at 0x%p\n", mem_map);
+	}
+#else /* !CONFIG_VIRTUAL_MEM_MAP */
 	if (max_low_pfn < max_dma)
 		zones_size[ZONE_DMA] = max_low_pfn;
 	else {
@@ -357,15 +544,7 @@
 		zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
 	}
 	free_area_init(zones_size);
-}
-
-static int
-count_pages (u64 start, u64 end, void *arg)
-{
-	unsigned long *count = arg;
-
-	*count += (end - start) >> PAGE_SHIFT;
-	return 0;
+#endif /* !CONFIG_VIRTUAL_MEM_MAP */
 }
 
 static int
@@ -401,9 +580,6 @@
 	if (!mem_map)
 		BUG();
 
-	num_physpages = 0;
-	efi_memmap_walk(count_pages, &num_physpages);
-
 	max_mapnr = max_low_pfn;
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
@@ -416,10 +592,10 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n",
+	printk(KERN_INFO "Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n",
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10),
-	       max_mapnr << (PAGE_SHIFT - 10), codesize >> 10, reserved_pages << (PAGE_SHIFT - 10),
-	       datasize >> 10, initsize >> 10);
+	       num_physpages << (PAGE_SHIFT - 10), codesize >> 10,
+	       reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10);
 
 	/*
 	 * Allow for enough (cached) page table pages so that we can map the entire memory
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/tlb.c linux-2.4.20/arch/ia64/mm/tlb.c
--- linux-2.4.19/arch/ia64/mm/tlb.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.20/arch/ia64/mm/tlb.c	2002-10-04 00:41:22.000000000 +0000
@@ -79,7 +79,7 @@
 	flush_tlb_all();
 }
 
-static inline void
+void
 ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
 	static spinlock_t ptcg_lock = SPIN_LOCK_UNLOCKED;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/README linux-2.4.20/arch/ia64/sn/fakeprom/README
--- linux-2.4.19/arch/ia64/sn/fakeprom/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/fakeprom/README	2002-10-04 00:41:20.000000000 +0000
@@ -71,7 +71,7 @@
     1GB*<dn>, where dn is the digit number. The amount of memory
     is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
 
-    SN1 doesnt support dimms this small but small memory systems 
+    SN1 doesn't support dimms this small but small memory systems 
     boot faster on Medusa.
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.20/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.19/arch/ia64/sn/fakeprom/fpmem.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/fakeprom/fpmem.c	2002-10-04 00:41:16.000000000 +0000
@@ -18,7 +18,7 @@
  */
 
 #include <linux/config.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include "fpmem.h"
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.20/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.19/arch/ia64/sn/fakeprom/fw-emu.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/fakeprom/fw-emu.c	2002-10-04 00:41:13.000000000 +0000
@@ -36,7 +36,7 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/Makefile linux-2.4.20/arch/ia64/sn/io/Makefile
--- linux-2.4.19/arch/ia64/sn/io/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/io/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -18,7 +18,7 @@
 O_TARGET := sgiio.o
 
 ifeq ($(CONFIG_MODULES),y)
-export-objs = pciio.o hcl.o
+export-objs = pciio.o hcl.o pci_dma.o
 endif
 
 obj-y  := stubs.o sgi_if.o pciio.o xtalk.o xbow.o xswitch.o klgraph_hack.o \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/efi-rtc.c linux-2.4.20/arch/ia64/sn/io/efi-rtc.c
--- linux-2.4.19/arch/ia64/sn/io/efi-rtc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/io/efi-rtc.c	2002-10-04 00:41:10.000000000 +0000
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/sn/klclock.h>
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/pci_dma.c linux-2.4.20/arch/ia64/sn/io/pci_dma.c
--- linux-2.4.19/arch/ia64/sn/io/pci_dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/io/pci_dma.c	2002-10-04 00:41:14.000000000 +0000
@@ -4,6 +4,9 @@
  * for more details.
  *
  * Copyright (C) 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ *
+ * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
+ * a description of how these routines should be used.
  */
 
 #include <linux/types.h>
@@ -12,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
@@ -27,15 +31,38 @@
 #include <asm/sn/pci/pci_bus_cvlink.h>
 #include <asm/sn/nag.h>
 
+/* DMA, PIO, and memory allocation flags */
+#ifdef CONFIG_IA64_SGI_SN1
+#define DMA_DATA_FLAGS		( PCIIO_BYTE_STREAM | PCIIO_DMA_DATA )
+#define DMA_CONTROL_FLAGS	( PCIIO_BYTE_STREAM | PCIBR_BARRIER | \
+				  PCIIO_DMA_CMD )
+#elif defined(CONFIG_IA64_SGI_SN2)
+#define DMA_DATA_FLAGS		( PCIIO_DMA_DATA )
+#define DMA_CONTROL_FLAGS	( PCIBR_BARRIER | PCIIO_DMA_CMD )
+#else
+#error need to define DMA mapping flags for this platform
+#endif
+
+/*
+ * For ATE allocations
+ */
 pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
 void free_pciio_dmamap(pcibr_dmamap_t);
-struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+
+/*
+ * Toplogy stuff
+ */
 extern devfs_handle_t busnum_to_pcibr_vhdl[];
 extern nasid_t busnum_to_nid[];
 extern void * busnum_to_atedmamaps[];
 
-/*
- * Get a free pciio_dmamap_t entry.
+/**
+ * get_free_pciio_dmamap - find and allocate an ATE
+ * @pci_bus: PCI bus to get an entry for
+ *
+ * Finds and allocates an ATE on the PCI bus specified
+ * by @pci_bus.
  */
 pciio_dmamap_t
 get_free_pciio_dmamap(devfs_handle_t pci_bus)
@@ -46,7 +73,7 @@
 	/*
 	 * Darn, we need to get the maps allocated for this bus.
 	 */
-	for (i=0; i<MAX_PCI_XWIDGET; i++) {
+	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
 		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
 			sn_dma_map = busnum_to_atedmamaps[i];
 		}
@@ -55,19 +82,21 @@
 	/*
 	 * Now get a free dmamap entry from this list.
 	 */
-	for (i=0; i<MAX_ATE_MAPS; i++, sn_dma_map++) {
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
 		if (!sn_dma_map->dma_addr) {
 			sn_dma_map->dma_addr = -1;
 			return( (pciio_dmamap_t) sn_dma_map );
 		}
 	}
 
-	return(NULL);
-
+	return NULL;
 }
 
-/*
- * Free pciio_dmamap_t entry.
+/**
+ * free_pciio_dmamap - free an ATE
+ * @dma_map: ATE to free
+ *
+ * Frees the ATE specified by @dma_map.
  */
 void
 free_pciio_dmamap(pcibr_dmamap_t dma_map)
@@ -76,177 +105,229 @@
 
 	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
 	sn_dma_map->dma_addr = 0;
+}
+
+/**
+ * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
+ * @dma_addr: DMA address to look for
+ * @busnum: PCI bus to look on
+ *
+ * Finds the ATE associated with @dma_addr and @busnum.
+ */
+static struct sn_dma_maps_s *
+find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+{
+
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+	int i;
+
+	sn_dma_map = busnum_to_atedmamaps[busnum];
+
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (sn_dma_map->dma_addr == dma_addr) {
+			return sn_dma_map;
+		}
+	}
 
+	printk(KERN_WARNING "find_sn_dma_map: Unable find the corresponding "
+	       "dma map\n");
+
+	return NULL;
 }
 
-/*
- * sn_dma_sync: This routine flushes all DMA buffers for the device into the II.
- *	This does not mean that the data is in the "Coherence Domain".  But it 
- *	is very close.
+/**
+ * sn_dma_sync - try to flush DMA buffers into the coherence domain
+ * @hwdev: device to flush
+ *
+ * This routine flushes all DMA buffers for the device into the II of
+ * the destination hub.
+ *
+ * NOTE!: this does not mean that the data is in the "coherence domain",
+ * but it is very close.  In other words, this routine *does not work*
+ * as advertised due to hardware bugs.  That said, it should be good enough for
+ * most situations.
  */
 void
-sn_dma_sync( struct pci_dev *hwdev )
+sn_dma_sync(struct pci_dev *hwdev)
 {
 
 	struct sn_device_sysdata *device_sysdata;
 	volatile unsigned long dummy;
 
 	/*
-	 * It is expected that on IA64 platform, a DMA sync ensures that all 
-	 * the DMA (dma_handle) are complete and coherent.
-	 *	1. Flush Write Buffers from Bridge.
-	 *	2. Flush Xbow Port.
+	 * It is expected that on an IA64 platform, a DMA sync ensures that 
+	 * all the DMA from a particular device is complete and coherent.  We
+	 * try to do this by
+	 *	1. flushing the write wuffers from Bridge
+	 *	2. flushing the Xbow port.
+	 * Unfortunately, this only gets the DMA transactions 'very close' to
+	 * the coherence domain, but not quite in it.
 	 */
 	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
 	dummy = (volatile unsigned long ) *device_sysdata->dma_buf_sync;
 
 	/*
-	 * For the Xbow Port flush, we maybe denied the request because 
-	 * someone else may be flushing the Port .. try again.
+	 * For the Xbow port flush, we maybe denied the request because 
+	 * someone else may be flushing the port .. try again.
 	 */
 	while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) {
 		udelay(2);
 	}
 }
 
-
-struct sn_dma_maps_s *
-find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
-{
-
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-	int i;
-
-	sn_dma_map = busnum_to_atedmamaps[busnum];
-
-	for (i=0; i<MAX_ATE_MAPS; i++, sn_dma_map++) {
-		if (sn_dma_map->dma_addr == dma_addr) {
-			return( sn_dma_map );
-		}
-	}
-
-printk("find_pciio_dmamap: Unable find the corresponding dma map\n");
-
-	return(NULL);
-
-}
-
-/*
- * sn1 platform specific pci_alloc_consistent()
+/**
+ * sn_pci_alloc_consistent - allocate memory for coherent DMA
+ * @hwdev: device to allocate for
+ * @size: size of the region
+ * @dma_handle: DMA (bus) address
+ *
+ * pci_alloc_consistent() returns a pointer to a memory region suitable for
+ * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
+ * that @dma_handle will have the PCIBR_BARRIER and PCIIO_DMA_CMD flags
+ * set.
  *
- * this interface is meant for "command" streams, i.e. called only
- * once for initializing a device, so we don't want prefetching or
- * write gathering turned on, hence the PCIIO_DMA_CMD flag
+ * This interface is usually used for "command" streams (e.g. the command
+ * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
+ * more information.  Note that this routine should always put a 32 bit
+ * DMA address into @dma_handle.  This is because most other platforms
+ * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
+ * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
+ *
+ * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
  */
 void *
-sn_pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
 {
-        void *ret;
-        int gfp = GFP_ATOMIC;
-	devfs_handle_t    vhdl;
+        void *cpuaddr;
+	devfs_handle_t vhdl;
 	struct sn_device_sysdata *device_sysdata;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
+	pciio_dmamap_t dma_map = 0;
+	struct sn_dma_maps_s *sn_dma_map;
 
-	*dma_handle = (dma_addr_t) NULL;
+	*dma_handle = 0;
+
+	/* We can't easily support < 32 bit devices */
+	if (IS_PCI32L(hwdev))
+		return NULL;
 
 	/*
-	 * get vertex for the device
+	 * Get hwgraph vertex for the device
 	 */
 	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 
-        if ( (ret = (void *)__get_free_pages(gfp, get_order(size))) ) {
-		memset(ret, 0, size);
-	} else {
-		return(NULL);
-	}
-
-	temp_ptr = (paddr_t) __pa(ret);
-	if (IS_PCIA64(hwdev)) {
+	/*
+	 * Allocate the memory.  FIXME: if we're allocating for
+	 * two devices on the same bus, we should at least try to
+	 * allocate memory in the same 2 GB window to avoid using
+	 * ATEs for the translation.  See the comment above about the
+	 * 32 bit requirement for this function.
+	 */
+	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+		return NULL;
 
-		/*
-		 * This device supports 64bits DMA addresses.
-		 */
-#ifdef CONFIG_IA64_SGI_SN1
-		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD
-			| PCIIO_DMA_A64 );
-#else /* SN2 */
-		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_DMA_CMD | PCIIO_DMA_A64 );
-#endif
+	memset(cpuaddr, 0, size); /* have to zero it out */
 
-		return (ret);
-	}
+	/* physical addr. of the memory we just got */
+	phys_addr = __pa(cpuaddr);
 
+	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					  DMA_CONTROL_FLAGS);
 	/*
-	 * Devices that supports 32 Bits upto 63 Bits DMA Address gets
-	 * 32 Bits DMA addresses.
-	 *
-	 * First try to get 32 Bit Direct Map Support.
+	 * It is a 32 bit card and we cannot do direct mapping,
+	 * so we use an ATE.
 	 */
-	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
-#else /* SN2 */
-		*dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size,
-			PCIBR_BARRIER | PCIIO_DMA_CMD);
-#endif
-
-		if (dma_handle) {
-			return (ret);
-		} else {
-			/*
-			 * We need to map this request by using ATEs.
-			 */
-			printk("sn_pci_alloc_consistent: 32Bits DMA Page Map support not available yet!");
+	if (!(*dma_handle)) {
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
+					     DMA_CONTROL_FLAGS | PCIIO_FIXED);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
+			       "allocate anymore 32 bit page map entries.\n");
 			BUG();
 		}
-	}
-
-	if (IS_PCI32L(hwdev)) {
-		/*
-		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
-		 */
-		return (NULL);
-	}
+		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
+							     size);
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = *dma_handle;
+		printk(KERN_INFO "%s: PMU mapping: %p\n", __FUNCTION__,
+		       (void *)*dma_handle);
+	}
+	else
+		printk(KERN_INFO "%s: direct mapping: %p\n", __FUNCTION__,
+		       (void *)*dma_handle);
+	
 
-        return NULL;
+        return cpuaddr;
 }
 
+/**
+ * sn_pci_free_consistent - free memory associated with coherent DMAable region
+ * @hwdev: device to free for
+ * @size: size to free
+ * @vaddr: kernel virtual address to free
+ * @dma_handle: DMA address associated with this region
+ *
+ * Frees the memory allocated by pci_alloc_consistent().  Also known
+ * as platform_pci_free_consistent() by the IA64 machvec code.
+ */
 void
 sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_handle))
+		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
-/*
- * On sn1 we use the page entry of the scatterlist to store
- * the physical address corresponding to the given virtual address
+/**
+ * sn_pci_map_sg - map a scatter-gather list for DMA
+ * @hwdev: device to map for
+ * @sg: scatterlist to map
+ * @nents: number of entries
+ * @direction: direction of the DMA transaction
+ *
+ * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
+ * IA64 machvec code.
  */
 int
-sn_pci_map_sg (struct pci_dev *hwdev,
-                        struct scatterlist *sg, int nents, int direction)
+sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
 
 	int i;
-	devfs_handle_t	vhdl;
+	devfs_handle_t vhdl;
 	dma_addr_t dma_addr;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map;
 
-
-
+	/* can't go anywhere w/o a direction in life */
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
 	/*
-	 * Handle 64 bit cards.
+	 * Get the hwgraph vertex for the device
 	 */
 	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Setup a DMA address for each entry in the
+	 * scatterlist.
+	 */
 	for (i = 0; i < nents; i++, sg++) {
 		/* this catches incorrectly written drivers that
                    attempt to map scatterlists that they have
@@ -262,50 +343,37 @@
 			    "%p - this is currently being worked around.\n",
 			    hwdev->slot_name, (void *)sg->address);
 #endif
-			temp_ptr = (u64)sg->address & TO_PHYS_MASK;
+			phys_addr = (u64)sg->address & TO_PHYS_MASK;
 			break;
-		case 0xe: /* a good address, we now map it. */
-			temp_ptr = (paddr_t) __pa(sg->address);
+		default: /* not previously mapped, get the phys. addr */
+			phys_addr = __pa(sg->address);
 			break;
-		default:
-			printk(KERN_ERR
-			       "Very bad address (%p) passed to sn_pci_map_sg\n",
-			       (void *)sg->address);
-			BUG();
 		}
-		sg->page = (char *)NULL;
+		sg->page = NULL;
 		dma_addr = 0;
 
 		/*
-		 * Handle the most common case 64Bit cards.
+		 * Handle the most common case: 64 bit cards.  This
+		 * call should always succeed.
 		 */
 		if (IS_PCIA64(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length,
-				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA |
-				PCIIO_DMA_A64 );
-#else
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length,
-				PCIIO_DMA_DATA | PCIIO_DMA_A64 );
-#endif
+			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+						       DMA_DATA_FLAGS | PCIIO_DMA_A64 );
 			sg->address = (char *)dma_addr;
 			continue;
 		}
 
 		/*
-		 * Handle 32Bits and greater cards.
+		 * Handle 32-63 bit cards via direct mapping
 		 */
 		if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length,
-				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
-#else
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length, PCIIO_DMA_DATA);
-#endif
+			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+						       DMA_DATA_FLAGS);
+			/*
+			 * See if we got a direct map entry
+			 */
 			if (dma_addr) {
 				sg->address = (char *)dma_addr;
 				continue;
@@ -314,22 +382,18 @@
 		}
 
 		/*
-		 * It is a 32bit card and we cannot do Direct mapping.
-		 * Let's 32Bit Page map the request.
+		 * It is a 32 bit card and we cannot do direct mapping,
+		 * so we use an ATE.
 		 */
-		dma_map = NULL;
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, 
-				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
-#else
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, PCIIO_DMA_DATA);
-#endif
+		dma_map = 0;
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
+					     DMA_DATA_FLAGS);
 		if (!dma_map) {
-			printk("pci_map_sg: Unable to allocate anymore 32Bits Page Map entries.\n");
+			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
+			       "anymore 32 bit page map entries.\n");
 			BUG();
 		}
-		dma_addr = (dma_addr_t)pciio_dmamap_addr(dma_map, temp_ptr, sg->length);
-		/* printk("pci_map_sg: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map, temp_ptr, dma_addr); */
+		dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
 		sg->address = (char *)dma_addr;
 		sg->page = (char *)dma_map;
 		
@@ -339,30 +403,34 @@
 
 }
 
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
+/**
+ * sn_pci_unmap_sg - unmap a scatter-gather list
+ * @hwdev: device to unmap
+ * @sg: scatterlist to unmap
+ * @nents: number of scatterlist entries
+ * @direction: DMA direction
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
+ * concerning calls here are the same as for pci_unmap_single() below.  Also
+ * known as sn_pci_unmap_sg() by the IA64 machvec code.
  */
 void
-sn_pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
+sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
 	int i;
 	struct sn_dma_maps_s *sn_dma_map;
 
-
+	/* can't go anywhere w/o a direction in life */
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
-	for (i = 0; i < nelems; i++, sg++)
+	for (i = 0; i < nents; i++, sg++)
 		if (sg->page) {
 			/*
 			 * We maintain the DMA Map pointer in sg->page if 
 			 * it is ever allocated.
 			 */
-			/* phys_to_virt((dma_addr_t)sg->address | ~0x80000000); */
-			/* sg->address = sg->page; */
-			sg->address = (char *)-1;
+			sg->address = 0;
 			sn_dma_map = (struct sn_dma_maps_s *)sg->page;
 			pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
 			pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
@@ -372,7 +440,17 @@
 
 }
 
-/*
+/**
+ * sn_pci_map_single - map a single region for DMA
+ * @hwdev: device to map for
+ * @ptr: kernel virtual address of the region to map
+ * @size: size of the region
+ * @direction: DMA direction
+ *
+ * Map the region pointed to by @ptr for DMA and return the
+ * DMA address.   Also known as platform_pci_map_single() by
+ * the IA64 machvec code.
+ *
  * We map this to the one step pciio_dmamap_trans interface rather than
  * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
  * no way of saving the dmamap handle from the alloc to later free
@@ -382,20 +460,21 @@
  *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
  *       figure out how to save dmamap handle so can use two step.
  */
-dma_addr_t sn_pci_map_single (struct pci_dev *hwdev,
-				void *ptr, size_t size, int direction)
+dma_addr_t
+sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
-	devfs_handle_t	vhdl;
+	devfs_handle_t vhdl;
 	dma_addr_t dma_addr;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map = NULL;
 	struct sn_dma_maps_s *sn_dma_map;
 
-
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
+	/* SN cannot support DMA addresses smaller than 32 bits. */
+	if (IS_PCI32L(hwdev)) return 0;
 
 	/*
 	 * find vertex for the device
@@ -407,79 +486,63 @@
 	 * Call our dmamap interface
 	 */
 	dma_addr = 0;
-	temp_ptr = (paddr_t) __pa(ptr);
+	phys_addr = __pa(ptr);
 
 	if (IS_PCIA64(hwdev)) {
 		/*
-		 * This device supports 64bits DMA addresses.
+		 * This device supports 64 bit DMA addresses.
 		 */
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size,
-			PCIIO_BYTE_STREAM | PCIIO_DMA_DATA | PCIIO_DMA_A64 );
-#else
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size, PCIIO_DMA_DATA | PCIIO_DMA_A64 );
-#endif
-		return (dma_addr);
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					       DMA_DATA_FLAGS | PCIIO_DMA_A64);
+		return dma_addr;
 	}
 
 	/*
-	 * Devices that supports 32 Bits upto 63 Bits DMA Address gets
-	 * 32 Bits DMA addresses.
+	 * Devices that supports 32 bit to 63 bit DMA addresses get
+	 * 32 bit DMA addresses.
 	 *
-	 * First try to get 32 Bit Direct Map Support.
+	 * First try to get a 32 bit direct map register.
 	 */
 	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size,
-			PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
-#else
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size, PCIIO_DMA_DATA);
-#endif
-		if (dma_addr) {
-			return (dma_addr);
-		}
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					       DMA_DATA_FLAGS);
+		if (dma_addr)
+			return dma_addr;
 	}
 
-	if (IS_PCI32L(hwdev)) {
-		/*
-		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
-		 */
-		return ((dma_addr_t) NULL);
-        }
-
 	/*
-	 * It is a 32bit card and we cannot do Direct mapping.
-	 * Let's 32Bit Page map the request.
+	 * It's a 32 bit card and we cannot do direct mapping so
+	 * let's use the PMU instead.
 	 */
 	dma_map = NULL;
-#ifdef CONFIG_IA64_SGI_SN1
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_BYTE_STREAM | 
-				     PCIIO_DMA_DATA);
-#else
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_DMA_DATA);
-#endif
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, DMA_DATA_FLAGS);
+
 	if (!dma_map) {
-		printk("pci_map_single: Unable to allocate anymore 32Bits Page Map entries.\n");
+		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
+		       "32 bits page map entries.\n");
 		BUG();
 	}
 
-	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, temp_ptr, size);
-	/* printk("pci_map_single: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map,
-		temp_ptr, dma_addr); */
+	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
 	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
 	sn_dma_map->dma_addr = dma_addr;
 
 	return ((dma_addr_t)dma_addr);
 }
 
+/**
+ * sn_pci_unmap_single - unmap a region used for DMA
+ * @hwdev: device to unmap
+ * @dma_addr: DMA address to unmap
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * Unmaps the region pointed to by @dma_addr.  Also known as
+ * platform_pci_unmap_single() by the IA64 machvec code.
+ */
 void
-sn_pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
-
 	struct sn_dma_maps_s *sn_dma_map = NULL;
 
         if (direction == PCI_DMA_NONE)
@@ -491,37 +554,97 @@
 	if (IS_PCI32_MAPPED(dma_addr))
 		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
 
+	/*
+	 * and free it if necessary...
+	 */
 	if (sn_dma_map) {
 		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
 		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
 		sn_dma_map->dma_addr = (dma_addr_t)NULL;
 	}
-
 }
 
+/**
+ * sn_pci_dma_sync_single - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @dma_handle: DMA address to sync
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA region specified
+ * by @dma_handle into the 'coherence domain'.  See sn_dma_sync()
+ * above for more information.   Also known as
+ * platform_pci_dma_sync_single() by the IA64 machvec code.
+ */
 void
-sn_pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
-	
-        if (direction == PCI_DMA_NONE)
+	if (direction == PCI_DMA_NONE)
                 BUG();
 
 	sn_dma_sync(hwdev);
-
 }
 
+/**
+ * sn_pci_dma_sync_sg - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @sg: scatterlist to sync
+ * @nents: number of entries in the scatterlist
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA regions specified
+ * by @sg into the 'coherence domain'.  See sn_dma_sync()
+ * above for more information.   Also known as
+ * platform_pci_dma_sync_sg() by the IA64 machvec code.
+ */
 void
-sn_pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
+sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
         if (direction == PCI_DMA_NONE)
                 BUG();
 
 	sn_dma_sync(hwdev);
-
 }
 
+/**
+ * sn_dma_address - get the DMA address for the first entry of a scatterlist
+ * @sg: sg to look at
+ *
+ * Gets the DMA address for the scatterlist @sg.  Also known as
+ * platform_dma_address() by the IA64 machvec code.
+ */
 unsigned long
-sn_dma_address (struct scatterlist *sg)
+sn_dma_address(struct scatterlist *sg)
 {
 	return ((unsigned long)sg->address);
 }
+
+/**
+ * sn_dma_supported - test a DMA mask
+ * @hwdev: device to test
+ * @mask: DMA mask to test
+ *
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * this function.  Of course, SN only supports devices that have 32 or more
+ * address bits.
+ */
+int
+sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	if (mask < 0xffffffff)
+		return 0;
+	return 1;
+}
+
+EXPORT_SYMBOL(sn_pci_unmap_single);
+EXPORT_SYMBOL(sn_pci_map_single);
+EXPORT_SYMBOL(sn_pci_dma_sync_single);
+EXPORT_SYMBOL(sn_pci_map_sg);
+EXPORT_SYMBOL(sn_pci_unmap_sg);
+EXPORT_SYMBOL(sn_pci_alloc_consistent);
+EXPORT_SYMBOL(sn_pci_free_consistent);
+EXPORT_SYMBOL(sn_dma_address);
+EXPORT_SYMBOL(sn_pci_dma_supported);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/llsc4.c linux-2.4.20/arch/ia64/sn/kernel/llsc4.c
--- linux-2.4.19/arch/ia64/sn/kernel/llsc4.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/kernel/llsc4.c	2002-10-04 00:41:11.000000000 +0000
@@ -17,7 +17,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/page.h>
 #include <linux/threads.h>
 #include <asm/sn/simulator.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/misctest.c linux-2.4.20/arch/ia64/sn/kernel/misctest.c
--- linux-2.4.19/arch/ia64/sn/kernel/misctest.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/kernel/misctest.c	2002-10-04 00:41:14.000000000 +0000
@@ -75,7 +75,7 @@
 	if (mcatest == 5) {
 		int zzzspec(long);
 		int	i;
-		long	flags, dcr, res, val, addr=0xff00000000UL;
+		long	psr, dcr, res, val, addr=0xff00000000UL;
 
 		dcr = ia64_get_dcr();
 		for (i=0; i<5; i++) {
@@ -87,11 +87,11 @@
 			ia64_set_dcr(dcr);
 			res = ia64_sn_probe_io_slot(0xff00000000UL, 8, &val);
 			printk("zzzspec: probe %ld, 0x%lx\n", res, val);
-			ia64_clear_ic(flags);
+			psr = ia64_clear_ic();
 			ia64_itc(0x2, 0xe00000ff00000000UL,
 			          pte_val(mk_pte_phys(0xff00000000UL,
 				  __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW))), _PAGE_SIZE_256M);
-			local_irq_restore(flags);
+			ia64_set_psr(psr);
 			ia64_srlz_i ();
 		}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/sn_ksyms.c linux-2.4.20/arch/ia64/sn/kernel/sn_ksyms.c
--- linux-2.4.19/arch/ia64/sn/kernel/sn_ksyms.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/sn/kernel/sn_ksyms.c	2002-10-04 00:41:30.000000000 +0000
@@ -17,15 +17,6 @@
 #include <asm/machvec.h>
 #include <asm/sn/intr.h>
 
-/*
- * other stuff (more to be added later, cleanup then)
- */
-EXPORT_SYMBOL(sn_pci_map_sg);
-EXPORT_SYMBOL(sn_pci_unmap_sg);
-EXPORT_SYMBOL(sn_pci_alloc_consistent);
-EXPORT_SYMBOL(sn_pci_free_consistent);
-EXPORT_SYMBOL(sn_dma_address);
-
 #include <linux/mm.h>
 #include <linux/devfs_fs_kernel.h>
 extern devfs_handle_t          base_io_scsi_ctlr_vhdl[];
@@ -62,6 +53,4 @@
 EXPORT_SYMBOL(sn_send_IPI_phys);
 
 #include <linux/mmzone.h>
-EXPORT_SYMBOL(sn_pci_unmap_single);
-EXPORT_SYMBOL(sn_pci_map_single);
-EXPORT_SYMBOL(sn_pci_dma_sync_single);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/tools/Makefile linux-2.4.20/arch/ia64/tools/Makefile
--- linux-2.4.19/arch/ia64/tools/Makefile	2002-02-25 19:37:53.000000000 +0000
+++ linux-2.4.20/arch/ia64/tools/Makefile	2002-10-04 00:41:09.000000000 +0000
@@ -2,9 +2,9 @@
 
 TARGET	= $(TOPDIR)/include/asm-ia64/offsets.h
 
-all: 
+all:
 
-mrproper:
+mrproper: clean
 
 clean:
 	rm -f print_offsets.s print_offsets offsets.h
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/tools/print_offsets.c linux-2.4.20/arch/ia64/tools/print_offsets.c
--- linux-2.4.19/arch/ia64/tools/print_offsets.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/tools/print_offsets.c	2002-10-04 00:41:29.000000000 +0000
@@ -58,7 +58,8 @@
     { "IA64_TASK_THREAD_OFFSET",	offsetof (struct task_struct, thread) },
     { "IA64_TASK_THREAD_KSP_OFFSET",	offsetof (struct task_struct, thread.ksp) },
 #ifdef CONFIG_PERFMON
-    { "IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET",offsetof(struct task_struct, thread.pfm_ovfl_block_reset) },
+    { "IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET",
+					offsetof(struct task_struct, thread.pfm_ovfl_block_reset) },
 #endif
     { "IA64_TASK_PID_OFFSET",		offsetof (struct task_struct, pid) },
     { "IA64_TASK_MM_OFFSET",		offsetof (struct task_struct, mm) },
@@ -152,6 +153,7 @@
     { "IA64_SWITCH_STACK_AR_RNAT_OFFSET",	offsetof (struct switch_stack, ar_rnat) },
     { "IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET",	offsetof (struct switch_stack, ar_bspstore) },
     { "IA64_SWITCH_STACK_PR_OFFSET",	offsetof (struct switch_stack, pr) },
+    { "IA64_SIGCONTEXT_IP_OFFSET",	offsetof (struct sigcontext, sc_ip) },
     { "IA64_SIGCONTEXT_AR_BSP_OFFSET",	offsetof (struct sigcontext, sc_ar_bsp) },
     { "IA64_SIGCONTEXT_AR_FPSR_OFFSET", offsetof (struct sigcontext, sc_ar_fpsr) },
     { "IA64_SIGCONTEXT_AR_RNAT_OFFSET",	offsetof (struct sigcontext, sc_ar_rnat) },
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/vmlinux.lds.S linux-2.4.20/arch/ia64/vmlinux.lds.S
--- linux-2.4.19/arch/ia64/vmlinux.lds.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/ia64/vmlinux.lds.S	2002-10-04 00:41:14.000000000 +0000
@@ -1,5 +1,6 @@
 #include <linux/config.h>
 
+#include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/system.h>
 
@@ -27,11 +28,6 @@
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
 	*(.text.ivt)
-	/* these are not really text pages, but they need to be page aligned: */
-	*(__special_page_section)
-	__start_gate_section = .;
-	*(.text.gate)
-	__stop_gate_section = .;
 	*(.text)
     }
   .text2 : AT(ADDR(.text2) - PAGE_OFFSET)
@@ -44,8 +40,6 @@
 
   /* Read-only data */
 
-  __gp = ALIGN(16) + 0x200000;	/* gp must be 16-byte aligned for exc. table */
-
   /* Global data */
   _data = .;
 
@@ -117,9 +111,13 @@
 	{ *(init_task) }
 
   .data.page_aligned : AT(ADDR(.data.page_aligned) - PAGE_OFFSET)
-        { *(.data.idt) }
+        { *(__special_page_section)
+	  __start_gate_section = .;
+	  *(.text.gate)
+	  __stop_gate_section = .;
+	}
 
-  . = ALIGN(64);
+  . = ALIGN(SMP_CACHE_BYTES);
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET)
         { *(.data.cacheline_aligned) }
 
@@ -130,6 +128,10 @@
   .data : AT(ADDR(.data) - PAGE_OFFSET)
 	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
 
+
+  . = ALIGN(16);
+  __gp = . + 0x200000;	/* gp must be 16-byte aligned for exc. table */
+
   .got : AT(ADDR(.got) - PAGE_OFFSET)
 	{ *(.got.plt) *(.got) }
   /* We want the small data sections together, so single-instruction offsets
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/amiga/config.c linux-2.4.20/arch/m68k/amiga/config.c
--- linux-2.4.19/arch/m68k/amiga/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/amiga/config.c	2002-10-04 00:41:10.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/console.h>
 #include <linux/rtc.h>
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
 #endif
@@ -128,8 +129,6 @@
 	"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 
     /*
      *  Motherboard Resources present in all Amiga models
@@ -390,10 +389,12 @@
     request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
 
   mach_sched_init      = amiga_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = amiga_keyb_init;
   mach_kbdrate         = amiga_kbdrate;
   mach_kbd_translate   = amiga_kbd_translate;
-  SYSRQ_KEY            = 0xff;
+  kd_mksound           = amiga_mksound;
+#endif
   mach_init_IRQ        = amiga_init_IRQ;
   mach_default_handler = &amiga_default_handler;
   mach_request_irq     = amiga_request_irq;
@@ -434,8 +435,8 @@
 #ifdef CONFIG_DUMMY_CONSOLE
   conswitchp           = &dummy_con;
 #endif
-  kd_mksound           = amiga_mksound;
 #ifdef CONFIG_MAGIC_SYSRQ
+  SYSRQ_KEY            = 0xff;
   mach_sysrq_key = 0x5f;	     /* HELP */
   mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */
   mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/apollo/config.c linux-2.4.20/arch/m68k/apollo/config.c
--- linux-2.4.19/arch/m68k/apollo/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/apollo/config.c	2002-10-04 00:41:15.000000000 +0000
@@ -5,6 +5,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
@@ -42,7 +43,6 @@
 extern void dn_dummy_waitbut(void);
 extern struct fb_info *dn_fb_init(long *);
 extern void dn_dummy_debug_init(void);
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void dn_dummy_video_setup(char *,int *);
 extern void dn_process_int(int irq, struct pt_regs *fp);
 #ifdef CONFIG_HEARTBEAT
@@ -166,8 +166,11 @@
 	dn_setup_model();	
 
 	mach_sched_init=dn_sched_init; /* */
+#ifdef CONFIG_VT
 	mach_keyb_init=dn_keyb_init;
 	mach_kbdrate=dn_dummy_kbdrate;
+	kd_mksound	     = dn_mksound;
+#endif
 	mach_init_IRQ=dn_init_IRQ;
 	mach_default_handler=NULL;
 	mach_request_irq     = dn_request_irq;
@@ -189,7 +192,6 @@
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
 #endif
-	kd_mksound	     = dn_mksound;
 #ifdef CONFIG_HEARTBEAT
   	mach_heartbeat = dn_heartbeat;
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/apollo/dn_ints.c linux-2.4.20/arch/m68k/apollo/dn_ints.c
--- linux-2.4.19/arch/m68k/apollo/dn_ints.c	2001-03-07 03:44:35.000000000 +0000
+++ linux-2.4.20/arch/m68k/apollo/dn_ints.c	2002-10-04 00:41:22.000000000 +0000
@@ -12,11 +12,6 @@
 
 static irq_handler_t dn_irqs[16];
 
-extern void write_keyb_cmd(u_short length, u_char *cmd);
-static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
-		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
-
-extern void dn_serial_print (const char *str);
 void dn_process_int(int irq, struct pt_regs *fp) {
 
 
@@ -120,6 +115,11 @@
 
 }
 
+#ifdef CONFIG_VT
+extern void write_keyb_cmd(u_short length, u_char *cmd);
+static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
+		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
+
 static void dn_nosound (unsigned long ignored) {
 
 	write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
@@ -141,6 +141,8 @@
 	else
 		write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
 }
+#endif /* CONFIG_VT */
+
 
 void dn_dummy_video_setup(char *options,int *ints) {
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/atari/Makefile linux-2.4.20/arch/m68k/atari/Makefile
--- linux-2.4.19/arch/m68k/atari/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux-2.4.20/arch/m68k/atari/Makefile	2002-10-04 00:41:11.000000000 +0000
@@ -11,10 +11,12 @@
 
 export-objs	:= atari_ksyms.o
 
-obj-y		:= config.o time.o debug.o atakeyb.o ataints.o stdma.o \
-			atasound.o joystick.o stram.o atari_ksyms.o
+obj-y		:= config.o time.o debug.o ataints.o stdma.o \
+			atasound.o stram.o atari_ksyms.o
 
-ifdef CONFIG_PCI
+obj-$(CONFIG_VT)	+= atakeyb.o joystick.o
+
+ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)	+= hades-pci.o
 endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/atari/config.c linux-2.4.20/arch/m68k/atari/config.c
--- linux-2.4.19/arch/m68k/atari/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/atari/config.c	2002-10-04 00:41:11.000000000 +0000
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/vt_kern.h>
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
@@ -102,7 +103,6 @@
 	"0.\r\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 
 /* I've moved hwreg_present() and hwreg_present_bywrite() out into
  * mm/hwtest.c, to avoid having multiple copies of the same routine
@@ -254,13 +254,13 @@
                                            to 4GB. */
 
     mach_sched_init      = atari_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
     mach_kbd_translate   = atari_kbd_translate;
-#ifdef CONFIG_MAGIC_SYSRQ
-    SYSRQ_KEY            = 0xff;
-#endif
     mach_kbd_leds        = atari_kbd_leds;
+    kd_mksound		 = atari_mksound;
+#endif
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
     mach_free_irq        = atari_free_irq;
@@ -278,8 +278,8 @@
     conswitchp	         = &dummy_con;
 #endif
     mach_max_dma_address = 0xffffff;
-    kd_mksound		 = atari_mksound;
 #ifdef CONFIG_MAGIC_SYSRQ
+    SYSRQ_KEY            = 0xff;
     mach_sysrq_key = 98;          /* HELP */
     mach_sysrq_shift_state = 8;   /* Alt */
     mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/bvme6000/config.c linux-2.4.20/arch/m68k/bvme6000/config.c
--- linux-2.4.19/arch/m68k/bvme6000/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/bvme6000/config.c	2002-10-04 00:41:10.000000000 +0000
@@ -135,8 +135,10 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = bvme6000_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = bvme6000_keyb_init;
     mach_kbdrate         = bvme6000_kbdrate;
+#endif
     mach_init_IRQ        = bvme6000_init_IRQ;
     mach_gettimeoffset   = bvme6000_gettimeoffset;
     mach_gettod  	 = bvme6000_gettod;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/bvme6000/rtc.c linux-2.4.20/arch/m68k/bvme6000/rtc.c
--- linux-2.4.19/arch/m68k/bvme6000/rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/bvme6000/rtc.c	2002-10-04 00:41:10.000000000 +0000
@@ -94,7 +94,7 @@
 
 		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
 
-		if ((mon > 12) || (day == 0))
+		if ((mon > 12) || (mon < 1) || (day == 0))
 			return -EINVAL;
 
 		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/config.in linux-2.4.20/arch/m68k/config.in
--- linux-2.4.19/arch/m68k/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/config.in	2002-10-04 00:41:29.000000000 +0000
@@ -141,7 +141,7 @@
    fi
    dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
    if [ "$CONFIG_PRINTER" != "n" ]; then
-      bool '    Support IEEE1284 status readback' CONFIG_PARPORT_1284
+      bool '    IEEE 1284 transfer modes' CONFIG_PARPORT_1284
    fi
 fi
 
@@ -376,6 +376,11 @@
 mainmenu_option next_comment
 comment 'Character devices'
  
+bool 'Virtual terminal' CONFIG_VT
+if [ "$CONFIG_VT" = "y" ]; then
+   bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
+fi
+
 if [ "$CONFIG_Q40" = "y" ]; then
    tristate 'Q40 Standard/generic serial support' CONFIG_SERIAL
 fi
@@ -391,13 +396,6 @@
    bool '    Support the Bell Technologies HUB6 card' CONFIG_HUB6
 fi
 
-if [ "$CONFIG_VME" = "n" ]; then
-   define_bool CONFIG_VT y
-   if [ "$CONFIG_VT" = "y" ]; then
-      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
-   fi
-fi
-
 if [ "$CONFIG_ATARI" = "y" ]; then
    define_bool CONFIG_NVRAM y
 fi
@@ -408,7 +406,7 @@
       define_bool CONFIG_BUSMOUSE y
    fi
 fi
-if [ "$CONFIG_ATARI" = "y" ]; then
+if [ "$CONFIG_ATARI" = "y" -a "$CONFIG_VT" = "y" ]; then
    tristate 'Atari mouse support' CONFIG_ATARIMOUSE
    if [ "$CONFIG_ATARIMOUSE" != "n" ]; then
       define_bool CONFIG_BUSMOUSE y
@@ -430,16 +428,16 @@
    if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
       tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
    fi
+   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
+   fi
 fi
 if [ "$CONFIG_PARPORT" = "n" ]; then
    if [ "$CONFIG_ZORRO" = "y" ]; then
       tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
-      tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
-      fi
    fi
 fi
 if [ "$CONFIG_MAC" = "y" ]; then
@@ -464,6 +462,20 @@
 if [ "$CONFIG_HP300" = "y" -a "$CONFIG_DIO" = "y" ]; then
    tristate 'HP DCA serial support' CONFIG_HPDCA
 fi
+if [ "$CONFIG_MVME147" = "y" ]; then
+   bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
+fi
+if [ "$CONFIG_MVME16x" = "y" ]; then
+   bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
+   bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
+fi
+if [ "$CONFIG_BVME6000" = "y" ]; then
+   bool 'SCC support for BVME6000 serial ports' CONFIG_BVME6000_SCC
+fi
+if [ "$CONFIG_APOLLO" = "y" ]; then
+   bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
+   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
+fi 
 
 if [ "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
    bool 'Sun3/3x builtin serial support' CONFIG_SUN3X_ZS
@@ -483,37 +495,16 @@
    define_bool CONFIG_SBUS n
 fi
 
-if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o \
-     "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" -o \
-     "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
-   if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
-        "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
-        "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
-        "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
-        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
-	"$CONFIG_SERIAL" = "y" ]; then
-      bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-   fi
-fi
-if [ "$CONFIG_VME" = "y" ]; then
-   define_bool CONFIG_SERIAL_CONSOLE y
-   if [ "$CONFIG_MVME147" = "y" ]; then
-      bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
-   fi
-   if [ "$CONFIG_MVME16x" = "y" ]; then
-      bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
-      bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
-   fi
-   if [ "$CONFIG_BVME6000" = "y" ]; then
-      bool 'SCC support for BVME6000 serial ports' CONFIG_BVME6000_SCC
-   fi
-fi
-if [ "$CONFIG_APOLLO" = "y" ]; then
-   bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
+if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
+     "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
+     "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o "$CONFIG_GVPIOEXT" = "y" -o \
+     "$CONFIG_MULTIFACE_III_TTY" = "y" -o "$CONFIG_HPDCA" = "y" -o \
+     "$CONFIG_SUN3X_ZS" = "y" -o "$CONFIG_SERIAL" = "y" -o \
+     "$CONFIG_MVME147_SCC" -o "$CONFIG_SERIAL167" = "y" -o \
+     "$CONFIG_MVME162_SCC" -o "$CONFIG_BVME6000_SCC" = "y" -o \
+     "$CONFIG_DN_SERIAL" -o ]; then
    bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-
-   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
-fi 
+fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
@@ -539,7 +530,7 @@
 mainmenu_option next_comment
 comment 'Sound support'
 
-tristate 'Sound support' CONFIG_SOUND
+tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
    source drivers/sound/dmasound/Config.in
 fi
@@ -547,7 +538,7 @@
 
 source fs/Config.in
 
-if [ "$CONFIG_VME" = "n" ]; then
+if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
    comment 'Console drivers'
    source drivers/video/Config.in
@@ -565,3 +556,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/config.c linux-2.4.20/arch/m68k/hp300/config.c
--- linux-2.4.19/arch/m68k/hp300/config.c	1999-08-26 19:42:31.000000000 +0000
+++ linux-2.4.20/arch/m68k/hp300/config.c	2002-10-04 00:41:10.000000000 +0000
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <asm/machdep.h>
 #include <asm/blinken.h>
-#include <asm/io.h>                               /* readb() and writeb() */
 #include <asm/hwtest.h>                           /* hwreg_present() */
 
 #include "ints.h"
@@ -29,10 +28,9 @@
 
 #ifdef CONFIG_VT
 extern int hp300_keyb_init(void);
-#else
-/* Dummy function for when there is no keyboard. */
-int __init hp300_keyb_init(void)
+static int hp300_kbdrate(struct kbd_repeat *k)
 {
+  return 0;
 }
 #endif
 
@@ -46,15 +44,6 @@
 }
 #endif
 
-static int hp300_kbdrate(struct kbd_repeat *k)
-{
-  return 0;
-}
-
-static void hp300_kbd_leds(unsigned int leds)
-{
-}
-
 static void hp300_get_model(char *model)
 {
   strcpy(model, "HP9000/300");
@@ -63,9 +52,10 @@
 void __init config_hp300(void)
 {
   mach_sched_init      = hp300_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = hp300_keyb_init;
   mach_kbdrate         = hp300_kbdrate;
-  mach_kbd_leds        = hp300_kbd_leds;
+#endif
   mach_init_IRQ        = hp300_init_IRQ;
   mach_request_irq     = hp300_request_irq;
   mach_free_irq        = hp300_free_irq;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/hil.c linux-2.4.20/arch/m68k/hp300/hil.c
--- linux-2.4.19/arch/m68k/hp300/hil.c	1999-08-26 19:42:31.000000000 +0000
+++ linux-2.4.20/arch/m68k/hp300/hil.c	2002-10-04 00:41:22.000000000 +0000
@@ -25,12 +25,12 @@
 #define	HIL_BUSY		0x02
 #define	HIL_DATA_RDY		0x01
 
-#define hil_busy()		(readb(HILBASE + HIL_CMD) & HIL_BUSY)
-#define hil_data_available()	(readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
-#define hil_status()		(readb(HILBASE + HIL_CMD))
-#define hil_command(x)		do { writeb((x), HILBASE + HIL_CMD); } while (0)
-#define hil_read_data()		(readb(HILBASE + HIL_DATA))
-#define hil_write_data(x)	do { writeb((x), HILBASE + HIL_DATA); } while (0)
+#define hil_busy()		(in_8(HILBASE + HIL_CMD) & HIL_BUSY)
+#define hil_data_available()	(in_8(HILBASE + HIL_CMD) & HIL_DATA_RDY)
+#define hil_status()		(in_8(HILBASE + HIL_CMD))
+#define hil_command(x)		out_8(HILBASE + HIL_CMD, (x))
+#define hil_read_data()		(in_8(HILBASE + HIL_DATA))
+#define hil_write_data(x)	out_8(HILBASE + HIL_DATA, (x))
 
 #define	HIL_SETARD		0xA0		/* set auto-repeat delay */
 #define	HIL_SETARR		0xA2		/* set auto-repeat rate */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/ints.c linux-2.4.20/arch/m68k/hp300/ints.c
--- linux-2.4.19/arch/m68k/hp300/ints.c	1999-09-08 18:59:00.000000000 +0000
+++ linux-2.4.20/arch/m68k/hp300/ints.c	2002-10-04 00:41:12.000000000 +0000
@@ -142,7 +142,9 @@
         }
         /* remove the entry after t: */
         t->next->flags = IRQ_FLG_STD;
-        t->next->dev_id = t->next->devname = t->next->handler = NULL;
+        t->next->dev_id = NULL;
+	t->next->devname = NULL;
+	t->next->handler = NULL;
         t->next = t->next->next;
         
 	spin_unlock_irqrestore(&irqlist_lock, flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/time.c linux-2.4.20/arch/m68k/hp300/time.c
--- linux-2.4.19/arch/m68k/hp300/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/hp300/time.c	2002-10-04 00:41:29.000000000 +0000
@@ -40,7 +40,7 @@
 {
   unsigned long tmp;
   void (*vector)(int, void *, struct pt_regs *) = dev_id;
-  readb(CLOCKBASE + CLKSR);
+  in_8(CLOCKBASE + CLKSR);
   asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
   vector(irq, NULL, regs);
 }
@@ -51,25 +51,25 @@
   unsigned char lsb, msb1, msb2;
   unsigned short ticks;
 
-  msb1 = readb(CLOCKBASE + 5);
-  lsb = readb(CLOCKBASE + 7);
-  msb2 = readb(CLOCKBASE + 5);
+  msb1 = in_8(CLOCKBASE + 5);
+  lsb = in_8(CLOCKBASE + 7);
+  msb2 = in_8(CLOCKBASE + 5);
   if (msb1 != msb2)
     /* A carry happened while we were reading.  Read it again */
-    lsb = readb(CLOCKBASE + 7);
+    lsb = in_8(CLOCKBASE + 7);
   ticks = INTVAL - ((msb2 << 8) | lsb);
   return (USECS_PER_JIFFY * ticks) / INTVAL;
 }
 
 void __init hp300_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x1, CLOCKBASE + CLKCR1);		/* reset */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x1);		/* reset */
 
   asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
 
   sys_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
 
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x40, CLOCKBASE + CLKCR1);		/* enable irq */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x40);		/* enable irq */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/entry.S linux-2.4.20/arch/m68k/kernel/entry.S
--- linux-2.4.19/arch/m68k/kernel/entry.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/kernel/entry.S	2002-10-04 00:41:10.000000000 +0000
@@ -645,6 +645,18 @@
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)	/* 225 */
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/head.S linux-2.4.20/arch/m68k/kernel/head.S
--- linux-2.4.19/arch/m68k/kernel/head.S	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/kernel/head.S	2002-10-04 00:41:20.000000000 +0000
@@ -310,8 +310,11 @@
 .globl SYMBOL_NAME(mvme_bdid)
 #endif
 #ifdef CONFIG_Q40
-.globl SYMBOL_NAME(q40_mem_cptr)	
-#endif		
+.globl SYMBOL_NAME(q40_mem_cptr)
+#endif
+#ifdef CONFIG_HP300
+.globl SYMBOL_NAME(hp300_phys_ram_base)
+#endif
 
 CPUTYPE_040	= 1	/* indicates an 040 */
 CPUTYPE_060	= 2	/* indicates an 060 */
@@ -596,6 +599,64 @@
 __INIT
 ENTRY(__start)
 
+#ifdef CONFIG_HP300
+/* This is a hack.  The HP NetBSD bootloader loads us at an arbitrary
+   address (apparently 0xff002000 in practice) which is not good if we need
+   to be able to map this to VA 0x1000.  We could do it with pagetables but
+   a better solution seems to be to relocate the kernel in physical memory
+   before we start.  
+	
+   So, we copy the entire kernel image (code+data+bss) down to the 16MB
+   boundary that marks the start of RAM.  This is slightly tricky because
+   we must not overwrite the copying code itself. :-)  */
+
+/* 15/5/98.  The start address of physical RAM changes depending on how much
+   RAM is present.  This is actually a blessing in disguise as it provides
+   a way for us to work out the RAM size rather than hardwiring it.  */
+
+	lea	%pc@(_start),%a0
+	movel	%a0,%d6
+	and	#0xffff0000, %d6
+	lea	%pc@(SYMBOL_NAME(hp300_phys_ram_base)),%a0
+	movel	%d6, %a0@
+	movel	%pc@(L(custom)),%a3
+	moveb	#0xfe,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(Lcopystart),%a0
+	lea	%pc@(Lcopyend),%a1
+	movel	%d6,%a2			/* Start of physical RAM */
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	movel	%d6,%a2
+	moveb	#0xfd,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(_stext),%a0
+	lea	%pc@(_end),%a1
+	jmp	%a2@
+
+Lcopystart:
+	moveb	#0xf7,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a2	/* Start of kernel */
+	add	#0x1000,%a2
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	moveb	#0,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a0
+	addl	#Lstart1,%a0
+	jmp	%a0@
+Lcopyend:	
+
+Lstart1:
+	moveb	#0x3f,%d7
+	moveb	%d7,%a3@(0x1ffff)
+#endif /* CONFIG_HP300 */
+
 /*
  * Setup initial stack pointer
  */
@@ -605,6 +666,7 @@
  * Record the CPU and machine type.
  */
 
+#ifndef CONFIG_HP300
 	get_bi_record	BI_MACHTYPE
 	lea	%pc@(SYMBOL_NAME(m68k_machtype)),%a1
 	movel	%a0@,%a1@
@@ -620,6 +682,23 @@
 	get_bi_record	BI_CPUTYPE
 	lea	%pc@(SYMBOL_NAME(m68k_cputype)),%a1
 	movel	%a0@,%a1@
+#else /* CONFIG_HP300 */
+	/* FIXME HP300 doesn't use bootinfo yet */
+	movel	#MACH_HP300,%d4
+	lea	%pc@(SYMBOL_NAME(m68k_machtype)),%a0
+	movel	%d4,%a0@
+	movel	#FPU_68881,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_fputype)),%a0
+	movel	%d0,%a0@
+	movel	#MMU_68030,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_mmutype)),%a0
+	movel	%d0,%a0@
+	movel	#CPU_68030,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_cputype)),%a0
+	movel	%d0,%a0@
+
+	leds(0x1)
+#endif /* CONFIG_HP300 */
 
 #ifdef CONFIG_MAC
 /*
@@ -893,6 +972,9 @@
 
 	putc	'\n'
 	putc	'A'
+#ifdef CONFIG_HP300
+	leds(0x2)
+#endif /* CONFIG_HP300 */
 	dputn	%pc@(L(cputype))
 	dputn	%pc@(SYMBOL_NAME(m68k_supervisor_cachemode))
 	dputn	%pc@(SYMBOL_NAME(m68k_pgtable_cachemode))
@@ -1490,6 +1572,7 @@
 
 	movel	ARG1,%d0
 	lea	%pc@(SYMBOL_NAME(_end)),%a0
+#ifndef CONFIG_HP300
 1:	tstw	%a0@(BIR_TAG)
 	jeq	3f
 	cmpw	%a0@(BIR_TAG),%d0
@@ -1503,6 +1586,7 @@
 3:	moveq	#-1,%d0
 	lea	%a0@(BIR_SIZE),%a0
 4:
+#endif /* CONFIG_HP300 */
 func_return	get_bi_record
 
 
@@ -3286,14 +3370,16 @@
 
 	/* Calculate font size */
 
-#if   defined(FONT_8x8)
+#if   defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
 	lea	%pc@(SYMBOL_NAME(font_vga_8x8)), %a0
-#elif defined(FONT_8x16)
+#elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
 	lea	%pc@(SYMBOL_NAME(font_vga_8x16)),%a0
-#elif defined(FONT_6x11)
+#elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
 	lea	%pc@(SYMBOL_NAME(font_vga_6x11)),%a0
-#else	/*   (FONT_8x8) default */
+#elif defined(CONFIG_FONT_8x8) /* default *
 	lea	%pc@(SYMBOL_NAME(font_vga_8x8)), %a0
+#else /* no compiled-in font */
+	lea	0,%a0
 #endif
 
 	/*
@@ -3302,6 +3388,8 @@
 	 */
 	lea	%pc@(L(console_font)),%a1
 	movel	%a0,%a1@	/* store pointer to struct fbcon_font_desc in Lconsole_font */
+	tstl	%a0
+	jeq	1f
 
 	/*
 	 *	Calculate global maxs
@@ -3329,7 +3417,7 @@
 	/*
 	 * Initialization is complete
 	 */
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 L(console_put_stats):
@@ -3415,6 +3503,8 @@
 	lea	%pc@(L(mac_rowbytes)),%a0
 	movel	%a0@,%d5
 	movel	%pc@(L(console_font)),%a0
+	tstl	%a0
+	jeq	1f
 	mulul	%a0@(FBCON_FONT_DESC_HEIGHT),%d5	/* account for # scan lines per character */
 	addal	%d5,%a2
 
@@ -3469,13 +3559,15 @@
 	movel	%d0,%a1@+
 	dbra	%d6,console_scroll_clear_loop
 
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 
 func_start	console_putc,%a0/%a1/%d0-%d7
 
 	is_not_mac(console_exit)
+	tstl	%pc@(L(console_font))
+	jeq	console_exit
 
 	/* Output character in d7 on console.
 	 */
@@ -3747,7 +3839,12 @@
 __INITDATA
 	.align	4
 
-#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || defined(CONFIG_HP300)
+#ifdef CONFIG_HP300
+SYMBOL_NAME_LABEL(hp300_phys_ram_base)
+#endif
+
+#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
+    defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
 L(custom):
 L(iobase):
 	.long 0
@@ -3838,8 +3935,6 @@
 LSRB0        = 0x10412
 LTHRB0       = 0x10416
 LCPUCTRL     = 0x10100
-L(iobase):
-        .long 0
 #endif
 
 __FINIT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/setup.c linux-2.4.20/arch/m68k/kernel/setup.c
--- linux-2.4.19/arch/m68k/kernel/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/kernel/setup.c	2002-10-04 00:41:30.000000000 +0000
@@ -34,6 +34,7 @@
 #endif
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
+#include <asm/atari_stram.h>
 #endif
 #ifdef CONFIG_SUN3X
 #include <asm/dvma.h>
@@ -71,11 +72,12 @@
 
 void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
 /* machine dependent keyboard functions */
+#ifdef CONFIG_VT
 int (*mach_keyb_init) (void) __initdata = NULL;
 int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
 void (*mach_kbd_leds) (unsigned int) = NULL;
 int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode) = NULL;
-unsigned int SYSRQ_KEY;
+#endif
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
@@ -104,6 +106,7 @@
 #endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
+unsigned int SYSRQ_KEY;
 int mach_sysrq_key = -1;
 int mach_sysrq_shift_state = 0;
 int mach_sysrq_shift_mask = 0;
@@ -218,8 +221,20 @@
 	int i;
 	char *p, *q;
 
-	/* The bootinfo is located right after the kernel bss */
-	m68k_parse_bootinfo((const struct bi_record *)&_end);
+	if (!MACH_IS_HP300) {
+		/* The bootinfo is located right after the kernel bss */
+		m68k_parse_bootinfo((const struct bi_record *)&_end);
+	} else {
+		/* FIXME HP300 doesn't use bootinfo yet */
+		extern unsigned long hp300_phys_ram_base;
+		unsigned long hp300_mem_size = 0xffffffff-hp300_phys_ram_base;
+		m68k_cputype = CPU_68030;
+		m68k_fputype = FPU_68882;
+		m68k_memory[0].addr = hp300_phys_ram_base;
+		/* 0.5M fudge factor */
+		m68k_memory[0].size = hp300_mem_size-512*1024;
+		m68k_num_memory++;
+	}
 
 	if (CPU_IS_040)
 		m68k_is040or060 = 4;
@@ -372,7 +387,7 @@
 
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI)
-		atari_stram_reserve_pages(availmem);
+		atari_stram_reserve_pages((void *)availmem);
 #endif
 #ifdef CONFIG_SUN3X
 	if (MACH_IS_SUN3X) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/traps.c linux-2.4.20/arch/m68k/kernel/traps.c
--- linux-2.4.19/arch/m68k/kernel/traps.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/kernel/traps.c	2002-10-04 00:41:20.000000000 +0000
@@ -816,8 +816,9 @@
 
 static inline int kernel_text_address(unsigned long addr)
 {
+#ifdef CONFIG_MODULES
 	struct module *mod;
-	int retval = 0;
+#endif
 	extern char _stext, _etext;
 
 	if (addr >= (unsigned long) &_stext &&
@@ -829,14 +830,12 @@
 		/* mod_bound tests for addr being inside the vmalloc'ed
 		 * module area. Of course it'd be better to test only
 		 * for the .text subset... */
-		if (mod_bound(addr, 0, mod)) {
-			retval = 1;
-			break;
-		}
+		if (mod_bound(addr, 0, mod))
+			return 1;
 	}
 #endif
 
-	return retval;
+	return 0;
 }
 
 void show_trace(unsigned long *stack)
@@ -874,11 +873,14 @@
 	show_trace((unsigned long *)tsk->thread.esp0);
 }
 
-static void dump_stack(struct frame *fp)
+static void show_stack(struct frame *fp)
 {
 	unsigned long *stack, *endstack, addr;
 	int i;
 
+	if (fp == NULL)
+	    fp = (struct frame *)&fp;
+
 	addr = (unsigned long)&fp->un;
 	printk("Frame format=%X ", fp->ptregs.format);
 	switch (fp->ptregs.format) {
@@ -952,6 +954,14 @@
 	printk ("\n");
 }
 
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
 void bad_super_trap (struct frame *fp)
 {
 	console_verbose();
@@ -1122,7 +1132,7 @@
 
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
-	dump_stack((struct frame *)fp);
+	show_stack((struct frame *)fp);
 	do_exit(SIGSEGV);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/config.c linux-2.4.20/arch/m68k/mac/config.c
--- linux-2.4.19/arch/m68k/mac/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mac/config.c	2002-10-04 00:41:17.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 /* keyb */
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 
 #define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
@@ -47,6 +48,8 @@
 struct mac_booter_data mac_bi_data = {0,};
 int mac_bisize = sizeof mac_bi_data;
 
+struct mac_hw_present mac_hw_present;
+
 /* New m68k bootinfo stuff and videobase */
 
 extern int m68k_num_memory;
@@ -76,7 +79,6 @@
 extern void psc_init(void);
 extern void baboon_init(void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void mac_mksound(unsigned int, unsigned int);
 
 extern void nubus_sweep_video(void);
@@ -85,8 +87,6 @@
 extern void mac_debug_init(void);
 extern void mac_debugging_long(int, long);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 extern int mackbd_init_hw(void);
 extern void mackbd_leds(unsigned int leds);
 extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
@@ -207,7 +207,7 @@
 	if (!MACH_IS_MAC) {
 	  printk("ERROR: no Mac, but config_mac() called!! \n");
 	}
-	
+
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT_ADBHID
 	mach_keyb_init       = mac_hid_init_hw;
@@ -228,9 +228,12 @@
 	mach_keyb_init       = mackbd_init_hw;
 	mach_kbd_leds        = mackbd_leds;
 	mach_kbd_translate   = mackbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
 	mach_sysrq_xlate     = mackbd_sysrq_xlate;
 	SYSRQ_KEY = 0x69;
+#endif /* CONFIG_MAGIC_SYSRQ */
 #endif /* CONFIG_INPUT_ADBHID */
+	kd_mksound		 = mac_mksound;
 #endif /* CONFIG_VT */
 
 	mach_sched_init      = mac_sched_init;
@@ -252,12 +255,13 @@
 	mach_reset           = mac_reset;
 	mach_halt            = mac_poweroff;
 	mach_power_off       = mac_poweroff;
+#ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp	         = &dummy_con;
+#endif
 	mach_max_dma_address = 0xffffffff;
 #if 0
 	mach_debug_init	 = mac_debug_init;
 #endif
-	kd_mksound		 = mac_mksound;
 #ifdef CONFIG_HEARTBEAT
 #if 0
 	mach_heartbeat = mac_heartbeat;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/debug.c linux-2.4.20/arch/m68k/mac/debug.c
--- linux-2.4.19/arch/m68k/mac/debug.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mac/debug.c	2002-10-04 00:41:30.000000000 +0000
@@ -36,7 +36,7 @@
 extern unsigned long mac_videodepth;
 extern unsigned long mac_rowbytes;
 
-extern void mac_serial_print(char *);
+extern void mac_serial_print(const char *);
 
 #define DEBUG_HEADS
 #undef DEBUG_SCREEN
@@ -137,7 +137,7 @@
  * TODO: serial debug code
  */
 
-struct SCC
+struct mac_SCC
  {
   u_char cha_b_ctrl;
   u_char char_dummy1;
@@ -148,7 +148,7 @@
   u_char cha_a_data;
  };
 
-# define scc (*((volatile struct SCC*)mac_bi_data.sccbase))
+# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
 
 /* Flag that serial port is already initialized and used */
 int mac_SCC_init_done = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/macints.c linux-2.4.20/arch/m68k/mac/macints.c
--- linux-2.4.19/arch/m68k/mac/macints.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/mac/macints.c	2002-10-04 00:41:14.000000000 +0000
@@ -249,7 +249,7 @@
 #endif /* SHUTUP_SONIC */
 
 	/* 
-	 * Now register the handlers for the the master IRQ handlers
+	 * Now register the handlers for the master IRQ handlers
 	 * at levels 1-7. Most of the work is done elsewhere.
 	 */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/misc.c linux-2.4.20/arch/m68k/mac/misc.c
--- linux-2.4.19/arch/m68k/mac/misc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mac/misc.c	2002-10-04 00:41:20.000000000 +0000
@@ -229,8 +229,8 @@
 	do {
 		if (++ct > 10) {
 			printk("via_read_time: couldn't get valid time, "
-			       "last read = 0x%08X and 0x%08X\n", last_result.idata,
-			       result.idata);
+			       "last read = 0x%08lx and 0x%08lx\n",
+			       last_result.idata, result.idata);
 			break;
 		}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mm/fault.c linux-2.4.20/arch/m68k/mm/fault.c
--- linux-2.4.19/arch/m68k/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mm/fault.c	2002-10-04 00:41:18.000000000 +0000
@@ -179,14 +179,12 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
-	
+
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mvme147/config.c linux-2.4.20/arch/m68k/mvme147/config.c
--- linux-2.4.19/arch/m68k/mvme147/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mvme147/config.c	2002-10-04 00:41:14.000000000 +0000
@@ -103,8 +103,10 @@
 {
 	mach_max_dma_address	= 0x01000000;
 	mach_sched_init		= mvme147_sched_init;
+#ifdef CONFIG_VT
 	mach_keyb_init		= mvme147_keyb_init;
 	mach_kbdrate		= mvme147_kbdrate;
+#endif
 	mach_init_IRQ		= mvme147_init_IRQ;
 	mach_gettimeoffset	= mvme147_gettimeoffset;
 	mach_gettod		= mvme147_gettod;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mvme16x/config.c linux-2.4.20/arch/m68k/mvme16x/config.c
--- linux-2.4.19/arch/m68k/mvme16x/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/mvme16x/config.c	2002-10-04 00:41:15.000000000 +0000
@@ -145,14 +145,16 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = mvme16x_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = mvme16x_keyb_init;
     mach_kbdrate         = mvme16x_kbdrate;
+/*  kd_mksound           = mvme16x_mksound; */
+#endif
     mach_init_IRQ        = mvme16x_init_IRQ;
     mach_gettimeoffset   = mvme16x_gettimeoffset;
     mach_gettod  	 = mvme16x_gettod;
     mach_hwclk           = mvme16x_hwclk;
     mach_set_clock_mmss	 = mvme16x_set_clock_mmss;
-/*  kd_mksound           = mvme16x_mksound; */
     mach_reset		 = mvme16x_reset;
     mach_free_irq	 = mvme16x_free_irq;
     mach_process_int	 = mvme16x_process_int;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/q40/config.c linux-2.4.20/arch/m68k/q40/config.c
--- linux-2.4.19/arch/m68k/q40/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/q40/config.c	2002-10-04 00:41:20.000000000 +0000
@@ -23,6 +23,7 @@
 #include <linux/major.h>
 #include <linux/serial_reg.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -63,7 +64,6 @@
 extern void q40_waitbut(void);
 void q40_set_vectors (void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
 
 extern char *saved_command_line;
@@ -164,42 +164,6 @@
     sprintf(model, "Q40");
 }
 
-/* pasted code to make parport_pc happy */
-extern __inline__ int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-void *pci_alloc_consistent(void *hwdev, size_t size,
-			   dma_addr_t *dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC;
-
-	ret = (void *)__get_free_pages(gfp, __get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_bus(ret);
-	}
-	return ret;
-}
-
-void pci_free_consistent(void *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, __get_order(size));
-}
-/* end pasted code */
-
-
 /* No hardware options on Q40? */
 
 static int q40_get_hardware_list(char *buffer)
@@ -223,8 +187,11 @@
 {
     mach_sched_init      = q40_sched_init;
 
+#ifdef CONFIG_VT
     mach_keyb_init       = q40kbd_init_hw;
     mach_kbd_translate   = q40kbd_translate;
+    kd_mksound             = q40_mksound;
+#endif
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_gettod  	 = q40_gettod;
@@ -241,7 +208,6 @@
     mach_default_handler = &q40_sys_default_handler;
     mach_get_model       = q40_get_model;
     mach_get_hardware_list = q40_get_hardware_list;
-    kd_mksound             = q40_mksound;
 
 #ifdef CONFIG_MAGIC_SYSRQ
     mach_sysrq_key       = 0x54;
@@ -250,7 +216,9 @@
     mach_heartbeat = q40_heartbeat;
 #endif
     mach_halt = q40_halt;
+#ifdef CONFIG_DUMMY_CONSOLE
     conswitchp = &dummy_con;
+#endif
 
     /* disable a few things that SMSQ might have left enabled */
     q40_disable_irqs();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/config.c linux-2.4.20/arch/m68k/sun3/config.c
--- linux-2.4.19/arch/m68k/sun3/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3/config.c	2002-10-04 00:41:22.000000000 +0000
@@ -141,7 +141,9 @@
         mach_default_handler = &sun3_default_handler;
         mach_request_irq     =  sun3_request_irq;
         mach_free_irq        =  sun3_free_irq;
+#ifdef CONFIG_VT
 //	mach_keyb_init       =  sun3_keyb_init;
+#endif
 	enable_irq     	     =  sun3_enable_irq;
         disable_irq  	     =  sun3_disable_irq;
 	mach_process_int     =  sun3_process_int;
@@ -152,7 +154,7 @@
 	mach_get_model	     =  sun3_get_model;
 	mach_hwclk           =  sun3_hwclk;
 	mach_halt	     =  sun3_halt;
-#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_FB)
+#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp 	     = &dummy_con;
 #endif
 
@@ -165,9 +167,9 @@
 	
 	sun3_bootmem_alloc(memory_start, memory_end);
 
+#ifdef CONFIG_SUN3X_ZS
 	sun_serial_setup();
-
-
+#endif
 }
 
 void __init sun3_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/mmu_emu.c linux-2.4.20/arch/m68k/sun3/mmu_emu.c
--- linux-2.4.19/arch/m68k/sun3/mmu_emu.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3/mmu_emu.c	2002-10-04 00:41:11.000000000 +0000
@@ -52,7 +52,9 @@
 
 /* pointers to the mm structs for each task in each
    context. 0xffffffff is a marker for kernel context */
-struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {0xffffffff, 0, 0, 0, 0, 0, 0, 0};
+struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {
+	(struct mm_struct *)0xffffffff, 0, 0, 0, 0, 0, 0, 0
+};
 /* has this context been mmdrop'd? */
 static unsigned char ctx_avail = CONTEXTS_NUM-1;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/sbus.c linux-2.4.20/arch/m68k/sun3/sbus.c
--- linux-2.4.19/arch/m68k/sun3/sbus.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3/sbus.c	2002-10-04 00:41:09.000000000 +0000
@@ -16,9 +16,9 @@
 
 void __init sbus_init(void)
 {
-
+#ifdef CONFIG_SUN3X_ZS
 	rs_init();
-
+#endif
 }
 
 void *sparc_alloc_io (u32 address, void *virtual, int len, char *name,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/sun3ints.c linux-2.4.20/arch/m68k/sun3/sun3ints.c
--- linux-2.4.19/arch/m68k/sun3/sun3ints.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3/sun3ints.c	2002-10-04 00:41:20.000000000 +0000
@@ -99,7 +99,7 @@
 };
 static void (*sun3_vechandler[192])(int, void *, struct pt_regs *);
 static void *vec_ids[192];
-static char *vec_names[192];
+static const char *vec_names[192];
 
 static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
 {
@@ -122,8 +122,8 @@
 	sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
 };
 
-static char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL, 
-				     NULL, "timer", NULL, NULL };
+static const char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL,
+					   NULL, "timer", NULL, NULL };
 
 void sun3_init_IRQ(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/config.c linux-2.4.20/arch/m68k/sun3x/config.c
--- linux-2.4.19/arch/m68k/sun3x/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3x/config.c	2002-10-04 00:41:10.000000000 +0000
@@ -61,9 +61,11 @@
 	mach_get_irq_list	 = sun3_get_irq_list;
 	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
 
+#ifdef CONFIG_VT
 	mach_keyb_init       = sun3x_keyb_init;
 	mach_kbdrate         = sun3x_kbdrate;
 	mach_kbd_leds        = sun3x_kbd_leds;
+#endif
 
 	mach_default_handler = &sun3_default_handler;
 	mach_sched_init      = sun3x_sched_init;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/prom.c linux-2.4.20/arch/m68k/sun3x/prom.c
--- linux-2.4.19/arch/m68k/sun3x/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3x/prom.c	2002-10-04 00:41:18.000000000 +0000
@@ -124,7 +124,8 @@
     idprom = &idprom_buffer;
 
     if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3X) {
-	    printk("Warning: machine reports strange type %02x\n");
+	    printk("Warning: machine reports strange type %02x\n",
+		   idprom->id_machtype);
 	    printk("Pretending it's a 3/80, but very afraid...\n");
 	    idprom->id_machtype = SM_SUN3X | SM_3_80;
     }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/time.c linux-2.4.20/arch/m68k/sun3x/time.c
--- linux-2.4.19/arch/m68k/sun3x/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/m68k/sun3x/time.c	2002-10-04 00:41:21.000000000 +0000
@@ -62,8 +62,8 @@
 
 int sun3x_hwclk(int set, struct rtc_time *t)
 {
-	volatile struct mostek_dt *h = 
-		(unsigned char *)(SUN3X_EEPROM+M_CONTROL);
+	volatile struct mostek_dt *h =
+		(struct mostek_dt *)(SUN3X_EEPROM+M_CONTROL);
 	unsigned long flags;
 
 	save_and_cli(flags);
@@ -100,6 +100,7 @@
     return 0L;
 }
 
+#if 0
 static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
 {
     void (*vector)(int, void *, struct pt_regs *) = dev_id;
@@ -110,6 +111,7 @@
     
     vector(irq, NULL, regs);
 }
+#endif
 
 void __init sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/Makefile linux-2.4.20/arch/mips/Makefile
--- linux-2.4.19/arch/mips/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -27,7 +27,7 @@
 endif
 
 #
-# GCC uses -G0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
 # code since it only slows down the whole thing.  At some point we might make
 # use of global pointer optimizations but their use of $28 conflicts with
 # the current pointer optimization.
@@ -141,7 +141,17 @@
 endif
 
 #
-# Au1000 (Alchemy Semi PB1500) eval board
+# Au1100 (Alchemy Semi PB1100) eval board
+#
+ifdef CONFIG_MIPS_PB1100
+LIBS          += arch/mips/au1000/pb1100/pb1100.o \
+                 arch/mips/au1000/common/au1000.o
+SUBDIRS       += arch/mips/au1000/pb1100 arch/mips/au1000/common
+LOADADDR      += 0x80100000
+endif
+
+#
+# Au1500 (Alchemy Semi PB1500) eval board
 #
 ifdef CONFIG_MIPS_PB1500
 LIBS		+= arch/mips/au1000/pb1500/pb1500.o \
@@ -257,6 +267,16 @@
 endif
 
 #
+# MIPS SEAD board
+#
+ifdef CONFIG_MIPS_SEAD
+LIBS		+= arch/mips/mips-boards/sead/sead.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/sead
+LOADADDR	:= 0x80100000
+endif
+
+#
 # Momentum Ocelot board
 #
 ifdef CONFIG_MOMENCO_OCELOT
@@ -269,11 +289,22 @@
 endif
 
 #
+# Momentum Ocelot-G board
+#
+ifdef CONFIG_MOMENCO_OCELOT_G
+# The Ocelot-G setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+CORE_FILES	+= arch/mips/momentum/ocelot_g/ocelot_g.o
+SUBDIRS		+= arch/mips/momentum/ocelot_g
+LOADADDR	:= 0x80100000
+endif
+
+#
 # NEC DDB Vrc-5074
 #
 ifdef CONFIG_DDB5074
-SUBDIRS		+= arch/mips/ddb5074
-LIBS		+= arch/mips/ddb5074/ddb5074.a
+SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5074
+LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o arch/mips/ddb5xxx/ddb5074/ddb5074.o
 LOADADDR	:= 0x80080000
 endif
 
@@ -294,7 +325,7 @@
 SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
 LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o \
 		   arch/mips/ddb5xxx/ddb5477/ddb5477.o
-LOADADDR	:= 0x80080000
+LOADADDR	:= 0x80100000
 endif
 
 #
@@ -308,6 +339,28 @@
 endif
 
 #
+# NEC Eagle/Hawk (VR4122/VR4131) board
+#
+ifdef CONFIG_NEC_EAGLE
+SUBDIRS		+= arch/mips/vr41xx/common \
+		   arch/mips/vr41xx/nec-eagle
+LIBS		+= arch/mips/vr41xx/common/vr41xx.o \
+		   arch/mips/vr41xx/nec-eagle/eagle.o
+LOADADDR	:= 0x80000000
+endif
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+ifdef CONFIG_ZAO_CAPCELLA
+SUBDIRS		+= arch/mips/vr41xx/common \
+		   arch/mips/vr41xx/zao-capcella
+LIBS		+= arch/mips/vr41xx/common/vr41xx.o \
+		   arch/mips/vr41xx/zao-capcella/capcella.o
+LOADADDR	:= 0x80000000
+endif
+
+#
 # Philips Nino
 #
 ifdef CONFIG_NINO
@@ -352,6 +405,14 @@
 endif
 
 #
+# Sibyte CFE firmware
+#
+ifdef CONFIG_SIBYTE_CFE
+LIBS		+= arch/mips/sibyte/cfe/cfe.a
+SUBDIRS		+= arch/mips/sibyte/cfe
+endif
+
+#
 # SB1 Cache Error handler
 #
 ifdef CONFIG_SB1_CACHE_ERROR
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/Makefile linux-2.4.20/arch/mips/arc/Makefile
--- linux-2.4.19/arch/mips/arc/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -1,18 +1,13 @@
 #
-# Makefile for the SGI arcs prom monitor library routines
-# under Linux.
+# Makefile for the ARC prom monitor library routines under Linux.
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
 
 L_TARGET = arclib.a
 
-obj-y		+= console.o init.o memory.o tree.o env.o cmdline.o misc.o \
-		   time.o file.o identify.o
+obj-y				+= cmdline.o console.o env.o file.o \
+				   identify.o init.o misc.o time.o tree.o
 
-obj-$(CONFIG_ARC_CONSOLE)   += arc_con.o
+obj-$(CONFIG_ARC_MEMORY)	+= memory.o
+obj-$(CONFIG_ARC_CONSOLE)	+= arc_con.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/arc_con.c linux-2.4.20/arch/mips/arc/arc_con.c
--- linux-2.4.19/arch/mips/arc/arc_con.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/arc_con.c	2002-10-04 00:41:20.000000000 +0000
@@ -2,61 +2,49 @@
  * Wrap-around code for a console using the
  * ARC io-routines.
  *
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 2001 Ralf Baechle
+ * Copyright (c) 2002 Thiemo Seufer
  */
-
 #include <linux/tty.h>
 #include <linux/major.h>
 #include <linux/ptrace.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/fs.h>
-
-extern char prom_getchar (void);
-extern void prom_printf (char *, ...);
+#include <asm/sgialib.h>
 
 static void prom_console_write(struct console *co, const char *s,
 			       unsigned count)
 {
-	unsigned i;
-
-	/*
-	 *    Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		if (*s == 10)
-			prom_printf("%c", 13);
-		prom_printf("%c", *s++);
+	/* Do each character */
+	while (count--) {
+		if (*s == '\n')
+			prom_putchar('\r');
+		prom_putchar(*s++);
 	}
 }
 
-static int prom_console_wait_key(struct console *co)
+static kdev_t prom_console_device(struct console *co)
 {
-	return prom_getchar();
+	return MKDEV(TTY_MAJOR, 64 + co->index);
 }
 
 static int __init prom_console_setup(struct console *co, char *options)
 {
-	return 0;
-}
-
-static kdev_t prom_console_device(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
+	if (prom_flags & PROM_FLAG_USE_AS_CONSOLE)
+		return 0;
+	else
+		return 1;
 }
 
 static struct console arc_cons = {
-	"ttyS",
-	prom_console_write,
-	NULL,
-	prom_console_device,
-	prom_console_wait_key,
-	NULL,
-	prom_console_setup,
-	CON_PRINTBUFFER,
-	-1,
-	0,
-	NULL
+	name:		"ttyS",
+	write:		prom_console_write,
+	device:		prom_console_device,
+	setup:		prom_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/cmdline.c linux-2.4.20/arch/mips/arc/cmdline.c
--- linux-2.4.19/arch/mips/arc/cmdline.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/cmdline.c	2002-10-04 00:41:30.000000000 +0000
@@ -1,4 +1,8 @@
 /*
+ * 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.
+ *
  * cmdline.c: Kernel command line creation using ARCS argc/argv.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -46,13 +50,13 @@
 		for(i = 0; i < NENTS(used_arc); i++) {
 			int len = strlen(used_arc[i][0]);
 
-			if(!strncmp(prom_argv[actr], used_arc[i][0], len)) {
+			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
 			/* Ok, we want it. First append the replacement... */
 				strcat(cp, used_arc[i][1]);
 				cp += strlen(used_arc[i][1]);
 				/* ... and now the argument */
-				s = strstr(prom_argv[actr], "=");
-				if(s) {
+				s = strstr(prom_argv(actr), "=");
+				if (s) {
 					s++;
 					strcpy(cp, s);
 					cp += strlen(s);
@@ -76,7 +80,7 @@
 	actr = 1; /* Always ignore argv[0] */
 
 	cp = &(arcs_cmdline[0]);
-	/* 
+	/*
 	 * Move ARC variables to the beginning to make sure they can be
 	 * overridden by later arguments.
 	 */
@@ -86,12 +90,12 @@
 		for (i = 0; i < NENTS(ignored); i++) {
 			int len = strlen(ignored[i]);
 
-			if(!strncmp(prom_argv[actr], ignored[i], len))
+			if (!strncmp(prom_argv(actr), ignored[i], len))
 				goto pic_cont;
 		}
 		/* Ok, we want it. */
-		strcpy(cp, prom_argv[actr]);
-		cp += strlen(prom_argv[actr]);
+		strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
 		*cp++ = ' ';
 
 	pic_cont:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/console.c linux-2.4.20/arch/mips/arc/console.c
--- linux-2.4.19/arch/mips/arc/console.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/console.c	2002-10-04 00:41:20.000000000 +0000
@@ -6,13 +6,9 @@
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  * Compability with board caches, Ulf Carlsson
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <asm/sgialib.h>
 #include <asm/bcache.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
 
 /*
  * IP22 boardcache is not compatible with board caches.  Thus we disable it
@@ -26,18 +22,18 @@
 
 void prom_putchar(char c)
 {
-	long cnt;
-	char it = c;
+	ULONG cnt;
+	CHAR it = c;
 
 	bc_disable();
 	ArcWrite(1, &it, 1, &cnt);
 	bc_enable();
 }
 
-char __init prom_getchar(void)
+char prom_getchar(void)
 {
-	long cnt;
-	char c;
+	ULONG cnt;
+	CHAR c;
 
 	bc_disable();
 	ArcRead(0, &c, 1, &cnt);
@@ -46,24 +42,22 @@
 	return c;
 }
 
-static char ppbuf[1024];
-
 void prom_printf(char *fmt, ...)
 {
 	va_list args;
-	char ch, *bptr;
-	int i;
+	char ppbuf[1024];
+	char *bptr;
 
 	va_start(args, fmt);
-	i = vsprintf(ppbuf, fmt, args);
+	vsprintf(ppbuf, fmt, args);
 
 	bptr = ppbuf;
 
-	while ((ch = *(bptr++)) != 0) {
-		if (ch == '\n')
+	while (*bptr != 0) {
+		if (*bptr == '\n')
 			prom_putchar('\r');
 
-		prom_putchar(ch);
+		prom_putchar(*bptr++);
 	}
 	va_end(args);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/identify.c linux-2.4.20/arch/mips/arc/identify.c
--- linux-2.4.19/arch/mips/arc/identify.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/identify.c	2002-10-04 00:41:13.000000000 +0000
@@ -1,10 +1,14 @@
 /*
+ * 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.
+ *
  * identify.c: identify machine by looking up system identifier
  *
  * Copyright (C) 1998 Thomas Bogendoerfer
- * 
+ *
  * This code is based on arch/mips/sgi/kernel/system.c, which is
- * 
+ *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/config.h>
@@ -13,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/string.h>
 
-#include <asm/sgi/sgi.h>
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
@@ -31,6 +34,21 @@
 		MACH_GROUP_SGI,
 		MACH_SGI_INDY,
 		PROM_FLAG_ARCS
+	}, {	"SGI-IP27",
+		"SGI Origin",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP27,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP28",
+		"SGI IP28",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP28,
+		PROM_FLAG_ARCS
+	}, {	"SGI-IP32",
+		"SGI IP32",
+		MACH_GROUP_SGI,
+		MACH_SGI_IP32,
+		PROM_FLAG_ARCS
 	}, {	"Microsoft-Jazz",
 		"Jazz MIPS_Magnum_4000",
 		MACH_GROUP_JAZZ,
@@ -51,7 +69,7 @@
 
 int prom_flags;
 
-static struct smatch *__init string_to_mach(const char *s)
+static struct smatch * __init string_to_mach(const char *s)
 {
 	int i;
 
@@ -77,15 +95,16 @@
 	const char *iname;
 
 	/*
-	 * The root component tells us what machine architecture we
-	 * have here.
+	 * The root component tells us what machine architecture we have here.
 	 */
 	p = ArcGetChild(PROM_NULL_COMPONENT);
 	if (p == NULL) {
 #ifdef CONFIG_SGI_IP27
-	/* IP27 PROM bisbehaves, seems to not implement ARC
-	   GetChild().  So we just assume it's an IP27.  */
+		/* IP27 PROM misbehaves, seems to not implement ARC
+		   GetChild().  So we just assume it's an IP27.  */
 		iname = "SGI-IP27";
+#else
+		iname = "Unknown";
 #endif
 	} else
 		iname = (char *) (long) p->iname;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/init.c linux-2.4.20/arch/mips/arc/init.c
--- linux-2.4.19/arch/mips/arc/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/init.c	2002-10-04 00:41:18.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * This file is subject to the terms and conditions of the GNU General Public+ 
+ * 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.
  *
@@ -17,20 +17,15 @@
 /* Master romvec interface. */
 struct linux_romvec *romvec;
 int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void prom_testtree(void);
+LONG *_prom_argv, *_prom_envp;
 
 void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
-	PSYSTEM_PARAMETER_BLOCK pb;
-	unsigned short prom_vers, prom_rev;
-
+	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
 	romvec = ROMVECTOR;
-	pb = PROMBLOCK;
 	prom_argc = argc;
-	prom_argv = argv;
-	prom_envp = envp;
+	_prom_argv = (LONG *) argv;
+	_prom_envp = (LONG *) envp;
 
 	if (pb->magic != 0x53435241) {
 		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
@@ -39,19 +34,14 @@
 	}
 
 	prom_init_cmdline();
-
-	prom_vers = pb->ver;
-	prom_rev = pb->rev;
 	prom_identify_arch();
-	printk("PROMLIB: ARC firmware Version %d Revision %d\n",
-		    prom_vers, prom_rev);
+	printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
+	       pb->ver, pb->rev);
 	prom_meminit();
 
 #ifdef DEBUG_PROM_INIT
-	{
-		prom_printf("Press a key to reboot\n");
-		(void) prom_getchar();
-		romvec->imode();
-	}
+	prom_printf("Press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
 #endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/memory.c linux-2.4.20/arch/mips/arc/memory.c
--- linux-2.4.19/arch/mips/arc/memory.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/memory.c	2002-10-04 00:41:11.000000000 +0000
@@ -2,7 +2,14 @@
  * memory.c: PROM library functions for acquiring/using memory descriptors
  *           given to us from the ARCS firmware.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 by David S. Miller
+ * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -19,8 +26,7 @@
 
 #undef DEBUG
 
-struct linux_mdesc * __init
-ArcGetMemoryDescriptor(struct linux_mdesc *Current)
+struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
 {
 	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
 }
@@ -47,7 +53,8 @@
 	"FirmwarePermanent",
 	"FreeContiguous"
 };
-#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
+						: arc_mtypes[a.arc]
 #endif
 
 static inline int memtype_classify_arcs (union linux_memtypes type)
@@ -92,7 +99,7 @@
 
 static int __init prom_memtype_classify (union linux_memtypes type)
 {
-	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ...  */
+	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
 		return memtype_classify_arcs(type);
 
 	return memtype_classify_arc(type);
@@ -128,8 +135,7 @@
 	}
 }
 
-void __init
-prom_free_prom_memory (void)
+void __init prom_free_prom_memory (void)
 {
 	unsigned long freed = 0;
 	unsigned long addr;
@@ -149,5 +155,5 @@
 			freed += PAGE_SIZE;
 		}
 	}
-	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/salone.c linux-2.4.20/arch/mips/arc/salone.c
--- linux-2.4.19/arch/mips/arc/salone.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/arc/salone.c	2002-10-04 00:41:30.000000000 +0000
@@ -1,23 +1,24 @@
 /*
- * salone.c: Routines to load into memory and execute stand-along
- *           program images using ARCS PROM firmware.
+ * Routines to load into memory and execute stand-along program images using
+ * ARCS PROM firmware.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
 
-long __init prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr)
+LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
 {
-	return romvec->load(name, end, pc, eaddr);
+	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
 }
 
-long __init prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp)
+LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
+	CHAR *Envp[])
 {
-	return romvec->invoke(pc, sp, argc, argv, envp);
+	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
 }
 
-long __init prom_exec(char *name, long argc, char **argv, char **envp)
+LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
 {
-	return romvec->exec(name, argc, argv, envp);
+	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/Makefile linux-2.4.20/arch/mips/au1000/common/Makefile
--- linux-2.4.19/arch/mips/au1000/common/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/Makefile	2002-10-04 00:41:30.000000000 +0000
@@ -10,22 +10,20 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 all: au1000.o
 
 O_TARGET := au1000.o
 
-export-objs		= prom.o serial.o clocks.o
+export-objs		= prom.o serial.o clocks.o power.o usbdev.o
 
-obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o power.o clocks.o
+obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \
+	clocks.o power.o usbdev.o
 
-obj-$(CONFIG_AU1000_UART) += serial.o             
+obj-$(CONFIG_AU1000_UART) += serial.o
 obj-$(CONFIG_AU1000_USB_DEVICE) += usbdev.o
-obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o             
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
 obj-$(CONFIG_RTC) += rtc.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/clocks.c linux-2.4.20/arch/mips/au1000/common/clocks.c
--- linux-2.4.19/arch/mips/au1000/common/clocks.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/clocks.c	2002-10-04 00:41:17.000000000 +0000
@@ -75,9 +75,9 @@
 	unsigned int static_cfg0;
 	unsigned int sys_busclk =
 		(get_au1000_speed()/1000) /
-		((int)(inl(SYS_POWERCTRL)&0x03) + 2);
+		((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
 
-	static_cfg0 = inl(MEM_STCFG0);
+	static_cfg0 = au_readl(MEM_STCFG0);
 
 	if (static_cfg0 & (1<<11))
 		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/dbg_io.c linux-2.4.20/arch/mips/au1000/common/dbg_io.c
--- linux-2.4.19/arch/mips/au1000/common/dbg_io.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/dbg_io.c	2002-10-04 00:41:16.000000000 +0000
@@ -53,8 +53,8 @@
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
 /* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (readl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y,z) (writel(z&0xff, DEBUG_BASE + y))
+#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y))
 
 extern unsigned long get_au1000_uart_baud_base(void);
 extern unsigned long cal_r4koff(void);
@@ -71,7 +71,7 @@
 	UART16550_WRITE(UART_IER, 0);
 
 	/* set up baud rate */
-	{ 
+	{
 		uint32 divisor;
 
 		/* set divisor */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/dma.c linux-2.4.20/arch/mips/au1000/common/dma.c
--- linux-2.4.19/arch/mips/au1000/common/dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/dma.c	2002-10-04 00:41:09.000000000 +0000
@@ -77,23 +77,22 @@
 	unsigned int fifo_addr;
 	unsigned int dma_mode;
 } dma_dev_table[DMA_NUM_DEV] = {
-	{
-	UART0_ADDR + UART_TX, 0}, {
-	UART0_ADDR + UART_RX, 0}, {
-	0, 0}, {
-	0, 0}, {
-	AC97C_DATA, DMA_DW16 | DMA_NC}, {
-	AC97C_DATA, DMA_DR | DMA_DW16 | DMA_NC}, {
-	UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC}, {
-	UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC}, {
-	USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC}, {
-	USBD_EP0WR, DMA_DW8 | DMA_NC}, {
-	USBD_EP2WR, DMA_DW8 | DMA_NC}, {
-	USBD_EP3WR, DMA_DW8 | DMA_NC}, {
-	USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC}, {
-	USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC}, {
-	I2S_DATA, DMA_DW32 | DMA_NC}, {
-	I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
+	{UART0_ADDR + UART_TX, 0},
+	{UART0_ADDR + UART_RX, 0},
+	{0, 0},
+	{0, 0},
+	{AC97C_DATA, DMA_DW16 },          // coherent
+	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
+	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
+	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP0WR, DMA_DW8 | DMA_NC},
+	{USBD_EP2WR, DMA_DW8 | DMA_NC},
+	{USBD_EP3WR, DMA_DW8 | DMA_NC},
+	{USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC},
+	{I2S_DATA, DMA_DW32 | DMA_NC},
+	{I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
 };
 
 
@@ -105,9 +104,8 @@
 
 	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
 		if ((chan = get_dma_chan(i)) != NULL) {
-			len +=
-			    sprintf(buf + len, "%2d: %s\n", i,
-				    chan->dev_str);
+			len += sprintf(buf + len, "%2d: %s\n",
+				       i, chan->dev_str);
 		}
 	}
 
@@ -134,28 +132,32 @@
 
 	printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
 	printk(KERN_INFO "  mode = 0x%08x\n",
-	       inl(chan->io + DMA_MODE_SET));
+	       au_readl(chan->io + DMA_MODE_SET));
 	printk(KERN_INFO "  addr = 0x%08x\n",
-	       inl(chan->io + DMA_PERIPHERAL_ADDR));
+	       au_readl(chan->io + DMA_PERIPHERAL_ADDR));
 	printk(KERN_INFO "  start0 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER0_START));
+	       au_readl(chan->io + DMA_BUFFER0_START));
 	printk(KERN_INFO "  start1 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER1_START));
+	       au_readl(chan->io + DMA_BUFFER1_START));
 	printk(KERN_INFO "  count0 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER0_COUNT));
+	       au_readl(chan->io + DMA_BUFFER0_COUNT));
 	printk(KERN_INFO "  count1 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER1_COUNT));
+	       au_readl(chan->io + DMA_BUFFER1_COUNT));
 }
 
 
 /*
  * Finds a free channel, and binds the requested device to it.
  * Returns the allocated channel number, or negative on error.
+ * Requests the DMA done IRQ if irqhandler != NULL.
  */
-int request_au1000_dma(int dev_id, const char *dev_str)
+int request_au1000_dma(int dev_id, const char *dev_str,
+		       void (*irqhandler)(int, void *, struct pt_regs *),
+		       unsigned long irqflags,
+		       void *irq_dev_id)
 {
 	struct dma_chan *chan;
-	int i;
+	int i, ret;
 
 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
 		return -EINVAL;
@@ -169,14 +171,30 @@
 
 	chan = &au1000_dma_table[i];
 
+	if (irqhandler) {
+		chan->irq = AU1000_DMA_INT_BASE + i;
+		chan->irq_dev = irq_dev_id;
+		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+				       dev_str, chan->irq_dev))) {
+			chan->irq = 0;
+			chan->irq_dev = NULL;
+			return ret;
+		}
+	} else {
+		chan->irq = 0;
+		chan->irq_dev = NULL;
+	}
+
 	// fill it in
 	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
-	chan->irq = AU1000_DMA_INT_BASE + i;
 	chan->dev_id = dev_id;
 	chan->dev_str = dev_str;
 	chan->fifo_addr = dma_dev_table[dev_id].fifo_addr;
 	chan->mode = dma_dev_table[dev_id].dma_mode;
 
+	/* initialize the channel before returning */
+	init_dma(i);
+
 	return i;
 }
 
@@ -190,6 +208,10 @@
 	}
 
 	disable_dma(dmanr);
+	if (chan->irq)
+		free_irq(chan->irq, chan->irq_dev);
 
+	chan->irq = 0;
+	chan->irq_dev = NULL;
 	chan->dev_id = -1;
-}				/* free_dma */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/int-handler.S linux-2.4.20/arch/mips/au1000/common/int-handler.S
--- linux-2.4.19/arch/mips/au1000/common/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/int-handler.S	2002-10-04 00:41:15.000000000 +0000
@@ -9,7 +9,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
@@ -40,30 +39,30 @@
 
 1:
 	andi	a0, t0, CAUSEF_IP2	# Interrupt Controller 0, Request 0
-	beq	a0, zero, 2f	        
-	move	a0,sp  
+	beq	a0, zero, 2f
+	move	a0,sp
 	jal	intc0_req0_irqdispatch
 	j	ret_from_irq
 2:
 	andi	a0, t0, CAUSEF_IP3	# Interrupt Controller 0, Request 1
-	beq	a0, zero, 3f	       
-	move	a0,sp  
+	beq	a0, zero, 3f
+	move	a0,sp
 	jal	intc0_req1_irqdispatch
 	j	ret_from_irq
 3:
 	andi	a0, t0, CAUSEF_IP4	# Interrupt Controller 1, Request 0
-	beq	a0, zero, 4f	       
-	move	a0,sp  
+	beq	a0, zero, 4f
+	move	a0,sp
 	jal	intc1_req0_irqdispatch
 	j	ret_from_irq
 4:
 	andi	a0, t0, CAUSEF_IP5	# Interrupt Controller 1, Request 1
-	beq	a0, zero, 5f	       
-	move	a0, sp  
+	beq	a0, zero, 5f
+	move	a0, sp
 	jal	intc1_req1_irqdispatch
 	j	ret_from_irq
 
-5:	
+5:
 	move	a0, sp
 	j	spurious_interrupt
 END(au1000_IRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/irq.c linux-2.4.20/arch/mips/au1000/common/irq.c
--- linux-2.4.19/arch/mips/au1000/common/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/irq.c	2002-10-04 00:41:15.000000000 +0000
@@ -51,6 +51,8 @@
 #include <asm/pb1000.h>
 #elif defined(CONFIG_MIPS_PB1500)
 #include <asm/pb1500.h>
+#elif defined(CONFIG_MIPS_PB1100)
+#include <asm/pb1100.h>
 #else
 #error unsupported alchemy board
 #endif
@@ -103,86 +105,86 @@
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG0SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1SET);
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<(irq_nr-32), IC1_CFG2SET);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG0SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<(irq_nr-32), IC1_CFG2SET);
-				outl(1<<(irq_nr-32), IC1_CFG1SET);
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
 				break;
 			default: /* disable the interrupt */
 				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<(irq_nr-32), IC1_ASSIGNCLR);
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			outl(1<<(irq_nr-32), IC1_ASSIGNSET);
-		outl(1<<(irq_nr-32), IC1_SRCSET);
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
-		outl(1<<(irq_nr-32), IC1_WAKECLR);
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
+		au_writel(1<<(irq_nr-32), IC1_SRCSET);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<irq_nr, IC0_CFG2CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG0SET);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<irq_nr, IC0_CFG2CLR);
-				outl(1<<irq_nr, IC0_CFG1SET);
-				outl(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<irq_nr, IC0_CFG2SET);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG0SET);
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<irq_nr, IC0_CFG2SET);
-				outl(1<<irq_nr, IC0_CFG1SET);
-				outl(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<irq_nr, IC0_CFG0CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
 				break;
 			default: /* disable the interrupt */
 				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				outl(1<<irq_nr, IC0_CFG0CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<irq_nr, IC0_ASSIGNCLR);
+			au_writel(1<<irq_nr, IC0_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			outl(1<<irq_nr, IC0_ASSIGNSET);
-		outl(1<<irq_nr, IC0_SRCSET);
-		outl(1<<irq_nr, IC0_MASKCLR);
-		outl(1<<irq_nr, IC0_WAKECLR);
+			au_writel(1<<irq_nr, IC0_ASSIGNSET);
+		au_writel(1<<irq_nr, IC0_SRCSET);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
 	}
 	au_sync();
 }
@@ -191,7 +193,7 @@
 static unsigned int startup_irq(unsigned int irq_nr)
 {
 	local_enable_irq(irq_nr);
-	return 0; 
+	return 0;
 }
 
 
@@ -205,12 +207,12 @@
 inline void local_enable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_MASKSET);
-		outl(1<<(irq_nr-32), IC1_WAKESET);
+		au_writel(1<<(irq_nr-32), IC1_MASKSET);
+		au_writel(1<<(irq_nr-32), IC1_WAKESET);
 	}
 	else {
-		outl(1<<irq_nr, IC0_MASKSET);
-		outl(1<<irq_nr, IC0_WAKESET);
+		au_writel(1<<irq_nr, IC0_MASKSET);
+		au_writel(1<<irq_nr, IC0_WAKESET);
 	}
 	au_sync();
 }
@@ -219,12 +221,12 @@
 inline void local_disable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
-		outl(1<<(irq_nr-32), IC1_WAKECLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_MASKCLR);
-		outl(1<<irq_nr, IC0_WAKECLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
 	}
 	au_sync();
 }
@@ -233,12 +235,12 @@
 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_RISINGCLR);
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_RISINGCLR);
-		outl(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_RISINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
 	}
 	au_sync();
 }
@@ -247,12 +249,12 @@
 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_FALLINGCLR);
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_FALLINGCLR);
-		outl(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_FALLINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
 	}
 	au_sync();
 }
@@ -265,7 +267,7 @@
 	au_sync();
 #if defined(CONFIG_MIPS_PB1000)
 	if (irq_nr == AU1000_GPIO_15) {
-		writew(0x8000, PB1000_MDR); /* ack int */
+		au_writel(0x8000, PB1000_MDR); /* ack int */
 		au_sync();
 	}
 #endif
@@ -279,12 +281,12 @@
 		local_enable_irq(irq_nr);
 	}
 	else {
-		printk("warning: end_irq %d did not enable (%x)\n", 
+		printk("warning: end_irq %d did not enable (%x)\n",
 				irq_nr, irq_desc[irq_nr].status);
 	}
 #if defined(CONFIG_MIPS_PB1000)
 	if (irq_nr == AU1000_GPIO_15) {
-		writew(0x4000, PB1000_MDR); /* enable int */
+		au_writel(0x4000, PB1000_MDR); /* enable int */
 		au_sync();
 	}
 #endif
@@ -297,13 +299,13 @@
 	save_and_cli(flags);
 
 	if (controller) {
-		mask = readl(IC1_MASKSET);
+		mask = au_readl(IC1_MASKSET);
 		for (i=32; i<64; i++) {
 			local_disable_irq(i);
 		}
 	}
 	else {
-		mask = readl(IC0_MASKSET);
+		mask = au_readl(IC0_MASKSET);
 		for (i=0; i<32; i++) {
 			local_disable_irq(i);
 		}
@@ -327,9 +329,9 @@
 		}
 	}
 	if (controller)
-		new_mask = readl(IC1_MASKSET);
+		new_mask = au_readl(IC1_MASKSET);
 	else
-		new_mask = readl(IC0_MASKSET);
+		new_mask = au_readl(IC0_MASKSET);
 
 	restore_flags(flags);
 }
@@ -390,10 +392,6 @@
 
 	init_generic_irq();
 
-	/* override the generic vec0 handler */
-	memcpy((void *)KSEG0, &except_vec0_au1000, 0x80);
-	flush_icache_range(KSEG0, KSEG0 + 0x200);
-	
 	for (i = 0; i <= AU1000_MAX_INTR; i++) {
 		switch (i) {
 			case AU1000_UART0_INT:
@@ -406,6 +404,12 @@
 			case AU1000_SSI1_INT:
 #endif
 
+#ifdef CONFIG_MIPS_PB1100
+			case AU1000_UART1_INT:
+
+			case AU1000_SSI0_INT:
+			case AU1000_SSI1_INT:
+#endif
 		        case AU1000_DMA_INT_BASE:
 		        case AU1000_DMA_INT_BASE+1:
 		        case AU1000_DMA_INT_BASE+2:
@@ -419,9 +423,14 @@
 			case AU1000_IRDA_RX_INT:
 
 			case AU1000_MAC0_DMA_INT:
+#ifdef CONFIG_MIPS_PB1000
 			case AU1000_MAC1_DMA_INT:
-
+#endif
+#ifdef CONFIG_MIPS_PB1500
+			case AU1000_MAC1_DMA_INT:
+#endif
 			case AU1500_GPIO_204:
+
 				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
 				irq_desc[i].handler = &level_irq_type;
 				break;
@@ -441,16 +450,24 @@
 			case AU1500_GPIO_205:
 			case AU1500_GPIO_207:
 #endif
+
+#ifdef CONFIG_MIPS_PB1100
+			case AU1000_GPIO_9: // PCMCIA Card Fully_Interted#
+			case AU1000_GPIO_10: // PCMCIA_STSCHG#
+			case AU1000_GPIO_11: // PCMCIA_IRQ#
+			case AU1000_GPIO_13: // DC_IRQ#
+			case AU1000_GPIO_23: // 2-wire SCL
+#endif
 				setup_local_irq(i, INTC_INT_LOW_LEVEL, 0);
 				irq_desc[i].handler = &level_irq_type;
                                 break;
 			case AU1000_ACSYNC_INT:
 			case AU1000_AC97C_INT:
-		        case AU1000_USB_DEV_REQ_INT:
-		        case AU1000_USB_DEV_SUS_INT:
 			case AU1000_TOY_INT:
 			case AU1000_TOY_MATCH0_INT:
 			case AU1000_TOY_MATCH1_INT:
+		        case AU1000_USB_DEV_SUS_INT:
+		        case AU1000_USB_DEV_REQ_INT:
 			case AU1000_RTC_INT:
 			case AU1000_RTC_MATCH0_INT:
 			case AU1000_RTC_MATCH1_INT:
@@ -478,7 +495,7 @@
 	/* If local serial I/O used for debug port, enter kgdb at once */
 	puts("Waiting for kgdb to connect...");
 	set_debug_traps();
-	breakpoint(); 
+	breakpoint();
 #endif
 }
 
@@ -494,10 +511,21 @@
 	int irq = 0, i;
 	static unsigned long intc0_req0 = 0;
 
-	intc0_req0 |= inl(IC0_REQ0INT);
+	intc0_req0 |= au_readl(IC0_REQ0INT);
 
 	if (!intc0_req0) return;
 
+	/*
+	 * Because of the tight timing of SETUP token to reply
+	 * transactions, the USB devices-side packet complete
+	 * interrupt needs the highest priority.
+	 */
+	if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
+		intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
+		do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
+		return;
+	}
+
 	for (i=0; i<32; i++) {
 		if ((intc0_req0 & (1<<i))) {
 			intc0_req0 &= ~(1<<i);
@@ -514,7 +542,7 @@
 	int irq = 0, i;
 	static unsigned long intc0_req1 = 0;
 
-	intc0_req1 = inl(IC0_REQ1INT);
+	intc0_req1 = au_readl(IC0_REQ1INT);
 
 	if (!intc0_req1) return;
 
@@ -527,7 +555,7 @@
 				counter0_irq(irq, NULL, regs);
 				local_enable_irq(irq);
 			}
-			else 
+			else
 #endif
 			{
 				do_IRQ(irq, regs);
@@ -550,20 +578,20 @@
 	volatile unsigned short levels, mdr;
 	unsigned char ide_status;
 
-	intc1_req0 |= inl(IC1_REQ0INT);
+	intc1_req0 |= au_readl(IC1_REQ0INT);
 
 	if (!intc1_req0) return;
 
-#ifdef CONFIG_MIPS_PB1000
-	writew(1, CPLD_AUX0); /* debug led 0 */
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+	au_writel(1, CPLD_AUX0); /* debug led 0 */
 #endif
 	for (i=0; i<32; i++) {
 		if ((intc1_req0 & (1<<i))) {
 			intc1_req0 &= ~(1<<i);
-#ifdef CONFIG_MIPS_PB1000
-			writew(2, CPLD_AUX0); /* turn on debug led 1  */
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+			au_writel(2, CPLD_AUX0); /* turn on debug led 1  */
 			do_IRQ(irq+32, regs);
-			writew(0, CPLD_AUX0); /* turn off debug led 1 */
+			au_writel(0, CPLD_AUX0); /* turn off debug led 1 */
 #else
 			do_IRQ(irq+32, regs);
 #endif
@@ -571,8 +599,8 @@
 		}
 		irq++;
 	}
-#ifdef CONFIG_MIPS_PB1000
-	writew(0, CPLD_AUX0);
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+	au_writel(0, CPLD_AUX0);
 #endif
 }
 
@@ -582,7 +610,7 @@
 	int irq = 0, i;
 	static unsigned long intc1_req1 = 0;
 
-	intc1_req1 |= inl(IC1_REQ1INT);
+	intc1_req1 |= au_readl(IC1_REQ1INT);
 
 	if (!intc1_req1) return;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/power.c linux-2.4.20/arch/mips/au1000/common/power.c
--- linux-2.4.19/arch/mips/au1000/common/power.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/power.c	2002-10-04 00:41:09.000000000 +0000
@@ -29,7 +29,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -49,7 +49,7 @@
 #  define DPRINTK(fmt, args...)
 #endif
 
-inline void au1_wait(void);
+extern void au1k_wait(void);
 static void calibrate_delay(void);
 
 extern void set_au1000_speed(unsigned int new_freq);
@@ -81,16 +81,16 @@
 
 	flush_cache_all();
 	/* pin 6 is gpio */
-	writel(readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
+	au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
 
 	/* gpio 6 can cause a wake up event */
-	wakeup = readl(SYS_WAKEMSK);
+	wakeup = au_readl(SYS_WAKEMSK);
 	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
 	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
-	writel(wakeup, SYS_WAKEMSK);
+	au_writel(wakeup, SYS_WAKEMSK);
 
-	writel(1, SYS_WAKESRC);	/* clear cause */
-	writel(1, SYS_SLPPWR);	/* prepare to sleep */
+	au_writel(1, SYS_WAKESRC);	/* clear cause */
+	au_writel(1, SYS_SLPPWR);	/* prepare to sleep */
 
 	__asm__("la $4, 1f\n\t"
 		"lui $5, 0xb190\n\t"
@@ -138,7 +138,7 @@
 		if (retval)
 			return retval;
 		suspend_mode = 1;
-		au1_wait();
+		au1k_wait();
 		retval = pm_send_all(PM_RESUME, (void *) 0);
 	}
 	return retval;
@@ -194,22 +194,22 @@
 		set_au1000_speed(new_cpu_freq);
 		set_au1000_uart_baud_base(new_baud_base);
 
-		old_refresh = readl(MEM_SDREFCFG) & 0x1ffffff;
+		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
 		new_refresh =
 		    ((old_refresh * new_cpu_freq) /
-		     old_cpu_freq) | (readl(MEM_SDREFCFG) & ~0x1ffffff);
+		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
 
-		writel(pll, SYS_CPUPLL);
+		au_writel(pll, SYS_CPUPLL);
 		au_sync_delay(1);
-		writel(new_refresh, MEM_SDREFCFG);
+		au_writel(new_refresh, MEM_SDREFCFG);
 		au_sync_delay(1);
 
 		for (i = 0; i < 4; i++) {
-			if (readl
+			if (au_readl
 			    (UART_BASE + UART_MOD_CNTRL +
 			     i * 0x00100000) == 3) {
 				old_clk =
-				    readl(UART_BASE + UART_CLK +
+				    au_readl(UART_BASE + UART_CLK +
 					  i * 0x00100000);
 				// baud_rate = baud_base/clk
 				baud_rate = old_baud_base / old_clk;
@@ -231,7 +231,7 @@
 					(baud_rate = 9600);
 				// new_clk = new_baud_base/baud_rate
 				new_clk = new_baud_base / baud_rate;
-				writel(new_clk,
+				au_writel(new_clk,
 				       UART_BASE + UART_CLK +
 				       i * 0x00100000);
 				au_sync_delay(10);
@@ -246,7 +246,7 @@
 	 */
 	intc0_mask = save_local_and_disable(0);
 	intc1_mask = save_local_and_disable(1);
-	local_enable_irq(AU1000_TOY_MATCH2);
+	local_enable_irq(AU1000_TOY_MATCH2_INT);
 	restore_flags(flags);
 	calibrate_delay();
 	restore_local_and_enable(0, intc0_mask);
@@ -278,13 +278,6 @@
 
 __initcall(pm_init);
 
-inline void au1_wait(void)
-{
-	__asm__(".set\tmips3\n\t"
-		"wait\n\t"
-		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
-}
-
 
 /*
  * This is right out of init/main.c
@@ -330,12 +323,4 @@
 	}
 }
 
-
-#else				/* CONFIG_PM */
-
-void au1_wait(void)
-{
-	__asm__("nop\n\t" "nop\n\t");
-}
-
 #endif				/* CONFIG_PM */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/prom.c linux-2.4.20/arch/mips/au1000/common/prom.c
--- linux-2.4.19/arch/mips/au1000/common/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/prom.c	2002-10-04 00:41:22.000000000 +0000
@@ -8,7 +8,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/xx files.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -125,7 +125,7 @@
 		ea[i] = num;
 	}
 }
- 
+
 int get_ethernet_addr(char *ethernet_addr)
 {
 	int i;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/reset.c linux-2.4.20/arch/mips/au1000/common/reset.c
--- linux-2.4.19/arch/mips/au1000/common/reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/reset.c	2002-10-04 00:41:10.000000000 +0000
@@ -27,7 +27,7 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <asm/io.h>
@@ -35,6 +35,7 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <asm/au1000.h>
 
 extern int au_sleep(void);
 
@@ -47,40 +48,60 @@
 	switch (prid & 0xFF000000)
 	{
 	case 0x00000000: /* Au1000 */
-		outl(0x02, 0xb0000010); /* ac97_enable */
-		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
 		asm("sync");
-		outl(0x00, 0xb017fffc); /* usbh_enable */
-		outl(0x00, 0xb0200058); /* usbd_enable */
-		outl(0x00, 0xb0300040); /* ir_enable */
-		outl(0x00, 0xb0520000); /* macen0 */
-		outl(0x00, 0xb0520004); /* macen1 */
-		outl(0x00, 0xb1000008); /* i2s_enable  */
-		outl(0x00, 0xb1100100); /* uart0_enable */
-		outl(0x00, 0xb1200100); /* uart1_enable */
-		outl(0x00, 0xb1300100); /* uart2_enable */
-		outl(0x00, 0xb1400100); /* uart3_enable */
-		outl(0x02, 0xb1600100); /* ssi0_enable */
-		outl(0x02, 0xb1680100); /* ssi1_enable */
-		outl(0x00, 0xb1900020); /* sys_freqctrl0 */
-		outl(0x00, 0xb1900024); /* sys_freqctrl1 */
-		outl(0x00, 0xb1900028); /* sys_clksrc */
-		outl(0x00, 0xb1900100); /* sys_pininputen */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb0520004); /* macen1 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1300100); /* uart2_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
 		break;
 	case 0x01000000: /* Au1500 */
-		outl(0x02, 0xb0000010); /* ac97_enable */
-		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb1520000); /* macen0 */
+		au_writel(0x00, 0xb1520004); /* macen1 */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x02000000: /* Au1100 */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
 		asm("sync");
-		outl(0x00, 0xb017fffc); /* usbh_enable */
-		outl(0x00, 0xb0200058); /* usbd_enable */
-		outl(0x00, 0xb1520000); /* macen0 */
-		outl(0x00, 0xb1520004); /* macen1 */
-		outl(0x00, 0xb1100100); /* uart0_enable */
-		outl(0x00, 0xb1400100); /* uart3_enable */
-		outl(0x00, 0xb1900020); /* sys_freqctrl0 */
-		outl(0x00, 0xb1900024); /* sys_freqctrl1 */
-		outl(0x00, 0xb1900028); /* sys_clksrc */
-		outl(0x00, 0xb1900100); /* sys_pininputen */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
 
 	default:
 		break;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/rtc.c linux-2.4.20/arch/mips/au1000/common/rtc.c
--- linux-2.4.19/arch/mips/au1000/common/rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/rtc.c	2002-10-04 00:41:20.000000000 +0000
@@ -9,19 +9,20 @@
  */
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
+#include <asm/au1000.h>
 
 #define PB1500_RTC_ADDR 0xAC000000
 
-static unsigned char std_rtc_read_data(unsigned long addr)
+unsigned char std_rtc_read_data(unsigned long offset)
 {
-	addr <<= 2;
-	return readb(addr + PB1500_RTC_ADDR);
+	offset <<= 2;
+	return (u8)(au_readl(offset + PB1500_RTC_ADDR) & 0xff);
 }
 
-static void std_rtc_write_data(unsigned char data, unsigned long addr)
+static void std_rtc_write_data(unsigned char data, unsigned long offset)
 {
-	addr <<= 2;
-	writeb(data, addr + PB1500_RTC_ADDR);
+	offset <<= 2;
+	au_writel(data, offset + PB1500_RTC_ADDR);
 }
 
 static int std_rtc_bcd_mode(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/serial.c linux-2.4.20/arch/mips/au1000/common/serial.c
--- linux-2.4.19/arch/mips/au1000/common/serial.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/serial.c	2002-10-04 00:41:15.000000000 +0000
@@ -10,7 +10,7 @@
  *  Derived almost entirely from drivers/char/serial.c:
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
  * 		1998, 1999  Theodore Ts'o
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -63,7 +63,7 @@
 
 #define RS_STROBE_TIME (10*HZ)
 #define RS_ISR_PASS_LIMIT 256
-  
+
 /*
  * End of serial driver configuration section.
  */
@@ -166,10 +166,10 @@
  * UART
  */
 static struct serial_uart_config uart_config[] = {
-	{ "unknown", 1, 0 }, 
-	{ "8250", 1, 0 }, 
-	{ "16450", 1, 0 }, 
-	{ "16550", 1, 0 }, 
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
 	{ 0, 0}
 };
 
@@ -238,15 +238,14 @@
 	return 0;
 }
 
-
 static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
 {
-	return (inl(info->port+offset) & 0xffff);
+	return (au_readl(info->port+offset) & 0xffff);
 }
 
 static _INLINE_ void serial_out(struct async_struct *info, int offset, int value)
 {
-	outl(value & 0xffff, info->port+offset);
+	au_writel(value & 0xffff, info->port+offset);
 }
 
 
@@ -275,7 +274,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if (info->IER & UART_IER_THRI) {
 		info->IER &= ~UART_IER_THRI;
@@ -288,10 +287,10 @@
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_start"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if (info->xmit.head != info->xmit.tail
 	    && info->xmit.buf
@@ -314,7 +313,7 @@
  * rs_interrupt() should try to keep the interrupt handler as fast as
  * possible.  After you are done making modifications, it is not a bad
  * idea to do:
- * 
+ *
  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
  *
  * and look at the resulting assemble code in serial.s.
@@ -350,7 +349,7 @@
 			goto ignore_char;
 		*tty->flip.char_buf_ptr = ch;
 		icount->rx++;
-		
+
 #ifdef SERIAL_DEBUG_INTR
 		printk("DR%02x:%02x...", ch, *status);
 #endif
@@ -468,7 +467,7 @@
 		serial_out(info, UART_IER, info->IER);
 		return;
 	}
-	
+
 	count = info->xmit_fifo_size;
 	do {
 		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
@@ -477,7 +476,7 @@
 		if (info->xmit.head == info->xmit.tail)
 			break;
 	} while (--count > 0);
-	
+
 	if (CIRC_CNT(info->xmit.head,
 		     info->xmit.tail,
 		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
@@ -499,7 +498,7 @@
 {
 	int	status;
 	struct	async_icount *icount;
-	
+
 	status = serial_in(info, UART_MSR);
 
 	if (status & UART_MSR_ANY_DELTA) {
@@ -526,7 +525,7 @@
 #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 		printk("ttys%d CD now %s...", info->line,
 		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
+#endif
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
 		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -573,7 +572,7 @@
 	int status;
 	int pass_counter = 0;
 	struct async_struct * info;
-	
+
 #ifdef SERIAL_DEBUG_INTR
 	printk("rs_interrupt_single(%d)...", irq);
 #endif
@@ -630,7 +629,7 @@
 {
 	struct async_struct	*info = (struct async_struct *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -750,8 +749,8 @@
 		info->xmit.buf = (unsigned char *) page;
 
 
-	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
-		outl(3, UART_MOD_CNTRL + state->port);
+	if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) {
+		au_writel(3, UART_MOD_CNTRL + state->port);
 		au_sync_delay(10);
 	}
 #ifdef SERIAL_DEBUG_OPEN
@@ -794,7 +793,7 @@
 			retval = -ENODEV;
 		goto errout;
 	}
-	
+
 	/*
 	 * Allocate the IRQ if necessary
 	 */
@@ -806,7 +805,7 @@
 		if (IRQ_ports[state->irq]) {
 			retval = -EBUSY;
 			goto errout;
-		} else 
+		} else
 			handler = rs_interrupt_single;
 
 		retval = request_irq(state->irq, handler, SA_SHIRQ,
@@ -833,7 +832,7 @@
 	figure_IRQ_timeout(state->irq);
 
 	/*
-	 * Now, initialize the UART 
+	 * Now, initialize the UART
 	 */
 	serial_outp(info, UART_LCR, UART_LCR_WLEN8);
 
@@ -846,13 +845,13 @@
 	}
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
 	serial_outp(info, UART_MCR, info->MCR);
-	
+
 	/*
 	 * Finally, enable interrupts
 	 */
 	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
-	
+
 
 	/*
 	 * And clear the interrupt registers again for luck.
@@ -884,7 +883,7 @@
 		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 			info->tty->alt_speed = 460800;
 	}
-	
+
 	/*
 	 * and set the speed of the serial port
 	 */
@@ -893,7 +892,7 @@
 	info->flags |= ASYNC_INITIALIZED;
 	restore_flags(flags);
 	return 0;
-	
+
 errout:
 	restore_flags(flags);
 	return retval;
@@ -918,7 +917,7 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       state->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
 
 	/*
@@ -926,7 +925,7 @@
 	 * here so the queue might never be waken up
 	 */
 	wake_up_interruptible(&info->delta_msr_wait);
-	
+
 	/*
 	 * First unlink the serial port from the IRQ chain...
 	 */
@@ -937,7 +936,7 @@
 	else
 		IRQ_ports[state->irq] = info->next_port;
 	figure_IRQ_timeout(state->irq);
-	
+
 	/*
 	 * Free the IRQ, if necessary
 	 */
@@ -949,7 +948,7 @@
 			retval = request_irq(state->irq, rs_interrupt_single,
 					     SA_SHIRQ, "serial",
 					     &IRQ_ports[state->irq]);
-			
+
 			if (retval)
 				printk("serial shutdown: request_irq: error %d"
 				       "  Couldn't reacquire IRQ.\n", retval);
@@ -967,28 +966,28 @@
 	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
 		info->MCR &= ~UART_MCR_OUT2;
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	
+
 	/* disable break condition */
 	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-	
+
 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
 		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
 	serial_outp(info, UART_MCR, info->MCR);
 
-	/* disable FIFO's */	
+	/* disable FIFO's */
 	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
 				     UART_FCR_CLEAR_RCVR |
 				     UART_FCR_CLEAR_XMIT));
 	serial_outp(info, UART_FCR, 0);
 
 	(void)serial_in(info, UART_RX);    /* read data port to reset things */
-	
+
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
 	info->flags &= ~ASYNC_INITIALIZED;
 #ifndef CONFIG_REMOTE_DEBUG
-	outl(0, UART_MOD_CNTRL + state->port);
+	au_writel(0, UART_MOD_CNTRL + state->port);
 	au_sync_delay(10);
 #endif
 	restore_flags(flags);
@@ -1076,7 +1075,7 @@
 	/* As a last resort, if the quotient is zero, default to 9600 bps */
 	if (!quot)
 		quot = baud_base / 9600;
-	
+
 	info->quot = quot;
 	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
 	info->timeout += HZ/50;		/* Add .02 seconds of slop */
@@ -1088,7 +1087,7 @@
 		else
 			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8;
 	}
-	
+
 	/* CTS flow control flag and modem status interrupts */
 	info->IER &= ~UART_IER_MSI;
 	if (info->flags & ASYNC_HARDPPS_CD)
@@ -1116,7 +1115,7 @@
 		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
 		info->read_status_mask |= UART_LSR_BI;
-	
+
 	/*
 	 * Characters to ignore
 	 */
@@ -1126,7 +1125,7 @@
 	if (I_IGNBRK(info->tty)) {
 		info->ignore_status_mask |= UART_LSR_BI;
 		/*
-		 * If we're ignore parity and break indicators, ignore 
+		 * If we're ignore parity and break indicators, ignore
 		 * overruns too.  (For real raw support).
 		 */
 		if (I_IGNPAR(info->tty))
@@ -1173,7 +1172,7 @@
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
 		return;
 
@@ -1195,7 +1194,7 @@
 	int	c, ret = 0;
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_write"))
 		return 0;
 
@@ -1278,7 +1277,7 @@
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
@@ -1288,7 +1287,7 @@
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 	save_flags(flags); cli();
@@ -1325,7 +1324,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1336,14 +1335,14 @@
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("throttle %s: %d....\n", tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
 		return;
-	
+
 	if (I_IXOFF(tty))
 		rs_send_xchar(tty, STOP_CHAR(tty));
 
@@ -1361,14 +1360,14 @@
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
@@ -1393,7 +1392,7 @@
 {
 	struct serial_struct tmp;
 	struct serial_state *state = info->state;
-   
+
 	if (!retinfo)
 		return -EFAULT;
 	memset(&tmp, 0, sizeof(tmp));
@@ -1439,7 +1438,7 @@
 	change_irq = new_serial.irq != state->irq;
 	change_port = (new_port != ((int) state->port)) ||
 		(new_serial.hub6 != state->hub6);
-  
+
 	if (!capable(CAP_SYS_ADMIN)) {
 		if (change_irq || change_port ||
 		    (new_serial.baud_base != state->baud_base) ||
@@ -1459,7 +1458,7 @@
 
 	new_serial.irq = irq_cannonicalize(new_serial.irq);
 
-	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
 	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
 	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
 	    (new_serial.type == PORT_STARTECH)) {
@@ -1522,7 +1521,7 @@
 			request_region(state->port,8,"serial(set)");
 	}
 
-	
+
 check_and_exit:
 	if (!state->port || !state->type)
 		return 0;
@@ -1555,7 +1554,7 @@
  * 	    release the bus after transmitting. This must be done when
  * 	    the transmit shift register is empty, not be done when the
  * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct async_struct * info, unsigned int *value)
 {
@@ -1574,7 +1573,7 @@
 	 * avoid a race condition (depending on when the transmit
 	 * interrupt happens).
 	 */
-	if (info->x_char || 
+	if (info->x_char ||
 	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
 		       SERIAL_XMIT_SIZE) > 0) &&
 	     !info->tty->stopped && !info->tty->hw_stopped))
@@ -1622,7 +1621,7 @@
 		return -EFAULT;
 
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->MCR |= UART_MCR_RTS;
 		if (arg & TIOCM_DTR)
@@ -1679,13 +1678,13 @@
 static int do_autoconfig(struct async_struct * info)
 {
 	int retval;
-	
+
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-	
+
 	if (info->state->count > 1)
 		return -EBUSY;
-	
+
 	shutdown(info);
 
 	autoconfig(info->state);
@@ -1702,7 +1701,7 @@
 {
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_break"))
 		return;
 
@@ -1725,7 +1724,7 @@
 	struct async_icount cprev, cnow;	/* kernel counter temps */
 	struct serial_icounter_struct icount;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
 		return -ENODEV;
 
@@ -1735,7 +1734,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TIOCMGET:
 			return get_modem_info(info, (unsigned int *) arg);
@@ -1760,8 +1759,8 @@
 					 info, sizeof(struct async_struct)))
 				return -EFAULT;
 			return 0;
-				
-			
+
+
 		/*
 		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
 		 * - mask passed in arg for lines of interest
@@ -1784,7 +1783,7 @@
 				save_flags(flags); cli();
 				cnow = info->state->icount; /* atomic copy */
 				restore_flags(flags);
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
 					return -EIO; /* no change => error */
 				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
@@ -1797,7 +1796,7 @@
 			}
 			/* NOTREACHED */
 
-		/* 
+		/*
 		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
 		 * Return: write counters to the user passed counter struct
 		 * NB: both 1->0 and 0->1 transitions are counted except for
@@ -1818,7 +1817,7 @@
 			icount.parity = cnow.parity;
 			icount.brk = cnow.brk;
 			icount.buf_overrun = cnow.buf_overrun;
-			
+
 			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
 				return -EFAULT;
 			return 0;
@@ -1839,9 +1838,9 @@
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
 	unsigned int cflag = tty->termios->c_cflag;
-	
+
 	if (   (cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
@@ -1855,12 +1854,12 @@
 		serial_out(info, UART_MCR, info->MCR);
 		restore_flags(flags);
 	}
-	
+
 	/* Handle transition away from B0 status */
 	if (!(old_termios->c_cflag & CBAUD) &&
 	    (cflag & CBAUD)) {
 		info->MCR |= UART_MCR_DTR;
-		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		if (!(tty->termios->c_cflag & CRTSCTS) ||
 		    !test_bit(TTY_THROTTLED, &tty->flags)) {
 			info->MCR |= UART_MCR_RTS;
 		}
@@ -1868,7 +1867,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		restore_flags(flags);
 	}
-	
+
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1880,7 +1879,7 @@
 /*
  * ------------------------------------------------------------
  * rs_close()
- * 
+ *
  * This routine is called when the serial port gets closed.  First, we
  * wait for the last remaining data to be sent.  Then, we unlink its
  * async structure from the interrupt chain if necessary, and we free
@@ -1897,16 +1896,16 @@
 		return;
 
 	state = info->state;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		DBG_CNT("before DEC-hung");
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
 #endif
@@ -1944,7 +1943,7 @@
 	if (info->flags & ASYNC_CALLOUT_ACTIVE)
 		info->state->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1996,7 +1995,7 @@
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	unsigned long orig_jiffies, char_time;
 	int lsr;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
 		return;
 
@@ -2011,7 +2010,7 @@
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
 	 * interval should also be less than the timeout.
-	 * 
+	 *
 	 * Note: we have to use pretty tight timings here to satisfy
 	 * the NIST-PCTS.
 	 */
@@ -2060,12 +2059,12 @@
 {
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	struct serial_state *state = info->state;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
 		return;
 
 	state = info->state;
-	
+
 	rs_flush_buffer(tty);
 	if (info->flags & ASYNC_CLOSING)
 		return;
@@ -2125,7 +2124,7 @@
 		info->flags |= ASYNC_CALLOUT_ACTIVE;
 		return 0;
 	}
-	
+
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -2145,7 +2144,7 @@
 		if (tty->termios->c_cflag & CLOCAL)
 			do_clocal = 1;
 	}
-	
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -2181,7 +2180,7 @@
 			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -2283,7 +2282,7 @@
 	tty->driver_data = info;
 	info->tty = tty;
 	if (serial_paranoia_check(info, tty->device, "rs_open")) {
-		MOD_DEC_USE_COUNT;		
+		MOD_DEC_USE_COUNT;
 		return -ENODEV;
 	}
 
@@ -2344,7 +2343,7 @@
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->state->normal_termios;
-		else 
+		else
 			*tty->termios = info->state->callout_termios;
 		change_speed(info, 0);
 	}
@@ -2376,7 +2375,7 @@
 	unsigned long flags;
 
 	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
-		      state->line, uart_config[state->type].name, 
+		      state->line, uart_config[state->type].name,
 		      state->port, state->irq);
 
 	if (!state->port || (state->type == PORT_UNKNOWN)) {
@@ -2399,7 +2398,7 @@
 	save_flags(flags); cli();
 	status = serial_in(info, UART_MSR);
 	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
-	restore_flags(flags); 
+	restore_flags(flags);
 
 	stat_buf[0] = 0;
 	stat_buf[1] = 0;
@@ -2426,12 +2425,12 @@
 
 	if (state->icount.frame)
 		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
-	
+
 	if (state->icount.parity)
 		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
-	
+
 	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
 		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
@@ -2511,15 +2510,15 @@
 	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
 	       state->port, (unsigned) state->iomem_base);
 #endif
-	
+
 	if (!CONFIGURED_SERIAL_PORT(state))
 		return;
 
-	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
-		outl(3, UART_MOD_CNTRL + state->port);
+	if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) {
+		au_writel(3, UART_MOD_CNTRL + state->port);
 		au_sync_delay(10);
 	}
-		
+
 	state->type = PORT_16550;
 	info = &scr_info;	/* This is just for serial_{in,out} */
 
@@ -2548,11 +2547,6 @@
 	serial_outp(info, UART_FCR, 0);
 	(void)serial_in(info, UART_RX);
 	serial_outp(info, UART_IER, 0);
-
-#ifndef CONFIG_REMOTE_DEBUG
-	outl(0, UART_MOD_CNTRL + state->port);
-	au_sync_delay(10);
-#endif
 	restore_flags(flags);
 }
 
@@ -2595,7 +2589,7 @@
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
-	
+
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
 	serial_driver.driver_name = "serial";
@@ -2637,7 +2631,7 @@
 	serial_driver.send_xchar = rs_send_xchar;
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 	serial_driver.read_proc = rs_read_proc;
-	
+
 	/*
 	 * The callout device is just like normal device except for
 	 * major number and the subtype code.
@@ -2657,7 +2651,7 @@
 		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver");
-	
+
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->baud_base = get_au1000_uart_baud_base();
 		state->magic = SSTATE_MAGIC;
@@ -2668,7 +2662,7 @@
 		state->closing_wait = 30*HZ;
 		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
-		state->icount.cts = state->icount.dsr = 
+		state->icount.cts = state->icount.dsr =
 			state->icount.rng = state->icount.dcd = 0;
 		state->icount.rx = state->icount.tx = 0;
 		state->icount.frame = state->icount.parity = 0;
@@ -2705,7 +2699,7 @@
  * register_serial and unregister_serial allows for 16x50 serial ports to be
  * configured at run-time, to support PCMCIA modems.
  */
- 
+
 /**
  *	register_serial - configure a 16x50 serial port at runtime
  *	@req: request structure
@@ -2719,7 +2713,7 @@
  *
  *	On success the port is ready to use and the line number is returned.
  */
- 
+
 int register_serial(struct serial_struct *req)
 {
 	int i;
@@ -2784,7 +2778,7 @@
 	      state->iomem_base ? (unsigned long)state->iomem_base :
 	      state->port, state->irq, uart_config[state->type].name);
 	tty_register_devfs(&serial_driver, 0,
-			   serial_driver.minor_start + state->line); 
+			   serial_driver.minor_start + state->line);
 	tty_register_devfs(&callout_driver, 0,
 			   callout_driver.minor_start + state->line);
 	return state->line + SERIAL_DEV_OFFSET;
@@ -2819,7 +2813,7 @@
 	restore_flags(flags);
 }
 
-static void __exit rs_fini(void) 
+static void __exit rs_fini(void)
 {
 	unsigned long flags;
 	int e1, e2;
@@ -2834,7 +2828,7 @@
 		printk("serial: failed to unregister serial driver (%d)\n",
 		       e1);
 	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("serial: failed to unregister callout driver (%d)\n", 
+		printk("serial: failed to unregister callout driver (%d)\n",
 		       e2);
 	restore_flags(flags);
 
@@ -2882,7 +2876,7 @@
 
 		if (status & UART_LSR_BI)
 			lsr_break_flag = UART_LSR_BI;
-		
+
 		if (--tmout == 0)
 			break;
 	} while((status & BOTH_EMPTY) != BOTH_EMPTY);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/time.c linux-2.4.20/arch/mips/au1000/common/time.c
--- linux-2.4.19/arch/mips/au1000/common/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/time.c	2002-10-04 00:41:15.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
  * Copied and modified Carsten Langgaard's time.c
  *
@@ -123,13 +123,13 @@
 	static int jiffie_drift = 0;
 
 	kstat.irqs[0][irq]++;
-	if (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
 		/* should never happen! */
 		printk(KERN_WARNING "counter 0 w status eror\n");
 		return;
 	}
 
-	pc0 = inl(SYS_TOYREAD);
+	pc0 = au_readl(SYS_TOYREAD);
 	if (pc0 < last_match20) {
 		/* counter overflowed */
 		time_elapsed = (0xffffffff - last_match20) + pc0;
@@ -146,13 +146,13 @@
 	}
 
 	last_pc0 = pc0;
-	outl(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 	au_sync();
 
 	/* our counter ticks at 10.009765625 ms/tick, we we're running
 	 * almost 10uS too slow per tick.
 	 */
-	 
+
 	if (jiffie_drift >= 999) {
 		jiffie_drift -= 999;
 		do_timer(regs); /* increment jiffies by one */
@@ -160,9 +160,9 @@
 }
 #endif
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the Programmable Counter 1 to do this.
  */
 unsigned long cal_r4koff(void)
@@ -176,27 +176,27 @@
 
 	save_and_cli(flags);
 
-	counter = inl(SYS_COUNTER_CNTRL);
-	outl(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
+	counter = au_readl(SYS_COUNTER_CNTRL);
+	au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
 
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
-	outl(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
-
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
-	outl (0, SYS_TOYWRITE);
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+	au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+	au_writel (0, SYS_TOYWRITE);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
 
-	start = inl(SYS_RTCREAD);
+	start = au_readl(SYS_RTCREAD);
 	start += 2;
 	/* wait for the beginning of a new tick */
-	while (inl(SYS_RTCREAD) < start);
+	while (au_readl(SYS_RTCREAD) < start);
 
 	/* Start r4k counter. */
 	write_32bit_cp0_register(CP0_COUNT, 0);
 	end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */
 
-	while (end > inl(SYS_RTCREAD));
+	while (end > au_readl(SYS_RTCREAD));
 
 	count = read_32bit_cp0_register(CP0_COUNT);
 	cpu_speed = count * 2;
@@ -215,11 +215,11 @@
 	r4k_offset = cal_r4koff();
 	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
 
-	//est_freq = 2*r4k_offset*HZ;	
-	est_freq = r4k_offset*HZ;	
+	//est_freq = 2*r4k_offset*HZ;
+	est_freq = r4k_offset*HZ;
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
 	       (est_freq%1000000)*100/1000000);
 	set_au1000_speed(est_freq);
 	set_au1000_lcd_clock(); // program the LCD clock
@@ -241,20 +241,20 @@
 	 * counter 0 interrupt as a special irq and it doesn't show
 	 * up under /proc/interrupts.
 	 */
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
-	writel(0, SYS_TOYWRITE);
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+	au_writel(0, SYS_TOYWRITE);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
 
-	writel(readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
-	writel(~0, SYS_WAKESRC);
+	au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+	au_writel(~0, SYS_WAKESRC);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 
 	/* setup match20 to interrupt once every 10ms */
-	last_pc0 = last_match20 = readl(SYS_TOYREAD);
-	writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
+	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 	startup_match20_interrupt();
 #endif
 
@@ -282,7 +282,7 @@
 	unsigned long pc0;
 	unsigned long offset;
 
-	pc0 = readl(SYS_TOYREAD);
+	pc0 = au_readl(SYS_TOYREAD);
 	if (pc0 < last_pc0) {
 		offset = 0xffffffff - last_pc0 + pc0;
 		printk("offset over: %x\n", (unsigned)offset);
@@ -291,8 +291,8 @@
 		offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10);
 	}
 	if ((pc0-last_pc0) > 2*MATCH20_INC) {
-		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", 
-				(unsigned)offset, (unsigned)last_pc0, 
+		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",
+				(unsigned)offset, (unsigned)last_pc0,
 				(unsigned)last_match20, (unsigned)pc0);
 	}
 	au_sync();
@@ -338,7 +338,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * Due to possible jiffies inconsistencies, we need to check
 	 * the result so that we'll get a timer that is monotonic.
 	 */
 	if (res >= USECS_PER_JIFFY)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/usbdev.c linux-2.4.20/arch/mips/au1000/common/usbdev.c
--- linux-2.4.19/arch/mips/au1000/common/usbdev.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/common/usbdev.c	2002-10-04 00:41:10.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Au1000 USB Device-Side Serial TTY Driver
+ *	Au1000 USB Device-Side (device layer)
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2001-2002 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *		stevel@mvista.com or source@mvista.com
  *
@@ -37,9 +37,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/fcntl.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
@@ -53,54 +50,30 @@
 #include <asm/mipsregs.h>
 #include <asm/au1000.h>
 #include <asm/au1000_dma.h>
+#include <asm/au1000_usbdev.h>
 
-/* Module information */
-MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com");
-MODULE_DESCRIPTION("Au1000 USB Device-Side Serial TTY Driver");
-
-#undef USBDEV_PIO
-
-#define SERIAL_TTY_MAJOR 189
+#ifdef DEBUG
+#undef VDEBUG
+#ifdef VDEBUG
+#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg)
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
 
 #define MAX(a,b)	(((a)>(b))?(a):(b))
 
 #define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
 
-#define MAX_NUM_PORTS 2
-
-#define NUM_PORTS 1
-#define NUM_EP 2*NUM_PORTS
-
-#define EP0_MAX_PACKET_SIZE 64
-#define EP2_MAX_PACKET_SIZE 64
-#define EP3_MAX_PACKET_SIZE 64
-#define EP4_MAX_PACKET_SIZE 64
-#define EP5_MAX_PACKET_SIZE 64
-
-#ifdef USBDEV_PIO
 #define EP_FIFO_DEPTH 8
-#endif
 
 typedef enum {
-	ATTACHED = 0,
-	POWERED,
-	DEFAULT,
-	ADDRESS,
-	CONFIGURED
-} dev_state_t;
-
-/* local function prototypes */
-static int serial_open(struct tty_struct *tty, struct file *filp);
-static void serial_close(struct tty_struct *tty, struct file *filp);
-static int serial_write(struct tty_struct *tty, int from_user,
-			const unsigned char *buf, int count);
-static int serial_write_room(struct tty_struct *tty);
-static int serial_chars_in_buffer(struct tty_struct *tty);
-static void serial_throttle(struct tty_struct *tty);
-static void serial_unthrottle(struct tty_struct *tty);
-static int serial_ioctl(struct tty_struct *tty, struct file *file,
-			unsigned int cmd, unsigned long arg);
-static void serial_set_termios (struct tty_struct *tty, struct termios * old);
+	SETUP_STAGE = 0,
+	DATA_STAGE,
+	STATUS_STAGE
+} ep0_stage_t;
 
 typedef struct {
 	int read_fifo;
@@ -110,184 +83,68 @@
 	int write_fifo_status;
 } endpoint_reg_t;
 
-typedef struct pkt {
-	int size;
-	u8 *bufptr;
-	struct pkt *next;
-	u8 buf[0];
-} pkt_t;
-
 typedef struct {
-	pkt_t *head;
-	pkt_t *tail;
+	usbdev_pkt_t *head;
+	usbdev_pkt_t *tail;
 	int count;
 } pkt_list_t;
 
 typedef struct {
+	int active;
 	struct usb_endpoint_descriptor *desc;
 	endpoint_reg_t *reg;
-	// Only one of these are used, unless this is a control ep
+	/* Only one of these are used, unless this is the control ep */
 	pkt_list_t inlist;
 	pkt_list_t outlist;
-	unsigned int indma, outdma;	// DMA channel numbers for IN, OUT
-	int inirq, outirq;	// DMA buffer done irq numbers
+	unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */
+	/* following are extracted from endpoint descriptor for easy access */
 	int max_pkt_size;
+	int type;
+	int direction;
+	/* WE assign endpoint addresses! */
+	int address;
 	spinlock_t lock;
 } endpoint_t;
 
-struct usb_serial_port {
-	struct usb_serial *serial;	/* ptr back to the owner of this port */
-	struct tty_struct *tty;	/* the coresponding tty for this port */
-	unsigned char number;
-	char active;		/* someone has this device open */
-	spinlock_t port_lock;
-
-	endpoint_t ep_bulkin;
-	endpoint_t ep_bulkout;
-
-	wait_queue_head_t write_wait;
-
-	/* task queue for line discipline waking up on send packet complete */
-	struct tq_struct send_complete_tq;
-	/* task queue for line discipline wakeup on receive packet complete */
-	struct tq_struct receive_complete_tq;
-
-	int open_count;		/* number of times this port has been opened */
-};
-
-struct usb_serial {
-	struct tty_driver *tty_driver;	/* the tty_driver for this device */
-	unsigned char minor;	/* the minor number for this device */
-
-	endpoint_t ep_ctrl;
 
-	struct usb_device_descriptor *dev_desc;
-	struct usb_interface_descriptor *if_desc;
-	struct usb_config_descriptor *conf_desc;
-	struct usb_string_descriptor *str_desc[6];
+static struct usb_dev {
+	endpoint_t ep[6];
+	ep0_stage_t ep0_stage;
+
+	struct usb_device_descriptor *   dev_desc;
+	struct usb_interface_descriptor* if_desc;
+	struct usb_config_descriptor *   conf_desc;
+	u8 *                             full_conf_desc;
+	struct usb_string_descriptor *   str_desc[6];
+
+	/* callback to function layer */
+	void (*func_cb)(usbdev_cb_type_t type, unsigned long arg,
+			void *cb_data);
+	void* cb_data;
 
-	struct usb_serial_port port[NUM_PORTS];
-
-	dev_state_t state;	// device state
+	usbdev_state_t state;	// device state
 	int suspended;		// suspended flag
 	int address;		// device address
 	int interface;
+	int num_ep;
 	u8 alternate_setting;
 	u8 configuration;	// configuration value
 	int remote_wakeup_en;
-};
-
-
-static struct usb_device_descriptor dev_desc = {
-	bLength:USB_DT_DEVICE_SIZE,
-	bDescriptorType:USB_DT_DEVICE,
-	bcdUSB:0x0110,		//usb rev 1.0
-	bDeviceClass:USB_CLASS_PER_INTERFACE,	//class    (none)
-	bDeviceSubClass:0x00,	//subclass (none)
-	bDeviceProtocol:0x00,	//protocol (none)
-	bMaxPacketSize0:EP0_MAX_PACKET_SIZE,	//max packet size for ep0
-	idVendor:0x6d04,	//vendor  id
-	idProduct:0x0bc0,	//product id
-	bcdDevice:0x0001,	//BCD rev 0.1
-	iManufacturer:0x01,	//manufactuer string index
-	iProduct:0x02,		//product string index
-	iSerialNumber:0x03,	//serial# string index
-	bNumConfigurations:0x01	//num configurations
-};
-
-static struct usb_endpoint_descriptor ep_desc[] = {
-	{
-	 // EP2, Bulk IN for Port 0
-	      bLength:USB_DT_ENDPOINT_SIZE,
-	      bDescriptorType:USB_DT_ENDPOINT,
-	      bEndpointAddress:USB_DIR_IN | 0x02,
-	      bmAttributes:USB_ENDPOINT_XFER_BULK,
-	      wMaxPacketSize:EP2_MAX_PACKET_SIZE,
-	      bInterval:0x00	// ignored for bulk
-	 },
-	{
-	 // EP4, Bulk OUT for Port 0
-	      bLength:USB_DT_ENDPOINT_SIZE,
-	      bDescriptorType:USB_DT_ENDPOINT,
-	      bEndpointAddress:USB_DIR_OUT | 0x04,
-	      bmAttributes:USB_ENDPOINT_XFER_BULK,
-	      wMaxPacketSize:EP4_MAX_PACKET_SIZE,
-	      bInterval:0x00	// ignored for bulk
-	 },
-	{
-	 // EP3, Bulk IN for Port 1
-	      bLength:USB_DT_ENDPOINT_SIZE,
-	      bDescriptorType:USB_DT_ENDPOINT,
-	      bEndpointAddress:USB_DIR_IN | 0x03,
-	      bmAttributes:USB_ENDPOINT_XFER_BULK,
-	      wMaxPacketSize:EP3_MAX_PACKET_SIZE,
-	      bInterval:0x00	// ignored for bulk
-	 },
-	{
-	 // EP5, Bulk OUT for Port 1
-	      bLength:USB_DT_ENDPOINT_SIZE,
-	      bDescriptorType:USB_DT_ENDPOINT,
-	      bEndpointAddress:USB_DIR_OUT | 0x05,
-	      bmAttributes:USB_ENDPOINT_XFER_BULK,
-	      wMaxPacketSize:EP5_MAX_PACKET_SIZE,
-	      bInterval:0x00	// ignored for bulk
-	 },
-};
-
-static struct usb_interface_descriptor if_desc = {
-	bLength:USB_DT_INTERFACE_SIZE,
-	bDescriptorType:USB_DT_INTERFACE,
-	bInterfaceNumber:0x00,
-	bAlternateSetting:0x00,
-	bNumEndpoints:NUM_EP,
-	bInterfaceClass:0xff,
-	bInterfaceSubClass:0xab,
-	bInterfaceProtocol:0x00,
-	iInterface:0x05
-};
-
-#define CONFIG_DESC_LEN \
- USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE
-
-static struct usb_config_descriptor config_desc = {
-	bLength:USB_DT_CONFIG_SIZE,
-	bDescriptorType:USB_DT_CONFIG,
-	wTotalLength:CONFIG_DESC_LEN,
-	bNumInterfaces:0x01,
-	bConfigurationValue:0x01,
-	iConfiguration:0x04,	// configuration string
-	bmAttributes:0xc0,	// self-powered
-	MaxPower:20		// 40 mA
-};
-
-// These strings will be converted to Unicode before sending
-static char *strings[5] = {
-	"Alchemy Semiconductor",
-	"Alchemy Au1000",
-	"1.0",
-	"Au1000 UART Config",
-	"Au1000 UART Interface"
-};
-
-// String[0] is a list of Language IDs supported by this device
-static struct usb_string_descriptor string_desc0 = {
-	bLength:4,
-	bDescriptorType:USB_DT_STRING,
-	wData:{0x0409}		// English, US
-};
+} usbdev;
 
 
 static endpoint_reg_t ep_reg[] = {
 	// FIFO's 0 and 1 are EP0 default control
-	{USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT},
-	// FIFO 2 is EP2, Port 0, bulk IN
+	{USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT },
+	{0},
+	// FIFO 2 is EP2, IN
 	{ -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT },
-	// FIFO 4 is EP4, Port 0, bulk OUT
-	    {USBD_EP4RD, -1, USBD_EP4CS, USBD_EP3WR, -1},
-	// FIFO 3 is EP3, Port 1, bulk IN
-	{ -1, USBD_EP3WRSTAT, USBD_EP3CS, -1, USBD_EP3WRSTAT },
-	// FIFO 5 is EP5, Port 1, bulk OUT
-	    {USBD_EP5RD, -1, USBD_EP5CS, USBD_EP5RDSTAT, -1}
+	// FIFO 3 is EP3, IN
+	{    -1,     USBD_EP3WR, USBD_EP3CS,     -1,         USBD_EP3WRSTAT },
+	// FIFO 4 is EP4, OUT
+	{USBD_EP4RD,     -1,     USBD_EP4CS, USBD_EP4RDSTAT,     -1         },
+	// FIFO 5 is EP5, OUT
+	{USBD_EP5RD,     -1,     USBD_EP5CS, USBD_EP5RDSTAT,     -1         }
 };
 
 static struct {
@@ -297,172 +154,88 @@
 	{ DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" },
 	{ DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" },
 	{ DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" },
-	{ DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" },
 	{ DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" },
+	{ DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" },
 	{ DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" }
 };
 
-static int serial_refcount;
-static struct tty_driver serial_tty_driver;
-static struct tty_struct *serial_tty[1];
-static struct termios *serial_termios[1];
-static struct termios *serial_termios_locked[1];
-static struct usb_serial usbserial;
-
 #define DIR_OUT 0
 #define DIR_IN  (1<<3)
 
-static const u32 au1000_config_table[25] __devinitdata = {
-	0x00,
-	    ((EP0_MAX_PACKET_SIZE & 0x380) >> 7) |
-	    (USB_ENDPOINT_XFER_CONTROL << 4),
-	(EP0_MAX_PACKET_SIZE & 0x7f) << 1,
-	0x00,
-	0x01,
-
-	0x10,
-	    ((EP2_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_IN |
-	    (USB_ENDPOINT_XFER_BULK << 4),
-	(EP2_MAX_PACKET_SIZE & 0x7f) << 1,
-	0x00,
-	0x02,
-
-	0x20,
-	    ((EP3_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_IN |
-	    (USB_ENDPOINT_XFER_BULK << 4),
-	(EP3_MAX_PACKET_SIZE & 0x7f) << 1,
-	0x00,
-	0x03,
-
-	0x30,
-	    ((EP4_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_OUT |
-	    (USB_ENDPOINT_XFER_BULK << 4),
-	(EP4_MAX_PACKET_SIZE & 0x7f) << 1,
-	0x00,
-	0x04,
-
-	0x40,
-	    ((EP5_MAX_PACKET_SIZE & 0x380) >> 7) | DIR_OUT |
-	    (USB_ENDPOINT_XFER_BULK << 4),
-	(EP5_MAX_PACKET_SIZE & 0x7f) << 1,
-	0x00,
-	0x05
-};
-
-static inline endpoint_t *
-fifonum_to_ep(struct usb_serial* serial, int fifo_num)
-{
-	switch (fifo_num) {
-	case 0:
-	case 1:
-		return &serial->ep_ctrl;
-	case 2:
-		return &serial->port[0].ep_bulkin;
-	case 3:
-		return &serial->port[1].ep_bulkin;
-	case 4:
-		return &serial->port[0].ep_bulkout;
-	case 5:
-		return &serial->port[1].ep_bulkout;
-	}
-
-	return NULL;
-}
-
-static inline struct usb_serial_port *
-fifonum_to_port(struct usb_serial* serial, int fifo_num)
-{
-	switch (fifo_num) {
-	case 2:
-	case 4:
-		return &serial->port[0];
-	case 3:
-	case 5:
-		return &serial->port[1];
-	}
-
-	return NULL;
-}
+#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL
+#define BULK_EP    USB_ENDPOINT_XFER_BULK
 
 static inline endpoint_t *
-epnum_to_ep(struct usb_serial* serial, int ep_num)
+epaddr_to_ep(struct usb_dev* dev, int ep_addr)
 {
-	switch (ep_num) {
-	case 0:
-		return &serial->ep_ctrl;
-	case 2:
-		return &serial->port[0].ep_bulkin;
-	case 3:
-		return &serial->port[1].ep_bulkin;
-	case 4:
-		return &serial->port[0].ep_bulkout;
-	case 5:
-		return &serial->port[1].ep_bulkout;
-	}
-
+	if (ep_addr >= 0 && ep_addr < 2)
+		return &dev->ep[0];
+	if (ep_addr < 6)
+		return &dev->ep[ep_addr];
 	return NULL;
 }
 
+static const char* std_req_name[] = {
+	"GET_STATUS",
+	"CLEAR_FEATURE",
+	"RESERVED",
+	"SET_FEATURE",
+	"RESERVED",
+	"SET_ADDRESS",
+	"GET_DESCRIPTOR",
+	"SET_DESCRIPTOR",
+	"GET_CONFIGURATION",
+	"SET_CONFIGURATION",
+	"GET_INTERFACE",
+	"SET_INTERFACE",
+	"SYNCH_FRAME"
+};
 
-static inline int
-port_paranoia_check(struct usb_serial_port *port, const char *function)
+static inline const char*
+get_std_req_name(int req)
 {
-	if (!port) {
-		dbg("%s - port == NULL", function);
-		return -1;
-	}
-	if (!port->serial) {
-		dbg("%s - port->serial == NULL", function);
-		return -1;
-	}
-	if (!port->tty) {
-		dbg("%s - port->tty == NULL", function);
-		return -1;
-	}
-
-	return 0;
+	return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN";
 }
 
-static inline struct usb_serial*
-get_usb_serial (struct usb_serial_port *port, const char *function)
+#if 0
+static void
+dump_setup(devrequest* s)
 {
-	/* if no port was specified, or it fails a paranoia check */
-	if (!port || port_paranoia_check(port, function)) {
-		/* then say that we dont have a valid usb_serial thing,
-		 * which will end up genrating -ENODEV return values */
-		return NULL;
-	}
-
-	return port->serial;
+	dbg(__FUNCTION__ ": requesttype=%d", s->requesttype);
+	dbg(__FUNCTION__ ": request=%d %s", s->request,
+	    get_std_req_name(s->request));
+	dbg(__FUNCTION__ ": value=0x%04x", s->wValue);
+	dbg(__FUNCTION__ ": index=%d", s->index);
+	dbg(__FUNCTION__ ": length=%d", s->length);
 }
+#endif
 
-
-static inline pkt_t *
-alloc_packet(int data_size)
+static inline usbdev_pkt_t *
+alloc_packet(endpoint_t * ep, int data_size, void* data)
 {
-	pkt_t* pkt = (pkt_t *)kmalloc(sizeof(pkt_t) + data_size, ALLOC_FLAGS);
+	usbdev_pkt_t* pkt =
+		(usbdev_pkt_t *)kmalloc(sizeof(usbdev_pkt_t) + data_size,
+					ALLOC_FLAGS);
 	if (!pkt)
 		return NULL;
+	pkt->ep_addr = ep->address;
 	pkt->size = data_size;
-	pkt->bufptr = pkt->buf;
-#ifndef USBDEV_PIO
-	pkt->bufptr = KSEG1ADDR(pkt->bufptr);
-#endif
+	pkt->status = 0;
 	pkt->next = NULL;
+	if (data)
+		memcpy(pkt->payload, data, data_size);
+
 	return pkt;
 }
 
 
 /*
  * Link a packet to the tail of the enpoint's packet list.
+ * EP spinlock must be held when calling.
  */
 static void
-link_packet(endpoint_t * ep, pkt_list_t * list, pkt_t * pkt)
+link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ep->lock, flags);
-
 	if (!list->tail) {
 		list->head = list->tail = pkt;
 		list->count = 1;
@@ -471,24 +244,20 @@
 		list->tail = pkt;
 		list->count++;
 	}
-
-	spin_unlock_irqrestore(&ep->lock, flags);
 }
 
 /*
- * Unlink and return a packet from the head of the enpoint's packet list.
+ * Unlink and return a packet from the head of the given packet
+ * list. It is the responsibility of the caller to free the packet.
+ * EP spinlock must be held when calling.
  */
-static pkt_t *
-unlink_packet(endpoint_t * ep, pkt_list_t * list)
+static usbdev_pkt_t *
+unlink_head(pkt_list_t * list)
 {
-	unsigned long flags;
-	pkt_t *pkt;
-
-	spin_lock_irqsave(&ep->lock, flags);
+	usbdev_pkt_t *pkt;
 
 	pkt = list->head;
 	if (!pkt || !list->count) {
-		spin_unlock_irqrestore(&ep->lock, flags);
 		return NULL;
 	}
 
@@ -499,118 +268,107 @@
 	} else
 		list->count--;
 
-	spin_unlock_irqrestore(&ep->lock, flags);
-
 	return pkt;
 }
 
 /*
  * Create and attach a new packet to the tail of the enpoint's
- * packet list.
+ * packet list. EP spinlock must be held when calling.
  */
-static pkt_t *
+static usbdev_pkt_t *
 add_packet(endpoint_t * ep, pkt_list_t * list, int size)
 {
-	pkt_t *pkt = alloc_packet(size);
+	usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL);
 	if (!pkt)
 		return NULL;
 
-	link_packet(ep, list, pkt);
+	link_tail(ep, list, pkt);
 	return pkt;
 }
 
 
 /*
  * Unlink and free a packet from the head of the enpoint's
- * packet list.
+ * packet list. EP spinlock must be held when calling.
  */
 static inline void
-free_packet(endpoint_t * ep, pkt_list_t * list)
+free_packet(pkt_list_t * list)
 {
-	kfree(unlink_packet(ep, list));
+	kfree(unlink_head(list));
 }
 
+/* EP spinlock must be held when calling. */
 static inline void
-flush_pkt_list(endpoint_t * ep, pkt_list_t * list)
+flush_pkt_list(pkt_list_t * list)
 {
 	while (list->count)
-		free_packet(ep, list);
+		free_packet(list);
 }
 
-
+/* EP spinlock must be held when calling */
 static inline void
 flush_write_fifo(endpoint_t * ep)
 {
 	if (ep->reg->write_fifo_status >= 0) {
-		outl_sync(USBDEV_FSTAT_FLUSH, ep->reg->write_fifo_status);
-		udelay(100);
-		outl_sync(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
 			  ep->reg->write_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->write_fifo_status);
 	}
 }
 
-
+/* EP spinlock must be held when calling */
 static inline void
 flush_read_fifo(endpoint_t * ep)
 {
 	if (ep->reg->read_fifo_status >= 0) {
-		outl_sync(USBDEV_FSTAT_FLUSH, ep->reg->read_fifo_status);
-		udelay(100);
-		outl_sync(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
 			  ep->reg->read_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->read_fifo_status);
 	}
 }
 
 
+/* EP spinlock must be held when calling. */
 static void
 endpoint_flush(endpoint_t * ep)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ep->lock, flags);
-
 	// First, flush all packets
-	flush_pkt_list(ep, &ep->inlist);
-	flush_pkt_list(ep, &ep->outlist);
+	flush_pkt_list(&ep->inlist);
+	flush_pkt_list(&ep->outlist);
 
 	// Now flush the endpoint's h/w FIFO(s)
 	flush_write_fifo(ep);
 	flush_read_fifo(ep);
-
-	spin_unlock_irqrestore(&ep->lock, flags);
 }
 
-
+/* EP spinlock must be held when calling. */
 static void
 endpoint_stall(endpoint_t * ep)
 {
-	unsigned long flags;
 	u32 cs;
 
-	dbg(__FUNCTION__);
-
-	spin_lock_irqsave(&ep->lock, flags);
-
-	cs = inl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
-	outl_sync(cs, ep->reg->ctrl_stat);
+	warn(__FUNCTION__);
 
-	spin_unlock_irqrestore(&ep->lock, flags);
+	cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
 }
 
+/* EP spinlock must be held when calling. */
 static void
 endpoint_unstall(endpoint_t * ep)
 {
-	unsigned long flags;
 	u32 cs;
 
-	dbg(__FUNCTION__);
-
-	spin_lock_irqsave(&ep->lock, flags);
-
-	cs = inl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
-	outl_sync(cs, ep->reg->ctrl_stat);
+	warn(__FUNCTION__);
 
-	spin_unlock_irqrestore(&ep->lock, flags);
+	cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
 }
 
 static void
@@ -620,147 +378,182 @@
 }
 
 
-#ifdef USBDEV_PIO
+/* EP spinlock must be held when calling. */
 static int
 endpoint_fifo_read(endpoint_t * ep)
 {
-	unsigned long flags;
 	int read_count = 0;
 	u8 *bufptr;
-	pkt_t *pkt = ep->outlist.tail;
+	usbdev_pkt_t *pkt = ep->outlist.tail;
 
 	if (!pkt)
 		return -EINVAL;
 
-	spin_lock_irqsave(&ep->lock, flags);
-
-	bufptr = pkt->bufptr;
-	while (inl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
-		*bufptr++ = inl(ep->reg->read_fifo) & 0xff;
+	bufptr = &pkt->payload[pkt->size];
+	while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
+		*bufptr++ = au_readl(ep->reg->read_fifo) & 0xff;
 		read_count++;
 		pkt->size++;
 	}
-	pkt->bufptr = bufptr;
 
-	spin_unlock_irqrestore(&ep->lock, flags);
 	return read_count;
 }
 
-
+#if 0
+/* EP spinlock must be held when calling. */
 static int
-endpoint_fifo_write(endpoint_t * ep)
+endpoint_fifo_write(endpoint_t * ep, int index)
 {
-	unsigned long flags;
 	int write_count = 0;
 	u8 *bufptr;
-	pkt_t *pkt = ep->inlist.head;
+	usbdev_pkt_t *pkt = ep->inlist.head;
 
 	if (!pkt)
 		return -EINVAL;
 
-	spin_lock_irqsave(&ep->lock, flags);
-
-	bufptr = pkt->bufptr;
-	while ((inl(ep->reg->write_fifo_status) & USBDEV_FSTAT_FCNT_MASK) <
-	       EP_FIFO_DEPTH) {
-		if (bufptr < pkt->buf + pkt->size) {
-			outl_sync(*bufptr++, ep->reg->write_fifo);
+	bufptr = &pkt->payload[index];
+	while ((au_readl(ep->reg->write_fifo_status) &
+		USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) {
+		if (bufptr < pkt->payload + pkt->size) {
+			au_writel(*bufptr++, ep->reg->write_fifo);
 			write_count++;
 		} else {
 			break;
 		}
 	}
-	pkt->bufptr = bufptr;
 
-	spin_unlock_irqrestore(&ep->lock, flags);
 	return write_count;
 }
-#endif				// USBDEV_PIO
+#endif
 
 /*
  * This routine is called to restart transmission of a packet.
  * The endpoint's TSIZE must be set to the new packet's size,
  * and DMA to the write FIFO needs to be restarted.
+ * EP spinlock must be held when calling.
  */
 static void
 kickstart_send_packet(endpoint_t * ep)
 {
 	u32 cs;
-	pkt_t *pkt = ep->inlist.head;
+	usbdev_pkt_t *pkt = ep->inlist.head;
 
-	dbg(__FUNCTION__ ": pkt=%p", pkt);
+	vdbg(__FUNCTION__ ": ep%d, pkt=%p", ep->address, pkt);
 
-	if (!pkt)
+	if (!pkt) {
+		err(__FUNCTION__ ": head=NULL! list->count=%d",
+		    ep->inlist.count);
 		return;
+	}
+
+	dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size);
 
 	/*
-	 * The write fifo should already be drained if things are
-	 * working right, but flush it anyway just in case.
+	 * make sure FIFO is empty
 	 */
 	flush_write_fifo(ep);
-	cs = inl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
+
+	cs = au_readl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
 	cs |= (pkt->size << USBDEV_CS_TSIZE_BIT);
-	outl_sync(cs, ep->reg->ctrl_stat);
-#ifdef USBDEV_PIO
-	endpoint_fifo_write(ep);
-#else
-	disable_dma(ep->indma);
-	if (get_dma_active_buffer(ep->indma)) {
+	au_writel(cs, ep->reg->ctrl_stat);
+
+	if (get_dma_active_buffer(ep->indma) == 1) {
 		set_dma_count1(ep->indma, pkt->size);
-		set_dma_addr1(ep->indma, virt_to_phys(pkt->bufptr));
+		set_dma_addr1(ep->indma, virt_to_phys(pkt->payload));
 		enable_dma_buffer1(ep->indma);	// reenable
 	} else {
 		set_dma_count0(ep->indma, pkt->size);
-		set_dma_addr0(ep->indma, virt_to_phys(pkt->bufptr));
+		set_dma_addr0(ep->indma, virt_to_phys(pkt->payload));
 		enable_dma_buffer0(ep->indma);	// reenable
 	}
-	enable_dma(ep->indma);
-#endif
+	if (dma_halted(ep->indma))
+		start_dma(ep->indma);
 }
 
 
 /*
  * This routine is called when a packet in the inlist has been
  * completed. Frees the completed packet and starts sending the
- * next.
+ * next. EP spinlock must be held when calling.
  */
-static void
+static usbdev_pkt_t *
 send_packet_complete(endpoint_t * ep)
 {
-	if (ep->inlist.head)
-		dbg(__FUNCTION__ ": pkt=%p, ab=%d",
-		    ep->inlist.head, get_dma_active_buffer(ep->indma));
-
-	outl_sync(inl(ep->reg->ctrl_stat) & USBDEV_CS_STALL,
-		  ep->reg->ctrl_stat);
-	//disable_dma(ep->indma);
-	free_packet(ep, &ep->inlist);
+	usbdev_pkt_t *pkt = unlink_head(&ep->inlist);
+
+	if (pkt) {
+		pkt->status =
+			(au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ?
+			PKT_STATUS_NAK : PKT_STATUS_ACK;
+
+		vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, list count=%d",
+		     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+		     "NAK" : "ACK", pkt, ep->inlist.count);
+	}
+
+	/*
+	 * The write fifo should already be drained if things are
+	 * working right, but flush it anyway just in case.
+	 */
+	flush_write_fifo(ep);
+
 	// begin transmitting next packet in the inlist
-	if (ep->inlist.count)
+	if (ep->inlist.count) {
 		kickstart_send_packet(ep);
-}
+	}
 
+	return pkt;
+}
 
 /*
- * Unlink and return a packet from the head of the given ep's packet
- * outlist. It is the responsibility of the caller to free the packet.
- * The receive complete interrupt adds packets to the tail of this list. 
+ * Add a new packet to the tail of the given ep's packet
+ * inlist. The transmit complete interrupt frees packets from
+ * the head of this list. EP spinlock must be held when calling.
  */
-static pkt_t *
-receive_packet(endpoint_t * ep)
+static int
+send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async)
 {
-	pkt_t *pkt = unlink_packet(ep, &ep->outlist);
-	//dma_cache_inv((unsigned long)pkt->buf, pkt->size);
-	return pkt;
+	pkt_list_t *list;
+	endpoint_t* ep;
+
+	if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr)))
+		return -EINVAL;
+
+	if (!pkt->size)
+		return 0;
+
+	list = &ep->inlist;
+
+	if (!async && list->count) {
+		halt_dma(ep->indma);
+		flush_pkt_list(list);
+	}
+
+	link_tail(ep, list, pkt);
+
+	vdbg(__FUNCTION__ ": ep%d, pkt=%p, size=%d, list count=%d",
+	     ep->address, pkt, pkt->size, list->count);
+
+	if (list->count == 1) {
+		/*
+		 * if the packet count is one, it means the list was empty,
+		 * and no more data will go out this ep until we kick-start
+		 * it again.
+		 */
+		kickstart_send_packet(ep);
+	}
+
+	return pkt->size;
 }
 
 /*
  * This routine is called to restart reception of a packet.
+ * EP spinlock must be held when calling.
  */
 static void
 kickstart_receive_packet(endpoint_t * ep)
 {
-	pkt_t *pkt;
+	usbdev_pkt_t *pkt;
 
 	// get and link a new packet for next reception
 	if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) {
@@ -768,23 +561,21 @@
 		return;
 	}
 
-	/*
-	 * The read fifo should already be drained if things are
-	 * working right, but flush it anyway just in case.
-	 */
-	flush_read_fifo(ep);
-#ifndef USBDEV_PIO
-	if (get_dma_active_buffer(ep->outdma)) {
+	if (get_dma_active_buffer(ep->outdma) == 1) {
+		clear_dma_done1(ep->outdma);
 		set_dma_count1(ep->outdma, ep->max_pkt_size);
-		set_dma_addr1(ep->outdma, virt_to_phys(pkt->bufptr));
+		set_dma_count0(ep->outdma, 0);
+		set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload));
 		enable_dma_buffer1(ep->outdma);	// reenable
 	} else {
+		clear_dma_done0(ep->outdma);
 		set_dma_count0(ep->outdma, ep->max_pkt_size);
-		set_dma_addr0(ep->outdma, virt_to_phys(pkt->bufptr));
+		set_dma_count1(ep->outdma, 0);
+		set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload));
 		enable_dma_buffer0(ep->outdma);	// reenable
 	}
-	enable_dma(ep->outdma);
-#endif
+	if (dma_halted(ep->outdma))
+		start_dma(ep->outdma);
 }
 
 
@@ -795,404 +586,499 @@
  * remaining DMA counter. Then prepares a new packet for reception
  * and restarts DMA. FIXME: what if another packet comes in
  * on top of the completed packet? Counter would be wrong.
+ * EP spinlock must be held when calling.
  */
-static void
+static usbdev_pkt_t *
 receive_packet_complete(endpoint_t * ep)
 {
-	pkt_t *pkt = ep->outlist.tail;
+	usbdev_pkt_t *pkt = ep->outlist.tail;
+	u32 cs;
+
+	halt_dma(ep->outdma);
+
+	cs = au_readl(ep->reg->ctrl_stat);
 
 	if (!pkt)
-		return;
+		return NULL;
 
-	disable_dma(ep->outdma);
 	pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma);
-#ifdef USBDEV_PIO
-	pkt->bufptr = pkt->buf;	// reset bufptr
-#endif
-	dbg(__FUNCTION__ ": size=%d", pkt->size);
+	if (pkt->size)
+		dma_cache_inv((unsigned long)pkt->payload, pkt->size);
+	/*
+	 * need to pull out any remaining bytes in the FIFO.
+	 */
+	endpoint_fifo_read(ep);
+	/*
+	 * should be drained now, but flush anyway just in case.
+	 */
+	flush_read_fifo(ep);
+
+	pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK;
+	if (ep->address == 0 && (cs & USBDEV_CS_SU))
+		pkt->status |= PKT_STATUS_SU;
+
+	vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, size=%d",
+	     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+	     "NAK" : "ACK", pkt, pkt->size);
 
 	kickstart_receive_packet(ep);
-}
 
+	return pkt;
+}
 
 
 /*
- * Add a new packet to the tail of the given ep's packet
- * inlist. The transmit complete interrupt frees packets from
- * the head of this list.
+ ****************************************************************************
+ * Here starts the standard device request handlers. They are
+ * all called by do_setup() via a table of function pointers.
+ ****************************************************************************
  */
-static int
-send_packet(endpoint_t * ep, u8 * data, int data_len, int from_user)
-{
-	unsigned long flags;
-	pkt_list_t *list = &ep->inlist;
-	pkt_t *pkt;
-
-	if (!data || !data_len)
-		return 0;
 
-	if (!(pkt = alloc_packet(data_len))) {
-		err(__FUNCTION__ ": could not alloc new packet");
-		return -ENOMEM;
+static ep0_stage_t
+do_get_status(struct usb_dev* dev, devrequest* setup)
+{
+	switch (setup->requesttype) {
+	case 0x80:	// Device
+		// FIXME: send device status
+		break;
+	case 0x81:	// Interface
+		// FIXME: send interface status
+		break;
+	case 0x82:	// End Point
+		// FIXME: send endpoint status
+		break;
+	default:
+		// Invalid Command
+		endpoint_stall(&dev->ep[0]); // Stall End Point 0
+		break;
 	}
 
-	if (from_user)
-		copy_from_user(pkt->bufptr, data, data_len);
-	else
-		memcpy(pkt->bufptr, data, data_len);
-	au_sync();
-
-	//dma_cache_wback_inv((unsigned long)pkt->buf, data_len);
+	return STATUS_STAGE;
+}
 
-	link_packet(ep, list, pkt);
+static ep0_stage_t
+do_clear_feature(struct usb_dev* dev, devrequest* setup)
+{
+	switch (setup->requesttype) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 0;
+	else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->index) & 0xff);
+
+			endpoint_unstall(ep);
+			endpoint_reset_datatoggle(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	}
 
-	spin_lock_irqsave(&ep->lock, flags);
+	return SETUP_STAGE;
+}
 
-	dbg(__FUNCTION__ ": size=%d, list count=%d", pkt->size, list->count);
+static ep0_stage_t
+do_reserved(struct usb_dev* dev, devrequest* setup)
+{
+	// Invalid request, stall End Point 0
+	endpoint_stall(&dev->ep[0]);
+	return SETUP_STAGE;
+}
 
-	if (list->count == 1) {
-		/*
-		 * if the packet count is one, it means the list was empty,
-		 * and no more data will go out this ep until we kick-start
-		 * it again.
-		 */
-		kickstart_send_packet(ep);
+static ep0_stage_t
+do_set_feature(struct usb_dev* dev, devrequest* setup)
+{
+	switch (setup->requesttype) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 1;
+		else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->vwValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->index) & 0xff);
+
+			endpoint_stall(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
 	}
 
-	spin_unlock_irqrestore(&ep->lock, flags);
-	return data_len;
+	return SETUP_STAGE;
 }
 
-
-// SETUP packet request parser
-static void
-process_setup (struct usb_serial* serial, devrequest* setup)
+static ep0_stage_t
+do_set_address(struct usb_dev* dev, devrequest* setup)
 {
-	int desc_len, strnum;
+	int new_state = dev->state;
+	int new_addr = le16_to_cpu(setup->wValue);
 
-	dbg(__FUNCTION__ ": req %d", setup->request);
+	dbg(__FUNCTION__ ": our address=%d", new_addr);
 
-	switch (setup->request) {
-	case USB_REQ_SET_ADDRESS:
-		serial->address = le16_to_cpu(setup->value);
-		dbg(__FUNCTION__ ": our address=%d", serial->address);
-		if (serial->address > 127 || serial->state == CONFIGURED) {
+	if (new_addr > 127) {
 			// usb spec doesn't tell us what to do, so just go to
 			// default state
-			serial->state = DEFAULT;
-			serial->address = 0;
-		} else if (serial->address)
-			serial->state = ADDRESS;
-		else
-			serial->state = DEFAULT;
-		break;
-	case USB_REQ_GET_DESCRIPTOR:
-		desc_len = le16_to_cpu(setup->length);
-		switch (le16_to_cpu(setup->value) >> 8) {
+		new_state = DEFAULT;
+		dev->address = 0;
+	} else if (dev->address != new_addr) {
+		dev->address = new_addr;
+		new_state = ADDRESS;
+	}
+
+	if (dev->state != new_state) {
+		dev->state = new_state;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_descriptor(struct usb_dev* dev, devrequest* setup)
+{
+	int strnum, desc_len = le16_to_cpu(setup->length);
+
+		switch (le16_to_cpu(setup->wValue) >> 8) {
 		case USB_DT_DEVICE:
 			// send device descriptor!
-			desc_len = desc_len > serial->dev_desc->bLength ?
-			    serial->dev_desc->bLength : desc_len;
+		desc_len = desc_len > dev->dev_desc->bLength ?
+			dev->dev_desc->bLength : desc_len;
 			dbg("sending device desc, size=%d", desc_len);
-			send_packet(&serial->ep_ctrl, (u8*)serial->dev_desc,
-				    desc_len, 0);
+		send_packet(dev, alloc_packet(&dev->ep[0], desc_len,
+					      dev->dev_desc), 0);
 			break;
 		case USB_DT_CONFIG:
 			// If the config descr index in low-byte of
-			// setup->value	is valid, send config descr,
+			// setup->wValue	is valid, send config descr,
 			// otherwise stall ep0.
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
+			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
 				// send config descriptor!
 				if (desc_len <= USB_DT_CONFIG_SIZE) {
 					dbg("sending partial config desc, size=%d",
 					     desc_len);
-					send_packet(&serial->ep_ctrl,
-						    (u8*)serial->conf_desc,
-						    desc_len, 0);
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->conf_desc),
+					    0);
 				} else {
-					u8 full_conf_desc[CONFIG_DESC_LEN];
-					int i, index = 0;
-					memcpy(&full_conf_desc[index],
-					       serial->conf_desc,
-					       USB_DT_CONFIG_SIZE);
-					index += USB_DT_CONFIG_SIZE;
-					memcpy(&full_conf_desc[index],
-					       serial->if_desc,
-					       USB_DT_INTERFACE_SIZE);
-					index += USB_DT_INTERFACE_SIZE;
-					for (i = 0; i < NUM_PORTS; i++) {
-						memcpy(&full_conf_desc[index],
-						       serial->port[i].ep_bulkin.desc,
-						       USB_DT_ENDPOINT_SIZE);
-						index += USB_DT_ENDPOINT_SIZE;
-						memcpy(&full_conf_desc[index],
-						       serial->port[i].ep_bulkout.desc,
-						       USB_DT_ENDPOINT_SIZE);
-						index += USB_DT_ENDPOINT_SIZE;
-					}
-					dbg("sending whole config desc, size=%d, our size=%d",
-					     desc_len, CONFIG_DESC_LEN);
-					desc_len = desc_len > CONFIG_DESC_LEN ?
-					    CONFIG_DESC_LEN : desc_len;
-					send_packet(&serial->ep_ctrl,
-						    full_conf_desc, desc_len, 0);
+				int len = dev->conf_desc->wTotalLength;
+				dbg("sending whole config desc,"
+				    " size=%d, our size=%d", desc_len, len);
+				desc_len = desc_len > len ? len : desc_len;
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->full_conf_desc),
+					    0);
 				}
 			} else
-				endpoint_stall(&serial->ep_ctrl);
+			endpoint_stall(&dev->ep[0]);
 			break;
 		case USB_DT_STRING:
-			// If the string descr index in low-byte of setup->value
+			// If the string descr index in low-byte of setup->wValue
 			// is valid, send string descr, otherwise stall ep0.
-			strnum = le16_to_cpu(setup->value) & 0xff;
+			strnum = le16_to_cpu(setup->wValue) & 0xff;
 			if (strnum >= 0 && strnum < 6) {
 				struct usb_string_descriptor *desc =
-				    serial->str_desc[strnum];
+				dev->str_desc[strnum];
 				desc_len = desc_len > desc->bLength ?
 					desc->bLength : desc_len;
 				dbg("sending string desc %d", strnum);
-				send_packet(&serial->ep_ctrl, (u8 *) desc,
-					    desc_len, 0);
+			send_packet(dev,
+				    alloc_packet(&dev->ep[0], desc_len,
+						 desc), 0);
 			} else
-				endpoint_stall(&serial->ep_ctrl);
+			endpoint_stall(&dev->ep[0]);
 			break;
-		default:	// Invalid request
-			dbg("invalid get desc=%d, stalled",
-			    le16_to_cpu(setup->value) >> 8);
-			endpoint_stall(&serial->ep_ctrl);	// Stall endpoint 0
+	default:
+		// Invalid request
+		err("invalid get desc=%d, stalled",
+			    le16_to_cpu(setup->wValue) >> 8);
+		endpoint_stall(&dev->ep[0]);	// Stall endpoint 0
 			break;
 		}
-		break;
-	case USB_REQ_SET_DESCRIPTOR:
-		// FIXME: anything to set here?
-		break;
-	case USB_REQ_GET_INTERFACE:
+
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_descriptor(struct usb_dev* dev, devrequest* setup)
+{
+	// TODO: implement
+	// there will be an OUT data stage (the descriptor to set)
+	return DATA_STAGE;
+}
+
+static ep0_stage_t
+do_get_configuration(struct usb_dev* dev, devrequest* setup)
+{
+	// send dev->configuration
+	dbg("sending config");
+	send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration),
+		    0);
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_configuration(struct usb_dev* dev, devrequest* setup)
+{
+	// set active config to low-byte of setup->wValue
+	dev->configuration = le16_to_cpu(setup->wValue) & 0xff;
+	dbg("set config, config=%d", dev->configuration);
+	if (!dev->configuration && dev->state > DEFAULT) {
+		dev->state = ADDRESS;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else if (dev->configuration == 1) {
+		dev->state = CONFIGURED;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else {
+		// FIXME: "respond with request error" - how?
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_interface(struct usb_dev* dev, devrequest* setup)
+{
 		// interface must be zero.
-		if ((le16_to_cpu(setup->index) & 0xff) ||
-		    serial->state == ADDRESS) {
+	if ((le16_to_cpu(setup->index) & 0xff) || dev->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
-		} else if (serial->state == CONFIGURED) {
-			// send serial->alternate_setting
+	} else if (dev->state == CONFIGURED) {
+		// send dev->alternate_setting
 			dbg("sending alt setting");
-			send_packet(&serial->ep_ctrl,
-				    &serial->alternate_setting, 1, 0);
+		send_packet(dev, alloc_packet(&dev->ep[0], 1,
+					      &dev->alternate_setting), 0);
 		}
-		break;
-	case USB_REQ_SET_INTERFACE:
-		if (serial->state == ADDRESS) {
+
+	return STATUS_STAGE;
+
+}
+
+static ep0_stage_t
+do_set_interface(struct usb_dev* dev, devrequest* setup)
+{
+	if (dev->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
-		} else if (serial->state == CONFIGURED) {
-			serial->interface = le16_to_cpu(setup->index) & 0xff;
-			serial->alternate_setting =
-			    le16_to_cpu(setup->value) & 0xff;
+	} else if (dev->state == CONFIGURED) {
+		dev->interface = le16_to_cpu(setup->index) & 0xff;
+		dev->alternate_setting =
+			    le16_to_cpu(setup->wValue) & 0xff;
 			// interface and alternate_setting must be zero
-			if (serial->interface || serial->alternate_setting) {
+		if (dev->interface || dev->alternate_setting) {
 				// FIXME: respond with "request error". how?
 			}
 		}
-		break;
-	case USB_REQ_SET_CONFIGURATION:
-		// set active config to low-byte of serial.value
-		serial->configuration = le16_to_cpu(setup->value) & 0xff;
-		dbg("set config, config=%d", serial->configuration);
-		if (!serial->configuration && serial->state > DEFAULT)
-			serial->state = ADDRESS;
-		else if (serial->configuration == 1)
-			serial->state = CONFIGURED;
-		else {
-			// FIXME: "respond with request error" - how?
-		}
-		break;
-	case USB_REQ_GET_CONFIGURATION:
-		// send serial->configuration
-		dbg("sending config");
-		send_packet(&serial->ep_ctrl, &serial->configuration, 1, 0);
-		break;
-	case USB_REQ_GET_STATUS:
-		// FIXME: looks like the h/w handles this one
-		switch (setup->requesttype) {
-		case 0x80:	// Device
-			// FIXME: send device status
-			break;
-		case 0x81:	// Interface
-			// FIXME: send interface status
-			break;
-		case 0x82:	// End Point
-			// FIXME: send endpoint status
-			break;
-		default:	// Invalid Command
-			endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
-			break;
-		}
-		break;
-	case USB_REQ_CLEAR_FEATURE:
-		switch (setup->requesttype) {
-		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 0xff) == 1)
-				serial->remote_wakeup_en = 0;
-			else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 0xff);
 
-				endpoint_unstall(ep);
-				endpoint_reset_datatoggle(ep);
-			} else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_synch_frame(struct usb_dev* dev, devrequest* setup)
+{
+	// TODO
+	return SETUP_STAGE;
+}
+
+typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev,
+				    devrequest* setup);
+
+
+/* Table of the standard device request handlers */
+static const req_method_t req_method[] = {
+	do_get_status,
+	do_clear_feature,
+	do_reserved,
+	do_set_feature,
+	do_reserved,
+	do_set_address,
+	do_get_descriptor,
+	do_set_descriptor,
+	do_get_configuration,
+	do_set_configuration,
+	do_get_interface,
+	do_set_interface,
+	do_synch_frame
+};
+
+
+// SETUP packet request dispatcher
+static void
+do_setup (struct usb_dev* dev, devrequest* setup)
+{
+	req_method_t m;
+
+	dbg(__FUNCTION__ ": req %d %s", setup->request,
+	    get_std_req_name(setup->request));
+
+	if ((setup->requesttype & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
+	    (setup->requesttype & USB_RECIP_MASK) != USB_RECIP_DEVICE) {
+		err(__FUNCTION__ ": invalid requesttype 0x%02x",
+		    setup->requesttype);
+		return;
 		}
-		break;
-	case USB_REQ_SET_FEATURE:
-		switch (setup->requesttype) {
-		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 0xff) == 1)
-				serial->remote_wakeup_en = 1;
+
+	if ((setup->requesttype & 0x80) == USB_DIR_OUT && setup->length)
+		dbg(__FUNCTION__ ": OUT phase! length=%d", setup->length);
+
+	if (setup->request < sizeof(req_method)/sizeof(req_method_t))
+		m = req_method[setup->request];
 			else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 0xff);
+		m = do_reserved;
 
-				endpoint_stall(ep);
-			} else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		}
-		break;
-	default:
-		endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
-		break;
-	}
+	dev->ep0_stage = (*m)(dev, setup);
 }
 
-
 /*
- * A complete packet (SETUP, DATA0, or DATA1) has been received
- * on the given endpoint's fifo.
+ * A SETUP, DATA0, or DATA1 packet has been received
+ * on the default control endpoint's fifo.
  */
 static void
-process_complete (struct usb_serial* serial, int fifo_num)
+process_ep0_receive (struct usb_dev* dev)
 {
-	endpoint_t *ep = fifonum_to_ep(serial, fifo_num);
-	struct usb_serial_port *port = NULL;
-	pkt_t *pkt = 0;
-	u32 cs;
+	endpoint_t *ep0 = &dev->ep[0];
+	usbdev_pkt_t *pkt;
 
-	cs = inl(ep->reg->ctrl_stat);
+	spin_lock(&ep0->lock);
 
-	switch (fifo_num) {
-	case 0:
-		spin_lock(&ep->lock);
 		// complete packet and prepare a new packet
-		receive_packet_complete(ep);
-
-		// Get it immediately from endpoint.
-		if (!(pkt = receive_packet(ep))) {
-			spin_unlock(&ep->lock);
+	pkt = receive_packet_complete(ep0);
+	if (!pkt) {
+		// FIXME: should  put a warn/err here.
+		spin_unlock(&ep0->lock);
 			return;
 		}
-	
-		// SETUP packet received ?
-		//if (cs & USBDEV_CS_SU) { FIXME: uncomment!
+
+	// unlink immediately from endpoint.
+	unlink_head(&ep0->outlist);
+
+	// override current stage if h/w says it's a setup packet
+	if (pkt->status & PKT_STATUS_SU)
+		dev->ep0_stage = SETUP_STAGE;
+
+	switch (dev->ep0_stage) {
+	case SETUP_STAGE:
+		vdbg("SU bit is %s in setup stage",
+		     (pkt->status & PKT_STATUS_SU) ? "set" : "not set");
+
 			if (pkt->size == sizeof(devrequest)) {
-				devrequest setup;
-			if ((cs & (USBDEV_CS_NAK | USBDEV_CS_ACK)) ==
-			    USBDEV_CS_ACK)
-					dbg("got SETUP");
+#ifdef VDEBUG
+			if (pkt->status & PKT_STATUS_ACK)
+				vdbg("received SETUP");
 				else
-					dbg("got NAK SETUP, cs=%08x", cs);
-			memcpy(&setup, pkt->bufptr, sizeof(devrequest));
-				process_setup(serial, &setup);
-			//} else  FIXME: uncomment!
-			//dbg(__FUNCTION__ ": wrong size SETUP received");
-		} else {
-			// DATAx packet received on endpoint 0
-			// FIXME: will need a state machine for control
-			// OUT transactions
-			dbg("got DATAx on EP0, size=%d, cs=%08x",
-			    pkt->size, cs);
+				vdbg("received NAK SETUP");
+#endif
+			do_setup(dev, (devrequest*)pkt->payload);
+		} else
+			err(__FUNCTION__ ": wrong size SETUP received");
+		break;
+	case DATA_STAGE:
+		/*
+		 * this setup has an OUT data stage. Of the standard
+		 * device requests, only set_descriptor has this stage,
+		 * so this packet is that descriptor. TODO: drop it for
+		 * now, set_descriptor not implemented.
+		 *
+		 * Need to place a byte in the write FIFO here, to prepare
+		 * to send a zero-length DATA ack packet to the host in the
+		 * STATUS stage.
+		 */
+		au_writel(0, ep0->reg->write_fifo);
+		dbg("received OUT stage DATAx on EP0, size=%d", pkt->size);
+		dev->ep0_stage = SETUP_STAGE;
+		break;
+	case STATUS_STAGE:
+		// this setup had an IN data stage, and host is ACK'ing
+		// the packet we sent during that stage.
+		if (pkt->size != 0)
+			warn("received non-zero ACK on EP0??");
+#ifdef VDEBUG
+		else
+			vdbg("received ACK on EP0");
+#endif
+		dev->ep0_stage = SETUP_STAGE;
+		break;
 		}
 
-		spin_unlock(&ep->lock);
+	spin_unlock(&ep0->lock);
 		// we're done processing the packet, free it
 		kfree(pkt);
-		break;
+}
+
+
+/*
+ * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5)
+ */
+static void
+process_ep_receive (struct usb_dev* dev, endpoint_t *ep)
+{
+	usbdev_pkt_t *pkt;
 
-	case 4:
-	case 5:
-		port = fifonum_to_port(serial, fifo_num);
-		dbg("got DATAx on port %d, cs=%08x", port->number, cs);
 		spin_lock(&ep->lock);
-		receive_packet_complete(ep);
+	pkt = receive_packet_complete(ep);
 		spin_unlock(&ep->lock);
-		// mark a bh to push this data up to the tty
-		queue_task(&port->receive_complete_tq, &tq_immediate);
-		mark_bh(IMMEDIATE_BH);
-		break;
 
-	default:
-		break;
-	}
+	dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data);
 }
 
 
 
-// This ISR needs to ack both the complete and suspend events
+/* This ISR handles the receive complete and suspend events */
 static void
 req_sus_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct usb_serial *serial = (struct usb_serial *) dev_id;
-	int i;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
 	u32 status;
 
-	status = inl(USB_DEV_INT_STATUS);
-	outl_sync(status, USB_DEV_INT_STATUS);	// ack'em
+	status = au_readl(USBD_INTSTAT);
+	au_writel(status, USBD_INTSTAT);	// ack'em
 
-#ifdef USBDEV_PIO
-	for (i = 0; i < 6; i++) {
-		if (status & (1 << (USBDEV_INT_HF_BIT + i))) {
-			endpoint_t *ep = fifonum_to_ep(serial, i);
-
-			if (ep->desc->bEndpointAddress & USB_DIR_IN)
-				endpoint_fifo_write(ep);
-			else
-				endpoint_fifo_read(ep);
-		}
-	}
-#endif
-
-	for (i = 0; i < 6; i++) {
-		if (status & (1 << i))
-			process_complete(serial, i);
-	}
+	if (status & (1<<0))
+		process_ep0_receive(dev);
+	if (status & (1<<4))
+		process_ep_receive(dev, &dev->ep[4]);
+	if (status & (1<<5))
+		process_ep_receive(dev, &dev->ep[5]);
 }
 
 
+/* This ISR handles the DMA done events on EP0 */
 static void
-dma_done_ctrl(struct usb_serial* serial)
+dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	endpoint_t *ep = &serial->ep_ctrl;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	usbdev_pkt_t* pkt;
+	endpoint_t *ep0 = &dev->ep[0];
 	u32 cs0, buff_done;
 
-	spin_lock(&ep->lock);
-	cs0 = inl(ep->reg->ctrl_stat);
+	spin_lock(&ep0->lock);
+	cs0 = au_readl(ep0->reg->ctrl_stat);
 
 	// first check packet transmit done
-	if ((buff_done = get_dma_buffer_done(ep->indma)) != 0) {
-		// transmitted a DATAx packet on control endpoint 0
+	if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) {
+		// transmitted a DATAx packet during DATA stage
+		// on control endpoint 0
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
-			clear_dma_done0(ep->indma);
-		else
-			clear_dma_done1(ep->indma);
-
-		send_packet_complete(ep);
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->indma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->indma);
+
+		pkt = send_packet_complete(ep0);
+		if (pkt)
+			kfree(pkt);
 	}
 
 	/*
@@ -1200,645 +1086,477 @@
 	 * the receive packet complete intr should happen
 	 * before the DMA done intr occurs.
 	 */
-	if ((buff_done = get_dma_buffer_done(ep->outdma)) != 0) {
+	if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) {
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
-			clear_dma_done0(ep->outdma);
-		else
-			clear_dma_done1(ep->outdma);
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->outdma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->outdma);
+
+		//process_ep0_receive(dev);
 	}
 
-	spin_unlock(&ep->lock);
+	spin_unlock(&ep0->lock);
 }
 
+/* This ISR handles the DMA done events on endpoints 2,3,4,5 */
 static void
-dma_done_port(struct usb_serial_port * port)
+dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	endpoint_t *ep;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	int i;
+
+	for (i = 2; i < 6; i++) {
 	u32 buff_done;
+		usbdev_pkt_t* pkt;
+		endpoint_t *ep = &dev->ep[i];
+
+		if (!ep->active) continue;
 
-	// first check packet transmit done (bulk IN ep)
-	ep = &port->ep_bulkin;
 	spin_lock(&ep->lock);
-	if ((buff_done = get_dma_buffer_done(ep->indma)) != 0) {
-		// transmitted a DATAx packet on the port's bulk IN endpoint
+
+		if (ep->direction == USB_DIR_IN) {
+			buff_done = get_dma_buffer_done(ep->indma);
+			if (buff_done != 0) {
+				// transmitted a DATAx pkt on the IN ep
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
+		if (buff_done & DMA_D0)
 			clear_dma_done0(ep->indma);
-		else
+		if (buff_done & DMA_D1)
 			clear_dma_done1(ep->indma);
 
-		send_packet_complete(ep);
-		// mark a bh to wakeup any tty write system call on the port.
-		queue_task(&port->send_complete_tq, &tq_immediate);
-		mark_bh(IMMEDIATE_BH);
-	}
-	spin_unlock(&ep->lock);
+				pkt = send_packet_complete(ep);
 
+				spin_unlock(&ep->lock);
+				dev->func_cb(CB_PKT_COMPLETE,
+					     (unsigned long)pkt,
+					     dev->cb_data);
+				spin_lock(&ep->lock);
+			}
+		} else {
 	/*
-	 * Now check packet receive done (bulk OUT ep). Shouldn't
-	 * get these, the receive packet complete intr should happen
+			 * Check packet receive done (OUT ep). Shouldn't get
+			 * these, the rx packet complete intr should happen
 	 * before the DMA done intr occurs.
 	 */
-	ep = &port->ep_bulkout;
-	spin_lock(&ep->lock);
-	if ((buff_done = get_dma_buffer_done(ep->outdma)) != 0) {
-		// received a DATAx packet on the port's bulk OUT endpoint
+			buff_done = get_dma_buffer_done(ep->outdma);
+			if (buff_done != 0) {
+				// received a DATAx pkt on the OUT ep
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
+		if (buff_done & DMA_D0)
 			clear_dma_done0(ep->outdma);
-		else
+		if (buff_done & DMA_D1)
 			clear_dma_done1(ep->outdma);
-	}
-	spin_unlock(&ep->lock);
-}
-
-
-// This ISR needs to handle dma done events for ALL endpoints!
-static void
-dma_done_intr (int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct usb_serial *serial = (struct usb_serial *) dev_id;
-	int i;
-
-	dma_done_ctrl(serial);
-	for (i = 0; i < NUM_PORTS; i++)
-		dma_done_port(&serial->port[i]);
-}
-
-
-
-/*****************************************************************************
- * Here begins the tty driver interface functions
- *****************************************************************************/
-
-static int serial_open(struct tty_struct *tty, struct file *filp)
-{
-	int portNumber;
-	struct usb_serial_port *port;
-	struct usb_serial *serial = &usbserial;
-	unsigned long flags;
-
-	/* initialize the pointer incase something fails */
-	tty->driver_data = NULL;
-
-	MOD_INC_USE_COUNT;
-
-	/* set up our port structure making the tty driver remember
-	   our port object, and us it */
-	portNumber = MINOR(tty->device) - serial->minor;
-	port = &serial->port[portNumber];
-	tty->driver_data = port;
-	port->tty = tty;
-
-	if (port_paranoia_check(port, __FUNCTION__))
-		return -ENODEV;
-
-	dbg(__FUNCTION__ " - port %d", port->number);
-
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	++port->open_count;
-
-	if (!port->active) {
-		port->active = 1;
-
-		/*
-		 * force low_latency on so that our tty_push actually forces
-		 * the data through, otherwise it is scheduled, and with high
-		 * data rates (like with OHCI) data can get lost.
-		 */
-		port->tty->low_latency = 1;
 
+				//process_ep_receive(dev, ep);
 	}
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-
-	return 0;
-}
-
-
-static void serial_close(struct tty_struct *tty, struct file *filp)
-{
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	unsigned long flags;
-
-	if (!serial)
-		return;
-
-	dbg(__FUNCTION__ " - port %d", port->number);
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not opened");
-		return;
 	}
 
-	spin_lock_irqsave(&port->port_lock, flags);
-
-	--port->open_count;
-
-	if (port->open_count <= 0) {
-		port->active = 0;
-		port->open_count = 0;
+		spin_unlock(&ep->lock);
 	}
-
-	spin_unlock_irqrestore(&port->port_lock, flags);
-	MOD_DEC_USE_COUNT;
 }
 
 
-static int serial_write(struct tty_struct *tty, int from_user,
-			const unsigned char *buf, int count)
+/***************************************************************************
+ * Here begins the external interface functions
+ ***************************************************************************
+ */
+
+/*
+ * allocate a new packet
+ */
+int
+usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt)
 {
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	endpoint_t *ep = &port->ep_bulkin;
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
+	usbdev_pkt_t* lpkt = NULL;
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not opened");
+	if (data_size > ep->max_pkt_size)
 		return -EINVAL;
-	}
-
-	if (count == 0) {
-		dbg(__FUNCTION__ " - write request of 0 bytes");
-		return (0);
-	}
 
-	count = (count > ep->max_pkt_size) ? ep->max_pkt_size : count;
-	send_packet(ep, (u8 *) buf, count, from_user);
-
-	return (count);
+	lpkt = *pkt = alloc_packet(ep, data_size, NULL);
+	if (!lpkt)
+		return -ENOMEM;
+	return 0;
 }
 
 
-static int serial_write_room(struct tty_struct *tty)
+/*
+ * packet send
+ */
+int
+usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt)
 {
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	endpoint_t *ep = &port->ep_bulkin;
+	unsigned long flags;
+	int count;
+	endpoint_t * ep;
 
-	if (!serial)
+	if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) ||
+	    !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
+	if (ep->direction != USB_DIR_IN)
 		return -EINVAL;
-	}
 
-	return ep->max_pkt_size;
-}
+	spin_lock_irqsave(&ep->lock, flags);
+	count = send_packet(&usbdev, pkt, 1);
+	spin_unlock_irqrestore(&ep->lock, flags);
 
+	return count;
+}
 
-static int serial_chars_in_buffer(struct tty_struct *tty)
+/*
+ * packet receive
+ */
+int
+usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt)
 {
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	endpoint_t *ep = &port->ep_bulkin;
-	pkt_list_t *list = &ep->inlist;
-	pkt_t *scan;
 	unsigned long flags;
-	int chars = 0;
+	usbdev_pkt_t* lpkt = NULL;
+	endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr);
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
+	if (ep->direction != USB_DIR_OUT)
 		return -EINVAL;
-	}
 
 	spin_lock_irqsave(&ep->lock, flags);
-	for (scan = list->head; scan; scan = scan->next)
-		chars += scan->size;
+	if (ep->outlist.count > 1)
+		lpkt = unlink_head(&ep->outlist);
 	spin_unlock_irqrestore(&ep->lock, flags);
 
-	return (chars);
-}
-
-
-static void serial_throttle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-
-	if (!serial)
-		return;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return;
+	if (!lpkt) {
+		/* no packet available */
+		*pkt = NULL;
+		return -ENODATA;
 	}
-	// FIXME: anything to do?
-}
-
-
-static void serial_unthrottle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
 
-	if (!serial)
-		return;
+	*pkt = lpkt;
 
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return;
-	}
-	// FIXME: anything to do?
+	return lpkt->size;
 }
 
 
-static int serial_ioctl(struct tty_struct *tty, struct file *file,
-			unsigned int cmd, unsigned long arg)
+/*
+ * return total queued byte count on the endpoint.
+ */
+int
+usbdev_get_byte_count(int ep_addr)
 {
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+        unsigned long flags;
+        pkt_list_t *list;
+        usbdev_pkt_t *scan;
+        int count = 0;
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		return -ENODEV;
 
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return -ENODEV;
-	}
-	// FIXME: need any IOCTLs?
-
-	return -ENOIOCTLCMD;
-}
-
-
-static void serial_set_termios(struct tty_struct *tty, struct termios *old)
-{
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-
-	if (!serial)
-		return;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return;
-	}
-	// FIXME: anything to do?
-}
-
+	if (ep->direction == USB_DIR_IN) {
+		list = &ep->inlist;
 
-static void serial_break(struct tty_struct *tty, int break_state)
-{
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-
-	if (!serial)
-		return;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return;
-	}
-	// FIXME: anything to do?
-}
-
-
-static void port_send_complete(void *private)
-{
-	struct usb_serial_port *port = (struct usb_serial_port *) private;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	struct tty_struct *tty;
-
-	dbg(__FUNCTION__ " - port %d", port->number);
-
-	if (!serial) {
-		return;
-	}
+		spin_lock_irqsave(&ep->lock, flags);
+		for (scan = list->head; scan; scan = scan->next)
+			count += scan->size;
+		spin_unlock_irqrestore(&ep->lock, flags);
+	} else {
+		list = &ep->outlist;
 
-	tty = port->tty;
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup) {
-		dbg(__FUNCTION__ " - write wakeup call.");
-		(tty->ldisc.write_wakeup) (tty);
+		spin_lock_irqsave(&ep->lock, flags);
+		if (list->count > 1) {
+			for (scan = list->head; scan != list->tail;
+			     scan = scan->next)
+				count += scan->size;
 	}
-
-	wake_up_interruptible(&tty->write_wait);
-}
-
-
-static void port_receive_complete(void *private)
-{
-	struct usb_serial_port *port = (struct usb_serial_port *) private;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
-	struct tty_struct *tty = port->tty;
-	pkt_t *pkt;
-	int i;
-
-	dbg(__FUNCTION__ " - port %d", port->number);
-
-	if (!serial) {
-		return;
+		spin_unlock_irqrestore(&ep->lock, flags);
 	}
 
-	if (!(pkt = receive_packet(&port->ep_bulkout)))
-		return;
-
-	for (i = 0; i < pkt->size; i++) {
-		/* if we insert more than TTY_FLIPBUF_SIZE characters,
-		   we drop them. */
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			tty_flip_buffer_push(tty);
-		}
-		/* this doesn't actually push the data through
-		   unless tty->low_latency is set */
-		tty_insert_flip_char(tty, pkt->bufptr[i], 0);
-	}
-	tty_flip_buffer_push(tty);
-
-	// we're done processing the packet, free it
-	kfree(pkt);
+	return count;
 }
 
 
-static struct tty_driver serial_tty_driver = {
-	magic:TTY_DRIVER_MAGIC,
-	driver_name:"usbdev-serial",
-	name:"usb/ttsdev/%d",
-	major:SERIAL_TTY_MAJOR,
-	minor_start:0,
-	num:1,
-	type:TTY_DRIVER_TYPE_SERIAL,
-	subtype:SERIAL_TYPE_NORMAL,
-	flags:TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
-	refcount:&serial_refcount,
-	table:serial_tty,
-	termios:serial_termios,
-	termios_locked:serial_termios_locked,
-
-	open:serial_open,
-	close:serial_close,
-	write:serial_write,
-	write_room:serial_write_room,
-	ioctl:serial_ioctl,
-	set_termios:serial_set_termios,
-	throttle:serial_throttle,
-	unthrottle:serial_unthrottle,
-	break_ctl:serial_break,
-	chars_in_buffer:serial_chars_in_buffer,
-};
-
-
-void usbdev_serial_exit(void)
+void
+usbdev_exit(void)
 {
 	endpoint_t *ep;
 	int i;
 
-	outl_sync(0, USB_DEV_INT_ENABLE);	// disable usb dev ints
-	outl_sync(0, USB_DEV_ENABLE);	// disable usb dev
+	au_writel(0, USBD_INTEN);	// disable usb dev ints
+	au_writel(0, USBD_ENABLE);	// disable usb dev
 
-	// first free all control endpoint resources
-	ep = &usbserial.ep_ctrl;
-	free_irq(AU1000_USB_DEV_REQ_INT, &usbserial);
-	free_irq(AU1000_USB_DEV_SUS_INT, &usbserial);
-	free_irq(ep->inirq, &usbserial);
-	//free_irq(ep->outirq, &usbserial);
+	free_irq(AU1000_USB_DEV_REQ_INT, &usbdev);
+	free_irq(AU1000_USB_DEV_SUS_INT, &usbdev);
+
+	// free all control endpoint resources
+	ep = &usbdev.ep[0];
 	free_au1000_dma(ep->indma);
 	free_au1000_dma(ep->outdma);
 	endpoint_flush(ep);
 
-	// now free all port resources
-	for (i = 0; i < NUM_PORTS; i++) {
-		// free port's bulk IN endpoint resources
-		ep = &usbserial.port[i].ep_bulkin;
-		free_irq(ep->inirq, &usbserial);
-		free_au1000_dma(ep->indma);
-		endpoint_flush(ep);
+	// free ep resources
+	for (i = 2; i < 6; i++) {
+		ep = &usbdev.ep[i];
+		if (!ep->active) continue;
 
-		// free port's bulk OUT endpoint resources
-		ep = &usbserial.port[i].ep_bulkout;
-		//free_irq(ep->outirq, &usbserial);
+		if (ep->direction == USB_DIR_IN) {
+			free_au1000_dma(ep->indma);
+		} else {
 		free_au1000_dma(ep->outdma);
+		}
 		endpoint_flush(ep);
-
-		tty_unregister_devfs(&serial_tty_driver, i);
-		info("usbdev serial converter now disconnected from ttyUSBdev%d",
-		     i);
 	}
 
-	kfree(usbserial.str_desc[0]);
-	tty_unregister_driver(&serial_tty_driver);
+	if (usbdev.full_conf_desc)
+		kfree(usbdev.full_conf_desc);
 }
 
-int usbdev_serial_init(void)
-{
-	struct usb_serial_port *port;
+int
+usbdev_init(struct usb_device_descriptor* dev_desc,
+	    struct usb_config_descriptor* config_desc,
+	    struct usb_interface_descriptor* if_desc,
+	    struct usb_endpoint_descriptor* ep_desc,
+	    struct usb_string_descriptor* str_desc[],
+	    void (*cb)(usbdev_cb_type_t, unsigned long, void *),
+	    void* cb_data)
+{
+	endpoint_t *ep0;
+	int i, ret=0;
+	u8* fcd;
+
+	if (dev_desc->bNumConfigurations > 1 ||
+	    config_desc->bNumInterfaces > 1 ||
+	    if_desc->bNumEndpoints > 4) {
+		err("Only one config, one i/f, and no more "
+		    "than 4 ep's allowed");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!cb) {
+		err("Function-layer callback required");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) {
+		warn("EP0 Max Packet size must be %d",
+		     USBDEV_EP0_MAX_PACKET_SIZE);
+		dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE;
+	}
+
+	memset(&usbdev, 0, sizeof(struct usb_dev));
+
+	usbdev.state = DEFAULT;
+	usbdev.dev_desc = dev_desc;
+	usbdev.if_desc = if_desc;
+	usbdev.conf_desc = config_desc;
+	for (i=0; i<6; i++)
+		usbdev.str_desc[i] = str_desc[i];
+	usbdev.func_cb = cb;
+	usbdev.cb_data = cb_data;
+
+	/* Initialize default control endpoint */
+	ep0 = &usbdev.ep[0];
+	ep0->active = 1;
+	ep0->type = CONTROL_EP;
+	ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE;
+	spin_lock_init(&ep0->lock);
+	ep0->desc = NULL;	// ep0 has no descriptor
+	ep0->address = 0;
+	ep0->direction = 0;
+	ep0->reg = &ep_reg[0];
+
+	/* Initialize the other requested endpoints */
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		struct usb_endpoint_descriptor* epd = &ep_desc[i];
 	endpoint_t *ep;
-	void *str_desc_buf;
-	int str_desc_len;
-	int i;
 
-	/* register the tty driver */
-	serial_tty_driver.init_termios = tty_std_termios;
-	serial_tty_driver.init_termios.c_cflag =
-	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-
-	if (tty_register_driver(&serial_tty_driver)) {
-		err(__FUNCTION__ ": failed to register tty driver");
-		return -1;
+		if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) {
+			ep = &usbdev.ep[2];
+			ep->address = 2;
+			if (ep->active) {
+				ep = &usbdev.ep[3];
+				ep->address = 3;
+				if (ep->active) {
+					err("too many IN ep's requested");
+					ret = -ENODEV;
+					goto out;
 	}
-
-	memset(&usbserial, 0, sizeof(struct usb_serial));
-	usbserial.minor = 0;
-
-	usbserial.state = DEFAULT;
-
-	usbserial.dev_desc = &dev_desc;
-	usbserial.if_desc = &if_desc;
-	usbserial.conf_desc = &config_desc;
-
-	/*
-	 * initialize the string descriptors
-	 */
-
-	/* alloc buffer big enough for all string descriptors */
-	str_desc_len = string_desc0.bLength;
-	for (i = 0; i < 5; i++)
-		str_desc_len += 2 + 2 * strlen(strings[i]);
-	str_desc_buf = (void *) kmalloc(str_desc_len, ALLOC_FLAGS);
-	if (!str_desc_buf) {
-		err(__FUNCTION__ ": failed to alloc string descriptors");
-		return -1;
-	}
-
-	usbserial.str_desc[0] = (struct usb_string_descriptor *)str_desc_buf;
-	memcpy(usbserial.str_desc[0], &string_desc0, string_desc0.bLength);
-	usbserial.str_desc[1] = (struct usb_string_descriptor *)
-	    (str_desc_buf + string_desc0.bLength);
-	for (i = 1; i < 6; i++) {
-		struct usb_string_descriptor *desc = usbserial.str_desc[i];
-		char *str = strings[i - 1];
-		int j, str_len = strlen(str);
-
-		desc->bLength = 2 + 2 * str_len;
-		desc->bDescriptorType = USB_DT_STRING;
-		for (j = 0; j < str_len; j++) {
-			desc->wData[j] = (u16) str[j];
-		}
-		if (i < 5)
-			usbserial.str_desc[i + 1] =
-			    (struct usb_string_descriptor *)
-			    ((u8 *) desc + desc->bLength);
-	}
-
-	// request the USB device transfer complete interrupt
-	if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_SHIRQ,
-			"USBdev req", &usbserial)) {
-		err("Can't get device request intr\n");
-		goto err_out;
-	}
-	// request the USB device suspend interrupt
-	if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_SHIRQ,
-			"USBdev sus", &usbserial)) {
-		err("Can't get device suspend intr\n");
-		goto err_out;
-	}
-
-	// Initialize default control endpoint
-	ep = &usbserial.ep_ctrl;
-	spin_lock_init(&ep->lock);
-	ep->desc = NULL;	// ep0 has no ep descriptor
-	ep->reg = &ep_reg[0];
-	ep->max_pkt_size = usbserial.dev_desc->bMaxPacketSize0;
-	ep->indma = ep->outdma = -1;
-	if ((ep->indma = request_au1000_dma(ep_dma_id[0].id,
-					    ep_dma_id[0].str)) < 0) {
-		err("Can't get %s DMA\n", ep_dma_id[0].str);
-		goto err_out;
-	}
-	if ((ep->outdma = request_au1000_dma(ep_dma_id[1].id,
-					     ep_dma_id[1].str)) < 0) {
-		err("Can't get %s DMA\n", ep_dma_id[1].str);
-		goto err_out;
-	}
-	ep->inirq = get_dma_done_irq(ep->indma);
-	ep->outirq = get_dma_done_irq(ep->outdma);
-	// allocate EP0's DMA done interrupts.
-	if (request_irq(ep->inirq, dma_done_intr, SA_INTERRUPT,
-			"USBdev ep0 IN", &usbserial)) {
-		err("Can't get ep0 IN dma done irq\n");
-		goto err_out;
 	}
-#if 0
-	if (request_irq(ep->outirq, dma_done_intr, SA_INTERRUPT,
-			"USBdev ep0 OUT", &usbserial)) {
-		err("Can't get ep0 OUT dma done irq\n");
-		goto err_out;
+		} else {
+			ep = &usbdev.ep[4];
+			ep->address = 4;
+			if (ep->active) {
+				ep = &usbdev.ep[5];
+				ep->address = 5;
+				if (ep->active) {
+					err("too many OUT ep's requested");
+					ret = -ENODEV;
+					goto out;
+	}
 	}
-#endif
-
-	/* initialize the devfs nodes for this device and let the user
-	   know what ports we are bound to */
-	for (i = 0; i < NUM_PORTS; ++i) {
-		tty_register_devfs(&serial_tty_driver, 0, i);
-		info("usbdev serial attached to ttyUSBdev%d (or devfs usb/ttsdev/%d)", 
-		     i, i);
-		port = &usbserial.port[i];
-		port->serial = &usbserial;
-		port->number = i;
-		port->send_complete_tq.routine = port_send_complete;
-		port->send_complete_tq.data = port;
-		port->receive_complete_tq.routine = port_receive_complete;
-		port->receive_complete_tq.data = port;
-		spin_lock_init(&port->port_lock);
-
-		// Initialize the port's bulk IN endpoint
-		ep = &port->ep_bulkin;
-		spin_lock_init(&ep->lock);
-		ep->desc = &ep_desc[NUM_PORTS * i];
-		ep->reg = &ep_reg[1 + NUM_PORTS * i];
-		ep->max_pkt_size = ep->desc->wMaxPacketSize;
-		ep->indma = ep->outdma = -1;
-		if ((ep->indma =
-		     request_au1000_dma(ep_dma_id[2+NUM_PORTS*i].id,
-				 ep_dma_id[2 + NUM_PORTS * i].str)) < 0) {
-			err("Can't get %s DMA\n",
-			    ep_dma_id[2 + NUM_PORTS * i].str);
-			goto err_out;
-		}
-		ep->inirq = get_dma_done_irq(ep->indma);
-		if (request_irq(ep->inirq, dma_done_intr, SA_INTERRUPT,
-				"USBdev bulk IN", &usbserial)) {
-			err("Can't get port %d bulk IN dma done irq\n", i);
-			goto err_out;
 		}
-		// Initialize the port's bulk OUT endpoint
-		ep = &port->ep_bulkout;
+
+		ep->active = 1;
+		epd->bEndpointAddress &= ~0x0f;
+		epd->bEndpointAddress |= (u8)ep->address;
+		ep->direction = epd->bEndpointAddress & 0x80;
+		ep->type = epd->bmAttributes & 0x03;
+		ep->max_pkt_size = epd->wMaxPacketSize;
 		spin_lock_init(&ep->lock);
-		ep->desc = &ep_desc[NUM_PORTS * i + 1];
-		ep->reg = &ep_reg[1 + NUM_PORTS * i + 1];
-		ep->max_pkt_size = ep->desc->wMaxPacketSize;
-		ep->indma = ep->outdma = -1;
-		if ((ep->outdma =
-		     request_au1000_dma(ep_dma_id[2+NUM_PORTS*i + 1].id,
-					ep_dma_id[2+NUM_PORTS*i + 1].str)) < 0) {
-			err("Can't get %s DMA\n",
-			    ep_dma_id[2 + NUM_PORTS * i + 1].str);
-			goto err_out;
+		ep->desc = epd;
+		ep->reg = &ep_reg[ep->address];
 		}
-		ep->outirq = get_dma_done_irq(ep->outdma);
-#if 0
-		if (request_irq(ep->outirq, dma_done_intr, SA_INTERRUPT,
-				"USBdev bulk OUT", &usbserial)) {
-			err("Can't get port %d bulk OUT dma done irq\n", i);
-			goto err_out;
-		}
-#endif
+
+	/*
+	 * initialize the full config descriptor
+	 */
+	usbdev.full_conf_desc = fcd = kmalloc(config_desc->wTotalLength,
+					      ALLOC_FLAGS);
+	if (!fcd) {
+		err("failed to alloc full config descriptor");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE);
+	fcd += USB_DT_CONFIG_SIZE;
+	memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE);
+	fcd += USB_DT_INTERFACE_SIZE;
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE);
+		fcd += USB_DT_ENDPOINT_SIZE;
 	}
 
-	// enable device controller
-	outl_sync(0x0002, USB_DEV_ENABLE);
+	/* Now we're ready to enable the controller */
+	au_writel(0x0002, USBD_ENABLE);
 	udelay(100);
-	outl_sync(0x0003, USB_DEV_ENABLE);
+	au_writel(0x0003, USBD_ENABLE);
 	udelay(100);
-	for (i = 0; i < sizeof(au1000_config_table) / sizeof(u32); ++i)
-		outl_sync(au1000_config_table[i], USB_DEV_CONFIG);
-
-	// Flush the endpoint buffers and FIFOs
-	ep = &usbserial.ep_ctrl;
-	endpoint_flush(ep);
-	// start packet reception on control ep
-	kickstart_receive_packet(ep);
 
-	for (i = 0; i < NUM_PORTS; ++i) {
-		struct usb_serial_port *port = &usbserial.port[i];
-		endpoint_flush(&port->ep_bulkin);
-		endpoint_flush(&port->ep_bulkout);
-		// start packet reception on bulk OUT endpoint
-		kickstart_receive_packet(&port->ep_bulkout);
+	/* build and send config table based on ep descriptors */
+	for (i = 0; i < 6; i++) {
+		endpoint_t *ep;
+		if (i == 1)
+			continue; // skip dummy ep
+		ep = &usbdev.ep[i];
+		if (ep->active) {
+			au_writel((ep->address << 4) | 0x04, USBD_CONFIG);
+			au_writel(((ep->max_pkt_size & 0x380) >> 7) |
+				  (ep->direction >> 4) | (ep->type << 4),
+				  USBD_CONFIG);
+			au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(ep->address, USBD_CONFIG);
+		} else {
+			u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT;
+			au_writel((i << 4) | 0x04, USBD_CONFIG);
+			au_writel(((16 & 0x380) >> 7) | dir |
+				  (BULK_EP << 4), USBD_CONFIG);
+			au_writel((16 & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(i, USBD_CONFIG);
+		}
 	}
 
 	/*
 	 * Enable Receive FIFO Complete interrupts only. Transmit
 	 * complete is being handled by the DMA done interrupts.
 	 */
-	outl_sync(0x31, USB_DEV_INT_ENABLE);
+	au_writel(0x31, USBD_INTEN);
 
-	return 0;
+	/*
+	 * Controller is now enabled, request DMA and IRQ
+	 * resources.
+	 */
 
-      err_out:
-	usbdev_serial_exit();
-	return -1;
-}
+	/* request the USB device transfer complete interrupt */
+	if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev req", &usbdev)) {
+		err("Can't get device request intr");
+		ret = -ENXIO;
+		goto out;
+	}
+	/* request the USB device suspend interrupt */
+	if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev sus", &usbdev)) {
+		err("Can't get device suspend intr");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	/* Request EP0 DMA and IRQ */
+	if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id,
+					     ep_dma_id[0].str,
+					     dma_done_ep0_intr,
+					     SA_INTERRUPT,
+					     &usbdev)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[0].str);
+		ret = -ENXIO;
+		goto out;
+	}
+	if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id,
+					      ep_dma_id[1].str,
+					      NULL, 0, NULL)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[1].str);
+		ret = -ENXIO;
+		goto out;
+	}
+
+	// Flush the ep0 buffers and FIFOs
+	endpoint_flush(ep0);
+	// start packet reception on ep0
+	kickstart_receive_packet(ep0);
+
+	/* Request DMA and IRQ for the other endpoints */
+	for (i = 2; i < 6; i++) {
+		endpoint_t *ep = &usbdev.ep[i];
+		if (!ep->active)
+			continue;
+
+		// Flush the endpoint buffers and FIFOs
+		endpoint_flush(ep);
 
+		if (ep->direction == USB_DIR_IN) {
+			ep->indma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   dma_done_ep_intr,
+						   SA_INTERRUPT,
+						   &usbdev);
+			if (ep->indma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+		} else {
+			ep->outdma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   NULL, 0, NULL);
+			if (ep->outdma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+
+			// start packet reception on OUT endpoint
+			kickstart_receive_packet(ep);
+		}
+	}
+
+ out:
+	if (ret)
+		usbdev_exit();
+	return ret;
+}
 
-module_init(usbdev_serial_init);
-module_exit(usbdev_serial_exit);
+EXPORT_SYMBOL(usbdev_init);
+EXPORT_SYMBOL(usbdev_exit);
+EXPORT_SYMBOL(usbdev_alloc_packet);
+EXPORT_SYMBOL(usbdev_receive_packet);
+EXPORT_SYMBOL(usbdev_send_packet);
+EXPORT_SYMBOL(usbdev_get_byte_count);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/Makefile linux-2.4.20/arch/mips/au1000/pb1000/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1000/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1000/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -10,10 +10,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := pb1000.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/init.c linux-2.4.20/arch/mips/au1000/pb1000/init.c
--- linux-2.4.19/arch/mips/au1000/pb1000/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1000/init.c	2002-10-04 00:41:14.000000000 +0000
@@ -34,7 +34,6 @@
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -59,7 +58,7 @@
 	prom_envp = envp;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
-	mips_machtype = MACH_PB1000;  
+	mips_machtype = MACH_PB1000;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/pci_fixup.c linux-2.4.20/arch/mips/au1000/pb1000/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1000/pci_fixup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1000/pci_fixup.c	2002-10-04 00:41:29.000000000 +0000
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 void __init pcibios_fixup_resources(struct pci_dev *dev)
@@ -54,15 +54,15 @@
 {
 	unsigned long pci_mem_start = (unsigned long) PCI_MEM_START;
 
-	writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
-	writel(0, SDRAM_MBAR);        // set mbar to 0
-	writel(0x2, SDRAM_CMD);       // enable memory accesses
+	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
 	au_sync_delay(1);
 
 	// set extend byte to mbar of ext slot
-	writel(((pci_mem_start >> 24) & 0xff) |
+	au_writel(((pci_mem_start >> 24) & 0xff) |
 	       (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG);
-	DBG("Set bridge config to %x\n", readl(PCI_BRIDGE_CONFIG));
+	DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG));
 }
 
 void __init pcibios_fixup_irqs(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/pci_ops.c linux-2.4.20/arch/mips/au1000/pb1000/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1000/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1000/pci_ops.c	2002-10-04 00:41:14.000000000 +0000
@@ -46,18 +46,18 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 static struct resource pci_io_resource = {
-	"pci IO space", 
+	"pci IO space",
 	PCI_IO_START,
 	PCI_IO_END,
 	IORESOURCE_IO
 };
 
 static struct resource pci_mem_resource = {
-	"pci memory space", 
+	"pci memory space",
 	PCI_MEM_START,
 	PCI_MEM_END,
 	IORESOURCE_MEM
@@ -74,10 +74,10 @@
 
 /*
  * "Bus 2" is really the first and only external slot on the pb1000.
- * We'll call that bus 0, and limit the accesses to that single 
+ * We'll call that bus 0, and limit the accesses to that single
  * external slot only. The SDRAM is already initialized in setup.c.
  */
-static int config_access(unsigned char access_type, struct pci_dev *dev, 
+static int config_access(unsigned char access_type, struct pci_dev *dev,
 			 unsigned char where, u32 * data)
 {
 	unsigned char bus = dev->bus->number;
@@ -92,18 +92,18 @@
 	config = PCI_CONFIG_BASE | (where & ~0x3);
 
 	if (access_type == PCI_ACCESS_WRITE) {
-		outl(*data, config);
+		au_writel(*data, config);
 	} else {
-		*data = inl(config);
+		*data = au_readl(config);
 	}
 	au_sync_udelay(1);
 
-	DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", 
+	DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n",
 			access_type, bus, dev_fn, where, *data, config);
 
-	DBG("bridge config reg: %x (%x)\n", inl(PCI_BRIDGE_CONFIG), *data);
+	DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data);
 
-	if (inl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
+	if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
 		*data = 0xffffffff;
 		return -1;
 	} else {
@@ -119,7 +119,7 @@
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
 	*val = data & 0xff;
-	return ret; 
+	return ret;
 }
 
 
@@ -130,7 +130,7 @@
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
 	*val = data & 0xffff;
-	return ret; 
+	return ret;
 }
 
 static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
@@ -138,14 +138,14 @@
 	int ret;
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, val);
-	return ret; 
+	return ret;
 }
 
 
 static int write_config_byte(struct pci_dev *dev, int where, u8 val)
 {
 	u32 data = 0;
-       
+
 	if (config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
@@ -164,11 +164,11 @@
 
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-       
+
         if (config_access(PCI_ACCESS_READ, dev, where, &data))
 	       return -1;
 
-	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/setup.c linux-2.4.20/arch/mips/au1000/pb1000/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1000/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1000/setup.c	2002-10-04 00:41:15.000000000 +0000
@@ -67,7 +67,6 @@
 extern struct ide_ops *ide_ops;
 #endif
 
-void (*__wbflush) (void);
 extern struct rtc_ops no_rtc_ops;
 extern char * __init prom_getcmdline(void);
 extern void au1000_restart(char *);
@@ -76,11 +75,7 @@
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 
-
-void au1000_wbflush(void)
-{
-	__asm__ volatile ("sync");
-}
+void __init bus_error_init(void) { /* nothing */ }
 
 void __init au1000_setup(void)
 {
@@ -88,7 +83,7 @@
 	u32 pin_func, static_cfg0;
 	u32 sys_freqctrl, sys_clksrc;
 	u32 prid = read_32bit_cp0_register(CP0_PRID);
-	
+
 	argptr = prom_getcmdline();
 
 	/* Various early Au1000 Errata corrected by this */
@@ -99,15 +94,14 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#endif
 
 	rtc_ops = &no_rtc_ops;
-        __wbflush = au1000_wbflush;
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
 
-	// IO/MEM resources. 
+	// IO/MEM resources.
 	set_io_port_base(0);
 	ioport_resource.start = 0x10000000;
 	ioport_resource.end = 0xffffffff;
@@ -121,8 +115,8 @@
 #endif
 
 	// set AUX clock to 12MHz * 8 = 96 MHz
-	outl(8, SYS_AUXPLL);
-	outl(0, SYS_PINSTATERD);
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
@@ -138,19 +132,19 @@
 #endif
 
 	/* zero and disable FREQ2 */
-	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
-	outl(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* zero and disable USBH/USBD clocks */
-	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
-	outl(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
-	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
-	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
 
 	switch (prid & 0x000000FF)
@@ -159,17 +153,17 @@
 	case 0x01: /* HA */
 	case 0x02: /* HB */
 	/* CPU core freq to 48MHz to slow it way down... */
-	outl(4, SYS_CPUPLL);
+	au_writel(4, SYS_CPUPLL);
 
 	/*
 	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
 	 */
 	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
 	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
-	outl(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* CPU core freq to 384MHz */
-	outl(0x20, SYS_CPUPLL);
+	au_writel(0x20, SYS_CPUPLL);
 
 	printk("Au1000: 48MHz OHCI workaround enabled\n");
 		break;
@@ -177,7 +171,7 @@
 	default:  /* HC and newer */
 	// FREQ2 = aux/2 = 48 MHz
 	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	outl(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 		break;
 	}
 
@@ -190,64 +184,69 @@
 #ifdef CONFIG_AU1000_USB_DEVICE
 	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
-	outl(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
 #ifdef CONFIG_USB_OHCI
 	// enable host controller and wait for reset done
-	outl(0x08, USB_HOST_CONFIG);
+	au_writel(0x08, USB_HOST_CONFIG);
 	udelay(1000);
-	outl(0x0E, USB_HOST_CONFIG);
+	au_writel(0x0E, USB_HOST_CONFIG);
 	udelay(1000);
-	inl(USB_HOST_CONFIG); // throw away first read
-	while (!(inl(USB_HOST_CONFIG) & 0x10))
-		inl(USB_HOST_CONFIG);
+	au_readl(USB_HOST_CONFIG); // throw away first read
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
+		au_readl(USB_HOST_CONFIG);
 #endif
-	
+
 	// configure pins GPIO[14:9] as GPIO
-	pin_func = inl(SYS_PINFUNC) & (u32)(~0x8080);
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
 
 #ifndef CONFIG_AU1000_USB_DEVICE
 	// 2nd USB port is USB host
 	pin_func |= 0x8000;
 #endif
-	outl(pin_func, SYS_PINFUNC);
-	outl(0x2800, SYS_TRIOUTCLR);
-	outl(0x0030, SYS_OUTPUTCLR);
+	au_writel(pin_func, SYS_PINFUNC);
+	au_writel(0x2800, SYS_TRIOUTCLR);
+	au_writel(0x0030, SYS_OUTPUTCLR);
 #endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
 
-	// make gpio 15 an input (for interrupt line) 
-	pin_func = inl(SYS_PINFUNC) & (u32)(~0x100);
-	// we don't need I2S, so make it available for GPIO[31:29] 
+	// make gpio 15 an input (for interrupt line)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
+	// we don't need I2S, so make it available for GPIO[31:29]
 	pin_func |= (1<<5);
-	outl(pin_func, SYS_PINFUNC);
+	au_writel(pin_func, SYS_PINFUNC);
+
+	au_writel(0x8000, SYS_TRIOUTCLR);
 
-	outl(0x8000, SYS_TRIOUTCLR);
-	
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
 
-	static_cfg0 = inl(MEM_STCFG0) & (u32)(~0xc00);
-	outl(static_cfg0, MEM_STCFG0);
+	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
+	au_writel(static_cfg0, MEM_STCFG0);
 
 	// configure RCE2* for LCD
-	outl(0x00000004, MEM_STCFG2);
+	au_writel(0x00000004, MEM_STCFG2);
 
 	// MEM_STTIME2
-	outl(0x09000000, MEM_STTIME2);
+	au_writel(0x09000000, MEM_STTIME2);
 
 	// Set 32-bit base address decoding for RCE2*
-	outl(0x10003ff0, MEM_STADDR2);
+	au_writel(0x10003ff0, MEM_STADDR2);
 
 	// PCI CPLD setup
 	// expand CE0 to cover PCI
-	outl(0x11803e40, MEM_STADDR1);
+	au_writel(0x11803e40, MEM_STADDR1);
+
+	// burst visibility on
+	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
 
-	// burst visibility on 
-	outl(inl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
 
-	outl(0x83, MEM_STCFG1);         // ewait enabled, flash timing
-	outl(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
 #ifdef CONFIG_FB_E1356
 	if ((argptr = strstr(argptr, "video=")) == NULL) {
@@ -258,39 +257,35 @@
 
 
 #ifdef CONFIG_PCI
-	outl(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
-	outl(0, SDRAM_MBAR);        // set mbar to 0
-	outl(0x2, SDRAM_CMD);       // enable memory accesses
+	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
 	au_sync_delay(1);
 #endif
 
 #ifndef CONFIG_SERIAL_NONSTANDARD
 	/* don't touch the default serial console */
-	outl(0, UART0_ADDR + UART_CLK);
+	au_writel(0, UART0_ADDR + UART_CLK);
 #endif
-	outl(0, UART1_ADDR + UART_CLK);
-	outl(0, UART2_ADDR + UART_CLK);
-	outl(0, UART3_ADDR + UART_CLK);
+	au_writel(0, UART1_ADDR + UART_CLK);
+	au_writel(0, UART2_ADDR + UART_CLK);
+	au_writel(0, UART3_ADDR + UART_CLK);
 
 #ifdef CONFIG_BLK_DEV_IDE
-	{
-		argptr = prom_getcmdline();
-		strcat(argptr, " ide0=noprobe");
-	}
 	ide_ops = &std_ide_ops;
 #endif
 
 	// setup irda clocks
 	// aux clock, divide by 2, clock from 2/4 divider
-	writel(readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC);
-	pin_func = inl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD
-	outl(pin_func, SYS_PINFUNC);
+	au_writel(au_readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC);
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD
+	au_writel(pin_func, SYS_PINFUNC);
 
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
-	outl(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
 	au_sync();
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
-	outl(0, SYS_TOYTRIM);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
 
 	/* Enable Au1000 BCLK switching - note: sed1356 must not use
 	 * its BCLK (Au1000 LCLK) for any timings */
@@ -301,7 +296,7 @@
 	case 0x02: /* HB */
 		break;
 	default:  /* HC and newer */
-		outl(0x00000060, 0xb190003c);
+		au_writel(0x00000060, 0xb190003c);
 		break;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/Makefile linux-2.4.20/arch/mips/au1000/pb1100/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1100/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1100/Makefile	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,24 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor Pb1100 board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET := pb1100.o
+
+obj-y := init.o setup.o
+
+obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/init.c linux-2.4.20/arch/mips/au1000/pb1100/init.c
--- linux-2.4.19/arch/mips/au1000/pb1100/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1100/init.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,73 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 board setup
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void  __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+	return "Alchemy Pb1100";
+}
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	unsigned char *memsize_str;
+	unsigned long memsize;
+
+	prom_argc = argc;
+	prom_argv = argv;
+	prom_envp = envp;
+
+	mips_machgroup = MACH_GROUP_ALCHEMY;
+	mips_machtype = MACH_PB1100;
+
+	prom_init_cmdline();
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		memsize = 0x04000000;
+	} else {
+		memsize = simple_strtol(memsize_str, NULL, 0);
+	}
+	add_memory_region(0, memsize, BOOT_MEM_RAM);
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/pci_fixup.c linux-2.4.20/arch/mips/au1000/pb1100/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1100/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1100/pci_fixup.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,68 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1100.h>
+
+#undef	DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)
+#endif
+
+static void fixup_resource(int r_num, struct pci_dev *dev) ;
+static unsigned long virt_io_addr;
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/pci_ops.c linux-2.4.20/arch/mips/au1000/pb1100/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1100/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1100/pci_ops.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,57 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 specific pci support.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1100.h>
+#include <asm/pci_channel.h>
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+#ifdef 	DEBUG
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)
+#endif
+
+struct pci_channel mips_pci_channels[] = {
+	{(struct pci_ops *) NULL, (struct resource *) NULL,
+	 (struct resource *) NULL, (int) NULL, (int) NULL}
+};
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/setup.c linux-2.4.20/arch/mips/au1000/pb1100/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1100/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1100/setup.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,248 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Pb1100 board setup.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/keyboard.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/au1000.h>
+#include <asm/pb1100.h>
+
+#ifdef CONFIG_USB_OHCI
+// Enable the workaround for the OHCI DoneHead
+// register corruption problem.
+#define CONFIG_AU1000_OHCI_FIX
+#endif
+
+#if defined(CONFIG_AU1000_SERIAL_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+extern struct ide_ops *ide_ops;
+#endif
+
+#ifdef CONFIG_RTC
+extern struct rtc_ops pb1500_rtc_ops;
+#endif
+
+extern char * __init prom_getcmdline(void);
+extern void au1000_restart(char *);
+extern void au1000_halt(void);
+extern void au1000_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+
+
+void __init bus_error_init(void) { /* nothing */ }
+
+void __init au1100_setup(void)
+{
+	char *argptr;
+	u32 pin_func, static_cfg0;
+	u32 sys_freqctrl, sys_clksrc;
+
+	argptr = prom_getcmdline();
+
+	/* NOTE: The memory map is established by YAMON 2.08+ */
+
+	/* Various early Au1000 Errata corrected by this */
+	set_cp0_config(1<<19); /* Config[OD] */
+
+#ifdef CONFIG_AU1000_SERIAL_CONSOLE
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " console=ttyS0,115200");
+	}
+#endif
+
+#ifdef CONFIG_SOUND_AU1000
+	strcat(argptr, " au1000_audio=vra");
+	argptr = prom_getcmdline();
+#endif
+
+	_machine_restart = au1000_restart;
+	_machine_halt = au1000_halt;
+	_machine_power_off = au1000_power_off;
+
+	// IO/MEM resources.
+	set_io_port_base(0);
+	ioport_resource.start = 0x10000000;
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.start = 0x10000000;
+	iomem_resource.end = 0xffffffff;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PININPUTEN);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
+	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
+	        char usb_args[80];
+		argptr = prom_getcmdline();
+		memset(usb_args, 0, sizeof(usb_args));
+		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
+			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
+		strcat(argptr, usb_args);
+	}
+#endif
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD/IrDA clock */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+	 */
+	sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+	// get USB Functionality pin state (device vs host drive pins)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1000_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_writel(pin_func, SYS_PINFUNC);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+
+#ifdef CONFIG_USB_OHCI
+	// enable host controller and wait for reset done
+	au_writel(0x08, USB_HOST_CONFIG);
+	udelay(1000);
+	au_writel(0x0c, USB_HOST_CONFIG);
+	udelay(1000);
+	au_readl(USB_HOST_CONFIG);
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
+	    ;
+	au_readl(USB_HOST_CONFIG);
+#endif
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_FB_AU1100
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		/* default panel */
+		strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");
+	}
+#endif
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=e1356fb:system:pb1500");
+	}
+#endif
+
+#ifndef CONFIG_SERIAL_NONSTANDARD
+	/* don't touch the default serial console */
+	au_writel(0, UART0_ADDR + UART_CLK);
+#endif
+	au_writel(0, UART1_ADDR + UART_CLK);
+	au_writel(0, UART3_ADDR + UART_CLK);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
+
+	au_writel(0x00000060, 0xb190003c);
+
+#ifdef CONFIG_RTC
+	rtc_ops = &pb1500_rtc_ops;
+	// Enable the RTC if not already enabled
+	if (!(readb(0xac000028) & 0x20)) {
+		writeb(readb(0xac000028) | 0x20, 0xac000028);
+		au_sync();
+	}
+	// Put the clock in BCD mode
+	if (readb(0xac00002C) & 0x4) { /* reg B */
+		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/Makefile linux-2.4.20/arch/mips/au1000/pb1500/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1500/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1500/Makefile	2002-10-04 00:41:20.000000000 +0000
@@ -10,10 +10,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := pb1500.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/init.c linux-2.4.20/arch/mips/au1000/pb1500/init.c
--- linux-2.4.19/arch/mips/au1000/pb1500/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1500/init.c	2002-10-04 00:41:17.000000000 +0000
@@ -34,7 +34,6 @@
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -59,7 +58,7 @@
 	prom_envp = envp;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
-	mips_machtype = MACH_PB1500;  
+	mips_machtype = MACH_PB1500;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/pci_fixup.c linux-2.4.20/arch/mips/au1000/pb1500/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1500/pci_fixup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1500/pci_fixup.c	2002-10-04 00:41:29.000000000 +0000
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 static void fixup_resource(int r_num, struct pci_dev *dev) ;
@@ -57,8 +57,8 @@
 {
 	int i;
 	struct pci_dev *dev;
-	
-	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, 
+
+	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START,
 			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
 
 	if (!virt_io_addr) {
@@ -103,7 +103,7 @@
 	return 0;
 }
 
-static void fixup_resource(int r_num, struct pci_dev *dev) 
+static void fixup_resource(int r_num, struct pci_dev *dev)
 {
 	unsigned long start, size, new_start;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/pci_ops.c linux-2.4.20/arch/mips/au1000/pb1500/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1500/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1500/pci_ops.c	2002-10-04 00:41:30.000000000 +0000
@@ -46,19 +46,19 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 /* TBD */
 static struct resource pci_io_resource = {
-	"pci IO space", 
+	"pci IO space",
 	Au1500_PCI_IO_START,
 	Au1500_PCI_IO_END,
 	IORESOURCE_IO
 };
 
 static struct resource pci_mem_resource = {
-	"pci memory space", 
+	"pci memory space",
 	Au1500_PCI_MEM_START,
 	Au1500_PCI_MEM_END,
 	IORESOURCE_MEM
@@ -73,7 +73,7 @@
 };
 
 static unsigned long cfg_addr;
-static int config_access(unsigned char access_type, struct pci_dev *dev, 
+static int config_access(unsigned char access_type, struct pci_dev *dev,
 			 unsigned char where, u32 * data)
 {
 	unsigned char bus = dev->bus->number;
@@ -82,7 +82,7 @@
 	unsigned long config, status;
 	static int first = 1;
 
-	/* 
+	/*
  	 * 7:3 = slot
  	 * 2:0 = function
 	 */
@@ -95,7 +95,7 @@
 	if (first) {
 		first = 0;
 		cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000);
-		if (!cfg_addr) 
+		if (!cfg_addr)
 			printk (KERN_ERR "PCI unable to ioremap cfg space\n");
 	}
 
@@ -110,13 +110,13 @@
 	}
 #endif
 
-	writel(((0x2000 << 16) | (readl(Au1500_PCI_STATCMD) & 0xffff)),
+	au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
 			Au1500_PCI_STATCMD);
-	//writel(readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
+	//au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
 	au_sync_udelay(1);
 
 	/* setup the lower 31 bits of the 36 bit address */
-	config = cfg_addr | 
+	config = cfg_addr |
 		((1<<device)<<11) | (function << 8) | (where & ~0x3);
 
 #if 0
@@ -125,18 +125,18 @@
 #endif
 
 	if (access_type == PCI_ACCESS_WRITE) {
-		writel(*data, config);
+		au_writel(*data, config);
 	} else {
-		*data = readl(config);
+		*data = au_readl(config);
 	}
 	au_sync_udelay(1);
 
-	DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", 
+	DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n",
 			access_type, bus, device, where, *data, config);
 
 	/* check master abort */
-	status = readl(Au1500_PCI_STATCMD);
-	if (status & (1<<29)) { 
+	status = au_readl(Au1500_PCI_STATCMD);
+	if (status & (1<<29)) {
 		*data = 0xffffffff;
 		return -1;
 	} else if ((status >> 28) & 0xf) {
@@ -159,7 +159,7 @@
         if (where & 1) data >>= 8;
         if (where & 2) data >>= 16;
         *val = data & 0xff;
-	return ret; 
+	return ret;
 }
 
 
@@ -171,7 +171,7 @@
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
         if (where & 2) data >>= 16;
         *val = data & 0xffff;
-	return ret; 
+	return ret;
 }
 
 static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
@@ -179,14 +179,14 @@
 	int ret;
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, val);
-	return ret; 
+	return ret;
 }
 
 
 static int write_config_byte(struct pci_dev *dev, int where, u8 val)
 {
 	u32 data = 0;
-       
+
 	if (config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
@@ -205,11 +205,11 @@
 
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-       
+
         if (config_access(PCI_ACCESS_READ, dev, where, &data))
 	       return -1;
 
-	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/setup.c linux-2.4.20/arch/mips/au1000/pb1500/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1500/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/au1000/pb1500/setup.c	2002-10-04 00:41:12.000000000 +0000
@@ -71,7 +71,6 @@
 extern struct rtc_ops pb1500_rtc_ops;
 #endif
 
-void (*__wbflush) (void);
 extern char * __init prom_getcmdline(void);
 extern void au1000_restart(char *);
 extern void au1000_halt(void);
@@ -80,17 +79,14 @@
 extern struct resource iomem_resource;
 
 
-void au1500_wbflush(void)
-{
-	__asm__ volatile ("sync");
-}
+void __init bus_error_init(void) { /* nothing */ }
 
 void __init au1500_setup(void)
 {
 	char *argptr;
 	u32 pin_func, static_cfg0;
 	u32 sys_freqctrl, sys_clksrc;
-	
+
 	argptr = prom_getcmdline();
 
 	/* NOTE: The memory map is established by YAMON 2.08+ */
@@ -103,19 +99,18 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#endif
 
 #ifdef CONFIG_SOUND_AU1000
 	strcat(argptr, " au1000_audio=vra");
 	argptr = prom_getcmdline();
 #endif
 
-        __wbflush = au1500_wbflush;
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
 
-	// IO/MEM resources. 
+	// IO/MEM resources.
 	set_io_port_base(0);
 	ioport_resource.start = 0x10000000;
 	ioport_resource.end = 0xffffffff;
@@ -129,8 +124,8 @@
 #endif
 
 	// set AUX clock to 12MHz * 8 = 96 MHz
-	writel(8, SYS_AUXPLL);
-	outl(0, SYS_PINSTATERD);
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
@@ -146,24 +141,24 @@
 #endif
 
 	/* zero and disable FREQ2 */
-	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
-	writel(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* zero and disable USBH/USBD clocks */
-	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
-	writel(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
-	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
-	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
 
 	// FREQ2 = aux/2 = 48 MHz
 	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	writel(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/*
 	 * Route 48MHz FREQ2 into USB Host and/or Device
@@ -174,30 +169,30 @@
 #ifdef CONFIG_AU1000_USB_DEVICE
 	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
-	writel(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
 
-	pin_func = readl(SYS_PINFUNC) & (u32)(~0x8000);
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
 #ifndef CONFIG_AU1000_USB_DEVICE
 	// 2nd USB port is USB host
 	pin_func |= 0x8000;
 #endif
-	writel(pin_func, SYS_PINFUNC);
+	au_writel(pin_func, SYS_PINFUNC);
 #endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
 
 
 #ifdef CONFIG_USB_OHCI
 	// enable host controller and wait for reset done
-	writel(0x08, USB_HOST_CONFIG);
+	au_writel(0x08, USB_HOST_CONFIG);
 	udelay(1000);
-	writel(0x0c, USB_HOST_CONFIG);
+	au_writel(0x0c, USB_HOST_CONFIG);
 	udelay(1000);
-	readl(USB_HOST_CONFIG);
-	while (!(readl(USB_HOST_CONFIG) & 0x10))
+	au_readl(USB_HOST_CONFIG);
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
 	    ;
-	readl(USB_HOST_CONFIG);
+	au_readl(USB_HOST_CONFIG);
 #endif
-	
+
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
@@ -205,15 +200,20 @@
 #ifdef CONFIG_FB_E1356
 	if ((argptr = strstr(argptr, "video=")) == NULL) {
 		argptr = prom_getcmdline();
-		strcat(argptr, " video=e1356fb:system:pb1500,mmunalign:1");
+		strcat(argptr, " video=e1356fb:system:pb1500");
+	}
+#elif defined (CONFIG_FB_XPERT98)
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=atyfb:1024x768-8@70");
 	}
 #endif // CONFIG_FB_E1356
 
 #ifndef CONFIG_SERIAL_NONSTANDARD
 	/* don't touch the default serial console */
-	writel(0, UART0_ADDR + UART_CLK);
+	au_writel(0, UART0_ADDR + UART_CLK);
 #endif
-	writel(0, UART3_ADDR + UART_CLK);
+	au_writel(0, UART3_ADDR + UART_CLK);
 
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &std_ide_ops;
@@ -221,35 +221,40 @@
 
 #ifdef CONFIG_PCI
 	// Setup PCI bus controller
-	writel(0, Au1500_PCI_CMEM);
-	writel(0x00003fff, Au1500_CFG_BASE);
-	writel(0xf, Au1500_PCI_CFG);
-	writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
-	writel(0, Au1500_PCI_MWBASE_REV_CCL);
-	writel(0x02a00356, Au1500_PCI_STATCMD);
-	writel(0x00003c04, Au1500_PCI_HDRTYPE);	
-	writel(0x00000008, Au1500_PCI_MBAR);
+	au_writel(0, Au1500_PCI_CMEM);
+	au_writel(0x00003fff, Au1500_CFG_BASE);
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
+	au_writel(0x02a00356, Au1500_PCI_STATCMD);
+	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
+	au_writel(0x00000008, Au1500_PCI_MBAR);
 	au_sync();
 #endif
 
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
-	writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
-	outl(0, SYS_TOYTRIM);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
 
 	/* Enable BCLK switching */
-	writel(0x00000060, 0xb190003c);
+	au_writel(0x00000060, 0xb190003c);
 
 #ifdef CONFIG_RTC
 	rtc_ops = &pb1500_rtc_ops;
-	// Enable the RTC if not already enabled 
-	if (!(readb(0xac000028) & 0x20)) {
-		writeb(readb(0xac000028) | 0x20, 0xac000028);
+	// Enable the RTC if not already enabled
+	if (!(au_readl(0xac000028) & 0x20)) {
+		printk("enabling clock ...\n");
+		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
 	}
 	// Put the clock in BCD mode
-	if (readb(0xac00002C) & 0x4) { /* reg B */
-		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+	if (readl(0xac00002C) & 0x4) { /* reg B */
+		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
 		au_sync();
 	}
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/Makefile linux-2.4.20/arch/mips/boot/Makefile
--- linux-2.4.19/arch/mips/boot/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/boot/Makefile	2002-10-04 00:41:13.000000000 +0000
@@ -8,8 +8,6 @@
 
 USE_STANDARD_AS_RULE := true
 
-OBJS  = milo.o a.out.o
-
 #
 # Some DECstations need all possible sections of an ECOFF executable
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/addinitrd.c linux-2.4.20/arch/mips/boot/addinitrd.c
--- linux-2.4.19/arch/mips/boot/addinitrd.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/boot/addinitrd.c	2002-10-04 00:41:12.000000000 +0000
@@ -82,7 +82,7 @@
 		die ("open initrd");
 	if (fstat (fd_initrd, &st) < 0)
 		die ("fstat initrd");
-	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size) 
+	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
 			+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
 	if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
 		loadaddr += MIPS_PAGE_SIZE;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/elf2ecoff.c linux-2.4.20/arch/mips/boot/elf2ecoff.c
--- linux-2.4.19/arch/mips/boot/elf2ecoff.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/boot/elf2ecoff.c	2002-10-04 00:41:18.000000000 +0000
@@ -49,485 +49,106 @@
 /*
  * Some extra ELF definitions
  */
-#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
+#define PT_MIPS_REGINFO 0x70000000	/* Register usage information */
 
 /* -------------------------------------------------------------------- */
 
 struct sect {
-  unsigned long vaddr;
-  unsigned long len;
+	unsigned long vaddr;
+	unsigned long len;
 };
 
-void combine (struct sect* base, struct sect* new, int pad);
-int phcmp ();
-char *saveRead (int file, off_t offset, off_t len, char *name);
-void copy (int, int, off_t, off_t);
-int translate_syms (int, int, off_t, off_t, off_t, off_t);
-void convert_elf_hdr (Elf32_Ehdr *);
-void convert_elf_phdrs (Elf32_Phdr *, int);
-void convert_elf_shdrs (Elf32_Shdr *, int);
-void convert_ecoff_filehdr(struct filehdr *);
-void convert_ecoff_aouthdr(struct aouthdr *);
-void convert_ecoff_esecs(struct scnhdr *, int);
-extern int errno;
 int *symTypeTable;
 int must_convert_endian = 0;
 int format_bigendian = 0;
 
-int
-main (int argc, char **argv, char **envp)
+static void copy(int out, int in, off_t offset, off_t size)
 {
-  Elf32_Ehdr ex;
-  Elf32_Phdr *ph;
-  Elf32_Shdr *sh;
-  char *shstrtab;
-  int i, pad;
-  struct sect text, data, bss;
-  struct filehdr efh;
-  struct aouthdr eah;
-  struct scnhdr esecs [6];
-  int infile, outfile;
-  unsigned long cur_vma = ULONG_MAX;
-  int addflag = 0;
-  int nosecs;
-
-  text.len = data.len = bss.len = 0;
-  text.vaddr = data.vaddr = bss.vaddr = 0;
-
-  /* Check args... */
-  if (argc < 3 || argc > 4)
-    {
-    usage:
-      fprintf (stderr,
-	       "usage: elf2aout <elf executable> <a.out executable> [-a]\n");
-      exit (1);
-    }
-  if (argc == 4)
-    {
-      if (strcmp (argv [3], "-a"))
-	goto usage;
-      addflag = 1;
-    }
-
-  /* Try the input file... */
-  if ((infile = open (argv [1], O_RDONLY)) < 0)
-    {
-      fprintf (stderr, "Can't open %s for read: %s\n",
-	       argv [1], strerror (errno));
-      exit (1);
-    }
-
-  /* Read the header, which is at the beginning of the file... */
-  i = read (infile, &ex, sizeof ex);
-  if (i != sizeof ex)
-    {
-      fprintf (stderr, "ex: %s: %s.\n",
-	       argv [1], i ? strerror (errno) : "End of file reached");
-      exit (1);
-    }
-
-  if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
-	format_bigendian = 1;
-
-  if (ntohs (0xaa55) == 0xaa55) {
-	if (!format_bigendian)
-		must_convert_endian = 1;
-  } else {
-	if (format_bigendian)
-		must_convert_endian = 1;
-  }
-  if (must_convert_endian)
-	convert_elf_hdr (&ex);
-
-  /* Read the program headers... */
-  ph = (Elf32_Phdr *)saveRead (infile, ex.e_phoff,
-				ex.e_phnum * sizeof (Elf32_Phdr), "ph");
-  if (must_convert_endian)
-	convert_elf_phdrs (ph, ex.e_phnum);
-  /* Read the section headers... */
-  sh = (Elf32_Shdr *)saveRead (infile, ex.e_shoff,
-				ex.e_shnum * sizeof (Elf32_Shdr), "sh");
-  if (must_convert_endian)
-	convert_elf_shdrs (sh, ex.e_shnum);
-  /* Read in the section string table. */
-  shstrtab = saveRead (infile, sh [ex.e_shstrndx].sh_offset,
-		       sh [ex.e_shstrndx].sh_size, "shstrtab");
-
-  /* Figure out if we can cram the program header into an ECOFF
-     header...  Basically, we can't handle anything but loadable
-     segments, but we can ignore some kinds of segments.  We can't
-     handle holes in the address space.  Segments may be out of order,
-     so we sort them first. */
-
-  qsort (ph, ex.e_phnum, sizeof (Elf32_Phdr), phcmp);
-
-  for (i = 0; i < ex.e_phnum; i++)
-    {
-      /* Section types we can ignore... */
-      if (ph [i].p_type == PT_NULL || ph [i].p_type == PT_NOTE ||
-	  ph [i].p_type == PT_PHDR || ph [i].p_type == PT_MIPS_REGINFO)
-	continue;
-      /* Section types we can't handle... */
-      else if (ph [i].p_type != PT_LOAD)
-        {
-	  fprintf (stderr, "Program header %d type %d can't be converted.\n", 
-			  	ex.e_phnum, ph[i].p_type );
-	  exit (1);
-	}
-      /* Writable (data) segment? */
-      if (ph [i].p_flags & PF_W)
-	{
-	  struct sect ndata, nbss;
+	char ibuf[4096];
+	int remaining, cur, count;
 
-	  ndata.vaddr = ph [i].p_vaddr;
-	  ndata.len = ph [i].p_filesz;
-	  nbss.vaddr = ph [i].p_vaddr + ph [i].p_filesz;
-	  nbss.len = ph [i].p_memsz - ph [i].p_filesz;
+	/* Go to the start of the ELF symbol table... */
+	if (lseek(in, offset, SEEK_SET) < 0) {
+		perror("copy: lseek");
+		exit(1);
+	}
+
+	remaining = size;
+	while (remaining) {
+		cur = remaining;
+		if (cur > sizeof(ibuf))
+			cur = sizeof(ibuf);
+		remaining -= cur;
+		if ((count = read(in, ibuf, cur)) != cur) {
+			fprintf(stderr, "copy: read: %s\n",
+				count ? strerror(errno) :
+				"premature end of file");
+			exit(1);
+		}
+		if ((count = write(out, ibuf, cur)) != cur) {
+			perror("copy: write");
+			exit(1);
+		}
+	}
+}
 
-	  combine (&data, &ndata, 0);
-	  combine (&bss, &nbss, 1);
+/*
+ * Combine two segments, which must be contiguous.   If pad is true, it's
+ * okay for there to be padding between.
+ */
+static void combine(struct sect *base, struct sect *new, int pad)
+{
+	if (!base->len)
+		*base = *new;
+	else if (new->len) {
+		if (base->vaddr + base->len != new->vaddr) {
+			if (pad)
+				base->len = new->vaddr - base->vaddr;
+			else {
+				fprintf(stderr,
+					"Non-contiguous data can't be converted.\n");
+				exit(1);
+			}
+		}
+		base->len += new->len;
 	}
-      else
-	{
-	  struct sect ntxt;
+}
 
-	  ntxt.vaddr = ph [i].p_vaddr;
-	  ntxt.len = ph [i].p_filesz;
+static int phcmp(const void *v1, const void *v2)
+{
+	const Elf32_Phdr *h1 = v1;
+	const Elf32_Phdr *h2 = v2;
 
-	  combine (&text, &ntxt, 0);
-	}
-      /* Remember the lowest segment start address. */
-      if (ph [i].p_vaddr < cur_vma)
-	cur_vma = ph [i].p_vaddr;
-    }
-
-  /* Sections must be in order to be converted... */
-  if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
-      text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr)
-    {
-      fprintf (stderr, "Sections ordering prevents a.out conversion.\n");
-      exit (1);
-    }
-
-  /* If there's a data section but no text section, then the loader
-     combined everything into one section.   That needs to be the
-     text section, so just make the data section zero length following
-     text. */
-  if (data.len && !text.len)
-    {
-      text = data;
-      data.vaddr = text.vaddr + text.len;
-      data.len = 0;
-    }
-
-  /* If there is a gap between text and data, we'll fill it when we copy
-     the data, so update the length of the text segment as represented in
-     a.out to reflect that, since a.out doesn't allow gaps in the program
-     address space. */
-  if (text.vaddr + text.len < data.vaddr)
-    text.len = data.vaddr - text.vaddr;
-
-  /* We now have enough information to cons up an a.out header... */
-  eah.magic = OMAGIC;
-  eah.vstamp = 200;
-  eah.tsize = text.len;
-  eah.dsize = data.len;
-  eah.bsize = bss.len;
-  eah.entry = ex.e_entry;
-  eah.text_start = text.vaddr;
-  eah.data_start = data.vaddr;
-  eah.bss_start = bss.vaddr;
-  eah.gprmask = 0xf3fffffe;
-  memset (&eah.cprmask, '\0', sizeof eah.cprmask);
-  eah.gp_value = 0; /* unused. */
-
-  if (format_bigendian)
-    efh.f_magic = MIPSEBMAGIC;
-  else
-    efh.f_magic = MIPSELMAGIC;
-  if (addflag)
-    nosecs = 6;
-  else
-    nosecs = 3;
-  efh.f_nscns = nosecs;
-  efh.f_timdat = 0;	/* bogus */
-  efh.f_symptr = 0;
-  efh.f_nsyms = 0;
-  efh.f_opthdr = sizeof eah;
-  efh.f_flags = 0x100f; /* Stripped, not sharable. */
-
-  memset (esecs, 0, sizeof esecs);
-  strcpy (esecs [0].s_name, ".text");
-  strcpy (esecs [1].s_name, ".data");
-  strcpy (esecs [2].s_name, ".bss");
-  if (addflag) {
-    strcpy (esecs [3].s_name, ".rdata");
-    strcpy (esecs [4].s_name, ".sdata");
-    strcpy (esecs [5].s_name, ".sbss");
-  }
-  esecs [0].s_paddr = esecs [0].s_vaddr = eah.text_start;
-  esecs [1].s_paddr = esecs [1].s_vaddr = eah.data_start;
-  esecs [2].s_paddr = esecs [2].s_vaddr = eah.bss_start;
-  if (addflag) {
-    esecs [3].s_paddr = esecs [3].s_vaddr = 0;
-    esecs [4].s_paddr = esecs [4].s_vaddr = 0;
-    esecs [5].s_paddr = esecs [5].s_vaddr = 0;
-  }
-  esecs [0].s_size = eah.tsize;
-  esecs [1].s_size = eah.dsize;
-  esecs [2].s_size = eah.bsize;
-  if (addflag) {
-    esecs [3].s_size = 0;
-    esecs [4].s_size = 0;
-    esecs [5].s_size = 0;
-  }
-  esecs [0].s_scnptr = N_TXTOFF (efh, eah);
-  esecs [1].s_scnptr = N_DATOFF (efh, eah);
-#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
-#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
-  esecs [2].s_scnptr = esecs [1].s_scnptr +
-	  ECOFF_ROUND (esecs [1].s_size, ECOFF_SEGMENT_ALIGNMENT (&eah));
-  if (addflag) {
-    esecs [3].s_scnptr = 0;
-    esecs [4].s_scnptr = 0;
-    esecs [5].s_scnptr = 0;
-  }
-  esecs [0].s_relptr = esecs [1].s_relptr
-	  = esecs [2].s_relptr = 0;
-  esecs [0].s_lnnoptr = esecs [1].s_lnnoptr
-	  = esecs [2].s_lnnoptr = 0;
-  esecs [0].s_nreloc = esecs [1].s_nreloc = esecs [2].s_nreloc = 0;
-  esecs [0].s_nlnno = esecs [1].s_nlnno = esecs [2].s_nlnno = 0;
-  if (addflag) {
-    esecs [3].s_relptr = esecs [4].s_relptr 
-  	  = esecs [5].s_relptr = 0;
-    esecs [3].s_lnnoptr = esecs [4].s_lnnoptr
-	  = esecs [5].s_lnnoptr = 0;
-    esecs [3].s_nreloc = esecs [4].s_nreloc = esecs [5].s_nreloc = 0;
-    esecs [3].s_nlnno = esecs [4].s_nlnno = esecs [5].s_nlnno = 0;
-  }
-  esecs [0].s_flags = 0x20;
-  esecs [1].s_flags = 0x40;
-  esecs [2].s_flags = 0x82;
-  if (addflag) {
-    esecs [3].s_flags = 0x100;
-    esecs [4].s_flags = 0x200;
-    esecs [5].s_flags = 0x400;
-  }
-
-  /* Make the output file... */
-  if ((outfile = open (argv [2], O_WRONLY | O_CREAT, 0777)) < 0)
-    {
-      fprintf (stderr, "Unable to create %s: %s\n", argv [2], strerror (errno));
-      exit (1);
-    }
-
-  if (must_convert_endian)
-	convert_ecoff_filehdr (&efh);
-  /* Write the headers... */
-  i = write (outfile, &efh, sizeof efh);
-  if (i != sizeof efh)
-    {
-      perror ("efh: write");
-      exit (1);
-
-    for (i = 0; i < nosecs; i++)
-      {
-        printf ("Section %d: %s phys %lx  size %lx  file offset %lx\n", 
-	      i, esecs [i].s_name, esecs [i].s_paddr,
-	      esecs [i].s_size, esecs [i].s_scnptr);
-      }
-    }
-  fprintf (stderr, "wrote %d byte file header.\n", i);
-
-  if (must_convert_endian)
-	convert_ecoff_aouthdr (&eah);
-  i = write (outfile, &eah, sizeof eah);
-  if (i != sizeof eah)
-    {
-      perror ("eah: write");
-      exit (1);
-    }
-  fprintf (stderr, "wrote %d byte a.out header.\n", i);
-
-  if (must_convert_endian)
-	convert_ecoff_esecs (&esecs[0], nosecs);
-  i = write (outfile, &esecs, nosecs * sizeof(struct scnhdr));
-  if (i != nosecs * sizeof(struct scnhdr))
-    {
-      perror ("esecs: write");
-      exit (1);
-    }
-  fprintf (stderr, "wrote %d bytes of section headers.\n", i);
-
-  if (pad = ((sizeof efh + sizeof eah + nosecs * sizeof(struct scnhdr)) & 15))
-    {
-      pad = 16 - pad;
-      i = write (outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
-      if (i < 0)
-	{
-	  perror ("ipad: write");
-	  exit (1);
-	}
-      fprintf (stderr, "wrote %d byte pad.\n", i);
-    }
+	if (h1->p_vaddr > h2->p_vaddr)
+		return 1;
+	else if (h1->p_vaddr < h2->p_vaddr)
+		return -1;
+	else
+		return 0;
+}
 
-  /* Copy the loadable sections.   Zero-fill any gaps less than 64k;
-     complain about any zero-filling, and die if we're asked to zero-fill
-     more than 64k. */
-  for (i = 0; i < ex.e_phnum; i++)
-    {
-      /* Unprocessable sections were handled above, so just verify that
-	 the section can be loaded before copying. */
-      if (ph [i].p_type == PT_LOAD && ph [i].p_filesz)
-	{
-	  if (cur_vma != ph [i].p_vaddr)
-	    {
-	      unsigned long gap = ph [i].p_vaddr - cur_vma;
-	      char obuf [1024];
-	      if (gap > 65536)
-		{
-		  fprintf (stderr, "Intersegment gap (%ld bytes) too large.\n",
-			   gap);
-		  exit (1);
-		}
-	      fprintf (stderr, "Warning: %ld byte intersegment gap.\n", gap);
-	      memset (obuf, 0, sizeof obuf);
-	      while (gap)
-		{
-		  int count = write (outfile, obuf, (gap > sizeof obuf
-						     ? sizeof obuf : gap));
-		  if (count < 0)
-		    {
-		      fprintf (stderr, "Error writing gap: %s\n",
-			       strerror (errno));
-		      exit (1);
-		    }
-		  gap -= count;
-		}
-	    }
-fprintf (stderr, "writing %d bytes...\n", ph [i].p_filesz);
-	  copy (outfile, infile, ph [i].p_offset, ph [i].p_filesz);
-	  cur_vma = ph [i].p_vaddr + ph [i].p_filesz;
-	}
-    }
-
-   /*
-     * Write a page of padding for boot PROMS that read entire pages.
-     * Without this, they may attempt to read past the end of the
-     * data section, incur an error, and refuse to boot.
-     */
-    {
-	char obuf[4096];
-	memset(obuf, 0, sizeof obuf);
-	if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
-	    fprintf(stderr, "Error writing PROM padding: %s\n",
-		    strerror(errno));
-	    exit(1);
-	}
-    }
-
-  /* Looks like we won... */
-  exit (0);
-}
-
-void
-copy (out, in, offset, size)
-     int out, in;
-     off_t offset, size;
-{
-  char ibuf [4096];
-  int remaining, cur, count;
-
-  /* Go to the start of the ELF symbol table... */
-  if (lseek (in, offset, SEEK_SET) < 0)
-    {
-      perror ("copy: lseek");
-      exit (1);
-    }
-
-  remaining = size;
-  while (remaining)
-    {
-      cur = remaining;
-      if (cur > sizeof ibuf)
-	cur = sizeof ibuf;
-      remaining -= cur;
-      if ((count = read (in, ibuf, cur)) != cur)
-	{
-	  fprintf (stderr, "copy: read: %s\n",
-		   count ? strerror (errno) : "premature end of file");
-	  exit (1);
+static char *saveRead(int file, off_t offset, off_t len, char *name)
+{
+	char *tmp;
+	int count;
+	off_t off;
+	if ((off = lseek(file, offset, SEEK_SET)) < 0) {
+		fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
+		exit(1);
 	}
-      if ((count = write (out, ibuf, cur)) != cur)
-	{
-	  perror ("copy: write");
-	  exit (1);
+	if (!(tmp = (char *) malloc(len))) {
+		fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
+			len);
+		exit(1);
 	}
-    }
-}
-
-/* Combine two segments, which must be contiguous.   If pad is true, it's
-   okay for there to be padding between. */
-void
-combine (base, new, pad)
-     struct sect *base, *new;
-     int pad;
-{
-  if (!base -> len)
-    *base = *new;
-  else if (new -> len)
-    {
-      if (base -> vaddr + base -> len != new -> vaddr)
-	{
-	  if (pad)
-	    base -> len = new -> vaddr - base -> vaddr;
-	  else
-	    {
-	      fprintf (stderr,
-		       "Non-contiguous data can't be converted.\n");
-	      exit (1);
-	    }
-	}
-      base -> len += new -> len;
-    }
-}
-
-int
-phcmp (h1, h2)
-     Elf32_Phdr *h1, *h2;
-{
-  if (h1 -> p_vaddr > h2 -> p_vaddr)
-    return 1;
-  else if (h1 -> p_vaddr < h2 -> p_vaddr)
-    return -1;
-  else
-    return 0;
-}
-
-char *saveRead (int file, off_t offset, off_t len, char *name)
-{
-  char *tmp;
-  int count;
-  off_t off;
-  if ((off = lseek (file, offset, SEEK_SET)) < 0)
-    {
-      fprintf (stderr, "%s: fseek: %s\n", name, strerror (errno));
-      exit (1);
-    }
-  if (!(tmp = (char *)malloc (len)))
-    {
-      fprintf (stderr, "%s: Can't allocate %ld bytes.\n", name, len);
-      exit (1);
-    }
-  count = read (file, tmp, len);
-  if (count != len)
-    {
-      fprintf (stderr, "%s: read: %s.\n",
-	       name, count ? strerror (errno) : "End of file reached");
-      exit (1);
-    }
-  return tmp;
+	count = read(file, tmp, len);
+	if (count != len) {
+		fprintf(stderr, "%s: read: %s.\n",
+			name,
+			count ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+	return tmp;
 }
 
 #define swab16(x) \
@@ -542,101 +163,450 @@
 		(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
 		(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
 
-void convert_elf_hdr (Elf32_Ehdr *e)
+static void convert_elf_hdr(Elf32_Ehdr * e)
 {
-	e->e_type      = swab16(e->e_type);
-	e->e_machine   = swab16(e->e_machine);
-	e->e_version   = swab32(e->e_version);
-	e->e_entry     = swab32(e->e_entry);
-	e->e_phoff     = swab32(e->e_phoff);
-	e->e_shoff     = swab32(e->e_shoff);
-	e->e_flags     = swab32(e->e_flags);
-	e->e_ehsize    = swab16(e->e_ehsize);
+	e->e_type = swab16(e->e_type);
+	e->e_machine = swab16(e->e_machine);
+	e->e_version = swab32(e->e_version);
+	e->e_entry = swab32(e->e_entry);
+	e->e_phoff = swab32(e->e_phoff);
+	e->e_shoff = swab32(e->e_shoff);
+	e->e_flags = swab32(e->e_flags);
+	e->e_ehsize = swab16(e->e_ehsize);
 	e->e_phentsize = swab16(e->e_phentsize);
-	e->e_phnum     = swab16(e->e_phnum);
+	e->e_phnum = swab16(e->e_phnum);
 	e->e_shentsize = swab16(e->e_shentsize);
-	e->e_shnum     = swab16(e->e_shnum);
-	e->e_shstrndx  = swab16(e->e_shstrndx);
+	e->e_shnum = swab16(e->e_shnum);
+	e->e_shstrndx = swab16(e->e_shstrndx);
 }
 
-void convert_elf_phdrs (Elf32_Phdr *p, int num)
+static void convert_elf_phdrs(Elf32_Phdr * p, int num)
 {
 	int i;
 
-	for (i = 0; i < num; i++,p++) {
-		p->p_type   = swab32(p->p_type);
+	for (i = 0; i < num; i++, p++) {
+		p->p_type = swab32(p->p_type);
 		p->p_offset = swab32(p->p_offset);
-		p->p_vaddr  = swab32(p->p_vaddr);
-		p->p_paddr  = swab32(p->p_paddr);
+		p->p_vaddr = swab32(p->p_vaddr);
+		p->p_paddr = swab32(p->p_paddr);
 		p->p_filesz = swab32(p->p_filesz);
-		p->p_memsz  = swab32(p->p_memsz);
-		p->p_flags  = swab32(p->p_flags);
-		p->p_align  = swab32(p->p_align);
+		p->p_memsz = swab32(p->p_memsz);
+		p->p_flags = swab32(p->p_flags);
+		p->p_align = swab32(p->p_align);
 	}
 
 }
 
-void convert_elf_shdrs (Elf32_Shdr *s, int num)
+static void convert_elf_shdrs(Elf32_Shdr * s, int num)
 {
 	int i;
 
-	for (i = 0; i < num; i++,s++) {
-		s->sh_name      = swab32(s->sh_name);
-		s->sh_type      = swab32(s->sh_type);
-		s->sh_flags     = swab32(s->sh_flags);
-		s->sh_addr      = swab32(s->sh_addr);
-		s->sh_offset    = swab32(s->sh_offset);
-		s->sh_size      = swab32(s->sh_size);
-		s->sh_link      = swab32(s->sh_link);
-		s->sh_info      = swab32(s->sh_info);
+	for (i = 0; i < num; i++, s++) {
+		s->sh_name = swab32(s->sh_name);
+		s->sh_type = swab32(s->sh_type);
+		s->sh_flags = swab32(s->sh_flags);
+		s->sh_addr = swab32(s->sh_addr);
+		s->sh_offset = swab32(s->sh_offset);
+		s->sh_size = swab32(s->sh_size);
+		s->sh_link = swab32(s->sh_link);
+		s->sh_info = swab32(s->sh_info);
 		s->sh_addralign = swab32(s->sh_addralign);
-		s->sh_entsize   = swab32(s->sh_entsize);
+		s->sh_entsize = swab32(s->sh_entsize);
 	}
 }
 
-void convert_ecoff_filehdr(struct filehdr *f)
+static void convert_ecoff_filehdr(struct filehdr *f)
 {
-	f->f_magic  = swab16(f->f_magic);
-	f->f_nscns  = swab16(f->f_nscns);
+	f->f_magic = swab16(f->f_magic);
+	f->f_nscns = swab16(f->f_nscns);
 	f->f_timdat = swab32(f->f_timdat);
 	f->f_symptr = swab32(f->f_symptr);
-	f->f_nsyms  = swab32(f->f_nsyms);
+	f->f_nsyms = swab32(f->f_nsyms);
 	f->f_opthdr = swab16(f->f_opthdr);
-	f->f_flags  = swab16(f->f_flags);
+	f->f_flags = swab16(f->f_flags);
 }
 
-void convert_ecoff_aouthdr(struct aouthdr *a)
+static void convert_ecoff_aouthdr(struct aouthdr *a)
 {
-	a->magic      = swab16(a->magic);
-	a->vstamp     = swab16(a->vstamp);
-	a->tsize      = swab32(a->tsize);
-	a->dsize      = swab32(a->dsize);
-	a->bsize      = swab32(a->bsize);
-	a->entry      = swab32(a->entry);
+	a->magic = swab16(a->magic);
+	a->vstamp = swab16(a->vstamp);
+	a->tsize = swab32(a->tsize);
+	a->dsize = swab32(a->dsize);
+	a->bsize = swab32(a->bsize);
+	a->entry = swab32(a->entry);
 	a->text_start = swab32(a->text_start);
 	a->data_start = swab32(a->data_start);
-	a->bss_start  = swab32(a->bss_start);
-	a->gprmask    = swab32(a->gprmask);
+	a->bss_start = swab32(a->bss_start);
+	a->gprmask = swab32(a->gprmask);
 	a->cprmask[0] = swab32(a->cprmask[0]);
 	a->cprmask[1] = swab32(a->cprmask[1]);
 	a->cprmask[2] = swab32(a->cprmask[2]);
 	a->cprmask[3] = swab32(a->cprmask[3]);
-	a->gp_value   = swab32(a->gp_value);
+	a->gp_value = swab32(a->gp_value);
 }
 
-void convert_ecoff_esecs(struct scnhdr *s, int num)
+static void convert_ecoff_esecs(struct scnhdr *s, int num)
 {
 	int i;
 
 	for (i = 0; i < num; i++, s++) {
-		s->s_paddr   = swab32(s->s_paddr);
-		s->s_vaddr   = swab32(s->s_vaddr);
-		s->s_size    = swab32(s->s_size);
-		s->s_scnptr  = swab32(s->s_scnptr);
-		s->s_relptr  = swab32(s->s_relptr);
+		s->s_paddr = swab32(s->s_paddr);
+		s->s_vaddr = swab32(s->s_vaddr);
+		s->s_size = swab32(s->s_size);
+		s->s_scnptr = swab32(s->s_scnptr);
+		s->s_relptr = swab32(s->s_relptr);
 		s->s_lnnoptr = swab32(s->s_lnnoptr);
-		s->s_nreloc  = swab16(s->s_nreloc);
-		s->s_nlnno   = swab16(s->s_nlnno);
-		s->s_flags   = swab32(s->s_flags);
+		s->s_nreloc = swab16(s->s_nreloc);
+		s->s_nlnno = swab16(s->s_nlnno);
+		s->s_flags = swab32(s->s_flags);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	Elf32_Ehdr ex;
+	Elf32_Phdr *ph;
+	Elf32_Shdr *sh;
+	char *shstrtab;
+	int i, pad;
+	struct sect text, data, bss;
+	struct filehdr efh;
+	struct aouthdr eah;
+	struct scnhdr esecs[6];
+	int infile, outfile;
+	unsigned long cur_vma = ULONG_MAX;
+	int addflag = 0;
+	int nosecs;
+
+	text.len = data.len = bss.len = 0;
+	text.vaddr = data.vaddr = bss.vaddr = 0;
+
+	/* Check args... */
+	if (argc < 3 || argc > 4) {
+	      usage:
+		fprintf(stderr,
+			"usage: elf2aout <elf executable> <a.out executable> [-a]\n");
+		exit(1);
+	}
+	if (argc == 4) {
+		if (strcmp(argv[3], "-a"))
+			goto usage;
+		addflag = 1;
+	}
+
+	/* Try the input file... */
+	if ((infile = open(argv[1], O_RDONLY)) < 0) {
+		fprintf(stderr, "Can't open %s for read: %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+
+	/* Read the header, which is at the beginning of the file... */
+	i = read(infile, &ex, sizeof(ex));
+	if (i != sizeof(ex)) {
+		fprintf(stderr, "ex: %s: %s.\n", argv[1],
+			i ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+
+	if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+		format_bigendian = 1;
+
+	if (ntohs(0xaa55) == 0xaa55) {
+		if (!format_bigendian)
+			must_convert_endian = 1;
+	} else {
+		if (format_bigendian)
+			must_convert_endian = 1;
+	}
+	if (must_convert_endian)
+		convert_elf_hdr(&ex);
+
+	/* Read the program headers... */
+	ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+				     ex.e_phnum * sizeof(Elf32_Phdr), "ph");
+	if (must_convert_endian)
+		convert_elf_phdrs(ph, ex.e_phnum);
+	/* Read the section headers... */
+	sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
+				     ex.e_shnum * sizeof(Elf32_Shdr),
+				     "sh");
+	if (must_convert_endian)
+		convert_elf_shdrs(sh, ex.e_shnum);
+	/* Read in the section string table. */
+	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
+			    sh[ex.e_shstrndx].sh_size, "shstrtab");
+
+	/* Figure out if we can cram the program header into an ECOFF
+	   header...  Basically, we can't handle anything but loadable
+	   segments, but we can ignore some kinds of segments.  We can't
+	   handle holes in the address space.  Segments may be out of order,
+	   so we sort them first. */
+
+	qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+
+	for (i = 0; i < ex.e_phnum; i++) {
+		/* Section types we can ignore... */
+		if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+		    ph[i].p_type == PT_PHDR
+		    || ph[i].p_type == PT_MIPS_REGINFO)
+			continue;
+		/* Section types we can't handle... */
+		else if (ph[i].p_type != PT_LOAD) {
+			fprintf(stderr,
+				"Program header %d type %d can't be converted.\n",
+				ex.e_phnum, ph[i].p_type);
+			exit(1);
+		}
+		/* Writable (data) segment? */
+		if (ph[i].p_flags & PF_W) {
+			struct sect ndata, nbss;
+
+			ndata.vaddr = ph[i].p_vaddr;
+			ndata.len = ph[i].p_filesz;
+			nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+			nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+			combine(&data, &ndata, 0);
+			combine(&bss, &nbss, 1);
+		} else {
+			struct sect ntxt;
+
+			ntxt.vaddr = ph[i].p_vaddr;
+			ntxt.len = ph[i].p_filesz;
+
+			combine(&text, &ntxt, 0);
+		}
+		/* Remember the lowest segment start address. */
+		if (ph[i].p_vaddr < cur_vma)
+			cur_vma = ph[i].p_vaddr;
+	}
+
+	/* Sections must be in order to be converted... */
+	if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+	    text.vaddr + text.len > data.vaddr
+	    || data.vaddr + data.len > bss.vaddr) {
+		fprintf(stderr,
+			"Sections ordering prevents a.out conversion.\n");
+		exit(1);
+	}
+
+	/*
+	 * If there's a data section but no text section, then the loader
+	 * combined everything into one section.   That needs to be the text
+	 * section, so just make the data section zero length following text.
+	 */
+	if (data.len && !text.len) {
+		text = data;
+		data.vaddr = text.vaddr + text.len;
+		data.len = 0;
+	}
+
+	/*
+	 * If there is a gap between text and data, we'll fill it when we copy
+	 * the data, so update the length of the text segment as represented in
+	 * a.out to reflect that, since a.out doesn't allow gaps in the program
+	 * address space.
+	 */
+	if (text.vaddr + text.len < data.vaddr)
+		text.len = data.vaddr - text.vaddr;
+
+	/* We now have enough information to cons up an a.out header... */
+	eah.magic = OMAGIC;
+	eah.vstamp = 200;
+	eah.tsize = text.len;
+	eah.dsize = data.len;
+	eah.bsize = bss.len;
+	eah.entry = ex.e_entry;
+	eah.text_start = text.vaddr;
+	eah.data_start = data.vaddr;
+	eah.bss_start = bss.vaddr;
+	eah.gprmask = 0xf3fffffe;
+	memset(&eah.cprmask, '\0', sizeof(eah.cprmask));
+	eah.gp_value = 0;	/* unused. */
+
+	if (format_bigendian)
+		efh.f_magic = MIPSEBMAGIC;
+	else
+		efh.f_magic = MIPSELMAGIC;
+	if (addflag)
+		nosecs = 6;
+	else
+		nosecs = 3;
+	efh.f_nscns = nosecs;
+	efh.f_timdat = 0;	/* bogus */
+	efh.f_symptr = 0;
+	efh.f_nsyms = 0;
+	efh.f_opthdr = sizeof(eah);
+	efh.f_flags = 0x100f;	/* Stripped, not sharable. */
+
+	memset(esecs, 0, sizeof(esecs));
+	strcpy(esecs[0].s_name, ".text");
+	strcpy(esecs[1].s_name, ".data");
+	strcpy(esecs[2].s_name, ".bss");
+	if (addflag) {
+		strcpy(esecs[3].s_name, ".rdata");
+		strcpy(esecs[4].s_name, ".sdata");
+		strcpy(esecs[5].s_name, ".sbss");
+	}
+	esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
+	esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
+	esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
+	if (addflag) {
+		esecs[3].s_paddr = esecs[3].s_vaddr = 0;
+		esecs[4].s_paddr = esecs[4].s_vaddr = 0;
+		esecs[5].s_paddr = esecs[5].s_vaddr = 0;
+	}
+	esecs[0].s_size = eah.tsize;
+	esecs[1].s_size = eah.dsize;
+	esecs[2].s_size = eah.bsize;
+	if (addflag) {
+		esecs[3].s_size = 0;
+		esecs[4].s_size = 0;
+		esecs[5].s_size = 0;
 	}
+	esecs[0].s_scnptr = N_TXTOFF(efh, eah);
+	esecs[1].s_scnptr = N_DATOFF(efh, eah);
+#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
+#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
+	esecs[2].s_scnptr = esecs[1].s_scnptr +
+	    ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
+	if (addflag) {
+		esecs[3].s_scnptr = 0;
+		esecs[4].s_scnptr = 0;
+		esecs[5].s_scnptr = 0;
+	}
+	esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
+	esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
+	esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
+	esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
+	if (addflag) {
+		esecs[3].s_relptr = esecs[4].s_relptr
+		    = esecs[5].s_relptr = 0;
+		esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
+		    = esecs[5].s_lnnoptr = 0;
+		esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
+		    0;
+		esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
+	}
+	esecs[0].s_flags = 0x20;
+	esecs[1].s_flags = 0x40;
+	esecs[2].s_flags = 0x82;
+	if (addflag) {
+		esecs[3].s_flags = 0x100;
+		esecs[4].s_flags = 0x200;
+		esecs[5].s_flags = 0x400;
+	}
+
+	/* Make the output file... */
+	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
+		fprintf(stderr, "Unable to create %s: %s\n", argv[2],
+			strerror(errno));
+		exit(1);
+	}
+
+	if (must_convert_endian)
+		convert_ecoff_filehdr(&efh);
+	/* Write the headers... */
+	i = write(outfile, &efh, sizeof(efh));
+	if (i != sizeof efh) {
+		perror("efh: write");
+		exit(1);
+	}
+
+	for (i = 0; i < nosecs; i++) {
+		printf("Section %d: %s phys %lx  size %lx  file offset %lx\n",
+		       i, esecs[i].s_name, esecs[i].s_paddr,
+		       esecs[i].s_size, esecs[i].s_scnptr);
+	}
+	fprintf(stderr, "wrote %d byte file header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_aouthdr(&eah);
+	i = write(outfile, &eah, sizeof(eah));
+	if (i != sizeof(eah)) {
+		perror("eah: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d byte a.out header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_esecs(&esecs[0], nosecs);
+	i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
+	if (i != nosecs * sizeof(struct scnhdr)) {
+		perror("esecs: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d bytes of section headers.\n", i);
+
+	pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
+	if (pad) {
+		pad = 16 - pad;
+		i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
+		if (i < 0) {
+			perror("ipad: write");
+			exit(1);
+		}
+		fprintf(stderr, "wrote %d byte pad.\n", i);
+	}
+
+	/*
+	 * Copy the loadable sections.   Zero-fill any gaps less than 64k;
+	 * complain about any zero-filling, and die if we're asked to zero-fill
+	 * more than 64k.
+	 */
+	for (i = 0; i < ex.e_phnum; i++) {
+		/*
+		 * Unprocessable sections were handled above, so just verify
+		 * that the section can be loaded before copying.
+		 */
+		if (ph[i].p_type != PT_LOAD || ph[i].p_filesz == 0)
+			continue;
+
+		if (cur_vma != ph[i].p_vaddr) {
+			unsigned long gap = ph[i].p_vaddr - cur_vma;
+			char obuf[1024];
+
+			if (gap > 65536) {
+				fprintf(stderr, "Intersegment gap (%ld "
+				        "bytes) too large.\n", gap);
+				exit(1);
+			}
+			fprintf(stderr, "Warning: %ld byte intersegment gap.\n",
+					gap);
+			memset(obuf, 0, sizeof(obuf));
+			while (gap) {
+				int count = write(outfile, obuf,
+				   gap > sizeof(obuf) ?  sizeof(obuf) : gap);
+				if (count < 0) {
+					fprintf(stderr,
+						"Error writing gap: %s\n",
+						strerror(errno));
+					exit(1);
+				}
+				gap -= count;
+			}
+		}
+		fprintf(stderr, "writing %d bytes...\n", ph[i].p_filesz);
+		copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz);
+		cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
+	}
+
+	/*
+	 * Write a page of padding for boot PROMS that read entire pages.
+	 * Without this, they may attempt to read past the end of the
+	 * data section, incur an error, and refuse to boot.
+	 */
+	{
+		char obuf[4096];
+		memset(obuf, 0, sizeof(obuf));
+		if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
+			fprintf(stderr, "Error writing PROM padding: %s\n",
+				strerror(errno));
+			exit(1);
+		}
+	}
+
+	/* Looks like we won... */
+	exit(0);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/int-handler.S linux-2.4.20/arch/mips/cobalt/int-handler.S
--- linux-2.4.19/arch/mips/cobalt/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/int-handler.S	2002-10-04 00:41:13.000000000 +0000
@@ -26,8 +26,8 @@
 		SAVE_ALL
 		CLI
 		.set	at
-	
-		/* 
+
+		/*
 		 * Get pending Interrupts
 		 */
 		mfc0	s0,CP0_CAUSE	# get irq mask
@@ -52,30 +52,30 @@
 		j	ret_from_irq
 		 nop
 
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP3 */
 		 andi	a0,s0,CAUSEF_IP4
 
 		/* Ethernet 0 interrupt */
-		li	a0,4
+		li	a0,COBALT_RAQ_ETH0_IRQ
 		jal     do_IRQ
 		 move	a1,sp
 
 		j	ret_from_irq
 		 nop
 
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP4 */
 		 andi	a0,s0,CAUSEF_IP5
 
 		/* Ethernet 1 interrupt */
-		li	a0,13
+		li	a0,COBALT_RAQ_ETH1_IRQ
 		jal     do_IRQ
 		 move	a1,sp
 
 		j	ret_from_irq
 		 nop
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP5 */
 		 andi	a0,s0,CAUSEF_IP7
 
@@ -86,7 +86,7 @@
 
 		j	ret_from_irq
 		 nop
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP7 */
 		  nop
 
@@ -100,4 +100,4 @@
 		 nop
 
 		END(cobalt_handle_int)
-	
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/irq.c linux-2.4.20/arch/mips/cobalt/irq.c
--- linux-2.4.19/arch/mips/cobalt/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/irq.c	2002-10-04 00:41:11.000000000 +0000
@@ -42,11 +42,12 @@
  *    4   - Tulip 1
  *    5   - 16550 UART
  *    6   - VIA southbridge PIC
- *    7   - PCI
+ *    7   - unused
  *
- * The VIA chip is a master/slave 8259 setup and has the 
+ * The VIA chip is a master/slave 8259 setup and has the
  *  following interrupts
  *    8   - RTC
+ *    9   - PCI
  *    14  - IDE0
  *    15  - IDE1
  *
@@ -61,8 +62,8 @@
 
 #define COBALT_IRQS	16
 
-static unsigned short irqnr_to_type[COBALT_IRQS] = 
-{ CPUINT_LINE(0),  NOINT_LINE,      VIAINT_LINE,  NOINT_LINE, 
+static unsigned short irqnr_to_type[COBALT_IRQS] =
+{ CPUINT_LINE(0),  NOINT_LINE,      VIAINT_LINE,  NOINT_LINE,
   CPUINT_LINE(1),  NOINT_LINE,      NOINT_LINE,   CPUINT_LINE(3),
   VIAINT_LINE,     VIAINT_LINE,     NOINT_LINE,   NOINT_LINE,
   NOINT_LINE,      CPUINT_LINE(2),  VIAINT_LINE,  VIAINT_LINE };
@@ -116,102 +117,20 @@
 	NULL
 };
 
-
-/*
- * Cobalt VIA irq
- */
-
-static void enable_via_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	unmask_irq(irq);
-	restore_flags(flags);
-}
-
-static unsigned startup_via_irq(unsigned int irq)
-{
-	enable_via_irq(irq);
-
-	return 0;
-}
-
-static void disable_via_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mask_irq(irq);
-	restore_flags(flags);
-}
-
-#define shutdown_via_irq	disable_via_irq
-#define mask_and_ack_via_irq	disable_via_irq
-
-static void end_via_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_via_irq(irq);
-}
-
-static struct hw_interrupt_type cobalt_via_irq_type = {
-	"Cobalt VIA",
-	startup_via_irq,
-	shutdown_via_irq,
-	enable_via_irq,
-	disable_via_irq,
-	mask_and_ack_via_irq,
-	end_via_irq,
-	NULL
-};
-
-
-static struct irqaction via_irq2 = {
-	no_action, 0, 0, "slave cascade", NULL, NULL
-};
-
-static struct resource pic1_io_resource = {
-	"VIA PIC Master", 0x20, 0x3f, IORESOURCE_BUSY
-};
-
-static struct resource pic2_io_resource = {
-	"VIA PIC Slave", 0xa0, 0xbf, IORESOURCE_BUSY
-};
-
-
 void __init init_IRQ(void)
 {
 	int i;
 
 	/* Initialise all of the IRQ descriptors */
-	init_generic_irq();
+	init_i8259_irqs();
 
 	/* Map the irqnr to the type int we have */
 	for (i=0; i < COBALT_IRQS; i++) {
 		if (irqnr_to_type[i] >= CPUINT_LINE(0))
 			/* cobalt_cpu_irq_type */
 			irq_desc[i].handler = &cobalt_cpu_irq_type;
-		else if (irqnr_to_type[i] == VIAINT_LINE)
-			/* VIA/8259 irq_type */
-			irq_desc[i].handler = &cobalt_via_irq_type;
-		else {} /* Leave it as disabled/no handler */
 	}
 
-	/* Setup the VIA interrupts */
-	request_resource(&ioport_resource, &pic1_io_resource);
-	request_resource(&ioport_resource, &pic2_io_resource);
-	setup_irq(2, &via_irq2);
-
-	/* This may be too simple.. FIX it later */
-	VIA_PORT_WRITE(0x20, 0x10);
-	VIA_PORT_WRITE(0x21, 0x00);
-	VIA_PORT_WRITE(0x21, 0x00);
-
-	VIA_PORT_WRITE(0xa0, 0x10);
-	VIA_PORT_WRITE(0xa1, 0x00);
-	VIA_PORT_WRITE(0xa1, 0x00);
-
 	/* Mask all cpu interrupts
 	    (except IE4, we already masked those at VIA level) */
 	clear_cp0_status(ST0_IM);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/pci.c linux-2.4.20/arch/mips/cobalt/pci.c
--- linux-2.4.19/arch/mips/cobalt/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/pci.c	2002-10-04 00:41:29.000000000 +0000
@@ -19,9 +19,11 @@
 #include <asm/cobalt/cobalt.h>
 #include <asm/pci.h>
 #include <asm/io.h>
- 
+
 #ifdef CONFIG_PCI
 
+int cobalt_board_id;
+
 static void qube_expansion_slot_bist(struct pci_dev *dev)
 {
 	unsigned char ctrl;
@@ -56,6 +58,7 @@
 
 	/* Give it a working IRQ. */
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_QUBE_SLOT_IRQ);
+	dev->irq = COBALT_QUBE_SLOT_IRQ;
 
 	/* Fixup base addresses, we only support I/O at the moment. */
 	for(i = 0; i <= 5; i++) {
@@ -119,24 +122,22 @@
 static void qube_raq_tulip_fixup(struct pci_dev *dev)
 {
 	unsigned short pci_cmd;
-	extern int cobalt_is_raq;
 
 	/* Fixup the first tulip located at device PCICONF_ETH0 */
 	if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH0) {
 		/*
-		 * Now tell the Ethernet device that we expect an interrupt at
-		 * IRQ 13 and not the default 189.
-		 *
 		 * The IRQ of the first Tulip is different on Qube and RaQ
 		 */
-		if (!cobalt_is_raq) {
-			/* All Qube's route this the same way. */
+		if (cobalt_board_id == COBALT_BRD_ID_RAQ2) {
+			/* Setup the first Tulip on the RAQ */
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-                                              COBALT_QUBE_ETH_IRQ);
+					      COBALT_RAQ_ETH0_IRQ);
+			dev->irq = COBALT_RAQ_ETH0_IRQ;
 		} else {
-			/* Setup the first Tulip on the RAQ */
+			/* All Qube's route this the same way. */
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-                                              COBALT_RAQ_ETH0_IRQ);
+					      COBALT_QUBE_ETH_IRQ);
+			dev->irq = COBALT_QUBE_ETH_IRQ;
 		}
 		dev->resource[0].start = 0x100000;
 		dev->resource[0].end = 0x10007f;
@@ -156,6 +157,7 @@
 		/* Give it it's IRQ. */
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
                                       COBALT_RAQ_ETH1_IRQ);
+		dev->irq = COBALT_RAQ_ETH1_IRQ;
 
 		/* And finally, a usable I/O space allocation, right after what
 		 * the first Tulip uses.
@@ -168,15 +170,15 @@
 static void qube_raq_scsi_fixup(struct pci_dev *dev)
 {
 	unsigned short pci_cmd;
-	extern int cobalt_is_raq;
 
         /*
          * Tell the SCSI device that we expect an interrupt at
          * IRQ 7 and not the default 0.
          */
         pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_SCSI_IRQ);
+	dev->irq = COBALT_SCSI_IRQ;
 
-	if (cobalt_is_raq) {
+	if (cobalt_board_id == COBALT_BRD_ID_RAQ2) {
 
 		/* Enable the device. */
 		pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
@@ -186,7 +188,8 @@
 		pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
 
 		/* Give it it's RAQ IRQ. */
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_RAQ_SCSI_IRQ);
+		dev->irq = COBALT_RAQ_SCSI_IRQ;
 
 		/* And finally, a usable I/O space allocation, right after what
 		 * the second Tulip uses.
@@ -252,11 +255,11 @@
 };
 
 
-static __inline__ int pci_range_ck(struct pci_dev *dev) 
+static __inline__ int pci_range_ck(struct pci_dev *dev)
 {
-       if ((dev->bus->number == 0) 
-           && ((PCI_SLOT (dev->devfn) == 0) 
-               || ((PCI_SLOT (dev->devfn) > 6) 
+       if ((dev->bus->number == 0)
+           && ((PCI_SLOT (dev->devfn) == 0)
+               || ((PCI_SLOT (dev->devfn) > 6)
                    && (PCI_SLOT (dev->devfn) <= 12))))
 		return 0;  /* OK device number  */
 
@@ -328,7 +331,7 @@
 
 static int
 qube_pci_write_config_word (struct pci_dev *dev,
-                                int where, 
+                                int where,
                                u16 val)
 {
 	unsigned long tmp;
@@ -347,7 +350,7 @@
 
 static int
 qube_pci_write_config_byte (struct pci_dev *dev,
-                                int where, 
+                                int where,
                                u8 val)
 {
 	unsigned long tmp;
@@ -374,8 +377,18 @@
 
 void __init pcibios_init(void)
 {
+	struct pci_dev dev;
+
 	printk("PCI: Probing PCI hardware\n");
 
+	/* Read the cobalt id register out of the PCI config space */
+	dev.devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
+	PCI_CFG_SET(&dev, (VIA_COBALT_BRD_ID_REG & ~0x3));
+	cobalt_board_id = *PCI_CFG_DATA >> ((VIA_COBALT_BRD_ID_REG & 3) * 8);
+	cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+
+	printk("Cobalt Board ID: %d\n", cobalt_board_id);
+
 	ioport_resource.start = 0x00000000;
 	ioport_resource.end = 0x0fffffff;
 
@@ -393,7 +406,7 @@
 int pcibios_enable_device(struct pci_dev *dev)
 {
 	u16 cmd, status;
-	
+
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	pci_read_config_word(dev, PCI_STATUS, &status);
 	printk("PCI: Enabling device %s (%04x  %04x)\n", dev->slot_name, cmd, status);
@@ -403,13 +416,13 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-		unsigned long size)
+		unsigned long size, unsigned long align)
 {
 
 	panic("Uhhoh called pcibios_align_resource\n");
 }
 
-void pcibios_update_resource(struct pci_dev *dev, struct resource *root, 
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 		struct resource *res, int resource)
 {
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/promcon.c linux-2.4.20/arch/mips/cobalt/promcon.c
--- linux-2.4.19/arch/mips/cobalt/promcon.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/promcon.c	2002-10-04 00:41:30.000000000 +0000
@@ -70,7 +70,7 @@
 	ns16550_cons_put_char(kgdb_char, port);
 }
 
-static kdev_t 
+static kdev_t
 ns16550_console_dev(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/reset.c linux-2.4.20/arch/mips/cobalt/reset.c
--- linux-2.4.19/arch/mips/cobalt/reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/reset.c	2002-10-04 00:41:11.000000000 +0000
@@ -49,14 +49,14 @@
 	/* Blink our cute? little LED (number 3)... */
 	while (1) {
 		led_state = led_state | ( 1 << 3 );
-		LEDSet(led_state);  
+		LEDSet(led_state);
 		mark = jiffies;
 		while (jiffies<(mark+HZ));
 		led_state = led_state & ~( 1 << 3 );
 		LEDSet(led_state);
 		mark = jiffies;
 		while (jiffies<(mark+HZ));
-	} 
+	}
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/setup.c linux-2.4.20/arch/mips/cobalt/setup.c
--- linux-2.4.19/arch/mips/cobalt/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/setup.c	2002-10-04 00:41:13.000000000 +0000
@@ -35,7 +35,17 @@
 extern struct ide_ops std_ide_ops;
 
 
-char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 root=/dev/hda1" };
+char arcs_cmdline[CL_SIZE] = {
+ "console=ttyS0,115200 "
+#ifdef CONFIG_IP_PNP
+ "ip=on "
+#endif
+#ifdef CONFIG_ROOT_NFS
+ "root=/dev/nfs "
+#else
+ "root=/dev/hda1 "
+#endif
+ };
 
 const char *get_system_type(void)
 {
@@ -63,23 +73,19 @@
 	*timer_reg = 500000;
 
 	/* Register our timer interrupt */
-	setup_irq(0, irq);
+	setup_irq(COBALT_TIMER_IRQ, irq);
 
 	/* Enable timer ints */
-	*((volatile unsigned long *) GALILEO_TIMER_CTRL) = 
+	*((volatile unsigned long *) GALILEO_TIMER_CTRL) =
 			(unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0);
 	/* Unmask timer int */
-	*((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; 
+	*((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100;
 }
 
 
 void __init bus_error_init(void) { /* nothing */ }
 
 
-int cobalt_serial_present;
-int cobalt_serial_type;
-int cobalt_is_raq;
-
 void __init cobalt_setup(void)
 {
 
@@ -95,21 +101,13 @@
 #endif
         set_io_port_base(0xb0000000);
 
-	/* 
+	/*
 	 * This is a prom style console. We just poke at the
 	 *  UART to make it talk.
 	 * Only use this console if you really screw up and can't
 	 *  get to the stage of setting up a real serial console.
 	 */
 	/*ns16550_setup_console();*/
-
-	/* We have to do this early, here, before the value could
-	 * possibly be overwritten by the bootup sequence.
-	 */
-	cobalt_serial_present = *((unsigned long *) 0xa020001c);
-	cobalt_serial_type    = *((unsigned long *) 0xa0200020);
-	cobalt_is_raq         = (cobalt_serial_present != 0x0
-				 && cobalt_serial_type == 0x1);
 }
 
 /* Prom init. We read our one and only communication with the
@@ -117,7 +115,7 @@
 void __init prom_init(int argc)
 {
 	mips_machgroup = MACH_GROUP_COBALT;
-	
+
 	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/via.c linux-2.4.20/arch/mips/cobalt/via.c
--- linux-2.4.19/arch/mips/cobalt/via.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/cobalt/via.c	2002-10-04 00:41:13.000000000 +0000
@@ -18,62 +18,30 @@
 
 extern void do_IRQ(int irq, struct pt_regs * regs);
 
-/* Cached values of VIA PIC masks, we start with cascade enabled */
-static unsigned int cached_irq_mask = 0xfffb;
-
-#define __byte(x,y)	(((unsigned char *)&(y))[x])
-#define cached_21	(__byte(0,cached_irq_mask))
-#define cached_A1	(__byte(1,cached_irq_mask))
-
-
-void mask_irq(unsigned int irq)
-{
-	unsigned int mask = 1 << irq;
-
-	cached_irq_mask |= mask;
-	if (irq & 8) {
-		VIA_PORT_WRITE(0xA1, cached_A1);
-	} else {
-		VIA_PORT_WRITE(0x21, cached_21);
-	}
-}
-
-void unmask_irq(unsigned int irq)
-{
-	unsigned int mask = ~(1 << irq);
-
-	cached_irq_mask &= mask;
-	if (irq & 8) {
-		VIA_PORT_WRITE(0xA1, cached_A1);
-	} else {
-		VIA_PORT_WRITE(0x21, cached_21);
-	}
-}
-
 asmlinkage void via_irq(struct pt_regs *regs)
 {
 	char mstat, sstat;
-  
+
 	/* Read Master Status */
-	VIA_PORT_WRITE(0x20, 0x0C);
-	mstat = VIA_PORT_READ(0x20);
- 
+	outb(0x0C, 0x20);
+	mstat = inb(0x20);
+
 	if (mstat < 0) {
 		mstat &= 0x7f;
-		if (mstat != 2) {     	
+		if (mstat != 2) {
 			do_IRQ(mstat, regs);
-			VIA_PORT_WRITE(0x20, mstat | 0x20);
+			outb(mstat | 0x20, 0x20);
 		} else {
-			sstat = VIA_PORT_READ(0xA0);
+			sstat = inb(0xA0);
 
 			/* Slave interrupt */
-			VIA_PORT_WRITE(0xA0, 0x0C);
-			sstat = VIA_PORT_READ(0xA0);
-   
+			outb(0x0C, 0xA0);
+			sstat = inb(0xA0);
+
 			if (sstat < 0) {
 				do_IRQ((sstat + 8) & 0x7f, regs);
-				VIA_PORT_WRITE(0x20, 0x22);       
-				VIA_PORT_WRITE(0xA0, (sstat & 0x7f) | 0x20);
+				outb(0x22, 0x20);
+				outb((sstat & 0x7f) | 0x20, 0xA0);
 			} else {
 				printk("Spurious slave interrupt...\n");
 			}
@@ -87,13 +55,13 @@
 
 asmlinkage void galileo_irq(struct pt_regs *regs)
 {
-	unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); 
+	unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE);
 
 	/* Check for timer irq ... */
 	if (irq_src & GALILEO_T0EXP) {
 		/* Clear the int line */
 		*((volatile unsigned long *) GALILEO_INTCAUSE) = 0;
-		do_IRQ(0, regs);
+		do_IRQ(COBALT_TIMER_IRQ, regs);
 	} else
 		printk("Spurious Galileo interrupt...\n");
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/config-shared.in linux-2.4.20/arch/mips/config-shared.in
--- linux-2.4.19/arch/mips/config-shared.in	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/config-shared.in	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,803 @@
+mainmenu_name "Linux/MIPS Kernel Configuration"
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+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 module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Machine selection'
+dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32
+if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
+   bool '  Support for PCI AUTO Config' CONFIG_PCI_AUTO
+fi
+dep_bool 'Support for Alchemy Semi PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32
+dep_bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32
+dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL
+dep_bool 'Support for DECstations' CONFIG_DECSTATION $CONFIG_MIPS32
+dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
+   bool '  Enable Second PCI (PCI1)' CONFIG_EVB_PCI1
+   choice '  Galileo Chip Clock' \
+	"75	CONFIG_SYSCLK_75 \
+	 83.3	CONFIG_SYSCLK_83 \
+	 100	CONFIG_SYSCLK_100" 83.3
+fi
+dep_bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 $CONFIG_EXPERIMENTAL
+bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR
+bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET
+bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
+   bool '  Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC
+fi
+dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL
+bool 'Support for MIPS Magnum 4000' CONFIG_MIPS_MAGNUM_4000
+dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL
+dep_bool 'Support for MIPS SEAD board (EXPERIMENTAL)' CONFIG_MIPS_SEAD $CONFIG_EXPERIMENTAL
+bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT
+bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G
+dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL
+bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476
+bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477
+if [ "$CONFIG_DDB5477" = "y" ]; then
+   int '   bus frequency (in kHZ, 0 for auto-detect)' CONFIG_DDB5477_BUS_FREQUENCY 0
+fi
+bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY
+bool 'Support for NEC Eagle/Hawk board' CONFIG_NEC_EAGLE
+bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
+dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_NINO" = "y" ]; then
+   choice 'Nino Model Number' \
+	"Model-300/301/302/319			CONFIG_NINO_4MB \
+	 Model-200/210/312/320/325/350/390	CONFIG_NINO_8MB \
+	 Model-500/510				CONFIG_NINO_16MB" Model-200
+fi
+bool 'Support for SGI IP22 (Indy/Indigo2)' CONFIG_SGI_IP22
+dep_bool 'Support for SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
+   bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   bool '  NUMA Support' CONFIG_NUMA
+   bool '  Mapped kernel support' CONFIG_MAPPED_KERNEL
+   bool '  Kernel text replication support' CONFIG_REPLICATE_KTEXT
+   bool '  Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS
+   bool '  Multi-Processing support' CONFIG_SMP
+   #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
+fi
+dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)' CONFIG_SIBYTE_SB1xxx_SOC $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
+   choice '   BCM1xxx SOC Type' \
+	  "BCM1250          CONFIG_SIBYTE_SB1250" BCM1250
+
+   bool '   Running under simulation' CONFIG_SIMULATION
+   bool '   Booting from CFE' CONFIG_SIBYTE_CFE
+   dep_bool '     Use firmware console' CONFIG_SIBYTE_CFE_CONSOLE $CONFIG_SIBYTE_CFE
+   if [ "$CONFIG_SIBYTE_CFE" = "n" ]; then
+      define_bool CONFIG_SIBYTE_STANDALONE y
+      int  '   Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32
+   fi
+
+   bool '   Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
+   bool '   Support for ZBbus profiling' CONFIG_BCM1250_TBPROF
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      if [ "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then
+	 bool '   Multi-Processing support' CONFIG_SMP
+      fi
+   fi
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      bool '   Support for BCM1250/BCM112x onchip PCI controller' CONFIG_PCI
+   fi
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      bool '   Support for SWARM board' CONFIG_SIBYTE_SWARM
+   fi
+fi
+bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32
+bool 'Support for ZAO Networks Capcella' CONFIG_ZAO_CAPCELLA
+
+dep_bool 'High Memory Support' CONFIG_HIGHMEM $CONFIG_MIPS32
+
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+#
+# Select some configuration options automatically based on user selections.
+#
+
+if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_MIPS_JAZZ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_ROTTEN_IRQ y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_AU1000_USB_DEVICE y
+fi
+if [ "$CONFIG_MIPS_PB1100" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PCI_AUTO n
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_AU1000_USB_DEVICE y
+fi
+if [ "$CONFIG_MIPS_PB1500" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_AU1000_USB_DEVICE y
+fi
+if [ "$CONFIG_ALGOR_P4032" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_COBALT" = "y" ]; then
+   define_bool CONFIG_COBALT_LCD y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_MIPS_GT64120 y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_MIPS_GT96100 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_SWAP_IO_SPACE y
+fi
+if [ "$CONFIG_MIPS_IVR" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_IT8172_CIR y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+fi
+if [ "$CONFIG_HP_LASERJET" = "y" ]; then
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   #not yet define_bool CONFIG_PCI_AUTO y
+fi
+if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_IT8712 y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_IT8172_CIR y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+fi
+if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SWAP_IO_SPACE y
+fi
+if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
+     "$CONFIG_OLIVETTI_M700"    = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_FB y
+   define_bool CONFIG_FB_G364 y
+   define_bool CONFIG_MIPS_JAZZ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_I8259 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_MIPS_SEAD" = "y" ]; then
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI n
+fi
+if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SYSCLK_100 y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SYSCLK_100 y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_DDB5074" = "y" ]; then
+   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_PCI y
+fi
+if [ "$CONFIG_DDB5476"  = "y" ]; then
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+if [ "$CONFIG_DDB5477" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_I8259 y
+fi
+if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
+   define_bool CONFIG_VR4181 y
+   define_bool CONFIG_SERIAL y
+   define_bool CONFIG_SERIAL_MANY_PORTS y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SCSI n
+fi
+if [ "$CONFIG_NEC_EAGLE" = "y" ]; then
+   define_bool CONFIG_CPU_VR41XX y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_VR41XX_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SCSI n
+fi
+if [ "$CONFIG_NINO" = "y" ]; then
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+fi
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_ARC_CONSOLE y
+   define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_IRQ_CPU y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SGI y
+fi
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF64 y
+   define_bool CONFIG_ARC64 y
+   #define_bool CONFIG_MAPPED_PCI_IO y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_QL_ISP_A64 y
+   define_int CONFIG_L1_CACHE_SHIFT 7
+fi
+if [ "$CONFIG_SGI_IP32" = "y" ]; then
+   define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_ARC32 y
+   #define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_BOOT_ELF32 y
+fi
+if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_I8259 y
+   define_bool CONFIG_ISA y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
+   define_bool CONFIG_TOSHIBA_BOARDS y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_PC_KEYB y
+fi
+if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then
+   define_bool CONFIG_CPU_VR41XX y
+   define_bool CONFIG_CPU_LITTLE_ENDIAN y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_VR41XX_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SCSI n
+fi
+
+if [ "$CONFIG_MIPS_AU1000" != "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'CPU selection'
+
+choice 'CPU type' \
+	"MIPS32	CONFIG_CPU_MIPS32 \
+	 MIPS64	CONFIG_CPU_MIPS64 \
+	 R3000	CONFIG_CPU_R3000 \
+	 R39XX	CONFIG_CPU_TX39XX \
+	 R41xx	CONFIG_CPU_VR41XX \
+	 R4300	CONFIG_CPU_R4300 \
+	 R4x00	CONFIG_CPU_R4X00 \
+	 R49XX	CONFIG_CPU_TX49XX \
+	 R5000	CONFIG_CPU_R5000 \
+	 R5432	CONFIG_CPU_R5432 \
+	 R6000	CONFIG_CPU_R6000 \
+	 R52xx	CONFIG_CPU_NEVADA \
+	 R8000	CONFIG_CPU_R8000 \
+	 R10000	CONFIG_CPU_R10000 \
+	 RM7000	CONFIG_CPU_RM7000 \
+	 SB1	CONFIG_CPU_SB1" R4x00
+
+if [ "$CONFIG_CPU_R5000" = "y" ]; then
+   define_bool CONFIG_BOARD_SCACHE y
+fi
+
+if [ "$CONFIG_CPU_NEVADA" = "y" ]; then
+   define_bool CONFIG_BOARD_SCACHE y
+fi
+ 
+if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
+fi
+
+if [ "$CONFIG_CPU_MIPS64" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
+fi
+
+if [ "$CONFIG_CPU_RM7000" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_PREFETCH y
+fi
+
+if [ "$CONFIG_CPU_SB1" = "y" ]; then
+   choice 'SB1 Pass' \
+	 "Pass1   CONFIG_CPU_SB1_PASS_1  \
+	  Pass2   CONFIG_CPU_SB1_PASS_2
+	  Pass2.2 CONFIG_CPU_SB1_PASS_2_2" Pass1
+   if [ "$CONFIG_CPU_SB1_PASS_1" = "y" ]; then
+      define_bool CONFIG_SB1_PASS_1_WORKAROUNDS y
+   fi
+   if [ "$CONFIG_CPU_SB1_PASS_2" = "y" ]; then
+      define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y
+   else
+      # Avoid prefetches on Pass 2 (before 2.2)
+      bool '  Enable prefetches' CONFIG_CPU_HAS_PREFETCH
+   fi
+   if [ "$CONFIG_CPU_SB1_PASS_2_2" = "y" ]; then
+      # XXXKW for now, let 2.2 use same WORKAROUNDS flag as pre-2.2
+      define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y
+   fi
+   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
+   dep_bool '    Ignore recoverable cache errors' CONFIG_SB1_CERR_IGNORE_RECOVERABLE $CONFIG_SB1_CACHE_ERROR
+   dep_bool '    Spin instead of running handler' CONFIG_SB1_CERR_SPIN $CONFIG_SB1_CACHE_ERROR
+   define_bool CONFIG_VTAG_ICACHE y
+fi
+
+if [ "$CONFIG_CPU_R4X00"  = "y" -o \
+     "$CONFIG_CPU_R5000"  = "y" -o \
+     "$CONFIG_CPU_RM7000" = "y" -o \
+     "$CONFIG_CPU_R10000" = "y" -o \
+     "$CONFIG_CPU_SB1"    = "y" -o \
+     "$CONFIG_CPU_MIPS32" = "y" -o \
+     "$CONFIG_CPU_MIPS64" = "y" ]; then
+   dep_bool '  Support for 64-bit physical address space' CONFIG_64BIT_PHYS_ADDR $CONFIG_MIPS32
+fi
+
+dep_bool 'Override CPU Options' CONFIG_CPU_ADVANCED $CONFIG_MIPS32
+if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
+   bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
+   bool '  lld/scd Instructions available' CONFIG_CPU_HAS_LLDSCD
+   bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
+else
+   if [ "$CONFIG_CPU_R3000"  = "y" -o \
+        "$CONFIG_CPU_VR41XX" = "y" -o \
+        "$CONFIG_CPU_TX39XX" = "y" ]; then
+      if [ "$CONFIG_DECSTATION" = "y" ]; then
+	 define_bool CONFIG_CPU_HAS_LLSC n
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB y
+      else
+	 define_bool CONFIG_CPU_HAS_LLSC n
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB n
+      fi
+   else
+      if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
+	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB n
+      else
+	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD y
+	 define_bool CONFIG_CPU_HAS_WB n
+      fi
+   fi
+fi
+if [ "$CONFIG_CPU_R3000" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_SYNC n
+else
+   define_bool CONFIG_CPU_HAS_SYNC y
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+if [ "$CONFIG_DECSTATION"  = "y" -o \
+     "$CONFIG_DDB5074"     = "y" -o \
+     "$CONFIG_NINO"        = "y" -o \
+     "$CONFIG_MIPS_COBALT" = "y" ]; then
+   define_bool CONFIG_CPU_LITTLE_ENDIAN y
+else
+   bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
+fi
+
+if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
+   bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
+fi
+
+if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
+   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
+   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD
+fi
+
+if [ "$CONFIG_CPU_R10000" = "y" ]; then
+   dep_bool 'Support for large 64-bit configurations' CONFIG_MIPS_INSANE_LARGE $CONFIG_MIPS64
+fi
+
+if [ "$CONFIG_ARC32" = "y" ]; then
+   bool 'ARC console support' CONFIG_ARC_CONSOLE
+fi
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   dep_bool 'Indigo-2 (IP22) EISA bus support' CONFIG_IP22_EISA $CONFIG_EXPERIMENTAL
+fi
+
+if [ "$CONFIG_IP22_EISA" = "y" ]; then
+   define_bool CONFIG_EISA y
+   bool '    ISA bus support' CONFIG_ISA
+fi
+
+bool 'Networking support' CONFIG_NET
+
+if [ "$CONFIG_PCI" != "y" ]; then
+   define_bool CONFIG_PCI n
+fi
+
+source drivers/pci/Config.in
+
+if [ "$CONFIG_ISA" != "y" ]; then
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_EISA n
+else
+   define_bool CONFIG_EISA y
+fi
+
+dep_bool 'TURBOchannel support' CONFIG_TC $CONFIG_DECSTATION
+#dep_bool 'Access.Bus support' CONFIG_ACCESSBUS $CONFIG_TC
+
+define_bool CONFIG_MCA n
+define_bool CONFIG_SBUS n
+
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+   source drivers/hotplug/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+   define_bool CONFIG_HOTPLUG_PCI n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
+define_bool CONFIG_KCORE_ELF y
+define_bool CONFIG_KCORE_AOUT n
+define_bool CONFIG_BINFMT_AOUT n
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+dep_bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT $CONFIG_MIPS64
+define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT
+
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000
+endmenu
+
+source drivers/mtd/Config.in
+
+source drivers/parport/Config.in
+
+source drivers/pnp/Config.in
+
+source drivers/block/Config.in
+if [ "$CONFIG_BLK_DEV_INITRD" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'MIPS initrd options'
+   bool '  Embed root filesystem ramdisk into the kernel' CONFIG_EMBEDDED_RAMDISK
+   endmenu
+fi
+
+source drivers/md/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+   source drivers/ide/Config.in
+else
+   define_bool CONFIG_BLK_DEV_IDE_MODES n
+   define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   source drivers/message/i2o/Config.in
+fi
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+	 source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+source net/ax25/Config.in
+
+source net/irda/Config.in
+
+if [ "$CONFIG_NET" != "n" ]; then
+   mainmenu_option next_comment
+   comment 'ISDN subsystem'
+
+   tristate 'ISDN support' CONFIG_ISDN
+   if [ "$CONFIG_ISDN" != "n" ]; then
+      source drivers/isdn/Config.in
+   fi
+   endmenu
+fi
+
+if [ "$CONFIG_ISA" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+   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
+   endmenu
+fi
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+source drivers/char/Config.in
+
+#source drivers/misc/Config.in
+
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'DECStation Character devices'
+
+   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
+   dep_bool '  DZ11 Serial Support' CONFIG_DZ $CONFIG_SERIAL
+   dep_bool '  Z85C30 Serial Support' CONFIG_ZS $CONFIG_SERIAL $CONFIG_TC
+   dep_bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE $CONFIG_SERIAL
+#   dep_bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS
+   bool 'Enhanced Real Time Clock Support' CONFIG_RTC
+   endmenu
+fi
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'SGI Character devices'
+   if [ "$CONFIG_VT" = "y" ]; then
+      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
+      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
+	 define_bool CONFIG_FONT_8x16 y
+      fi
+      define_bool CONFIG_DUMMY_CONSOLE y
+   fi
+   endmenu
+fi
+
+source fs/Config.in
+
+source drivers/media/Config.in
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   source drivers/sgi/Config.in
+fi
+
+source drivers/usb/Config.in
+
+source net/bluetooth/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then
+   bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+   dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG
+fi
+bool 'Enable run-time debugging' CONFIG_DEBUG
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_SMP" != "y" ]; then
+   bool 'Run uncached' CONFIG_MIPS_UNCACHED
+fi
+endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/config.in linux-2.4.20/arch/mips/config.in
--- linux-2.4.19/arch/mips/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/config.in	2002-10-04 00:41:22.000000000 +0000
@@ -4,631 +4,6 @@
 #
 define_bool CONFIG_MIPS y
 define_bool CONFIG_MIPS32 y
+define_bool CONFIG_MIPS64 n
 
-mainmenu_name "Linux/MIPS Kernel Configuration"
-
-mainmenu_option next_comment
-comment 'Code maturity level options'
-bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
-endmenu
-
-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 module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'Machine selection'
-dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL
-bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000
-if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
-   bool '  Support for PCI AUTO Config' CONFIG_PCI_AUTO
-fi
-bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500
-dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL
-dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_EXPERIMENTAL
-dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL
-bool 'Support for DECstations' CONFIG_DECSTATION
-dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL
-if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
-   bool '  Enable Second PCI (PCI1)' CONFIG_EVB_PCI1
-   choice '  Galileo Chip Clock' \
-	"75	CONFIG_SYSCLK_75 \
-	 83.3	CONFIG_SYSCLK_83 \
-	 100	CONFIG_SYSCLK_100" 83.3
-fi
-dep_bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 $CONFIG_EXPERIMENTAL
-bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR
-bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET
-bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172
-if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
-   bool '  Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC
-fi
-dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL
-bool 'Support for MIPS Magnum 4000' CONFIG_MIPS_MAGNUM_4000
-dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL
-bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT
-dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL
-bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476
-bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477
-bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY
-bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
-dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_EXPERIMENTAL
-if [ "$CONFIG_NINO" = "y" ]; then
-   choice 'Nino Model Number' \
-	"Model-300/301/302/319			CONFIG_NINO_4MB \
-	 Model-200/210/312/320/325/350/390	CONFIG_NINO_8MB \
-	 Model-500/510				CONFIG_NINO_16MB" Model-200
-fi
-bool 'Support for SGI IP22 (Indy/Indigo2)' CONFIG_SGI_IP22
-dep_bool 'Support for SiByte SB1250 SOC (EXPERIMENTAL)' CONFIG_SIBYTE_SB1250 $CONFIG_EXPERIMENTAL
-if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
-   bool '  Support for SB1250 onchip PCI controller' CONFIG_PCI
-   bool '  Support for SB1250 profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
-   bool '  Support for BCM1250 profiling using trace buffer' CONFIG_BCM1250_TBPROF
-   bool '  Remote debugging (kgdb over UART 1)' CONFIG_REMOTE_DEBUG
-   bool '  Support for SiByte SWARM board' CONFIG_SIBYTE_SWARM
-   if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
-      bool '    Running under simulation' CONFIG_SIMULATION
-      bool '    Configure for L3proc Demo' CONFIG_L3DEMO
-      int '    Maximum memory chunks' CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS 16
-      bool '    Multi-Processing support' CONFIG_SMP
-   fi
-fi
-bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
-bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927
-
-dep_bool 'High Memory Support (EXPERIMENTAL)' CONFIG_HIGHMEM $CONFIG_EXPERIMENTAL
-
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
-
-#
-# Select some configuration options automatically based on user selections.
-#
-
-if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_MIPS_JAZZ y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_ROTTEN_IRQ y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
-   define_bool CONFIG_MIPS_AU1000 y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-   define_int  MAX_HWIFS 1
-fi
-if [ "$CONFIG_MIPS_PB1500" = "y" ]; then
-   define_bool CONFIG_MIPS_AU1000 y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-fi
-if [ "$CONFIG_ALGOR_P4032" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_MIPS_COBALT" = "y" ]; then
-   define_bool CONFIG_COBALT_LCD y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-fi
-if [ "$CONFIG_DECSTATION" = "y" ]; then
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NONCOHERENT_IO y
-fi
-if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_ISA n
-   define_bool CONFIG_MIPS_GT64120 y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_MIPS_GT96100 y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
-if [ "$CONFIG_MIPS_IVR" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_IT8172_CIR y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-fi
-if [ "$CONFIG_HP_LASERJET" = "y" ]; then
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   #not yet define_bool CONFIG_PCI_AUTO y
-fi
-if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_IT8712 y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_IT8172_CIR y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-fi
-if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
-if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
-     "$CONFIG_OLIVETTI_M700" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_FB y
-   define_bool CONFIG_FB_G364 y
-   define_bool CONFIG_MIPS_JAZZ y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_SWAP_IO_SPACE y
-   define_bool CONFIG_PC_KEYB y
-fi
-if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_SYSCLK_100 y
-   define_bool CONFIG_SWAP_IO_SPACE y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_DDB5074" = "y" ]; then
-   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_ROTTEN_IRQ y
-   define_bool CONFIG_OLD_TIME_C y
-fi
-if [ "$CONFIG_DDB5476"  = "y" ]; then
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-fi
-if [ "$CONFIG_DDB5477" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_DUMMY_KEYB y
-fi
-if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
-   define_bool CONFIG_VR4181 y
-   define_bool CONFIG_SERIAL y
-   define_bool CONFIG_SERIAL_MANY_PORTS y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_DUMMY_KEYB y
-   define_bool CONFIG_SCSI n
-fi
-if [ "$CONFIG_NINO" = "y" ]; then
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-fi
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_BOARD_SCACHE y
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_SGI y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-fi
-if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_DUMMY_KEYB y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
-if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_I8259 y
-   define_bool CONFIG_ISA y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
-fi
-if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
-   define_bool CONFIG_TOSHIBA_BOARDS y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_NEW_IRQ y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_SWAP_IO_SPACE y
-   define_bool CONFIG_PC_KEYB y
-fi
-
-if [ "$CONFIG_MIPS_AU1000" != "y" ]; then
-   define_bool CONFIG_MIPS_AU1000 n
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'CPU selection'
-
-choice 'CPU type' \
-	"R3000	CONFIG_CPU_R3000 \
-	 R39XX	CONFIG_CPU_TX39XX \
-	 R6000	CONFIG_CPU_R6000 \
-	 R41xx	CONFIG_CPU_VR41XX \
-	 R4300	CONFIG_CPU_R4300 \
-	 R4x00	CONFIG_CPU_R4X00 \
-	 R49XX	CONFIG_CPU_TX49XX \
-	 R5000	CONFIG_CPU_R5000 \
-	 R5432	CONFIG_CPU_R5432 \
-	 RM7000	CONFIG_CPU_RM7000 \
-	 R52xx	CONFIG_CPU_NEVADA \
-	 R10000	CONFIG_CPU_R10000 \
-	 SB1	CONFIG_CPU_SB1 \
-	 MIPS32	CONFIG_CPU_MIPS32 \
-	 MIPS64	CONFIG_CPU_MIPS64" R4x00
-
-if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
-   define_bool CONFIG_CPU_HAS_PREFETCH y
-   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
-fi
-
-if [ "$CONFIG_CPU_MIPS64" = "y" ]; then
-   define_bool CONFIG_CPU_HAS_PREFETCH y
-   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
-fi
-
-if [ "$CONFIG_CPU_RM7000" = "y" ]; then
-   define_bool CONFIG_CPU_HAS_PREFETCH y
-fi
-
-if [ "$CONFIG_CPU_SB1" = "y" ]; then
-   bool '  Workarounds for pass 1 sb1 bugs' CONFIG_SB1_PASS_1_WORKAROUNDS
-   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
-   define_bool CONFIG_VTAG_ICACHE y
-   define_bool CONFIG_CPU_HAS_PREFETCH y
-fi
-
-if [ "$CONFIG_CPU_R4X00"  = "y" -o \
-     "$CONFIG_CPU_R5000" = "y" -o \
-     "$CONFIG_CPU_RM7000" = "y" -o \
-     "$CONFIG_CPU_R10000" = "y" -o \
-     "$CONFIG_CPU_SB1" = "y" -o \
-     "$CONFIG_CPU_MIPS32" = "y" -o \
-     "$CONFIG_CPU_MIPS64" = "y" ]; then
-   bool '  Support for 64-bit physical address space' CONFIG_64BIT_PHYS_ADDR
-fi
-
-bool 'Override CPU Options' CONFIG_CPU_ADVANCED
-if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
-   bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
-   bool '  lld/scd Instructions available' CONFIG_CPU_HAS_LLDSCD
-   bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
-else
-   if [ "$CONFIG_CPU_R3000" = "y" -o \
-        "$CONFIG_CPU_VR41XX" = "y" -o    \
-        "$CONFIG_CPU_TX39XX" = "y" ]; then
-      if [ "$CONFIG_DECSTATION" = "y" ]; then
-	 define_bool CONFIG_CPU_HAS_LLSC n
-	 define_bool CONFIG_CPU_HAS_LLDSCD n
-	 define_bool CONFIG_CPU_HAS_WB y
-      else
-	 define_bool CONFIG_CPU_HAS_LLSC n
-	 define_bool CONFIG_CPU_HAS_LLDSCD n
-	 define_bool CONFIG_CPU_HAS_WB n
-      fi
-   else
-      if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
-	 define_bool CONFIG_CPU_HAS_LLSC y
-	 define_bool CONFIG_CPU_HAS_LLDSCD n
-	 define_bool CONFIG_CPU_HAS_WB n
-      else
-	 define_bool CONFIG_CPU_HAS_LLSC y
-	 define_bool CONFIG_CPU_HAS_LLDSCD y
-	 define_bool CONFIG_CPU_HAS_WB n
-      fi
-   fi
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'General setup'
-if [ "$CONFIG_DECSTATION" = "y" -o \
-     "$CONFIG_DDB5074" = "y" -o    \
-     "$CONFIG_NINO" = "y" -o       \
-     "$CONFIG_MIPS_COBALT" = "y" ]; then
-   define_bool CONFIG_CPU_LITTLE_ENDIAN y
-else
-   bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
-fi
-
-if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
-       bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
-fi
-
-if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
-   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
-   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD
-fi
-
-if [ "$CONFIG_ARC32" = "y" ]; then
-   bool 'ARC console support' CONFIG_ARC_CONSOLE
-fi
-
-bool 'Networking support' CONFIG_NET
-
-if [ "$CONFIG_PCI" != "y" ]; then
-   define_bool CONFIG_PCI n
-fi
-
-source drivers/pci/Config.in
-
-if [ "$CONFIG_ISA" != "y" ]; then
-   define_bool CONFIG_ISA n
-   define_bool CONFIG_EISA n
-else
-   define_bool CONFIG_EISA y
-fi
-
-dep_bool 'TURBOchannel support' CONFIG_TC $CONFIG_DECSTATION
-#dep_bool 'Access.Bus support' CONFIG_ACCESSBUS $CONFIG_TC
-
-define_bool CONFIG_MCA n
-define_bool CONFIG_SBUS n
-
-bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
-
-if [ "$CONFIG_HOTPLUG" = "y" ] ; then
-   source drivers/pcmcia/Config.in
-   source drivers/hotplug/Config.in
-else
-   define_bool CONFIG_PCMCIA n
-   define_bool CONFIG_HOTPLUG_PCI n
-fi
-
-bool 'System V IPC' CONFIG_SYSVIPC
-bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
-bool 'Sysctl support' CONFIG_SYSCTL
-define_bool CONFIG_KCORE_ELF y
-define_bool CONFIG_KCORE_AOUT n
-define_bool CONFIG_BINFMT_AOUT n
-define_bool CONFIG_BINFMT_ELF y
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-
-dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000
-endmenu
-
-source drivers/mtd/Config.in
-
-source drivers/parport/Config.in
-
-source drivers/pnp/Config.in
-
-source drivers/block/Config.in
-if [ "$CONFIG_BLK_DEV_INITRD" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'MIPS initrd options'
-   bool '  Embed root filesystem ramdisk into the kernel' CONFIG_EMBEDDED_RAMDISK
-   endmenu
-fi
-
-source drivers/md/Config.in
-
-if [ "$CONFIG_NET" = "y" ]; then
-   source net/Config.in
-fi
-
-source drivers/telephony/Config.in
-
-if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
-
-   mainmenu_option next_comment
-   comment 'ATA/IDE/MFM/RLL support'
-
-   tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
-
-   if [ "$CONFIG_IDE" != "n" ]; then
-      source drivers/ide/Config.in
-   else
-      define_bool CONFIG_BLK_DEV_IDE_MODES n
-      define_bool CONFIG_BLK_DEV_HD n
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'SCSI support'
-
-tristate 'SCSI support' CONFIG_SCSI
-
-if [ "$CONFIG_SCSI" != "n" ]; then
-   source drivers/scsi/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_PCI" = "y" ]; then
-   source drivers/message/i2o/Config.in
-fi
-
-if [ "$CONFIG_NET" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Network device support'
-
-   bool 'Network device support' CONFIG_NETDEVICES
-   if [ "$CONFIG_NETDEVICES" = "y" ]; then
-      source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
-	 source drivers/atm/Config.in
-      fi
-   fi
-   endmenu
-fi
-
-source net/ax25/Config.in
-
-source net/irda/Config.in
-
-if [ "$CONFIG_NET" != "n" ]; then
-   mainmenu_option next_comment
-   comment 'ISDN subsystem'
-
-   tristate 'ISDN support' CONFIG_ISDN
-   if [ "$CONFIG_ISDN" != "n" ]; then
-      source drivers/isdn/Config.in
-   fi
-   endmenu
-fi
-
-if [ "$CONFIG_ISA" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-
-   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
-   endmenu
-fi
-
-source drivers/char/Config.in
-
-#source drivers/misc/Config.in
-
-source drivers/media/Config.in
-
-if [ "$CONFIG_DECSTATION" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'DECStation Character devices'
-
-   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
-   dep_bool '  DZ11 Serial Support' CONFIG_DZ $CONFIG_SERIAL
-   dep_bool '  Z85C30 Serial Support' CONFIG_ZS $CONFIG_SERIAL $CONFIG_TC
-   dep_bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE $CONFIG_SERIAL
-#   dep_bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS
-   bool 'Enhanced Real Time Clock Support' CONFIG_RTC
-   endmenu
-fi
-
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'SGI Character devices'
-   if [ "$CONFIG_VT" = "y" ]; then
-      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
-      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
-	 define_bool CONFIG_FONT_8x16 y
-      fi
-      define_bool CONFIG_DUMMY_CONSOLE y
-   fi
-   endmenu
-fi
-
-source fs/Config.in
-
-if [ "$CONFIG_VT" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Console drivers'
-   bool 'VGA text console' CONFIG_VGA_CONSOLE
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
-      source drivers/video/Config.in
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'Sound'
-
-tristate 'Sound card support' CONFIG_SOUND
-if [ "$CONFIG_SOUND" != "n" ]; then
-   source drivers/sound/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   source drivers/sgi/Config.in
-fi
-
-source drivers/usb/Config.in
-
-source net/bluetooth/Config.in
-
-source drivers/input/Config.in
-
-mainmenu_option next_comment
-comment 'Kernel hacking'
-
-bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then
-  bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-  dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG
-fi
-bool 'Enable run-time debugging' CONFIG_DEBUG
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-if [ "$CONFIG_SMP" != "y" ]; then
-   bool 'Run uncached' CONFIG_MIPS_UNCACHED
-fi
-endmenu
+source arch/mips/config-shared.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/Makefile linux-2.4.20/arch/mips/ddb5074/Makefile
--- linux-2.4.19/arch/mips/ddb5074/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5074/Makefile	2002-10-04 00:41:11.000000000 +0000
@@ -9,10 +9,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET = ddb5074.a
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/irq.c linux-2.4.20/arch/mips/ddb5074/irq.c
--- linux-2.4.19/arch/mips/ddb5074/irq.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5074/irq.c	2002-10-04 00:41:30.000000000 +0000
@@ -60,9 +60,9 @@
 	 *
 	 *      IRQ1  - keyboard (default set by M1543)
 	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
-	 *              the schematics for the DDB Vrc-5074 board seem to 
-	 *              indicate that IRQ3 is connected to the DS1386 
-	 *              watchdog timer interrupt output so we might have 
+	 *              the schematics for the DDB Vrc-5074 board seem to
+	 *              indicate that IRQ3 is connected to the DS1386
+	 *              watchdog timer interrupt output so we might have
 	 *              a conflict)
 	 *      IRQ4  - reserved for UART A (default set by M1543)
 	 *      IRQ5  - parallel (default set by M1543)
@@ -71,7 +71,7 @@
 	 */
 
 	/*
-	 *  Assing mouse interrupt to IRQ12 
+	 *  Assing mouse interrupt to IRQ12
 	 */
 
 	/* Enter configuration mode */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/pci.c linux-2.4.20/arch/mips/ddb5074/pci.c
--- linux-2.4.19/arch/mips/ddb5074/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5074/pci.c	2002-10-04 00:41:20.000000000 +0000
@@ -396,7 +396,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/setup.c linux-2.4.20/arch/mips/ddb5074/setup.c
--- linux-2.4.19/arch/mips/ddb5074/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5074/setup.c	2002-10-04 00:41:13.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/nile4.h>
 #include <asm/ddb5074.h>
+#include <asm/traps.h>
 
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -91,6 +92,10 @@
 		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init ddb_setup(void)
 {
 	extern int panic_timeout;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/Makefile linux-2.4.20/arch/mips/ddb5xxx/common/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/common/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/common/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= ddb5xxx.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/irq.c linux-2.4.20/arch/mips/ddb5xxx/common/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/common/irq.c	2002-10-04 00:41:29.000000000 +0000
@@ -13,6 +13,7 @@
  */
 #include <linux/config.h>
 #include <linux/init.h>
+#include <asm/irq.h>
 
 void (*irq_setup)(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/nile4.c linux-2.4.20/arch/mips/ddb5xxx/common/nile4.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/nile4.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/common/nile4.c	2002-10-04 00:41:22.000000000 +0000
@@ -16,14 +16,13 @@
  ***********************************************************************
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 u32
-ddb_calc_pdar(u32 phys, u32 size, int width, 
+ddb_calc_pdar(u32 phys, u32 size, int width,
 	      int on_memory_bus, int pci_visible)
 {
         u32 maskbits;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/prom.c linux-2.4.20/arch/mips/ddb5xxx/common/prom.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/common/prom.c	2002-10-04 00:41:15.000000000 +0000
@@ -26,6 +26,8 @@
 
 char arcs_cmdline[CL_SIZE];
 
+void ddb5477_runtime_detection(void);
+
 const char *get_system_type(void)
 {
 	switch (mips_machtype) {
@@ -33,6 +35,8 @@
 	case MACH_NEC_DDB5476:		return "NEC DDB Vrc-5476";
 	case MACH_NEC_DDB5477:		return "NEC DDB Vrc-5477";
 	case MACH_NEC_ROCKHOPPER:	return "NEC Rockhopper";
+	case MACH_NEC_ROCKHOPPERII:	return "NEC RockhopperII";
+	default:			return "Unknown NEC board";
 	}
 }
 
@@ -92,6 +96,13 @@
            around just after that.
          */
 
+	/* We can only use the PCI bus to distinquish between
+	   the Rockhopper and RockhopperII backplanes and this must
+	   wait until ddb5477_board_init() in setup.c after the 5477
+	   is initialized.  So, until then handle
+	   both Rockhopper and RockhopperII backplanes as Rockhopper 1
+	 */
+
         test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800);
         saved_test_byte = *test_offset;
 
@@ -119,7 +130,7 @@
         *test_offset = saved_test_byte;
 
 	/* before we know a better way, we will trust PMON for getting
-	 * RAM size 
+	 * RAM size
 	 */
 	board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/rtc_ds1386.c linux-2.4.20/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/rtc_ds1386.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/common/rtc_ds1386.c	2002-10-04 00:41:14.000000000 +0000
@@ -24,6 +24,7 @@
 #include <asm/time.h>
 #include <asm/addrspace.h>
 
+#include <asm/mc146818rtc.h>
 #include <asm/debug.h>
 
 #define	EPOCH		2000
@@ -41,7 +42,7 @@
 
 static unsigned long
 rtc_ds1386_get_time(void)
-{	
+{
 	u8 byte;
 	u8 temp;
 	unsigned int year, month, day, hour, minute, second;
@@ -78,7 +79,7 @@
 	return mktime(year, month, day, hour, minute, second);
 }
 
-static int 
+static int
 rtc_ds1386_set_time(unsigned long t)
 {
 	struct rtc_time tm;
@@ -94,6 +95,7 @@
 	/* convert */
 	to_tm(t, &tm);
 
+
 	/* check each field one by one */
 	year = BIN_TO_BCD(tm.tm_year - EPOCH);
 	if (year != READ_RTC(0xA)) {
@@ -136,7 +138,7 @@
 	if (second != READ_RTC(0x1)) {
 		WRITE_RTC(0x1, second);
 	}
-	
+
 	return 0;
 }
 
@@ -144,7 +146,7 @@
 rtc_ds1386_init(unsigned long base)
 {
 	unsigned char byte;
-	
+
 	/* remember the base */
 	rtc_base = base;
 	db_assert((rtc_base & 0xe0000000) == KSEG1);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/Makefile linux-2.4.20/arch/mips/ddb5xxx/ddb5074/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/Makefile	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
+# under Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET = ddb5074.o
+
+obj-y				+= setup.o irq.o int-handler.o pci.o pci_ops.o nile4_pic.o time.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/int-handler.S linux-2.4.20/arch/mips/ddb5xxx/ddb5074/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/int-handler.S	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,120 @@
+/*
+ *  arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
+ *
+ *  Based on arch/mips/sgi/kernel/indyIRQ.S
+ *
+ *  Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop and moving across
+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
+ *    common case is one pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register IRQ mask, that
+ *    would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
+ *    between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring software IRQs
+ * which we don't use at all) like:
+ *
+ *	MIPS IRQ	Source
+ *      --------        ------
+ *             0	Software (ignored)
+ *             1        Software (ignored)
+ *             2        Local IRQ level zero
+ *             3        Local IRQ level one
+ *             4        8254 Timer zero
+ *             5        8254 Timer one
+ *             6        Bus Error
+ *             7        R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ----     R4k Timer
+ *                  Local IRQ zero
+ *                  Local IRQ one
+ *                  Bus Error
+ *                  8254 Timer zero
+ * Lowest  ----     8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+	.text
+	.set	noreorder
+	.set	noat
+	.align	5
+	NESTED(ddbIRQ, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+	mfc0	s0, CP0_CAUSE		# get irq mask
+
+#if 1
+	mfc0	t2,CP0_STATUS		# get enabled interrupts
+	and	s0,t2			# isolate allowed ones
+#endif
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP3	# delay slot, check local level one
+
+	/* Wheee, local level zero interrupt. */
+	jal	ddb_local0_irqdispatch
+	 move	a0, sp			# delay slot
+
+	j	ret_from_irq
+	 nop				# delay slot
+
+1:
+	beq	a0, zero, 1f
+	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
+
+	/* Wheee, local level one interrupt. */
+	move	a0, sp
+	jal	ddb_local1_irqdispatch
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	beq	a0, zero, 1f
+	 nop
+
+	/* Wheee, an asynchronous bus error... */
+	move	a0, sp
+	jal	ddb_buserror_irq
+	 nop
+
+	j	ret_from_irq
+	 nop
+
+1:
+	/* Here by mistake?  This is possible, what can happen
+	 * is that by the time we take the exception the IRQ
+	 * pin goes low, so just leave if this is the case.
+	 */
+	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+	beq	a0, zero, 1f
+
+	/* Must be one of the 8254 timers... */
+	move	a0, sp
+	jal	ddb_8254timer_irq
+	 nop
+1:
+	j	ret_from_irq
+	 nop
+	END(ddbIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/irq.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/irq.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,174 @@
+/*
+ *  arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/ptrace.h>
+#include <asm/nile4.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/ddb5xxx/ddb5074.h>
+
+
+extern void __init i8259_init(void);
+extern void init_i8259_irqs (void);
+extern void i8259_disable_irq(unsigned int irq_nr);
+extern void i8259_enable_irq(unsigned int irq_nr);
+
+extern asmlinkage void ddbIRQ(void);
+extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs);
+extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
+
+#define M1543_PNP_CONFIG	0x03f0	/* PnP Config Port */
+#define M1543_PNP_INDEX		0x03f0	/* PnP Index Port */
+#define M1543_PNP_DATA		0x03f1	/* PnP Data Port */
+
+#define M1543_PNP_ALT_CONFIG	0x0370	/* Alternative PnP Config Port */
+#define M1543_PNP_ALT_INDEX	0x0370	/* Alternative PnP Index Port */
+#define M1543_PNP_ALT_DATA	0x0371	/* Alternative PnP Data Port */
+
+#define M1543_INT1_MASTER_CTRL	0x0020	/* INT_1 (master) Control Register */
+#define M1543_INT1_MASTER_MASK	0x0021	/* INT_1 (master) Mask Register */
+
+#define M1543_INT1_SLAVE_CTRL	0x00a0	/* INT_1 (slave) Control Register */
+#define M1543_INT1_SLAVE_MASK	0x00a1	/* INT_1 (slave) Mask Register */
+
+#define M1543_INT1_MASTER_ELCR	0x04d0	/* INT_1 (master) Edge/Level Control */
+#define M1543_INT1_SLAVE_ELCR	0x04d1	/* INT_1 (slave) Edge/Level Control */
+
+
+static void m1543_irq_setup(void)
+{
+	/*
+	 *  The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13.  Not all
+	 *  the possible IO sources in the M1543 are in use by us.  We will
+	 *  use the following mapping:
+	 *
+	 *      IRQ1  - keyboard (default set by M1543)
+	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
+	 *              the schematics for the DDB Vrc-5074 board seem to
+	 *              indicate that IRQ3 is connected to the DS1386
+	 *              watchdog timer interrupt output so we might have
+	 *              a conflict)
+	 *      IRQ4  - reserved for UART A (default set by M1543)
+	 *      IRQ5  - parallel (default set by M1543)
+	 *      IRQ8  - DS1386 time of day (RTC) interrupt
+	 *      IRQ12 - mouse
+	 */
+
+	/*
+	 *  Assing mouse interrupt to IRQ12
+	 */
+
+	/* Enter configuration mode */
+	outb(0x51, M1543_PNP_CONFIG);
+	outb(0x23, M1543_PNP_CONFIG);
+
+	/* Select logical device 7 (Keyboard) */
+	outb(0x07, M1543_PNP_INDEX);
+	outb(0x07, M1543_PNP_DATA);
+
+	/* Select IRQ12 */
+	outb(0x72, M1543_PNP_INDEX);
+	outb(0x0c, M1543_PNP_DATA);
+
+	outb(0x30, M1543_PNP_INDEX);
+	printk("device 7, 0x30: %02x\n",inb(M1543_PNP_DATA));
+
+	outb(0x70, M1543_PNP_INDEX);
+	printk("device 7, 0x70: %02x\n",inb(M1543_PNP_DATA));
+
+	/* Leave configration mode */
+	outb(0xbb, M1543_PNP_CONFIG);
+
+
+}
+
+void ddb_local0_irqdispatch(struct pt_regs *regs)
+{
+	u32 mask;
+	int nile4_irq;
+
+	mask = nile4_get_irq_stat(0);
+
+	/* Handle the timer interrupt first */
+#if 0
+	if (mask & (1 << NILE4_INT_GPT)) {
+		do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
+		mask &= ~(1 << NILE4_INT_GPT);
+	}
+#endif
+	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
+		if (mask & 1) {
+			if (nile4_irq == NILE4_INT_INTE) {
+				int i8259_irq;
+
+				nile4_clear_irq(NILE4_INT_INTE);
+				i8259_irq = nile4_i8259_iack();
+				do_IRQ(i8259_irq, regs);
+			} else
+				do_IRQ(nile4_to_irq(nile4_irq), regs);
+
+		}
+}
+
+void ddb_local1_irqdispatch(void)
+{
+	printk("ddb_local1_irqdispatch called\n");
+}
+
+void ddb_buserror_irq(void)
+{
+	printk("ddb_buserror_irq called\n");
+}
+
+void ddb_8254timer_irq(void)
+{
+	printk("ddb_8254timer_irq called\n");
+}
+
+void __init ddb_irq_setup(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug)
+		set_debug_traps();
+	breakpoint();		/* you may move this line to whereever you want :-) */
+#endif
+
+	/* setup cascade interrupts */
+	setup_irq(NILE4_IRQ_BASE  + NILE4_INT_INTE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
+
+	set_except_vector(0, ddbIRQ);
+
+	nile4_irq_setup(NILE4_IRQ_BASE);
+	m1543_irq_setup();
+	init_i8259_irqs();
+
+
+	printk("CPU_IRQ_BASE: %d\n",CPU_IRQ_BASE);
+
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	printk("enabling 8259 cascade\n");
+
+	ddb5074_led_hex(0);
+
+	/* Enable the interrupt cascade */
+	nile4_enable_irq(NILE4_IRQ_BASE+IRQ_I8259_CASCADE);
+
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,288 @@
+/*
+ *  arch/mips/ddb5476/nile4.c --
+ *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ *  Copyright 2001 MontaVista Software Inc.
+ *  Author: jsun@mvista.com or jsun@junsun.net
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static int irq_base;
+
+/*
+ *  Interrupt Programming
+ */
+void nile4_map_irq(int nile4_irq, int cpu_irq)
+{
+	u32 offset, t;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(7 << (nile4_irq * 4));
+	t |= cpu_irq << (nile4_irq * 4);
+	ddb_out32(offset, t);
+}
+
+void nile4_map_irq_all(int cpu_irq)
+{
+	u32 all, t;
+
+	all = cpu_irq;
+	all |= all << 4;
+	all |= all << 8;
+	all |= all << 16;
+	t = ddb_in32(DDB_INTCTRL);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL, t);
+	t = ddb_in32(DDB_INTCTRL + 4);
+	t &= 0x88888888;
+	t |= all;
+	ddb_out32(DDB_INTCTRL + 4, t);
+}
+
+void nile4_enable_irq(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	ddb5074_led_hex(8);
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	ddb5074_led_hex(9);
+	t = ddb_in32(offset);
+	ddb5074_led_hex(0xa);
+	t |= 8 << (nile4_irq * 4);
+	ddb_out32(offset, t);
+	ddb5074_led_hex(0xb);
+}
+
+void nile4_disable_irq(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	t = ddb_in32(offset);
+	t &= ~(8 << (nile4_irq * 4));
+	ddb_out32(offset, t);
+}
+
+void nile4_disable_irq_all(void)
+{
+	ddb_out32(DDB_INTCTRL, 0);
+	ddb_out32(DDB_INTCTRL + 4, 0);
+}
+
+u16 nile4_get_irq_stat(int cpu_irq)
+{
+	return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2);
+}
+
+void nile4_enable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t |= 1 << (16 + cpu_irq);
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_disable_irq_output(int cpu_irq)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTSTAT1 + 4);
+	t &= ~(1 << (16 + cpu_irq));
+	ddb_out32(DDB_INTSTAT1, t);
+}
+
+void nile4_set_pci_irq_polarity(int pci_irq, int high)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (high)
+		t &= ~(1 << (pci_irq * 2));
+	else
+		t |= 1 << (pci_irq * 2);
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
+{
+	u32 t;
+
+	t = ddb_in32(DDB_INTPPES);
+	if (level)
+		t |= 2 << (pci_irq * 2);
+	else
+		t &= ~(2 << (pci_irq * 2));
+	ddb_out32(DDB_INTPPES, t);
+}
+
+void nile4_clear_irq(int nile4_irq)
+{
+	nile4_irq-=irq_base;
+	ddb_out32(DDB_INTCLR, 1 << nile4_irq);
+}
+
+void nile4_clear_irq_mask(u32 mask)
+{
+	ddb_out32(DDB_INTCLR, mask);
+}
+
+u8 nile4_i8259_iack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	/* restore window 0 for PCI I/O space */
+	// ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
+	ddb_out32(DDB_PCIINIT0, reg);
+
+	/* i8269.c set the base vector to be 0x0 */
+	return irq ;
+}
+
+static unsigned int nile4_irq_startup(unsigned int irq) {
+
+	nile4_enable_irq(irq);
+	return 0;
+
+}
+
+static void nile4_ack_irq(unsigned int irq) {
+
+    ddb5074_led_hex(4);
+
+	nile4_clear_irq(irq);
+    ddb5074_led_hex(2);
+	nile4_disable_irq(irq);
+
+    ddb5074_led_hex(0);
+}
+
+static void nile4_irq_end(unsigned int irq) {
+
+	ddb5074_led_hex(3);
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	ddb5074_led_hex(5);
+		nile4_enable_irq(irq);
+	ddb5074_led_hex(7);
+	}
+
+	ddb5074_led_hex(1);
+}
+
+#define nile4_irq_shutdown nile4_disable_irq
+
+static hw_irq_controller nile4_irq_controller = {
+    "nile4",
+    nile4_irq_startup,
+    nile4_irq_shutdown,
+    nile4_enable_irq,
+    nile4_disable_irq,
+    nile4_ack_irq,
+    nile4_irq_end,
+    NULL
+};
+
+void nile4_irq_setup(u32 base) {
+
+	int i;
+	extern irq_desc_t irq_desc[];
+
+	irq_base=base;
+
+	/* Map all interrupts to CPU int #0 */
+	nile4_map_irq_all(0);
+
+	/* PCI INTA#-E# must be level triggered */
+	nile4_set_pci_irq_level_or_edge(0, 1);
+	nile4_set_pci_irq_level_or_edge(1, 1);
+	nile4_set_pci_irq_level_or_edge(2, 1);
+	nile4_set_pci_irq_level_or_edge(3, 1);
+	nile4_set_pci_irq_level_or_edge(4, 1);
+
+	/* PCI INTA#-D# must be active low, INTE# must be active high */
+	nile4_set_pci_irq_polarity(0, 0);
+	nile4_set_pci_irq_polarity(1, 0);
+	nile4_set_pci_irq_polarity(2, 0);
+	nile4_set_pci_irq_polarity(3, 0);
+	nile4_set_pci_irq_polarity(4, 1);
+
+
+	for (i = 0; i < 16; i++) {
+		nile4_clear_irq(i);
+		nile4_disable_irq(i);
+	}
+
+	/* Enable CPU int #0 */
+	nile4_enable_irq_output(0);
+
+	for (i= base; i< base + NUM_NILE4_INTERRUPTS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &nile4_irq_controller;
+	}
+
+}
+
+#if defined(CONFIG_LL_DEBUG)
+void nile4_dump_irq_status(void)
+{
+	printk(KERN_DEBUG "
+	       CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4),
+	       (void *) ddb_in32(DDB_CPUSTAT));
+	printk(KERN_DEBUG "
+	       INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4),
+	       (void *) ddb_in32(DDB_INTCTRL));
+	printk(KERN_DEBUG
+	       "INTSTAT0 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT0 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT0));
+	printk(KERN_DEBUG
+	       "INTSTAT1 = %p:%p\n",
+	       (void *) ddb_in32(DDB_INTSTAT1 + 4),
+	       (void *) ddb_in32(DDB_INTSTAT1));
+	printk(KERN_DEBUG
+	       "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4),
+	       (void *) ddb_in32(DDB_INTCLR));
+	printk(KERN_DEBUG
+	       "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4),
+	       (void *) ddb_in32(DDB_INTPPES));
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/pci.c	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,130 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/pci_channel.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static struct resource extpci_io_resource = {
+    "pci IO space",
+    0x1000,             /* leave some room for ISA bus */
+    DDB_PCI_IO_SIZE -1,
+    IORESOURCE_IO};
+
+static struct resource extpci_mem_resource = {
+    "pci memory space",
+    DDB_PCI_MEM_BASE + 0x00100000,  /* leave 1 MB for RTC */
+    DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1,
+    IORESOURCE_MEM};
+
+extern struct pci_ops ddb5476_ext_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+    { &ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource },
+    { NULL, NULL, NULL}
+};
+
+#define     PCI_EXT_INTA        8
+#define     PCI_EXT_INTB        9
+#define     PCI_EXT_INTC        10
+#define     PCI_EXT_INTD        11
+#define     PCI_EXT_INTE        12
+
+#define     MAX_SLOT_NUM        14
+
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0 */ nile4_to_irq(PCI_EXT_INTE),
+	/* SLOT:  1 */ nile4_to_irq(PCI_EXT_INTA),
+	/* SLOT:  2 */ nile4_to_irq(PCI_EXT_INTA),
+	/* SLOT:  3 */ nile4_to_irq(PCI_EXT_INTB),
+	/* SLOT:  4 */ nile4_to_irq(PCI_EXT_INTC),
+	/* SLOT:  5 */ nile4_to_irq(NILE4_INT_UART),
+	/* SLOT:  6 */ 0xff,
+	/* SLOT:  7 */ 0xff,
+	/* SLOT:  8 */ 0xff,
+	/* SLOT:  9 */ 0xff,
+	/* SLOT:  10 */ nile4_to_irq(PCI_EXT_INTE),
+	/* SLOT:  11 */ 0xff,
+	/* SLOT:  12 */ 0xff,
+	/* SLOT:  13 */ nile4_to_irq(PCI_EXT_INTE),
+};
+
+void __init pcibios_fixup_irqs(void) {
+
+	struct pci_dev *dev;
+	int slot_num;
+
+	pci_for_each_dev(dev) {
+		slot_num = PCI_SLOT(dev->devfn);
+		db_assert(slot_num < MAX_SLOT_NUM);
+printk("irq_map[%d]: %02x\n",slot_num, irq_map[slot_num]);
+		db_assert(irq_map[slot_num] != 0xff);
+
+		pci_write_config_byte(dev,
+							PCI_INTERRUPT_LINE,
+							irq_map[slot_num]);
+
+		dev->irq = irq_map[slot_num];
+	}
+}
+
+void __init ddb_pci_reset_bus(void)
+{
+    u32 temp;
+
+    /*
+     * I am not sure about the "official" procedure, the following
+     * steps work as far as I know:
+     * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
+     * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
+     * The same is true for both PCI channels.
+     */
+    temp = ddb_in32(DDB_PCICTRL+4);
+    temp |= 0x80000000;
+    ddb_out32(DDB_PCICTRL+4, temp);
+    temp &= ~0xc0000000;
+    ddb_out32(DDB_PCICTRL+4, temp);
+
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+    /* we hope pci_auto has assigned the bus numbers to all buses */
+    return 1;
+}
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->vendor == PCI_VENDOR_ID_AL &&
+			dev->device == PCI_DEVICE_ID_AL_M7101) {
+				/*
+				 * It's nice to have the LEDs on the GPIO pins
+				 * available for debugging
+				 */
+				extern struct pci_dev *pci_pmu;
+				u8 t8;
+
+				pci_pmu = dev;  /* for LEDs D2 and D3 */
+				/* Program the lines for LEDs D2 and D3 to output */
+				pci_read_config_byte(dev, 0x7d, &t8);
+				t8 |= 0xc0;
+				pci_write_config_byte(dev, 0x7d, t8);
+				/* Turn LEDs D2 and D3 off */
+				pci_read_config_byte(dev, 0x7e, &t8);
+				t8 |= 0xc0;
+				pci_write_config_byte(dev, 0x7e, t8);
+
+		}
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci_ops.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/pci_ops.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/ddb5xxx/ddb5476/pci_ops.c
+ *     Define the pci_ops for DB5477.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.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 <linux/config.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+/*
+ * config_swap structure records what set of pdar/pmr are used
+ * to access pci config space.  It also provides a place hold the
+ * original values for future restoring.
+ */
+struct pci_config_swap {
+	u32 	pdar;
+	u32	pmr;
+	u32	config_base;
+	u32	config_size;
+	u32	pdar_backup;
+	u32	pmr_backup;
+};
+
+/*
+ * On DDB5476, we have one set of swap registers
+ */
+struct pci_config_swap ext_pci_swap = {
+	DDB_PCIW0,
+	DDB_PCIINIT0,
+	DDB_PCI_CONFIG_BASE,
+	DDB_PCI_CONFIG_SIZE
+};
+
+static int pci_config_workaround=1;
+
+/*
+ * access config space
+ */
+static inline u32 ddb_access_config_base(struct pci_config_swap *swap,
+					 u32 bus,/* 0 means top level bus */
+					 u32 slot_num)
+{
+	u32 pci_addr = 0;
+	u32 pciinit_offset = 0;
+        u32 virt_addr = swap->config_base;
+	u32 option;
+
+	if (pci_config_workaround) {
+		if (slot_num == 5) slot_num = 14;
+	}
+	else {
+		if (slot_num == 5) return DDB_BASE + DDB_PCI_BASE;
+	}
+
+	/* minimum pdar (window) size is 2MB */
+	db_assert(swap->config_size >= (2 << 20));
+
+	db_assert(slot_num < (1 << 5));
+	db_assert(bus < (1 << 8));
+
+	/* backup registers */
+	swap->pdar_backup = ddb_in32(swap->pdar);
+	swap->pmr_backup = ddb_in32(swap->pmr);
+
+	/* set the pdar (pci window) register */
+	ddb_set_pdar(swap->pdar,
+		     swap->config_base,
+		     swap->config_size,
+		     32,	/* 32 bit wide */
+		     0,		/* not on local memory bus */
+		     0);	/* not visible from PCI bus (N/A) */
+
+	/*
+	 * calcuate the absolute pci config addr;
+	 * according to the spec, we start scanning from adr:11 (0x800)
+	 */
+	if (bus == 0) {
+		/* type 0 config */
+		pci_addr = 0x00040000 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = 0x00040000 << slot_num;
+		panic("ddb_access_config_base: we don't support type 1 config Yet");
+	}
+
+	/*
+	 * if pci_addr is less than pci config window size,  we set
+	 * pciinit_offset to 0 and adjust the virt_address.
+	 * Otherwise we will try to adjust pciinit_offset.
+	 */
+	if (pci_addr < swap->config_size) {
+		virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
+		pciinit_offset = 0;
+	} else {
+		db_assert( (pci_addr & (swap->config_size - 1)) == 0);
+		virt_addr = KSEG1ADDR(swap->config_base);
+		pciinit_offset = pci_addr;
+	}
+
+	/* set the pmr register */
+	option = DDB_PCI_ACCESS_32;
+	if (bus != 0) option |= DDB_PCI_CFGTYPE1;
+	ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
+
+	return virt_addr;
+}
+
+static inline void ddb_close_config_base(struct pci_config_swap *swap)
+{
+	ddb_out32(swap->pdar, swap->pdar_backup);
+	ddb_out32(swap->pmr, swap->pmr_backup);
+}
+
+static int read_config_dword(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u32 *val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*val = *(volatile u32*) (base + (func_num << 8) + where);
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int read_config_word(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u16 *val)
+{
+        int status;
+        u32 result;
+
+	db_assert((where & 1) == 0);
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 2) result >>= 16;
+        *val = result & 0xffff;
+        return status;
+}
+
+static int read_config_byte(struct pci_config_swap *swap,
+			    struct pci_dev *dev,
+			    u32 where,
+			    u8 *val)
+{
+        int status;
+        u32 result;
+
+        status = read_config_dword(swap, dev, where & ~3, &result);
+        if (where & 1) result >>= 8;
+        if (where & 2) result >>= 16;
+        *val = result & 0xff;
+        return status;
+}
+
+static int write_config_dword(struct pci_config_swap *swap,
+			      struct pci_dev *dev,
+			      u32 where,
+			      u32 val)
+{
+	u32 bus, slot_num, func_num;
+	u32 base;
+
+	db_assert((where & 3) == 0);
+	db_assert(where < (1 << 8));
+
+	/* check if the bus is top-level */
+	if (dev->bus->parent != NULL) {
+		bus = dev->bus->number;
+		db_assert(bus != 0);
+	} else {
+		bus = 0;
+	}
+
+	slot_num = PCI_SLOT(dev->devfn);
+	func_num = PCI_FUNC(dev->devfn);
+	base = ddb_access_config_base(swap, bus, slot_num);
+	*(volatile u32*) (base + (func_num << 8) + where) = val;
+	ddb_close_config_base(swap);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u16 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	db_assert((where & 1) == 0);
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        result &= ~(0xffff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+static int write_config_byte(struct pci_config_swap *swap,
+			     struct pci_dev *dev,
+			     u32 where,
+			     u8 val)
+{
+	int status, shift=0;
+	u32 result;
+
+	status = read_config_dword(swap, dev, where & ~3, &result);
+	if (status != PCIBIOS_SUCCESSFUL) return status;
+
+        if (where & 2)
+                shift += 16;
+        if (where & 1)
+                shift += 8;
+        result &= ~(0xff << shift);
+        result |= val << shift;
+        return write_config_dword(swap, dev, where & ~3, result);
+}
+
+#define	MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
+static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
+{ \
+     return rw##_config_##unitname(pciswap, \
+                                   dev, \
+                                   where, \
+                                   val); \
+}
+
+MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
+
+MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
+MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
+
+struct pci_ops ddb5476_ext_pci_ops ={
+	extpci_read_config_byte,
+	extpci_read_config_word,
+	extpci_read_config_dword,
+	extpci_write_config_byte,
+	extpci_write_config_word,
+	extpci_write_config_dword
+};
+
+
+#if defined(CONFIG_DEBUG)
+void jsun_scan_pci_bus(void)
+{
+	struct pci_bus bus;
+	struct pci_dev dev;
+	unsigned int devfn;
+	int j;
+
+	pci_config_workaround = 0;
+
+	bus.parent = NULL;	/* we scan the top level only */
+	dev.bus = &bus;
+	dev.sysdata = NULL;
+
+	/* scan ext pci bus and io pci bus*/
+	for (j=0; j< 1; j++) {
+		printk(KERN_INFO "scan ddb5476 external PCI bus:\n");
+		bus.ops = &ddb5476_ext_pci_ops;
+
+		for (devfn = 0; devfn < 0x100; devfn += 8) {
+			u32 temp;
+			u16 temp16;
+			u8 temp8;
+			int i;
+
+			dev.devfn = devfn;
+			db_verify(pci_read_config_dword(&dev, 0, &temp),
+				    == PCIBIOS_SUCCESSFUL);
+			if (temp == 0xffffffff) continue;
+
+			printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8,
+			       11+devfn/8);
+
+			/* verify read word and byte */
+			db_verify(pci_read_config_word(&dev, 2, &temp16),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp16 == (temp >> 16));
+			db_verify(pci_read_config_byte(&dev, 3, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == (temp >> 24));
+			db_verify(pci_read_config_byte(&dev, 1, &temp8),
+				  == PCIBIOS_SUCCESSFUL);
+			db_assert(temp8 == ((temp >> 8) & 0xff));
+
+			for (i=0; i < 16; i++) {
+				if ((i%4) == 0)
+					printk(KERN_INFO);
+				db_verify(pci_read_config_dword(&dev, i*4, &temp),
+					  == PCIBIOS_SUCCESSFUL);
+				printk("\t%08X", temp);
+				if ((i%4) == 3)
+					printk("\n");
+			}
+		}
+	}
+
+	pci_config_workaround = 1;
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/setup.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,275 @@
+/*
+ *  arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/pc_keyb.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/keyboard.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/gdb-stub.h>
+#include <asm/time.h>
+#include <asm/nile4.h>
+#include <asm/ddb5xxx/ddb5074.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+extern void breakpoint(void);
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+extern void console_setup(char *);
+#endif
+
+extern struct ide_ops std_ide_ops;
+extern struct kbd_ops std_kbd_ops;
+extern struct rtc_ops ddb_rtc_ops;
+
+static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
+
+static void ddb_machine_restart(char *command)
+{
+	u32 t;
+
+	/* PCI cold reset */
+	t = nile4_in32(NILE4_PCICTRL + 4);
+	t |= 0x40000000;
+	nile4_out32(NILE4_PCICTRL + 4, t);
+	/* CPU cold reset */
+	t = nile4_in32(NILE4_CPUSTAT);
+	t |= 1;
+	nile4_out32(NILE4_CPUSTAT, t);
+	/* Call the PROM */
+	back_to_prom();
+}
+
+static void ddb_machine_halt(void)
+{
+	printk("DDB Vrc-5074 halted.\n");
+	do {
+	} while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk("DDB Vrc-5074 halted. Please turn off the power.\n");
+	do {
+	} while (1);
+}
+
+extern void ddb_irq_setup(void);
+extern void rtc_ds1386_init(unsigned long base);
+
+extern void (*board_timer_setup) (struct irqaction * irq);
+
+void __init bus_error_init(void)
+{
+}
+
+static void __init ddb_timer_init(struct irqaction *irq)
+{
+	/* set the clock to 1 Hz */
+	nile4_out32(NILE4_T2CTRL, 1000000);
+	/* enable the General-Purpose Timer */
+	nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
+	/* reset timer */
+	nile4_out32(NILE4_T2CNTR, 0);
+	/* enable interrupt */
+	setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
+	nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT));
+	change_cp0_status(ST0_IM,
+		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
+
+}
+
+static void __init ddb_time_init(void)
+{
+    /* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
+}
+
+
+
+void __init ddb_setup(void)
+{
+	extern int panic_timeout;
+
+	irq_setup = ddb_irq_setup;
+	set_io_port_base(NILE4_PCI_IO_BASE);
+	isa_slot_offset = NILE4_PCI_MEM_BASE;
+	board_timer_setup = ddb_timer_init;
+	board_time_init = ddb_time_init;
+
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+#ifdef CONFIG_PC_KEYB
+    kbd_ops = &std_kbd_ops;
+#endif
+
+	rtc_ops = &ddb_rtc_ops;
+
+    ddb_out32(DDB_BAR0, 0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, 0x10);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE , 0x10);
+
+#ifdef CONFIG_FB
+    conswitchp = &dummy_con;
+#endif
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+}
+
+
+#define USE_NILE4_SERIAL	0
+
+#if USE_NILE4_SERIAL
+#define ns16550_in(reg)		nile4_in8((reg)*8)
+#define ns16550_out(reg, val)	nile4_out8((reg)*8, (val))
+#else
+#define NS16550_BASE		(NILE4_PCI_IO_BASE+0x03f8)
+static inline u8 ns16550_in(u32 reg)
+{
+	return *(volatile u8 *) (NS16550_BASE + reg);
+}
+
+static inline void ns16550_out(u32 reg, u8 val)
+{
+	*(volatile u8 *) (NS16550_BASE + reg) = val;
+}
+#endif
+
+#define NS16550_RBR		0
+#define NS16550_THR		0
+#define NS16550_DLL		0
+#define NS16550_IER		1
+#define NS16550_DLM		1
+#define NS16550_FCR		2
+#define NS16550_IIR		2
+#define NS16550_LCR		3
+#define NS16550_MCR		4
+#define NS16550_LSR		5
+#define NS16550_MSR		6
+#define NS16550_SCR		7
+
+#define NS16550_LSR_DR		0x01	/* Data ready */
+#define NS16550_LSR_OE		0x02	/* Overrun */
+#define NS16550_LSR_PE		0x04	/* Parity error */
+#define NS16550_LSR_FE		0x08	/* Framing error */
+#define NS16550_LSR_BI		0x10	/* Break */
+#define NS16550_LSR_THRE	0x20	/* Xmit holding register empty */
+#define NS16550_LSR_TEMT	0x40	/* Xmitter empty */
+#define NS16550_LSR_ERR		0x80	/* Error */
+
+
+void _serinit(void)
+{
+#if USE_NILE4_SERIAL
+	ns16550_out(NS16550_LCR, 0x80);
+	ns16550_out(NS16550_DLM, 0x00);
+	ns16550_out(NS16550_DLL, 0x36);	/* 9600 baud */
+	ns16550_out(NS16550_LCR, 0x00);
+	ns16550_out(NS16550_LCR, 0x03);
+	ns16550_out(NS16550_FCR, 0x47);
+#else
+	/* done by PMON */
+#endif
+}
+
+void _putc(char c)
+{
+	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+	ns16550_out(NS16550_THR, c);
+	if (c == '\n') {
+		while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
+		ns16550_out(NS16550_THR, '\r');
+	}
+}
+
+void _puts(const char *s)
+{
+	char c;
+	while ((c = *s++))
+		_putc(c);
+}
+
+char _getc(void)
+{
+	while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
+	return ns16550_in(NS16550_RBR);
+}
+
+int _testc(void)
+{
+	return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
+}
+
+
+/*
+ *  Hexadecimal 7-segment LED
+ */
+void ddb5074_led_hex(int hex)
+{
+	outb(hex, 0x80);
+}
+
+
+/*
+ *  LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
+ */
+struct pci_dev *pci_pmu = NULL;
+
+void ddb5074_led_d2(int on)
+{
+	u8 t;
+
+	if (pci_pmu) {
+		pci_read_config_byte(pci_pmu, 0x7e, &t);
+		if (on)
+			t &= 0x7f;
+		else
+			t |= 0x80;
+		pci_write_config_byte(pci_pmu, 0x7e, t);
+	}
+}
+
+void ddb5074_led_d3(int on)
+{
+	u8 t;
+
+	if (pci_pmu) {
+		pci_read_config_byte(pci_pmu, 0x7e, &t);
+		if (on)
+			t &= 0xbf;
+		else
+			t |= 0x40;
+		pci_write_config_byte(pci_pmu, 0x7e, t);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/time.c linux-2.4.20/arch/mips/ddb5xxx/ddb5074/time.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5074/time.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,33 @@
+/*
+ *  arch/mips/ddb5074/time.c -- Timer routines
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ *
+ */
+#include <linux/init.h>
+#include <asm/mc146818rtc.h>
+#include <asm/ddb5xxx/ddb5074.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+static unsigned char ddb_rtc_read_data(unsigned long addr)
+{
+	return *(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr);
+}
+
+static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
+{
+ 	*(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr)=data;
+}
+
+static int ddb_rtc_bcd_mode(void)
+{
+	return 1;
+}
+
+struct rtc_ops ddb_rtc_ops = {
+	ddb_rtc_read_data,
+	ddb_rtc_write_data,
+	ddb_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/Makefile linux-2.4.20/arch/mips/ddb5xxx/ddb5476/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/Makefile	2002-10-04 00:41:09.000000000 +0000
@@ -9,10 +9,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET = ddb5476.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/int-handler.S linux-2.4.20/arch/mips/ddb5xxx/ddb5476/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/int-handler.S	2002-10-04 00:41:14.000000000 +0000
@@ -9,8 +9,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
-
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
@@ -30,7 +28,7 @@
 	CLI
 	.set	at
 	.set	noreorder
-	mfc0	t0, CP0_CAUSE  
+	mfc0	t0, CP0_CAUSE
 	mfc0	t2, CP0_STATUS
 
 	and	t0, t2
@@ -64,13 +62,13 @@
 
 	.align	5
 
-ll_cpu_ip0:	
+ll_cpu_ip0:
 	li	a0, CPU_IRQ_BASE + 0
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip1:	
+ll_cpu_ip1:
 	li	a0, CPU_IRQ_BASE + 1
 	move	a1, sp
 	jal	do_IRQ
@@ -81,25 +79,25 @@
 	jal	vrc5476_irq_dispatch
 	j	ret_from_irq
 
-ll_cpu_ip3:	
+ll_cpu_ip3:
 	li	a0, CPU_IRQ_BASE + 3
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip4:	
+ll_cpu_ip4:
 	li	a0, CPU_IRQ_BASE + 4
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip5:	
+ll_cpu_ip5:
 	li	a0, CPU_IRQ_BASE + 5
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip6:	
+ll_cpu_ip6:
 	li	a0, CPU_IRQ_BASE + 6
 	move	a1, sp
 	jal	do_IRQ
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/irq.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/irq.c	2002-10-04 00:41:18.000000000 +0000
@@ -9,7 +9,6 @@
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -46,9 +45,9 @@
 	 *
 	 *      IRQ1  - keyboard (default set by M1543)
 	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
-	 *              the schematics for the DDB Vrc-5476 board seem to 
-	 *              indicate that IRQ3 is connected to the DS1386 
-	 *              watchdog timer interrupt output so we might have 
+	 *              the schematics for the DDB Vrc-5476 board seem to
+	 *              indicate that IRQ3 is connected to the DS1386
+	 *              watchdog timer interrupt output so we might have
 	 *              a conflict)
 	 *      IRQ4  - reserved for UART A (default set by M1543)
 	 *      IRQ5  - parallel (default set by M1543)
@@ -60,7 +59,7 @@
 	 */
 
 	/*
-	 *  Assing mouse interrupt to IRQ12 
+	 *  Assing mouse interrupt to IRQ12
 	 */
 
 	/* Enter configuration mode */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	2002-10-04 00:41:20.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  arch/mips/ddb5476/nile4.c -- 
+ *  arch/mips/ddb5476/nile4.c --
  *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
  *
  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
@@ -9,6 +9,7 @@
  *  Author: jsun@mvista.com or jsun@junsun.net
  *
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/pci.c	2002-10-04 00:41:12.000000000 +0000
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -9,13 +10,13 @@
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 static struct resource extpci_io_resource = {
-	"pci IO space", 
+	"pci IO space",
 	0x1000,				/* leave some room for ISA bus */
 	DDB_PCI_IO_SIZE -1,
 	IORESOURCE_IO};
 
 static struct resource extpci_mem_resource = {
-	"pci memory space", 
+	"pci memory space",
 	DDB_PCI_MEM_BASE + 0x00100000,	/* leave 1 MB for RTC */
 	DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1,
 	IORESOURCE_MEM};
@@ -31,7 +32,7 @@
 /*
  * we fix up irqs based on the slot number.
  * The first entry is at AD:11.
- * 
+ *
  * This does not work for devices on sub-buses yet.
  */
 
@@ -92,7 +93,7 @@
 		db_assert(slot_num < MAX_SLOT_NUM);
 		db_assert(irq_map[slot_num] != 0xff);
 
-		pci_write_config_byte(dev, 
+		pci_write_config_byte(dev,
 				      PCI_INTERRUPT_LINE,
 				      irq_map[slot_num]);
 		dev->irq = irq_map[slot_num];
@@ -104,7 +105,7 @@
 #endif
 
 void __init ddb_pci_reset_bus(void)
-{	
+{
 	u32 temp;
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/pci_ops.c	2002-10-04 00:41:15.000000000 +0000
@@ -5,7 +5,7 @@
  * arch/mips/ddb5xxx/ddb5476/pci_ops.c
  *     Define the pci_ops for DB5477.
  *
- * Much of the code is derived from the original DDB5074 port by 
+ * Much of the code is derived from the original DDB5074 port by
  * Geert Uytterhoeven <geert@sonycom.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -43,7 +43,7 @@
  * On DDB5476, we have one set of swap registers
  */
 struct pci_config_swap ext_pci_swap = {
-	DDB_PCIW0,  
+	DDB_PCIW0,
 	DDB_PCIINIT0,
 	DDB_PCI_CONFIG_BASE,
 	DDB_PCI_CONFIG_SIZE
@@ -53,7 +53,7 @@
 
 /*
  * access config space
- */	
+ */
 static inline u32 ddb_access_config_base(struct pci_config_swap *swap,
 					 u32 bus,/* 0 means top level bus */
 					 u32 slot_num)
@@ -66,7 +66,7 @@
 	if (pci_config_workaround) {
 		/* [jsun] work around Vrc5476 controller itself, returnning
 		 * slot 0 essentially makes vrc5476 invisible
-		 */ 
+		 */
 		if (slot_num == 12) slot_num = 0;
 
 #if 0
@@ -77,7 +77,7 @@
 	} else {
 		/* now we have to be hornest, returning the true
 		 * PCI config headers for vrc5476
-		 */ 
+		 */
 		if (slot_num == 12) {
 			swap->pdar_backup = ddb_in32(swap->pdar);
 			swap->pmr_backup = ddb_in32(swap->pmr);
@@ -103,10 +103,10 @@
 		     0,		/* not on local memory bus */
 		     0);	/* not visible from PCI bus (N/A) */
 
-	/* 
-	 * calcuate the absolute pci config addr; 
+	/*
+	 * calcuate the absolute pci config addr;
 	 * according to the spec, we start scanning from adr:11 (0x800)
-	 */ 
+	 */
 	if (bus == 0) {
 		/* type 0 config */
 		pci_addr = 0x800 << slot_num;
@@ -224,7 +224,7 @@
 	slot_num = PCI_SLOT(dev->devfn);
 	func_num = PCI_FUNC(dev->devfn);
 	base = ddb_access_config_base(swap, bus, slot_num);
-	*(volatile u32*) (base + (func_num << 8) + where) = val; 
+	*(volatile u32*) (base + (func_num << 8) + where) = val;
 	ddb_close_config_base(swap);
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -314,7 +314,7 @@
 	for (j=0; j< 1; j++) {
 		printk(KERN_INFO "scan ddb5476 external PCI bus:\n");
 		bus.ops = &ddb5476_ext_pci_ops;
-	
+
 		for (devfn = 0; devfn < 0x100; devfn += 8) {
 			u32 temp;
 			u16 temp16;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/setup.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/setup.c	2002-10-04 00:41:13.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/time.h>
 #include <asm/debug.h>
+#include <asm/traps.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -138,11 +139,15 @@
 	{ "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
 };
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 static void ddb5476_board_init(void);
 extern void ddb5476_irq_setup(void);
 extern void (*irq_setup)(void);
 
-void __init 
+void __init
 ddb_setup(void)
 {
 	extern int panic_timeout;
@@ -197,7 +202,7 @@
  * We don't trust bios.  We essentially does hardware re-initialization
  * as complete as possible, as far as we know we can safely do.
  */
-static void 
+static void
 ddb5476_board_init(void)
 {
 	/* ----------- setup PDARs ------------ */
@@ -240,7 +245,7 @@
 	/* this is problematic - it will reset Aladin which cause we loose
 	 * serial port, and we don't know how to set up Aladin chip again.
 	 */
-	// ddb_pci_reset_bus(); 
+	// ddb_pci_reset_bus();
 
 	ddb_out32(DDB_BAR0, 0x00000008);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-2.4.20/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	2002-10-04 00:41:12.000000000 +0000
@@ -62,7 +62,7 @@
 	NULL				/* no affinity stuff for UP */
 };
 
-void __init 
+void __init
 vrc5476_irq_init(u32 base)
 {
 	extern irq_desc_t irq_desc[];
@@ -78,7 +78,7 @@
 }
 
 
-asmlinkage void 
+asmlinkage void
 vrc5476_irq_dispatch(struct pt_regs *regs)
 {
 	extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/Makefile linux-2.4.20/arch/mips/ddb5xxx/ddb5477/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= ddb5477.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/debug.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/debug.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/debug.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/debug.c	2002-10-04 00:41:12.000000000 +0000
@@ -30,9 +30,9 @@
 
 	printk("\nshow regs: %s\n", name);
 	for(i=0;regs[i].regname!= NULL; i++) {
-		printk("%-16s= %08x\t\t(@%08x)\n", 
-		       regs[i].regname, 
-		       *(unsigned *)(regs[i].regaddr), 
+		printk("%-16s= %08x\t\t(@%08x)\n",
+		       regs[i].regname,
+		       *(unsigned *)(regs[i].regaddr),
 		       regs[i].regaddr);
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/int-handler.S linux-2.4.20/arch/mips/ddb5xxx/ddb5477/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/int-handler.S	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/int-handler.S	2002-10-04 00:41:11.000000000 +0000
@@ -9,8 +9,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
-
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
@@ -28,14 +26,14 @@
 	CLI
 	.set	at
 	.set	noreorder
-	mfc0	t0, CP0_CAUSE  
+	mfc0	t0, CP0_CAUSE
 	mfc0	t2, CP0_STATUS
 
 	and	t0, t2
-       
+
 	andi	t1, t0, STATUSF_IP7	/* cpu timer */
 	bnez	t1, ll_cputimer_irq
-	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) 
+	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
 	bnez	t1, ll_vrc5477_irq
 	andi	t1, t0, STATUSF_IP0	/* software int 0 */
 	bnez	t1, ll_cpu_ip0
@@ -51,7 +49,7 @@
 
 	.align	5
 
-ll_vrc5477_irq:	
+ll_vrc5477_irq:
 	move	a0, sp
 	jal	vrc5477_irq_dispatch
 	j	ret_from_irq
@@ -63,13 +61,13 @@
 	j	ret_from_irq
 
 
-ll_cpu_ip0:	
+ll_cpu_ip0:
 	li	a0, 0
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip1:	
+ll_cpu_ip1:
 	li	a0, 1
 	move	a1, sp
 	jal	do_IRQ
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/irq.c	2002-10-04 00:41:11.000000000 +0000
@@ -19,6 +19,8 @@
 #include <asm/system.h>
 #include <asm/mipsregs.h>
 #include <asm/debug.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -37,7 +39,7 @@
  *	7 - 	cpu timer (used by default)
  *
  *  8-39: 32 Vrc5477 interrupt sources
- *	(refer to the Vrc5477 manual)	
+ *	(refer to the Vrc5477 manual)
  */
 
 #define	PCI0			DDB_INTPPES0
@@ -55,7 +57,7 @@
 #define	INTD			3
 #define	INTE			4
 
-static inline void 
+static inline void
 set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
 {
 	u32 reg_value;
@@ -63,22 +65,25 @@
 
 	reg_value = ddb_in32(pci);
 	reg_bitmask = 0x3 << (intn * 2);
-	
+
 	reg_value &= ~reg_bitmask;
 	reg_value |= (active | trigger) << (intn * 2);
 	ddb_out32(pci, reg_value);
 }
 
+extern void init_i8259_irqs (void);
 extern void vrc5477_irq_init(u32 base);
 extern void mips_cpu_irq_init(u32 base);
 extern asmlinkage void ddb5477_handle_int(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
 
 void
 ddb5477_irq_setup(void)
 {
 	db_run(printk("ddb5477_irq_setup invoked.\n"));
 
-	/* by default, we disable all interrupts and route all vrc5477 
+	/* by default, we disable all interrupts and route all vrc5477
 	 * interrupts to pin 0 (irq 2) */
 	ddb_out32(DDB_INTCTRL0, 0);
 	ddb_out32(DDB_INTCTRL1, 0);
@@ -91,7 +96,10 @@
 	/* setup PCI interrupt attributes */
 	set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE);
-	set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
+		set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE);
+	else
+		set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE);
 
@@ -101,9 +109,9 @@
 	set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE);
 
-	/* 
+	/*
 	 * for debugging purpose, we enable several error interrupts
-	 * and route them to pin 1. (IP3) 
+	 * and route them to pin 1. (IP3)
 	 */
 	/* cpu parity check - 0 */
 	ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0);
@@ -121,13 +129,34 @@
 	ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31);
 
 	/* init all controllers */
-	mips_cpu_irq_init(0);
-	vrc5477_irq_init(8);
+	init_i8259_irqs();
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+	vrc5477_irq_init(VRC5477_IRQ_BASE);
+
+
+	/* setup cascade interrupts */
+	setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
 
 	/* hook up the first-level interrupt handler */
 	set_except_vector(0, ddb5477_handle_int);
 }
 
+u8 i8259_interrupt_ack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT10);
+
+	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	ddb_out32(DDB_PCIINIT10, reg);
+
+	/* i8259.c set the base vector to be 0x0 */
+	return irq + I8259_IRQ_BASE;
+}
 /*
  * the first level int-handler will jump here if it is a vrc5477 irq
  */
@@ -154,10 +183,21 @@
 	}
 
 	intStatus = ddb_in32(DDB_INT0STAT);
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* check for i8259 interrupts */
+		if (intStatus & (1 << VRC5477_I8259_CASCADE)) {
+			int i8259_irq = i8259_interrupt_ack();
+			do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+			return;
+		}
+	}
+
 	for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
 		/* do we need to "and" with the int mask? */
 		if (intStatus & bitmask) {
-			do_IRQ(8 + i, regs);
+			do_IRQ(VRC5477_IRQ_BASE + i, regs);
+			return;
 		}
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2002-10-04 00:41:14.000000000 +0000
@@ -18,6 +18,7 @@
  * This file exports one function:
  *	vrc5477_irq_init(u32 irq_base);
  */
+
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
@@ -32,7 +33,7 @@
 static int vrc5477_irq_base = -1;
 
 
-static void 
+static void
 vrc5477_irq_enable(unsigned int irq)
 {
 	db_assert(vrc5477_irq_base != -1);
@@ -42,7 +43,7 @@
 	ll_vrc5477_irq_enable(irq - vrc5477_irq_base);
 }
 
-static void 
+static void
 vrc5477_irq_disable(unsigned int irq)
 {
 	db_assert(vrc5477_irq_base != -1);
@@ -99,7 +100,7 @@
 	NULL			/* no affinity stuff for UP */
 };
 
-void 
+void
 vrc5477_irq_init(u32 irq_base)
 {
 	extern irq_desc_t irq_desc[];
@@ -111,17 +112,8 @@
 		irq_desc[i].depth = 1;
 		irq_desc[i].handler = &vrc5477_irq_controller;
 	}
-	
-	vrc5477_irq_base = irq_base;
-}
 
-
-int vrc5477_irq_to_irq(int irq)
-{
-	db_assert(irq >= 0);
-	db_assert(irq < NUM_5477_IRQ);
-
-	return irq + vrc5477_irq_base;
+	vrc5477_irq_base = irq_base;
 }
 
 void ll_vrc5477_irq_route(int vrc5477_irq, int ip)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/pci.c	2002-10-04 00:41:20.000000000 +0000
@@ -11,36 +11,38 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 
+#include <asm/bootinfo.h>
 #include <asm/pci_channel.h>
 #include <asm/debug.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 static struct resource extpci_io_resource = {
-	"ext pci IO space", 
-	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE,
+	"ext pci IO space",
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000,
 	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE -1,
 	IORESOURCE_IO};
 
 static struct resource extpci_mem_resource = {
-	"ext pci memory space", 
-	DDB_PCI0_MEM_BASE,
+	"ext pci memory space",
+	DDB_PCI0_MEM_BASE + 0x100000,
 	DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE -1,
 	IORESOURCE_MEM};
 
 static struct resource iopci_io_resource = {
-	"io pci IO space", 
+	"io pci IO space",
 	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
 	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE -1,
 	IORESOURCE_IO};
 
 static struct resource iopci_mem_resource = {
-	"ext pci memory space", 
+	"ext pci memory space",
 	DDB_PCI1_MEM_BASE,
 	DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE -1,
 	IORESOURCE_MEM};
@@ -59,79 +61,108 @@
  * we fix up irqs based on the slot number.
  * The first entry is at AD:11.
  * Fortunately this works because, although we have two pci buses,
- * they all have different slot numbers.
- * 
- * This does not work for devices on sub-buses.
+ * they all have different slot numbers (except for rockhopper slot 20
+ * which is handled below).
  *
- * Note that the irq number in the array is relative number in vrc5477.
- * We need to translate it to global irq number.
  */
 
 /*
- * irq mapping : PCI int # -> vrc5477 irq #
- * based on vrc5477 manual page 46
- */
-#define		PCI_EXT_INTA		8
-#define		PCI_EXT_INTB		9
-#define		PCI_EXT_INTC		10
-#define		PCI_EXT_INTD		11
-#define		PCI_EXT_INTE		12
-
-#define		PCI_IO_INTA		16
-#define		PCI_IO_INTB		17
-#define		PCI_IO_INTC		18
-#define		PCI_IO_INTD		19
-
-/* 
- * irq mapping : device -> pci int #, 
+ * irq mapping : device -> pci int # -> vrc4377 irq# ,
  * ddb5477 board manual page 4  and vrc5477 manual page 46
  */
-#define		INT_ONBOARD_TULIP	PCI_EXT_INTA
-#define		INT_SLOT1		PCI_EXT_INTB
-#define		INT_SLOT2		PCI_EXT_INTC
-#define		INT_SLOT3		PCI_EXT_INTD
-#define		INT_SLOT4		PCI_EXT_INTE
-
-#define		INT_USB_HOST		PCI_IO_INTA
-#define		INT_USB_PERI		PCI_IO_INTB
-#define		INT_AC97		PCI_IO_INTC
 
 /*
  * based on ddb5477 manual page 11
  */
 #define		MAX_SLOT_NUM		21
 static unsigned char irq_map[MAX_SLOT_NUM] = {
-	/* AD:11 */ 0xff, 0xff, 0xff, 0xff, 
-	/* AD:15 */ INT_ONBOARD_TULIP, INT_SLOT1, INT_SLOT2, INT_SLOT3,
-	/* AD:19 */ INT_SLOT4, 0xff, 0xff, 0xff,
-	/* AD:23 */ 0xff, 0xff, 0xff, 0xff,
-	/* AD:27 */ 0xff, 0xff, INT_AC97, INT_USB_PERI, 
-	/* AD:31 */ INT_USB_HOST
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ 0xff,
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ VRC5477_IRQ_INTA,       /* onboard tulip */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTB,       /* slot 1 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTC,       /* slot 2 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 3 */
+	/* SLOT:  8, AD:19 */ VRC5477_IRQ_INTE,       /* slot 4 */
+	/* SLOT:  9, AD:20 */ 0xff,
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0xff,
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
+};
+static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ VRC5477_IRQ_INTB,       /* onboard AMD PCNET */
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ 14,                     /* M5229 ide ISA irq */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTD,       /* slot 3 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTA,       /* slot 4 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 5 */
+	/* SLOT:  8, AD:19 */ 0,                      /* M5457 modem nop */
+	/* SLOT:  9, AD:20 */ VRC5477_IRQ_INTA,       /* slot 2 */
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0,                      /* M7101 PMU nop */
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
 };
 
-extern int vrc5477_irq_to_irq(int irq);
 void __init pcibios_fixup_irqs(void)
 {
         struct pci_dev *dev;
         int slot_num;
+        unsigned char *slot_irq_map;
+        unsigned char irq;
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
+		slot_irq_map = rockhopperII_irq_map;
+	else
+		slot_irq_map = irq_map;
+
 
 	pci_for_each_dev(dev) {
 		slot_num = PCI_SLOT(dev->devfn);
-
-               /* we don't do IRQ fixup for sub-bus yet */
-               if (dev->bus->parent != NULL) {
-                       db_run(printk("Don't know how to fixup irq for PCI device %d on sub-bus %d\n",
-                                       slot_num, dev->bus->number));
-                       continue;
-               }
+		irq = slot_irq_map[slot_num];
 
 		db_assert(slot_num < MAX_SLOT_NUM);
-		db_assert(irq_map[slot_num] != 0xff);
 
-		pci_write_config_byte(dev, 
+                db_assert(irq != 0xff);
+
+		pci_write_config_byte(dev,
 				      PCI_INTERRUPT_LINE,
-				      irq_map[slot_num]);
-		dev->irq = vrc5477_irq_to_irq(irq_map[slot_num]);
+				      irq);
+
+		dev->irq = irq;
+
+		if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+			/* hack to distinquish overlapping slot 20s, one
+			 * on bus 0 (ALI USB on the M1535 on the backplane),
+			 * and one on bus 2 (NEC USB controller on the CPU board)
+			 * Make the M1535 USB - ISA IRQ number 9.
+			 */
+			if (slot_num == 20 && dev->bus->number == 0) {
+				pci_write_config_byte(dev,
+						      PCI_INTERRUPT_LINE,
+						      9);
+				dev->irq = 9;
+			}
+		}
+
 	}
 }
 
@@ -139,8 +170,8 @@
 extern void jsun_scan_pci_bus(void);
 extern void jsun_assign_pci_resource(void);
 #endif
-void __init ddb_pci_reset_bus(void)
-{	
+void ddb_pci_reset_bus(void)
+{
 	u32 temp;
 
 	/*
@@ -175,5 +206,43 @@
 
 void __init pcibios_fixup(void)
 {
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		struct pci_dev *dev;
+
+#define M1535_CONFIG_PORT 0x3f0
+#define M1535_INDEX_PORT  0x3f0
+#define M1535_DATA_PORT   0x3f1
+
+		printk("Configuring ALI M1535 Super I/O mouse irq.\n");
+
+		request_region(M1535_CONFIG_PORT, 2, "M1535 Super I/O config");
+
+		/* Enter config mode. */
+		outb(0x51, M1535_CONFIG_PORT);
+		outb(0x23, M1535_CONFIG_PORT);
+
+		/* Select device 0x07. */
+		outb(0x07, M1535_INDEX_PORT);
+		outb(0x07, M1535_DATA_PORT);
+
+		/* Set mouse irq (register 0x72) to 12. */
+		outb(0x72, M1535_INDEX_PORT);
+		outb(0x0c, M1535_DATA_PORT);
+
+		/* Exit config mode. */
+		outb(0xbb, M1535_CONFIG_PORT);
+
+		pci_for_each_dev(dev) {
+			if(dev->vendor == PCI_VENDOR_ID_AL)
+				if(dev->device == PCI_DEVICE_ID_AL_M1535
+				    || dev->device == PCI_DEVICE_ID_AL_M1533) {
+				u8 old;
+				printk("Enabling ALI M1533/35 PS2 keyboard/mouse.\n");
+				pci_read_config_byte(dev, 0x41, &old);
+				pci_write_config_byte(dev, 0x41, old | 0xd0);
+			}
+		}
+
+	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2002-10-04 00:41:09.000000000 +0000
@@ -5,7 +5,7 @@
  * arch/mips/ddb5xxx/ddb5477/pci_ops.c
  *     Define the pci_ops for DB5477.
  *
- * Much of the code is derived from the original DDB5074 port by 
+ * Much of the code is derived from the original DDB5074 port by
  * Geert Uytterhoeven <geert@sonycom.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -48,13 +48,13 @@
  * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI.
  */
 struct pci_config_swap ext_pci_swap = {
-	DDB_PCIW0,  
+	DDB_PCIW0,
 	DDB_PCIINIT00,
 	DDB_PCI0_CONFIG_BASE,
 	DDB_PCI0_CONFIG_SIZE
 };
 struct pci_config_swap io_pci_swap = {
-	DDB_IOPCIW0,  
+	DDB_IOPCIW0,
 	DDB_PCIINIT01,
 	DDB_PCI1_CONFIG_BASE,
 	DDB_PCI1_CONFIG_SIZE
@@ -63,7 +63,7 @@
 
 /*
  * access config space
- */	
+ */
 static inline u32 ddb_access_config_base(struct pci_config_swap *swap,
 					 u32 bus,/* 0 means top level bus */
 					 u32 slot_num)
@@ -91,10 +91,10 @@
 		     0,		/* not on local memory bus */
 		     0);	/* not visible from PCI bus (N/A) */
 
-	/* 
-	 * calcuate the absolute pci config addr; 
+	/*
+	 * calcuate the absolute pci config addr;
 	 * according to the spec, we start scanning from adr:11 (0x800)
-	 */ 
+	 */
 	if (bus == 0) {
 		/* type 0 config */
 		pci_addr = 0x800 << slot_num;
@@ -211,7 +211,7 @@
 	slot_num = PCI_SLOT(dev->devfn);
 	func_num = PCI_FUNC(dev->devfn);
 	base = ddb_access_config_base(swap, bus, slot_num);
-	*(volatile u32*) (base + (func_num << 8) + where) = val; 
+	*(volatile u32*) (base + (func_num << 8) + where) = val;
 	ddb_close_config_base(swap);
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -300,114 +300,3 @@
 	iopci_write_config_dword
 };
 
-#if defined(CONFIG_DEBUG)
-void jsun_scan_pci_bus(void)
-{
-	struct pci_bus bus;
-	struct pci_dev dev;
-	unsigned int devfn;
-	int j;
-
-	bus.parent = NULL;	/* we scan the top level only */
-	dev.bus = &bus;
-	dev.sysdata = NULL;
-
-	/* scan ext pci bus and io pci bus*/
-	for (j=0; j< 2; j++) {
-		if (j ==  0) {
-			printk("scan ddb5477 external PCI bus:\n");
-			bus.ops = &ddb5477_ext_pci_ops;
-		} else {
-			printk("scan ddb5477 IO PCI bus:\n");
-			bus.ops = &ddb5477_io_pci_ops;
-		}
-	
-		for (devfn = 0; devfn < 0x100; devfn += 8) {
-			u32 temp;
-			u16 temp16;
-			u8 temp8;
-			int i;
-
-			dev.devfn = devfn;
-			db_verify(pci_read_config_dword(&dev, 0, &temp),
-				  == PCIBIOS_SUCCESSFUL);
-			if (temp == 0xffffffff) continue;
-
-			printk("slot %d: (addr %d) \n", devfn/8, 11+devfn/8);
-
-			/* verify read word and byte */
-			db_verify(pci_read_config_word(&dev, 2, &temp16),
-				  == PCIBIOS_SUCCESSFUL);
-			db_assert(temp16 == (temp >> 16));
-			db_verify(pci_read_config_byte(&dev, 3, &temp8),
-				  == PCIBIOS_SUCCESSFUL);
-			db_assert(temp8 == (temp >> 24));
-			db_verify(pci_read_config_byte(&dev, 1, &temp8),
-				  == PCIBIOS_SUCCESSFUL);
-			db_assert(temp8 == ((temp >> 8) & 0xff));
-
-			for (i=0; i < 16; i++) {
-				db_verify(pci_read_config_dword(&dev, i*4, &temp),
-					  == PCIBIOS_SUCCESSFUL);
-				printk("\t%08X", temp);
-				if ((i%4) == 3) printk("\n");
-			}
-		}
-	}
-}
-
-
-static void jsun_hardcode_pci_resources_eepro(void)
-{
-	struct pci_bus bus;
-	struct pci_dev dev;
-	u32 temp;
-
-	bus.parent = NULL;	/* we scan the top level only */
-	bus.ops = &ddb5477_ext_pci_ops;
-	dev.bus = &bus;
-	dev.sysdata = NULL;
-
-	/* for slot 5 (ext pci 1) eepro card */
-	dev.devfn = 5*8;
-	pci_read_config_dword(&dev, 0, &temp);
-	db_assert(temp == 0x12298086);
-
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, DDB_PCI0_MEM_BASE);
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, 0);
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_2, DDB_PCI0_MEM_BASE+0x100000);
-	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 17);
-}
-
-static void jsun_hardcode_pci_resources_onboard_tulip(void)
-{
-	struct pci_bus bus;
-	struct pci_dev dev;
-	u32 temp;
-
-	bus.parent = NULL;	/* we scan the top level only */
-	bus.ops = &ddb5477_ext_pci_ops;
-	dev.bus = &bus;
-	dev.sysdata = NULL;
-
-	/* for slot 4 on board ether chip */
-	dev.devfn = 4*8;
-	pci_read_config_dword(&dev, 0, &temp);
-	db_assert(temp == 0x00191011);
-
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, 0x1000);
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, DDB_PCI0_MEM_BASE);
-	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 16);
-}
-
-static void jsun_hardcode_pci_resources(void)
-{
-	jsun_hardcode_pci_resources_onboard_tulip();
-}
-
-void jsun_assign_pci_resource(void)
-{
-	jsun_hardcode_pci_resources();
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/setup.c linux-2.4.20/arch/mips/ddb5xxx/ddb5477/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/ddb5xxx/ddb5477/setup.c	2002-10-04 00:41:15.000000000 +0000
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/param.h>	/* for HZ */
 
+#include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
@@ -31,7 +32,11 @@
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/gdb-stub.h>
+#include <asm/traps.h>
 #include <asm/debug.h>
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -40,15 +45,13 @@
 
 // #define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
 
-#ifdef USE_CPU_COUNTER_TIMER
-#define	CPU_COUNTER_FREQUENCY		83000000
-#else
-/* otherwise we use special timer 1 */
-#define	SP_TIMER_FREQUENCY		83000000
+#ifndef USE_CPU_COUNTER_TIMER
 #define	SP_TIMER_BASE			DDB_SPT1CTRL_L
-#define	SP_TIMER_IRQ			(8 + 6)
+#define	SP_TIMER_IRQ			VRC5477_IRQ_SPT1
 #endif
 
+static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000;
+
 static void ddb_machine_restart(char *command)
 {
 	static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
@@ -79,19 +82,71 @@
 	while (1);
 }
 
+static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+{
+	unsigned int freq;
+	unsigned char c;
+	unsigned int t1, t2;
+	unsigned i;
+	unsigned preset_freq[]={
+		0,        83330000, 100000000, 124000000,133300000, 0xffffffff};
+
+	ddb_out32(SP_TIMER_BASE, 0xffffffff);
+	ddb_out32(SP_TIMER_BASE+4, 0x1);
+	ddb_out32(SP_TIMER_BASE+8, 0xffffffff);
+	c= *(volatile unsigned char*)rtc_base;
+	for(i=0; (i<100000000) && (c == *(volatile unsigned char*)rtc_base); i++);
+
+	if (c == *(volatile unsigned char*)rtc_base) {
+		printk("Failed to detect bus frequency.  Use default 83.3MHz.\n");
+		return 83333000;
+	}
+
+	/* we are now at the turn of 1/100th second */
+	t1 = ddb_in32(SP_TIMER_BASE+8);
+
+	c= *(volatile unsigned char*)rtc_base;
+	while (c == *(volatile unsigned char*)rtc_base);
+
+	/* we are now at the turn of another 1/100th second */
+	t2 = ddb_in32(SP_TIMER_BASE+8);
+	ddb_out32(SP_TIMER_BASE+4, 0x0);	/* disable it again */
+	freq = (t1 - t2)*100;
+
+	/* find the nearest preset freq */
+	for (i=0; freq > preset_freq[i+1]; i++);
+	if ((freq - preset_freq[i]) >= (preset_freq[i+1]-freq))
+		i++;
+
+	printk("DDB bus frequency detection : %d -> %d\n", freq, preset_freq[i]);
+	return preset_freq[i];
+}
+
 extern void rtc_ds1386_init(unsigned long base);
 static void __init ddb_time_init(void)
 {
-#if defined(USE_CPU_COUNTER_TIMER)
-	mips_counter_frequency = CPU_COUNTER_FREQUENCY;
-#endif
+	unsigned long rtc_base;
+	unsigned int i;
 
 	/* we have ds1396 RTC chip */
-	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
-		rtc_ds1386_init(KSEG1ADDR(DDB_LCS2_BASE));
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		rtc_base = KSEG1ADDR(DDB_LCS2_BASE);
 	} else {
-		rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE));
+		rtc_base = KSEG1ADDR(DDB_LCS1_BASE);
+	}
+	rtc_ds1386_init(rtc_base);
+
+	/* do we need to do run-time detection of bus speed? */
+	if (bus_frequency == 0) {
+		bus_frequency = detect_bus_frequency(rtc_base);
 	}
+
+	/* mips_counter_frequency is 1/2 of the cpu core freq */
+	i =  (read_32bit_cp0_register(CP0_CONFIG) >> 28 ) & 7;
+	if ((mips_cpu.cputype == CPU_R5432) && (i == 3))
+		i = 4;
+	mips_counter_frequency = bus_frequency*(i+4)/4;
 }
 
 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
@@ -101,7 +156,7 @@
 	unsigned int count;
 
         /* we are using the cpu counter for timer interrupts */
-	setup_irq(7, irq);
+	setup_irq(CPU_IRQ_BASE + 7, irq);
 
         /* to generate the first timer interrupt */
         count = read_32bit_cp0_register(CP0_COUNT);
@@ -109,24 +164,32 @@
 
 #else
 
-	/* if we don't use Special purpose timer 1 */
-	ddb_out32(SP_TIMER_BASE, SP_TIMER_FREQUENCY/HZ);
+	/* if we use Special purpose timer 1 */
+	ddb_out32(SP_TIMER_BASE, bus_frequency/HZ);
 	ddb_out32(SP_TIMER_BASE+4, 0x1);
 	setup_irq(SP_TIMER_IRQ, irq);
 
 #endif
 }
 
+void __init bus_error_init(void) { /* nothing */ }
+
 static void ddb5477_board_init(void);
 extern void ddb5477_irq_setup(void);
 
 #if defined(CONFIG_BLK_DEV_INITRD)
 extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end;
-#endif 
+#endif
 
 void __init ddb_setup(void)
 {
 	extern int panic_timeout;
+#ifdef CONFIG_BLK_DEV_IDE
+	extern struct ide_ops std_ide_ops;
+#endif
+
+	/* initialize board - we don't trust the loader */
+        ddb5477_board_init();
 
 	irq_setup = ddb5477_irq_setup;
 	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
@@ -141,17 +204,19 @@
 	/* setup resource limits */
 	ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
 	iomem_resource.end = 0xffffffff;
-	
+
 	/* Reboot on panic */
 	panic_timeout = 180;
 
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
 
-	/* initialize board - we don't trust the loader */
-	ddb5477_board_init();
-
 #if defined(CONFIG_BLK_DEV_INITRD)
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 	initrd_start = (unsigned long)&__rd_start;
@@ -161,10 +226,13 @@
 
 static void __init ddb5477_board_init()
 {
+#ifdef CONFIG_PC_KEYB
+	extern struct kbd_ops std_kbd_ops;
+#endif
 	/* ----------- setup PDARs ------------ */
 
 	/* SDRAM should have been set */
-	db_assert(ddb_in32(DDB_SDRAM0) == 
+	db_assert(ddb_in32(DDB_SDRAM0) ==
 		    ddb_calc_pdar(DDB_SDRAM_BASE, board_ram_size, 32, 0, 1));
 
 	/* SDRAM1 should be turned off.  What is this for anyway ? */
@@ -193,11 +261,11 @@
 	}
 
 	/* verify VRC5477 base addr */
-	db_assert(ddb_in32(DDB_VRC5477) == 
+	db_assert(ddb_in32(DDB_VRC5477) ==
 		  ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
-	
+
 	/* verify BOOT ROM addr */
-	db_assert(ddb_in32(DDB_BOOTCS) == 
+	db_assert(ddb_in32(DDB_BOOTCS) ==
 		  ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
 
 	/* setup PCI windows - window0 for MEM/config, window1 for IO */
@@ -232,7 +300,7 @@
 	ddb_out32(DDB_BAR51, 0xffffffff);
 	ddb_out32(DDB_BARB1, 0xffffffff);
 
-	/* 
+	/*
 	 * We use pci master register 0  for memory space / config space
 	 * And we use register 1 for IO space.
 	 * Note that for memory space, we bump up the pci base address
@@ -240,22 +308,49 @@
 	 * For PCI IO space, it starts from 0 in PCI IO space but with
 	 * DDB_xx_IO_BASE in CPU physical address space.
 	 */
-	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE, 
+	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE,
 		    DDB_PCI_ACCESS_32);
 	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
 
-	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE, 
+	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE,
 		    DDB_PCI_ACCESS_32);
-	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE, 
+	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE,
                     DDB_PCI_ACCESS_32);
 
-	
+
 	/* PCI cross window should be set properly */
 	ddb_set_pdar(DDB_BARP00, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP10, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP01, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP11, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
 
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* Disable bus diagnostics. */
+		ddb_out32(DDB_PCICTL0_L, 0);
+		ddb_out32(DDB_PCICTL0_H, 0);
+		ddb_out32(DDB_PCICTL1_L, 0);
+		ddb_out32(DDB_PCICTL1_H, 0);
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		u16			vid;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+		pci_read_config_word(&dev_m1533, 0, &vid);
+		if (vid == PCI_VENDOR_ID_AL) {
+			printk("Changing mips_machtype to MACH_NEC_ROCKHOPPERII\n");
+			mips_machtype = MACH_NEC_ROCKHOPPERII;
+		}
+	}
+
 	/* enable USB input buffers */
 	ddb_out32(DDB_PIBMISC, 0x00000007);
 
@@ -263,9 +358,83 @@
 	ddb_out32(DDB_GIUFUNSEL, 0x0);
 	// ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff);  /* NEC recommanded value */
 
-	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+#ifdef CONFIG_PC_KEYB
+	printk("kdb_ops is std\n");
+	kbd_ops = &std_kbd_ops;
+#endif
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+
+		/* enable IDE controller on Ali chip (south bridge) */
+		u8			temp8;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		struct pci_dev		dev_m5229;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		/* Setup M1535 registers */
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+
+		/* setup IDE controller
+		 * enable IDE controller (bit 6 - 1)
+		 * IDE IDSEL to be addr:A15 (bit 4:5 - 11)
+		 * disable IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
+		 * enable IDE ATA Primary Bus Signal Pad Control (bit 2 - 1)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x58, 0x74);
+
+		/*
+		 * positive decode (bit6 -0)
+		 * enable IDE controler interrupt (bit 4 -1)
+		 * setup SIRQ to point to IRQ 14 (bit 3:0 - 1101)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x44, 0x1d);
+
+		/* Setup M5229 registers */
+		dev_m5229.bus = &bus;
+		dev_m5229.sysdata = NULL;
+		dev_m5229.devfn = 4*8;  	// slot 4 (AD15): M5229 IDE
+
+		/*
+		 * enable IDE in the M5229 config register 0x50 (bit 0 - 1)
+		 * M5229 IDSEL is addr:15; see above setting
+		 */
+		pci_read_config_byte(&dev_m5229, 0x50, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x50, temp8 | 0x1);
+
+		/*
+		 * enable bus master (bit 2)  and IO decoding  (bit 0)
+		 */
+		pci_read_config_byte(&dev_m5229, 0x04, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x04, temp8 | 0x5);
+
+		/*
+		 * enable native, copied from arch/ppc/k2boot/head.S
+		 * TODO - need volatile, need to be portable
+		 */
+		pci_write_config_byte(&dev_m5229, 0x09, 0xef);
+
+		/* Set Primary Channel Command Block Timing */
+		pci_write_config_byte(&dev_m5229, 0x59, 0x31);
+
+		/*
+		 * Enable primary channel 40-pin cable
+		 * M5229 register 0x4a (bit 0)
+		 */
+		pci_read_config_byte(&dev_m5229, 0x4a, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x4a, temp8 | 0x1);
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
 		printk("lcd44780: initializing\n");
 		lcd44780_init();
-		lcd44780_puts("Linux/MIPS rolls");
+		lcd44780_puts("MontaVista Linux");
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/Makefile linux-2.4.20/arch/mips/dec/Makefile
--- linux-2.4.19/arch/mips/dec/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/Makefile	2002-10-04 00:41:15.000000000 +0000
@@ -14,9 +14,10 @@
 
 export-objs := setup.o wbflush.o
 obj-y	 := int-handler.o ioasic-irq.o kn02-irq.o reset.o rtc-dec.o setup.o \
-	time.o wbflush.o
+	time.o
 
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
+obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
 
 int-handler.o:	int-handler.S
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/int-handler.S linux-2.4.20/arch/mips/dec/int-handler.S
--- linux-2.4.19/arch/mips/dec/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/int-handler.S	2002-10-04 00:41:11.000000000 +0000
@@ -240,7 +240,7 @@
 		srl	t0,IO_INR_DMA
 		li	t1,IO_IRQ_DMA>>IO_INR_DMA # mask
 		li	t2,8			# nr of bits / 2
-		
+
 		/*
 		 * Find irq with highest priority.
 		 * Highest irq number takes precedence.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/ioasic-irq.c linux-2.4.20/arch/mips/dec/ioasic-irq.c
--- linux-2.4.19/arch/mips/dec/ioasic-irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/ioasic-irq.c	2002-10-04 00:41:14.000000000 +0000
@@ -84,6 +84,7 @@
 	spin_lock(&ioasic_lock);
 	mask_ioasic_irq(irq);
 	spin_unlock(&ioasic_lock);
+	fast_iob();
 }
 
 static inline void end_ioasic_irq(unsigned int irq)
@@ -119,6 +120,7 @@
 static inline void end_ioasic_dma_irq(unsigned int irq)
 {
 	clear_ioasic_irq(irq);
+	fast_iob();
 	end_ioasic_irq(irq);
 }
 
@@ -142,6 +144,7 @@
 
 	/* Mask interrupts. */
 	ioasic_write(SIMR, 0);
+	fast_iob();
 
 	for (i = base; i < base + IO_INR_DMA; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/irq.c linux-2.4.20/arch/mips/dec/irq.c
--- linux-2.4.19/arch/mips/dec/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,307 +0,0 @@
-/*
- * Code to handle DECstation IRQs plus some generic interrupt stuff.
- *
- * Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-#include <asm/dec/interrupts.h>
-
-extern void dec_init_kn01(void);
-extern void dec_init_kn230(void);
-extern void dec_init_kn02(void);
-extern void dec_init_kn02ba(void);
-extern void dec_init_kn02ca(void);
-extern void dec_init_kn03(void);
-
-extern asmlinkage void decstation_handle_int(void);
-
-atomic_t irq_err_count;
-
-static inline void mask_irq(unsigned int irq_nr)
-{
-	unsigned int dummy;
-
-	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
-		*imr &= ~dec_interrupt[irq_nr].iemask;
-		dummy = *imr;
-		dummy = *imr;
-	} else			/* This is a cpu interrupt        */
-		change_cp0_status(ST0_IM,
-				  read_32bit_cp0_register(CP0_STATUS) &
-				  ~dec_interrupt[irq_nr].cpu_mask);
-}
-
-static inline void unmask_irq(unsigned int irq_nr)
-{
-	unsigned int dummy;
-
-	if (dec_interrupt[irq_nr].iemask) {	/* This is an ASIC interrupt    */
-		*imr |= dec_interrupt[irq_nr].iemask;
-		dummy = *imr;
-		dummy = *imr;
-	}
-	change_cp0_status(ST0_IM,
-			  read_32bit_cp0_register(CP0_STATUS) |
-			  dec_interrupt[irq_nr].cpu_mask);
-}
-
-void disable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mask_irq(irq_nr);
-	restore_flags(flags);
-}
-
-void enable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	unmask_irq(irq_nr);
-	restore_flags(flags);
-}
-
-/*
- * Pointers to the low-level handlers: first the general ones, then the
- * fast ones, then the bad ones.
- */
-extern void interrupt(void);
-
-static struct irqaction *irq_action[32] = {
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-int get_irq_list(char *buf)
-{
-	int i, len = 0;
-	struct irqaction *action;
-
-	for (i = 0; i < 32; i++) {
-		action = irq_action[i];
-		if (!action)
-			continue;
-		len += sprintf(buf + len, "%2d: %8d %c %s",
-			       i, kstat.irqs[0][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;
-}
-
-/*
- * do_IRQ handles IRQ's that have been installed without the
- * SA_INTERRUPT flag: it uses the full signal-handling return
- * and runs with other interrupts enabled. All relatively slow
- * IRQ's should use this format: notably the keyboard/timer
- * routines.
- */
-asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
-{
-	struct irqaction *action;
-	int do_random, cpu;
-
-	cpu = smp_processor_id();
-	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
-
-	mask_irq(irq);
-	action = *(irq + irq_action);
-	if (action) {
-		if (!(action->flags & SA_INTERRUPT))
-			__sti();
-		action = *(irq + irq_action);
-		do_random = 0;
-		do {
-			do_random |= action->flags;
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-		} while (action);
-		if (do_random & SA_SAMPLE_RANDOM)
-			add_interrupt_randomness(irq);
-		__cli();
-		unmask_irq(irq);
-	}
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
-}
-
-/*
- * Idea is to put all interrupts
- * in a single table and differenciate them just by number.
- */
-int setup_dec_irq(int irq, struct irqaction *new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-	unsigned long flags;
-
-	p = irq_action + irq;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ))
-			return -EBUSY;
-
-		/* Can't share interrupts unless both are same type */
-		if ((old->flags ^ new->flags) & SA_INTERRUPT)
-			return -EBUSY;
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-	if (new->flags & SA_SAMPLE_RANDOM)
-		rand_initialize_irq(irq);
-
-	save_and_cli(flags);
-	*p = new;
-
-	if (!shared) {
-		unmask_irq(irq);
-	}
-	restore_flags(flags);
-	return 0;
-}
-
-int request_irq(unsigned int irq,
-		void (*handler) (int, void *, struct pt_regs *),
-		unsigned long irqflags, const char *devname, void *dev_id)
-{
-	int retval;
-	struct irqaction *action;
-
-	if (irq >= 32)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	action =
-	    (struct irqaction *) kmalloc(sizeof(struct irqaction),
-					 GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	retval = setup_dec_irq(irq, action);
-
-	if (retval)
-		kfree(action);
-	return retval;
-}
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action, **p;
-	unsigned long flags;
-
-	if (irq > 39) {
-		printk("Trying to free IRQ%d\n", irq);
-		return;
-	}
-	for (p = irq + irq_action; (action = *p) != NULL;
-	     p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		save_and_cli(flags);
-		*p = action->next;
-		if (!irq[irq_action])
-			mask_irq(irq);
-		restore_flags(flags);
-		kfree(action);
-		return;
-	}
-	printk("Trying to free free IRQ%d\n", irq);
-}
-
-unsigned long probe_irq_on(void)
-{
-	/* TODO */
-	return 0;
-}
-
-int probe_irq_off(unsigned long irqs)
-{
-	/* TODO */
-	return 0;
-}
-
-void init_irq_proc(void)
-{
-	/* Nothing, for now.  */
-}
-
-void __init init_IRQ(void)
-{
-	switch (mips_machtype) {
-	case MACH_DS23100:
-		dec_init_kn01();
-		break;
-	case MACH_DS5100:	/*  DS5100 MIPSMATE */
-		dec_init_kn230();
-		break;
-	case MACH_DS5000_200:	/* DS5000 3max */
-		dec_init_kn02();
-		break;
-	case MACH_DS5000_1XX:	/* DS5000/100 3min */
-		dec_init_kn02ba();
-		break;
-	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-		dec_init_kn03();
-		break;
-	case MACH_DS5000_XX:	/* Personal DS5000/2x */
-		dec_init_kn02ca();
-		break;
-	case MACH_DS5800:	/* DS5800 Isis */
-		panic("Don't know how to set this up!");
-		break;
-	case MACH_DS5400:	/* DS5400 MIPSfair */
-		panic("Don't know how to set this up!");
-		break;
-	case MACH_DS5500:	/* DS5500 MIPSfair-2 */
-		panic("Don't know how to set this up!");
-		break;
-	}
-	set_except_vector(0, decstation_handle_int);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/kn02-irq.c linux-2.4.20/arch/mips/dec/kn02-irq.c
--- linux-2.4.19/arch/mips/dec/kn02-irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/kn02-irq.c	2002-10-04 00:41:11.000000000 +0000
@@ -83,6 +83,7 @@
 	spin_lock(&kn02_lock);
 	mask_kn02_irq(irq);
 	spin_unlock(&kn02_lock);
+	iob();
 }
 
 static void end_kn02_irq(unsigned int irq)
@@ -113,6 +114,7 @@
 	/* Mask interrupts and preset write-only bits. */
 	cached_kn02_csr = (*csr & ~0xff0000) | 0xff;
 	*csr = cached_kn02_csr;
+	iob();
 
 	for (i = base; i < base + KN02_IRQ_LINES; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/prom/identify.c linux-2.4.20/arch/mips/dec/prom/identify.c
--- linux-2.4.19/arch/mips/dec/prom/identify.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/prom/identify.c	2002-10-04 00:41:16.000000000 +0000
@@ -21,7 +21,7 @@
 
 extern unsigned long mips_machtype;
 const char *get_system_type(void)
-{ 
+{
 	static char system[32];
 	int called = 0;
 	const char *dec_system_strings[] = { "unknown", "DECstation 2100/3100",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/prom/init.c linux-2.4.20/arch/mips/dec/prom/init.c
--- linux-2.4.19/arch/mips/dec/prom/init.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/prom/init.c	2002-10-04 00:41:21.000000000 +0000
@@ -77,7 +77,7 @@
 		pmax_read = (int (*)(int, void *, int)) PMAX_PROM_READ;
 		pmax_close = (int (*)(int)) PMAX_PROM_CLOSE;
 	}
-} 
+}
 
 int __init prom_init(int argc, char **argv,
 	       unsigned long magic, int *prom_vec)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/prom/prom.h linux-2.4.20/arch/mips/dec/prom/prom.h
--- linux-2.4.19/arch/mips/dec/prom/prom.h	1999-06-26 00:40:12.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/prom/prom.h	2002-10-04 00:41:13.000000000 +0000
@@ -1,11 +1,11 @@
-/*  
+/*
  * Miscellaneous definitions used to call the routines contained in the boot
  * PROMs on various models of DECSTATION's.
  * the rights to redistribute these changes.
  */
 
-#ifndef __ASM_DEC_PROM_H 
-#define __ASM_DEC_PROM_H 
+#ifndef __ASM_DEC_PROM_H
+#define __ASM_DEC_PROM_H
 
 /*
  * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.  Many of
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/promcon.c linux-2.4.20/arch/mips/dec/promcon.c
--- linux-2.4.19/arch/mips/dec/promcon.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/promcon.c	2002-10-04 00:41:21.000000000 +0000
@@ -2,7 +2,7 @@
  * Wrap-around code for a console using the
  * DECstation PROM io-routines.
  *
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
  */
 
 #include <linux/tty.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/rtc-dec.c linux-2.4.20/arch/mips/dec/rtc-dec.c
--- linux-2.4.19/arch/mips/dec/rtc-dec.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/rtc-dec.c	2002-10-04 00:41:15.000000000 +0000
@@ -3,33 +3,35 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * RTC routines for DECstation style attached Dallas chip.
+ * RTC routines for DECstation style attached Dallas DS1287 chip.
  *
  * Copyright (C) 1998, 2001 by Ralf Baechle
  * Copyright (C) 1998 by Harald Koerfgen
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
+
 #include <linux/mc146818rtc.h>
+#include <linux/types.h>
 
-extern char *dec_rtc_base;
+volatile u8 *dec_rtc_base;
 
 static unsigned char dec_rtc_read_data(unsigned long addr)
 {
-    return (dec_rtc_base[addr * 4]);
+	return dec_rtc_base[addr * 4];
 }
 
 static void dec_rtc_write_data(unsigned char data, unsigned long addr)
 {
-    dec_rtc_base[addr * 4] = data;
+	dec_rtc_base[addr * 4] = data;
 }
 
 static int dec_rtc_bcd_mode(void)
 {
-    return 0;
+	return 0;
 }
 
-struct rtc_ops dec_rtc_ops =
-{
-    &dec_rtc_read_data,
-    &dec_rtc_write_data,
-    &dec_rtc_bcd_mode
+struct rtc_ops dec_rtc_ops = {
+	&dec_rtc_read_data,
+	&dec_rtc_write_data,
+	&dec_rtc_bcd_mode
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/setup.c linux-2.4.20/arch/mips/dec/setup.c
--- linux-2.4.19/arch/mips/dec/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/setup.c	2002-10-04 00:41:16.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/traps.h>
+#include <asm/wbflush.h>
 
 #include <asm/dec/interrupts.h>
 #include <asm/dec/kn01.h>
@@ -45,10 +46,8 @@
 
 extern asmlinkage void decstation_handle_int(void);
 
-
-char *dec_rtc_base = (void *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */
-
 volatile u32 *ioasic_base;
+unsigned long dec_kn_slot_size;
 
 /*
  * IRQ routing and priority tables.  Priorites are set as follows:
@@ -71,7 +70,7 @@
  *
  * * -- shared with SCSI
  */
- 
+
 int dec_interrupt[DEC_NR_INTS] = {
 	[0 ... DEC_NR_INTS - 1] = -1
 };
@@ -89,10 +88,6 @@
 static struct irqaction haltirq = {dec_intr_halt, 0, 0, "halt", NULL, NULL};
 
 
-extern void wbflush_setup(void);
-
-extern struct rtc_ops dec_rtc_ops;
-
 void (*board_time_init) (struct irqaction * irq);
 
 
@@ -208,7 +203,8 @@
 void __init dec_init_kn01(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN01_RTC_BASE;
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn01_interrupt,
@@ -286,7 +282,8 @@
 void __init dec_init_kn230(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN01_RTC_BASE;
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn230_interrupt,
@@ -379,7 +376,8 @@
 void __init dec_init_kn02(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN02_RTC_BASE;
+	dec_rtc_base = (void *)KN02_RTC_BASE;
+	dec_kn_slot_size = KN02_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02_interrupt,
@@ -426,7 +424,7 @@
 	[DEC_IRQ_TC2]		= DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2),
 	[DEC_IRQ_TIMER]		= -1,
 	[DEC_IRQ_VIDEO]		= -1,
-	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_LANCE_MERR),
+	[DEC_IRQ_ASC_MERR]	= IO_IRQ_NR(IO_INR_ASC_MERR),
 	[DEC_IRQ_ASC_ERR]	= IO_IRQ_NR(IO_INR_ASC_ERR),
 	[DEC_IRQ_ASC_DMA]	= IO_IRQ_NR(IO_INR_ASC_DMA),
 	[DEC_IRQ_FLOPPY_ERR]	= -1,
@@ -483,8 +481,9 @@
 void __init dec_init_kn02ba(void)
 {
 	/* Setup some memory addresses. */
-	ioasic_base = (void *) KN02BA_IOASIC_BASE;
-	dec_rtc_base = (char *) KN02BA_RTC_BASE;
+	ioasic_base = (void *)KN02BA_IOASIC_BASE;
+	dec_rtc_base = (void *)KN02BA_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02ba_interrupt,
@@ -584,8 +583,9 @@
 void __init dec_init_kn02ca(void)
 {
 	/* Setup some memory addresses. */
-	ioasic_base = (void *) KN02CA_IOASIC_BASE;
-	dec_rtc_base = (char *) KN02CA_RTC_BASE;
+	ioasic_base = (void *)KN02CA_IOASIC_BASE;
+	dec_rtc_base = (void *)KN02CA_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02ca_interrupt,
@@ -659,9 +659,9 @@
 		{ i: DEC_CPU_IRQ_NR(KN03_CPU_INR_MEMORY) } },
 	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) },
 		{ i: DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } },
-	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) }, 
+	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) },
 		{ p: kn03_io_int } },
-	{ { i: DEC_CPU_IRQ_ALL }, 
+	{ { i: DEC_CPU_IRQ_ALL },
 		{ p: cpu_all_int } },
 };
 
@@ -689,12 +689,13 @@
 void __init dec_init_kn03(void)
 {
 	/* Setup some memory addresses.  */
-	ioasic_base = (void *) KN03_IOASIC_BASE;
-	dec_rtc_base = (char *) KN03_RTC_BASE;
+	ioasic_base = (void *)KN03_IOASIC_BASE;
+	dec_rtc_base = (void *)KN03_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn03_interrupt,
-		sizeof(kn03_interrupt));	
+		sizeof(kn03_interrupt));
 
 	/* CPU IRQ priorities. */
 	memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl,
@@ -760,4 +761,7 @@
 		setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
 }
 
+EXPORT_SYMBOL(ioasic_base);
+EXPORT_SYMBOL(dec_rtc_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
 EXPORT_SYMBOL(dec_interrupt);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/time.c linux-2.4.20/arch/mips/dec/time.c
--- linux-2.4.19/arch/mips/dec/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/time.c	2002-10-04 00:41:14.000000000 +0000
@@ -110,7 +110,7 @@
 		: "r" (count), "r" (quotient));
 
 	/*
-	 * Due to possible jiffies inconsistencies, we need to check 
+	 * Due to possible jiffies inconsistencies, we need to check
 	 * the result so that we'll get a timer that is monotonic.
 	 */
 	if (res >= USECS_PER_JIFFY)
@@ -160,9 +160,9 @@
 	return res;
 }
 
-/* This function must be called with interrupts disabled 
+/* 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
@@ -176,7 +176,7 @@
  * 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 
+ * 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
@@ -187,7 +187,7 @@
  * 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!
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/wbflush.c linux-2.4.20/arch/mips/dec/wbflush.c
--- linux-2.4.19/arch/mips/dec/wbflush.c	2001-10-05 19:06:51.000000000 +0000
+++ linux-2.4.20/arch/mips/dec/wbflush.c	2002-10-04 00:41:29.000000000 +0000
@@ -11,15 +11,18 @@
  * for more details.
  *
  * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
  */
 
-#include <asm/bootinfo.h>
 #include <linux/init.h>
 
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+
 static void wbflush_kn01(void);
 static void wbflush_kn210(void);
-static void wbflush_kn02ba(void);
-static void wbflush_kn03(void);
+static void wbflush_mips(void);
 
 void (*__wbflush) (void);
 
@@ -27,28 +30,23 @@
 {
 	switch (mips_machtype) {
 	case MACH_DS23100:
-	    __wbflush = wbflush_kn01;
-	    break;
-	case MACH_DS5100:	/*  DS5100 MIPSMATE */
-	    __wbflush = wbflush_kn210;
-	    break;
 	case MACH_DS5000_200:	/* DS5000 3max */
-	    __wbflush = wbflush_kn01;
-	    break;
+		__wbflush = wbflush_kn01;
+		break;
+	case MACH_DS5100:	/* DS5100 MIPSMATE */
+		__wbflush = wbflush_kn210;
+		break;
 	case MACH_DS5000_1XX:	/* DS5000/100 3min */
-	    __wbflush = wbflush_kn02ba;
-	    break;
-	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-	    __wbflush = wbflush_kn03;
-	    break;
 	case MACH_DS5000_XX:	/* Personal DS5000/2x */
-	    __wbflush = wbflush_kn02ba;
-	    break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	default:
+		__wbflush = wbflush_mips;
+		break;
 	}
 }
 
 /*
- * For the DS3100 and DS5000/200 the writeback buffer functions
+ * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions
  * as part of Coprocessor 0.
  */
 static void wbflush_kn01(void)
@@ -78,29 +76,16 @@
 	"mtc0\t$2,$12\n\t"
 	"nop\n\t"
 	".set\tpop"
-  : : :"$2", "$3");
-}
-
-/*
- * Looks like some magic with the System Interrupt Mask Register
- * in the famous IOASIC for kmins and maxines.
- */
-static void wbflush_kn02ba(void)
-{
-    asm(".set\tpush\n\t"
-	".set\tnoreorder\n\t"
-	"lui\t$2,0xbc04\n\t"
-	"lw\t$3,0x120($2)\n\t"
-	"lw\t$3,0x120($2)\n\t"
-	".set\tpop"
-  : : :"$2", "$3");
+	: : : "$2", "$3");
 }
 
 /*
- * The DS500/2x0 doesnt need to write back the WB.
+ * I/O ASIC systems use a standard writeback buffer that gets flushed
+ * upon an uncached read.
  */
-static void wbflush_kn03(void)
+static void wbflush_mips(void)
 {
+	__fast_iob();
 }
 
 #include <linux/module.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig linux-2.4.20/arch/mips/defconfig
--- linux-2.4.19/arch/mips/defconfig	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig	2002-10-04 00:41:11.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,53 +36,68 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 CONFIG_SGI_IP22=y
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_MEMORY=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
 CONFIG_IRQ_CPU=y
-CONFIG_PC_KEYB=y
-CONFIG_SGI=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SGI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -88,7 +105,8 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
-# CONFIG_ARC_CONSOLE is not set
+CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -106,6 +124,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -219,6 +240,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -321,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -367,6 +396,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -419,7 +457,6 @@
 # CONFIG_EUROTECH_WDT is not set
 # CONFIG_IB700_WDT is not set
 # CONFIG_WAFER_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_I810_TCO is not set
 # CONFIG_MIXCOMWD is not set
 # CONFIG_60XX_WDT is not set
@@ -430,6 +467,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -444,11 +482,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -468,6 +501,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -485,6 +520,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -515,6 +553,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -528,7 +567,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -548,10 +586,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -586,18 +630,15 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-atlas linux-2.4.20/arch/mips/defconfig-atlas
--- linux-2.4.19/arch/mips/defconfig-atlas	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-atlas	2002-10-04 00:41:15.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,20 +34,28 @@
 CONFIG_MIPS_ATLAS=y
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BOOT_ELF32=y
+CONFIG_L1_CACHE_SHIFT=5
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
@@ -56,32 +66,36 @@
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
-CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_LLDSCD is not set
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_BINFMT_IRIX=y
+# CONFIG_BINFMT_IRIX is not set
 # CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
@@ -95,11 +109,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -130,11 +146,12 @@
 # CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -151,13 +168,14 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
@@ -165,6 +183,7 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
@@ -273,8 +292,14 @@
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_NCR53C8XX=y
 # CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -330,7 +355,38 @@
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+CONFIG_LAN_SAA9730=y
 # CONFIG_NET_POCKET is not set
 
 #
@@ -338,6 +394,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -384,6 +441,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -424,7 +490,7 @@
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -437,15 +503,10 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
@@ -454,6 +515,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -462,7 +525,7 @@
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
-CONFIG_EFS_FS=y
+# CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
@@ -471,6 +534,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -497,12 +563,14 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -514,17 +582,35 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
 CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -540,15 +626,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -557,3 +634,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-capcella linux-2.4.20/arch/mips/defconfig-capcella
--- linux-2.4.19/arch/mips/defconfig-capcella	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-capcella	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,645 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+CONFIG_ZAO_CAPCELLA=y
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CPU_VR41XX=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_TIME_C=y
+CONFIG_VR41XX_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_ISA is not set
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_DUMMY_KEYB=y
+# CONFIG_SCSI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INDYDOG is not set
+# CONFIG_AMD7XX_TCO is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-cobalt linux-2.4.20/arch/mips/defconfig-cobalt
--- linux-2.4.19/arch/mips/defconfig-cobalt	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-cobalt	2002-10-04 00:41:22.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,21 +34,28 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_COBALT_LCD=y
+CONFIG_I8259=y
 CONFIG_PCI=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
@@ -56,25 +65,28 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -97,6 +109,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -131,6 +145,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -271,6 +286,8 @@
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_PIIX_TUNING is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
@@ -341,13 +358,13 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
-# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -359,11 +376,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -375,6 +393,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -421,6 +440,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -474,11 +502,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -491,6 +514,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -508,6 +533,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -538,6 +566,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -551,7 +580,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -571,10 +599,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -590,15 +624,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -607,3 +632,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-ddb5476 linux-2.4.20/arch/mips/defconfig-ddb5476
--- linux-2.4.19/arch/mips/defconfig-ddb5476	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-ddb5476	2002-10-04 00:41:17.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -10,39 +11,49 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
 # CONFIG_MIPS_EV64120 is not set
 # CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
-# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
 CONFIG_DDB5476=y
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1500 is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_HP_LASERJET is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_ISA=y
 CONFIG_PCI=y
 CONFIG_PC_KEYB=y
@@ -54,59 +65,57 @@
 CONFIG_PCI_AUTO=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_EISA=y
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 CONFIG_CPU_R5432=y
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+CONFIG_EISA=y
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -119,6 +128,12 @@
 # CONFIG_PARPORT is not set
 
 #
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -126,11 +141,14 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -175,6 +193,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -192,6 +215,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -215,6 +243,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -229,6 +258,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -240,12 +270,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_IDEDMA_PCI is not set
-# CONFIG_BLK_DEV_ADMA is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_ADMA is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
@@ -253,11 +286,14 @@
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_PIIX_TUNING is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
@@ -330,13 +366,13 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
-# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -348,11 +384,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -364,11 +401,13 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -414,6 +453,15 @@
 # CONFIG_CD_NO_IDESCSI is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -438,6 +486,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -457,7 +506,6 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -472,11 +520,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -489,6 +532,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -502,10 +547,13 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -536,6 +584,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -549,7 +598,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -560,6 +608,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -573,15 +626,18 @@
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_MATROX is not set
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
 CONFIG_FB_3DFX=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -603,116 +659,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-
-#
-#   SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
+# Bluetooth support
 #
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-#   Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
@@ -723,3 +672,9 @@
 CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-ddb5477 linux-2.4.20/arch/mips/defconfig-ddb5477
--- linux-2.4.19/arch/mips/defconfig-ddb5477	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-ddb5477	2002-10-04 00:41:14.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -10,39 +11,50 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
 # Machine selection
 #
 # CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_DECSTATION is not set
-# CONFIG_DDB5074 is not set
 # CONFIG_MIPS_EV64120 is not set
 # CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_NINO is not set
-# CONFIG_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 CONFIG_DDB5477=y
+CONFIG_DDB5477_BUS_FREQUENCY=0
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1500 is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_HP_LASERJET is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
 CONFIG_PCI=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NEW_IRQ=y
@@ -51,54 +63,59 @@
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+CONFIG_I8259=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 CONFIG_CPU_R5432=y
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_KCORE_ELF=y
-CONFIG_ELF_KERNEL=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -111,6 +128,12 @@
 # CONFIG_PARPORT is not set
 
 #
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -118,11 +141,14 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -167,6 +193,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -184,6 +215,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -243,18 +279,18 @@
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
-# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -266,11 +302,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -282,11 +319,13 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -327,9 +366,13 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
+# Input core support
 #
-# CONFIG_CD_NO_IDESCSI is not set
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Character devices
@@ -371,7 +414,6 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -386,11 +428,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -403,6 +440,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -416,10 +455,13 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -450,6 +492,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -463,7 +506,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -474,9 +516,15 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -488,10 +536,10 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_HAL2 is not set
 CONFIG_SOUND_VRC5477=y
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
@@ -507,116 +555,9 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-
-#
-#   SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-#   Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
+# Bluetooth support
 #
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-#   Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
@@ -627,3 +568,9 @@
 CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-decstation linux-2.4.20/arch/mips/defconfig-decstation
--- linux-2.4.19/arch/mips/defconfig-decstation	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-decstation	2002-10-04 00:41:20.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,17 +36,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -56,25 +64,27 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 CONFIG_CPU_R3000=y
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
 CONFIG_CPU_HAS_WB=y
+# CONFIG_CPU_HAS_SYNC is not set
 
 #
 # General setup
@@ -97,6 +107,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -131,6 +143,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -209,6 +222,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -310,6 +330,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -356,6 +377,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -409,11 +439,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # DECStation Character devices
 #
 CONFIG_SERIAL=y
@@ -435,6 +460,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -452,6 +479,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -482,6 +512,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 # CONFIG_SUNRPC is not set
 # CONFIG_LOCKD is not set
 # CONFIG_SMB_FS is not set
@@ -495,7 +526,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -515,10 +545,16 @@
 # CONFIG_SGI_PARTITION is not set
 CONFIG_ULTRIX_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -534,15 +570,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -551,3 +578,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-eagle linux-2.4.20/arch/mips/defconfig-eagle
--- linux-2.4.19/arch/mips/defconfig-eagle	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-eagle	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,677 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+CONFIG_NEC_EAGLE=y
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CPU_VR41XX=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_TIME_C=y
+CONFIG_VR41XX_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_ISA is not set
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_DUMMY_KEYB=y
+# CONFIG_SCSI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=1c000000
+CONFIG_MTD_PHYSMAP_LEN=2000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MS02NV is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INDYDOG is not set
+# CONFIG_AMD7XX_TCO is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_PROC_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-ev64120 linux-2.4.20/arch/mips/defconfig-ev64120
--- linux-2.4.19/arch/mips/defconfig-ev64120	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-ev64120	2002-10-04 00:41:12.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -38,17 +40,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -62,26 +70,29 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -106,6 +117,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +153,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -274,11 +288,11 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
-# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -290,11 +304,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -306,6 +321,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -359,6 +375,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -412,11 +437,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -429,6 +449,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -446,6 +468,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -476,6 +501,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -489,7 +515,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -500,6 +525,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -515,15 +545,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -532,3 +553,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-ev96100 linux-2.4.20/arch/mips/defconfig-ev96100
--- linux-2.4.19/arch/mips/defconfig-ev96100	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-ev96100	2002-10-04 00:41:14.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,17 +36,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -60,27 +68,29 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-CONFIG_CPU_RM7000=y
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -105,6 +115,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -139,6 +151,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -274,13 +287,13 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
-# CONFIG_TC35815 is not set
 # CONFIG_TULIP_MWI is not set
 # CONFIG_TULIP_MMIO is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -292,11 +305,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -308,6 +322,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -354,6 +369,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -407,11 +431,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -424,6 +443,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -441,6 +462,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -471,6 +495,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -484,7 +509,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -495,6 +519,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -510,15 +539,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -527,3 +547,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-ip22 linux-2.4.20/arch/mips/defconfig-ip22
--- linux-2.4.19/arch/mips/defconfig-ip22	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-ip22	2002-10-04 00:41:30.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,53 +36,68 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 CONFIG_SGI_IP22=y
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_MEMORY=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
 CONFIG_IRQ_CPU=y
-CONFIG_PC_KEYB=y
-CONFIG_SGI=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SGI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -88,7 +105,8 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
-# CONFIG_ARC_CONSOLE is not set
+CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -106,6 +124,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -219,6 +240,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -321,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -367,6 +396,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -419,7 +457,6 @@
 # CONFIG_EUROTECH_WDT is not set
 # CONFIG_IB700_WDT is not set
 # CONFIG_WAFER_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_I810_TCO is not set
 # CONFIG_MIXCOMWD is not set
 # CONFIG_60XX_WDT is not set
@@ -430,6 +467,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -444,11 +482,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -468,6 +501,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -485,6 +520,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -515,6 +553,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -528,7 +567,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -548,10 +586,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -586,18 +630,15 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-malta linux-2.4.20/arch/mips/defconfig-malta
--- linux-2.4.19/arch/mips/defconfig-malta	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-malta	2002-10-04 00:41:14.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,48 +34,57 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 CONFIG_MIPS_MALTA=y
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_I8259=y
-CONFIG_PCI=y
+CONFIG_BOOT_ELF32=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_I8259=y
+CONFIG_L1_CACHE_SHIFT=5
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_PC_KEYB=y
+CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -81,6 +92,7 @@
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -98,11 +110,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -138,6 +152,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -339,11 +354,11 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
-# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -355,11 +370,12 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -371,6 +387,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -417,6 +434,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -470,11 +496,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -487,6 +508,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -504,6 +527,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -534,6 +560,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -547,7 +574,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -558,6 +584,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -573,15 +604,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -590,3 +612,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-pb1000 linux-2.4.20/arch/mips/defconfig-pb1000
--- linux-2.4.19/arch/mips/defconfig-pb1000	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-pb1000	2002-10-04 00:41:15.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -22,6 +23,7 @@
 # CONFIG_ACER_PICA_61 is not set
 CONFIG_MIPS_PB1000=y
 CONFIG_PCI_AUTO=y
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -35,17 +37,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -55,33 +63,36 @@
 CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
-MAX_HWIFS=1
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_AU1000_USB_DEVICE=y
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_64BIT_PHYS_ADDR=y
 CONFIG_CPU_ADVANCED=y
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -105,6 +116,7 @@
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1000=m
+CONFIG_PCMCIA_PB1X00=y
 
 #
 # PCI Hotplug Support
@@ -120,6 +132,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -163,6 +177,7 @@
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PB1000=y
 # CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
 # CONFIG_MTD_PCI is not set
@@ -211,10 +226,11 @@
 # CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -396,6 +412,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -429,7 +446,18 @@
 #
 # PCMCIA network device support
 #
-# CONFIG_NET_PCMCIA is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
 
 #
 # Amateur Radio support
@@ -439,7 +467,49 @@
 #
 # IrDA (infrared) support
 #
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+CONFIG_AU1000_FIR=m
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
 
 #
 # ISDN subsystem
@@ -447,9 +517,19 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 CONFIG_SERIAL_NONSTANDARD=y
@@ -463,6 +543,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -473,6 +554,8 @@
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
 CONFIG_AU1000_UART=y
 CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -523,15 +606,11 @@
 # PCMCIA character devices
 #
 # CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
 CONFIG_AU1000_GPIO=y
 # CONFIG_TS_AU1000_ADS7846 is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -544,6 +623,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -562,6 +643,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -592,6 +676,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -605,7 +690,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -616,9 +700,67 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_E1356=y
+CONFIG_PB1000_CRT=y
+# CONFIG_PB1000_NTSC is not set
+# CONFIG_PB1000_TFT is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
 # Sound
 #
 CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -630,6 +772,7 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
@@ -653,15 +796,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -670,3 +804,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-pb1100 linux-2.4.20/arch/mips/defconfig-pb1100
--- linux-2.4.19/arch/mips/defconfig-pb1100	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-pb1100	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,874 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+CONFIG_MIPS_PB1100=y
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_MIPS_AU1000=y
+CONFIG_NEW_IRQ=y
+CONFIG_PCI=y
+# CONFIG_PCI_AUTO is not set
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_AU1000_USB_DEVICE=y
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+# CONFIG_TCIC is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+CONFIG_PCMCIA_AU1000=m
+CONFIG_PCMCIA_PB1X00=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MS02NV is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_AU1000_ENET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+CONFIG_AU1000_FIR=y
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+CONFIG_AU1000_UART=y
+CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_AU1000_GPIO is not set
+# CONFIG_TS_AU1000_ADS7846 is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=m
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_AU1100 is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+CONFIG_SOUND_AU1000=y
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-pb1500 linux-2.4.20/arch/mips/defconfig-pb1500
--- linux-2.4.19/arch/mips/defconfig-pb1500	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-pb1500	2002-10-04 00:41:15.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 CONFIG_MIPS_PB1500=y
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,46 +36,54 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_MIPS_AU1000=y
 CONFIG_NEW_IRQ=y
 CONFIG_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
+CONFIG_AU1000_USB_DEVICE=y
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -81,6 +91,7 @@
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -119,6 +130,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -162,6 +175,7 @@
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_PB1000 is not set
 CONFIG_MTD_PB1500=y
+# CONFIG_MTD_PB1100 is not set
 CONFIG_MTD_PB1500_BOOT=y
 # CONFIG_MTD_PB1500_USER is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
@@ -216,6 +230,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -371,6 +386,8 @@
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_PIIX_TUNING is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
@@ -442,11 +459,11 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
-# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -458,11 +475,12 @@
 CONFIG_8139TOO_PIO=y
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_8139_OLD_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -474,6 +492,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -543,6 +562,17 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -560,6 +590,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -570,6 +601,8 @@
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
 CONFIG_AU1000_UART=y
 CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -642,15 +675,11 @@
 # PCMCIA character devices
 #
 # CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
 # CONFIG_AU1000_GPIO is not set
 # CONFIG_TS_AU1000_ADS7846 is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -663,6 +692,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -683,6 +714,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -713,6 +747,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
@@ -727,7 +762,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=m
 
 #
 # Partition Types
@@ -780,6 +814,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -804,6 +843,7 @@
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_FBCON_ADVANCED=y
 # CONFIG_FBCON_MFB is not set
@@ -831,6 +871,7 @@
 # Sound
 #
 CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -842,6 +883,7 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
@@ -881,6 +923,7 @@
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
 
 #
 #   SCSI support is needed for USB Storage
@@ -893,6 +936,7 @@
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_HP8200e is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
@@ -903,6 +947,7 @@
 CONFIG_USB_HID=y
 # CONFIG_USB_HIDINPUT is not set
 # CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
 
 #
@@ -941,39 +986,15 @@
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
 
 #
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
 # CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
 
 #
 # Bluetooth support
@@ -981,17 +1002,6 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=y
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
@@ -1000,3 +1010,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-sb1250-swarm linux-2.4.20/arch/mips/defconfig-sb1250-swarm
--- linux-2.4.19/arch/mips/defconfig-sb1250-swarm	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-sb1250-swarm	2002-10-04 00:41:30.000000000 +0000
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,26 +36,32 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
 CONFIG_SIBYTE_SB1250=y
-# CONFIG_PCI is not set
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_BCM1250_TBPROF is not set
-# CONFIG_REMOTE_DEBUG is not set
-CONFIG_SIBYTE_SWARM=y
-# CONFIG_SIMULATION is not set
-# CONFIG_L3DEMO is not set
-CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS=16
 CONFIG_SMP=y
+# CONFIG_PCI is not set
+CONFIG_SIBYTE_SWARM=y
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -61,35 +69,43 @@
 CONFIG_NEW_TIME_C=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_SB1=y
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_SB1_PASS_1=y
+# CONFIG_CPU_SB1_PASS_2 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_SB1_CACHE_ERROR=y
+CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y
+# CONFIG_SB1_CERR_SPIN is not set
 CONFIG_VTAG_ICACHE=y
-CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -109,11 +125,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -148,6 +166,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -222,6 +241,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 # CONFIG_SCSI is not set
@@ -246,7 +272,6 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_SB1250_MAC=y
-CONFIG_NET_SB1250_MAC=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
@@ -264,6 +289,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -310,6 +336,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -326,6 +361,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -334,7 +370,6 @@
 # CONFIG_STALDRV is not set
 # CONFIG_SERIAL_TX3912 is not set
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
-# CONFIG_AU1000_UART is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_SIBYTE_SB1250_DUART=y
 CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
@@ -387,11 +422,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -404,6 +434,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -421,6 +453,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -451,6 +486,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -465,7 +501,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -476,6 +511,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -491,17 +531,14 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/defconfig-sead linux-2.4.20/arch/mips/defconfig-sead
--- linux-2.4.19/arch/mips/defconfig-sead	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/defconfig-sead	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,363 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+CONFIG_MIPS_SEAD=y
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_PCI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_NET is not set
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# MIPS initrd options
+#
+CONFIG_EMBEDDED_RAMDISK=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/cntmr.c linux-2.4.20/arch/mips/galileo-boards/ev64120/cntmr.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/cntmr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/cntmr.c	2002-10-04 00:41:22.000000000 +0000
@@ -25,7 +25,7 @@
 * cntTmrStart - Starts a counter/timer with given an initiate value.
 *
 * INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
-*          unsigned int countValue - Initial value for count down. 
+*          unsigned int countValue - Initial value for count down.
 *          CNT_TMR_OP_MODES opMode - Set Mode, Counter or Timer.
 *
 * RETURNS: false if one of the parameters is erroneous, true otherwise.
@@ -63,11 +63,11 @@
 }
 
 /********************************************************************
-* cntTmrDisable - Disables the timer/counter operation and return its 
+* cntTmrDisable - Disables the timer/counter operation and return its
 *                 value.
 *
 * INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
-* RETURNS: The counter/timer value (unsigned int), if any of the arguments are 
+* RETURNS: The counter/timer value (unsigned int), if any of the arguments are
 *          erroneous return 0.
 *********************************************************************/
 
@@ -166,10 +166,10 @@
 *                 or as a timer. (for more details on the different between
 *                 those two modes is written in the Data Sheet).
 *                 NOTE: This function only set the counter/timer mode and
-*                 don't enable it. 
+*                 don't enable it.
 *                 Be aware: If this function try to load value to an enabled
 *                           counter/timer it terminate with false.
-* 
+*
 * INPUTS:  unsigned int countNum - Selects one of the 8 counters/timers.
 *          CNT_TMR_OP_MODES opMode - TIMER or COUNTER mode.
 * RETURNS: false if one of the parameters is erroneous true otherwise .
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/Makefile linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/Makefile
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -11,13 +11,13 @@
 #
 #   The system comes in three forms:
 #
-#       1. - ramsys - 
+#       1. - ramsys -
 #          to be loaded into ram then run. When run
 #          it decompresses the kernel housed in its internal
 #          data structures and then jumps to the image which
 #          results in a linux kernel boot.
 #
-#       2. - flashsys - 
+#       2. - flashsys -
 #          to be loaded into ram so that it can be
 #          burned into the onboard flash. Then the board jumpers
 #          can be switched so that the next power cycle caused
@@ -26,10 +26,10 @@
 #          Note: burner.srec is the utility that will allow
 #          the user to get this image into flash.
 #
-#       3. - flashsys2 - 
+#       3. - flashsys2 -
 #          to be loaded into ram so that it can be
 #          burned into the onboard flash. Then on each power
-#          cycle when the standard PMON prompt is presented 
+#          cycle when the standard PMON prompt is presented
 #          the user can type `call 0xbf000000` to invoke
 #          the system in flash which then proceeds as
 #          described by #1 above.
@@ -75,7 +75,7 @@
 	gcc -o doit doit.c
 
 piggy.gz: $(SYSTEM)
-	rm -f piggy piggy.gz 
+	rm -f piggy piggy.gz
 	$(OBJCOPY) -S -O binary $(SYSTEM) piggy
 	gzip -f -9 < piggy > piggy.gz
 
@@ -89,7 +89,7 @@
 
 ramsys.srec : $(OBJECTS_ramsys) ld.script.gal
 	@# Note: this image is intended to run out of ram. No flash involved.
-	$(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys) 
+	$(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys)
 	$(NM) ramsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_ramsys.map
 	$(OBJCOPY) -O srec ramsys ramsys.srec
 	cp ramsys.srec $(TOPDIR)/.
@@ -97,7 +97,7 @@
 flashsys.srec : $(OBJECTS_flashsys) ld.sys.big.Flash
 	@# Note1: Use the burn utility to get this image into flash.
 	@# Note2: This image is intended to run out of flash as invoked
-	@# directly at powerup when EVB64120A jumpers are configured to 
+	@# directly at powerup when EVB64120A jumpers are configured to
 	@# bypass the onboard eprom.
 	@# Assumes that 0xBFC00000 is the bootup run address (normal MIPS).
 	@# And assumes that EVB64120A jumber J11 is added to the board and jumber
@@ -105,8 +105,8 @@
 	@# the jumper settings the system will execute at address 0xBFC00000,
 	@# as normal, yet that address will map to the onboard eeprom instead
 	@# of the onboard flash.
-	@# 
-	$(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys) 
+	@#
+	$(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys)
 	$(NM) flashsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys.map
 	@#
 	@# Next, Create the image that we want to place in the flash part.
@@ -125,7 +125,7 @@
 	@# to the board's ram it will land starting at address 0xA0300000
 	@# because this is where we have choosen to have the image temporarily sit
 	@# while we subsequently burn it (using some method not revealed here) into
-	@# the board's flash. After the burn the system can be setup (via jumpers) 
+	@# the board's flash. After the burn the system can be setup (via jumpers)
 	@# to boot this image directory from the flash part.
 	$(OBJCOPY) -O srec --adjust-vma=0xe0700000 flashsys.temp flashsys.srec
 	cp flashsys.srec $(TOPDIR)/.
@@ -139,8 +139,8 @@
 	@# the standard location such that the board boots out of onboard
 	@# eprom. From the PMON prompt the user can type `call 0xbf000000`
 	@# to transfer control to the image we are constructing here.
-	@# 
-	$(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2) 
+	@#
+	$(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2)
 	$(NM) flashsys2 | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys2.map
 	@#
 	@# Next, Create the image that we want to place in the flash part.
@@ -168,7 +168,7 @@
 burner.srec : $(OBJECTS_burner) ld.sys.big.burner
 	@# This utility can be used to burn the flashsys.srec or flashsys2.srec
 	@# into the EVB64120A's on board flash part (1Meg minimum).
-	$(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner) 
+	$(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner)
 	$(NM) burner | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_burner.map
 	$(OBJCOPY) -O srec burner burner.srec
 	cp burner.srec $(TOPDIR)/.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/README linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/README
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/README	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/README	2002-10-04 00:41:09.000000000 +0000
@@ -21,13 +21,13 @@
   Four systems are availalbe for download to the EVB64120A
   board.
 
-   1. - ramsys - 
+   1. - ramsys -
       To be loaded into ram then run. When run
       it decompresses the "vmlinux" kernel housed in its internal
       data structures and then jumps to the image which
       results in a linux kernel boot.
 
-   2. - flashsys - 
+   2. - flashsys -
       To be loaded into ram so that it can be
       burned into the onboard flash. Then the board jumpers
       can be switched so that the next power cycle caused
@@ -36,10 +36,10 @@
       Note: burner.srec is the utility that will allow
       the user to get this image into flash.
 
-   3. - flashsys2 - 
+   3. - flashsys2 -
       To be loaded into ram so that it can be
       burned into the onboard flash. Then on each power
-      cycle when the standard PMON prompt is presented 
+      cycle when the standard PMON prompt is presented
       the user can type `call 0xbf000000` to invoke
       the system in flash which then proceeds as
       described by #1 above.
@@ -53,8 +53,8 @@
 ==========================
 
   In this scenario the compressed system is downloaded
-  into ram and run directly from there. No flash is involved 
-  in this scenario. Naturally, the download must be repeated 
+  into ram and run directly from there. No flash is involved
+  in this scenario. Naturally, the download must be repeated
   on every power cycle.
 
   1. At the PMON prompt type `load`
@@ -69,7 +69,7 @@
 ========================================
 
   In this scenario vmlinux runs out of flash code
-  automatically on every power up. This means that 
+  automatically on every power up. This means that
   standard PMON code (of eprom) never runs.
 
   1. Place the boot jumpers in the Boot-from-eprom
@@ -77,7 +77,7 @@
      are found when booting PMON.
 
      Jumper settings. J11 - Removed
-                      J20 - Moved from the 1&2 position to 
+                      J20 - Moved from the 1&2 position to
                             the 2&3 position instead
 
   2. Use PMON to "load" the burner.srec image and then
@@ -89,12 +89,12 @@
      utility. The utililty will indicate when the burn
      process has completed.
 
-  4. Now switch off power and change the jumpers to 
+  4. Now switch off power and change the jumpers to
      the boot-from-flash position. The next power cycle
      will run the flash based system automatically.
 
      Jumper settings. J11 - Added.
-                      J20 - Moved from the 2&3 position to 
+                      J20 - Moved from the 2&3 position to
                             the 1&2 position instead
 
 Example: Running from flash: Scenario #2
@@ -111,7 +111,7 @@
      are found when booting PMON.
 
      Jumper settings. J11 - Removed
-                      J20 - Moved from the 1&2 position to 
+                      J20 - Moved from the 1&2 position to
                             the 2&3 position instead
 
   2. Use PMON to "load" the burner.srec image and then
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/burner.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/burner.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/burner.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/burner.c	2002-10-04 00:41:11.000000000 +0000
@@ -3,7 +3,7 @@
  *
  *  By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc).
  *
- *  Burn image from ram to flash 
+ *  Burn image from ram to flash
  *  For use with Galileo EVB64120A MIPS eval board.
  */
 #include <asm/types.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/doit.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/doit.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/doit.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/doit.c	2002-10-04 00:41:21.000000000 +0000
@@ -12,7 +12,7 @@
  *
  *    Example Usage:
  *       ./doit < piggy.gz > piggy.S
- *       
+ *
  */
 
 #include <stdio.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	2002-10-04 00:41:19.000000000 +0000
@@ -29,14 +29,14 @@
 
 /******************************************************************************
 * Those two tables contain the supported flash devices information needed by
-* the driver: 
-* The first table "flashParametrs" starts with 10 shared fields 
+* the driver:
+* The first table "flashParametrs" starts with 10 shared fields
 *  (currently 6 are reserved):
 *   index 0 => Pointer to an entry in the second table list
 *   index 1 => baseAddress - Flash memory device base address.
-*   index 2 => width - 1, 2, 4 or 8 Bytes. 
+*   index 2 => width - 1, 2, 4 or 8 Bytes.
 *   index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only)
-* The second table (flashTypes) contains: 
+* The second table (flashTypes) contains:
 * Entry`s structure:
 *   Manufacture ID,Device ID,number of sectors,list of sector`s sizes
 *   (in Kbytes starting with sector number 0).
@@ -120,14 +120,14 @@
 };
 
 /********************************************************************
-* flashInit - Initializes the FLASH memory driver`s parameters, this function 
+* flashInit - Initializes the FLASH memory driver`s parameters, this function
 *             must be called at least once before using the FLASH memory.
 *             If you are changing the FLASH base address call this function
 *             again.
 *
 * INPUTS:     unsigned int flashBaseAddress - The flash base Address.
 *             unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8.
-*             flashMode - PURE8, X8 or X16. 
+*             flashMode - PURE8, X8 or X16.
 * RETURNS:    Flash Size, zero when operation (flashInit) failed.
 *********************************************************************/
 unsigned int flashInit(unsigned int flashBaseAddress,
@@ -229,10 +229,10 @@
 		break;
 
 	}
-	/* Try to locate the device in the supported flashes list (FLASH_TYPE). 
-	   according to the keys: 
+	/* Try to locate the device in the supported flashes list (FLASH_TYPE).
+	   according to the keys:
 	   1) mfrId - manufactor ID.
-	   2) devId - device ID.  
+	   2) devId - device ID.
 	 */
 
 	while (true) {
@@ -266,9 +266,9 @@
 
 /********************************************************************
 * flashReset - Resets the Flash memory (FLASH`s internal protocol reset).
-*                
-* INTPUTS:  N/A    
-* OUTPUT:   N/A  
+*
+* INTPUTS:  N/A
+* OUTPUT:   N/A
 *********************************************************************/
 void flashReset()
 {
@@ -771,7 +771,7 @@
 * flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the
 *                  FLASH base address.
 *   			   address 0 = 0x00000000 !!
-*				   Attention!!! data "0" cannot be programed back to 
+*				   Attention!!! data "0" cannot be programed back to
 *                  "1" (only by first performing an earase operation).
 *                  The function takes care of Big/Little endian conversion
 *
@@ -899,7 +899,7 @@
 				}
 			}
 			break;
-		case 2:	/* Split the 32 bit write into two 8/16 bit Writings 
+		case 2:	/* Split the 32 bit write into two 8/16 bit Writings
 				   (16bit width). */
 			if (FLASH_MODE == X16) {
 				FirstData = 0xaa;	/* Data for the First  Cycle    */
@@ -1269,7 +1269,7 @@
 }
 
 /********************************************************************
-* flashReadWord - Read 32Bit from the FLASH memory at a given offset 
+* flashReadWord - Read 32Bit from the FLASH memory at a given offset
 *                 from the FLASH base address.
 * 				  address 0 = 0x00000000 !!
 *                 The function takes care of Big/Little endian conversion
@@ -1288,7 +1288,7 @@
 * flashInWhichSector - Returns the sector`s number at which offset is at.
 *
 * INPUTS:  Offset
-* RETURNS: Sector number,or 0xffffffff in case the address is out of range or 
+* RETURNS: Sector number,or 0xffffffff in case the address is out of range or
 *          flash wasn't initialize.
 *********************************************************************/
 unsigned int flashInWhichSector(unsigned int offset)
@@ -1317,7 +1317,7 @@
 * flashGetSectorSize - When given a Valid sector Number returns its Size.
 *
 * INPUTS:  unsigned int sectorNumber.
-* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't 
+* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't
 *          initialize return 0.)
 *********************************************************************/
 unsigned int flashGetSectorSize(unsigned int sectorNumber)
@@ -1484,7 +1484,7 @@
 
 /********************************************************************
 * flashWriteShort - write 16bit data to a given flash offset.
-*                  It reads the whole word 32bit wide, modify the  short 
+*                  It reads the whole word 32bit wide, modify the  short
 *                  and write back the word.
 *
 * INPUTS:  unsigned int offset - required offset to be write to.
@@ -1520,7 +1520,7 @@
 
 /********************************************************************
 * flashWriteChar - write one charecter (8 bit) to a given flash offset.
-*                  It reads the whole word 32bit wide, modify the charecter 
+*                  It reads the whole word 32bit wide, modify the charecter
 *                  and write back the word.
 *
 * INPUTS:  unsigned int offset - required offset to be write to.
@@ -1548,7 +1548,7 @@
 
 /********************************************************************
 * flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset.
-*                        It reads the whole word 32bit wide, modify the  
+*                        It reads the whole word 32bit wide, modify the
 *                        charecter and write back the word.
 *
 * INPUTS:  N/A.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/head.S linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/head.S
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/head.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/head.S	2002-10-04 00:41:09.000000000 +0000
@@ -9,11 +9,11 @@
 	.text
 NESTED(startup, 16, sp)
 	.set	noreorder
-        
+
 	jal decompress_kernel
 	nop
-        
+
         jal kernel_location_start+0x584
         nop
-        
+
 	END(startup)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	2002-10-04 00:41:09.000000000 +0000
@@ -1,8 +1,8 @@
 OUTPUT_FORMAT("elf32-bigmips")
 OUTPUT_ARCH(mips)
 ENTRY(startup)
-SECTIONS 
-{ 
+SECTIONS
+{
   kernel_location_start = 0x80100000;
   . = 0x80400000;
   .text : {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	2002-10-04 00:41:22.000000000 +0000
@@ -6,7 +6,7 @@
 {
   . = 0xBFC00000;
   .got : {*(.got)}
-  .reset : { 
+  .reset : {
     sbdreset = ABSOLUTE(.);
     sbdreset_evb64120A.o
     evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	2002-10-04 00:41:12.000000000 +0000
@@ -6,7 +6,7 @@
 {
   . = 0xBF000000;
   .got : {*(.got)}
-  .reset : { 
+  .reset : {
     xfer.o
   }
   kernel_location_start = 0x80100000;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/meminit.S linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/meminit.S
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/meminit.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/meminit.S	2002-10-04 00:41:17.000000000 +0000
@@ -1,8 +1,8 @@
-/* 
- * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming 
+/*
+ * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming
  * 2-way interleaving).  This is so that the test pattern and
  * inverted pattern are written to the same bank of memory, which
- * prevents us reading back data sitting in the dram buffers and 
+ * prevents us reading back data sitting in the dram buffers and
  * getting a false match.
  */
 
@@ -17,11 +17,11 @@
 #ifndef RAM_BASE
 #define RAM_BASE	KSEG1_BASE
 #endif
-			
+
 #ifndef MEMSTART
 #define MEMSTART	0x0		/* start of physical memory */
 #endif
-		
+
 #ifndef MEMINCR
 # define MEMINCR	0x10000		/* work up in 64Kb increments */
 #endif
@@ -36,13 +36,13 @@
 
 	li	t0,RAM_BASE+MEMSTART	# start at bottom of phys mem
 	move	t1,t0			# remember start address
-	li	t2,0xaa55aa55		# pattern 
+	li	t2,0xaa55aa55		# pattern
 	not	t3,t2			# ~pattern
 
 	move	t7,k0
 	la	t4,.fail		# bus error exception catcher
-	addu	k0,t4,s8		# RELOC 
-	
+	addu	k0,t4,s8		# RELOC
+
 	/* fill first 64Kb with zero (for cache init) */
 	move	t4,t0
 	li	t5,0x10000
@@ -55,7 +55,7 @@
 	bnez	t5,1b
 
 .loop:
-        addu    t0,MEMINCR		
+        addu    t0,MEMINCR
 	move	t4,t0
 
 	/* store pattern in bank 0, line 0 */
@@ -109,25 +109,25 @@
 
 
 /*
- * We must often initialise memory so that it has good parity/ecc, 
+ * We must often initialise memory so that it has good parity/ecc,
  * and this must be done before the caches are used.
  */
 
 /*
 	clear_mem (size)
 	  - clear memory from RAM_BASE+MEMSTART to RAM_BASE+MEMSTART+size
-	clear_mem_range (size, start)  
+	clear_mem_range (size, start)
 	  - clear memory from start to start+size
 */
 
 SLEAF(clear_mem)
 	li	a1,RAM_BASE+MEMSTART	# start at bottom of phys mem
-clear_mem_range:	
+clear_mem_range:
 	beqz	a0,9f
-	addu	a0,a1			# end of memory 
-	
+	addu	a0,a1			# end of memory
+
 	/* XXX should run cached, but caches may not be initialised yet */
-	.set noreorder	
+	.set noreorder
 #if __mips >= 3
 1:	sd	zero,0(a1)
 	sd	zero,8(a1)
@@ -139,7 +139,7 @@
 	addu	a1,64
 	bne	a1,a0,1b
 	sd	zero,-8(a1)		# BDSLOT
-#else	
+#else
 1:	sw	zero,0(a1)
 	sw	zero,4(a1)
 	sw	zero,8(a1)
@@ -158,7 +158,7 @@
 	addu	a1,64
 	bne	a1,a0,1b
 	sw	zero,-4(a1)		# BDSLOT
-#endif	
+#endif
 	.set	reorder
 
 9:	j	ra
@@ -172,7 +172,7 @@
         mtc0	zero,C0_PGMASK
 	li	t8,K1BASE		/* tlbhi  = impossible vpn */
 	li	t9,(NTLBENTRIES-1)	/* index */
-	
+
 	.set noreorder
 	nop
 1:	mtc0	t8,C0_TLBHI
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/memory.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/memory.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/memory.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/memory.c	2002-10-04 00:41:20.000000000 +0000
@@ -8,7 +8,7 @@
 SDRAM memory and devices windows, please pay attention to overlapping windows
 since the function do not take care of that for you.
 When remapping the SDRAM or devices memory space pay attention to the PCI
-mappings and make sure to coordinate between the two interfaces!!!           
+mappings and make sure to coordinate between the two interfaces!!!
 */
 
 /* includes */
@@ -26,7 +26,7 @@
 *      - If the memory bank size is 0 then this base address has no meaning !!!
 *
 * INPUTS:  MEMORY_BANK bank - SDRAM Bank number.
-* OUTPUT:  N/A  
+* OUTPUT:  N/A
 * RETURNS: Memory bank base address.
 *********************************************************************/
 unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank)
@@ -45,7 +45,7 @@
 *           - If the device size is 0 then this base address has no meaning!!!
 *
 * INPUT:   DEVICE device - Bank number.
-* OUTPUT:  N/A  
+* OUTPUT:  N/A
 * RETURNS: Device base address.
 *********************************************************************/
 unsigned int getDeviceBaseAddress(DEVICE device)
@@ -83,7 +83,7 @@
 * getDeviceSize - Extract the size of a device memory space
 *
 * INPUT:    DEVICE device - Device number
-* OUTPUT:   N/A  
+* OUTPUT:   N/A
 * RETURNS:  Size of a device memory space.
 *********************************************************************/
 unsigned int getDeviceSize(DEVICE device)
@@ -103,10 +103,10 @@
 * getDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width.
 *                  The width is determine in registers: 'Device Parameters'
 *                  registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device.
-*                  at bits: [21:20].                  
+*                  at bits: [21:20].
 *
 * INPUT:    DEVICE device - Device number
-* OUTPUT:   N/A  
+* OUTPUT:   N/A
 * RETURNS:  Device width in Bytes (1,2,4, or 8), 0 if error had occurred.
 *********************************************************************/
 unsigned int getDeviceWidth(DEVICE device)
@@ -132,9 +132,9 @@
 
 /********************************************************************
 * mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - Pay attention to the PCI mappings and make sure to
 *                       coordinate between the two interfaces!!!
-*                     - It is the programmer`s responsibility to make sure 
+*                     - It is the programmer`s responsibility to make sure
 *                       there are no conflicts with other memory spaces!!!
 *                     - If a bank needs to be closed , give it a 0 length
 *
@@ -143,7 +143,7 @@
 *         unsigned int bank0Length - required bank 0 size.
 *         unsigned int bank1Base - required bank 1 base address.
 *         unsigned int bank1Length - required bank 1 size.
-* RETURNS: true on success, false on failure or if one of the parameters is 
+* RETURNS: true on success, false on failure or if one of the parameters is
 *          erroneous.
 *********************************************************************/
 bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
@@ -205,7 +205,7 @@
 
 /********************************************************************
 * mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3
-*                     - Pay attention to the PCI mappings and make sure to  
+*                     - Pay attention to the PCI mappings and make sure to
 *                       coordinate between the two interfaces!!!
 *                     - It`s the programmer`s responsibility to make sure there
 *                       are no conflicts with other memory spaces!!!
@@ -216,7 +216,7 @@
 *         unsigned int bank2Length - required bank 2 size.
 *         unsigned int bank3Base - required bank 3 base address.
 *         unsigned int bank3Length - required bank 3 size.
-* RETURNS: true on success, false on failure or if one of the parameters is 
+* RETURNS: true on success, false on failure or if one of the parameters is
 *          erroneous.
 *********************************************************************/
 bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
@@ -278,9 +278,9 @@
 }
 
 /********************************************************************
-* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1 
+* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1
 *                                and 2
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - Pay attention to the PCI mappings and make sure to
 *                        coordinate between the two interfaces!!!
 *                     - It`s the programmer`s responsibility to make sure there
 *                       are no conflicts with other memory spaces!!!
@@ -289,11 +289,11 @@
 *
 * INPUTS: unsigned int device0Base - required cs_0 base address.
 *         unsigned int device0Length - required cs_0 size.
-*         unsigned int device1Base - required cs_1 base address. 
-*         unsigned int device1Length - required cs_0 size.       
-*         unsigned int device2Base - required cs_2 base address. 
-*         unsigned int device2Length - required cs_2 size.       
-* RETURNS: true on success, false on failure or if one of the parameters is 
+*         unsigned int device1Base - required cs_1 base address.
+*         unsigned int device1Length - required cs_0 size.
+*         unsigned int device2Base - required cs_2 base address.
+*         unsigned int device2Length - required cs_2 size.
+* RETURNS: true on success, false on failure or if one of the parameters is
 *          erroneous.
 *********************************************************************/
 bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
@@ -431,11 +431,11 @@
 }
 
 /********************************************************************
-* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices: 
+* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices:
 *                                 3 and boot
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - Pay attention to the PCI mappings and make sure to
 *                       coordinate between the two interfaces!!!
-*                     - It is the programmer`s responsibility to make sure 
+*                     - It is the programmer`s responsibility to make sure
 *                       there are no conflicts with other memory spaces!!!
 *                     - If a device needs to be closed , give it a 0 length.
 *
@@ -501,7 +501,7 @@
 }
 
 /********************************************************************
-* modifyDeviceParameters - This function can be used to modify a device`s 
+* modifyDeviceParameters - This function can be used to modify a device`s
 *                          parameters.
 *                        - Be advised to check the spec before modifying them.
 * Inputs:
@@ -579,8 +579,8 @@
 }
 
 /********************************************************************
-* remapAddress - This fubction used for address remapping 
-* Inputs:      - regOffset: remap register 
+* remapAddress - This fubction used for address remapping
+* Inputs:      - regOffset: remap register
 *                remapHeader : remapped address
 * Returns: false if one of the parameters is erroneous,true otherwise.
 *********************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/misc.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/misc.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/misc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/misc.c	2002-10-04 00:41:15.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * arch/mips/galileo/misc.c
- * 
- * This is a collection of several routines from gzip-1.0.3 
+ *
+ * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/pci.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/pci.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/pci.c	2002-10-04 00:41:11.000000000 +0000
@@ -25,12 +25,12 @@
 
 /********************************************************************
 * pci0ScanDevices   - This function scan PCI0 bus, if found any device on
-*                     this bus it interrogate the Device for the information 
+*                     this bus it interrogate the Device for the information
 *                     it can discover.
-*                     The fields with all information are the following: 
+*                     The fields with all information are the following:
 *    char            type[20];
 *    unsigned int    deviceNum;
-*    unsigned int    venID;                                            
+*    unsigned int    venID;
 *    unsigned int    deviceID;
 *    unsigned int    bar0Base;
 *    unsigned int    bar0Size;
@@ -44,7 +44,7 @@
 *    unsigned int    bar4Size;
 *    unsigned int    bar5Base;
 *    unsigned int    bar5Size;
-* 
+*
 * Inputs:   PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE.
 *           unsigned int numberOfElment - The PCI0_DEVICE Array length.
 * Output:   None.
@@ -307,12 +307,12 @@
 
 /********************************************************************
 * pci1ScanDevices   - This function scan PCI1 bus, if found any device on
-*                     this bus it interrogate the Device for the information 
+*                     this bus it interrogate the Device for the information
 *                     it can discover.
-*                     The fields with all information are the following: 
+*                     The fields with all information are the following:
 *    char            type[20];
 *    unsigned int    deviceNum;
-*    unsigned int    venID;                                            
+*    unsigned int    venID;
 *    unsigned int    deviceID;
 *    unsigned int    bar0Base;
 *    unsigned int    bar0Size;
@@ -326,8 +326,8 @@
 *    unsigned int    bar4Size;
 *    unsigned int    bar5Base;
 *    unsigned int    bar5Size;
-* 
-* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE. 
+*
+* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE.
 * Output:   None.
 *********************************************************************/
 
@@ -562,12 +562,12 @@
 
 /********************************************************************
 * pci0WriteConfigReg - Write to a PCI configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - Make sure the GT is configured as a master before
 *                      writingto another device on the PCI.
 *                    - The function takes care of Big/Little endian conversion.
-* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec 
+* Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec
 *                   (or any other PCI device spec)
-*           pciDevNum: The device number needs to be addressed.                
+*           pciDevNum: The device number needs to be addressed.
 *
 *  Configuration Address 0xCF8:
 *
@@ -604,9 +604,9 @@
 *                   - Make sure the GT is configured as a master before writing
 *                     to another device on the PCI.
 *                   - The function takes care of Big/Little endian conversion.
-* Inputs:   unsigned int regOffset: The register offset as it apears in the  
+* Inputs:   unsigned int regOffset: The register offset as it apears in the
 *           GT spec (or any other PCI device spec)
-*           pciDevNum: The device number needs to be addressed.                
+*           pciDevNum: The device number needs to be addressed.
 *
 *  Configuration Address 0xCF8:
 *
@@ -626,7 +626,7 @@
 	pciDevNum = pciDevNum << 11;
 	regOffset = regOffset & 0x0fffffff;
 	if (pciDevNum == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* when configurating our own PCI 1 L-unit the access is through
 		   the PCI 0 interface with reg number = reg number + 0x80 */
 		DataForRegCf8 =
 		    (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
@@ -647,13 +647,13 @@
 
 /********************************************************************
 * pci0ReadConfigReg  - Read from a PCI0 configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - Make sure the GT is configured as a master before
 *                      reading from another device on the PCI.
 *                   - The function takes care of Big/Little endian conversion.
 * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
 *                        spec)
-*           pciDevNum: The device number needs to be addressed.                
-* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+*           pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
 *                 cause register to make sure the data is valid
 *
 *  Configuration Address 0xCF8:
@@ -690,13 +690,13 @@
 
 /********************************************************************
 * pci1ReadConfigReg  - Read from a PCI1 configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - Make sure the GT is configured as a master before
 *                      reading from another device on the PCI.
 *                   - The function takes care of Big/Little endian conversion.
 * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
 *                        spec)
-*           pciDevNum: The device number needs to be addressed.                
-* RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+*           pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
 *                 cause register to make sure the data is valid
 *
 *  Configuration Address 0xCF8:
@@ -718,7 +718,7 @@
 	pciDevNum = pciDevNum << 11;
 	regOffset = regOffset & 0x0fffffff;
 	if (pciDevNum == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* when configurating our own PCI 1 L-unit the access is through
 		   the PCI 0 interface with reg number = reg number + 0x80 */
 		DataForRegCf8 =
 		    (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
@@ -1058,7 +1058,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegSpace - Maps the internal registers memory space for the 
+* pci0MapInternalRegSpace - Maps the internal registers memory space for the
 *                           slave.
 *                           Stays the same for all GT devices Disco include
 * Inputs: base of pci0 internal register
@@ -1078,7 +1078,7 @@
 }
 
 /********************************************************************
-* pci1MapInternalRegSpace - Maps the internal registers memory space for the 
+* pci1MapInternalRegSpace - Maps the internal registers memory space for the
 *                           slave.
 *                           Stays the same for all GT devices Disco include
 * Inputs: base of pci1 internal register
@@ -1098,7 +1098,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the
 *                             slave.
 *                             Stays the same for all GT devices Disco include
 * Inputs: base of pci0 internal io register
@@ -1117,7 +1117,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the
 *                             slave.
 *                             Stays the same for all GT devices Disco include
 * Inputs: base of pci1 internal io register
@@ -1137,7 +1137,7 @@
 
 /********************************************************************
 * pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave.
-*                         for Discovery we need two function: SCS0 & SCS1 
+*                         for Discovery we need two function: SCS0 & SCS1
 *                         (instead of SCS[1:0])
 * Inputs: base and size of pci0 dram
 *********************************************************************/
@@ -1163,7 +1163,7 @@
 
 /********************************************************************
 * pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave.
-*                         for Discovery we need two function: SCS0 & SCS1 
+*                         for Discovery we need two function: SCS0 & SCS1
 *                         (instead of SCS[1:0])
 * Inputs: base and size of pci1 dram
 *********************************************************************/
@@ -1188,7 +1188,7 @@
 
 /********************************************************************
 * pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave.
-*                         for Discovery we need two function: SCS2 & SCS3 
+*                         for Discovery we need two function: SCS2 & SCS3
 *                         (instead of SCS[3:2])
 * Inputs: base and size of pci0 dram
 *********************************************************************/
@@ -1213,7 +1213,7 @@
 
 /********************************************************************
 * pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave.
-*                         for Discovery we need two function: SCS2 & SCS3 
+*                         for Discovery we need two function: SCS2 & SCS3
 *                         (instead of SCS[3:2])
 * Inputs: base and size of pci1 dram
 *********************************************************************/
@@ -1237,7 +1237,7 @@
 }
 
 /********************************************************************
-* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces 
+* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces
 *                                    for the slave.
 *                                    For the Discovery there are 3 separate
 *                                    fucnction's
@@ -1260,7 +1260,7 @@
 }
 
 /********************************************************************
-* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces 
+* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces
 *                                    for the slave.
 *                                    For the Discovery there are 3 separate
 *                                    fucnction's
@@ -1282,9 +1282,9 @@
 }
 
 /********************************************************************
-* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory 
+* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory
 *                                     spaces for the slave.
-*                                     For the Discovery there are 2 separate 
+*                                     For the Discovery there are 2 separate
 *                                     fucnction's
 * Inputs: base and length of pci0 device3/ boot
 *********************************************************************/
@@ -1309,9 +1309,9 @@
 }
 
 /********************************************************************
-* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory 
+* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory
 *                                     spaces for the slave.
-*                                     For the Discovery there are 2 separate 
+*                                     For the Discovery there are 2 separate
 *                                     fucnction's
 * Inputs: base and length of pci1 device3/ boot
 *********************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	2002-10-04 00:41:10.000000000 +0000
@@ -21,7 +21,7 @@
 	if ((bus == 0) && (dev >= 0) && (dev < 30))
 		return 0;	// Bus/Device Number OK
 
-	return -1;		// Bus/Device Number not OK  
+	return -1;		// Bus/Device Number not OK
 }
 
 /********************************************************************
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	2002-10-04 00:41:09.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Copyright 1997 Algorithmics Ltd
  *	All Rights Reserved
- *	
+ *
  * gal9/sbdreset.sx -- low level board dependent routines
  */
 
@@ -23,29 +23,29 @@
 
 #include "gt64011.h"
 #include "ns16550.h"
-			
+
 #ifdef GALILEO_PORT // miniBios crack
 #define C0_CONFIG CP0_CONFIG
 #define C0_STATUS CP0_STATUS
 #define C0_TLBLO0 CP0_ENTRYLO0
 #define C0_TLBLO1 CP0_ENTRYLO1
 #define C0_PGMASK CP0_PAGEMASK
-#define C0_TLBHI CP0_ENTRYHI 
+#define C0_TLBHI CP0_ENTRYHI
 #define C0_INX CP0_INDEX
 #define NTLBENTRIES     48
-        
-        
+
+
 #define CFG_IB CONF_IB
 #define CFG_DB CONF_DB
 #define CFG_C_NONCOHERENT CONF_CM_CACHABLE_NONCOHERENT
-#define C0_SR CP0_STATUS        
+#define C0_SR CP0_STATUS
 #define SR_DE ST0_DE
 
-        
+
         #define SLEAF(x) LEAF(x)
         #define SEND(x) END(x)
         #define XLEAF(x) LEAF(x)
-        #define SBD_DISPLAY(a,b,c,d,e) ; 
+        #define SBD_DISPLAY(a,b,c,d,e) ;
 
 #define K0BASE          0x80000000
 #define K0SIZE          0x20000000
@@ -70,7 +70,7 @@
 #endif
 
 #define MB	0x100000
-				
+
 #define MemTypeNone		0x8000
 #define MemRasMask		0x0f00
 #define MemRasShift		8
@@ -85,7 +85,7 @@
 #define bank3	s5
 #define memtop	s6
 #define membase	s7
-	
+
 /*#if #endian(big)	*/
 #ifdef __MIPSEB__
 
@@ -104,9 +104,9 @@
 #else
 #define HTOLL(sr,tr)
 #endif
-				
+
 #undef DBGSBD
-	
+
 #ifdef DBGSBD
 #define DBG(s) \
 	.rdata ; \
@@ -114,7 +114,7 @@
 	.text ; \
 	la	a0, 88b ; \
 	jal	_dbgmsg
-	
+
 LEAF(_dbgmsg)
 	.set noat
 	li	AT,PHYS_TO_K1(NS16550_CHANB)
@@ -123,13 +123,13 @@
 	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
 	and	v1,LSR_TXRDY
 	beqz	v1,waitrdy
-	
+
 	lbu	v1,(a0)
 	addu	a0,1
 	beqz	v1,9f
 	sb	v1,DATA(AT)
 	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
-	b	waitrdy	
+	b	waitrdy
 9:	j	ra
 	.set at
 END(_dbgmsg)
@@ -142,7 +142,7 @@
 	.set noreorder;	nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
 	and	t1,LSR_TXRDY
 	beqz	t1,1b
-	
+
 	srl	t1,a0,28
 	addu	t1,'0'
 	ble	t1,'9',2f
@@ -153,11 +153,11 @@
 	sll	a0,4
 	sub	t0,1
 	bnez	t0,1b
-		
+
 	j	ra
 	.set at
 END(_dbghex)
-	
+
 	.rdata
 initb_str:
 	.byte	9,0x40	/* Reset CH B */
@@ -171,7 +171,7 @@
 	.byte	0,0x10
 	.byte	14,0x01	/* enable baud rate gen. */
 	.byte	15,0x00	/* known state for reg 15 */
-	
+
 	.byte	14,0x00	/* disable baud rate gen. */
 	.byte	12,0x0a /* 0x0a	= 9600 baud time const. - lower 8 bits */
 	.byte	13,0x00	/* 9600 buad time const. - upper 8 bits */
@@ -179,7 +179,7 @@
 	.byte	0xff
 
 	.text
-	
+
 SLEAF(_dbginit)
         /*
         li	v0,PHYS_TO_K1(NS16550_CHANB)
@@ -194,27 +194,27 @@
         */
         jal     init_ns16550_chan_b # Debug channel
 	j	ra
-SEND(_dbginit)		
+SEND(_dbginit)
 #else
-#define DBG(s)		
+#define DBG(s)
 #endif
-		
+
 LEAF(sbdreset)
 	move	rasave,ra
 
 	/* if launched by ITROM, leave Config alone */
-#ifndef ITBASE	
+#ifndef ITBASE
 	/* set config register for 32b/32b cachelines, kseg0 cacheable */
 	mfc0	t1,C0_CONFIG
 	and	t1,~0x3f		# set bits 5..0 only
 	or	t1,CFG_IB | CFG_DB | CFG_C_NONCOHERENT
 	mtc0	t1,C0_CONFIG
-#endif	
+#endif
+
+       /* Initialize stack pointer to 6MB address */
+         li sp,0xa0600000
 
-       /* Initialize stack pointer to 6MB address */        
-         li sp,0xa0600000 
 
-        
         /*
 	 * slight amount of kludgery here to stop RAM resident
 	 * program from overwriting itself...
@@ -248,23 +248,23 @@
 #define GT_INTERNAL_REG_BASE 0xb4000000
 
         li      p64011, PA_TO_KVA1(GT64011_BASE)
-         
+
         li  v0,0xb400046c       /* Boot Device */
         lw  t0,0(v0)
         and t0,0x00003000       /* Keep the correct boot size */
 	or  t0,htoll(0x3847de70)
 	sw  t0,0(v0)
-        
+
         li  v0,0xb4000468       /* CS3 Device - 16 bit FLASH memory */
         li  t0,htoll(0x3859e6e8)
 	sw  t0,0(v0)
-        
-                
+
+
         li  v0,0xb4000c84       /* PCI 1 timeout register */
         li  t0,htoll(0xffff)
 	sw  t0,0(v0)
-        
-                
+
+
         li  v0,0xb4000c3c       /* Enable I/O response on PCI0 */
         li  t0,htoll(0x7)
 	sw  t0,0(v0)
@@ -274,14 +274,14 @@
 	sw  t0,0(v0)
 
         /* GT-64120 Initialization */
-        
-        li      p64011, PA_TO_KVA1(GT64011_BASE)	
+
+        li      p64011, PA_TO_KVA1(GT64011_BASE)
 
         /*********************************************************************/
         /************************* SDRAM initializing ************************/
         /******************************* START *******************************/
-        
-        
+
+
                                         /* SDRAM banks 0,1,2,3 parameters               */
         li      t0,htoll(0x01908200)    /* - Standard Monitor: Interleave enabled       */
         li      v0,0xb4000448           /* - Registered SDRAM (Bit 23)                  */
@@ -292,76 +292,76 @@
                                         /* - No ECC                                     */
                                         /* - No ByPass                                  */
                                         /* - Burst length: 8                            */
-        
+
         /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM0 */
         /* Set bank0`s range to: 0 - 0x10000000 (256 MByte)     */
 _DIMM0:
-        li  v0,0xb4000008      
+        li  v0,0xb4000008
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000010      
+
+        li  v0,0xb4000010
 	li  t0,htoll(0x7f)
 	sw  t0,0(v0)
-        
+
         /* Close banks 2 and 3 */
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x7ff)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        li  v0,0xb4000020
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        
+
         /* Extend bank0 to 0x10000000 and Close bank1,2 and 3 */
         DBG("Extend bank0 to 0x10000000 and Close bank1,2 and 3...\r\n")
-        li  v0,0xb4000400      
+        li  v0,0xb4000400
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400040c      
+	sw  t0,0(v0)
+        li  v0,0xb400040c
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)        
+	sw  t0,0(v0)
 
         /* Configure bank0 to 256 Mbit */
         DBG("Configure bank0 to 256 Mbit...\r\n")
-        li  v0,0xb400044c      
+        li  v0,0xb400044c
 	li  t0,htoll(0x00004c69)
         sw  t0,0(v0)
-        
+
         /* Config the SDRAM banks decode system */
-	li  v0,0xb400047c      
+	li  v0,0xb400047c
 	li  t0,htoll(2)
 	sw  t0,0(v0)
- 
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa0000000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
-	sw  t0,0(v0)      
-        
+	sw  t0,0(v0)
+
         /* Write to address 0x2000000 and check if 0x00000000 is being written too */
         DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
         li  v0,0xa0000000
@@ -372,7 +372,7 @@
         bne t1,v0,1b
 
         /* The address should activate Dadr12 */
-        li  v0,0xa2000000      
+        li  v0,0xa2000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -387,7 +387,7 @@
         li    v0,0x11111111
         lw    t0,(t0)
         bne   t0,v0,_256MBIT
-        
+
         /* Write to address 0x1000 and check if 0x00000000 is being written too */
         DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
         li  v0,0xa0000000
@@ -398,7 +398,7 @@
         bne t1,v0,1b
 
         /* The address should activate bank select1*/
-        li  v0,0xa0001000      
+        li  v0,0xa0001000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -425,7 +425,7 @@
 
         /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
            device */
-        li  v0,0xa8000000      
+        li  v0,0xa8000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -441,11 +441,11 @@
         lw    t0,(t0)
         beq   t0,v0,_64MBIT
         b     _128MBIT
-        
+
 _16MBIT:
         DBG("16 Mbit SDRAM detected...\r\n")
         /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(16)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000449)
@@ -454,7 +454,7 @@
 _64MBIT:
         DBG("64 Mbit SDRAM detected...\r\n")
         /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(64)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -463,7 +463,7 @@
 _128MBIT:
         DBG("128 Mbit SDRAM detected...\r\n")
         /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(128)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -472,85 +472,85 @@
 _256MBIT:
         DBG("256 Mbit SDRAM detected...\r\n")
         /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(256)
 	sw  t0,0(v0)
         li  t1,htoll(0x00004c69)
         b   _DIMM1
-        
-_DIMM1:        
+
+_DIMM1:
         li  v0,0xb400044c
         sw  t1,0(v0)  # Bank0
-        sw  t1,4(v0)  # Bank1           
-        
+        sw  t1,4(v0)  # Bank1
+
         /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM1 */
         /* Close banks 0 and 1 */
-        li  v0,0xb4000008      
+        li  v0,0xb4000008
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000010      
+
+        li  v0,0xb4000010
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
+
         /* Set bank2`s range to: 0 - 0x10000000 (256 MByte)     */
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        li  v0,0xb4000020
 	li  t0,htoll(0x7f)
 	sw  t0,0(v0)
-        
+
         /* Extend bank2 to 0x10000000 and Close bank0,1 and 3 */
         DBG("Extend bank2 to 0x10000000 and Close banks 0,1 and 3...\r\n")
-        li  v0,0xb4000400      
+        li  v0,0xb4000400
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400040c      
+	sw  t0,0(v0)
+        li  v0,0xb400040c
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)        
+	sw  t0,0(v0)
 
         /* Configure bank2 to 256 Mbit */
         DBG("Configure bank2 to 256 Mbit...\r\n")
-        li  v0,0xb4000454      
+        li  v0,0xb4000454
 	li  t0,htoll(0x00004c69)
         sw  t0,0(v0)
-        
+
         /* Config the SDRAM banks decode system */
-	li  v0,0xb400047c      
+	li  v0,0xb400047c
 	li  t0,htoll(2)
 	sw  t0,0(v0)
- 
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa0000000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
-	sw  t0,0(v0)      
-        
+	sw  t0,0(v0)
+
         /* Write to address 0x2000000 and check if 0x00000000 is being written too */
         DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
         li  v0,0xa0000000
@@ -561,7 +561,7 @@
         bne t1,v0,1b
 
         /* The address should activate Dadr12 */
-        li  v0,0xa2000000      
+        li  v0,0xa2000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -576,7 +576,7 @@
         li    v0,0x11111111
         lw    t0,(t0)
         bne   t0,v0,_256MBIT2
-        
+
         /* Write to address 0x1000 and check if 0x00000000 is being written too */
         DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
         li  v0,0xa0000000
@@ -587,7 +587,7 @@
         bne t1,v0,1b
 
         /* The address should activate bank select1*/
-        li  v0,0xa0001000      
+        li  v0,0xa0001000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -614,7 +614,7 @@
 
         /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
            device */
-        li  v0,0xa8000000      
+        li  v0,0xa8000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -630,11 +630,11 @@
         lw    t0,(t0)
         beq   t0,v0,_64MBIT2
         b     _128MBIT2
-        
+
 _16MBIT2:
         DBG("16 Mbit SDRAM detected...\r\n")
         /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(16)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000449)
@@ -643,7 +643,7 @@
 _64MBIT2:
         DBG("64 Mbit SDRAM detected...\r\n")
         /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(64)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -652,7 +652,7 @@
 _128MBIT2:
         DBG("128 Mbit SDRAM detected...\r\n")
         /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(128)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -661,104 +661,104 @@
 _256MBIT2:
         DBG("256 Mbit SDRAM detected...\r\n")
         /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(256)
 	sw  t0,0(v0)
         li  t1,htoll(0x00004c69)
         b   _INIT_SDRAM
 
-_INIT_SDRAM:        
+_INIT_SDRAM:
         /* Restore defaults */
         DBG("Restoring defaults...\r\n")
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0x07)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0x08)
 	sw  t0,0(v0)
-        li  v0,0xb400040c      
+        li  v0,0xb400040c
 	li  t0,htoll(0x0f)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0x10)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0x17)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0x18)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x1f)
 	sw  t0,0(v0)
-        li  v0,0xb4000010      
+        li  v0,0xb4000010
 	li  t0,htoll(0x07)
 	sw  t0,0(v0)
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x008)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        li  v0,0xb4000020
 	li  t0,htoll(0x0f)
-	sw  t0,0(v0)        
-        
+	sw  t0,0(v0)
+
         li  v0,0xb400044c
         sw  t1,8(v0)  # Bank2
         sw  t1,12(v0) # Bank3
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa0000000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa0800000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa1000000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x3)
 	sw  t0,0(v0)
-        
+
         li  v0,0xa1800000
         li  t0,0
         sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        li  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
+
         /*********************************************************************/
         /************************* SDRAM initializing ************************/
         /******************************* END *********************************/
-        
+
         li      p64011, PA_TO_KVA1(GT64011_BASE)
-        
+
         li      t0,htoll(0x00000000)    /* RAS[1:0] low decode address */
         sw      t0,0x008(p64011)
 
@@ -794,8 +794,8 @@
 
         li      t0,htoll(0x0000001f)    /* RAS[3] High Decode Address <<<<<< 1*/
         sw      t0,0x41c(p64011)
-	
-#ifdef DBGSBD	
+
+#ifdef DBGSBD
 #define DREG(str,rname) \
 	DBG(str); \
 	DBG(":\t") ;			\
@@ -803,7 +803,7 @@
 	HTOLL(a0,t0) ;			\
 	jal	_dbghex ;		\
 	DBG("\r\n")
-	
+
 	DBG("GT-64120 settings:\r\n")
         DREG("DRAMPAR_BANK0   (44c)",GT_DRAMPAR_BANK0)
         DREG("DRAMPAR_BANK1   (450)",GT_DRAMPAR_BANK1)
@@ -828,7 +828,7 @@
         DREG("GT_DEVPAR_BANK3 (468)",GT_DEVPAR_BANK3)
         DREG("GT_IPCI_TOR     (c04)",GT_IPCI_TOR)
 #endif
-		
+
 	/* we can now initialise the caches for a fast clear_mem */
 	SBD_DISPLAY ('C','A','C','H',CHKPNT_CACH)
 	DBG("init_cache\r\n")
@@ -839,7 +839,7 @@
 	/* initialise tlb */
 	SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB)
 	DBG("init_tlb\r\n")
-//	bal	init_tlb 
+//	bal	init_tlb
 
 //	DBG("sbdreset completed\r\n")
 //	move	ra,rasave
@@ -928,7 +928,7 @@
 
 LEAF(sbdberrenb)
 	mfc0	v0,C0_SR
-	li	t0,SR_DE	
+	li	t0,SR_DE
 	bnez	a0,1f
 	or	t1,v0,t0	# disable cache/parity errors (SR_DE = 1)
 	b	2f
@@ -966,7 +966,7 @@
 1:	mul	a0,t1
 	subu	a0,15		# approx number of loops so far
 
-	.set	noreorder	
+	.set	noreorder
 	.set	nomacro
 	nop
 2:	bgtz	a0,2b
@@ -981,7 +981,7 @@
 
 
 LEAF(mips_cycle)
-	.set	noreorder	
+	.set	noreorder
 	.set	nomacro
 1:	bgtz	a0,1b
 	subu	a0,1
@@ -992,7 +992,7 @@
 
 LEAF(init_ns16550_chan_b)
 	# enable 16550 fifo if it is there
-        li      a0,NS16550_CHANB 
+        li      a0,NS16550_CHANB
         li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
 	sb	t0,FIFO(a0)
 
@@ -1002,25 +1002,25 @@
 	li	t0,CFCR_DLAB			# select brtc divisor
 	sb	t0,CFCR(a0)
 	sb	t2,DATA(a0)			# store divisor lsb
-	srl	t2,8	
+	srl	t2,8
 	sb	t2,IER(a0)			# store divisor msb
 
 	li	t0,CFCR_8BITS			# set 8N1 mode
 	sb	t0,CFCR(a0)
 
-	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS 
+	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS
   	sb	t0,MCR(a0)
- 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!) 
+ 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!)
 	sb	t0,IER(a0)
 
 	move	v0,zero				# indicate success
 	j	ra
-	
+
 END(init_ns16550_chan_b)
 
 LEAF(init_ns16550_chan_a)
 	# enable 16550 fifo if it is there
-        li      a0,NS16550_CHANA 
+        li      a0,NS16550_CHANA
         li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
 	sb	t0,FIFO(a0)
 
@@ -1030,20 +1030,20 @@
 	li	t0,CFCR_DLAB			# select brtc divisor
 	sb	t0,CFCR(a0)
 	sb	t2,DATA(a0)			# store divisor lsb
-	srl	t2,8	
+	srl	t2,8
 	sb	t2,IER(a0)			# store divisor msb
 
 	li	t0,CFCR_8BITS			# set 8N1 mode
 	sb	t0,CFCR(a0)
 
-	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS 
+	li	t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE	# enable DTR & RTS
   	sb	t0,MCR(a0)
- 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!) 
+ 	li	t0,0 # Galileo IER_ERXRDY			# enable receive interrupt(!)
 	sb	t0,IER(a0)
 
 	move	v0,zero				# indicate success
 	j	ra
-	
+
 END(init_ns16550_chan_a)
 
 #endif /* EVB64120A */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/dma.c linux-2.4.20/arch/mips/galileo-boards/ev64120/dma.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/dma.c	2002-10-04 00:41:14.000000000 +0000
@@ -6,7 +6,7 @@
 DESCRIPTION
 This file gives the user a complete interface to the powerful DMA engines,
 including functions for controling the priority mechanism.
-To fully understand the capabilities of the DMA engines please spare some 
+To fully understand the capabilities of the DMA engines please spare some
 time to go trough the spec.
 */
 
@@ -20,11 +20,11 @@
 #include "DMA.h"
 #endif
 /********************************************************************
-* dmaCommand - Write a command to a DMA channel 
+* dmaCommand - Write a command to a DMA channel
 *
 * Inputs: DMA_ENGINE channel - choosing one of the four engine.
 *         unsigned int command - The command to be written to the control register.
-* Returns: false if one of the parameters is erroneous else returns true. 
+* Returns: false if one of the parameters is erroneous else returns true.
 *********************************************************************/
 
 bool dmaCommand(DMA_ENGINE channel, unsigned int command)
@@ -39,14 +39,14 @@
 * dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel
 * Inputs:
 *   DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer,
-*   then this pointer should point to the next recored,otherwise it should be 
+*   then this pointer should point to the next recored,otherwise it should be
 *   NULL.
-*   VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes 
-*   aligned, the function will take care of that for you, but you need to 
+*   VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes
+*   aligned, the function will take care of that for you, but you need to
 *   allocate one more record for that, meaning: if you are having 3 records ,
 *   declare 4 (see the example bellow) and start using the second one.
 *   Example:
-*   Performing a chain mode DMA transfer(Copy a 1/4 mega of data using 
+*   Performing a chain mode DMA transfer(Copy a 1/4 mega of data using
 *   chain mode DMA):
 *    DMA_RECORED dmaRecoredArray[4];
 *    dmaRecoredArray[1].ByteCnt = _64KB;
@@ -149,10 +149,10 @@
 
 
 /********************************************************************
-* changeDmaPriority - update the arbiter`s priority for channels 0-3 
+* changeDmaPriority - update the arbiter`s priority for channels 0-3
 *
-* Inputs: priority  for channels 0-1, priority  for channels 2-3, 
-          priority for groups and other priority options   
+* Inputs: priority  for channels 0-1, priority  for channels 2-3,
+          priority for groups and other priority options
 * RETURNS: false if one of the parameters is erroneous and true else
 *********************************************************************/
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/i2o.c linux-2.4.20/arch/mips/galileo-boards/ev64120/i2o.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/i2o.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/i2o.c	2002-10-04 00:41:22.000000000 +0000
@@ -21,7 +21,7 @@
 *                     the CPU.
 *                     The messaging unit contains two sets of registers
 *                     so, actually it can receive a 64 bit message.
-* 
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: Data received from the remote agent.
@@ -37,12 +37,12 @@
 
 
 /********************************************************************
-* checkInboundIntAndClear - When a message is received an interrupt is 
+* checkInboundIntAndClear - When a message is received an interrupt is
 *                           generated, to enable polling instead the use of
 *                           an interrupt handler the user can use this fuction.
 *                           You will need to mask the incomming interrupt for
 *                           proper use.
-* 
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true if the corresponding bit in the cause register is set otherwise
@@ -76,9 +76,9 @@
 *                     the PCI agent.
 *                     The messaging unit contains two sets of registers
 *                     so, actually it can send a 64 bit message.
-* 
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
-*         unsigned int message - Message to be sent.   
+*         unsigned int message - Message to be sent.
 * OUTPUT: N/A.
 * RETURNS: true.
 *********************************************************************/
@@ -94,7 +94,7 @@
 * checkOutboundInt - When the CPU sends a message to the Outbound
 *                    register it generates an interrupt which is refelcted on
 *                    the Outbound Interrupt cause register, the interrupt can
-*                    be cleard only by the PCI agent which read the message. 
+*                    be cleard only by the PCI agent which read the message.
 *                    After sending the message you can acknowledge it by
 *                    monitoring the corresponding bit in the cause register.
 *
@@ -124,8 +124,8 @@
 /********************************************************************
 * maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking
 *                               the interrupt you can work in polling mode
-*                               using the checkInboundIntAndClear function. 
-* 
+*                               using the checkInboundIntAndClear function.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -146,8 +146,8 @@
 }
 
 /********************************************************************
-* enableInBoundMessageInterrupt - unMask the inbound interrupt. 
-* 
+* enableInBoundMessageInterrupt - unMask the inbound interrupt.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -170,8 +170,8 @@
 /********************************************************************
 * maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
 *                           the PCI agent needs to poll on the interrupt
-*                           cause register to monitor an incoming message. 
-* 
+*                           cause register to monitor an incoming message.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -194,8 +194,8 @@
 /********************************************************************
 * enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
 *                           the PCI agent needs to poll on the interrupt
-*                           cause register to monitor an incoming message. 
-* 
+*                           cause register to monitor an incoming message.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -216,13 +216,13 @@
 }
 
 /********************************************************************
-* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the 
+* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the
 *                       CPU generates a PCI interrupt (if it is not masked by
 *                       the Outbound interrupt Mask register)
 *                       Only the PCI agent which recieved the interrupt can
 *                       clear it, only after clearing all the bits the
 *                       interrupt will be de-asserted.
-* 
+*
 * INPUTS: unsigned int data - Requested interrupt bits.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -236,7 +236,7 @@
 /********************************************************************
 * readInBoundDoorBellInt - Read the in bound door bell interrupt cause
 *                          register.
-* 
+*
 * OUTPUT:  N/A.
 * RETURNS: The 32 bit interrupt cause register.
 *********************************************************************/
@@ -253,7 +253,7 @@
 *                           only by the CPU. The interrupt will be de-asserted
 *                           only if all the bits which where set by the PCI
 *                           agent are cleared.
-* 
+*
 * INPUTS:  unsigned int data - Bits to be cleared.
 * OUTPUT:  N/A.
 * RETURNS: true.
@@ -282,11 +282,11 @@
 }
 
 /********************************************************************
-* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is 
+* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is
 *                                  set, can be used for acknowledging interrupt
 *                                  handling by the agent who recieived the
-*                                  interrupt. 
-* 
+*                                  interrupt.
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true if the corresponding bit in the cause register is set otherwise
@@ -354,7 +354,7 @@
 
 /********************************************************************
 * circularQueueEnable - Initialize the I2O messaging mechanism.
-* 
+*
 * INPUTS:   CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the:
 *           Queue Control Register, Offset 0x50 (0x1c50).
 *           Defines the queues size (refer to the data sheet
@@ -364,7 +364,7 @@
 *           Inbound Free = queueBaseAddr
 *           Inbound Post = queueBaseAddr + cirQueSize
 *           Outbound Post = queueBaseAddr + cirQueSize
-*           
+*
 * OUTPUT:  N/A.
 * RETURNS: true.
 *
@@ -410,10 +410,10 @@
 }
 
 /********************************************************************
-* inBoundPostQueuePop - Two actions are being taken upon pop: 
+* inBoundPostQueuePop - Two actions are being taken upon pop:
 *           1) Getting out the data from the Queue`s head.
 *           2) Increment the tail pointer in a cyclic way (The HEAD is
-*              incremented automaticaly by the GT) 
+*              incremented automaticaly by the GT)
 *
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
@@ -469,7 +469,7 @@
 
 /********************************************************************
 * clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true.
@@ -486,7 +486,7 @@
 *
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
-* RETURNS: 
+* RETURNS:
 *********************************************************************/
 void maskInBoundPostQueueInterrupt()
 {
@@ -501,7 +501,7 @@
 /********************************************************************
 * enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new
 *                                   message from the PCI agent.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS:
@@ -516,11 +516,11 @@
 }
 
 /********************************************************************
-* inBoundFreeQueuePush - Two actions are being taken upon push: 
+* inBoundFreeQueuePush - Two actions are being taken upon push:
 *           1) Place the user`s data on the Queue`s head.
 *           2) Increment the haed pointer in a cyclic way (The tail is
 *              decremented automaticaly by the GT)
-* 
+*
 * INPUTS:  unsigned int data - Data to be placed in the queue.
 * OUTPUT:  N/A.
 * RETURNS: true.
@@ -558,7 +558,7 @@
 * isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty.
 *                           Can be used for acknowledging the messages
 *                           being sent by us to the PCI agent.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true if the queue is empty , otherwise false.
@@ -579,12 +579,12 @@
 }
 
 /********************************************************************
-* outBoundPostQueuePush  - Two actions are being taken upon push: 
+* outBoundPostQueuePush  - Two actions are being taken upon push:
 *           1) Place the user`s data on the Queue`s head.
 *           2) Increment the haed pointer in a cyclic way (The tail is
 *              decremented automaticaly by the GT when the Agent on the
 *              PCI have read data from the Outbound Port).
-* 
+*
 * INPUTS:  unsigned int data - Data to be placed in the queue`s head.
 * OUTPUT:  N/A.
 * RETURNS: true.
@@ -622,7 +622,7 @@
 * isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty.
 *                            Can be used for acknowledging the messages
 *                            being sent by us to the PCI agent.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true if the queue is empty , otherwise false.
@@ -643,11 +643,11 @@
 }
 
 /********************************************************************
-* outBoundFreeQueuePop - Two actions are being taken upon pop: 
+* outBoundFreeQueuePop - Two actions are being taken upon pop:
 *           1) Getting out the data from the Queue`s head.
 *           2) Increment the tail pointer in a cyclic way (The HEAD is
 *              incremented automaticaly by the GT)
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: Data pointed by tail.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/int-handler.S linux-2.4.20/arch/mips/galileo-boards/ev64120/int-handler.S
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/int-handler.S	2002-10-04 00:41:15.000000000 +0000
@@ -21,11 +21,11 @@
 		SAVE_ALL
 		CLI
 		.set	at
-		mfc0	t0,CP0_CAUSE  
+		mfc0	t0,CP0_CAUSE
 		mfc0	t2,CP0_STATUS
 
 		and	t0,t2
-        
+
 		andi	t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
 		bnez	t1,ll_galileo_irq
 		andi	t1,t0,STATUSF_IP2 /* int0 hardware line */
@@ -42,7 +42,7 @@
 		j	spurious_interrupt
 		nop
 		END(galileo_handle_int)
-	
+
 
 		.align	5
 		.set	reorder
@@ -57,7 +57,7 @@
 		.align	5
 		.set	reorder
 ll_compare_irq:
-		li 	a0,7	
+		li 	a0,7
 		move	a1,sp
 		jal	do_IRQ
 		nop
@@ -76,7 +76,7 @@
 #if 0
 		.align	5
 		.set	reorder
-ll_pci_intB:	
+ll_pci_intB:
 		move 	a0,sp
 		jal	pci_intB
 		nop
@@ -85,14 +85,14 @@
 
 		.align	5
 		.set	reorder
-ll_pci_intC:	
+ll_pci_intC:
 		move 	a0,sp
 		jal	pci_intC
 		nop
 		j	ret_from_irq
 		nop
 #endif
-        
+
 		.align	5
 		.set	reorder
 ll_pci_intD:
@@ -101,10 +101,10 @@
 		nop
 		j	ret_from_irq
 		nop
-	
+
 		.align	5
 		.set	reorder
-ll_serial_irq:	
+ll_serial_irq:
 		li	a0,6
 		move	a1,sp
 		jal	do_IRQ
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/irq-handler.c linux-2.4.20/arch/mips/galileo-boards/ev64120/irq-handler.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/irq-handler.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/irq-handler.c	2002-10-04 00:41:13.000000000 +0000
@@ -33,8 +33,8 @@
  * the interrupt service routine is called.
  *
  * Inputs :
- * int_cause - The interrupt cause number. In EVB64120 two parameters 
- *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. 
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
  * bit_num   - Indicates which bit number in the cause register
  * isr_ptr   - Pointer to the interrupt service routine
  *
@@ -52,7 +52,7 @@
  * Enables the IRQ on Galileo Chip
  *
  * Inputs :
- * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ * int_cause -  The interrupt cause number. In EVB64120 two parameters
  *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
  * bit_num   - Indicates which bit number in the cause register
  *
@@ -77,7 +77,7 @@
  * Disables the IRQ on Galileo Chip
  *
  * Inputs :
- * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ * int_cause -  The interrupt cause number. In EVB64120 two parameters
  *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
  * bit_num   - Indicates which bit number in the cause register
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/irq.c linux-2.4.20/arch/mips/galileo-boards/ev64120/irq.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/irq.c	2002-10-04 00:41:19.000000000 +0000
@@ -65,7 +65,7 @@
 /*  Duplicate interrupt handlers.  */
 /********************************************************************
  *pci_int(A/B/C/D) -
- *	
+ *
  *Calls all the handlers connected to PCI interrupt A/B/C/D
  *
  *Inputs :
@@ -175,7 +175,7 @@
 	end:no_irq_enable_disable,
 };
 
-//      ack:            no_irq_ack,                re-enable later -- SKJ  
+//      ack:            no_irq_ack,                re-enable later -- SKJ
 
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/pci_bios.c linux-2.4.20/arch/mips/galileo-boards/ev64120/pci_bios.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/pci_bios.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/pci_bios.c	2002-10-04 00:41:14.000000000 +0000
@@ -441,7 +441,7 @@
  * pci_range_ck -
  *
  * Check if the pci device that are trying to access does really exists
- * on the evaluation board.  
+ * on the evaluation board.
  *
  * Inputs :
  * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
@@ -455,18 +455,18 @@
 	//DBG(KERN_INFO "p_r_c %d %d\n",bus,dev);
 	if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
 		return 0;	// Bus/Device Number OK
-	return -1;		// Bus/Device Number not OK  
+	return -1;		// Bus/Device Number not OK
 }
 
 /*
  * pciXReadConfigReg  - Read from a PCI configuration register
- *                    - Make sure the GT is configured as a master before 
+ *                    - Make sure the GT is configured as a master before
  *                      reading from another device on the PCI.
  *                   - The function takes care of Big/Little endian conversion.
  * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
  *                        spec)
- *           pciDevNum: The device number needs to be addressed.                
- * RETURNS: data , if the data == 0xffffffff check the master abort bit in the 
+ *           pciDevNum: The device number needs to be addressed.
+ * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  *                 cause register to make sure the data is valid
  *
  *  Configuration Address 0xCF8:
@@ -518,7 +518,7 @@
 	   to stabilize, so the READ can work.
 	 */
 	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* when configurating our own PCI 1 L-unit the access is through
 		   the PCI 0 interface with reg number = reg number + 0x80 */
 		DataForRegCf8 |= 0x80;
 		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
@@ -538,13 +538,13 @@
 
 /*
  * pciXWriteConfigReg - Write to a PCI configuration register
- *                    - Make sure the GT is configured as a master before 
+ *                    - Make sure the GT is configured as a master before
  *                      writingto another device on the PCI.
  *                    - The function takes care of Big/Little endian conversion.
  * Inputs:   unsigned int regOffset: The register offset as it apears in the
- *           GT spec 
+ *           GT spec
  *                   (or any other PCI device spec)
- *           pciDevNum: The device number needs to be addressed.                
+ *           pciDevNum: The device number needs to be addressed.
  *
  *  Configuration Address 0xCF8:
  *
@@ -584,7 +584,7 @@
 	   to stabilize, so the WRITE can work.
 	 */
 	if (PCI_SLOT(device->devfn) == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* when configurating our own PCI 1 L-unit the access is through
 		   the PCI 0 interface with reg number = reg number + 0x80 */
 		DataForRegCf8 |= 0x80;
 		GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
@@ -906,7 +906,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/promcon.c linux-2.4.20/arch/mips/galileo-boards/ev64120/promcon.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/promcon.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/promcon.c	2002-10-04 00:41:19.000000000 +0000
@@ -5,7 +5,7 @@
  * Copyright (c) 1999 Ulf Carlsson
  *
  * Derived from DECstation promcon.c
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
  */
 #include <linux/tty.h>
 #include <linux/major.h>
@@ -51,8 +51,8 @@
 
 void gal_serial_console_init(void)
 {
-	//  serial_init(); 
-	//serial_set(115200); 
+	//  serial_init();
+	//serial_set(115200);
 
 	register_console(&sercons);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/serialGT.c linux-2.4.20/arch/mips/galileo-boards/ev64120/serialGT.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/serialGT.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/serialGT.c	2002-10-04 00:41:21.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * BRIEF MODULE DESCRIPTION
  *  Low Level Serial Port control for use
- *  with the Galileo EVB64120A MIPS eval board and 
+ *  with the Galileo EVB64120A MIPS eval board and
  *  its on board two channel 16552 Uart.
  *
  * Copyright (C) 2000 RidgeRun, Inc.
@@ -139,7 +139,7 @@
 
 #if 0
 	/*
-	 * Set baud rate 
+	 * Set baud rate
 	 */
 	outreg(channel, LCR, LCR_DLAB | sav_lcr);
 	//  outreg(DLL,(XTAL/(16*2*(baud))-2));
@@ -149,7 +149,7 @@
 #else
 	/*
 	 * Note: Set baud rate, hardcoded here for rate of 115200
-	 * since became unsure of above "buad rate" algorithm (??). 
+	 * since became unsure of above "buad rate" algorithm (??).
 	 */
 	outreg(channel, LCR, 0x83);
 	outreg(channel, DLM, 0x00);	// See note above
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev64120/setup.c linux-2.4.20/arch/mips/galileo-boards/ev64120/setup.c
--- linux-2.4.19/arch/mips/galileo-boards/ev64120/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev64120/setup.c	2002-10-04 00:41:09.000000000 +0000
@@ -61,7 +61,7 @@
 extern void galileo_machine_restart(char *command);
 extern void galileo_machine_halt(void);
 extern void galileo_machine_power_off(void);
-/* 
+/*
  *This structure holds pointers to the pci configuration space accesses
  *and interrupts allocating routine for device over the PCI
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/init.c linux-2.4.20/arch/mips/galileo-boards/ev96100/init.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/init.c	2002-10-04 00:41:15.000000000 +0000
@@ -3,7 +3,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/generic.c
  *
  * Carsten Langgaard, carstenl@mips.com
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/irq.c linux-2.4.20/arch/mips/galileo-boards/ev96100/irq.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/irq.c	2002-10-04 00:41:17.000000000 +0000
@@ -3,7 +3,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_int.c.
  *
  * Carsten Langgaard, carstenl@mips.com
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/pci_fixups.c linux-2.4.20/arch/mips/galileo-boards/ev96100/pci_fixups.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/pci_fixups.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/pci_fixups.c	2002-10-04 00:41:14.000000000 +0000
@@ -72,19 +72,19 @@
 		pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
 
 #ifdef DEBUG
-		printk("devfn %x, slot %d devid %x\n", 
+		printk("devfn %x, slot %d devid %x\n",
 				dev->devfn, slot, gt_devid);
 #endif
 
 		/* fixup irq line based on slot # */
 		if (slot == 8) {
 			dev->irq = 5;
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
 					dev->irq);
 		}
 		else if (slot == 9) {
 			dev->irq = 2;
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
 					dev->irq);
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/pci_ops.c linux-2.4.20/arch/mips/galileo-boards/ev96100/pci_ops.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/pci_ops.c	2002-10-04 00:41:09.000000000 +0000
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/pci.c
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -63,13 +63,13 @@
 #define GT_PCI_IO_BASE     0x10000000
 #define GT_PCI_IO_SIZE     0x02000000
 static struct resource pci_io_resource = {
-	"io pci IO space", 
+	"io pci IO space",
 	0x10000000,
 	0x10000000 + 0x02000000,
 	IORESOURCE_IO};
 
 static struct resource pci_mem_resource = {
-	"ext pci memory space", 
+	"ext pci memory space",
 	0x12000000,
 	0x12000000 + 0x02000000,
 	IORESOURCE_MEM};
@@ -95,11 +95,11 @@
         }
 
 	/* Clear cause register bits */
-	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 	                             GT_INTRCAUSE_TARABORT0_BIT));
 
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
 		 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 		 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 		 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
@@ -112,7 +112,7 @@
 		*data = le32_to_cpu(*data);
 		}
 		GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
-	} 
+	}
         else {
 		GT_READ(GT_PCI0_CFGDATA_OFS, *data);
 		if (dev_fn != 0) {
@@ -131,7 +131,7 @@
 	        /* Error occured */
 
 	        /* Clear bits */
-	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 					      GT_INTRCAUSE_TARABORT0_BIT) );
 
 		if (access_type == PCI_ACCESS_READ) {
@@ -158,7 +158,7 @@
 	}
 
 	*val = (data >> ((where & 3) << 3)) & 0xff;
-        DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, *val);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -179,7 +179,7 @@
 	}
 
 	*val = (data >> ((where & 3) << 3)) & 0xffff;
-        DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, *val);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -192,14 +192,14 @@
 
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	
+
 	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
 		*val = 0xffffffff;
 		return -1;
 	}
 
 	*val = data;
-        DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, *val);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -210,13 +210,13 @@
 write_config_byte (struct pci_dev *dev, int where, u8 val)
 {
 	u32 data = 0;
-       
+
 	if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
 	data = (data & ~(0xff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
-        DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, val);
 
 	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
@@ -232,13 +232,13 @@
 
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-       
+
         if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
 	       return -1;
 
-	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
-        DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, val);
 
 	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
@@ -256,7 +256,7 @@
 
 	if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
 	       return -1;
-        DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n", 
+        DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, val);
 
 	return PCIBIOS_SUCCESSFUL;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.20/arch/mips/galileo-boards/ev96100/setup.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/setup.c	2002-10-04 00:41:30.000000000 +0000
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_setup.c.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -52,8 +52,6 @@
 #include <asm/galileo-boards/ev96100int.h>
 
 
-void (*__wbflush) (void);
-
 #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
 extern void console_setup(char *, int *);
 char serial_console[20];
@@ -65,11 +63,6 @@
 extern struct rtc_ops no_rtc_ops;
 extern struct resource ioport_resource;
 
-static void rm7000_wbflush(void)
-{
-	 __asm__ __volatile__ ("sync");
-}
-
 unsigned char mac_0_1[12];
 
 
@@ -83,7 +76,6 @@
 	char *argptr;
 
 	clear_cp0_status(ST0_FR);
-        __wbflush = rm7000_wbflush;
 
         if (config & 0x8) {
             printk("Secondary cache is enabled\n");
@@ -144,7 +136,7 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#endif
 
 	rtc_ops = &no_rtc_ops;
 	mips_reboot_setup();
@@ -157,15 +149,15 @@
 #endif
 
 
-	/* 
-	 * setup gt controller master bit so we can do config cycles 
+	/*
+	 * setup gt controller master bit so we can do config cycles
 	 */
 
 	/* Clear cause register bits */
-	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 	                             GT_INTRCAUSE_TARABORT0_BIT));
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
 		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
@@ -174,9 +166,9 @@
 	udelay(2);
 	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
 
-	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
 		PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
 		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
@@ -185,7 +177,7 @@
 	*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp);
 
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
 		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
@@ -195,12 +187,12 @@
 	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
 }
 
-unsigned short get_gt_devid() 
+unsigned short get_gt_devid()
 {
 	u32 gt_devid;
 
 	/* Figure out if this is a gt96100 or gt96100A */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	GT_WRITE(GT_PCI0_CFGADDR_OFS,
 		 (0      << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 		 (0      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 		 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/ev96100/time.c linux-2.4.20/arch/mips/galileo-boards/ev96100/time.c
--- linux-2.4.19/arch/mips/galileo-boards/ev96100/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/ev96100/time.c	2002-10-04 00:41:18.000000000 +0000
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_rtc.c.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -67,9 +67,9 @@
 
 
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the RTC to calculate offset.
  */
 static unsigned long __init cal_r4koff(void)
@@ -104,10 +104,10 @@
 
 	r4k_offset = cal_r4koff();
 
-	est_freq = 2*r4k_offset*HZ;	
+	est_freq = 2*r4k_offset*HZ;
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
 	       (est_freq%1000000)*100/1000000);
 	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
 
@@ -184,7 +184,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * Due to possible jiffies inconsistencies, we need to check
 	 * the result so that we'll get a timer that is monotonic.
 	 */
 	if (res >= USECS_PER_JIFFY)
@@ -260,7 +260,7 @@
 		r4k_cur += r4k_offset;
 		ack_r4ktimer(r4k_cur);
 
-	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) 
+	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
                     - r4k_cur) < 0x7fffffff);
 	return;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/generic/Makefile linux-2.4.20/arch/mips/galileo-boards/generic/Makefile
--- linux-2.4.19/arch/mips/galileo-boards/generic/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/generic/Makefile	2002-10-04 00:41:20.000000000 +0000
@@ -7,12 +7,12 @@
 # This program is free software; you can distribute it and/or modify it
 # under the terms of the GNU General Public License (Version 2) as
 # published by the Free Software Foundation.
-# 
+#
 # This program is distributed in the hope 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.,
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/galileo-boards/generic/reset.c linux-2.4.20/arch/mips/galileo-boards/generic/reset.c
--- linux-2.4.19/arch/mips/galileo-boards/generic/reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/galileo-boards/generic/reset.c	2002-10-04 00:41:20.000000000 +0000
@@ -6,7 +6,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/reset.c
  *
  * Carsten Langgaard, carstenl@mips.com
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/gt64120/common/pci.c linux-2.4.20/arch/mips/gt64120/common/pci.c
--- linux-2.4.19/arch/mips/gt64120/common/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/gt64120/common/pci.c	2002-10-04 00:41:20.000000000 +0000
@@ -886,7 +886,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/Makefile linux-2.4.20/arch/mips/kernel/Makefile
--- linux-2.4.19/arch/mips/kernel/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/Makefile	2002-10-04 00:41:17.000000000 +0000
@@ -12,13 +12,12 @@
 
 O_TARGET := kernel.o
 
-export-objs			= irq.o pci-dma.o setup.o smp.o mips_ksyms.o \
-				  old-irq.o
+export-objs	= irq.o pci-dma.o setup.o smp.o mips_ksyms.o old-irq.o
+
+obj-y		+= branch.o cpu-probe.o process.o signal.o entry.o traps.o \
+		   ptrace.o vm86.o ioport.o reset.o semaphore.o setup.o \
+		   syscall.o sysmips.o ipc.o scall_o32.o unaligned.o
 
-obj-y				+= branch.o process.o signal.o entry.o \
-				   traps.o ptrace.o vm86.o ioport.o reset.o \
-				   semaphore.o setup.o syscall.o sysmips.o \
-				   ipc.o scall_o32.o unaligned.o
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o
 
 obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
@@ -54,14 +53,14 @@
 
 obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
 				   irixinv.o
-obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-low.o gdb-stub.o 
+obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-low.o gdb-stub.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
 
 obj-$(CONFIG_NEW_PCI)		+= pci.o
+obj-$(CONFIG_PCI_AUTO)		+= pci_auto.o
 ifndef CONFIG_MAPPED_PCI_IO
 obj-y				+= pci-dma.o
 endif
-obj-$(CONFIG_PCI_AUTO)		+= pci_auto.o
 
 entry.o: entry.S
 head.o: head.S
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/cpu-probe.c linux-2.4.20/arch/mips/kernel/cpu-probe.c
--- linux-2.4.19/arch/mips/kernel/cpu-probe.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/cpu-probe.c	2002-10-04 00:41:18.000000000 +0000
@@ -0,0 +1,489 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void) = NULL;
+
+static void r3081_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
+static void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+void au1k_wait(void)
+{
+#ifdef CONFIG_PM
+	/* using the wait instruction makes CP0 counter unusable */
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
+#else
+	__asm__("nop\n\t" "nop\n\t");
+#endif
+}
+
+static inline void check_wait(void)
+{
+	printk("Checking for 'wait' instruction... ");
+	switch(mips_cpu.cputype) {
+	case CPU_R3081:
+	case CPU_R3081E:
+		cpu_wait = r3081_wait;
+		printk(" available.\n");
+		break;
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		cpu_wait = r39xx_wait;
+		printk(" available.\n");
+		break;
+	case CPU_R4200:
+/*	case CPU_R4300: */
+	case CPU_R4600:
+	case CPU_R4640:
+	case CPU_R4650:
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+	case CPU_RM7000:
+	case CPU_TX49XX:
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+/*	case CPU_20KC:*/
+		cpu_wait = r4k_wait;
+		printk(" available.\n");
+		break;
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+		cpu_wait = au1k_wait;
+		printk(" available.\n");
+		break;
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+void __init check_bugs(void)
+{
+	check_wait();
+}
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+	extern unsigned long r3k_cache_size(unsigned long);
+	unsigned long size1, size2;
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+
+	size1 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
+	size2 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg);
+	return size1 != size2;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+	unsigned long tmp, fpu_id;
+
+	tmp = read_32bit_cp0_register(CP0_STATUS);
+	__enable_fpu();
+	fpu_id = read_32bit_cp1_register(CP1_REVISION);
+	write_32bit_cp0_register(CP0_STATUS, tmp);
+	return fpu_id;
+}
+
+/*
+ * Check the CPU has an FPU the official way.
+ */
+static inline int cpu_has_fpu(void)
+{
+	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+}
+
+/* declaration of the global struct */
+struct mips_cpu mips_cpu = {
+    processor_id:	PRID_IMP_UNKNOWN,
+    fpu_id:		FPIR_IMP_NONE,
+    cputype:		CPU_UNKNOWN
+};
+
+/* Shortcut for assembler access to mips_cpu.options */
+int *cpuoptions = &mips_cpu.options;
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
+__init void cpu_probe(void)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long config1;
+
+        if (config0 & (1 << 31)) {
+		/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+			mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+			mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & (1 << 1))
+			mips_cpu.options |= MIPS_CPU_EJTAG;
+		if (config1 & 1) {
+			mips_cpu.options |= MIPS_CPU_FPU;
+#if defined(CONFIG_CPU_MIPS64)
+			mips_cpu.options |= MIPS_CPU_32FPR;
+#endif
+		}
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+	}
+#endif
+	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
+	switch (mips_cpu.processor_id & 0xff0000) {
+	case PRID_COMP_LEGACY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_R2000:
+			mips_cpu.cputype = CPU_R2000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R3000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
+				if (cpu_has_confreg())
+					mips_cpu.cputype = CPU_R3081E;
+				else
+					mips_cpu.cputype = CPU_R3000A;
+			else
+				mips_cpu.cputype = CPU_R3000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R4000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
+				mips_cpu.cputype = CPU_R4400SC;
+			else
+				mips_cpu.cputype = CPU_R4000SC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
+			                   MIPS_CPU_VCE;
+			mips_cpu.tlbsize = 48;
+			break;
+                case PRID_IMP_VR41XX:
+			switch (mips_cpu.processor_id & 0xf0) {
+#ifndef CONFIG_VR4181
+			case PRID_REV_VR4111:
+				mips_cpu.cputype = CPU_VR4111;
+				break;
+#else
+			case PRID_REV_VR4181:
+				mips_cpu.cputype = CPU_VR4181;
+				break;
+#endif
+			case PRID_REV_VR4121:
+				mips_cpu.cputype = CPU_VR4121;
+				break;
+			case PRID_REV_VR4122:
+				if ((mips_cpu.processor_id & 0xf) < 0x3)
+					mips_cpu.cputype = CPU_VR4122;
+				else
+					mips_cpu.cputype = CPU_VR4181A;
+				break;
+			case PRID_REV_VR4131:
+				mips_cpu.cputype = CPU_VR4131;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+				break;
+			default:
+				printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+				mips_cpu.cputype = CPU_VR41XX;
+				break;
+			}
+                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
+                        mips_cpu.options = R4K_OPTS;
+                        mips_cpu.tlbsize = 32;
+                        break;
+		case PRID_IMP_R4300:
+			mips_cpu.cputype = CPU_R4300;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+					   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R4600:
+			mips_cpu.cputype = CPU_R4600;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 48;
+			break;
+		#if 0
+ 		case PRID_IMP_R4650:
+			/*
+			 * This processor doesn't have an MMU, so it's not
+			 * "real easy" to run Linux on it. It is left purely
+			 * for documentation.  Commented out because it shares
+			 * it's c0_prid id number with the TX3900.
+			 */
+	 		mips_cpu.cputype = CPU_R4650;
+		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+		        mips_cpu.tlbsize = 48;
+			break;
+		#endif
+		case PRID_IMP_TX39:
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB;
+
+			if ((mips_cpu.processor_id & 0xf0) ==
+			    (PRID_REV_TX3927 & 0xf0)) {
+				mips_cpu.cputype = CPU_TX3927;
+				mips_cpu.tlbsize = 64;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+			} else {
+				switch (mips_cpu.processor_id & 0xff) {
+				case PRID_REV_TX3912:
+					mips_cpu.cputype = CPU_TX3912;
+					mips_cpu.tlbsize = 32;
+					break;
+				case PRID_REV_TX3922:
+					mips_cpu.cputype = CPU_TX3922;
+					mips_cpu.tlbsize = 64;
+					break;
+				default:
+					mips_cpu.cputype = CPU_UNKNOWN;
+					break;
+				}
+			}
+			break;
+		case PRID_IMP_R4700:
+			mips_cpu.cputype = CPU_R4700;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_TX49:
+			mips_cpu.cputype = CPU_TX49XX;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 4;
+			mips_cpu.dcache.ways = 4;
+			break;
+		case PRID_IMP_R5000:
+			mips_cpu.cputype = CPU_R5000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5432:
+			mips_cpu.cputype = CPU_R5432;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5500:
+			mips_cpu.cputype = CPU_R5500;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_NEVADA:
+			mips_cpu.cputype = CPU_NEVADA;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 2;
+			mips_cpu.dcache.ways = 2;
+			break;
+		case PRID_IMP_R6000:
+			mips_cpu.cputype = CPU_R6000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R6000A:
+			mips_cpu.cputype = CPU_R6000A;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_RM7000:
+			mips_cpu.cputype = CPU_RM7000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			/*
+			 * Undocumented RM7000:  Bit 29 in the info register of
+			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
+			 * entries.
+			 *
+			 * 29      1 =>    64 entry JTLB
+			 *         0 =>    48 entry JTLB
+			 */
+			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
+			break;
+		case PRID_IMP_R8000:
+			mips_cpu.cputype = CPU_R8000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 384;      /* has weird TLB: 3-way x 128 */
+			break;
+		case PRID_IMP_R10000:
+			mips_cpu.cputype = CPU_R10000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR |
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R12000:
+			mips_cpu.cputype = CPU_R12000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR |
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	case PRID_COMP_MIPS:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_4KC:
+			mips_cpu.cputype = CPU_4KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KEC:
+			mips_cpu.cputype = CPU_4KEC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KSC:
+			mips_cpu.cputype = CPU_4KSC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_5KC:
+			mips_cpu.cputype = CPU_5KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		case PRID_IMP_20KC:
+			mips_cpu.cputype = CPU_20KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	case PRID_COMP_ALCHEMY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			switch ((mips_cpu.processor_id >> 24) & 0xff) {
+			case 0:
+ 				mips_cpu.cputype = CPU_AU1000;
+				break;
+			case 1:
+				mips_cpu.cputype = CPU_AU1500;
+				break;
+			case 2:
+				mips_cpu.cputype = CPU_AU1100;
+				break;
+			default:
+				panic("Unknown Au Core!");
+				break;
+			}
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+ 			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+#endif /* CONFIG_CPU_MIPS32 */
+	case PRID_COMP_SIBYTE:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_SB1:
+			mips_cpu.cputype = CPU_SB1;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+			                   MIPS_CPU_MCHECK;
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+			/* FPU in pass1 is known to have issues. */
+			mips_cpu.options |= MIPS_CPU_FPU;
+#endif
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		mips_cpu.cputype = CPU_UNKNOWN;
+	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
+}
+
+__init void cpu_report(void)
+{
+	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/entry.S linux-2.4.20/arch/mips/kernel/entry.S
--- linux-2.4.19/arch/mips/kernel/entry.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/entry.S	2002-10-04 00:41:12.000000000 +0000
@@ -26,48 +26,29 @@
 #include <asm/unistd.h>
 #include <asm/isadep.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002		/* tracing system calls */
-
 
 		.text
 		.align 4
 		.set	push
 		.set	reorder
-EXPORT(ret_from_fork)
-		move	a0, v0			# prev
-		jal	schedule_tail
-		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
-		bnez	t0, tracesys_exit
-		j	ret_from_sys_call
-
-tracesys_exit:	jal	syscall_trace
-		b	ret_from_sys_call
-
-EXPORT(ret_from_irq)
-EXPORT(ret_from_exception)
+FEXPORT(ret_from_irq)
+FEXPORT(ret_from_exception)
 		lw	t0, PT_STATUS(sp)	# returning to kernel mode?
 		andi	t0, t0, KU_USER
-		bnez	t0, ret_from_sys_call
-		j	restore_all
-
-reschedule:	jal	schedule 
-
-EXPORT(ret_from_sys_call)
-		.type	ret_from_irq,@function
+		beqz	t0, restore_all
 
+FEXPORT(ret_from_sys_call)		# here to prevent code duplication
+ret_from_schedule:
 		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
-		nop; nop; nop
+		SSNOP; SSNOP; SSNOP
 
 		lw	v0, TASK_NEED_RESCHED($28)
 		lw	v1, TASK_SIGPENDING($28)
 		bnez	v0, reschedule
 		bnez	v1, signal_return
-		FEXPORT(restore_all)
 restore_all:	.set	noat
 		RESTORE_ALL_AND_RET
 		.set	at
@@ -85,6 +66,10 @@
 		jal	do_signal
 		b	restore_all
 
+reschedule:
+		jal	schedule
+		b	ret_from_schedule
+
 /*
  * Common spurious interrupt handler.
  */
@@ -100,35 +85,38 @@
 		addiu   t0,1
 		sw      t0,%lo(irq_err_count)(t1)
 		j	ret_from_irq
-		END(spurious_interrupt)
+END(spurious_interrupt)
 
 		__INIT
 
 		.set	reorder
 
-		NESTED(except_vec1_generic, 0, sp)
+NESTED(except_vec1_generic, 0, sp)
 		PANIC("Exception vector 1 called")
-		END(except_vec1_generic)
+END(except_vec1_generic)
 
 		/*
 		 * General exception vector.  Used for all CPUs except R4000
 		 * and R4400 SC and MC versions.
 		 */
-		NESTED(except_vec3_generic, 0, sp)
+NESTED(except_vec3_generic, 0, sp)
 		mfc0	k1, CP0_CAUSE
 		la	k0, exception_handlers
 		andi	k1, k1, 0x7c
 		addu	k0, k0, k1
 		lw	k0, (k0)
 		jr	k0
-		END(except_vec3_generic)
+END(except_vec3_generic)
 		.set	at
 
 		/* General exception vector R4000 version. */
-		NESTED(except_vec3_r4000, 0, sp)
+NESTED(except_vec3_r4000, 0, sp)
 		.set	push
 		.set    mips3
 		.set	noat
+#if defined(R5432_CP0_INTERRUPT_WAR)
+		mfc0	k0, CP0_INDEX
+#endif
 		mfc0	k1, CP0_CAUSE
 		li	k0, 31<<2
 		andi	k1, k1, 0x7c
@@ -174,7 +162,7 @@
 #endif
 		eret
 		.set    pop
-		END(except_vec3_r4000)
+END(except_vec3_r4000)
 
 		__FINIT
 
@@ -221,10 +209,10 @@
 		.previous;
 #define BUILD_HANDLER(exception,handler,clear,verbose)                  \
 		.align	5;                                              \
-		NESTED(handle_##exception, PT_SIZE, sp);                \
+NESTED(handle_##exception, PT_SIZE, sp);		                \
 		.set	noat;                                           \
 		SAVE_ALL;                                               \
-		FEXPORT(handle_##exception##_int);			\
+FEXPORT(handle_##exception##_int);					\
 		__BUILD_clear_##clear(exception);                       \
 		.set	at;                                             \
 		__BUILD_##verbose(exception);                           \
@@ -232,7 +220,7 @@
 		 move	a0, sp;                                         \
 		j	ret_from_exception;                             \
 		 nop;                                                   \
-		END(handle_##exception)
+END(handle_##exception)
 
 		BUILD_HANDLER(adel,ade,ade,silent)		/* #4  */
 		BUILD_HANDLER(ades,ade,ade,silent)		/* #5  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/gdb-low.S linux-2.4.20/arch/mips/kernel/gdb-low.S
--- linux-2.4.19/arch/mips/kernel/gdb-low.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/gdb-low.S	2002-10-04 00:41:13.000000000 +0000
@@ -97,7 +97,7 @@
 		sw	ra,GDB_FR_REG31(sp)
 
 		CLI				/* disable interrupts */
-		
+
 /*
  * Followed by the floating point registers
  */
@@ -211,7 +211,7 @@
 		lw	v0,GDB_FR_CP0_CONTEXT(sp)
 		mtc0	v1,CP0_INDEX
 		mtc0	v0,CP0_CONTEXT
-		
+
 
 /*
  * Next, the floating point registers
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/gdb-stub.c linux-2.4.20/arch/mips/kernel/gdb-stub.c
--- linux-2.4.19/arch/mips/kernel/gdb-stub.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/gdb-stub.c	2002-10-04 00:41:30.000000000 +0000
@@ -62,7 +62,7 @@
  * Host:                  Reply:
  * $m0,10#2a               +$00010203040506070809101112131415#42
  *
- * 
+ *
  *  ==============
  *  MORE EXAMPLES:
  *  ==============
@@ -72,11 +72,11 @@
  *  going. In this scenario the host machine was a PC and the
  *  target platform was a Galileo EVB64120A MIPS evaluation
  *  board.
- *   
+ *
  *  Step 1:
  *  First download gdb-5.0.tar.gz from the internet.
  *  and then build/install the package.
- * 
+ *
  *  Example:
  *    $ tar zxf gdb-5.0.tar.gz
  *    $ cd gdb-5.0
@@ -85,35 +85,35 @@
  *    $ install
  *    $ which mips-linux-elf-gdb
  *    /usr/local/bin/mips-linux-elf-gdb
- * 
+ *
  *  Step 2:
  *  Configure linux for remote debugging and build it.
- * 
+ *
  *  Example:
  *    $ cd ~/linux
  *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
  *    $ make dep; make vmlinux
- * 
+ *
  *  Step 3:
  *  Download the kernel to the remote target and start
- *  the kernel running. It will promptly halt and wait 
+ *  the kernel running. It will promptly halt and wait
  *  for the host gdb session to connect. It does this
- *  since the "Kernel Hacking" option has defined 
+ *  since the "Kernel Hacking" option has defined
  *  CONFIG_REMOTE_DEBUG which in turn enables your calls
  *  to:
  *     set_debug_traps();
  *     breakpoint();
- * 
+ *
  *  Step 4:
  *  Start the gdb session on the host.
- * 
+ *
  *  Example:
  *    $ mips-linux-elf-gdb vmlinux
  *    (gdb) set remotebaud 115200
  *    (gdb) target remote /dev/ttyS1
- *    ...at this point you are connected to 
+ *    ...at this point you are connected to
  *       the remote target and can use gdb
- *       in the normal fasion. Setting 
+ *       in the normal fasion. Setting
  *       breakpoints, single stepping,
  *       printing variables, etc.
  *
@@ -213,7 +213,7 @@
 		checksum = 0;
 		xmitcsum = -1;
 		count = 0;
-	
+
 		/*
 		 * now, read until a # or end of buffer is found
 		 */
@@ -378,7 +378,7 @@
 	save_and_cli(flags);
 	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
 		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
-  
+
 	putDebugChar('+'); /* 'hello world' */
 	/*
 	 * In case GDB is started before us, ack any packets
@@ -547,7 +547,7 @@
 		targ += 4 + (insn.i_format.simmediate << 2);
 		break;
 	}
-				
+
 	if (is_branch) {
 		i = 0;
 		if (is_cond && targ != (regs->cp0_epc + 8)) {
@@ -567,7 +567,7 @@
 
 /*
  *  If asynchronously interrupted by gdb, then we need to set a breakpoint
- *  at the interrupted instruction so that we wind up stopped with a 
+ *  at the interrupted instruction so that we wind up stopped with a
  *  reasonable stack frame.
  */
 static struct gdb_bp_save async_bp;
@@ -595,11 +595,11 @@
 	char *ptr;
 	unsigned long *stack;
 
-#if 0	
+#if 0
 	printk("in handle_exception()\n");
 	show_gdbregs(regs);
 #endif
-	
+
 	/*
 	 * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1,
 	 * the simply switch the FPU on and return since this is no error
@@ -619,7 +619,7 @@
 	/*
 	 * If we're in breakpoint() increment the PC
 	 */
-	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)		
+	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
 		regs->cp0_epc += 4;
 
 	/*
@@ -629,7 +629,7 @@
 	if (step_bp[0].addr) {
 		*(unsigned *)step_bp[0].addr = step_bp[0].val;
 		step_bp[0].addr = 0;
-		    
+
 		if (step_bp[1].addr) {
 			*(unsigned *)step_bp[1].addr = step_bp[1].val;
 			step_bp[1].addr = 0;
@@ -723,7 +723,7 @@
 			ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*4, 0); /* frp */
 			ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*4, 0); /* cp0 */
 			break;
-	  
+
 		/*
 		 * set the value of the CPU registers - return OK
 		 * FIXME: Needs to be written
@@ -769,7 +769,7 @@
 		/*
 		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
 		 */
-		case 'M': 
+		case 'M':
 			ptr = &input_buffer[1];
 
 			if (hexToInt(&ptr, &addr)
@@ -788,13 +788,13 @@
 		/*
 		 * cAA..AA    Continue at address AA..AA(optional)
 		 */
-		case 'c':    
+		case 'c':
 			/* try to read optional parameter, pc unchanged if no parm */
 
 			ptr = &input_buffer[1];
 			if (hexToInt(&ptr, &addr))
 				regs->cp0_epc = addr;
-	  
+
 			/*
 			 * Need to flush the instruction cache here, as we may
 			 * have deposited a breakpoint, and the icache probably
@@ -843,7 +843,7 @@
 		 */
 		case 'b':
 		{
-#if 0				
+#if 0
 			int baudrate;
 			extern void set_timer_3();
 
@@ -934,7 +934,7 @@
 		int i = (l>8)?8:l;
 		mem2hex((char *)str, &outbuf[1], i, 0);
 		outbuf[(i*2)+1]=0;
-		putpacket(outbuf); 
+		putpacket(outbuf);
 		str += i;
 		l -= i;
 	}
@@ -962,5 +962,5 @@
 {
 	register_console(&gdb_console);
 }
-     
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/head.S linux-2.4.20/arch/mips/kernel/head.S
--- linux-2.4.19/arch/mips/kernel/head.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/head.S	2002-10-04 00:41:11.000000000 +0000
@@ -35,6 +35,10 @@
 		 */
 		.fill	0x400
 
+		/* The following two symbols are used for kernel profiling. */
+		EXPORT(stext)
+		EXPORT(_stext)
+
 		__INIT
 
 		/* Cache Error */
@@ -81,7 +85,7 @@
 		 * The EJTAG debug exception entry point is 0xbfc00480, which
 		 * normally is in the boot PROM, so the boot PROM must do a
 		 * unconditional jump to this vector.
-		 */	
+		 */
 		NESTED(except_vec_ejtag_debug, 0, sp)
 		j	ejtag_debug_handler
 		 nop
@@ -94,7 +98,7 @@
 		.set	noat
 		.set	noreorder
 		mtc0	k0, CP0_DESAVE
-		mfc0	k0, CP0_DEBUG	
+		mfc0	k0, CP0_DEBUG
 
 		sll	k0, k0, 30	# Check for SDBBP.
 		bgez	k0, ejtag_return
@@ -106,15 +110,15 @@
 		 move	a0, sp
 		RESTORE_ALL
 		la	k0, ejtag_debug_buffer
-		lw	k1, 0(k0)	
+		lw	k1, 0(k0)
 
 ejtag_return:
-		mfc0	k0, CP0_DESAVE	
+		mfc0	k0, CP0_DESAVE
 		.word	0x4200001f     # DERET, return from EJTAG debug exception.
 		 nop
 		.set	at
 		END(ejtag_debug_handler)
-	
+
 		/*
 		* NMI debug exception handler for MIPS reference boards.
 		* The NMI debug exception entry point is 0xbfc00000, which
@@ -137,16 +141,13 @@
 		eret
 		.set    at
 		.set    mips0
-		END(nmi_handler)	
+		END(nmi_handler)
 
 		/*
 		 * Kernel entry point
 		 */
 		NESTED(kernel_entry, 16, sp)
 		.set	noreorder
-		/* The following two symbols are used for kernel profiling. */
-		EXPORT(stext)
-		EXPORT(_stext)
 
 		/*
 		 * Stack for kernel and init, current variable
@@ -178,7 +179,7 @@
 
 /*
  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
- * function after setting up the stack and gp registers. 
+ * function after setting up the stack and gp registers.
  */
 		LEAF(smp_bootstrap)
 		.set push
@@ -198,13 +199,13 @@
 		__FINIT
 
 		/*
-		 * This buffer is reserved for the use of the EJTAG debug 
+		 * This buffer is reserved for the use of the EJTAG debug
 		 * handler.
 		 */
 		.data
 		EXPORT(ejtag_debug_buffer)
 		.fill	4
-	
+
 		.comm	kernelsp,    NR_CPUS * 8, 8
 		.comm	pgd_current, NR_CPUS * 8, 8
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/i8259.c linux-2.4.20/arch/mips/kernel/i8259.c
--- linux-2.4.19/arch/mips/kernel/i8259.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/i8259.c	2002-10-04 00:41:12.000000000 +0000
@@ -42,7 +42,7 @@
 void mask_and_ack_8259A(unsigned int);
 
 static unsigned int startup_8259A_irq(unsigned int irq)
-{ 
+{
 	enable_8259A_irq(irq);
 
 	return 0; /* never anything pending */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/ipc.c linux-2.4.20/arch/mips/kernel/ipc.c
--- linux-2.4.19/arch/mips/kernel/ipc.c	2000-02-25 06:52:30.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/ipc.c	2002-10-04 00:41:12.000000000 +0000
@@ -45,7 +45,7 @@
 	}
 
 	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
 				   second, third);
 	case MSGRCV:
 		switch (version) {
@@ -53,9 +53,9 @@
 			struct ipc_kludge tmp;
 			if (!ptr)
 				return -EINVAL;
-			
+
 			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr, 
+					   (struct ipc_kludge *) ptr,
 					   sizeof (tmp)))
 				return -EFAULT;
 			return sys_msgrcv (first, tmp.msgp, second,
@@ -85,7 +85,7 @@
 				return -EINVAL;
 			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	case SHMDT: 
+	case SHMDT:
 		return sys_shmdt ((char *)ptr);
 	case SHMGET:
 		return sys_shmget (first, second, third);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/irixelf.c linux-2.4.20/arch/mips/kernel/irixelf.c
--- linux-2.4.19/arch/mips/kernel/irixelf.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/irixelf.c	2002-10-04 00:41:20.000000000 +0000
@@ -128,7 +128,7 @@
 {
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
-	if (end <= start) 
+	if (end <= start)
 		return;
 	do_brk(start, end - start);
 }
@@ -158,7 +158,7 @@
 	elf_caddr_t *argv;
 	elf_caddr_t *envp;
 	elf_addr_t *sp, *csp;
-	
+
 #ifdef DEBUG_ELF
 	printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
 	       "load_addr[%08x] interp_load_addr[%08x]\n",
@@ -247,7 +247,7 @@
 	elf_bss = 0;
 	last_bss = 0;
 	error = load_addr = 0;
-	
+
 #ifdef DEBUG_ELF
 	print_elfhdr(interp_elf_ex);
 #endif
@@ -268,7 +268,7 @@
 	    return 0xffffffff;
 	}
 
-	elf_phdata =  (struct elf_phdr *) 
+	elf_phdata =  (struct elf_phdr *)
 		kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
 			GFP_KERNEL);
 
@@ -394,7 +394,7 @@
 		return -ENOEXEC;
 
 	/* First of all, some simple consistency checks */
-	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || 
+	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
 	    !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
 		return -ENOEXEC;
 	}
@@ -558,7 +558,7 @@
 }
 
 /*
- * IRIX maps a page at 0x200000 that holds information about the 
+ * IRIX maps a page at 0x200000 that holds information about the
  * process and the system, here we map the page and fill the
  * structure
  */
@@ -568,7 +568,7 @@
 	struct prda *pp;
 
 	v =  do_brk (PRDA_ADDRESS, PAGE_SIZE);
-	
+
 	if (v < 0)
 		return;
 
@@ -579,9 +579,9 @@
 
 	/* We leave the rest set to zero */
 }
-	
 
-	
+
+
 /* These are the functions used to load ELF style executables and shared
  * libraries.  There is no binary dependent code anywhere else.
  */
@@ -596,7 +596,7 @@
 	int retval, has_interp, has_ephdr, size, i;
 	char *elf_interpreter;
 	mm_segment_t old_fs;
-	
+
 	load_addr = 0;
 	has_interp = has_ephdr = 0;
 	elf_ihdr = elf_ephdr = 0;
@@ -685,7 +685,7 @@
 	current->mm->mmap = NULL;
 	current->flags &= ~PF_FORKNOEXEC;
 	elf_entry = (unsigned int) elf_ex.e_entry;
-	
+
 	/* Do this so that we can load the interpreter, if need be.  We will
 	 * change some of these later.
 	 */
@@ -724,7 +724,7 @@
 	set_binfmt(&irix_format);
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
-	bprm->p = (unsigned long) 
+	bprm->p = (unsigned long)
 	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
 			(elf_interpreter ? &elf_ex : NULL),
 			load_addr, interp_load_addr, regs, elf_ephdr);
@@ -812,30 +812,30 @@
 	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
 	   !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
 		return -ENOEXEC;
-	
+
 	/* Now read in all of the header information. */
 	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
 		return -ENOEXEC;
-	
-	elf_phdata =  (struct elf_phdr *) 
+
+	elf_phdata =  (struct elf_phdr *)
 		kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
 	if (elf_phdata == NULL)
 		return -ENOMEM;
-	
+
 	retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,
 			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
-	
+
 	j = 0;
 	for(i=0; i<elf_ex.e_phnum; i++)
 		if((elf_phdata + i)->p_type == PT_LOAD) j++;
-	
+
 	if(j != 1)  {
 		kfree(elf_phdata);
 		return -ENOEXEC;
 	}
-	
+
 	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
-	
+
 	/* Now use mmap to map the library into memory. */
 	down_write(&current->mm->mmap_sem);
 	error = do_mmap(file,
@@ -863,7 +863,7 @@
 	kfree(elf_phdata);
 	return 0;
 }
-	
+
 /* Called through irix_syssgi() to map an elf image given an FD,
  * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many
  * phdrs there are in the USER_PHDRP array.  We return the vaddr the
@@ -1026,7 +1026,7 @@
 	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
 	DUMP_WRITE(men->data, men->datasz);
 	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
-	
+
 	return 1;
 
 end_coredump:
@@ -1072,13 +1072,13 @@
 		if (maydump(vma))
 		{
 			int sz = vma->vm_end-vma->vm_start;
-		
+
 			if (size+sz >= limit)
 				break;
 			else
 				size += sz;
 		}
-		
+
 		segs++;
 	}
 #ifdef DEBUG
@@ -1105,7 +1105,7 @@
 	elf.e_shentsize = 0;
 	elf.e_shnum = 0;
 	elf.e_shstrndx = 0;
-	
+
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
@@ -1147,7 +1147,7 @@
 	} else {
 		*(struct pt_regs *)&prstatus.pr_reg = *regs;
 	}
-	
+
 	notes[1].name = "CORE";
 	notes[1].type = NT_PRPSINFO;
 	notes[1].datasz = sizeof(psinfo);
@@ -1164,7 +1164,7 @@
 		int i, len;
 
 		set_fs(fs);
-		
+
 		len = current->mm->arg_end - current->mm->arg_start;
 		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
 		copy_from_user(&psinfo.pr_psargs,
@@ -1201,7 +1201,7 @@
 
 		for(i = 0; i < numnote; i++)
 			sz += notesize(&notes[i]);
-		
+
 		phdr.p_type = PT_NOTE;
 		phdr.p_offset = offset;
 		phdr.p_vaddr = 0;
@@ -1217,7 +1217,7 @@
 
 	/* Page-align dumped data. */
 	dataoff = offset = roundup(offset, PAGE_SIZE);
-	
+
 	/* Write program headers for segments dump. */
 	for(vma = current->mm->mmap, i = 0;
 		i < segs && vma != NULL; vma = vma->vm_next) {
@@ -1227,7 +1227,7 @@
 		i++;
 
 		sz = vma->vm_end - vma->vm_start;
-		
+
 		phdr.p_type = PT_LOAD;
 		phdr.p_offset = offset;
 		phdr.p_vaddr = vma->vm_start;
@@ -1246,17 +1246,17 @@
 	for(i = 0; i < numnote; i++)
 		if (!writenote(&notes[i], file))
 			goto end_coredump;
-	
+
 	set_fs(fs);
 
 	DUMP_SEEK(dataoff);
-	
+
 	for(i = 0, vma = current->mm->mmap;
 	    i < segs && vma != NULL;
 	    vma = vma->vm_next) {
 		unsigned long addr = vma->vm_start;
 		unsigned long len = vma->vm_end - vma->vm_start;
-		
+
 		if (!maydump(vma))
 			continue;
 		i++;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/irixinv.c linux-2.4.20/arch/mips/kernel/irixinv.c
--- linux-2.4.19/arch/mips/kernel/irixinv.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/irixinv.c	2002-10-04 00:41:10.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Support the inventory interface for IRIX binaries
  * This is invoked before the mm layer is working, so we do not
- * use the linked lists for the inventory yet. 
+ * use the linked lists for the inventory yet.
  *
  * Miguel de Icaza, 1997.
  */
@@ -23,7 +23,7 @@
 
 	if (inventory_items == MAX_INVENTORY)
 		return;
-	
+
 	ni->inv_class      = class;
 	ni->inv_type       = type;
 	ni->inv_controller = controller;
@@ -57,7 +57,7 @@
 	 * most likely this will not let just anyone run the X server
 	 * until we put the right values all over the place
 	 */
-	 
+
 	add_to_inventory (10, 3, 0, 0, 16400);
 	add_to_inventory (1, 1, 150, -1, 12);
 	add_to_inventory (1, 3, 0, 0, 8976);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/irixsig.c linux-2.4.20/arch/mips/kernel/irixsig.c
--- linux-2.4.19/arch/mips/kernel/irixsig.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/irixsig.c	2002-10-04 00:41:14.000000000 +0000
@@ -379,7 +379,7 @@
 }
 #endif
 
-asmlinkage int 
+asmlinkage int
 irix_sigaction(int sig, const struct sigaction *act,
 	      struct sigaction *oact, void *trampoline)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/irq.c linux-2.4.20/arch/mips/kernel/irq.c
--- linux-2.4.19/arch/mips/kernel/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/irq.c	2002-10-04 00:41:11.000000000 +0000
@@ -31,6 +31,8 @@
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+static void register_irq_proc (unsigned int irq);
+
 /*
  * Special irq handlers.
  */
@@ -48,7 +50,7 @@
 {
 	/*
 	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesnt deserve
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("unexpected interrupt %d\n", irq);
@@ -87,7 +89,7 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
-		if (!action) 
+		if (!action)
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
@@ -198,12 +200,12 @@
 }
 
 /*
- * A global "cli()" while in an interrupt context turns into just a local 
- * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * A global "cli()" while in an interrupt context turns into just a local
+ * cli(). Interrupts should use spinlocks for the (very unlikely) case that
  * they ever want to protect against each other.
- * 
- * If we already have local interrupts disabled, this will not turn a local 
- * disable into a global one (problems with spinlocks: this makes 
+ *
+ * If we already have local interrupts disabled, this will not turn a local
+ * disable into a global one (problems with spinlocks: this makes
  * save_flags+cli+sti usable inside a spinlock).
  */
 
@@ -317,9 +319,9 @@
  * Generic enable/disable code: this just calls
  * down into the PIC-specific version for the actual
  * hardware disable after having gotten the irq
- * controller lock. 
+ * controller lock.
  */
- 
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -330,7 +332,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void inline disable_irq_nosync(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -356,7 +358,7 @@
  *
  *	This function may be called - with care - from IRQ context.
  */
- 
+
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
@@ -377,7 +379,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void enable_irq(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -412,7 +414,7 @@
  */
 asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
 {
-	/* 
+	/*
 	 * We ack quickly, we don't want the irq controller
 	 * thinking we're snobs just because some other CPU has
 	 * disabled global interrupts (we have already done the
@@ -472,7 +474,7 @@
 		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, regs, action);
 		spin_lock(&desc->lock);
-		
+
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -502,7 +504,7 @@
  *	This call allocates interrupt resources and enables the
  *	interrupt line and IRQ handling. From the point this
  *	call is made your handler function may be invoked. Since
- *	your handler function must clear any interrupt the board 
+ *	your handler function must clear any interrupt the board
  *	raises, you must take care both to initialise your hardware
  *	and to set up the interrupt handler in the right order.
  *
@@ -522,10 +524,10 @@
  *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  *
  */
- 
-int request_irq(unsigned int irq, 
+
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -580,12 +582,12 @@
  *	does not return until any executing interrupts for this IRQ
  *	have completed.
  *
- *	This function may be called from interrupt context. 
+ *	This function may be called from interrupt context.
  *
  *	Bugs: Attempting to free an irq in a handler for the same irq hangs
  *	      the machine.
  */
- 
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	irq_desc_t *desc;
@@ -646,7 +648,7 @@
  *	and a mask of potential interrupt lines is returned.
  *
  */
- 
+
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
@@ -655,15 +657,15 @@
 	unsigned long delay;
 
 	down(&probe_sem);
-	/* 
+	/*
 	 * something may have generated an irq long ago and we want to
-	 * flush such a longstanding irq before considering it as spurious. 
+	 * flush such a longstanding irq before considering it as spurious.
 	 */
 	for (i = NR_IRQS-1; i > 0; i--)  {
 		desc = irq_desc + i;
 
 		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
+		if (!irq_desc[i].action)
 			irq_desc[i].handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
@@ -725,7 +727,7 @@
  * Return a mask of triggered interrupts (this
  * can handle only legacy ISA interrupts).
  */
- 
+
 /**
  *	probe_irq_mask - scan a bitmap of interrupt lines
  *	@val:	mask of interrupts to consider
@@ -787,7 +789,7 @@
  *	nothing prevents two IRQ probe callers from overlapping. The
  *	results of this are non-optimal.
  */
- 
+
 int probe_irq_off(unsigned long val)
 {
 	int i, irq_found, nr_irqs;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/irq_cpu.c linux-2.4.20/arch/mips/kernel/irq_cpu.c
--- linux-2.4.19/arch/mips/kernel/irq_cpu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/irq_cpu.c	2002-10-04 00:41:14.000000000 +0000
@@ -13,7 +13,7 @@
 /*
  * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
  * level triggered (i.e., cannot be cleared from CPU; must be cleared from
- * device).  The first two are software interrupts.  The last one is 
+ * device).  The first two are software interrupts.  The last one is
  * usually the CPU timer interrupt if counter register is present or, for
  * CPUs with an external FPU, by convention it's the FPU exception interrupt.
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/mips_ksyms.c linux-2.4.20/arch/mips/kernel/mips_ksyms.c
--- linux-2.4.19/arch/mips/kernel/mips_ksyms.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/mips_ksyms.c	2002-10-04 00:41:13.000000000 +0000
@@ -43,7 +43,9 @@
 extern long __strnlen_user_asm(const char *s);
 
 EXPORT_SYMBOL(mips_machtype);
+#ifdef CONFIG_EISA
 EXPORT_SYMBOL(EISA_bus);
+#endif
 
 /*
  * String functions
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/old-irq.c linux-2.4.20/arch/mips/kernel/old-irq.c
--- linux-2.4.19/arch/mips/kernel/old-irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/old-irq.c	2002-10-04 00:41:21.000000000 +0000
@@ -130,7 +130,7 @@
 
 	for (i = 0 ; i < 32 ; i++) {
 		action = irq_action[i];
-		if (!action) 
+		if (!action)
 			continue;
 		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.irqs[0][i],
@@ -286,7 +286,7 @@
  * specific variants.  For now we still use this as broken as it is because
  * it used to work ...
  */
-int request_irq(unsigned int irq, 
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, const char * devname, void *dev_id)
 {
@@ -315,7 +315,7 @@
 		kfree(action);
 	return retval;
 }
-		
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	struct irqaction * action, **p;
@@ -386,7 +386,7 @@
 	outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
 	outb(0x01, 0x21); /* Select 8086 mode */
 	outb(0xff, 0x21); /* Mask all */
-        
+
 	/* Init slave interrupt controller */
 	outb(0x11, 0xa0); /* Start init sequence */
 	outb(0x08, 0xa1); /* Vector base */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/old-time.c linux-2.4.20/arch/mips/kernel/old-time.c
--- linux-2.4.19/arch/mips/kernel/old-time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/old-time.c	2002-10-04 00:41:12.000000000 +0000
@@ -106,7 +106,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * Due to possible jiffies inconsistencies, we need to check
 	 * the result so that we'll get a timer that is monotonic.
 	 */
 	if (res >= USECS_PER_JIFFY)
@@ -115,9 +115,9 @@
 	return res;
 }
 
-/* This function must be called with interrupts disabled 
+/* 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
@@ -131,7 +131,7 @@
  * 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 
+ * 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
@@ -142,7 +142,7 @@
  * 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!
  */
@@ -157,7 +157,7 @@
 	static unsigned long jiffies_p;
 
 	/*
-	 * cache volatile jiffies temporarily; we have IRQs turned off. 
+	 * cache volatile jiffies temporarily; we have IRQs turned off.
 	 */
 	unsigned long jiffies_t;
 
@@ -167,7 +167,7 @@
 	count = inb_p(0x40);	/* read the latched count */
 
 	/*
-	 * We do this guaranteed double memory access instead of a _p 
+	 * We do this guaranteed double memory access instead of a _p
 	 * postfix in the previous port access. Wheee, hackady hack
 	 */
 	jiffies_t = jiffies;
@@ -192,7 +192,7 @@
 			/* assumption about timer being IRQ1 */
 			if (inb(0x20) & 0x01) {
 				/*
-				 * We cannot detect lost timer interrupts ... 
+				 * We cannot detect lost timer interrupts ...
 				 * well, that's why we call them lost, don't we? :)
 				 * [hmm, on the Pentium and Alpha we can ... sort of]
 				 */
@@ -348,7 +348,7 @@
 	    ddb5074_led_d2(1);
 	else if (cnt == 7 || cnt == dist+7)
 	    ddb5074_led_d2(0);
-	
+
 	if (++cnt > period) {
 	    cnt = 0;
 	    /* The hyperbolic function below modifies the heartbeat period
@@ -383,7 +383,7 @@
 	 * 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.
 	 */
-	read_lock (&xtime_lock); 
+	read_lock (&xtime_lock);
 	if ((time_status & STA_UNSYNC) == 0 &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
@@ -402,10 +402,10 @@
 	 * look closely for now..
 	 */
 	/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
-	read_unlock (&xtime_lock); 
+	read_unlock (&xtime_lock);
 }
 
-static inline void 
+static inline void
 r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	unsigned int count;
@@ -425,7 +425,7 @@
 	 * we need only ask for the next in r4k_interval counts. On other
 	 * archs we have a real timer, so we don't want this.
 	 */
-	write_32bit_cp0_register (CP0_COMPARE, 
+	write_32bit_cp0_register (CP0_COMPARE,
 				  (unsigned long) (count + r4k_interval));
         kstat.irqs[0][irq]++;
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/pci-dma.c linux-2.4.20/arch/mips/kernel/pci-dma.c
--- linux-2.4.19/arch/mips/kernel/pci-dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/pci-dma.c	2002-10-04 00:41:11.000000000 +0000
@@ -22,17 +22,19 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
+#ifdef CONFIG_ISA
 	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
+#endif
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
+		*dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret));
 #ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
-		ret = KSEG1ADDR(ret);
+		ret = UNCAC_ADDR(ret);
 #endif
-		*dma_handle = virt_to_bus(ret);
 	}
 
 	return ret;
@@ -44,7 +46,7 @@
 	unsigned long addr = (unsigned long) vaddr;
 
 #ifdef CONFIG_NONCOHERENT_IO
-	addr = KSEG0ADDR(addr);
+	addr = CAC_ADDR(addr);
 #endif
 	free_pages(addr, get_order(size));
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/pci.c linux-2.4.20/arch/mips/kernel/pci.c
--- linux-2.4.19/arch/mips/kernel/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/pci.c	2002-10-04 00:41:12.000000000 +0000
@@ -162,7 +162,8 @@
 }
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 	/* this should not be called */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/pci_auto.c linux-2.4.20/arch/mips/kernel/pci_auto.c
--- linux-2.4.19/arch/mips/kernel/pci_auto.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/pci_auto.c	2002-10-04 00:41:30.000000000 +0000
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 /*
@@ -95,7 +95,7 @@
 static u32 pciauto_lower_memspc;
 static u32 pciauto_upper_memspc;
 
-void __init 
+void __init
 pciauto_setup_bars(struct pci_channel *hose,
 		   int top_bus,
 		   int current_bus,
@@ -144,7 +144,7 @@
 			    PCI_BASE_ADDRESS_MEM_TYPE_64)
 				found_mem64 = 1;
 
-			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
 			upper_limit = &pciauto_upper_memspc;
 			lower_limit = &pciauto_lower_memspc;
 			DBG("        Mem");
@@ -160,22 +160,22 @@
 		if ((bar_value + bar_size) > *upper_limit) {
 			if (bar_response & PCI_BASE_ADDRESS_SPACE) {
 				if (io_resource_inuse->child) {
-					io_resource_inuse = 
+					io_resource_inuse =
 						io_resource_inuse->child;
-					pciauto_lower_iospc = 
+					pciauto_lower_iospc =
 						io_resource_inuse->start;
-					pciauto_upper_iospc = 
+					pciauto_upper_iospc =
 						io_resource_inuse->end + 1;
 					goto retry;
 				}
 
 			} else {
 				if (mem_resource_inuse->child) {
-					mem_resource_inuse = 
+					mem_resource_inuse =
 						mem_resource_inuse->child;
-					pciauto_lower_memspc = 
+					pciauto_lower_memspc =
 						mem_resource_inuse->start;
-					pciauto_upper_memspc = 
+					pciauto_upper_memspc =
 						mem_resource_inuse->end + 1;
 					goto retry;
 				}
@@ -194,7 +194,7 @@
 		 * If we are a 64-bit decoder then increment to the
 		 * upper 32 bits of the bar and force it to locate
 		 * in the lower 4GB of memory.
-		 */ 
+		 */
 		if (found_mem64) {
 			bar += 4;
 			early_write_config_dword(hose, top_bus,
@@ -295,12 +295,12 @@
 	int devfn_stop = 0xff;
 
 	sub_bus = current_bus;
-	
+
 	if (hose->first_devfn)
 		devfn_start = hose->first_devfn;
 	if (hose->last_devfn)
 		devfn_stop = hose->last_devfn;
-	
+
 	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
 
 		if (PCI_FUNC(pci_devfn) && !found_multi)
@@ -387,7 +387,7 @@
 	pciauto_upper_memspc = mem_resource_inuse->end + 1;
 	DBG("Autoconfig PCI channel 0x%p\n", hose);
 	DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n",
-		busno, pciauto_lower_iospc, pciauto_upper_iospc, 
+		busno, pciauto_lower_iospc, pciauto_upper_iospc,
 		pciauto_lower_memspc, pciauto_upper_memspc);
 
 	return pciauto_bus_scan(hose, busno, busno);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/proc.c linux-2.4.20/arch/mips/kernel/proc.c
--- linux-2.4.19/arch/mips/kernel/proc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/proc.c	2002-10-04 00:41:14.000000000 +0000
@@ -67,7 +67,13 @@
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
 	[CPU_TX39XX]	"TX39xx",
-	[CPU_20KC]	"MIPS 20Kc"
+	[CPU_20KC]	"MIPS 20Kc",
+	[CPU_VR4111]	"NEC VR4111",
+	[CPU_VR4121]	"NEC VR4121",
+	[CPU_VR4122]	"NEC VR4122",
+	[CPU_VR4131]	"NEC VR4131",
+	[CPU_VR4181]	"NEC VR4181",
+	[CPU_VR4181A]	"NEC VR4181A"
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/process.c linux-2.4.20/arch/mips/kernel/process.c
--- linux-2.4.19/arch/mips/kernel/process.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/process.c	2002-10-04 00:41:17.000000000 +0000
@@ -77,7 +77,6 @@
 {
 	struct pt_regs * childregs;
 	long childksp;
-	extern void save_fp(void*);
 
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/ptrace.c linux-2.4.20/arch/mips/kernel/ptrace.c
--- linux-2.4.19/arch/mips/kernel/ptrace.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/ptrace.c	2002-10-04 00:41:20.000000000 +0000
@@ -84,7 +84,7 @@
 		goto out_tsk;
 
 	switch (request) {
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -119,7 +119,7 @@
 			 	if(!(mips_cpu.options & MIPS_CPU_FPU)) {
 					fregs = (unsigned long long *)
 						child->thread.fpu.soft.regs;
-				} else 
+				} else
 					if (last_task_used_math == child) {
 						__enable_fpu();
 						save_fp(child);
@@ -132,11 +132,6 @@
 				 * order bits of the values stored in the even
 				 * registers - unless we're using r2k_switch.S.
 				 */
-#ifdef CONFIG_CPU_R3000
-				if (mips_cpu.options & MIPS_CPU_FPU)
-					tmp = *(unsigned long *)(fregs + addr);
-				else
-#endif
 				if (addr & 1)
 					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
 				else
@@ -258,7 +253,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			if (!(mips_cpu.options & MIPS_CPU_FPU)) 
+			if (!(mips_cpu.options & MIPS_CPU_FPU))
 				child->thread.fpu.soft.sr = data;
 			else
 				child->thread.fpu.hard.control = data;
@@ -287,8 +282,8 @@
 		}
 
 	/*
-	 * 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 
+	 * 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:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/r4k_switch.S linux-2.4.20/arch/mips/kernel/r4k_switch.S
--- linux-2.4.19/arch/mips/kernel/r4k_switch.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/r4k_switch.S	2002-10-04 00:41:30.000000000 +0000
@@ -46,16 +46,16 @@
 	move	$28, a1
 	CPU_RESTORE_NONSCRATCH($28)
 	addiu	t0, $28, KERNEL_STACK_SIZE-32
-#ifdef CONFIG_SMP	 
+#ifdef CONFIG_SMP
 	mfc0	a3, CP0_CONTEXT
 	la	t1, kernelsp
 	srl	a3, 23
 	sll	a3, 2
 	addu	t1, a3, t1
-	sw	t0, (t1)	
+	sw	t0, (t1)
 #else
 	sw	t0, kernelsp
-#endif 
+#endif
 	mfc0	t1, CP0_STATUS		/* Do we really need this? */
 	li	a3, 0xff00
 	and	t1, a3
@@ -80,6 +80,7 @@
 	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
@@ -129,6 +130,7 @@
 	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	li	t1, FPU_DEFAULT
 	ctc1	t1, fcr31
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/scall_o32.S linux-2.4.20/arch/mips/kernel/scall_o32.S
--- linux-2.4.19/arch/mips/kernel/scall_o32.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/scall_o32.S	2002-10-04 00:41:29.000000000 +0000
@@ -38,7 +38,7 @@
 	sll	t0, v0, 2
 	lw	t2, sys_call_table(t0)	# syscall routine
 	lbu	t3, sys_narg_table(v0)	# number of arguments
-	beqz	t2, illegal_syscall;
+	beqz	t2, illegal_syscall
 
 	subu	t0, t3, 5		# 5 or more arguments?
 	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
@@ -47,7 +47,7 @@
 stack_done:
         sw      a3, PT_R26(sp)          # save for syscall restart
 	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, trace_a_syscall
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -61,20 +61,41 @@
 	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 1:	sw	v0, PT_R2(sp)		# result
 
-EXPORT(o32_ret_from_sys_call)
+fast_ret_from_sys_call:
+ret_from_schedule:
 	mfc0	t0, CP0_STATUS		# need_resched and signals atomic test
 	ori	t0, t0, 1
 	xori	t0, t0, 1
 	mtc0	t0, CP0_STATUS
+	SSNOP; SSNOP; SSNOP
 
 	lw	t2, TASK_NEED_RESCHED($28)
-	bnez	t2, o32_reschedule
 	lw	v0, TASK_SIGPENDING($28)
+	bnez	t2, reschedule
 	bnez	v0, signal_return
 restore_all:
 	RESTORE_SOME
 	RESTORE_SP_AND_RET
 
+/* ------------------------------------------------------------------------ */
+
+FEXPORT(ret_from_fork)
+	move	a0, v0			# prev
+	jal	schedule_tail
+	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, _PT_TRACESYS
+	bnez	t0, tracesys_exit
+
+static_ret_from_sys_call:
+	RESTORE_STATIC
+	j	fast_ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
+
+/* ret_from_sys_call should be here but is in entry.S.  */
+
+/* ------------------------------------------------------------------------ */
+
 /* Put this behind restore_all for the sake of the branch prediction.  */
 signal_return:
 	.type	signal_return, @function
@@ -87,11 +108,14 @@
 	move	a0, zero
 	move	a1, sp
 	jal	do_signal
+	RESTORE_STATIC
 	b	restore_all
 
-o32_reschedule:
+/* ------------------------------------------------------------------------ */
+
+reschedule:
 	jal	schedule
-	b	o32_ret_from_sys_call
+	b	ret_from_schedule
 
 /* ------------------------------------------------------------------------ */
 
@@ -116,8 +140,9 @@
 	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 1:	sw	v0, PT_R2(sp)		# result
 
+tracesys_exit:
 	jal	syscall_trace
-	j	ret_from_sys_call
+	j	static_ret_from_sys_call
 
 /* ------------------------------------------------------------------------ */
 
@@ -136,7 +161,7 @@
 	bltz	t0, bad_stack		# -> sp is bad
 
 	lw	t0, PT_R29(sp)		# get old user stack pointer
-	la	t1, 3f			# copy 1 to 2 arguments
+	PTR_LA	t1, 3f			# copy 1 to 2 arguments
 	sll	t3, t3, 4
 	subu	t1, t3
 	jr	t1
@@ -150,6 +175,7 @@
 	 */
 	.set    push
 	.set    noreorder
+	.set	nomacro
 1:	lw	t1, 20(t0)		# argument #6 from usp
 	nop
 	sw	t1, 20(sp)
@@ -158,43 +184,58 @@
 	nop
 	sw	t1, 16(sp)
 	nop
-	.set	pop
+3:	.set	pop
 
-3:	j	stack_done		# go back
+	j	stack_done		# go back
 
 	.section __ex_table,"a"
 	PTR	1b,bad_stack
 	PTR	2b,bad_stack
 	.previous
 
+/* ------------------------------------------------------------------------ */
+
 	/*
 	 * The stackpointer for a call with more than 4 arguments is bad.
 	 * We probably should handle this case a bit more drastic.
 	 */
 bad_stack:
-	negu	v0				# error
+	negu	v0			# error
 	sw	v0, PT_R0(sp)
 	sw	v0, PT_R2(sp)
-	li	t0, 1				# set error flag
+	li	t0, 1			# set error flag
 	sw	t0, PT_R7(sp)
-	j	ret_from_sys_call
+	j	fast_ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
 
 	/*
 	 * The system call does not exist in this kernel
 	 */
 illegal_syscall:
-	li	v0, ENOSYS			# error
+	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, _PT_TRACESYS
+	beqz	t0, 1f
+
+	SAVE_STATIC
+	jal	syscall_trace
+	li	t0, _PT_TRACESYS
+
+1:	li	v0, ENOSYS		# error
+	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 	sw	v0, PT_R2(sp)
-	li	t0, 1				# set error flag
-	sw	t0, PT_R7(sp)
-	j	ret_from_sys_call
-	END(handle_sys)
+	li	t1, 1			# set error flag
+	sw	t1, PT_R7(sp)
+	bnez	t0, tracesys_exit
 
-	LEAF(mips_atomic_set)
-	andi	v0, a1, 3			# must be word aligned
+	j	fast_ret_from_sys_call
+END(handle_sys)
+
+LEAF(mips_atomic_set)
+	andi	v0, a1, 3		# must be word aligned
 	bnez	v0, bad_alignment
 
-	lw	v1, THREAD_CURDS($28)		# in legal address range?
+	lw	v1, THREAD_CURDS($28)	# in legal address range?
 	addiu	a0, a1, 4
 	or	a0, a0, a1
 	and	a0, a0, v1
@@ -236,19 +277,17 @@
 	.previous
 #endif
 
+	sw	zero, PT_R7(sp)		# success
 	sw	v0, PT_R2(sp)		# result
-1:
 
 	/* Success, so skip usual error handling garbage.  */
 	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
-	bnez	t0, 1f
-	b	o32_ret_from_sys_call
+	andi	t0, _PT_TRACESYS
+	beqz	t0, fast_ret_from_sys_call
 
-1:	SAVE_STATIC
+	SAVE_STATIC
 	jal	syscall_trace
-	li	a3, 0			# success
-	j	ret_from_sys_call
+	j	static_ret_from_sys_call
 
 no_mem:	li	v0, -ENOMEM
 	jr	ra
@@ -260,40 +299,40 @@
 bad_alignment:
 	li	v0, -EINVAL
 	jr	ra
-	END(mips_atomic_set)	
+END(mips_atomic_set)
 
-	LEAF(sys_sysmips)
+LEAF(sys_sysmips)
 	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
 	j	_sys_sysmips
-	END(sys_sysmips)
+END(sys_sysmips)
 
-	LEAF(sys_syscall)
-	lw	t0, PT_R29(sp)			# user sp
+LEAF(sys_syscall)
+	lw	t0, PT_R29(sp)		# user sp
 
 	sltu	v0, a0, __NR_Linux + __NR_Linux_syscalls + 1
 	beqz	v0, enosys
 
-	sll	v0, t1, 2
+	sll	v0, a0, 2
 	la	v1, sys_syscall
-	lw	t2, sys_call_table(v0)		# function pointer
-	lbu	t4, sys_narg_table(t1)		# number of arguments
+	lw	t2, sys_call_table(v0)	# function pointer
+	lbu	t4, sys_narg_table(a0)	# number of arguments
 
 	li	v0, -EINVAL
-	beq	t2, v1, out			# do not recurse
+	beq	t2, v1, out		# do not recurse
 
-	beqz	t2, enosys			# null function pointer?
+	beqz	t2, enosys		# null function pointer?
 
-	andi	v0, t0, 0x3			# unaligned stack pointer?
+	andi	v0, t0, 0x3		# unaligned stack pointer?
 	bnez	v0, sigsegv
 
-	addu	v0, t0, 16			# v0 = usp + 16
-	addu	t1, v0, 12			# 3 32-bit arguments
+	addu	v0, t0, 16		# v0 = usp + 16
+	addu	t1, v0, 12		# 3 32-bit arguments
 	lw	v1, THREAD_CURDS($28)
 	or	v0, v0, t1
 	and	v1, v1, v0
 	bltz	v1, efault
 
-	move	a0, a1				# shit argument registers
+	move	a0, a1			# shift argument registers
 	move	a1, a2
 	move	a2, a3
 
@@ -307,11 +346,11 @@
 	.word	3b, efault
 	.previous
 
-	sw	t3, 16(sp)			# put into new stackframe
+	sw	t3, 16(sp)		# put into new stackframe
 	sw	t4, 20(sp)
 
-	bnez	t4, 1f				# zero arguments?
-	addu	a0, sp, 32			# then pass sp in a0
+	bnez	t4, 1f			# zero arguments?
+	addu	a0, sp, 32		# then pass sp in a0
 1:
 
 	sw	t3, 16(sp)
@@ -331,4 +370,4 @@
 efault:	li	v0, -EFAULT
 
 out:	jr	ra
-	END(sys_syscall)
+END(sys_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/setup.c linux-2.4.20/arch/mips/kernel/setup.c
--- linux-2.4.19/arch/mips/kernel/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/setup.c	2002-10-04 00:41:12.000000000 +0000
@@ -44,22 +44,15 @@
 #endif
 
 /*
- * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
- * the implementation of the "wait" feature differs between CPU families. This
- * points to the function that implements CPU specific wait. 
- * The wait instruction stops the pipeline and reduces the power consumption of
- * the CPU very much.
- */
-void (*cpu_wait)(void) = NULL;
-
-/*
  * There are several bus types available for MIPS machines.  "RISC PC"
  * type machines have ISA, EISA, VLB or PCI available, DECstations
  * have Turbochannel or Q-Bus, SGI has GIO, there are lots of VME
  * boxes ...
  * This flag is set if a EISA slots are available.
  */
+#ifdef CONFIG_EISA
 int EISA_bus = 0;
+#endif
 
 struct screen_info screen_info;
 
@@ -122,403 +115,9 @@
 static struct resource code_resource = { "Kernel code" };
 static struct resource data_resource = { "Kernel data" };
 
-static inline void check_wait(void)
-{
-	printk("Checking for 'wait' instruction... ");
-	switch(mips_cpu.cputype) {
-	case CPU_R3081:
-	case CPU_R3081E:
-		cpu_wait = r3081_wait;
-		printk(" available.\n");
-		break;
-	case CPU_TX3927:
-	case CPU_TX39XX:
-		cpu_wait = r39xx_wait;
-		printk(" available.\n");
-		break;
-	case CPU_R4200: 
-/*	case CPU_R4300: */
-	case CPU_R4600: 
-	case CPU_R4640: 
-	case CPU_R4650: 
-	case CPU_R4700: 
-	case CPU_R5000: 
-	case CPU_NEVADA:
-	case CPU_RM7000:
-	case CPU_TX49XX:
-	case CPU_4KC:
-	case CPU_4KEC:
-	case CPU_4KSC:
-	case CPU_5KC:
-/*	case CPU_20KC:*/
-		cpu_wait = r4k_wait;
-		printk(" available.\n");
-		break;
-	default:
-		printk(" unavailable.\n");
-		break;
-	}
-}
-
-void __init check_bugs(void)
-{
-	check_wait();
-}
-
-/*
- * Probe whether cpu has config register by trying to play with
- * alternate cache bit and see whether it matters.
- * It's used by cpu_probe to distinguish between R3000A and R3081.
- */
-static inline int cpu_has_confreg(void)
-{
-#ifdef CONFIG_CPU_R3000
-	extern unsigned long r3k_cache_size(unsigned long);
-	unsigned long size1, size2; 
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-
-	size1 = r3k_cache_size(ST0_ISC);
-	write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
-	size2 = r3k_cache_size(ST0_ISC);
-	write_32bit_cp0_register(CP0_CONF, cfg);
-	return size1 != size2;
-#else
-	return 0;
-#endif
-}
-
-/*
- * Get the FPU Implementation/Revision.
- */
-static inline unsigned long cpu_get_fpu_id(void)
-{
-	unsigned long tmp, fpu_id;
-
-	tmp = read_32bit_cp0_register(CP0_STATUS);
-	__enable_fpu();
-	fpu_id = read_32bit_cp1_register(CP1_REVISION);
-	write_32bit_cp0_register(CP0_STATUS, tmp);
-	return fpu_id;
-}
-
-/*
- * Check the CPU has an FPU the official way.
- */
-static inline int cpu_has_fpu(void)
-{
-	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
-}
-
-/* declaration of the global struct */
-struct mips_cpu mips_cpu = {
-    processor_id:	PRID_IMP_UNKNOWN,
-    fpu_id:		FPIR_IMP_NONE,
-    cputype:		CPU_UNKNOWN
-};
-
-/* Shortcut for assembler access to mips_cpu.options */
-int *cpuoptions = &mips_cpu.options;
-
-#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
-		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
-
-static inline void cpu_probe(void)
-{
-#ifdef CONFIG_CPU_MIPS32
-	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
-	unsigned long config1;
-
-        if (config0 & (1 << 31)) {
-		/* MIPS32 compliant CPU. Read Config 1 register. */
-		mips_cpu.isa_level = MIPS_CPU_ISA_M32;
-		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
-		config1 = read_mips32_cp0_config1();
-		if (config1 & (1 << 3))
-			mips_cpu.options |= MIPS_CPU_WATCH;
-		if (config1 & (1 << 2))
-			mips_cpu.options |= MIPS_CPU_MIPS16;
-		if (config1 & (1 << 1))
-			mips_cpu.options |= MIPS_CPU_EJTAG;
-		if (config1 & 1)
-			mips_cpu.options |= MIPS_CPU_FPU;
-		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
-	}
-#endif
-	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
-	switch (mips_cpu.processor_id & 0xff0000) {
-	case PRID_COMP_LEGACY:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_R2000:
-			mips_cpu.cputype = CPU_R2000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
-			if (cpu_has_fpu())
-				mips_cpu.options |= MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R3000:
-			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
-				if (cpu_has_confreg())
-					mips_cpu.cputype = CPU_R3081E;
-				else
-					mips_cpu.cputype = CPU_R3000A;
-			else
-				mips_cpu.cputype = CPU_R3000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
-			if (cpu_has_fpu())
-				mips_cpu.options |= MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R4000:
-			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
-				mips_cpu.cputype = CPU_R4400SC;
-			else
-				mips_cpu.cputype = CPU_R4000SC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
-			                   MIPS_CPU_VCE;
-			mips_cpu.tlbsize = 48;
-			break;
-                case PRID_IMP_VR41XX:
-                        mips_cpu.cputype = CPU_VR41XX;
-                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
-                        mips_cpu.options = R4K_OPTS;
-                        mips_cpu.tlbsize = 32;
-                        break;
-		case PRID_IMP_R4300:
-			mips_cpu.cputype = CPU_R4300;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-					   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_R4600:
-			mips_cpu.cputype = CPU_R4600;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 48;
-			break;
-		#if 0
- 		case PRID_IMP_R4650:
-			/*
-			 * This processor doesn't have an MMU, so it's not
-			 * "real easy" to run Linux on it. It is left purely
-			 * for documentation.  Commented out because it shares
-			 * it's c0_prid id number with the TX3900.
-			 */
-	 		mips_cpu.cputype = CPU_R4650;
-		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
-		        mips_cpu.tlbsize = 48;
-			break;
-		#endif
-		case PRID_IMP_TX39:
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
-
-			if ((mips_cpu.processor_id & 0xf0) ==
-			    (PRID_REV_TX3927 & 0xf0)) {
-				mips_cpu.cputype = CPU_TX3927;
-				mips_cpu.tlbsize = 64;
-				mips_cpu.icache.ways = 2;
-				mips_cpu.dcache.ways = 2;
-			} else {
-				switch (mips_cpu.processor_id & 0xff) {
-				case PRID_REV_TX3912:
-					mips_cpu.cputype = CPU_TX3912;
-					mips_cpu.tlbsize = 32;
-					break;
-				case PRID_REV_TX3922:
-					mips_cpu.cputype = CPU_TX3922;
-					mips_cpu.tlbsize = 64;
-					break;
-				default:
-					mips_cpu.cputype = CPU_UNKNOWN;
-					break;
-				}
-			}
-			break;
-		case PRID_IMP_R4700:
-			mips_cpu.cputype = CPU_R4700;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_TX49:
-			mips_cpu.cputype = CPU_TX49XX;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			mips_cpu.icache.ways = 4;
-			mips_cpu.dcache.ways = 4;
-			break;
-		case PRID_IMP_R5000:
-			mips_cpu.cputype = CPU_R5000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_R5432:
-			mips_cpu.cputype = CPU_R5432;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_R5500:
-			mips_cpu.cputype = CPU_R5500;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_NEVADA:
-			mips_cpu.cputype = CPU_NEVADA;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
-			mips_cpu.tlbsize = 48;
-			mips_cpu.icache.ways = 2;
-			mips_cpu.dcache.ways = 2;
-			break;
-		case PRID_IMP_R6000:
-			mips_cpu.cputype = CPU_R6000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_II;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_R6000A:
-			mips_cpu.cputype = CPU_R6000A;
-			mips_cpu.isa_level = MIPS_CPU_ISA_II;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_RM7000:
-			mips_cpu.cputype = CPU_RM7000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			/*
-			 * Undocumented RM7000:  Bit 29 in the info register of
-			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
-			 * entries.
-			 *
-			 * 29      1 =>    64 entry JTLB
-			 *         0 =>    48 entry JTLB
-			 */
-			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
-			break;
-		case PRID_IMP_R8000:
-			mips_cpu.cputype = CPU_R8000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 384;      /* has wierd TLB: 3-way x 128 */
-			break;
-		case PRID_IMP_R10000:
-			mips_cpu.cputype = CPU_R10000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
-				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R12000:
-			mips_cpu.cputype = CPU_R12000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
-				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 64;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-#ifdef CONFIG_CPU_MIPS32
-	case PRID_COMP_MIPS:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_4KC:
-			mips_cpu.cputype = CPU_4KC;
-			break;
-		case PRID_IMP_4KEC:
-			mips_cpu.cputype = CPU_4KEC;
-			break;
-		case PRID_IMP_4KSC:
-			mips_cpu.cputype = CPU_4KSC;
-			break;
-		case PRID_IMP_5KC:
-			mips_cpu.cputype = CPU_5KC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-			break;
-		case PRID_IMP_20KC:
-			mips_cpu.cputype = CPU_20KC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}		
-		break;
-	case PRID_COMP_ALCHEMY:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_AU1_REV1:
-		case PRID_IMP_AU1_REV2:
-			if (mips_cpu.processor_id & 0xff000000)
-				mips_cpu.cputype = CPU_AU1500;
-			else
-				mips_cpu.cputype = CPU_AU1000;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-#endif /* CONFIG_CPU_MIPS32 */
-	case PRID_COMP_SIBYTE:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_SB1:
-			mips_cpu.cputype = CPU_SB1;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
-			                   MIPS_CPU_MCHECK;
-#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
-			/* FPU in pass1 is known to have issues. */
-			mips_cpu.options |= MIPS_CPU_FPU;
-#endif
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-	default:
-		mips_cpu.cputype = CPU_UNKNOWN;
-	}
-	if (mips_cpu.options & MIPS_CPU_FPU)
-		mips_cpu.fpu_id = cpu_get_fpu_id();
-}
-
-static inline void cpu_report(void)
-{
-	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
-	if (mips_cpu.options & MIPS_CPU_FPU)
-		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
-}
-
 asmlinkage void __init
 init_arch(int argc, char **argv, char **envp, int *prom_vec)
 {
-	unsigned int s;
-
 	/* Determine which MIPS variant we are running on. */
 	cpu_probe();
 
@@ -650,10 +249,14 @@
 	void ip22_setup(void);
         void ev96100_setup(void);
 	void malta_setup(void);
+	void sead_setup(void);
 	void ikos_setup(void);
 	void momenco_ocelot_setup(void);
+	void momenco_ocelot_g_setup(void);
 	void nino_setup(void);
 	void nec_osprey_setup(void);
+	void nec_eagle_setup(void);
+	void zao_capcella_setup(void);
 	void jmr3927_setup(void);
  	void it8172_setup(void);
 	void swarm_setup(void);
@@ -679,13 +282,13 @@
 #ifdef CONFIG_PC_KEYB
 	kbd_ops = &no_kbd_ops;
 #endif
-	
+
 	rtc_ops = &no_rtc_ops;
 
 	switch(mips_machgroup)
 	{
 #ifdef CONFIG_BAGET_MIPS
-	case MACH_GROUP_BAGET: 
+	case MACH_GROUP_BAGET:
 		baget_setup();
 		break;
 #endif
@@ -719,6 +322,16 @@
 		momenco_ocelot_setup();
 		break;
 #endif
+#ifdef CONFIG_MOMENCO_OCELOT_G
+	case MACH_GROUP_MOMENCO:
+		momenco_ocelot_g_setup();
+		break;
+#endif
+#ifdef CONFIG_MIPS_SEAD
+	case MACH_GROUP_UNKNOWN:
+		sead_setup();
+		break;
+#endif
 #ifdef CONFIG_SGI_IP22
 	/* As of now this is only IP22.  */
 	case MACH_GROUP_SGI:
@@ -745,9 +358,25 @@
                ddb_setup();
                break;
 #endif
-#ifdef CONFIG_NEC_OSPREY
+#ifdef CONFIG_CPU_VR41XX
 	case MACH_GROUP_NEC_VR41XX:
-		nec_osprey_setup();
+		switch (mips_machtype) {
+#ifdef CONFIG_NEC_OSPREY
+		case MACH_NEC_OSPREY:
+			nec_osprey_setup();
+			break;
+#endif
+#ifdef CONFIG_NEC_EAGLE
+		case MACH_NEC_EAGLE:
+			nec_eagle_setup();
+			break;
+#endif
+#ifdef CONFIG_ZAO_CAPCELLA
+		case MACH_ZAO_CAPCELLA:
+			zao_capcella_setup();
+			break;
+#endif
+		}
 		break;
 #endif
 #ifdef CONFIG_MIPS_EV96100
@@ -765,7 +394,7 @@
 	case  MACH_GROUP_GLOBESPAN:
 		it8172_setup();
 		break;
-#endif  
+#endif
 #ifdef CONFIG_NINO
 	case MACH_GROUP_PHILIPS:
 		nino_setup();
@@ -776,6 +405,11 @@
 		au1000_setup();
 		break;
 #endif
+#ifdef CONFIG_MIPS_PB1100
+	case MACH_GROUP_ALCHEMY:
+		au1100_setup();
+		break;
+#endif
 #ifdef CONFIG_MIPS_PB1500
 	case MACH_GROUP_ALCHEMY:
 		au1500_setup();
@@ -815,8 +449,8 @@
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; 
-	if (tmp < (unsigned long)&_end) 
+	tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+	if (tmp < (unsigned long)&_end)
 		tmp += PAGE_SIZE;
 	initrd_header = (unsigned long *)tmp;
 	if (initrd_header[0] == 0x494E5244) {
@@ -952,17 +586,17 @@
 	}
 	initrd_below_start_ok = 1;
 	if (initrd_start) {
-		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); 
+		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start);
 		printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
-		       (void *)initrd_start, 
+		       (void *)initrd_start,
 		       initrd_size);
-		if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+		if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
 			printk("initrd extends beyond end of memory "
 			       "(0x%lx > 0x%p)\ndisabling initrd\n",
-			       initrd_end,
-			       phys_to_virt(PFN_PHYS(max_low_pfn)));
+			       PHYSADDR(initrd_end),
+			       PFN_PHYS(max_low_pfn));
 			initrd_start = initrd_end = 0;
-		} 
+		}
 	}
 #endif /* CONFIG_BLK_DEV_INITRD  */
 
@@ -1013,25 +647,6 @@
 	}
 }
 
-void r3081_wait(void) 
-{
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
-}
-
-void r39xx_wait(void)
-{
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
-}
-
-void r4k_wait(void)
-{
-	__asm__(".set\tmips3\n\t"
-		"wait\n\t"
-		".set\tmips0");
-}
-
 static int __init fpu_disable(char *s)
 {
 	mips_cpu.options &= ~MIPS_CPU_FPU;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/signal.c linux-2.4.20/arch/mips/kernel/signal.c
--- linux-2.4.19/arch/mips/kernel/signal.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/signal.c	2002-10-04 00:41:29.000000000 +0000
@@ -17,14 +17,14 @@
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
-#include <linux/ptrace.h>
 #include <linux/unistd.h>
 
 #include <asm/asm.h>
 #include <asm/bitops.h>
 #include <asm/cpu.h>
+#include <asm/offset.h>
 #include <asm/pgalloc.h>
-#include <asm/stackframe.h>
+#include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
 
@@ -190,7 +190,7 @@
 	u64 *pfreg = &current->thread.fpu.soft.regs[0];
 	int err = 0;
 
-	/* 
+	/*
 	 * Copy all 32 64-bit values, for two reasons.  First, the R3000 and
 	 * R4000/MIPS32 kernels use the thread FP register storage differently,
 	 * such that a full copy is essentially necessary to support both.
@@ -416,15 +416,15 @@
 		goto out;
 
 	/* There exists FP thread state that may be trashed by signal */
-	if (owned_fp) {	
+	if (owned_fp) {
 		/* fp is active.  Save context from FPU */
 		err |= save_fp_context(sc);
 		goto out;
 	}
 
-	/* 
-	 * Someone else has FPU. 
-	 * Copy Thread context into signal context 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
 	 */
 	err |= save_thread_fp_context(sc);
 
@@ -443,7 +443,7 @@
 	/* Default to using normal stack */
 	sp = regs->regs[29];
 
-	/* 
+	/*
  	 * FPU emulator may have it's own trampoline active just
  	 * above the user stack, 16-bytes before the next lowest
  	 * 16 byte boundary.  Try to avoid trashing it.
@@ -508,8 +508,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->sf_code);
 #endif
         return;
 
@@ -583,8 +584,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->rs_code);
 #endif
 	return;
 
@@ -708,7 +710,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
@@ -732,10 +734,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/smp.c linux-2.4.20/arch/mips/kernel/smp.c
--- linux-2.4.19/arch/mips/kernel/smp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/smp.c	2002-10-04 00:41:12.000000000 +0000
@@ -8,7 +8,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -17,17 +17,18 @@
  * Copyright (C) 2000, 2001 Ralf Baechle
  * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  * Copyright (C) 2000, 2001 Broadcom Corporation
- */ 
+ */
+#include <linux/config.h>
 #include <linux/cache.h>
+#include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/threads.h>
-#include <linux/time.h>
 #include <linux/module.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -36,23 +37,22 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
-#include <asm/delay.h>
 #include <asm/smp.h>
 
-/* Ze Big Kernel Lock! */
+/* The 'big kernel lock' */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-int smp_threads_ready;
+int smp_threads_ready;	/* Not used */
 atomic_t smp_commenced = ATOMIC_INIT(0);
-int smp_num_cpus = 1;			/* Number that came online.  */
-cpumask_t cpu_online_map;		/* Bitmask of currently online CPUs */
-int __cpu_number_map[NR_CPUS];
-int __cpu_logical_map[NR_CPUS];
 struct cpuinfo_mips cpu_data[NR_CPUS];
-void (*volatile smp_cpu0_finalize)(void);
 
 // static atomic_t cpus_booted = ATOMIC_INIT(0);
 atomic_t cpus_booted = ATOMIC_INIT(0);
 
+int smp_num_cpus = 1;			/* Number that came online.  */
+cpumask_t cpu_online_map;		/* Bitmask of currently online CPUs */
+int __cpu_number_map[NR_CPUS];
+int __cpu_logical_map[NR_CPUS];
+cycles_t cacheflush_time;
 
 /* These are defined by the board-specific code. */
 
@@ -65,13 +65,13 @@
 
 /*
  * Clear all undefined state in the cpu, set up sp and gp to the passed
- * values, and kick the cpu into smp_bootstrap(); 
+ * values, and kick the cpu into smp_bootstrap();
  */
 void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
 
 /*
  *  After we've done initial boot, this function is called to allow the
- *  board code to clean up state, if needed 
+ *  board code to clean up state, if needed
  */
 void prom_init_secondary(void);
 
@@ -81,6 +81,21 @@
  */
 int prom_setup_smp(void);
 
+void prom_smp_finish(void);
+
+static void smp_tune_scheduling(void)
+{
+}
+
+void __init smp_callin(void)
+{
+#if 0
+	calibrate_delay();
+	smp_store_cpu_info(cpuid);
+#endif
+}
+
+#ifndef CONFIG_SGI_IP27
 /*
  * Hook for doing final board-specific setup after the generic smp setup
  * is done
@@ -96,7 +111,6 @@
 	 * XXX parity protection should be folded in here when it's converted
 	 * to an option instead of something based on .cputype
 	 */
-
 	pgd_current[cpu] = init_mm.pgd;
 	cpu_data[cpu].udelay_val = loops_per_jiffy;
 	prom_smp_finish();
@@ -106,6 +120,7 @@
 	while (!atomic_read(&smp_commenced));
 	cpu_idle();
 }
+#endif /* CONFIG_SGI_IP27 */
 
 void __init smp_commence(void)
 {
@@ -113,6 +128,11 @@
 	atomic_set(&smp_commenced, 1);
 }
 
+/*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+ * anything. Worst case is that we lose a reschedule ...
+ */
 void smp_send_reschedule(int cpu)
 {
 	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
@@ -123,11 +143,17 @@
 struct call_data_struct *call_data;
 
 /*
- * The caller of this wants the passed function to run on every cpu.  If wait
- * is set, wait until all cpus have finished the function before returning.
- * The lock is here to protect the call structure.
+ * Run a function on all other CPUs.
+ *  <func>      The function to run. This must be fast and non-blocking.
+ *  <info>      An arbitrary pointer to pass to the function.
+ *  <retry>     If true, keep retrying until ready.
+ *  <wait>      If true, wait until function has completed on other CPUs.
+ *  [RETURNS]   0 on success, else a negative status code.
+ *
+ * Does not return until remote CPUs are nearly ready to execute <func>
+ * or are or have executed.
  */
-int smp_call_function (void (*func) (void *info), void *info, int retry, 
+int smp_call_function (void (*func) (void *info), void *info, int retry,
 								int wait)
 {
 	struct call_data_struct data;
@@ -174,14 +200,14 @@
 
 	irq_enter(cpu, 0);	/* XXX choose an irq number? */
 	/*
-	 * Notify initiating CPU that I've grabbed the data
-	 * and am about to execute the function
+	 * Notify initiating CPU that I've grabbed the data and am
+	 * about to execute the function.
 	 */
 	mb();
 	atomic_inc(&call_data->started);
 
 	/*
-	 * At this point the info structure may be out of scope unless wait==1
+	 * At this point the info structure may be out of scope unless wait==1.
 	 */
 	(*func)(info);
 	if (wait) {
@@ -193,18 +219,23 @@
 
 static void stop_this_cpu(void *dummy)
 {
-	int cpu = smp_processor_id();
-	if (cpu)
-		for (;;);		/* XXX Use halt like i386 */
-
-	/* XXXKW this isn't quite there yet */
-	while (!smp_cpu0_finalize) ;
-	smp_cpu0_finalize();
+	/*
+	 * Remove this CPU:
+	 */
+	clear_bit(smp_processor_id(), &cpu_online_map);
+	/* May need to service _machine_restart IPI */
+	__sti();
+	/* XXXKW wait if available? */
+	for (;;);
 }
 
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	/*
+	 * Fix me: this prevents future IPIs, for example that would
+	 * cause a restart to happen on CPU0.
+	 */
 	smp_num_cpus = 1;
 }
 
@@ -231,11 +262,11 @@
 }
 
 /*
- * The following tlb flush calls are invoked when old translations are 
+ * The following tlb flush calls are invoked when old translations are
  * being torn down, or pte attributes are changing. For single threaded
  * address spaces, a new context is obtained on the current cpu, and tlb
  * context on other cpus are invalidated to force a new context allocation
- * at switch_mm time, should the mm ever be used on other cpus. For 
+ * at switch_mm time, should the mm ever be used on other cpus. For
  * multithreaded address spaces, intercpu interrupts have to be sent.
  * Another case where intercpu interrupts are required is when the target
  * mm might be active on another cpu (eg debuggers doing the flushes on
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/syscall.c linux-2.4.20/arch/mips/kernel/syscall.c
--- linux-2.4.19/arch/mips/kernel/syscall.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/syscall.c	2002-10-04 00:41:14.000000000 +0000
@@ -221,7 +221,7 @@
 		return -EFAULT;
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
-  
+
 	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
 	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
 	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/syscalls.h linux-2.4.20/arch/mips/kernel/syscalls.h
--- linux-2.4.19/arch/mips/kernel/syscalls.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/syscalls.h	2002-10-04 00:41:10.000000000 +0000
@@ -221,7 +221,7 @@
 SYS(sys_capget, 2)
 SYS(sys_capset, 2)				/* 4205 */
 SYS(sys_sigaltstack, 0)
-SYS(sys_sendfile, 3)
+SYS(sys_sendfile, 4)
 SYS(sys_ni_syscall, 0)
 SYS(sys_ni_syscall, 0)
 SYS(sys_mmap2, 6)				/* 4210 */
@@ -238,18 +238,18 @@
 SYS(sys_ni_syscall, 0)
 SYS(sys_gettid, 0)
 SYS(sys_readahead, 5)
-SYS(sys_ni_syscall, 0)				/* reserved for setxattr */
-SYS(sys_ni_syscall, 0)				/* 4225 res. for lsetxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for fsetxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for getxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for lgetxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for fgetxattr */
-SYS(sys_ni_syscall, 0)				/* 4230 res. for listxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for llistxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for flistxattr */
-SYS(sys_ni_syscall, 0)				/* reserved for removexattr */
-SYS(sys_ni_syscall, 0)				/* reserved for lremovexattr */
-SYS(sys_ni_syscall, 0)				/* 4235 res. for fremovexattr */
+SYS(sys_setxattr, 5)
+SYS(sys_lsetxattr, 5)				/* 4225 */
+SYS(sys_fsetxattr, 5)
+SYS(sys_getxattr, 4)
+SYS(sys_lgetxattr, 4)
+SYS(sys_fgetxattr, 4)
+SYS(sys_listxattr, 3)				/* 4230 */
+SYS(sys_llistxattr, 3)
+SYS(sys_flistxattr, 3)
+SYS(sys_removexattr, 2)
+SYS(sys_lremovexattr, 2)
+SYS(sys_fremovexattr, 2)			/* 4235 */
 SYS(sys_tkill, 2)
 SYS(sys_ni_syscall, 0)				/* res. for sendfile64 */
 SYS(sys_ni_syscall, 0)				/* res. for futex */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/sysirix.c linux-2.4.20/arch/mips/kernel/sysirix.c
--- linux-2.4.19/arch/mips/kernel/sysirix.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/sysirix.c	2002-10-04 00:41:29.000000000 +0000
@@ -109,7 +109,7 @@
 		if (error)
 			error = (task->run_list.next != NULL);
 		read_unlock(&tasklist_lock);
-		/* Can _your_ OS find this out that fast? */ 
+		/* Can _your_ OS find this out that fast? */
 		break;
 	}
 
@@ -332,7 +332,7 @@
 		       current->comm, current->pid, name, value, retval);
 /*		if (retval == PROM_ENOENT)
 		  	retval = -ENOENT; */
-		break;				   
+		break;
 	}
 #endif
 
@@ -505,7 +505,7 @@
 		}
 		break;
 	}
-	
+
 	default:
 		printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
 		retval = -EINVAL;
@@ -1071,7 +1071,7 @@
 		if (flags & IRIX_MAP_AUTOGROW) {
 			unsigned long old_pos;
 			long max_size = offset + len;
-			
+
 			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
 				sys_write (fd, "", 1);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/sysmips.c linux-2.4.20/arch/mips/kernel/sysmips.c
--- linux-2.4.19/arch/mips/kernel/sysmips.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/sysmips.c	2002-10-04 00:41:14.000000000 +0000
@@ -61,13 +61,13 @@
 		name = (char *) arg1;
 
 		len = strncpy_from_user(nodename, name, sizeof(nodename));
-		if (len < 0) 
+		if (len < 0)
 			return -EFAULT;
 
 		down_write(&uts_sem);
 		strncpy(system_utsname.nodename, name, len);
+		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
-		system_utsname.nodename[len] = '\0'; 
 		return 0;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/time.c linux-2.4.20/arch/mips/kernel/time.c
--- linux-2.4.19/arch/mips/kernel/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/time.c	2002-10-04 00:41:17.000000000 +0000
@@ -2,8 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
- * Common time service routines for MIPS machines. See 
- * Documents/MIPS/README.txt. 
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
  *
  * 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
@@ -289,9 +289,9 @@
 
 /*
  * local_timer_interrupt() does profiling and process accounting
- * on a per-CPU basis.  
+ * on a per-CPU basis.
  *
- * In UP mode, it is invoked from the (global) timer_interrupt.  
+ * In UP mode, it is invoked from the (global) timer_interrupt.
  *
  * In SMP mode, it might invoked by per-CPU timer interrupt, or
  * a broadcasted inter-processor interrupt which itself is triggered
@@ -368,7 +368,7 @@
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
+			last_rtc_update = xtime.tv_sec - 600;
 			/* do it again in 60 s */
 		}
 	}
@@ -384,9 +384,9 @@
 	}
 
 #if !defined(CONFIG_SMP)
-	/* 
+	/*
 	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.  
+	 * and process accouting.
 	 *
 	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
 	 * low-level local timer interrupt handler.
@@ -396,7 +396,7 @@
 #else	/* CONFIG_SMP */
 
 	if (emulate_local_timer_interrupt) {
-		/* 
+		/*
 		 * this is the place where we send out inter-process
 		 * interrupts and let each CPU do its own profiling
 		 * and process accouting.
@@ -418,7 +418,7 @@
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -434,7 +434,7 @@
 
 	/* we keep interrupt disabled all the time */
 	local_timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -444,19 +444,19 @@
 /*
  * time_init() - it does the following things.
  *
- * 1) board_time_init() - 
- * 	a) (optional) set up RTC routines, 
+ * 1) board_time_init() -
+ * 	a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_counter_frequency
  *	    (only needed if you intended to use fixed_rate_gettimeoffset
  *	     or use cpu counter as timer interrupt source)
  * 2) setup xtime based on rtc_get_time().
  * 3) choose a appropriate gettimeoffset routine.
  * 4) calculate a couple of cached variables for later usage
- * 5) board_timer_setup() - 
+ * 5) board_timer_setup() -
  *	a) (optional) over-write any choices made above by time_init().
  *	b) machine specific code should setup the timer irqaction.
  *	c) enable the timer interrupt
- */ 
+ */
 
 void (*board_time_init)(void) = NULL;
 void (*board_timer_setup)(struct irqaction *irq) = NULL;
@@ -497,10 +497,12 @@
 		/* we need to calibrate the counter but we *do* have
 		 * 64-bit division. */
 		do_gettimeoffset = calibrate_div64_gettimeoffset;
-	}	
+	}
 
 	/* caclulate cache parameters */
 	if (mips_counter_frequency) {
+		u32 count;
+
 		cycles_per_jiffy = mips_counter_frequency / HZ;
 
 		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
@@ -508,16 +510,24 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
+
+		/*
+		 * For those using cpu counter as timer,  this sets up the
+		 * first interrupt
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
 	}
 
-	/* 
+	/*
 	 * Call board specific timer interrupt setup.
 	 *
-	 * this pointer must be setup in machine setup routine. 
+	 * this pointer must be setup in machine setup routine.
 	 *
 	 * Even if the machine choose to use low-level timer interrupt,
 	 * it still needs to setup the timer_irqaction.
-	 * In that case, it might be better to set timer_irqaction.handler 
+	 * In that case, it might be better to set timer_irqaction.handler
 	 * to be NULL function so that we are sure the high-level code
 	 * is not invoked accidentally.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/traps.c linux-2.4.20/arch/mips/kernel/traps.c
--- linux-2.4.19/arch/mips/kernel/traps.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/traps.c	2002-10-04 00:41:17.000000000 +0000
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/siginfo.h>
 #include <asm/watch.h>
+#include <asm/types.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/uaccess.h>
@@ -64,7 +65,8 @@
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-extern int fpu_emulator_cop1Handler(struct pt_regs *);
+extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx);
 
 char watch_available = 0;
 
@@ -180,61 +182,95 @@
 }
 
 /*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+	int retval = 0;
+	struct module *mod;
+
+	if (addr >= (long) &_stext && addr <= (long) &_etext)
+		return 1;
+
+	for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+		/* mod_bound tests for addr being inside the vmalloc'ed
+		 * module area. Of course it'd be better to test only
+		 * for the .text subset... */
+		if (mod_bound(addr, 0, mod)) {
+			retval = 1;
+			break;
+		}
+	}
+
+	return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+
+	return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
+/*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
  */
-void show_stack(unsigned int *sp)
+void show_stack(long *sp)
 {
 	int i;
-	unsigned int *stack;
+	long stackdata;
 
-	stack = sp ? sp : (unsigned int *)&sp;
-	i = 0;
+	sp = sp ? sp : (long *)&sp;
 
-	printk("Stack:");
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long stackdata;
-
-		if (__get_user(stackdata, stack++)) {
-			printk(" (Bad stack address)");
+	printk("Stack:   ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % 8) == 0))
+			printk("\n");
+		if (i > 40) {
+			printk(" ...");
 			break;
 		}
 
-		printk(" %08lx", stackdata);
-
-		if (++i > 40) {
-			printk(" ...");
+		if (__get_user(stackdata, sp++)) {
+			printk(" (Bad stack address)");
 			break;
 		}
 
-		if (i % 8 == 0)
-			printk("\n      ");
+		printk(" %08lx", stackdata);
+		i++;
 	}
+	printk("\n");
 }
 
-void show_trace(unsigned int *sp)
+void show_trace(long *sp)
 {
 	int i;
-	int column = 0;
-	unsigned int *stack;
-	unsigned long kernel_start, kernel_end;
-	unsigned long module_start, module_end;
-	extern char _stext, _etext;
+	long addr;
 
-	stack = sp ? sp : (unsigned int *) &sp;
-	i = 0;
+	sp = sp ? sp : (long *) &sp;
 
-	kernel_start = (unsigned long) &_stext;
-	kernel_end = (unsigned long) &_etext;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
+	printk("Call Trace:  ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
 
-	printk("\nCall Trace:");
-
-	while ((unsigned long) stack & (PAGE_SIZE -1)) {
-		unsigned long addr;
-
-		if (__get_user(addr, stack++)) {
+		if (__get_user(addr, sp++)) {
+			if (i && ((i % 6) == 0))
+				printk("\n");
 			printk(" (Bad stack address)\n");
 			break;
 		}
@@ -248,27 +284,24 @@
 		 * out the call path that was taken.
 		 */
 
-		if ((addr >= kernel_start && addr < kernel_end) ||
-		    (addr >= module_start && addr < module_end)) { 
-
-			printk(" [<%08lx>]", addr);
-			if (column++ == 5) {
+		if (kernel_text_address(addr)) {
+			if (i && ((i % 6) == 0))
 				printk("\n");
-				column = 0;
-			}
-			if (++i > 40) {
+			if (i > 40) {
 				printk(" ...");
 				break;
 			}
+
+			printk(" [<%08lx>]", addr);
+			i++;
 		}
 	}
-	if (column != 0)
-		printk("\n");
+	printk("\n");
 }
 
 void show_trace_task(struct task_struct *tsk)
 {
-	show_trace((unsigned int *)tsk->thread.reg29);
+	show_trace((long *)tsk->thread.reg29);
 }
 
 void show_code(unsigned int *pc)
@@ -320,33 +353,33 @@
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
-	show_stack((unsigned int *) regs->regs[29]);
-	show_trace((unsigned int *) regs->regs[29]);
+	show_stack((long *) regs->regs[29]);
+	show_trace((long *) regs->regs[29]);
 	show_code((unsigned int *) regs->cp0_epc);
 	printk("\n");
 }
 
 static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
-void __die(const char * str, struct pt_regs * regs, const char *where,
-           unsigned long line)
+void __die(const char * str, struct pt_regs * regs, const char * file,
+	   const char * func, unsigned long line)
 {
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	printk("%s", str);
-	if (where)
-		printk(" in %s, line %ld", where, line);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
 	printk(":\n");
 	show_registers(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where,
-	unsigned long line)
+void __die_if_kernel(const char * str, struct pt_regs * regs,
+		     const char * file, const char * func, unsigned long line)
 {
 	if (!user_mode(regs))
-		__die(str, regs, where, line);
+		__die(str, regs, file, func, line);
 }
 
 extern const struct exception_table_entry __start___dbe_table[];
@@ -461,10 +494,16 @@
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
+	siginfo_t info;
+
 	if (compute_return_epc(regs))
 		return;
 
-	force_sig(SIGFPE, current);
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
 }
 
 /*
@@ -473,27 +512,26 @@
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
 	if (fcr31 & FPU_CSR_UNI_X) {
-		extern void save_fp(struct task_struct *);
-		extern void restore_fp(struct task_struct *);
 		int sig;
+
 		/*
-	 	 * Unimplemented operation exception.  If we've got the
-	 	 * full software emulator on-board, let's use it...
+	 	 * Unimplemented operation exception.  If we've got the full
+		 * software emulator on-board, let's use it...
 		 *
-		 * Force FPU to dump state into task/thread context.
-		 * We're moving a lot of data here for what is probably
-		 * a single instruction, but the alternative is to 
-		 * pre-decode the FP register operands before invoking
-		 * the emulator, which seems a bit extreme for what
-		 * should be an infrequent event.
+		 * Force FPU to dump state into task/thread context.  We're
+		 * moving a lot of data here for what is probably a single
+		 * instruction, but the alternative is to pre-decode the FP
+		 * register operands before invoking the emulator, which seems
+		 * a bit extreme for what should be an infrequent event.
 		 */
 		save_fp(current);
-	
+
 		/* Run the emulator */
-		sig = fpu_emulator_cop1Handler(regs);
+		sig = fpu_emulator_cop1Handler (0, regs,
+			&current->thread.fpu.soft);
 
-		/* 
-		 * We can't allow the emulated instruction to leave any of 
+		/*
+		 * We can't allow the emulated instruction to leave any of
 		 * the cause bit set in $fcr31.
 		 */
 		current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X;
@@ -504,8 +542,8 @@
 		/* If something went wrong, signal */
 		if (sig)
 		{
-			/* 
-			 * Return EPC is not calculated in the FPU emulator, 
+			/*
+			 * Return EPC is not calculated in the FPU emulator,
 			 * if a signal is being send. So we calculate it here.
 			 */
 			compute_return_epc(regs);
@@ -522,9 +560,9 @@
 
 static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
 {
-	unsigned int *epc;
+	unsigned long *epc;
 
-	epc = (unsigned int *) regs->cp0_epc +
+	epc = (unsigned long *) regs->cp0_epc +
 	      ((regs->cp0_cause & CAUSEF_BD) != 0);
 	if (!get_user(*opcode, epc))
 		return 0;
@@ -535,14 +573,11 @@
 
 asmlinkage void do_bp(struct pt_regs *regs)
 {
-	siginfo_t info;
 	unsigned int opcode, bcode;
-	unsigned int *epc;
+	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
@@ -572,35 +607,30 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
 asmlinkage void do_tr(struct pt_regs *regs)
 {
 	siginfo_t info;
-	unsigned int opcode, bcode;
-	unsigned *epc;
+	unsigned int opcode, tcode = 0;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
-	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+	/* Immediate versions don't provide a code.  */
+	if (!(opcode & OPCODE))
+		tcode = ((opcode >> 6) & ((1 << 20) - 1));
 
 	/*
-	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
-	 * insns, even for break codes that indicate arithmetic failures.
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
+	 * insns, even for trap codes that indicate arithmetic failures.
 	 * Weird ...)
 	 * But should we continue the brokenness???  --macro
 	 */
-	switch (bcode) {
+	switch (tcode) {
 	case 6:
 	case 7:
-		if (bcode == 7)
+		if (tcode == 7)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -612,10 +642,6 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
 /*
@@ -627,8 +653,7 @@
  */
 asmlinkage void do_ri(struct pt_regs *regs)
 {
-	if (!user_mode(regs))
-		BUG();
+	die_if_kernel("Reserved instruction in kernel code", regs);
 
 #ifndef CONFIG_CPU_HAS_LLSC
 
@@ -660,9 +685,6 @@
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
 	unsigned int cpid;
-	extern void lazy_fpu_switch(void *);
-	extern void save_fp(struct task_struct *);
-	extern void init_fpu(void);
 	void fpu_emulator_init_fpu(void);
 	int sig;
 
@@ -696,12 +718,11 @@
 			current->used_math = 1;
 		}
 	}
-	sig = fpu_emulator_cop1Handler(regs);
+	sig = fpu_emulator_cop1Handler(0, regs, &current->thread.fpu.soft);
 	last_task_used_math = current;
-	if (sig)
-	{
-		/* 
-		 * Return EPC is not calculated in the FPU emulator, if 
+	if (sig) {
+		/*
+		 * Return EPC is not calculated in the FPU emulator, if
 		 * a signal is being send. So we calculate it here.
 		 */
 		compute_return_epc(regs);
@@ -738,8 +759,14 @@
 asmlinkage void do_mcheck(struct pt_regs *regs)
 {
 	show_regs(regs);
-	panic("Caught Machine Check exception - probably caused by multiple "
-	      "matching entries in the TLB.");
+	dump_tlb_all();
+	/*
+	 * Some chips may have other causes of machine check (e.g. SB1
+	 * graduation timer)
+	 */
+	panic("Caught Machine Check exception - %scaused by multiple "
+	      "matching entries in the TLB.",
+	      (regs->cp0_status & ST0_TS) ? "" : "not ");
 }
 
 asmlinkage void do_reserved(struct pt_regs *regs)
@@ -774,7 +801,7 @@
 		       "MIPS 5KC CPUs.\n");
 		write_32bit_cp0_register(CP0_ECC,
 		                         read_32bit_cp0_register(CP0_ECC)
-		                         | 0x80000000); 
+		                         | 0x80000000);
 		break;
 	default:
 		break;
@@ -827,9 +854,9 @@
         printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
         depc = read_32bit_cp0_register(CP0_DEPC);
         debug = read_32bit_cp0_register(CP0_DEBUG);
-        printk("DEPC = %08x, DEBUG = %08x\n", depc, debug); 
+        printk("DEPC = %08x, DEBUG = %08x\n", depc, debug);
         if (debug & 0x80000000) {
-                /* 
+                /*
                  * In branch delay slot.
                  * We cheat a little bit here and use EPC to calculate the
                  * debug return address (DEPC). EPC is restored after the
@@ -869,10 +896,10 @@
  */
 void *set_except_vector(int n, void *addr)
 {
-	unsigned handler = (unsigned long) addr;
-	unsigned old_handler = exception_handlers[n];
-	exception_handlers[n] = handler;
+	unsigned long handler = (unsigned long) addr;
+	unsigned long old_handler = exception_handlers[n];
 
+	exception_handlers[n] = handler;
 	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
@@ -928,8 +955,8 @@
 	for (i = 0; i <= 31; i++)
 		set_except_vector(i, handle_reserved);
 
-	/* 
-	 * Copy the EJTAG debug exception vector handler code to it's final 
+	/*
+	 * Copy the EJTAG debug exception vector handler code to it's final
 	 * destination.
 	 */
 	if (mips_cpu.options & MIPS_CPU_EJTAG)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/kernel/unaligned.c linux-2.4.20/arch/mips/kernel/unaligned.c
--- linux-2.4.19/arch/mips/kernel/unaligned.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/kernel/unaligned.c	2002-10-04 00:41:10.000000000 +0000
@@ -41,7 +41,7 @@
  *
  * #include <stdio.h>
  * #include <asm/sysmips.h>
- * 
+ *
  * struct foo {
  *         unsigned char bar[8];
  * };
@@ -368,7 +368,7 @@
 	unsigned long pc;
 	extern int do_dsemulret(struct pt_regs *);
 
-	/* 
+	/*
 	 * Address errors may be deliberately induced
 	 * by the FPU emulator to take retake control
 	 * of the CPU after executing the instruction
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/Makefile linux-2.4.20/arch/mips/lib/Makefile
--- linux-2.4.19/arch/mips/lib/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/Makefile	2002-10-04 00:41:11.000000000 +0000
@@ -12,9 +12,9 @@
 				   strnlen_user.o
 
 ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y)
-  obj-y	+= r3k_dump_tlb.o 
+  obj-y	+= r3k_dump_tlb.o
 else
-  obj-y	+= dump_tlb.o 
+  obj-y	+= dump_tlb.o
 endif
 
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy-no.o floppy-std.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/csum_partial_copy.c linux-2.4.20/arch/mips/lib/csum_partial_copy.c
--- linux-2.4.19/arch/mips/lib/csum_partial_copy.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/csum_partial_copy.c	2002-10-04 00:41:20.000000000 +0000
@@ -23,7 +23,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const char *src, char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -51,6 +51,6 @@
 		memset(dst + len - missing, 0, missing);
 		*err_ptr = -EFAULT;
 	}
-		
+
 	return csum_partial(dst, len, sum);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/floppy-std.c linux-2.4.20/arch/mips/lib/floppy-std.c
--- linux-2.4.19/arch/mips/lib/floppy-std.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/floppy-std.c	2002-10-04 00:41:12.000000000 +0000
@@ -111,8 +111,8 @@
 }
 
 static void std_fd_dma_mem_free(unsigned long addr, unsigned long size)
-{       
-	free_pages(addr, get_order(size));	
+{
+	free_pages(addr, get_order(size));
 }
 
 static unsigned long std_fd_drive_type(unsigned long n)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/ide-no.c linux-2.4.20/arch/mips/lib/ide-no.c
--- linux-2.4.19/arch/mips/lib/ide-no.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/ide-no.c	2002-10-04 00:41:15.000000000 +0000
@@ -35,7 +35,7 @@
                               void *dev_id)
 {
 	panic("no_no_ide_request_irq called - shouldn't happen");
-}			
+}
 
 static void no_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/ide-std.c linux-2.4.20/arch/mips/lib/ide-std.c
--- linux-2.4.19/arch/mips/lib/ide-std.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/ide-std.c	2002-10-04 00:41:21.000000000 +0000
@@ -68,7 +68,7 @@
                                 void *dev_id)
 {
 	return request_irq(irq, handler, flags, device, dev_id);
-}			
+}
 
 static void std_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/memcpy.S linux-2.4.20/arch/mips/lib/memcpy.S
--- linux-2.4.19/arch/mips/lib/memcpy.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/memcpy.S	2002-10-04 00:41:10.000000000 +0000
@@ -249,7 +249,7 @@
 EXC(	LOAD	 t0, 0(src),		l_exc)
 	ADD	src, src, NBYTES
 	SUB	len, len, NBYTES
-EXC(	STORE	t0, 0(dst),		s_exc)
+EXC(	STORE	t0, 0(dst),		s_exc_p1u)
 	bne	rem, len, 1b
 	 ADD	dst, dst, NBYTES
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/memset.S linux-2.4.20/arch/mips/lib/memset.S
--- linux-2.4.19/arch/mips/lib/memset.S	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/memset.S	2002-10-04 00:41:20.000000000 +0000
@@ -54,7 +54,6 @@
 1:
 
 EXPORT(__bzero)
-	.type   __bzero, @function
 	sltiu	t0, a2, 4			/* very small region? */
 	bnez	t0, small_memset
 	 andi	t0, a0, 3			/* aligned? */
@@ -84,13 +83,17 @@
 	.set	noreorder
 
 memset_partial:
-	la	t1, 2f				/* where to start */
+	PTR_LA	t1, 2f				/* where to start */
 	subu	t1, t0
 	jr	t1
 	 addu	a0, t0				/* dest ptr */
 
+	.set	push
+	.set	noreorder
+	.set	nomacro
 	F_FILL64(a0, -64, a1, partial_fixup)	/* ... but first do wrds ... */
-2:	andi	a2, 3				/* 0 <= n <= 3 to go */
+2:	.set	pop
+	andi	a2, 3				/* 0 <= n <= 3 to go */
 
 	beqz	a2, 1f
 	 addu	a0, a2				/* What's left */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/strlen_user.S linux-2.4.20/arch/mips/lib/strlen_user.S
--- linux-2.4.19/arch/mips/lib/strlen_user.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/strlen_user.S	2002-10-04 00:41:30.000000000 +0000
@@ -27,7 +27,7 @@
 	and	v0, a0
 	bltz	v0, fault
 
-EXPORT(__strlen_user_nocheck_asm)
+FEXPORT(__strlen_user_nocheck_asm)
 	move	v0, a0
 1:	EX(lb, t0, (v0), fault)
 	addiu	v0, 1
@@ -36,9 +36,5 @@
 	jr	ra
 	END(__strlen_user_asm)
 
-	.section __ex_table,"a"
-	PTR	1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/strnlen_user.S linux-2.4.20/arch/mips/lib/strnlen_user.S
--- linux-2.4.19/arch/mips/lib/strnlen_user.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/strnlen_user.S	2002-10-04 00:41:14.000000000 +0000
@@ -31,7 +31,7 @@
 	and	v0, a0
 	bltz	v0, fault
 
-EXPORT(__strnlen_user_nocheck_asm)
+FEXPORT(__strnlen_user_nocheck_asm)
 	.type	__strnlen_user_nocheck_asm,@function
 	move	v0, a0
 	addu	a1, a0			# stop pointer
@@ -45,9 +45,5 @@
 	jr	ra
 	END(__strnlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/lib/tinycon.c linux-2.4.20/arch/mips/lib/tinycon.c
--- linux-2.4.19/arch/mips/lib/tinycon.c	1997-06-26 19:33:37.000000000 +0000
+++ linux-2.4.20/arch/mips/lib/tinycon.c	2002-10-04 00:41:20.000000000 +0000
@@ -38,7 +38,7 @@
   cursor_y = 0;
 
   vram_addr = (unsigned short *)0xb00b8000;
-  
+
   console_needs_init = 0;
 }
 
@@ -87,7 +87,7 @@
     *(caddr++) = *(caddr + size_x);
 
   /* blank last line */
-  
+
   caddr = vram_addr + (size_x * (size_y-1));
   for(i=0; i<size_x; i++)
     *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/Makefile linux-2.4.20/arch/mips/math-emu/Makefile
--- linux-2.4.19/arch/mips/math-emu/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -16,6 +16,6 @@
 	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
 	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
 	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
-	   dp_sqrt.o sp_sqrt.o kernel_linkage.o
+	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/cp1emu.c linux-2.4.20/arch/mips/math-emu/cp1emu.c
--- linux-2.4.19/arch/mips/math-emu/cp1emu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/cp1emu.c	2002-10-04 00:41:29.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
- * 
+ *
  * MIPS floating point support
  * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
  * http://www.algor.co.uk
@@ -23,38 +23,30 @@
  *
  * A complete emulator for MIPS coprocessor 1 instructions.  This is
  * required for #float(switch) or #float(trap), where it catches all
- * COP1 instructions via the "CoProcessor Unusable" exception.  
+ * COP1 instructions via the "CoProcessor Unusable" exception.
  *
  * More surprisingly it is also required for #float(ieee), to help out
  * the hardware fpu at the boundaries of the IEEE-754 representation
  * (denormalised values, infinities, underflow, etc).  It is made
  * quite nasty because emulation of some non-COP1 instructions is
  * required, e.g. in branch delay slots.
- * 
- * Note if you know that you won't have an fpu, then you'll get much 
+ *
+ * Note if you know that you won't have an fpu, then you'll get much
  * better performance by compiling with -msoft-float!
  */
-#include <linux/compiler.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/asm.h>
-#include <asm/branch.h>
+#include <asm/inst.h>
 #include <asm/bootinfo.h>
-#include <asm/byteorder.h>
 #include <asm/cpu.h>
-#include <asm/inst.h>
-#include <asm/uaccess.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
 #include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
 #include <asm/fpu_emulator.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
 
 #include "ieee754.h"
+#include "dsemul.h"
 
 /* Strap kernel emulator for full MIPS IV emulation */
 
@@ -63,20 +55,14 @@
 #endif
 #define __mips 4
 
-typedef void *vaddr_t;
-
-/* Function which emulates the instruction in a branch delay slot. */
-
-static int mips_dsemul(struct pt_regs *, mips_instruction, unsigned long);
-
 /* Function which emulates a floating point instruction. */
 
 static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
-	 mips_instruction);
+	mips_instruction);
 
 #if __mips >= 4 && __mips != 32
 static int fpux_emu(struct pt_regs *,
-		    struct mips_fpu_soft_struct *, mips_instruction);
+	struct mips_fpu_soft_struct *, mips_instruction);
 #endif
 
 /* Further private data for which no space exists in mips_fpu_soft_struct */
@@ -108,8 +94,7 @@
 #endif
 
 
-
-/* 
+/*
  * Redundant with logic already in kernel/branch.c,
  * embedded in compute_return_epc.  At some point,
  * a single subroutine should be used across both
@@ -165,46 +150,70 @@
 	return 0;
 }
 
-#define REG_TO_VA (vaddr_t)
-#define VA_TO_REG (unsigned long)
-
 /*
  * In the Linux kernel, we support selection of FPR format on the
  * basis of the Status.FR bit.  This does imply that, if a full 32
  * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position.  In any case, normal MIPS ABI uses
+ * to one at that bit position.  In any case, O32 MIPS ABI uses
  * only the even FPRs (Status.FR = 0).
  */
 
 #define CP0_STATUS_FR_SUPPORT
 
+#ifdef CP0_STATUS_FR_SUPPORT
+#define FR_BIT ST0_FR
+#else
+#define FR_BIT 0
+#endif
+
+#define SIFROMREG(si,x)	((si) = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			(int)ctx->regs[x] : \
+			(int)(ctx->regs[x & ~1] >> 32 ))
+#define SITOREG(si,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			ctx->regs[x & ~1] >> 32 << 32 | (u32)(si) : \
+			ctx->regs[x & ~1] << 32 >> 32 | (u64)(si) << 32)
+
+#define DIFROMREG(di,x)	((di) = \
+			ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)])
+#define DITOREG(di,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
+			= (di))
+#define DIFROMREG(di,x)	((di) = \
+			ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)])
+#define DITOREG(di,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
+			= (di))
+
+#define SPFROMREG(sp,x)	SIFROMREG((sp).bits,x)
+#define SPTOREG(sp,x)	SITOREG((sp).bits,x)
+#define DPFROMREG(dp,x)	DIFROMREG((dp).bits,x)
+#define DPTOREG(dp,x)	DITOREG((dp).bits,x)
+
 /*
  * Emulate the single floating point instruction pointed at by EPC.
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int cop1Emulate(struct pt_regs *regs, struct mips_fpu_soft_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
 {
-	vaddr_t emulpc, contpc;
 	mips_instruction ir;
+	vaddr_t emulpc, contpc;
 	unsigned int cond;
-	int err = 0;
 
-	err = get_user(ir, (mips_instruction *) regs->cp0_epc);
-	if (err) {
+	if (get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) {
 		fpuemuprivate.stats.errors++;
 		return SIGBUS;
 	}
 
 	/* XXX NEC Vr54xx bug workaround */
-	if ((regs->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
-		regs->cp0_cause &= ~CAUSEF_BD;
+	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
+		xcp->cp0_cause &= ~CAUSEF_BD;
 
-	if (regs->cp0_cause & CAUSEF_BD) {
+	if (xcp->cp0_cause & CAUSEF_BD) {
 		/*
 		 * The instruction to be emulated is in a branch delay slot
 		 * which means that we have to  emulate the branch instruction
-		 * BEFORE we do the cop1 instruction. 
+		 * BEFORE we do the cop1 instruction.
 		 *
 		 * This branch could be a COP1 branch, but in that case we
 		 * would have had a trap for that instruction, and would not
@@ -213,368 +222,206 @@
 		 * Linux MIPS branch emulator operates on context, updating the
 		 * cp0_epc.
 		 */
-		emulpc = REG_TO_VA(regs->cp0_epc + 4);	/* Snapshot emulation target */
+		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
 
-		if (__compute_return_epc(regs)) {
+		if (__compute_return_epc(xcp)) {
 #ifdef CP1DBG
 			printk("failed to emulate branch at %p\n",
-				    REG_TO_VA(regs->cp0_epc));
+				REG_TO_VA(xcp->cp0_epc));
 #endif
 			return SIGILL;
 		}
-		err = get_user(ir, (mips_instruction *) emulpc);
-		if (err) {
+		if (get_user(ir, (mips_instruction *) emulpc)) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
 		/* __computer_return_epc() will have updated cp0_epc */
-		contpc = REG_TO_VA regs->cp0_epc;
+		contpc = REG_TO_VA xcp->cp0_epc;
 		/* In order not to confuse ptrace() et al, tweak context */
-		regs->cp0_epc = VA_TO_REG emulpc - 4;
-	} else {
-		emulpc = REG_TO_VA regs->cp0_epc;
-		contpc = REG_TO_VA regs->cp0_epc + 4;
+		xcp->cp0_epc = VA_TO_REG emulpc - 4;
+	}
+	else {
+		emulpc = REG_TO_VA xcp->cp0_epc;
+		contpc = REG_TO_VA(xcp->cp0_epc + 4);
 	}
 
-emul:
+      emul:
 	fpuemuprivate.stats.emulated++;
 	switch (MIPSInst_OPCODE(ir)) {
-#ifdef CP0_STATUS_FR_SUPPORT
-		/* R4000+ 64-bit fpu registers */
 #ifndef SINGLE_ONLY_FPU
-	case ldc1_op:
-		{
-			u64 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-
-			if (!(regs->cp0_status & ST0_FR))
-				ft &= ~1;
-			err = get_user(ctx->regs[ft], va);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+	case ldc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
+		DITOREG(val, MIPSInst_RT(ir));
 		break;
+	}
 
-	case sdc1_op:
-		{
-			fpureg_t *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			               MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-
-			if (!(regs->cp0_status & ST0_FR))
-				ft &= ~1;
-			fpuemuprivate.stats.stores++;
-			if (put_user(ctx->regs[ft], va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+	case sdc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.stores++;
+		DIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
 		break;
+	}
 #endif
 
-	case lwc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			               MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			u32 val;
+	case lwc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
 
-			fpuemuprivate.stats.loads++;
-			err = get_user(val, va);
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-			if (regs->cp0_status & ST0_FR) {
-				/* load whole register */
-				ctx->regs[ft] = (s64) val;
-			} else if (ft & 1) {
-				/* load to m.s. 32 bits */
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				ctx->regs[(ft & ~1)] &= 0xffffffff;
-				ctx->regs[(ft & ~1)] |= (fpureg_t) val << 32;
-#endif
-			} else {
-				/* load to l.s. 32 bits */
-				ctx->regs[ft] &= ~0xffffffffLL;
-				ctx->regs[ft] |= val;
-			}
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
-		break;
-
-	case swc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			unsigned int val;
-			int ft = MIPSInst_RT(ir);
-
-			fpuemuprivate.stats.stores++;
-			if (regs->cp0_status & ST0_FR) {
-				/* store whole register */
-				val = ctx->regs[ft];
-			} else if (ft & 1) {
 #ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				/* store from m.s. 32 bits */
-				val = ctx->regs[(ft & ~1)] >> 32;
-#endif
-			} else {
-				/* store from l.s. 32 bits */
-				val = ctx->regs[ft];
-			}
-			if (put_user(val, va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#else				/* old 32-bit fpu registers */
-	case lwc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			err = get_user(ctx->regs[MIPSInst_RT(ir)], va);
-
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			fpuemuprivate.stats.stores++;
-			if (put_user(ctx->regs[MIPSInst_RT(ir)], va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
 		}
-		break;
-	case ldc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			unsigned int rt = MIPSInst_RT(ir) & ~1;
-			int errs = 0;
-			fpuemuprivate.stats.loads++;
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			err = get_user(ctx->regs[rt + 1], va + 0);
-			err |= get_user(ctx->regs[rt + 0], va + 1);
-#else
-			err = get_user(ctx->regs[rt + 0], va + 0);
-			err |= get_user(ctx->regs[rt + 1], va + 1);
 #endif
-			if (err)
-				return SIGBUS;
-		}
+		SITOREG(val, MIPSInst_RT(ir));
 		break;
+	}
 
-	case sdc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			unsigned int rt = MIPSInst_RT(ir) & ~1;
+	case swc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
 
-			fpuemuprivate.stats.stores++;
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			if (put_user(ctx->regs[rt + 1], va + 0)
-			    || put_user(ctx->regs[rt + 0], va + 1))
-				return SIGBUS;
-#else
-			if (put_user(ctx->regs[rt + 0], va + 0)
-			    || put_user(ctx->regs[rt + 1], va + 1))
-				return SIGBUS;
+		fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
+		}
 #endif
+		SIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
 		break;
-#endif
+	}
 
 	case cop1_op:
 		switch (MIPSInst_RS(ir)) {
 
-#ifdef CP0_STATUS_FR_SUPPORT
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
 		case dmfc_op:
 			/* copregister fs -> gpr[rt] */
 			if (MIPSInst_RT(ir) != 0) {
-				int fs = MIPSInst_RD(ir);
-				if (!(regs->cp0_status & ST0_FR))
-					fs &= ~1;
-				regs->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
+				DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
 			}
 			break;
 
-		case dmtc_op: {
+		case dmtc_op:
 			/* copregister fs <- rt */
-				fpureg_t value;
-				int fs = MIPSInst_RD(ir);
-				if (!(regs->cp0_status & ST0_FR))
-					fs &= ~1;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
-				ctx->regs[fs] = value;
+			DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
 			break;
-		}
 #endif
 
 		case mfc_op:
 			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				/* default value from l.s. 32 bits */
-				int value = ctx->regs[MIPSInst_RD(ir)];
-				if (MIPSInst_RD(ir) & 1) {
 #ifdef SINGLE_ONLY_FPU
-					/* illegal register in single-float mode */
-					return SIGILL;
-#else
-					if (!(regs->cp0_status & ST0_FR)) {
-						/* move from m.s. 32 bits */
-						value =
-						    ctx->
-						    regs[MIPSInst_RD(ir) &
-							 ~1] >> 32;
-					}
-#endif
-				}
-				regs->regs[MIPSInst_RT(ir)] = value;
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
 			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				fpureg_t value;
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value =
-					    (unsigned int) regs->
-					    regs[MIPSInst_RT(ir)];
-				if (MIPSInst_RD(ir) & 1) {
-#ifdef SINGLE_ONLY_FPU
-					/* illegal register in single-float mode */
-					return SIGILL;
-#else
-					if (!(regs->cp0_status & ST0_FR)) {
-						/* move to m.s. 32 bits */
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] |=
-						    value << 32;
-						break;
-					}
 #endif
-				}
-				/* move to l.s. 32 bits */
-				ctx->regs[MIPSInst_RD(ir)] &=
-				    ~0xffffffffLL;
-				ctx->regs[MIPSInst_RD(ir)] |= value;
-			}
-			break;
-#else
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
 			if (MIPSInst_RT(ir) != 0) {
-				unsigned value =
-				    ctx->regs[MIPSInst_RD(ir)];
-				regs->regs[MIPSInst_RT(ir)] = value;
+				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
 			}
 			break;
 
 		case mtc_op:
 			/* copregister rd <- rt */
-			{
-				unsigned value;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
-				ctx->regs[MIPSInst_RD(ir)] = value;
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
 			}
-			break;
 #endif
+			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+			break;
 
-		case cfc_op:
+		case cfc_op:{
 			/* cop control register rd -> gpr[rt] */
-			{
-				unsigned value;
+			u32 value;
 
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-					value = ctx->sr;
+			if (ir == CP1UNDEF) {
+				return do_dsemulret(xcp);
+			}
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+				value = ctx->sr;
 #ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]<-csr=%08x\n",
-					     REG_TO_VA(regs->cp0_epc),
-					     MIPSInst_RT(ir), value);
+				printk("%p gpr[%d]<-csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
 #endif
-				} else if (MIPSInst_RD(ir) == FPCREG_RID)
-					value = 0;
-				else
-					value = 0;
-				if (MIPSInst_RT(ir))
-					regs->regs[MIPSInst_RT(ir)] = value;
 			}
+			else if (MIPSInst_RD(ir) == FPCREG_RID)
+				value = 0;
+			else
+				value = 0;
+			if (MIPSInst_RT(ir))
+				xcp->regs[MIPSInst_RT(ir)] = value;
 			break;
+		}
 
-		case ctc_op:
+		case ctc_op:{
 			/* copregister rd <- rt */
-			{
-				unsigned value;
-
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value = regs->regs[MIPSInst_RT(ir)];
+			u32 value;
 
-				/* we only have one writable control reg
-				 */
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
+			if (MIPSInst_RT(ir) == 0)
+				value = 0;
+			else
+				value = xcp->regs[MIPSInst_RT(ir)];
+
+			/* we only have one writable control reg
+			 */
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
 #ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]->csr=%08x\n",
-					     REG_TO_VA(regs->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-					ctx->sr = value;
-					/* copy new rounding mode and
-					   flush bit to ieee library state! */
-					ieee754_csr.nod =
-					    (ctx->sr & 0x1000000) != 0;
-					ieee754_csr.rm =
-					    ieee_rm[value & 0x3];
-				}
+				printk("%p gpr[%d]->csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
+#endif
+				ctx->sr = value;
+				/* copy new rounding mode and
+				   flush bit to ieee library state! */
+				ieee754_csr.nod = (ctx->sr & 0x1000000) != 0;
+				ieee754_csr.rm = ieee_rm[value & 0x3];
+			}
+			if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
+				return SIGFPE;
 			}
 			break;
+		}
 
-		case bc_op: {
+		case bc_op:{
 			int likely = 0;
 
-			if (regs->cp0_cause & CAUSEF_BD)
+			if (xcp->cp0_cause & CAUSEF_BD)
 				return SIGILL;
 
 #if __mips >= 4
-			cond = ctx-> sr & fpucondbit[MIPSInst_RT(ir) >> 2];
+			cond = ctx->sr & fpucondbit[MIPSInst_RT(ir) >> 2];
 #else
 			cond = ctx->sr & FPU_CSR_COND;
 #endif
@@ -593,16 +440,18 @@
 				return SIGILL;
 			}
 
-			regs->cp0_cause |= CAUSEF_BD;
+			xcp->cp0_cause |= CAUSEF_BD;
 			if (cond) {
-				/* branch taken: emulate dslot instruction */
-				regs->cp0_epc += 4;
-				contpc = REG_TO_VA regs->cp0_epc +
-				                   (MIPSInst_SIMM(ir) << 2);
-
-				err = get_user(ir,
-					(mips_instruction *)regs->cp0_epc);
-				if (err) {
+				/* branch taken: emulate dslot
+				 * instruction
+				 */
+				xcp->cp0_epc += 4;
+				contpc = REG_TO_VA
+					(xcp->cp0_epc +
+					(MIPSInst_SIMM(ir) << 2));
+
+				if (get_user(ir, (mips_instruction *)
+						REG_TO_VA xcp->cp0_epc)) {
 					fpuemuprivate.stats.errors++;
 					return SIGBUS;
 				}
@@ -629,49 +478,50 @@
 				}
 
 				/*
-				 * Single step the non-cp1 instruction in the
-				 * dslot
+				 * Single step the non-cp1
+				 * instruction in the dslot
 				 */
-				return mips_dsemul(regs, ir, contpc);
-			} else {
+				return mips_dsemul(xcp, ir, VA_TO_REG contpc);
+			}
+			else {
 				/* branch not taken */
 				if (likely) {
 					/*
-					 * branch likely nullifies dslot if not
-					 * taken
+					 * branch likely nullifies
+					 * dslot if not taken
 					 */
-					regs->cp0_epc += 4;
+					xcp->cp0_epc += 4;
 					contpc += 4;
 					/*
-					 * else continue & execute dslot as
-					 * normal insn
+					 * else continue & execute
+					 * dslot as normal insn
 					 */
 				}
 			}
 			break;
 		}
 
-		default: {
-			int sig;
-
+		default:
 			if (!(MIPSInst_RS(ir) & 0x10))
 				return SIGILL;
+			{
+				int sig;
 
-			/* a real fpu computation instruction */
-				if ((sig = fpu_emu(regs, ctx, ir)))
+				/* a real fpu computation instruction */
+				if ((sig = fpu_emu(xcp, ctx, ir)))
 					return sig;
 			}
 		}
 		break;
 
 #if __mips >= 4 && __mips != 32
-	case cop1x_op:
-		{
-			int sig;
-			if ((sig = fpux_emu(regs, ctx, ir)))
-				return sig;
-		}
+	case cop1x_op:{
+		int sig;
+
+		if ((sig = fpux_emu(xcp, ctx, ir)))
+			return sig;
 		break;
+	}
 #endif
 
 #if __mips >= 4
@@ -681,7 +531,7 @@
 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
 		if (((ctx->sr & cond) != 0) != ((MIPSInst_RT(ir) & 1) != 0))
 			return 0;
-		regs->regs[MIPSInst_RD(ir)] = regs->regs[MIPSInst_RS(ir)];
+		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
 		break;
 #endif
 
@@ -690,194 +540,26 @@
 	}
 
 	/* we did it !! */
-	regs->cp0_epc = VA_TO_REG(contpc);
-	regs->cp0_cause &= ~CAUSEF_BD;
+	xcp->cp0_epc = VA_TO_REG(contpc);
+	xcp->cp0_cause &= ~CAUSEF_BD;
 	return 0;
 }
 
 /*
- * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
- * we have to emulate the instruction in a COP1 branch delay slot.  Do
- * not change cp0_epc due to the instruction
- *
- * According to the spec:
- * 1) it shouldnt be a branch :-)
- * 2) it can be a COP instruction :-(
- * 3) if we are tring to run a protected memory space we must take
- *    special care on memory access instructions :-(
- */
-
-/*
- * "Trampoline" return routine to catch exception following
- *  execution of delay-slot instruction execution.
- */
-
-/* Instruction inserted following delay slot instruction to force trap */
-#define AdELOAD 0x8c000001	/* lw $0,1($0) */
-
-/* Instruction inserted following the AdELOAD to further tag the sequence */
-#define BD_COOKIE 0x0000bd36	/* tne $0,$0 with baggage */
-
-struct emuframe {
-	mips_instruction	emul;
-	mips_instruction	adel;
-	mips_instruction	cookie;
-	unsigned long	epc;
-};
-
-int do_dsemulret(struct pt_regs *xcp)
-{
-	struct emuframe *fr;
-	unsigned long epc;
-	u32 insn, cookie;
-	int err = 0;
-
-	fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction));
-
-	/* 
-	 * If we can't even access the area, something is very wrong, but we'll
-	 * leave that to the default handling
-	 */
-	if (verify_area(VERIFY_READ, fr, sizeof(struct emuframe)))
-		return 0;
-
-	/*
-	 * Do some sanity checking on the stackframe:
-	 *
-	 *  - Is the instruction pointed to by the EPC an AdELOAD?
-	 *  - Is the following memory word the BD_COOKIE?
-	 */
-	err = __get_user(insn, &fr->adel);
-	err |= __get_user(cookie, &fr->cookie);
-
-	if (unlikely(err || (insn != AdELOAD) || (cookie != BD_COOKIE))) {
-		fpuemuprivate.stats.errors++;
-
-		return 0;
-	}
-
-	/* 
-	 * At this point, we are satisfied that it's a BD emulation trap.  Yes,
-	 * a user might have deliberately put two malformed and useless
-	 * instructions in a row in his program, in which case he's in for a
-	 * nasty surprise - the next instruction will be treated as a
-	 * continuation address!  Alas, this seems to be the only way that we
-	 * can handle signals, recursion, and longjmps() in the context of
-	 * emulating the branch delay instruction.
-	 */
-
-#ifdef DSEMUL_TRACE
-	printk("desemulret\n");
-#endif
-	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
-		/* This is not a good situation to be in */
-		force_sig(SIGBUS, current);
-
-		return 1;
-	}
-
-	/* Set EPC to return to post-branch instruction */
-	xcp->cp0_epc = epc;
-
-	return 1;
-}
-
-static int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
-	unsigned long cpc)
-{
-	extern asmlinkage void handle_dsemulret(void);
-	mips_instruction *dsemul_insns;
-	struct emuframe *fr;
-	int err;
-
-	if (ir == 0) {		/* a nop is easy */
-		regs->cp0_epc = cpc;
-		regs->cp0_cause &= ~CAUSEF_BD;
-		return 0;
-	}
-#ifdef DSEMUL_TRACE
-	printk("desemul %lx %lx\n", regs->cp0_epc, cpc);
-
-#endif
- 
-	/* 
-	 * The strategy is to push the instruction onto the user stack 
-	 * and put a trap after it which we can catch and jump to 
-	 * the required address any alternative apart from full 
-	 * instruction emulation!!.
-	 *
-	 * Algorithmics used a system call instruction, and
-	 * borrowed that vector.  MIPS/Linux version is a bit
-	 * more heavyweight in the interests of portability and
-	 * multiprocessor support.  We flag the thread for special
-	 * handling in the unaligned access handler and force an
-	 * address error excpetion.
-	 */
-
-	/* Ensure that the two instructions are in the same cache line */
-	dsemul_insns = (mips_instruction *) (regs->regs[29] & ~0xf);
-	dsemul_insns -= 4;	/* Retain 16-byte alignment */
-	fr = (struct emuframe *) dsemul_insns;
-
-	/* Verify that the stack pointer is not competely insane */
-	if (unlikely(verify_area(VERIFY_WRITE, fr, sizeof(struct emuframe))))
-		return SIGBUS;
-
-	err = __put_user(ir, &dsemul_insns[0]);
-	err |= __put_user((mips_instruction)AdELOAD, &fr->adel);
-	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
-	err |= __put_user(cpc, &fr->epc);
-
-	if (unlikely(err)) {
-		fpuemuprivate.stats.errors++;
-		return SIGBUS;
-	}
-
-	regs->cp0_epc = VA_TO_REG & dsemul_insns[0];
-
-	flush_cache_sigtramp((unsigned long)&fr->adel);
-
-	return SIGILL;		/* force out of emulation loop */
-}
-
-/* 
  * Conversion table from MIPS compare ops 48-63
- * cond = ieee754dp_cmp(x,y,IEEE754_UN);
+ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
  */
 static const unsigned char cmptab[8] = {
-	0,					/* cmp_0 (sig) cmp_sf */
-	IEEE754_CUN,				/* cmp_un (sig) cmp_ngle */
-	IEEE754_CEQ,				/* cmp_eq (sig) cmp_seq */
-	IEEE754_CEQ | IEEE754_CUN,		/* cmp_ueq (sig) cmp_ngl  */
-	IEEE754_CLT,				/* cmp_olt (sig) cmp_lt */
-	IEEE754_CLT | IEEE754_CUN,		/* cmp_ult (sig) cmp_nge */
-	IEEE754_CLT | IEEE754_CEQ,		/* cmp_ole (sig) cmp_le */
-	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
+	0,			/* cmp_0 (sig) cmp_sf */
+	IEEE754_CUN,		/* cmp_un (sig) cmp_ngle */
+	IEEE754_CEQ,		/* cmp_eq (sig) cmp_seq */
+	IEEE754_CEQ | IEEE754_CUN,	/* cmp_ueq (sig) cmp_ngl  */
+	IEEE754_CLT,		/* cmp_olt (sig) cmp_lt */
+	IEEE754_CLT | IEEE754_CUN,	/* cmp_ult (sig) cmp_nge */
+	IEEE754_CLT | IEEE754_CEQ,	/* cmp_ole (sig) cmp_le */
+	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,	/* cmp_ule (sig) cmp_ngt */
 };
 
-#define SIFROMREG(si,x)	((si) = ctx->regs[x])
-#define SITOREG(si,x)	(ctx->regs[x] = (int)(si))
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-#define DIFROMREG(di,x)	((di) = ctx->regs[x])
-#define DITOREG(di,x)	(ctx->regs[x] = (di))
-#endif
-
-#define SPFROMREG(sp,x)	((sp).bits = ctx->regs[x])
-#define SPTOREG(sp,x)	(ctx->regs[x] = (sp).bits)
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#define DPFROMREG(dp,x)	((dp).bits = \
-	ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)])
-#define DPTOREG(dp,x)	(ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)] \
-	= (dp).bits)
-#else
-/* Beware: MIPS COP1 doubles are always little_word endian in registers */
-#define DPFROMREG(dp,x)	\
-	((dp).bits = ((u64)ctx->regs[(x)+1] << 32) | ctx->regs[x])
-#define DPTOREG(dp,x) \
-	(ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
-#endif
 
 #if __mips >= 4 && __mips != 32
 
@@ -889,17 +571,17 @@
 static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
     ieee754##p t) \
 { \
-    struct ieee754_csr ieee754_csr_save; \
-    s = f1 (s, t); \
-    ieee754_csr_save = ieee754_csr; \
-    s = f2 (s, r); \
-    ieee754_csr_save.cx |= ieee754_csr.cx; \
-    ieee754_csr_save.sx |= ieee754_csr.sx; \
-    s = f3 (s); \
-    ieee754_csr.cx |= ieee754_csr_save.cx; \
-    ieee754_csr.sx |= ieee754_csr_save.sx; \
-    return s; \
-}    
+	struct ieee754_csr ieee754_csr_save; \
+	s = f1 (s, t); \
+	ieee754_csr_save = ieee754_csr; \
+	s = f2 (s, r); \
+	ieee754_csr_save.cx |= ieee754_csr.cx; \
+	ieee754_csr_save.sx |= ieee754_csr.sx; \
+	s = f3 (s); \
+	ieee754_csr.cx |= ieee754_csr_save.cx; \
+	ieee754_csr.sx |= ieee754_csr_save.sx; \
+	return s; \
+}
 
 static ieee754dp fpemu_dp_recip(ieee754dp d)
 {
@@ -921,233 +603,184 @@
 	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
 }
 
-DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
-DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
+DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,);
+DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,);
 DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
 DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
-DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
-DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
+DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,);
+DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,);
 DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
 DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
 
 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-                    mips_instruction ir)
+	mips_instruction ir)
 {
 	unsigned rcsr = 0;	/* resulting csr */
 
 	fpuemuprivate.stats.cp1xops++;
 
 	switch (MIPSInst_FMA_FFMT(ir)) {
-	case s_fmt:		/* 0 */
-		{
-			ieee754sp(*handler) (ieee754sp, ieee754sp,
-					     ieee754sp);
-			ieee754sp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case lwxc1_op:
-				{
-					u32 *va = REG_TO_VA(
-						xcp->regs[MIPSInst_FR(ir)] +
-						xcp->regs[MIPSInst_FT(ir)]);
-					fpureg_t val;
-
-					if (get_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-					if (xcp->cp0_status & ST0_FR) {
-						/* load whole register */
-						ctx->regs[MIPSInst_FD(ir)] =
-						    val;
-					} else if (MIPSInst_FD(ir) & 1) {
-						/* load to m.s. 32 bits */
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] |=
-						    val << 32;
-#endif
-					} else {
-						/* load to l.s. 32 bits */
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    &= ~0xffffffffLL;
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    |= val;
-					}
-				}
-				break;
+	case s_fmt:{		/* 0 */
 
-			case swxc1_op:
-				{
-					u32 *va = REG_TO_VA(
-						xcp->regs[MIPSInst_FR(ir)] +
-						xcp->regs[MIPSInst_FT(ir)]);
-					unsigned int val;
-
-					if (xcp->cp0_status & ST0_FR) {
-						/* store whole register */
-						val = ctx->regs[MIPSInst_FS(ir)];
-					} else if (MIPSInst_FS(ir) & 1) {
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						/* store from m.s. 32 bits */
-						val = ctx->regs[(MIPSInst_FS(ir) & ~1)] >> 32;
+		ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
+		ieee754sp fd, fr, fs, ft;
+		u32 *va;
+		u32 val;
+
+		switch (MIPSInst_FUNC(ir)) {
+		case lwxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FD(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
 #endif
-					} else {
-						/* store from l.s. 32 bits */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
-					}
-					if (put_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-				}
-				break;
+			SITOREG(val, MIPSInst_FD(ir));
+			break;
 
-			case madd_s_op:
-				handler = fpemu_sp_madd;
-				goto scoptop;
-			case msub_s_op:
-				handler = fpemu_sp_msub;
-				goto scoptop;
-			case nmadd_s_op:
-				handler = fpemu_sp_nmadd;
-				goto scoptop;
-			case nmsub_s_op:
-				handler = fpemu_sp_nmsub;
-				goto scoptop;
+		case swxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			      scoptop:
-				SPFROMREG(fr, MIPSInst_FR(ir));
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				SPTOREG(fd, MIPSInst_FD(ir));
+			fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FS(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
+#endif
 
-			      copcsr:
-				if (ieee754_cxtest(IEEE754_INEXACT))
-					rcsr |=
-					    FPU_CSR_INE_X | FPU_CSR_INE_S;
-				if (ieee754_cxtest(IEEE754_UNDERFLOW))
-					rcsr |=
-					    FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-				if (ieee754_cxtest(IEEE754_OVERFLOW))
-					rcsr |=
-					    FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-				if (ieee754_cxtest
-				    (IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-
-				ctx->sr =
-				    (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
-				if (ieee754_csr.nod)
-				    ctx->sr |= 0x1000000;
-				if ((ctx->sr >> 5) & ctx->
-				    sr & FPU_CSR_ALL_E) {
-		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
-					return SIGFPE;
-				}
+			SIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			break;
 
-				break;
+		case madd_s_op:
+			handler = fpemu_sp_madd;
+			goto scoptop;
+		case msub_s_op:
+			handler = fpemu_sp_msub;
+			goto scoptop;
+		case nmadd_s_op:
+			handler = fpemu_sp_nmadd;
+			goto scoptop;
+		case nmsub_s_op:
+			handler = fpemu_sp_nmsub;
+			goto scoptop;
 
-			default:
-				return SIGILL;
+		      scoptop:
+			SPFROMREG(fr, MIPSInst_FR(ir));
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			SPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			SPTOREG(fd, MIPSInst_FD(ir));
+
+		      copcsr:
+			if (ieee754_cxtest(IEEE754_INEXACT))
+				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+			if (ieee754_cxtest(IEEE754_UNDERFLOW))
+				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+			if (ieee754_cxtest(IEEE754_OVERFLOW))
+				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+
+			ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
+			if (ieee754_csr.nod)
+				ctx->sr |= 0x1000000;
+			if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
+				/*printk ("SIGFPE: fpu csr = %08x\n",
+				   ctx->sr); */
+				return SIGFPE;
 			}
+
+			break;
+
+		default:
+			return SIGILL;
 		}
 		break;
+	}
 
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:		/* 1 */
-		{
-			ieee754dp(*handler) (ieee754dp, ieee754dp,
-					     ieee754dp);
-			ieee754dp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case ldxc1_op:
-				{
-					u64 *va = REG_TO_VA(
-						xcp->regs[MIPSInst_FR(ir)] +
-						xcp->regs[MIPSInst_FT(ir)]);
-					u64 val;
-
-					if (get_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-					ctx->regs[MIPSInst_FD(ir)] = val;
-				}
-				break;
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{		/* 1 */
+		ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
+		ieee754dp fd, fr, fs, ft;
+		u64 *va;
+		u64 val;
 
-			case sdxc1_op:
-				{
-					u64 *va = REG_TO_VA(
-						xcp->regs[MIPSInst_FR(ir)] +
-						xcp->regs[MIPSInst_FT(ir)]);
-					u64 val;
-
-					val = ctx->regs[MIPSInst_FS(ir)];
-					if (put_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-				}
-				break;
+		switch (MIPSInst_FUNC(ir)) {
+		case ldxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			case madd_d_op:
-				handler = fpemu_dp_madd;
-				goto dcoptop;
-
-			case msub_d_op:
-				handler = fpemu_dp_msub;
-				goto dcoptop;
-
-			case nmadd_d_op:
-				handler = fpemu_dp_nmadd;
-				goto dcoptop;
-
-			case nmsub_d_op:
-				handler = fpemu_dp_nmsub;
-				goto dcoptop;
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			DITOREG(val, MIPSInst_FD(ir));
+			break;
 
-			      dcoptop:
-				DPFROMREG(fr, MIPSInst_FR(ir));
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				DPTOREG(fd, MIPSInst_FD(ir));
-				goto copcsr;
+		case sdxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			default:
-				return SIGILL;
+			fpuemuprivate.stats.stores++;
+			DIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
 			}
+			break;
+
+		case madd_d_op:
+			handler = fpemu_dp_madd;
+			goto dcoptop;
+		case msub_d_op:
+			handler = fpemu_dp_msub;
+			goto dcoptop;
+		case nmadd_d_op:
+			handler = fpemu_dp_nmadd;
+			goto dcoptop;
+		case nmsub_d_op:
+			handler = fpemu_dp_nmsub;
+			goto dcoptop;
+
+		      dcoptop:
+			DPFROMREG(fr, MIPSInst_FR(ir));
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			DPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			DPTOREG(fd, MIPSInst_FD(ir));
+			goto copcsr;
+
+		default:
+			return SIGILL;
 		}
 		break;
+	}
 #endif
 
 	case 0x7:		/* 7 */
-		{
-			if (MIPSInst_FUNC(ir) != pfetch_op) {
-				return SIGILL;
-			}
-			/* ignore prefx operation */
+		if (MIPSInst_FUNC(ir) != pfetch_op) {
+			return SIGILL;
 		}
+		/* ignore prefx operation */
 		break;
 
 	default:
@@ -1164,7 +797,7 @@
  * Emulate a single COP1 arithmetic instruction.
  */
 static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-                   mips_instruction ir)
+	mips_instruction ir)
 {
 	int rfmt;		/* resulting format */
 	unsigned rcsr = 0;	/* resulting csr */
@@ -1174,49 +807,52 @@
 		ieee754sp s;
 		int w;
 #if __mips64
-		long long l;
+		s64 l;
 #endif
 	} rv;			/* resulting value */
 
 	fpuemuprivate.stats.cp1ops++;
 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
-	case s_fmt: {		/* 0 */
-		ieee754sp(*handler) ();
+	case s_fmt:{		/* 0 */
+		union {
+			ieee754sp(*b) (ieee754sp, ieee754sp);
+			ieee754sp(*u) (ieee754sp);
+		} handler;
 
 		switch (MIPSInst_FUNC(ir)) {
 			/* binary ops */
 		case fadd_op:
-			handler = ieee754sp_add;
+			handler.b = ieee754sp_add;
 			goto scopbop;
 		case fsub_op:
-			handler = ieee754sp_sub;
+			handler.b = ieee754sp_sub;
 			goto scopbop;
 		case fmul_op:
-			handler = ieee754sp_mul;
+			handler.b = ieee754sp_mul;
 			goto scopbop;
 		case fdiv_op:
-			handler = ieee754sp_div;
+			handler.b = ieee754sp_div;
 			goto scopbop;
 
 			/* unary  ops */
 #if __mips >= 2 || __mips64
 		case fsqrt_op:
-			handler = ieee754sp_sqrt;
+			handler.u = ieee754sp_sqrt;
 			goto scopuop;
 #endif
 #if __mips >= 4 && __mips != 32
 		case frsqrt_op:
-			handler = fpemu_sp_rsqrt;
+			handler.u = fpemu_sp_rsqrt;
 			goto scopuop;
 		case frecip_op:
-			handler = fpemu_sp_recip;
+			handler.u = fpemu_sp_recip;
 			goto scopuop;
 #endif
 #if __mips >= 4
 		case fmovc_op:
 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
 			if (((ctx->sr & cond) != 0) !=
-			    ((MIPSInst_FT(ir) & 1) != 0))
+				((MIPSInst_FT(ir) & 1) != 0))
 				return 0;
 			SPFROMREG(rv.s, MIPSInst_FS(ir));
 			break;
@@ -1232,10 +868,10 @@
 			break;
 #endif
 		case fabs_op:
-			handler = ieee754sp_abs;
+			handler.u = ieee754sp_abs;
 			goto scopuop;
 		case fneg_op:
-			handler = ieee754sp_neg;
+			handler.u = ieee754sp_neg;
 			goto scopuop;
 		case fmov_op:
 			/* an easy one */
@@ -1243,25 +879,25 @@
 			goto copcsr;
 
 			/* binary op on handler */
-scopbop:
+		      scopbop:
 			{
 				ieee754sp fs, ft;
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
 				SPFROMREG(ft, MIPSInst_FT(ir));
 
-				rv.s = (*handler) (fs, ft);
+				rv.s = (*handler.b) (fs, ft);
 				goto copcsr;
 			}
-scopuop:
+		      scopuop:
 			{
 				ieee754sp fs;
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = (*handler) (fs);
+				rv.s = (*handler.u) (fs);
 				goto copcsr;
 			}
-copcsr:
+		      copcsr:
 			if (ieee754_cxtest(IEEE754_INEXACT))
 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
 			if (ieee754_cxtest(IEEE754_UNDERFLOW))
@@ -1270,15 +906,14 @@
 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
 			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
 				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
-			if (ieee754_cxtest
-				(IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-				break;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+			break;
 
-				/* unary conv ops */
+			/* unary conv ops */
 		case fcvts_op:
 			return SIGILL;	/* not defined */
-		case fcvtd_op: {
+		case fcvtd_op:{
 #ifdef SINGLE_ONLY_FPU
 			return SIGILL;	/* not defined */
 #else
@@ -1290,7 +925,7 @@
 			goto copcsr;
 		}
 #endif
-		case fcvtw_op: {
+		case fcvtw_op:{
 			ieee754sp fs;
 
 			SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1303,7 +938,7 @@
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op: {
+		case ffloor_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754sp fs;
 
@@ -1317,7 +952,7 @@
 #endif /* __mips >= 2 */
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op: {
+		case fcvtl_op:{
 			ieee754sp fs;
 
 			SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1329,7 +964,7 @@
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op: {
+		case ffloorl_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754sp fs;
 
@@ -1349,14 +984,17 @@
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
 				SPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]);
+				rv.w = ieee754sp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
 				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				if ((cmpop & 0x8) && ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
 				else
 					goto copcsr;
 
-			} else {
+			}
+			else {
 				return SIGILL;
 			}
 			break;
@@ -1364,43 +1002,47 @@
 		break;
 	}
 
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt: {
-		ieee754dp(*handler) ();
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{
+		union {
+			ieee754dp(*b) (ieee754dp, ieee754dp);
+			ieee754dp(*u) (ieee754dp);
+		} handler;
 
 		switch (MIPSInst_FUNC(ir)) {
 			/* binary ops */
 		case fadd_op:
-			handler = ieee754dp_add;
+			handler.b = ieee754dp_add;
 			goto dcopbop;
 		case fsub_op:
-			handler = ieee754dp_sub;
+			handler.b = ieee754dp_sub;
 			goto dcopbop;
 		case fmul_op:
-			handler = ieee754dp_mul;
+			handler.b = ieee754dp_mul;
 			goto dcopbop;
 		case fdiv_op:
-			handler = ieee754dp_div;
+			handler.b = ieee754dp_div;
 			goto dcopbop;
 
 			/* unary  ops */
 #if __mips >= 2 || __mips64
 		case fsqrt_op:
-			handler = ieee754dp_sqrt;
+			handler.u = ieee754dp_sqrt;
 			goto dcopuop;
 #endif
 #if __mips >= 4 && __mips != 32
 		case frsqrt_op:
-			handler = fpemu_dp_rsqrt;
+			handler.u = fpemu_dp_rsqrt;
 			goto dcopuop;
 		case frecip_op:
-			handler = fpemu_dp_recip;
+			handler.u = fpemu_dp_recip;
 			goto dcopuop;
 #endif
 #if __mips >= 4
 		case fmovc_op:
 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0))
+			if (((ctx->sr & cond) != 0) !=
+				((MIPSInst_FT(ir) & 1) != 0))
 				return 0;
 			DPFROMREG(rv.d, MIPSInst_FS(ir));
 			break;
@@ -1416,11 +1058,11 @@
 			break;
 #endif
 		case fabs_op:
-			handler = ieee754dp_abs;
+			handler.u = ieee754dp_abs;
 			goto dcopuop;
 
 		case fneg_op:
-			handler = ieee754dp_neg;
+			handler.u = ieee754dp_neg;
 			goto dcopuop;
 
 		case fmov_op:
@@ -1429,27 +1071,25 @@
 			goto copcsr;
 
 			/* binary op on handler */
-dcopbop:
-			{
+		      dcopbop:{
 				ieee754dp fs, ft;
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
 				DPFROMREG(ft, MIPSInst_FT(ir));
 
-				rv.d = (*handler) (fs, ft);
+				rv.d = (*handler.b) (fs, ft);
 				goto copcsr;
 			}
-dcopuop:
-			{
+		      dcopuop:{
 				ieee754dp fs;
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = (*handler) (fs);
+				rv.d = (*handler.u) (fs);
 				goto copcsr;
 			}
 
-		/* unary conv ops */
-		case fcvts_op: {
+			/* unary conv ops */
+		case fcvts_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1460,7 +1100,7 @@
 		case fcvtd_op:
 			return SIGILL;	/* not defined */
 
-		case fcvtw_op: {
+		case fcvtw_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1473,7 +1113,7 @@
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op: {
+		case ffloor_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754dp fs;
 
@@ -1487,7 +1127,7 @@
 #endif
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op: {
+		case fcvtl_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1499,7 +1139,7 @@
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op: {
+		case ffloorl_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754dp fs;
 
@@ -1519,33 +1159,42 @@
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
 				DPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]);
+				rv.w = ieee754dp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
 				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
+				if ((cmpop & 0x8)
+					&&
+					ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
 				else
 					goto copcsr;
 
-			} else {
+			}
+			else {
 				return SIGILL;
 			}
 			break;
 		}
 		break;
 	}
-#endif /* !defined(SINGLE_ONLY_FPU) */
+#endif /* ifndef SINGLE_ONLY_FPU */
+
+	case w_fmt:{
+		ieee754sp fs;
 
-	case w_fmt: {
 		switch (MIPSInst_FUNC(ir)) {
 		case fcvts_op:
 			/* convert word to single precision real */
-			rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]);
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.s = ieee754sp_fint(fs.bits);
 			rfmt = s_fmt;
 			goto copcsr;
-#if !defined(SINGLE_ONLY_FPU)
+#ifndef SINGLE_ONLY_FPU
 		case fcvtd_op:
 			/* convert word to double precision real */
-			rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]);
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.d = ieee754dp_fint(fs.bits);
 			rfmt = d_fmt;
 			goto copcsr;
 #endif
@@ -1556,16 +1205,16 @@
 	}
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt: {
+	case l_fmt:{
 		switch (MIPSInst_FUNC(ir)) {
 		case fcvts_op:
 			/* convert long to single precision real */
-			rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]);
+			rv.s = ieee754sp_flong(ctx->regs[MIPSInst_FS(ir)]);
 			rfmt = s_fmt;
 			goto copcsr;
 		case fcvtd_op:
 			/* convert long to double precision real */
-			rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]);
+			rv.d = ieee754dp_flong(ctx->regs[MIPSInst_FS(ir)]);
 			rfmt = d_fmt;
 			goto copcsr;
 		default:
@@ -1592,11 +1241,11 @@
 		return SIGFPE;
 	}
 
-	/* 
+	/*
 	 * Now we can safely write the result back to the register file.
 	 */
 	switch (rfmt) {
-	case -1: {
+	case -1:{
 #if __mips >= 4
 		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
 #else
@@ -1608,7 +1257,7 @@
 			ctx->sr &= ~cond;
 		break;
 	}
-#if !defined(SINGLE_ONLY_FPU)
+#ifndef SINGLE_ONLY_FPU
 	case d_fmt:
 		DPTOREG(rv.d, MIPSInst_FD(ir));
 		break;
@@ -1631,16 +1280,10 @@
 	return 0;
 }
 
-
-/*
- * Emulate the floating point instruction at EPC, and continue to run until we
- * hit a non-fp instruction, or a backward branch.  This cuts down dramatically
- * on the per instruction exception overhead.
- */
-int fpu_emulator_cop1Handler(struct pt_regs *xcp)
+int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx)
 {
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned long oldepc, prevepc;
+	gpreg_t oldepc, prevepc;
 	mips_instruction insn, *insnp;
 	int sig = 0;
 
@@ -1652,9 +1295,10 @@
 		 * This is a braindead way to do it but the only sane way I
 		 * found to keep the 64-bit egcs 1.1.2 from crashing.
 		 */
-		insnp = (mips_instruction *) xcp->cp0_epc;
+		insnp = (mips_instruction *) REG_TO_VA xcp->cp0_epc;
+
 		if (verify_area(VERIFY_READ, insnp, 4) ||
-		    __get_user(insn, insnp)) {
+			__get_user(insn, insnp)) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
@@ -1673,9 +1317,13 @@
 			break;
 		if (sig)
 			break;
-
+#ifdef STANDALONE_EMULATOR
+		if (xcptno == EX_FPE)
+			break;
+#else
 		if (current->need_resched)
 			schedule();
+#endif
 	} while (xcp->cp0_epc > prevepc);
 
 	/* SIGILL indicates a non-fpu instruction */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_add.c linux-2.4.20/arch/mips/math-emu/dp_add.c
--- linux-2.4.19/arch/mips/math-emu/dp_add.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_add.c	2002-10-04 00:41:14.000000000 +0000
@@ -70,7 +70,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_cmp.c linux-2.4.20/arch/mips/math-emu/dp_cmp.c
--- linux-2.4.19/arch/mips/math-emu/dp_cmp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_cmp.c	2002-10-04 00:41:14.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp)
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
 {
 	COMPXDP;
 	COMPYDP;
@@ -39,18 +39,18 @@
 	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
-		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
 			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
+			if (sig && SETCX(IEEE754_INVALID_OPERATION))
 				return ieee754si_xcpt(0, "fcmpf", x);
 		}
 		return 0;
 	} else {
-		long long int vx = x.bits;
-		long long int vy = y.bits;
+		s64 vx = x.bits;
+		s64 vy = y.bits;
 
 		if (vx < 0)
 			vx = -vx ^ DP_SIGN_BIT;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_div.c linux-2.4.20/arch/mips/math-emu/dp_div.c
--- linux-2.4.19/arch/mips/math-emu/dp_div.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_div.c	2002-10-04 00:41:10.000000000 +0000
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -86,7 +86,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754dp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -126,9 +126,9 @@
 	{
 		/* now the dirty work */
 
-		unsigned long long rm = 0;
+		u64 rm = 0;
 		int re = xe - ye;
-		unsigned long long bm;
+		u64 bm;
 
 		for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
 			if (xm >= ym) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_flong.c linux-2.4.20/arch/mips/math-emu/dp_flong.c
--- linux-2.4.19/arch/mips/math-emu/dp_flong.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_flong.c	2002-10-04 00:41:11.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-ieee754dp ieee754dp_flong(long long x)
+ieee754dp ieee754dp_flong(s64 x)
 {
 	COMPXDP;
 
@@ -67,9 +67,9 @@
 	DPNORMRET1(xs, xe, xm, "dp_flong", x);
 }
 
-ieee754dp ieee754dp_fulong(unsigned long long u)
+ieee754dp ieee754dp_fulong(u64 u)
 {
-	if ((long long) u < 0)
+	if ((s64) u < 0)
 		return ieee754dp_add(ieee754dp_1e63(),
 				     ieee754dp_flong(u & ~(1ULL << 63)));
 	return ieee754dp_flong(u);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_frexp.c linux-2.4.20/arch/mips/math-emu/dp_frexp.c
--- linux-2.4.19/arch/mips/math-emu/dp_frexp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_frexp.c	2002-10-04 00:41:14.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-/* close to ieeep754dp_logb 
+/* close to ieeep754dp_logb
 */
 ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_fsp.c linux-2.4.20/arch/mips/math-emu/dp_fsp.c
--- linux-2.4.19/arch/mips/math-emu/dp_fsp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_fsp.c	2002-10-04 00:41:11.000000000 +0000
@@ -44,7 +44,7 @@
 	case IEEE754_CLASS_QNAN:
 		return ieee754dp_nanxcpt(builddp(xs,
 						 DP_EMAX + 1 + DP_EBIAS,
-						 ((unsigned long long) xm
+						 ((u64) xm
 						  << (DP_MBITS -
 						      SP_MBITS))), "fsp",
 					 x);
@@ -70,5 +70,5 @@
 	xm &= ~SP_HIDDEN_BIT;
 
 	return builddp(xs, xe + DP_EBIAS,
-		       (unsigned long long) xm << (DP_MBITS - SP_MBITS));
+		       (u64) xm << (DP_MBITS - SP_MBITS));
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_modf.c linux-2.4.20/arch/mips/math-emu/dp_modf.c
--- linux-2.4.19/arch/mips/math-emu/dp_modf.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_modf.c	2002-10-04 00:41:10.000000000 +0000
@@ -59,7 +59,7 @@
 		*ip = x;
 		return ieee754dp_zero(xs);
 	}
-	/* generate ipart mantissa by clearing bottom bits 
+	/* generate ipart mantissa by clearing bottom bits
 	 */
 	*ip = builddp(xs, xe + DP_EBIAS,
 		      ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_mul.c linux-2.4.20/arch/mips/math-emu/dp_mul.c
--- linux-2.4.19/arch/mips/math-emu/dp_mul.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_mul.c	2002-10-04 00:41:17.000000000 +0000
@@ -111,7 +111,7 @@
 	{
 		int re = xe + ye;
 		int rs = xs ^ ys;
-		unsigned long long rm;
+		u64 rm;
 
 		/* shunt to top of word */
 		xm <<= 64 - (DP_MBITS + 1);
@@ -121,23 +121,23 @@
 		 */
 
 		/* 32 * 32 => 64 */
-#define DPXMULT(x,y)	((unsigned long long)(x) * (unsigned long long)y)
+#define DPXMULT(x,y)	((u64)(x) * (u64)y)
 
 		{
 			unsigned lxm = xm;
 			unsigned hxm = xm >> 32;
 			unsigned lym = ym;
 			unsigned hym = ym >> 32;
-			unsigned long long lrm;
-			unsigned long long hrm;
+			u64 lrm;
+			u64 hrm;
 
 			lrm = DPXMULT(lxm, lym);
 			hrm = DPXMULT(hxm, hym);
 
 			{
-				unsigned long long t = DPXMULT(lxm, hym);
+				u64 t = DPXMULT(lxm, hym);
 				{
-					unsigned long long at =
+					u64 at =
 					    lrm + (t << 32);
 					hrm += at < lrm;
 					lrm = at;
@@ -146,9 +146,9 @@
 			}
 
 			{
-				unsigned long long t = DPXMULT(hxm, lym);
+				u64 t = DPXMULT(hxm, lym);
 				{
-					unsigned long long at =
+					u64 at =
 					    lrm + (t << 32);
 					hrm += at < lrm;
 					lrm = at;
@@ -161,7 +161,7 @@
 		/*
 		 * sticky shift down to normal rounding precision
 		 */
-		if ((signed long long) rm < 0) {
+		if ((s64) rm < 0) {
 			rm =
 			    (rm >> (64 - (DP_MBITS + 1 + 3))) |
 			    ((rm << (DP_MBITS + 1 + 3)) != 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_sqrt.c linux-2.4.20/arch/mips/math-emu/dp_sqrt.c
--- linux-2.4.19/arch/mips/math-emu/dp_sqrt.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_sqrt.c	2002-10-04 00:41:15.000000000 +0000
@@ -99,7 +99,7 @@
 	yh = y.bits >> 32;
 	yh = (yh >> 1) + 0x1ff80000;
 	yh = yh - table[(yh >> 15) & 31];
-	y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff);
+	y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff);
 
 	/* Heron's rule once with correction to improve to ~18 sig. bits */
 	/* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_sub.c linux-2.4.20/arch/mips/math-emu/dp_sub.c
--- linux-2.4.19/arch/mips/math-emu/dp_sub.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_sub.c	2002-10-04 00:41:12.000000000 +0000
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -180,7 +180,7 @@
 				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
 		}
 
-		/* normalize to rounding precision 
+		/* normalize to rounding precision
 		 */
 		while ((xm >> (DP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_tint.c linux-2.4.20/arch/mips/math-emu/dp_tint.c
--- linux-2.4.19/arch/mips/math-emu/dp_tint.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_tint.c	2002-10-04 00:41:11.000000000 +0000
@@ -49,10 +49,7 @@
 	case IEEE754_CLASS_NORM:
 		break;
 	}
-	if (xe >= 31) {
-		/* look for valid corner case */
-		if (xe == 31 && xs && xm == DP_HIDDEN_BIT)
-			return -2147483648;
+	if (xe > 31) {
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -62,7 +59,7 @@
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
-		unsigned long long residue;
+		u64 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -98,7 +95,8 @@
 				xm++;
 			break;
 		}
-		if ((xm >> 31) != 0) {
+		/* look for valid corner case 0x80000000 */
+		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
 			/* This can happen after rounding */
 			SETCX(IEEE754_INVALID_OPERATION);
 			return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dp_tlong.c linux-2.4.20/arch/mips/math-emu/dp_tlong.c
--- linux-2.4.19/arch/mips/math-emu/dp_tlong.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dp_tlong.c	2002-10-04 00:41:17.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-long long ieee754dp_tlong(ieee754dp x)
+s64 ieee754dp_tlong(ieee754dp x)
 {
 	COMPXDP;
 
@@ -49,9 +49,9 @@
 		break;
 	}
 	if (xe >= 63) {
-		/* look for valid corner case */ 
+		/* look for valid corner case */
 		if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
-			return -9223372036854775808LL;
+			return -0x8000000000000000LL;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -61,7 +61,7 @@
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
-		unsigned long long residue;
+		u64 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -73,7 +73,11 @@
 			xm = 0;
 		}
 		else {
-			residue = xm << (64 - DP_MBITS + xe);
+			/* Shifting a u64 64 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 63 - DP_MBITS;
 			round = (residue >> 63) != 0;
 			sticky = (residue << 1) != 0;
 			xm >>= DP_MBITS - xe;
@@ -110,14 +114,14 @@
 }
 
 
-unsigned long long ieee754dp_tulong(ieee754dp x)
+u64 ieee754dp_tulong(ieee754dp x)
 {
 	ieee754dp hb = ieee754dp_1e63();
 
 	/* what if x < 0 ?? */
 	if (ieee754dp_lt(x, hb))
-		return (unsigned long long) ieee754dp_tlong(x);
+		return (u64) ieee754dp_tlong(x);
 
-	return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
+	return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
 	    (1ULL << 63);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dsemul.c linux-2.4.20/arch/mips/math-emu/dsemul.c
--- linux-2.4.19/arch/mips/math-emu/dsemul.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dsemul.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,173 @@
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/inst.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+#include <asm/fpu_emulator.h>
+
+#include "ieee754.h"
+#include "dsemul.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+extern struct mips_fpu_emulator_private fpuemuprivate;
+
+
+/*
+ * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
+ * we have to emulate the instruction in a COP1 branch delay slot.  Do
+ * not change cp0_epc due to the instruction
+ *
+ * According to the spec:
+ * 1) it shouldnt be a branch :-)
+ * 2) it can be a COP instruction :-(
+ * 3) if we are tring to run a protected memory space we must take
+ *    special care on memory access instructions :-(
+ */
+
+/*
+ * "Trampoline" return routine to catch exception following
+ *  execution of delay-slot instruction execution.
+ */
+
+struct emuframe {
+	mips_instruction	emul;
+	mips_instruction	badinst;
+	mips_instruction	cookie;
+	gpreg_t			epc;
+};
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
+{
+	extern asmlinkage void handle_dsemulret(void);
+	mips_instruction *dsemul_insns;
+	struct emuframe *fr;
+	int err;
+
+	if (ir == 0) {		/* a nop is easy */
+		regs->cp0_epc = cpc;
+		regs->cp0_cause &= ~CAUSEF_BD;
+		return 0;
+	}
+#ifdef DSEMUL_TRACE
+	printk("dsemul %lx %lx\n", regs->cp0_epc, cpc);
+
+#endif
+
+	/*
+	 * The strategy is to push the instruction onto the user stack
+	 * and put a trap after it which we can catch and jump to
+	 * the required address any alternative apart from full
+	 * instruction emulation!!.
+	 *
+	 * Algorithmics used a system call instruction, and
+	 * borrowed that vector.  MIPS/Linux version is a bit
+	 * more heavyweight in the interests of portability and
+	 * multiprocessor support.  For Linux we generate a
+	 * an unaligned access and force an address error exception.
+	 *
+	 * For embedded systems (stand-alone) we prefer to use a
+	 * non-existing CP1 instruction. This prevents us from emulating
+	 * branches, but gives us a cleaner interface to the exception
+	 * handler (single entry point).
+	 */
+
+	/* Ensure that the two instructions are in the same cache line */
+	dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+	fr = (struct emuframe *) dsemul_insns;
+
+	/* Verify that the stack pointer is not competely insane */
+	if (unlikely(verify_area(VERIFY_WRITE, fr, sizeof(struct emuframe))))
+		return SIGBUS;
+
+	err = __put_user(ir, &fr->emul);
+	err |= __put_user((mips_instruction)BADINST, &fr->badinst);
+	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
+	err |= __put_user(cpc, &fr->epc);
+
+	if (unlikely(err)) {
+		fpuemuprivate.stats.errors++;
+		return SIGBUS;
+	}
+
+	regs->cp0_epc = VA_TO_REG & fr->emul;
+
+	flush_cache_sigtramp((unsigned long)&fr->badinst);
+
+	return SIGILL;		/* force out of emulation loop */
+}
+
+int do_dsemulret(struct pt_regs *xcp)
+{
+	struct emuframe *fr;
+	gpreg_t epc;
+	u32 insn, cookie;
+	int err = 0;
+
+	fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction));
+
+	/*
+	 * If we can't even access the area, something is very wrong, but we'll
+	 * leave that to the default handling
+	 */
+	if (verify_area(VERIFY_READ, fr, sizeof(struct emuframe)))
+		return 0;
+
+	/*
+	 * Do some sanity checking on the stackframe:
+	 *
+	 *  - Is the instruction pointed to by the EPC an BADINST?
+	 *  - Is the following memory word the BD_COOKIE?
+	 */
+	err = __get_user(insn, &fr->badinst);
+	err |= __get_user(cookie, &fr->cookie);
+
+	if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) {
+		fpuemuprivate.stats.errors++;
+
+		return 0;
+	}
+
+	/*
+	 * At this point, we are satisfied that it's a BD emulation trap.  Yes,
+	 * a user might have deliberately put two malformed and useless
+	 * instructions in a row in his program, in which case he's in for a
+	 * nasty surprise - the next instruction will be treated as a
+	 * continuation address!  Alas, this seems to be the only way that we
+	 * can handle signals, recursion, and longjmps() in the context of
+	 * emulating the branch delay instruction.
+	 */
+
+#ifdef DSEMUL_TRACE
+	printk("dsemulret\n");
+#endif
+	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
+		/* This is not a good situation to be in */
+		force_sig(SIGBUS, current);
+
+		return 0;
+	}
+
+	/* Set EPC to return to post-branch instruction */
+	xcp->cp0_epc = epc;
+
+	return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/dsemul.h linux-2.4.20/arch/mips/math-emu/dsemul.h
--- linux-2.4.19/arch/mips/math-emu/dsemul.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/dsemul.h	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,23 @@
+typedef long gpreg_t;
+typedef void *vaddr_t;
+
+#define REG_TO_VA (vaddr_t)
+#define VA_TO_REG (gpreg_t)
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
+int do_dsemulret(struct pt_regs *xcp);
+
+/* Instruction which will always cause an address error */
+#define AdELOAD 0x8c000001	/* lw $0,1($0) */
+/* Instruction which will plainly cause a CP1 exception when FPU is disabled */
+#define CP1UNDEF 0x44400001    /* cfc1 $0,$0 undef  */
+
+/* Instruction inserted following the badinst to further tag the sequence */
+#define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */
+
+/* Setup which instruction to use for trampoline */
+#ifdef STANDALONE_EMULATOR
+#define BADINST CP1UNDEF
+#else
+#define BADINST AdELOAD
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754.c linux-2.4.20/arch/mips/math-emu/ieee754.c
--- linux-2.4.19/arch/mips/math-emu/ieee754.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754.c	2002-10-04 00:41:10.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * BUGS
  * not much dp done
- * doesnt generate IEEE754_INEXACT
+ * doesn't generate IEEE754_INEXACT
  *
  */
 /*
@@ -50,7 +50,7 @@
 	"SNaN",
 };
 
-/* the control status register 
+/* the control status register
 */
 struct ieee754_csr ieee754_csr;
 
@@ -123,7 +123,7 @@
 	return ax.rv.si;
 }
 
-long long ieee754di_xcpt(long long r, const char *op, ...)
+s64 ieee754di_xcpt(s64 r, const char *op, ...)
 {
 	struct ieee754xctx ax;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754.h linux-2.4.20/arch/mips/math-emu/ieee754.h
--- linux-2.4.19/arch/mips/math-emu/ieee754.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754.h	2002-10-04 00:41:11.000000000 +0000
@@ -26,7 +26,7 @@
 
 /**************************************************************************
  *  Nov 7, 2000
- *  Modification to allow integration with Linux kernel 
+ *  Modification to allow integration with Linux kernel
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
@@ -36,8 +36,8 @@
 /* Going from Algorithmics to Linux native environment, add this */
 #include <linux/types.h>
 
-/* 
- * Not very pretty, but the Linux kernel's normal va_list definition 
+/*
+ * Not very pretty, but the Linux kernel's normal va_list definition
  * does not allow it to be used as a structure element, as it is here.
  */
 #ifndef _STDARG_H
@@ -71,18 +71,18 @@
 typedef union _ieee754dp {
 	struct ieee754dp_konst oparts;
 	struct {
-		unsigned long long mant:52;
+		u64 mant:52;
 		unsigned int bexp:11;
 		unsigned int sign:1;
 	} parts;
-	unsigned long long bits;
+	u64 bits;
 	double d;
 } ieee754dp;
 
 typedef union _ieee754sp {
 	struct ieee754sp_konst parts;
 	float f;
-	unsigned long bits;
+	u32 bits;
 } ieee754sp;
 #endif
 
@@ -98,10 +98,10 @@
 	struct {
 		unsigned int sign:1;
 		unsigned int bexp:11;
-		unsigned long long mant:52;
+		u64 mant:52;
 	} parts;
 	double d;
-	unsigned long long bits;
+	u64 bits;
 } ieee754dp;
 
 struct ieee754sp_konst {
@@ -113,7 +113,7 @@
 typedef union _ieee754sp {
 	struct ieee754sp_konst parts;
 	float f;
-	unsigned long bits;
+	u32 bits;
 } ieee754sp;
 #endif
 
@@ -138,16 +138,16 @@
 
 ieee754sp ieee754sp_fint(int x);
 ieee754sp ieee754sp_funs(unsigned x);
-ieee754sp ieee754sp_flong(long long x);
-ieee754sp ieee754sp_fulong(unsigned long long x);
+ieee754sp ieee754sp_flong(s64 x);
+ieee754sp ieee754sp_fulong(u64 x);
 ieee754sp ieee754sp_fdp(ieee754dp x);
 
 int ieee754sp_tint(ieee754sp x);
 unsigned int ieee754sp_tuns(ieee754sp x);
-long long ieee754sp_tlong(ieee754sp x);
-unsigned long long ieee754sp_tulong(ieee754sp x);
+s64 ieee754sp_tlong(ieee754sp x);
+u64 ieee754sp_tulong(ieee754sp x);
 
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop);
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
 /*
  * basic sp math
  */
@@ -179,14 +179,14 @@
 ieee754dp ieee754dp_neg(ieee754dp x);
 ieee754dp ieee754dp_scalb(ieee754dp x, int);
 
-/* return exponent as integer in floating point format 
+/* return exponent as integer in floating point format
  */
 ieee754dp ieee754dp_logb(ieee754dp x);
 
 ieee754dp ieee754dp_fint(int x);
 ieee754dp ieee754dp_funs(unsigned x);
-ieee754dp ieee754dp_flong(long long x);
-ieee754dp ieee754dp_fulong(unsigned long long x);
+ieee754dp ieee754dp_flong(s64 x);
+ieee754dp ieee754dp_fulong(u64 x);
 ieee754dp ieee754dp_fsp(ieee754sp x);
 
 ieee754dp ieee754dp_ceil(ieee754dp x);
@@ -195,10 +195,10 @@
 
 int ieee754dp_tint(ieee754dp x);
 unsigned int ieee754dp_tuns(ieee754dp x);
-long long ieee754dp_tlong(ieee754dp x);
-unsigned long long ieee754dp_tulong(ieee754dp x);
+s64 ieee754dp_tlong(ieee754dp x);
+u64 ieee754dp_tulong(ieee754dp x);
 
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop);
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
 /*
  * basic sp math
  */
@@ -214,7 +214,7 @@
 
 
 
-/* 5 types of floating point number 
+/* 5 types of floating point number
 */
 #define IEEE754_CLASS_NORM	0x00
 #define IEEE754_CLASS_ZERO	0x01
@@ -238,7 +238,7 @@
 #define IEEE754_CGT	0x04
 #define IEEE754_CUN	0x08
 
-/* rounding mode 
+/* rounding mode
 */
 #define IEEE754_RN	0	/* round to nearest */
 #define IEEE754_RZ	1	/* round toward zero  */
@@ -253,65 +253,65 @@
 */
 static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
 {
 	return ieee754sp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 }
 
 static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CLT);
+	return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
 }
 
 static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CGT);
+	return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
 }
 
 
 static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
 {
 	return ieee754dp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 }
 
 static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CLT);
+	return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
 }
 
 static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CGT);
+	return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
 }
 
 static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 }
 
 
@@ -321,7 +321,7 @@
 char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
 
 
-/* the control status register 
+/* the control status register
 */
 struct ieee754_csr {
 	unsigned pad:13;
@@ -350,7 +350,7 @@
 	return (ieee754_csr.cx);
 }
 
-/* test for current exception condition 
+/* test for current exception condition
  */
 static __inline int ieee754_cxtest(unsigned n)
 {
@@ -372,7 +372,7 @@
 	return (ieee754_csr.sx = 0);
 }
 
-/* test for sticky exception condition 
+/* test for sticky exception condition
  */
 static __inline int ieee754_sxtest(unsigned n)
 {
@@ -450,13 +450,13 @@
 #define ieee754sp_1e63() \
   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
 
-/* indefinite integer value 
+/* indefinite integer value
 */
 #define ieee754si_indef()	INT_MAX
 #ifdef LONG_LONG_MAX
 #define ieee754di_indef()	LONG_LONG_MAX
 #else
-#define ieee754di_indef()	((long long)(~0ULL>>1))
+#define ieee754di_indef()	((s64)(~0ULL>>1))
 #endif
 
 /* IEEE exception context, passed to handler */
@@ -470,7 +470,7 @@
 		ieee754xp xp;	/* extended precision */
 #endif
 		int si;		/* standard signed integer (32bits) */
-		long long di;	/* extended signed integer (64bits) */
+		s64 di;		/* extended signed integer (64bits) */
 	} rv;			/* default result format implied by op */
 	va_list ap;
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754d.c linux-2.4.20/arch/mips/math-emu/ieee754d.c
--- linux-2.4.19/arch/mips/math-emu/ieee754d.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754d.c	2002-10-04 00:41:29.000000000 +0000
@@ -20,7 +20,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  *  Nov 7, 2000
- *  Modified to build and operate in Linux kernel environment. 
+ *  Modified to build and operate in Linux kernel environment.
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
@@ -39,12 +39,12 @@
 #define SP_EMAX		127
 #define SP_FBITS	23
 
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
+#define DP_MBIT(x)	((u64)1 << (x))
 #define DP_HIDDEN_BIT	DP_MBIT(DP_FBITS)
 #define DP_SIGN_BIT	DP_MBIT(63)
 
 
-#define SP_MBIT(x)	((unsigned long)1 << (x))
+#define SP_MBIT(x)	((u32)1 << (x))
 #define SP_HIDDEN_BIT	SP_MBIT(SP_FBITS)
 #define SP_SIGN_BIT	SP_MBIT(31)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754dp.c linux-2.4.20/arch/mips/math-emu/ieee754dp.c
--- linux-2.4.19/arch/mips/math-emu/ieee754dp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754dp.c	2002-10-04 00:41:22.000000000 +0000
@@ -98,9 +98,9 @@
 }
 
 
-static unsigned long long get_rounding(int sn, unsigned long long xm)
+static u64 get_rounding(int sn, u64 xm)
 {
-	/* inexact must round of 3 bits 
+	/* inexact must round of 3 bits
 	 */
 	if (xm & (DP_MBIT(3) - 1)) {
 		switch (ieee754_csr.rm) {
@@ -129,7 +129,7 @@
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
-ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
+ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
 {
 	assert(xm);		/* we dont gen exact zeros (probably should) */
 
@@ -174,7 +174,7 @@
 			xe++;
 		}
 		else {
-			/* sticky right shift es bits 
+			/* sticky right shift es bits
 			 */
 			xm = XDPSRS(xm, es);
 			xe += es;
@@ -188,10 +188,10 @@
 			SETCX(IEEE754_UNDERFLOW);
 		}
 
-		/* inexact must round of 3 bits 
+		/* inexact must round of 3 bits
 		 */
 		xm = get_rounding(sn, xm);
-		/* adjust exponent for rounding add overflowing 
+		/* adjust exponent for rounding add overflowing
 		 */
 		if (xm >> (DP_MBITS + 3 + 1)) {
 			/* add causes mantissa overflow */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754dp.h linux-2.4.20/arch/mips/math-emu/ieee754dp.h
--- linux-2.4.19/arch/mips/math-emu/ieee754dp.h	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754dp.h	2002-10-04 00:41:10.000000000 +0000
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * double precision internal header file
  */
@@ -46,7 +46,7 @@
 #define DPDNORMX	DPDNORMx(xm,xe)
 #define DPDNORMY	DPDNORMx(ym,ye)
 
-static __inline ieee754dp builddp(int s, int bx, unsigned long long m)
+static __inline ieee754dp builddp(int s, int bx, u64 m)
 {
 	ieee754dp r;
 
@@ -64,11 +64,11 @@
 extern int ieee754dp_isnan(ieee754dp);
 extern int ieee754dp_issnan(ieee754dp);
 extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
 extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
 extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
 extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
-extern ieee754dp ieee754dp_format(int, int, unsigned long long);
+extern ieee754dp ieee754dp_format(int, int, u64);
 
 
 #define DPNORMRET2(s,e,m,name,a0,a1) \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754int.h linux-2.4.20/arch/mips/math-emu/ieee754int.h
--- linux-2.4.19/arch/mips/math-emu/ieee754int.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754int.h	2002-10-04 00:41:21.000000000 +0000
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * common internal header file
  */
@@ -38,11 +38,11 @@
 #define SP_EMAX		127
 #define SP_MBITS	23
 
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
+#define DP_MBIT(x)	((u64)1 << (x))
 #define DP_HIDDEN_BIT	DP_MBIT(DP_MBITS)
 #define DP_SIGN_BIT	DP_MBIT(63)
 
-#define SP_MBIT(x)	((unsigned long)1 << (x))
+#define SP_MBIT(x)	((u32)1 << (x))
 #define SP_HIDDEN_BIT	SP_MBIT(SP_MBITS)
 #define SP_SIGN_BIT	SP_MBIT(31)
 
@@ -102,10 +102,10 @@
 
 
 #define COMPXDP \
-unsigned long long xm; int xe; int xs; int xc
+u64 xm; int xe; int xs; int xc
 
 #define COMPYDP \
-unsigned long long ym; int ye; int ys; int yc
+u64 ym; int ye; int ys; int yc
 
 #define EXPLODEDP(v,vc,vs,ve,vm) \
 {\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754sp.c linux-2.4.20/arch/mips/math-emu/ieee754sp.c
--- linux-2.4.19/arch/mips/math-emu/ieee754sp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754sp.c	2002-10-04 00:41:15.000000000 +0000
@@ -101,7 +101,7 @@
 
 static unsigned get_rounding(int sn, unsigned xm)
 {
-	/* inexact must round of 3 bits 
+	/* inexact must round of 3 bits
 	 */
 	if (xm & (SP_MBIT(3) - 1)) {
 		switch (ieee754_csr.rm) {
@@ -175,7 +175,7 @@
 			xe++;
 		}
 		else {
-			/* sticky right shift es bits 
+			/* sticky right shift es bits
 			 */
 			SPXSRSXn(es);
 			assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
@@ -188,10 +188,10 @@
 			SETCX(IEEE754_UNDERFLOW);
 		}
 
-		/* inexact must round of 3 bits 
+		/* inexact must round of 3 bits
 		 */
 		xm = get_rounding(sn, xm);
-		/* adjust exponent for rounding add overflowing 
+		/* adjust exponent for rounding add overflowing
 		 */
 		if (xm >> (SP_MBITS + 1 + 3)) {
 			/* add causes mantissa overflow */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754sp.h linux-2.4.20/arch/mips/math-emu/ieee754sp.h
--- linux-2.4.19/arch/mips/math-emu/ieee754sp.h	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754sp.h	2002-10-04 00:41:09.000000000 +0000
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * double precision internal header file
  */
@@ -70,7 +70,7 @@
 extern int ieee754sp_isnan(ieee754sp);
 extern int ieee754sp_issnan(ieee754sp);
 extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
 extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
 extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
 extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/ieee754xcpt.c linux-2.4.20/arch/mips/math-emu/ieee754xcpt.c
--- linux-2.4.19/arch/mips/math-emu/ieee754xcpt.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/ieee754xcpt.c	2002-10-04 00:41:11.000000000 +0000
@@ -23,7 +23,7 @@
 
 /**************************************************************************
  *  Nov 7, 2000
- *  Added preprocessor hacks to map to Linux kernel diagnostics. 
+ *  Added preprocessor hacks to map to Linux kernel diagnostics.
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/kernel_linkage.c linux-2.4.20/arch/mips/math-emu/kernel_linkage.c
--- linux-2.4.19/arch/mips/math-emu/kernel_linkage.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/kernel_linkage.c	2002-10-04 00:41:10.000000000 +0000
@@ -39,7 +39,7 @@
 {
 	static int first = 1;
 	int i;
- 
+
 	if (first) {
 		first = 0;
 		printk("Algorithmics/MIPS FPU Emulator v1.5\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_add.c linux-2.4.20/arch/mips/math-emu/sp_add.c
--- linux-2.4.19/arch/mips/math-emu/sp_add.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_add.c	2002-10-04 00:41:14.000000000 +0000
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_cmp.c linux-2.4.20/arch/mips/math-emu/sp_cmp.c
--- linux-2.4.19/arch/mips/math-emu/sp_cmp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_cmp.c	2002-10-04 00:41:09.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp)
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
 {
 	COMPXSP;
 	COMPYSP;
@@ -39,12 +39,12 @@
 	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
-		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
 			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
+			if (sig && SETCX(IEEE754_INVALID_OPERATION))
 				return ieee754si_xcpt(0, "fcmpf", x);
 		}
 		return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_div.c linux-2.4.20/arch/mips/math-emu/sp_div.c
--- linux-2.4.19/arch/mips/math-emu/sp_div.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_div.c	2002-10-04 00:41:29.000000000 +0000
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -86,7 +86,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754sp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_fdp.c linux-2.4.20/arch/mips/math-emu/sp_fdp.c
--- linux-2.4.19/arch/mips/math-emu/sp_fdp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_fdp.c	2002-10-04 00:41:20.000000000 +0000
@@ -43,7 +43,7 @@
 		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
 	case IEEE754_CLASS_QNAN:
-		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (unsigned long)
+		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
 				(xm >> (DP_MBITS - SP_MBITS)));
 		if (!ieee754sp_isnan(nan))
 			nan = ieee754sp_indef();
@@ -57,7 +57,7 @@
 		SETCX(IEEE754_UNDERFLOW);
 		SETCX(IEEE754_INEXACT);
 		if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
-		    (ieee754_csr.rm == IEEE754_RD && xs))
+				(ieee754_csr.rm == IEEE754_RD && xs))
 			return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
 		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
 	case IEEE754_CLASS_NORM:
@@ -65,9 +65,9 @@
 	}
 
 	{
-		unsigned long rm;
+		u32 rm;
 
-		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift 
+		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
 		 */
 		rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
 		    ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_fint.c linux-2.4.20/arch/mips/math-emu/sp_fint.c
--- linux-2.4.19/arch/mips/math-emu/sp_fint.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_fint.c	2002-10-04 00:41:15.000000000 +0000
@@ -52,13 +52,13 @@
 	xe = SP_MBITS + 3;
 
 	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
+		/* shunt out overflow bits
 		 */
 		while (xm >> (SP_MBITS + 1 + 3)) {
 			SPXSRSX1();
 		}
 	} else {
-		/* normalize in grs extended single precision 
+		/* normalize in grs extended single precision
 		 */
 		while ((xm >> (SP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_flong.c linux-2.4.20/arch/mips/math-emu/sp_flong.c
--- linux-2.4.19/arch/mips/math-emu/sp_flong.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_flong.c	2002-10-04 00:41:14.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-ieee754sp ieee754sp_flong(long long x)
+ieee754sp ieee754sp_flong(s64 x)
 {
 	COMPXDP;		/* <--- need 64-bit mantissa temp */
 
@@ -52,7 +52,7 @@
 	xe = SP_MBITS + 3;
 
 	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
+		/* shunt out overflow bits
 		 */
 		while (xm >> (SP_MBITS + 1 + 3)) {
 			SPXSRSX1();
@@ -68,9 +68,9 @@
 }
 
 
-ieee754sp ieee754sp_fulong(unsigned long long u)
+ieee754sp ieee754sp_fulong(u64 u)
 {
-	if ((long long) u < 0)
+	if ((s64) u < 0)
 		return ieee754sp_add(ieee754sp_1e63(),
 				     ieee754sp_flong(u & ~(1ULL << 63)));
 	return ieee754sp_flong(u);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_frexp.c linux-2.4.20/arch/mips/math-emu/sp_frexp.c
--- linux-2.4.19/arch/mips/math-emu/sp_frexp.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_frexp.c	2002-10-04 00:41:09.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-/* close to ieeep754sp_logb 
+/* close to ieeep754sp_logb
 */
 ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_modf.c linux-2.4.20/arch/mips/math-emu/sp_modf.c
--- linux-2.4.19/arch/mips/math-emu/sp_modf.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_modf.c	2002-10-04 00:41:16.000000000 +0000
@@ -59,7 +59,7 @@
 		*ip = x;
 		return ieee754sp_zero(xs);
 	}
-	/* generate ipart mantissa by clearing bottom bits 
+	/* generate ipart mantissa by clearing bottom bits
 	 */
 	*ip = buildsp(xs, xe + SP_EBIAS,
 		      ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_sub.c linux-2.4.20/arch/mips/math-emu/sp_sub.c
--- linux-2.4.19/arch/mips/math-emu/sp_sub.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_sub.c	2002-10-04 00:41:15.000000000 +0000
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -173,7 +173,7 @@
 			else
 				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
 
-		/* normalize to rounding precision 
+		/* normalize to rounding precision
 		 */
 		while ((xm >> (SP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_tint.c linux-2.4.20/arch/mips/math-emu/sp_tint.c
--- linux-2.4.19/arch/mips/math-emu/sp_tint.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_tint.c	2002-10-04 00:41:20.000000000 +0000
@@ -52,7 +52,7 @@
 	if (xe >= 31) {
 		/* look for valid corner case */
 		if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
-			return -2147483648;
+			return -0x80000000;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -62,7 +62,7 @@
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
 	} else {
-		unsigned long residue;
+		u32 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -74,7 +74,11 @@
 			xm = 0;
 		}
 		else {
-			residue = xm << (32 - SP_MBITS + xe);
+			/* Shifting a u32 32 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 31 - SP_MBITS;
 			round = (residue >> 31) != 0;
 			sticky = (residue << 1) != 0;
 			xm >>= SP_MBITS - xe;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/math-emu/sp_tlong.c linux-2.4.20/arch/mips/math-emu/sp_tlong.c
--- linux-2.4.19/arch/mips/math-emu/sp_tlong.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/math-emu/sp_tlong.c	2002-10-04 00:41:20.000000000 +0000
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-long long ieee754sp_tlong(ieee754sp x)
+s64 ieee754sp_tlong(ieee754sp x)
 {
 	COMPXDP;		/* <-- need 64-bit mantissa tmp */
 
@@ -51,7 +51,7 @@
 	if (xe >= 63) {
 		/* look for valid corner case */
 		if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
-			return -9223372036854775808LL;
+			return -0x8000000000000000LL;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -61,7 +61,7 @@
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
 	} else if (xe < SP_MBITS) {
-		unsigned long residue;
+		u32 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -98,7 +98,7 @@
 		if ((xm >> 63) != 0) {
 			/* This can happen after rounding */
 			SETCX(IEEE754_INVALID_OPERATION);
-			return ieee754si_xcpt(ieee754di_indef(), "sp_tlong", x);
+			return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
 		}
 		if (round || sticky)
 			SETCX(IEEE754_INEXACT);
@@ -110,14 +110,14 @@
 }
 
 
-unsigned long long ieee754sp_tulong(ieee754sp x)
+u64 ieee754sp_tulong(ieee754sp x)
 {
 	ieee754sp hb = ieee754sp_1e63();
 
 	/* what if x < 0 ?? */
 	if (ieee754sp_lt(x, hb))
-		return (unsigned long long) ieee754sp_tlong(x);
+		return (u64) ieee754sp_tlong(x);
 
-	return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
+	return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
 	    (1ULL << 63);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/atlas/Makefile linux-2.4.20/arch/mips/mips-boards/atlas/Makefile
--- linux-2.4.19/arch/mips/mips-boards/atlas/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/atlas/Makefile	2002-10-04 00:41:30.000000000 +0000
@@ -7,12 +7,12 @@
 # This program is free software; you can distribute it and/or modify it
 # under the terms of the GNU General Public License (Version 2) as
 # published by the Free Software Foundation.
-# 
+#
 # This program is distributed in the hope 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.,
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/atlas/atlas_int.c linux-2.4.20/arch/mips/mips-boards/atlas/atlas_int.c
--- linux-2.4.19/arch/mips/mips-boards/atlas/atlas_int.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/atlas/atlas_int.c	2002-10-04 00:41:22.000000000 +0000
@@ -19,7 +19,7 @@
  *
  * ########################################################################
  *
- * Routines for generic manipulation of the interrupts found on the MIPS 
+ * Routines for generic manipulation of the interrupts found on the MIPS
  * Atlas board.
  *
  */
@@ -104,7 +104,7 @@
 	unsigned long int_status;
 	int irq, cpu = smp_processor_id();
 
-	int_status = atlas_hw0_icregs->intstatus; 
+	int_status = atlas_hw0_icregs->intstatus;
 
 	/* if int_status == 0, then the interrupt has already been cleared */
 	if (int_status == 0)
@@ -127,7 +127,7 @@
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 
-	return;		
+	return;
 }
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -139,11 +139,11 @@
 {
 	int i;
 
-	/* 
-	 * Mask out all interrupt by writing "1" to all bit position in 
-	 * the interrupt reset reg. 
+	/*
+	 * Mask out all interrupt by writing "1" to all bit position in
+	 * the interrupt reset reg.
 	 */
-	atlas_hw0_icregs->intrsten = 0xffffffff;    
+	atlas_hw0_icregs->intrsten = 0xffffffff;
 
 	/* Now safe to set the exception vector. */
 	set_except_vector(0, mipsIRQ);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.20/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-2.4.19/arch/mips/mips-boards/atlas/atlas_setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/atlas/atlas_setup.c	2002-10-04 00:41:10.000000000 +0000
@@ -59,6 +59,8 @@
 }
 
 extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+extern unsigned long mips_rtc_get_time(void);
 
 void __init atlas_setup(void)
 {
@@ -86,7 +88,7 @@
 		prom_printf("Config serial console: %s\n", serial_console);
 		console_setup(serial_console, NULL);
 	}
-#endif	  
+#endif
 
 #ifdef CONFIG_REMOTE_DEBUG
 	argptr = prom_getcmdline();
@@ -124,6 +126,8 @@
 
 	rtc_ops = &atlas_rtc_ops;
 	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+	rtc_get_time = mips_rtc_get_time;
 
 	mips_reboot_setup();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/Makefile linux-2.4.20/arch/mips/mips-boards/generic/Makefile
--- linux-2.4.19/arch/mips/mips-boards/generic/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/Makefile	2002-10-04 00:41:29.000000000 +0000
@@ -5,12 +5,12 @@
 # This program is free software; you can distribute it and/or modify it
 # under the terms of the GNU General Public License (Version 2) as
 # published by the Free Software Foundation.
-# 
+#
 # This program is distributed in the hope 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.,
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
@@ -28,7 +28,9 @@
 O_TARGET := mipsboards.o
 
 obj-y				:= mipsIRQ.o reset.o display.o init.o \
-				   memory.o printf.o cmdline.o time.o
+				   memory.o printf.o cmdline.o
+obj-$(CONFIG_MIPS_ATLAS)	+= time.o
+obj-$(CONFIG_MIPS_MALTA)	+= time.o
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb_hook.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/display.c linux-2.4.20/arch/mips/mips-boards/generic/display.c
--- linux-2.4.19/arch/mips/mips-boards/generic/display.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/display.c	2002-10-04 00:41:23.000000000 +0000
@@ -18,7 +18,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  * ########################################################################
- * 
+ *
  * Display routines for display messages in MIPS boards ascii display.
  *
  */
@@ -39,9 +39,11 @@
 	}
 }
 
+#ifndef CONFIG_MIPS_SEAD
 void mips_display_word(unsigned int num)
 {
         volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE;
-	
+
 	*display = num;
 }
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/gdb_hook.c linux-2.4.20/arch/mips/mips-boards/generic/gdb_hook.c
--- linux-2.4.19/arch/mips/mips-boards/generic/gdb_hook.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/gdb_hook.c	2002-10-04 00:41:16.000000000 +0000
@@ -67,28 +67,28 @@
 	serial_in(&kdb_port_info, UART_MSR);
 
 	/*
-	 * Now, initialize the UART 
+	 * Now, initialize the UART
 	 */
 	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
 	if (kdb_port_info.flags & ASYNC_FOURPORT) {
 		kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
 		t = UART_MCR_DTR | UART_MCR_OUT1;
 	} else {
-		kdb_port_info.MCR 
+		kdb_port_info.MCR
 			= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
 		t = UART_MCR_DTR | UART_MCR_RTS;
 	}
 
 	kdb_port_info.MCR = t;		/* no interrupts, please */
 	serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
-	
+
 	/*
 	 * and set the speed of the serial port
 	 * (currently hardwired to 9600 8N1
 	 */
 
 	/* baud rate is fixed to 9600 (is this sufficient?)*/
-	t = kdb_port_info.state->baud_base / 9600;	
+	t = kdb_port_info.state->baud_base / 9600;
 	/* set DLAB */
 	serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
 	serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
@@ -102,7 +102,7 @@
 	return generic_putDebugChar(c);
 }
 
-char getDebugChar(void) 
+char getDebugChar(void)
 {
 	return generic_getDebugChar();
 }
@@ -156,7 +156,7 @@
 
 static int saa9730_kgdb_active = 0;
 
-void saa9730_kgdb_hook(void) 
+void saa9730_kgdb_hook(void)
 {
         volatile unsigned char t;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/init.c linux-2.4.20/arch/mips/mips-boards/generic/init.c
--- linux-2.4.19/arch/mips/mips-boards/generic/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/init.c	2002-10-04 00:41:10.000000000 +0000
@@ -54,8 +54,8 @@
 {
 	/*
 	 * Return a pointer to the given environment variable.
-	 * In 64-bit mode: we're using 64-bit pointers, but all pointers 
-	 * in the PROM structures are only 32-bit, so we need some 
+	 * In 64-bit mode: we're using 64-bit pointers, but all pointers
+	 * in the PROM structures are only 32-bit, so we need some
 	 * workarounds, if we are running in 64-bit mode.
 	 */
 	int i, index=0;
@@ -95,7 +95,7 @@
 		ea[i] = num;
 	}
 }
- 
+
 int get_ethernet_addr(char *ethernet_addr)
 {
         char *ethaddr_str;
@@ -135,7 +135,7 @@
 	case MIPS_REVISION_CORID_CORE_LV:
 	case MIPS_REVISION_CORID_CORE_FPGA:
 		/*
-		 * Setup the North bridge to do Master byte-lane swapping 
+		 * Setup the North bridge to do Master byte-lane swapping
 		 * when running in bigendian.
 		 */
 #if defined(__MIPSEL__)
@@ -149,15 +149,15 @@
 		set_io_port_base(MALTA_GT_PORT_BASE);
 #else
 		set_io_port_base(KSEG1);
-#endif		
+#endif
 
 		break;
 	case MIPS_REVISION_CORID_BONITO64:
 	case MIPS_REVISION_CORID_CORE_20K:
-		/* 
+		/*
 		 * Disable Bonito IOBC.
 		 */
-		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 
+		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
 			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
 			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 
@@ -166,12 +166,12 @@
 		 * when running in bigendian.
 		 */
 #if defined(__MIPSEL__)
-		BONITO_BONGENCFG = BONITO_BONGENCFG & 
-			~(BONITO_BONGENCFG_MSTRBYTESWAP | 
+		BONITO_BONGENCFG = BONITO_BONGENCFG &
+			~(BONITO_BONGENCFG_MSTRBYTESWAP |
 			  BONITO_BONGENCFG_BYTESWAP);
 #else
-		BONITO_BONGENCFG = BONITO_BONGENCFG | 
-			BONITO_BONGENCFG_MSTRBYTESWAP | 
+		BONITO_BONGENCFG = BONITO_BONGENCFG |
+			BONITO_BONGENCFG_MSTRBYTESWAP |
 			BONITO_BONGENCFG_BYTESWAP;
 #endif
 
@@ -187,7 +187,7 @@
 #if defined(__MIPSEL__)
 		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
 #else
-		MSC_WRITE(MSC01_PCI_SWAP, 
+		MSC_WRITE(MSC01_PCI_SWAP,
 			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
 			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
 			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/memory.c linux-2.4.20/arch/mips/mips-boards/generic/memory.c
--- linux-2.4.19/arch/mips/mips-boards/generic/memory.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/memory.c	2002-10-04 00:41:11.000000000 +0000
@@ -19,9 +19,9 @@
  *
  * ########################################################################
  *
- * PROM library functions for acquiring/using memory descriptors given to 
+ * PROM library functions for acquiring/using memory descriptors given to
  * us from the YAMON.
- * 
+ *
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -83,11 +83,11 @@
 	mdesc[1].size = 0x000ef000;
 
 #if (CONFIG_MIPS_MALTA)
-	/* 
+	/*
 	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
-	 * south bridge and PCI access always forwarded to the ISA Bus and 
+	 * south bridge and PCI access always forwarded to the ISA Bus and
 	 * BIOSCS# is always generated.
-	 * This mean that this area can't be used as DMA memory for PCI 
+	 * This mean that this area can't be used as DMA memory for PCI
 	 * devices.
 	 */
 	mdesc[2].type = yamon_dontuse;
@@ -148,7 +148,7 @@
 		size = p->size;
 
 		add_memory_region(base, size, type);
-                p++; 
+                p++;
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/mipsIRQ.S linux-2.4.20/arch/mips/mips-boards/generic/mipsIRQ.S
--- linux-2.4.19/arch/mips/mips-boards/generic/mipsIRQ.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/mipsIRQ.S	2002-10-04 00:41:15.000000000 +0000
@@ -59,7 +59,7 @@
  * Note: On the SEAD board thing are a little bit different.
  *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
  *       wired to UART1.
- *	
+ *
  * We handle the IRQ according to _our_ priority which is:
  *
  * Highest ----     R4k Timer
@@ -78,7 +78,9 @@
 	CLI
 	.set	at
 
-	mfc0	s0, CP0_CAUSE		# get irq mask
+	mfc0	s0, CP0_CAUSE		# get irq bits
+	mfc0	s1, CP0_STATUS		# get irq mask
+	and	s0, s1
 
 	/* First we check for r4k counter/timer IRQ. */
 	andi	a0, s0, CAUSEF_IP7
@@ -94,14 +96,14 @@
 	 nop
 
 1:
-#if defined(CONFIG_MIPS_SEAD) 	
+#if defined(CONFIG_MIPS_SEAD)
 	beq	a0, zero, 1f
 	 andi	a0, s0, CAUSEF_IP3	# delay slot, check hw1 interrupt
 #else
 	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
- 	 andi	a0, s0, CAUSEF_IP5	
+ 	 andi	a0, s0, CAUSEF_IP5
 #endif
-	
+
 	/* Wheee, combined hardware level zero interrupt. */
 #if defined(CONFIG_MIPS_ATLAS)
 	jal	atlas_hw0_irqdispatch
@@ -110,7 +112,7 @@
 #elif defined(CONFIG_MIPS_SEAD)
 	jal	sead_hw0_irqdispatch
 #else
-#error "MIPS board not supported\n"	
+#error "MIPS board not supported\n"
 #endif
 	 move	a0, sp			# delay slot
 
@@ -118,24 +120,24 @@
 	 nop				# delay slot
 
 1:
-#if defined(CONFIG_MIPS_SEAD) 	
+#if defined(CONFIG_MIPS_SEAD)
 	beq	a0, zero, 1f
 	 andi	a0, s0, CAUSEF_IP5	# delay slot, check hw3 interrupt
 	jal	sead_hw1_irqdispatch
-	 move	a0, sp			# delay slot	
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
 	 nop				# delay slot
-1:	
-#endif	
-
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
 	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
 	 nop
 	jal	corehi_irqdispatch
-	 move	a0, sp			
+	 move	a0, sp
 	j	ret_from_irq
-	 nop				
-1:	
-
+	 nop
+1:
+#endif
 	/*
 	 * Here by mistake?  This is possible, what can happen is that by the
 	 * time we take the exception the IRQ pin goes low, so just leave if
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/pci.c linux-2.4.20/arch/mips/mips-boards/generic/pci.c
--- linux-2.4.19/arch/mips/mips-boards/generic/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/pci.c	2002-10-04 00:41:16.000000000 +0000
@@ -72,12 +72,12 @@
 
 		/* Clear cause register bits */
 		GT_READ(GT_INTRCAUSE_OFS, intr);
-		GT_WRITE(GT_INTRCAUSE_OFS, intr & 
-			 ~(GT_INTRCAUSE_MASABORT0_BIT | 
+		GT_WRITE(GT_INTRCAUSE_OFS, intr &
+			 ~(GT_INTRCAUSE_MASABORT0_BIT |
 			   GT_INTRCAUSE_TARABORT0_BIT));
 
 		/* Setup address */
-		GT_WRITE(GT_PCI0_CFGADDR_OFS, 
+		GT_WRITE(GT_PCI0_CFGADDR_OFS,
 			 (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
 			 (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
 			 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
@@ -85,9 +85,9 @@
 
 		if (access_type == PCI_ACCESS_WRITE) {
 			if (bus == 0 && dev_fn == 0) {
-				/* 
-				 * The Galileo system controller is acting 
-				 * differently than other devices. 
+				/*
+				 * The Galileo system controller is acting
+				 * differently than other devices.
 				 */
 				GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
 			} else {
@@ -95,9 +95,9 @@
 			}
 		} else {
 			if (bus == 0 && dev_fn == 0) {
-				/* 
-				 * The Galileo system controller is acting 
-				 * differently than other devices. 
+				/*
+				 * The Galileo system controller is acting
+				 * differently than other devices.
 				 */
 				GT_READ(GT_PCI0_CFGDATA_OFS, *data);
 			} else {
@@ -108,15 +108,15 @@
 		/* Check for master or target abort */
 		GT_READ(GT_INTRCAUSE_OFS, intr);
 
-		if (intr & (GT_INTRCAUSE_MASABORT0_BIT | 
+		if (intr & (GT_INTRCAUSE_MASABORT0_BIT |
 			    GT_INTRCAUSE_TARABORT0_BIT))
 		{
 			/* Error occured */
 
 			/* Clear bits */
 			GT_READ(GT_INTRCAUSE_OFS, intr);
-			GT_WRITE(GT_INTRCAUSE_OFS, intr & 
-				 ~(GT_INTRCAUSE_MASABORT0_BIT | 
+			GT_WRITE(GT_INTRCAUSE_OFS, intr &
+				 ~(GT_INTRCAUSE_MASABORT0_BIT |
 				   GT_INTRCAUSE_TARABORT0_BIT));
 
 			return -1;
@@ -133,12 +133,12 @@
 		}
 
 		/* Clear cause register bits */
-		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
 				  BONITO_PCICMD_MTABORT_CLR);
 
-		/* 
-		 * Setup pattern to be used as PCI "address" for 
-		 * Type 0 cycle 
+		/*
+		 * Setup pattern to be used as PCI "address" for
+		 * Type 0 cycle
 		 */
 		if (bus == 0) {
 		        /* IDSEL */
@@ -153,10 +153,10 @@
 
 		/* Function (same for Type 0/1) */
 		pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF;
-		
+
 		/* Register number (same for Type 0/1) */
 		pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
-		
+
 		if (bus == 0) {
 		        /* Type 0 */
 		        BONITO_PCIMAP_CFG = pci_addr >> 16;
@@ -164,7 +164,7 @@
 		        /* Type 1 */
 		        BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
 		}
-	  
+
 		/* Flush Bonito register block */
 		dummy = BONITO_PCIMAP_CFG;
 		__asm__ __volatile__(
@@ -176,28 +176,28 @@
 
 		/* Perform access */
 		if (access_type == PCI_ACCESS_WRITE) {
-		        *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + 
+		        *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE +
 					  (pci_addr & 0xffff))) = *(u32 *)data;
 
 			/* Wait till done */
 			while (BONITO_PCIMSTAT & 0xF)
 			        ;
 		} else {
-		        *(u32 *)data = 
-			  *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + 
+		        *(u32 *)data =
+			  *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE +
 					    (pci_addr & 0xffff)));
 		}
 
 		/* Detect Master/Target abort */
-		if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | 
+		if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
 				     BONITO_PCICMD_MTABORT_CLR) )
 		{
 		        /* Error occurred */
 
 		        /* Clear bits */
-		        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+		        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
 					  BONITO_PCICMD_MTABORT_CLR);
-    
+
 			return -1;
 		}
 	        break;
@@ -210,8 +210,8 @@
 		}
 
 		/* Clear status register bits. */
-		MSC_WRITE(MSC01_PCI_INTSTAT, 
-			  (MSC01_PCI_INTCFG_MA_BIT | 
+		MSC_WRITE(MSC01_PCI_INTSTAT,
+			  (MSC01_PCI_INTCFG_MA_BIT |
 			   MSC01_PCI_INTCFG_TA_BIT));
 
 		/* Setup address */
@@ -236,7 +236,7 @@
 
 		/* Detect Master/Target abort */
 		MSC_READ(MSC01_PCI_INTSTAT, intr);
-		if (intr & (MSC01_PCI_INTCFG_MA_BIT | 
+		if (intr & (MSC01_PCI_INTCFG_MA_BIT |
 			    MSC01_PCI_INTCFG_TA_BIT))
 		{
 		        /* Error occurred */
@@ -244,7 +244,7 @@
 		        /* Clear bits */
 			MSC_READ(MSC01_PCI_INTSTAT, intr);
 			MSC_WRITE(MSC01_PCI_INTSTAT,
-				  (MSC01_PCI_INTCFG_MA_BIT | 
+				  (MSC01_PCI_INTCFG_MA_BIT |
 				   MSC01_PCI_INTCFG_TA_BIT));
 
 			return -1;
@@ -300,7 +300,7 @@
 
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	
+
 	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
@@ -314,7 +314,7 @@
 mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
 {
 	u32 data = 0;
-       
+
 	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
@@ -334,11 +334,11 @@
 
 	if (where & 1)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-       
+
         if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
 	       return -1;
 
-	data = (data & ~(0xffff << ((where & 3) << 3))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
@@ -369,6 +369,55 @@
 	mips_pcibios_write_config_dword
 };
 
+int mips_pcibios_iack(void)
+{
+	int irq;
+        u32 dummy;
+
+	/*
+	 * Determine highest priority pending interrupt by performing
+	 * a PCI Interrupt Acknowledge cycle.
+	 */
+	switch(mips_revision_corid) {
+	case MIPS_REVISION_CORID_QED_RM5261:
+	case MIPS_REVISION_CORID_CORE_LV:
+	case MIPS_REVISION_CORID_CORE_FPGA:
+	case MIPS_REVISION_CORID_CORE_MSC:
+		if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC)
+			MSC_READ(MSC01_PCI_IACK, irq);
+		else
+			GT_READ(GT_PCI0_IACK_OFS, irq);
+		irq &= 0xff;
+		break;
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		/* The following will generate a PCI IACK cycle on the
+		 * Bonito controller. It's a little bit kludgy, but it
+		 * was the easiest way to implement it in hardware at
+		 * the given time.
+		 */
+		BONITO_PCIMAP_CFG = 0x20000;
+
+		/* Flush Bonito register block */
+		dummy = BONITO_PCIMAP_CFG;
+		__asm__ __volatile__(
+			".set\tnoreorder\n\t"
+			".set\tnoat\n\t"
+			"sync\n\t"
+			".set\tat\n\t"
+			".set\treorder");
+
+		irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE));
+		irq &= 0xff;
+		BONITO_PCIMAP_CFG = 0;
+		break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
+		return -1;
+	}
+	return irq;
+}
+
 void __init pcibios_init(void)
 {
 #ifdef CONFIG_MIPS_MALTA
@@ -383,11 +432,11 @@
 	case MIPS_REVISION_CORID_QED_RM5261:
 	case MIPS_REVISION_CORID_CORE_LV:
 	case MIPS_REVISION_CORID_CORE_FPGA:
-		/* 
-		 * Due to a bug in the Galileo system controller, we need 
+		/*
+		 * Due to a bug in the Galileo system controller, we need
 		 * to setup the PCI BAR for the Galileo internal registers.
-		 * This should be done in the bios/bootprom and will be 
-		 * fixed in a later revision of YAMON (the MIPS boards 
+		 * This should be done in the bios/bootprom and will be
+		 * fixed in a later revision of YAMON (the MIPS boards
 		 * boot prom).
 		 */
 		GT_WRITE(GT_PCI0_CFGADDR_OFS,
@@ -398,7 +447,7 @@
 			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
 
 		/* Perform the write */
-		GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); 
+		GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE));
 		break;
 	}
 
@@ -428,15 +477,15 @@
 		}
 	}
 
-	/* 
-	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 
+	/*
+	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O
 	 * Controller.
 	 * This should be done in the bios/bootprom and will be fixed in
          * a later revision of YAMON (the MIPS boards boot prom).
 	 */
 	/* Entering config state. */
-	SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); 
-       
+	SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG);
+
 	/* Activate floppy controller. */
 	SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG);
 	SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG);
@@ -456,7 +505,8 @@
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/printf.c linux-2.4.20/arch/mips/mips-boards/generic/printf.c
--- linux-2.4.19/arch/mips/mips-boards/generic/printf.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/printf.c	2002-10-04 00:41:13.000000000 +0000
@@ -32,20 +32,20 @@
 #include <asm/serial.h>
 
 
-#ifdef CONFIG_MIPS_ATLAS 
-/* 
- * Atlas registers are memory mapped on 64-bit aligned boundaries and 
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD)
+/*
+ * Atlas registers are memory mapped on 64-bit aligned boundaries and
  * only word access are allowed.
  * When reading the UART 8 bit registers only the LSB are valid.
  */
 unsigned int atlas_serial_in(struct async_struct *info, int offset)
 {
-	return inl(info->port + offset*8) & 0xff;
+	return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff);
 }
 
 void atlas_serial_out(struct async_struct *info, int offset, int value)
 {
-	outl(value, info->port + offset*8);
+	*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
 }
 
 #define serial_in  atlas_serial_in
@@ -70,8 +70,8 @@
 };
 
 /*
- * Hooks to fake "prom" console I/O before devices 
- * are fully initialized. 
+ * Hooks to fake "prom" console I/O before devices
+ * are fully initialized.
  */
 static struct async_struct prom_port_info = {0};
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/generic/time.c linux-2.4.20/arch/mips/mips-boards/generic/time.c
--- linux-2.4.19/arch/mips/mips-boards/generic/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/generic/time.c	2002-10-04 00:41:22.000000000 +0000
@@ -35,6 +35,7 @@
 #include <asm/hardirq.h>
 #include <asm/div64.h>
 #include <asm/cpu.h>
+#include <asm/time.h>
 
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
@@ -46,8 +47,6 @@
 static unsigned int r4k_offset; /* Amount to increment compare reg each time */
 static unsigned int r4k_cur;    /* What counter should be at next timer irq */
 
-extern unsigned int mips_counter_frequency;
-
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
 #if defined(CONFIG_MIPS_ATLAS)
@@ -57,7 +56,7 @@
 static char display_string[] = "        LINUX ON MALTA       ";
 #endif
 static unsigned int display_count = 0;
-#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
 
 #define MIPS_CPU_TIMER_IRQ 7
 
@@ -71,13 +70,6 @@
 
 void mips_timer_interrupt(struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
-	int irq = MIPS_CPU_TIMER_IRQ;
-
-	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
-	timer_interrupt(irq, NULL, regs);
-
 	if ((timer_tick_count++ % HZ) == 0) {
 		mips_display_message(&display_string[display_count++]);
 		if (display_count == MAX_DISPLAY_COUNT)
@@ -85,15 +77,12 @@
 
 	}
 
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
+	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
 }
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the RTC to calculate offset.
  */
 static unsigned int __init cal_r4koff(void)
@@ -141,7 +130,7 @@
 		if ((hour & 0xf) == 0xc)
 		        hour &= 0x80;
 	        if (hour & 0x80)
-		        hour = (hour & 0xf) + 12;     
+		        hour = (hour & 0xf) + 12;
 	}
 	day = CMOS_READ(RTC_DAY_OF_MONTH);
 	mon = CMOS_READ(RTC_MONTH);
@@ -162,14 +151,14 @@
 
 	__save_and_cli(flags);
 
-        /* Set Data mode - binary. */ 
+        /* Set Data mode - binary. */
         CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
 
 	printk("calculating r4koff... ");
 	r4k_offset = cal_r4koff();
 	printk("%08x(%d)\n", r4k_offset, r4k_offset);
 
-        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == 
+        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) ==
 	    (PRID_COMP_MIPS | PRID_IMP_20KC))
 		est_freq = r4k_offset*HZ;
 	else
@@ -177,7 +166,7 @@
 
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
 	       (est_freq%1000000)*100/1000000);
 
 	__restore_flags(flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/malta/Makefile linux-2.4.20/arch/mips/mips-boards/malta/Makefile
--- linux-2.4.19/arch/mips/mips-boards/malta/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/malta/Makefile	2002-10-04 00:41:09.000000000 +0000
@@ -7,12 +7,12 @@
 # This program is free software; you can distribute it and/or modify it
 # under the terms of the GNU General Public License (Version 2) as
 # published by the Free Software Foundation.
-# 
+#
 # This program is distributed in the hope 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.,
 # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/malta/malta_int.c linux-2.4.20/arch/mips/mips-boards/malta/malta_int.c
--- linux-2.4.19/arch/mips/mips-boards/malta/malta_int.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/malta/malta_int.c	2002-10-04 00:41:14.000000000 +0000
@@ -16,9 +16,9 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
- * Routines for generic manipulation of the interrupts found on the MIPS 
+ * Routines for generic manipulation of the interrupts found on the MIPS
  * Malta board.
- * The interrupt controller is located in the South Bridge a PIIX4 device 
+ * The interrupt controller is located in the South Bridge a PIIX4 device
  * with two internal 82C95 interrupt controllers.
  */
 #include <linux/config.h>
@@ -41,207 +41,49 @@
 extern asmlinkage void mipsIRQ(void);
 extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
 extern void init_i8259_irqs (void);
-
-void enable_mips_irq(unsigned int irq);
-void disable_mips_irq(unsigned int irq);
+extern int mips_pcibios_iack(void);
 
 static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED;
 
-static void end_mips_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_mips_irq(irq);
-}
-
-#define shutdown_mips_irq	disable_mips_irq
-
-void mask_and_ack_mips_irq(unsigned int irq);
-
-static unsigned int startup_mips_irq(unsigned int irq)
-{ 
-	enable_mips_irq(irq);
-
-	return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type mips_irq_type = {
-	"XT-PIC",
-	startup_mips_irq,
-	shutdown_mips_irq,
-	enable_mips_irq,
-	disable_mips_irq,
-	mask_and_ack_mips_irq,
-	end_mips_irq,
-	NULL
-};
-
-/*
- * This contains the interrupt mask for both 82C59 interrupt controllers.
- */
-static unsigned int cached_int_mask = 0xffff;
-
-void disable_mips_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	spin_lock_irqsave(&mips_irq_lock, flags);
-	cached_int_mask |= (1 << irq_nr);
-	if (irq_nr & 8) {
-	        outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}
-	spin_unlock_irqrestore(&mips_irq_lock, flags);
-}
-
-void enable_mips_irq(unsigned int irq_nr)
-{
-        unsigned long flags;
-
-	if(irq_nr >= MALTAINT_END) {
-		printk("whee, invalid irq_nr %d\n", irq_nr);
-		panic("IRQ, you lose...");
-	}
-
-	spin_lock_irqsave(&mips_irq_lock, flags);
-	cached_int_mask &= ~(1 << irq_nr);
-	if (irq_nr & 8) {
-		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-		/* Enable irq 2 (cascade interrupt). */
-	        cached_int_mask &= ~(1 << 2); 
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	} else {
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-	}	
-	spin_unlock_irqrestore(&mips_irq_lock, flags);
-}
-
-void mask_and_ack_mips_irq(unsigned int irq)
-{
-        unsigned long flags;
-
-	spin_lock_irqsave(&mips_irq_lock, flags);
-	if (irq & 8) {
-	        /* Non specific EOI to cascade */
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, 
-		     PIIX4_ICTLR1_OCW2);
-
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2);
-	} else {
-		outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2);
-	}
-	spin_unlock_irqrestore(&mips_irq_lock, flags);
-}
-
 static inline int get_int(int *irq)
 {
-	unsigned char irr;
-	
-	switch(mips_revision_corid) {
-	case MIPS_REVISION_CORID_QED_RM5261:
-	case MIPS_REVISION_CORID_CORE_LV:
-	case MIPS_REVISION_CORID_CORE_FPGA:
-	case MIPS_REVISION_CORID_CORE_MSC:
-		/*  
-		 * Determine highest priority pending interrupt by performing
-		 * a PCI Interrupt Acknowledge cycle.
-		 */
-		if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC)
-			MSC_READ(MSC01_PCI_IACK, *irq);
-		else
-			GT_READ(GT_PCI0_IACK_OFS, *irq);
-		*irq &= 0xFF;
-
-		/*  
-		 * IRQ7 is used to detect spurious interrupts.
-		 * The interrupt acknowledge cycle returns IRQ7, if no 
-		 * interrupts is requested.
-		 * We can differentiate between this situation and a
-		 * "Normal" IRQ7 by reading the ISR.
-		 */
-		if (*irq == 7) 
-		{
-			outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, 
-			     PIIX4_ICTLR1_OCW3);
-			if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
-				printk("We got a spurious interrupt from PIIX4.\n");
-				atomic_inc(&irq_err_count);
-				return -1;    /* Spurious interrupt. */
-			}
-		}
-		break;
+	unsigned long flags;
 
-	case MIPS_REVISION_CORID_BONITO64:
-	case MIPS_REVISION_CORID_CORE_20K:
-	        /*
-		 * Determine highest priority pending interrupt by reading 
-		 * the IRR register of controller 1.
-		 */
+	spin_lock_irqsave(&mips_irq_lock, flags);
 
-		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_IRR, PIIX4_ICTLR1_OCW3);
-		irr = inb(PIIX4_ICTLR1_OCW3) & ~(cached_int_mask & 0xff);
+	*irq = mips_pcibios_iack();
 
-		if (!irr) {
-		        printk("We got a spurious interrupt from PIIX4.\n");
+	/*
+	 * IRQ7 is used to detect spurious interrupts.
+	 * The interrupt acknowledge cycle returns IRQ7, if no
+	 * interrupts is requested.
+	 * We can differentiate between this situation and a
+	 * "Normal" IRQ7 by reading the ISR.
+	 */
+	if (*irq == 7)
+	{
+		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR,
+		     PIIX4_ICTLR1_OCW3);
+		if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) {
+			spin_unlock_irqrestore(&mips_irq_lock, flags);
+			printk("We got a spurious interrupt from PIIX4.\n");
 			atomic_inc(&irq_err_count);
-			return -1;   /* Spurious interrupt. */
-		}
-		*irq = 0;
-		while ((*irq < 7) && !(irr & 0x01)) {
-		        (*irq)++;
-			irr >>= 1;
+			return -1;    /* Spurious interrupt. */
 		}
-
-		if (*irq == 2)
-		{
-		        /*
-			 * Determine highest priority pending interrupt by 
-			 * reading the IRR register of controller 1.
-			 */
-		        outb(PIIX4_OCW3_SEL | PIIX4_OCW3_IRR, 
-			     PIIX4_ICTLR2_OCW3);
-			irr = inb(PIIX4_ICTLR2_OCW3) & 
-			~((cached_int_mask >> 8) & 0xff);
-
-			*irq = 8;
-			while ((*irq < 15) && !(irr & 0x01)) {
-			        (*irq)++;
-				irr >>= 1;
-			}
-		}
-		break;
-	default:
-	        printk("Unknown Core card, don't know the system controller.\n");
-		return -1;
 	}
 
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+
 	return 0;
 }
 
 void malta_hw0_irqdispatch(struct pt_regs *regs)
 {
 	int irq;
-	struct irqaction *action;
 
 	if (get_int(&irq))
 	        return;  /* interrupt has already been cleared */
 
-	switch(mips_revision_corid) {
-	case MIPS_REVISION_CORID_BONITO64:
-	case MIPS_REVISION_CORID_CORE_20K:
-		action = irq_desc[irq].action;
-		if (!action)
-			return;
-		action->flags |= SA_INTERRUPT;
-		break;
-	}
-	
 	do_IRQ(irq, regs);
 }
 
@@ -288,38 +130,9 @@
 
 void __init init_IRQ(void)
 {
-	unsigned int i;
-
 	set_except_vector(0, mipsIRQ);
 	init_generic_irq();
-	
-	switch(mips_revision_corid) {
-	case MIPS_REVISION_CORID_QED_RM5261:
-	case MIPS_REVISION_CORID_CORE_LV:
-	case MIPS_REVISION_CORID_CORE_FPGA:
-	case MIPS_REVISION_CORID_CORE_MSC:
-		init_i8259_irqs();
-		break;
-	case MIPS_REVISION_CORID_BONITO64:
-	case MIPS_REVISION_CORID_CORE_20K:
-		/* 
-		 * Mask out all interrupt by writing "1" to all bit position 
-		 * in the IMR register. 
-		 */
-		outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1);
-		outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1);
-
-		for (i = 0; i < 16; i++) {
-			irq_desc[i].status = IRQ_DISABLED;
-			irq_desc[i].action = 0;
-			irq_desc[i].depth = 1;
-			irq_desc[i].handler = &mips_irq_type;
-		}
-		break;
-	default:
-	        printk("Unknown Core card, don't know the system controller.\n");
-		return;
-	}
+	init_i8259_irqs();
 
 #ifdef CONFIG_REMOTE_DEBUG
 	if (remote_debug) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.20/arch/mips/mips-boards/malta/malta_setup.c
--- linux-2.4.19/arch/mips/mips-boards/malta/malta_setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/malta/malta_setup.c	2002-10-04 00:41:20.000000000 +0000
@@ -104,7 +104,7 @@
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, standard_io_resources+i);
 
-	/* 
+	/*
 	 * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.
 	 */
 	enable_dma(4);
@@ -145,14 +145,6 @@
 	if ((argptr = strstr(argptr, "nofpu")) != NULL)
 		mips_cpu.options &= ~MIPS_CPU_FPU;
 
-        /* 
-	 * For some reason the irq probing doesn't work on the 
-	 * Bonito controller.
-	 * For now this work just fine.
-	 */
-	argptr = prom_getcmdline();
-	strcat(argptr, " ide0=0x1f0,0x3f6,14");
-		
 	rtc_ops = &malta_rtc_ops;
 
 #ifdef CONFIG_BLK_DEV_IDE
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/sead/Makefile linux-2.4.20/arch/mips/mips-boards/sead/Makefile
--- linux-2.4.19/arch/mips/mips-boards/sead/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/sead/Makefile	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,40 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the MIPS SEAD specific kernel interface routines
+# under Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+
+all: sead.o
+
+O_TARGET := sead.o
+
+obj-y	:= sead_int.o sead_setup.o sead_time.o
+
+include $(TOPDIR)/Rules.make
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/sead/sead_int.c linux-2.4.20/arch/mips/mips-boards/sead/sead_int.c
--- linux-2.4.19/arch/mips/mips-boards/sead/sead_int.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/sead/sead_int.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,116 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Sead board.
+ *
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/irq.h>
+#include <asm/mips-boards/sead.h>
+#include <asm/mips-boards/seadint.h>
+
+extern asmlinkage void mipsIRQ(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+void disable_sead_irq(unsigned int irq_nr)
+{
+	if (irq_nr == SEADINT_UART0)
+		clear_cp0_status(0x00000400);
+	else
+		if (irq_nr == SEADINT_UART1)
+			clear_cp0_status(0x00000800);
+}
+
+void enable_sead_irq(unsigned int irq_nr)
+{
+	if (irq_nr == SEADINT_UART0)
+		set_cp0_status(0x00000400);
+	else
+		if (irq_nr == SEADINT_UART1)
+			set_cp0_status(0x00000800);
+}
+
+static unsigned int startup_sead_irq(unsigned int irq)
+{
+	enable_sead_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sead_irq	disable_sead_irq
+
+#define mask_and_ack_sead_irq disable_sead_irq
+
+static void end_sead_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_sead_irq(irq);
+}
+
+static struct hw_interrupt_type sead_irq_type = {
+	"SEAD",
+	startup_sead_irq,
+	shutdown_sead_irq,
+	enable_sead_irq,
+	disable_sead_irq,
+	mask_and_ack_sead_irq,
+	end_sead_irq,
+	NULL
+};
+
+void sead_hw0_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(0, regs);
+}
+
+void sead_hw1_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(1, regs);
+}
+
+void __init init_IRQ(void)
+{
+	int i;
+
+        /*
+         * Mask out all interrupt
+	 */
+	clear_cp0_status(0x0000ff00);
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+
+	init_generic_irq();
+
+	for (i = 0; i <= SEADINT_END; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= NULL;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].lock	= SPIN_LOCK_UNLOCKED;
+		irq_desc[i].handler	= &sead_irq_type;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.20/arch/mips/mips-boards/sead/sead_setup.c
--- linux-2.4.19/arch/mips/mips-boards/sead/sead_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/sead/sead_setup.c	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,81 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * SEAD specific setup.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mc146818rtc.h>
+#include <linux/ioport.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/seadint.h>
+#include <asm/time.h>
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+extern void mips_reboot_setup(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+
+const char *get_system_type(void)
+{
+	return "MIPS SEAD";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init sead_setup(void)
+{
+	char *argptr;
+
+	ioport_resource.end = 0x7fffffff;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	argptr = prom_getcmdline();
+	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+		int i = 0;
+		char *s = prom_getenv("modetty0");
+		while(s[i] >= '0' && s[i] <= '9')
+			i++;
+		strcpy(serial_console, "ttyS0,");
+		strncpy(serial_console + 6, s, i);
+		prom_printf("Config serial console: %s\n", serial_console);
+		console_setup(serial_console, NULL);
+	}
+#endif
+
+	argptr = prom_getcmdline();
+
+	if ((argptr = strstr(argptr, "nofpu")) != NULL)
+		mips_cpu.options &= ~MIPS_CPU_FPU;
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+
+	mips_reboot_setup();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mips-boards/sead/sead_time.c linux-2.4.20/arch/mips/mips-boards/sead/sead_time.c
--- linux-2.4.19/arch/mips/mips-boards/sead/sead_time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/mips-boards/sead/sead_time.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,149 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope 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.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/hardirq.h>
+#include <asm/cpu.h>
+
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern volatile unsigned long wall_jiffies;
+
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
+extern rwlock_t xtime_lock;
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5)
+
+static char display_string[] = "        LINUX ON SEAD       ";
+
+static unsigned int display_count = 0;
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
+
+#define MIPS_CPU_TIMER_IRQ 7
+
+static unsigned int timer_tick_count=0;
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+	write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around.  This one is rather different, but the algorithm
+ * is provably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = MIPS_CPU_TIMER_IRQ;
+
+	irq_enter(cpu, irq);
+
+	do {
+		kstat.irqs[cpu][irq]++;
+		do_timer(regs);
+
+		if ((timer_tick_count++ % HZ) == 0) {
+		    mips_display_message(&display_string[display_count++]);
+		    if (display_count == MAX_DISPLAY_COUNT)
+		        display_count = 0;
+		}
+
+		r4k_cur += r4k_offset;
+		ack_r4ktimer(r4k_cur);
+
+	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
+	         - r4k_cur) < 0x7fffffff);
+
+	irq_exit(cpu, irq);
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+/*
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+	/*
+	 * The SEAD board doesn't have a real time clock, so we can't
+	 * really calculate the timer offset.
+	 * For now we hardwire the SEAD board frequency to 12MHz.
+	 */
+	return(6000000/HZ);
+}
+
+void __init mips_time_init(void)
+{
+        unsigned int est_freq, flags;
+
+	__save_and_cli(flags);
+
+        /* Start r4k counter. */
+        write_32bit_cp0_register(CP0_COUNT, 0);
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) ==
+	    (PRID_COMP_MIPS | PRID_IMP_20KC))
+		est_freq = r4k_offset*HZ;
+	else
+		est_freq = 2*r4k_offset*HZ;
+
+	est_freq += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+	__restore_flags(flags);
+}
+
+void __init mips_timer_setup(struct irqaction *irq)
+{
+	/* we are using the cpu counter for timer interrupts */
+	irq->handler = no_action;     /* we use our own handler */
+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
+
+        /* to generate the first timer interrupt */
+	r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+	write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+	set_cp0_status(ALLINTS);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/Makefile linux-2.4.20/arch/mips/mm/Makefile
--- linux-2.4.19/arch/mips/mm/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -20,8 +20,10 @@
 obj-$(CONFIG_CPU_R4300)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_R4X00)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_VR41XX)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_R5000)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \
+				   r5k-sc.o
+obj-$(CONFIG_CPU_NEVADA)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \
+				   r5k-sc.o
 obj-$(CONFIG_CPU_R5432)		+= pg-r5432.o c-r5432.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_RM7000)	+= pg-rm7k.o c-rm7k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_R10000)	+= pg-andes.o c-andes.o tlb-r4k.o tlbex-r4k.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-andes.c linux-2.4.20/arch/mips/mm/c-andes.c
--- linux-2.4.19/arch/mips/mm/c-andes.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-andes.c	2002-10-04 00:41:21.000000000 +0000
@@ -124,6 +124,6 @@
 			printk("Unknown L2 line size\n");
 			while(1);
 	}
-    
+
         flush_cache_l1();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-mips32.c linux-2.4.20/arch/mips/mm/c-mips32.c
--- linux-2.4.19/arch/mips/mm/c-mips32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-mips32.c	2002-10-04 00:41:11.000000000 +0000
@@ -424,33 +424,33 @@
 	unsigned int lsize;
 
         if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
+	        /*
+		 * Not a MIPS32 complainant CPU.
 		 * Config 1 register not supported, we assume R4k style.
 		 */
 	        icache_size = 1 << (12 + ((config >> 9) & 7));
 		ic_lsize = 16 << ((config >> 5) & 1);
 		mips_cpu.icache.linesz = ic_lsize;
-		
-		/* 
+
+		/*
 		 * We cannot infer associativity - assume direct map
 		 * unless probe template indicates otherwise
 		 */
 		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
-		mips_cpu.icache.sets = 
+		mips_cpu.icache.sets =
 			(icache_size / ic_lsize) / mips_cpu.icache.ways;
 	} else {
-	       config1 = read_mips32_cp0_config1(); 
+	       config1 = read_mips32_cp0_config1();
 
 	       if ((lsize = ((config1 >> 19) & 7)))
 		       mips_cpu.icache.linesz = 2 << lsize;
-	       else 
+	       else
 		       mips_cpu.icache.linesz = lsize;
 	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
 	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
 
 	       ic_lsize = mips_cpu.icache.linesz;
-	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * 
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
 		             ic_lsize;
 	}
 	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
@@ -463,32 +463,32 @@
 	unsigned int lsize;
 
         if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
+	        /*
+		 * Not a MIPS32 complainant CPU.
 		 * Config 1 register not supported, we assume R4k style.
-		 */  
+		 */
 		dcache_size = 1 << (12 + ((config >> 6) & 7));
 		dc_lsize = 16 << ((config >> 4) & 1);
 		mips_cpu.dcache.linesz = dc_lsize;
-		/* 
+		/*
 		 * We cannot infer associativity - assume direct map
 		 * unless probe template indicates otherwise
 		 */
 		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
-		mips_cpu.dcache.sets = 
+		mips_cpu.dcache.sets =
 			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
 	} else {
 	        config1 = read_mips32_cp0_config1();
 
 		if ((lsize = ((config1 >> 10) & 7)))
 		        mips_cpu.dcache.linesz = 2 << lsize;
-		else 
+		else
 		        mips_cpu.dcache.linesz= lsize;
 		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
 		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
 
 		dc_lsize = mips_cpu.dcache.linesz;
-		dcache_size = 
+		dcache_size =
 			mips_cpu.dcache.sets * mips_cpu.dcache.ways
 			* dc_lsize;
 	}
@@ -638,12 +638,12 @@
 
 	if (sc_present) {
 	  	mips_cpu.scache.linesz = sc_lsize;
-		/* 
+		/*
 		 * We cannot infer associativity - assume direct map
 		 * unless probe template indicates otherwise
 		 */
 		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
-		mips_cpu.scache.sets = 
+		mips_cpu.scache.sets =
 		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
 
 		setup_scache_funcs();
@@ -657,11 +657,7 @@
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-#ifdef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-r3k.c linux-2.4.20/arch/mips/mm/c-r3k.c
--- linux-2.4.19/arch/mips/mm/c-r3k.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-r3k.c	2002-10-04 00:41:21.000000000 +0000
@@ -19,7 +19,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -50,8 +49,8 @@
 		for (size = 128; size <= 0x40000; size <<= 1)
 			*(p + size) = 0;
 		*p = -1;
-		for (size = 128; 
-		     (size <= 0x40000) && (*(p + size) == 0); 
+		for (size = 128;
+		     (size <= 0x40000) && (*(p + size) == 0);
 		     size <<= 1)
 			;
 		if (size > 0x40000)
@@ -97,7 +96,7 @@
 	dcache_size = r3k_cache_size(ST0_ISC);
 	if (dcache_size)
 		dcache_lsize = r3k_cache_lsize(ST0_ISC);
-	
+
 
 	icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
 	if (icache_size)
@@ -239,7 +238,7 @@
 static inline void r3k_flush_cache_all(void)
 {
 }
- 
+
 static inline void r3k___flush_cache_all(void)
 {
 	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
@@ -314,7 +313,7 @@
 
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
-	wbflush();
+	iob();
 	r3k_flush_dcache_range(start, start + size);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-r4k.c linux-2.4.20/arch/mips/mm/c-r4k.c
--- linux-2.4.19/arch/mips/mm/c-r4k.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-r4k.c	2002-10-04 00:41:30.000000000 +0000
@@ -1150,12 +1150,6 @@
 	}
 }
 
-static void
-r4k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("r4k_dma_cache called - should not happen.");
-}
-
 /*
  * While we're protected against bad userland addresses we don't care
  * very much about what happens in that case.  Usually a segmentation
@@ -1200,6 +1194,12 @@
 {
         switch (mips_cpu.cputype) {
         case CPU_VR41XX:
+        case CPU_VR4111:
+        case CPU_VR4121:
+        case CPU_VR4122:
+        case CPU_VR4131:
+        case CPU_VR4181:
+        case CPU_VR4181A:
                 icache_size = 1 << (10 + ((config >> 9) & 7));
                 break;
         default:
@@ -1216,6 +1216,12 @@
 {
         switch (mips_cpu.cputype) {
         case CPU_VR41XX:
+        case CPU_VR4111:
+        case CPU_VR4121:
+        case CPU_VR4122:
+        case CPU_VR4131:
+        case CPU_VR4181:
+        case CPU_VR4181A:
                 dcache_size = 1 << (10 + ((config >> 6) & 7));
                 break;
         default:
@@ -1358,7 +1364,7 @@
 	_flush_icache_page = r4k_flush_icache_page_p;
 
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
-	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_wback = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
 }
 
@@ -1441,7 +1447,7 @@
 	___flush_cache_all = _flush_cache_all;
 	_flush_icache_page = r4k_flush_icache_page_s;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
-	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_wback = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
 }
 
@@ -1456,23 +1462,31 @@
 	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
 	sc_present = probe_scache_kseg1(config);
 
-	if (sc_present) {
-		setup_scache_funcs();
+	if (!sc_present) {
+		setup_noscache_funcs();
 		return;
 	}
 
-	setup_noscache_funcs();
+	switch(mips_cpu.cputype) {
+	case CPU_R5000:
+	case CPU_NEVADA:
+			setup_noscache_funcs();
+#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+			r5k_sc_init();
+#endif
+			break;
+	default:
+			setup_scache_funcs();
+	}
+
+
 }
 
 void __init ld_mmu_r4xx0(void)
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-#ifdef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
+	change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-r5432.c linux-2.4.20/arch/mips/mm/c-r5432.c
--- linux-2.4.19/arch/mips/mm/c-r5432.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-r5432.c	2002-10-04 00:41:15.000000000 +0000
@@ -352,7 +352,7 @@
 	blast_dcache32_page((unsigned long)page_address(page));
 }
 
-static void 
+static void
 r5432_flush_icache_range(unsigned long start, unsigned long end)
 {
 	r5432_flush_cache_all_d32i32();
@@ -455,7 +455,7 @@
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-rm7k.c linux-2.4.20/arch/mips/mm/c-rm7k.c
--- linux-2.4.19/arch/mips/mm/c-rm7k.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-rm7k.c	2002-10-04 00:41:10.000000000 +0000
@@ -139,7 +139,7 @@
 		a += sc_lsize;
 	}
 
-	if (!rm7k_tcache_enabled) 
+	if (!rm7k_tcache_enabled)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -150,7 +150,7 @@
 		a += tc_pagesize;
 	}
 }
-	       
+
 static void
 rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
 {
@@ -165,7 +165,7 @@
 		a += sc_lsize;
 	}
 
-	if (!rm7k_tcache_enabled) 
+	if (!rm7k_tcache_enabled)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -210,10 +210,10 @@
 }
 
 
-/* 
+/*
  * This function is executed in the uncached segment KSEG1.
  * It must not touch the stack, because the stack pointer still points
- * into KSEG0. 
+ * into KSEG0.
  *
  * Three options:
  *	- Write it in assembly and guarantee that we don't use the stack.
@@ -228,12 +228,12 @@
 static __init void setup_scache(void)
 {
 	int register i;
-	
+
 	set_cp0_config(1<<3 /* CONF_SE */);
 
 	set_taglo(0);
 	set_taghi(0);
-	
+
 	for (i=0; i<scache_size; i+=sc_lsize) {
 		__asm__ __volatile__ (
 		      ".set noreorder\n\t"
@@ -265,7 +265,7 @@
 	func();
 	printk("Done\n");
 }
- 
+
 static inline void probe_tcache(unsigned long config)
 {
 	if ((config >> 17) & 1)
@@ -275,10 +275,10 @@
 	 * magic necessary to turn it on, and blindly asking the CPU to
 	 * start using it would may give cache errors.
 	 *
-	 * Also, board-specific knowledge may allow us to use the 
+	 * Also, board-specific knowledge may allow us to use the
 	 * CACHE Flash_Invalidate_T instruction if the tag RAM supports
 	 * it, and may specify the size of the L3 cache so we don't have
-	 * to probe it. 
+	 * to probe it.
 	 */
 	printk(KERN_INFO "Tertiary cache present, %s enabled\n",
 	       config&(1<<12) ? "already" : "not (yet)");
@@ -319,9 +319,7 @@
 			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
 	}
 
-#ifndef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-sb1.c linux-2.4.20/arch/mips/mm/c-sb1.c
--- linux-2.4.19/arch/mips/mm/c-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-sb1.c	2002-10-04 00:41:22.000000000 +0000
@@ -12,11 +12,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <asm/mmu_context.h>
@@ -63,7 +63,7 @@
  * if we miss in the icache, and have dirty data in the
  * L1 dcache, then we'll go out to memory (or the L2) and
  * get the not-as-recent data.
- * 
+ *
  * So the only time we have to flush the dcache is when
  * we're flushing the icache.  Since the L2 is fully
  * coherent to everything, including I/O, we never have
@@ -80,7 +80,7 @@
 	 * Haven't worried too much about speed here; given that we're flushing
 	 * the icache, the time to invalidate is dwarfed by the time it's going
 	 * to take to refill it.  Register usage:
-	 * 
+	 *
 	 * $1 - moving cache index
 	 * $2 - set count
 	 */
@@ -104,7 +104,7 @@
 		".set noreorder             \n"
 		".set mips2                 \n"
 		"sync                       \n"
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
 		"sync                       \n"
 #endif
 		".set pop                   \n");
@@ -160,7 +160,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		"1:                         \n"
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 		".align 3                   \n"
@@ -199,7 +199,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		".align 3                   \n"
 		"1:   cache  %3, (0<<13)($1) \n" /* Index-inval this address */
 		"     cache  %3, (1<<13)($1) \n" /* Index-inval this address */
@@ -279,9 +279,9 @@
 static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
-	/* Have to be sure the TLB entry exists for the cache op, 
+	/* Have to be sure the TLB entry exists for the cache op,
 	   so we have to be sure that nothing happens in between the
-	   lw and the cache op 
+	   lw and the cache op
 	*/
 	unsigned long flags;
 	local_irq_save(flags);
@@ -371,7 +371,7 @@
 	 * Haven't worried too much about speed here; given that we're flushing
 	 * the icache, the time to invalidate is dwarfed by the time it's going
 	 * to take to refill it.  Register usage:
-	 * 
+	 *
 	 * $1 - moving cache index
 	 * $2 - set count
 	 */
@@ -403,23 +403,23 @@
 
 /*
  * This only needs to make sure stores done up to this
- * point are visible to other agents outside the CPU.  Given 
- * the coherent nature of the ZBbus, all that's required here is 
+ * point are visible to other agents outside the CPU.  Given
+ * the coherent nature of the ZBbus, all that's required here is
  * a sync to make sure the data gets out to the caches and is
- * visible to an arbitrary A Phase from an external agent 
- *   
+ * visible to an arbitrary A Phase from an external agent
+ *
  * Actually, I'm not even sure that's necessary; the semantics
  * of this function aren't clear.  If it's supposed to serve as
- * a memory barrier, this is needed.  If it's only meant to 
+ * a memory barrier, this is needed.  If it's only meant to
  * prevent data from being invisible to non-cpu memory accessors
- * for some indefinite period of time (e.g. in a non-coherent 
+ * for some indefinite period of time (e.g. in a non-coherent
  * dcache) then this function would be a complete nop.
  */
 static void sb1_flush_page_to_ram(struct page *page)
 {
 	__asm__ __volatile__(
 		"     sync  \n"  /* Short pipe */
-		:::"memory");	
+		:::"memory");
 }
 
 /*
@@ -433,13 +433,13 @@
  * 6 - 4096
  * 7 - Reserved
  */
-  
+
 static unsigned int decode_cache_sets(unsigned int config_field)
 {
 	if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 6));
 }
 
@@ -462,7 +462,7 @@
 	} else if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 1));
 }
 
@@ -519,6 +519,6 @@
 	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
 	_flush_icache_all = sb1_flush_icache_all;
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 	flush_cache_all();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-tx39.c linux-2.4.20/arch/mips/mm/c-tx39.c
--- linux-2.4.19/arch/mips/mm/c-tx39.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-tx39.c	2002-10-04 00:41:09.000000000 +0000
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -63,8 +62,8 @@
 static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
-	wbflush();
 
+	iob();
 	a = addr & ~(dcache_lsize - 1);
 	end = (addr + size) & ~(dcache_lsize - 1);
 	while (1) {
@@ -89,7 +88,7 @@
 	write_32bit_cp0_register(CP0_CONF, config);
 	__restore_flags(flags);
 }
- 
+
 static void tx39_flush_cache_mm(struct mm_struct *mm)
 {
 	if(mm->context != 0) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/c-tx49.c linux-2.4.20/arch/mips/mm/c-tx49.c
--- linux-2.4.19/arch/mips/mm/c-tx49.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/c-tx49.c	2002-10-04 00:41:13.000000000 +0000
@@ -387,11 +387,7 @@
 	if (mips_configk0 != -1)
 		change_cp0_config(CONF_CM_CMASK, mips_configk0);
 	else
-#ifdef CONFIG_MIPS_UNCACHED
-		change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-		change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
+		change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/extable.c linux-2.4.20/arch/mips/mm/extable.c
--- linux-2.4.19/arch/mips/mm/extable.c	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/extable.c	2002-10-04 00:41:21.000000000 +0000
@@ -36,14 +36,13 @@
 search_exception_table(unsigned long addr)
 {
 	unsigned long ret = 0;
-	
+
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 	return ret;
 #else
 	unsigned long flags;
-
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/fault.c linux-2.4.20/arch/mips/mm/fault.c
--- linux-2.4.19/arch/mips/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/fault.c	2002-10-04 00:41:14.000000000 +0000
@@ -211,13 +211,11 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk(KERN_NOTICE "VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/init.c linux-2.4.20/arch/mips/mm/init.c
--- linux-2.4.19/arch/mips/mm/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/init.c	2002-10-04 00:41:29.000000000 +0000
@@ -67,9 +67,9 @@
 {
 	unsigned long order, size;
 	struct page *page;
-	if(mips_cpu.options & MIPS_CPU_VCE) 
+	if(mips_cpu.options & MIPS_CPU_VCE)
 		order = 3;
-	else 
+	else
 		order = 0;
 
 	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
@@ -367,7 +367,7 @@
 	unsigned long addr;
 
 	prom_free_prom_memory ();
-    
+
 	addr = (unsigned long) &__init_begin;
 	while (addr < (unsigned long) &__init_end) {
 		ClearPageReserved(virt_to_page(addr));
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/ioremap.c linux-2.4.20/arch/mips/mm/ioremap.c
--- linux-2.4.19/arch/mips/mm/ioremap.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/ioremap.c	2002-10-04 00:41:20.000000000 +0000
@@ -122,10 +122,11 @@
 		return NULL;
 
 	/*
-	 * Map objects in the low 512mb of address space using KSEG1, otherwise
-	 * map using page tables.
+	 * Map uncached objects in the low 512mb of address space using KSEG1,
+	 * otherwise map using page tables.
 	 */
-	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr))
+	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
+	    flags == _CACHE_UNCACHED)
 		return (void *) KSEG1ADDR(phys_addr);
 
 	/*
@@ -137,7 +138,7 @@
 
 		t_addr = __va(phys_addr);
 		t_end = t_addr + (size - 1);
-	   
+
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/loadmmu.c linux-2.4.20/arch/mips/mm/loadmmu.c
--- linux-2.4.19/arch/mips/mm/loadmmu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/loadmmu.c	2002-10-04 00:41:12.000000000 +0000
@@ -119,6 +119,7 @@
 #endif
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
+	case CPU_R12000:
 		ld_mmu_andes();
 		r4k_tlb_init();
 		break;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/pg-r4k.S linux-2.4.20/arch/mips/mm/pg-r4k.S
--- linux-2.4.19/arch/mips/mm/pg-r4k.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/pg-r4k.S	2002-10-04 00:41:22.000000000 +0000
@@ -83,10 +83,10 @@
  *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
  *      executed if there is no other dcache activity. If the dcache is
  *      accessed for another instruction immeidately preceding when these
- *      cache instructions are executing, it is possible that the dcache 
- *      tag match outputs used by these cache instructions will be 
+ *      cache instructions are executing, it is possible that the dcache
+ *      tag match outputs used by these cache instructions will be
  *      incorrect. These cache instructions should be preceded by at least
- *      four instructions that are not any kind of load or store 
+ *      four instructions that are not any kind of load or store
  *      instruction.
  *
  *      This is not allowed:    lw
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/pg-sb1.c linux-2.4.20/arch/mips/mm/pg-sb1.c
--- linux-2.4.19/arch/mips/mm/pg-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/pg-sb1.c	2002-10-04 00:41:23.000000000 +0000
@@ -2,7 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000 Sibyte
- * 
+ *
  * Written by Justin Carlson (carlson@sibyte.com)
  *
  *
@@ -15,11 +15,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <asm/page.h>
 
@@ -39,7 +39,7 @@
 	   performance model */
 
 	/* We prefetch 4 lines ahead.  We're also "cheating" slightly here...
-	   since we know we're on an SB1, we force the assembler to take 
+	   since we know we're on an SB1, we force the assembler to take
 	   64-bit operands to speed things up */
 	__asm__ __volatile__(
 		".set push                  \n"
@@ -47,15 +47,19 @@
 		".set noat                  \n"
 		".set mips4                 \n"
 		"     addiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"  
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"  
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"
+#endif
 		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
 		"     sd        $0,  8(%0)  \n"
 		"     sd        $0, 16(%0)  \n"
 		"     sd        $0, 24(%0)  \n"
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
+#endif
 		"     bne       $1, %0, 1b  \n"
 		"     addiu     %0, %0, 32  \n"  /* Next cacheline (This instruction better be short piped!) */
 		".set pop                   \n"
@@ -71,7 +75,7 @@
 
 	/* This should be optimized in assembly...can't use ld/sd, though,
 	 * because the top 32 bits could be nuked if we took an interrupt
-	 * during the routine.	And this is not a good place to be cli()'ing 
+	 * during the routine.	And this is not a good place to be cli()'ing
 	 */
 
 	/* The pref's used here are using "streaming" hints, which cause the
@@ -87,12 +91,14 @@
 		".set noat                  \n"
 		".set mips4                 \n"
 		"     addiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)  \n"  /* Prefetch the first 3 lines */
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"
+#endif
 		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
 		"     lw        $3,  4(%0)  \n"
 		"     lw        $4,  8(%0)  \n"
@@ -101,22 +107,24 @@
 		"     lw        $7, 20(%0)  \n"
 		"     lw        $8, 24(%0)  \n"
 		"     lw        $9, 28(%0)  \n"
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
-		"     sw        $2,  0(%1)  \n"  
+#endif
+		"     sw        $2,  0(%1)  \n"
 		"     sw        $3,  4(%1)  \n"
 		"     sw        $4,  8(%1)  \n"
 		"     sw        $5, 12(%1)  \n"
 		"     sw        $6, 16(%1)  \n"
 		"     sw        $7, 20(%1)  \n"
 		"     sw        $8, 24(%1)  \n"
-		"     sw        $9, 28(%1)  \n"		
+		"     sw        $9, 28(%1)  \n"
 		"     addiu     %1, %1, 32  \n"  /* Next cacheline */
 		"     nop                   \n"  /* Force next add to short pipe */
 		"     nop                   \n"  /* Force next add to short pipe */
 		"     bne       $1, %0, 1b  \n"
 		"     addiu     %0, %0, 32  \n"  /* Next cacheline */
-		".set pop                   \n" 
+		".set pop                   \n"
 		:"=r" (to),
 		"=r" (from)
 		:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/r5k-sc.c linux-2.4.20/arch/mips/mm/r5k-sc.c
--- linux-2.4.19/arch/mips/mm/r5k-sc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/r5k-sc.c	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheops.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+#define cache_op(base,op)                   \
+__asm__ __volatile__("				\
+		.set noreorder;                 \
+		.set mips3;                     \
+		cache %1, (%0);                 \
+		.set mips0;                     \
+		.set reorder"                   \
+		:                               \
+		: "r" (base),                   \
+		  "i" (op));
+
+static inline void blast_r5000_scache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache_op(start, R5K_Page_Invalidate_S);
+		start += SC_PAGE;
+	}
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_r5000_scache();
+		return;
+	}
+
+	/* On the R5000 secondary cache we cannot
+	 * invalidate less than a page at a time.
+	 * The secondary cache is physically indexed, write-through.
+	 */
+	a = addr & ~(SC_PAGE - 1);
+	end = (addr + size - 1) & ~(SC_PAGE - 1);
+	while (a <= end) {
+		cache_op(a, R5K_Page_Invalidate_S);
+		a += SC_PAGE;
+	}
+}
+
+static void r5k_sc_enable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	change_cp0_config(CONF_SE, CONF_SE);
+	blast_r5000_scache();
+	__restore_flags(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_r5000_scache();
+	change_cp0_config(CONF_SE, 0);
+	__restore_flags(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if(config & CONF_SC)
+		return(0);
+
+	scache_size = (512*1024) << ((config >> 20)&3);
+
+	printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+			scache_size >> 10);
+
+	return 1;
+}
+
+struct bcache_ops r5k_sc_ops = {
+	r5k_sc_enable,
+	r5k_sc_disable,
+	r5k_dma_cache_inv_sc,
+	r5k_dma_cache_inv_sc
+};
+
+void __init r5k_sc_init(void)
+{
+	if (r5k_sc_probe()) {
+		r5k_sc_enable();
+		bcops = &r5k_sc_ops;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/tlb-r3k.c linux-2.4.20/arch/mips/mm/tlb-r3k.c
--- linux-2.4.19/arch/mips/mm/tlb-r3k.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/tlb-r3k.c	2002-10-04 00:41:11.000000000 +0000
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -200,12 +199,12 @@
 	unsigned long flags;
 	unsigned long old_ctx;
 	static unsigned long wired = 0;
-	
+
 #ifdef CONFIG_CPU_TX39XX
 	if (r3k_have_wired_reg) {
 		unsigned long old_pagemask;
 		unsigned long w;
-	
+
 #ifdef DEBUG_TLB
 		printk("[tlbwired]");
 		printk("ently lo0 %8x, hi %8x\n, pagemask %8x\n",
@@ -226,7 +225,7 @@
 		set_entryhi(entryhi);
 		set_entrylo0(entrylo0);
 		tlb_write_indexed();
-    
+
 		set_entryhi(old_ctx);
 		set_pagemask (old_pagemask);
 		local_flush_tlb_all();
@@ -244,7 +243,7 @@
 		wired++;
 		tlb_write_indexed();
 		set_entryhi(old_ctx);
-	        local_flush_tlb_all();    
+	        local_flush_tlb_all();
 		__restore_flags(flags);
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/tlb-r4k.c linux-2.4.20/arch/mips/mm/tlb-r4k.c
--- linux-2.4.19/arch/mips/mm/tlb-r4k.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/tlb-r4k.c	2002-10-04 00:41:09.000000000 +0000
@@ -119,12 +119,11 @@
 				idx = get_index();
 				set_entrylo0(0);
 				set_entrylo1(0);
-				set_entryhi(KSEG0);
 				if (idx < 0)
 					continue;
-				BARRIER;
 				/* Make sure all entries differ. */
-				set_entryhi(KSEG0+idx*0x2000);
+				set_entryhi(KSEG0 + idx*0x2000);
+				BARRIER;
 				tlb_write_indexed();
 				BARRIER;
 			}
@@ -271,19 +270,19 @@
 	wired = get_wired();
 	set_wired(wired + 1);
 	set_index(wired);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(pagemask);
 	set_entryhi(entryhi);
 	set_entrylo0(entrylo0);
 	set_entrylo1(entrylo1);
-	BARRIER;    
+	BARRIER;
 	tlb_write_indexed();
-	BARRIER;    
-    
+	BARRIER;
+
 	set_entryhi(old_ctx);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(old_pagemask);
-	local_flush_tlb_all();    
+	local_flush_tlb_all();
 	__restore_flags(flags);
 }
 
@@ -316,17 +315,17 @@
 	}
 
 	set_index(temp_tlb_entry);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(pagemask);
 	set_entryhi(entryhi);
 	set_entrylo0(entrylo0);
 	set_entrylo1(entrylo1);
-	BARRIER;    
+	BARRIER;
 	tlb_write_indexed();
-	BARRIER;    
-    
+	BARRIER;
+
 	set_entryhi(old_ctx);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(old_pagemask);
 out:
 	__restore_flags(flags);
@@ -339,11 +338,11 @@
 
 	prid = read_32bit_cp0_register(CP0_PRID) & 0xff00;
 	if (prid == PRID_IMP_RM7000 || !(config & (1 << 31)))
-		/* 
+		/*
 		 * Not a MIPS32 complianant CPU.  Config 1 register not
 		 * supported, we assume R4k style.  Cpu probing already figured
 		 * out the number of tlb entries.
-		 */  
+		 */
 		return;
 
 	config1 = read_mips32_cp0_config1();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/tlb-sb1.c linux-2.4.20/arch/mips/mm/tlb-sb1.c
--- linux-2.4.19/arch/mips/mm/tlb-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/tlb-sb1.c	2002-10-04 00:41:21.000000000 +0000
@@ -12,11 +12,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <asm/mmu_context.h>
 #include <asm/bootinfo.h>
@@ -38,13 +38,13 @@
 		"     tlbr             \n"
 		"     dmfc0  $1, $10   \n"
 		"     dsrl32 %0, $1, 0 \n"
-		"     sra    %1, $1, 0 \n"
+		"     sll    %1, $1, 0 \n"
 		"     dmfc0  $1, $2    \n"
 		"     dsrl32 %2, $1, 0 \n"
-		"     sra    %3, $1, 0 \n"
+		"     sll    %3, $1, 0 \n"
 		"     dmfc0  $1, $3    \n"
 		"     dsrl32 %4, $1, 0 \n"
-		"     sra    %5, $1, 0 \n"
+		"     sll    %5, $1, 0 \n"
 		"     mfc0   %6, $5    \n"
 		".set pop              \n"
 		: "=r" (entryhihi),
@@ -63,7 +63,11 @@
 
 void sb1_dump_tlb(void)
 {
+	unsigned long old_ctx;
+	unsigned long flags;
 	int entry;
+	__save_and_cli(flags);
+	old_ctx = get_entryhi();
 	printk("Current TLB registers state:\n"
 	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
 	       "--------------------------------------------------------------------\n");
@@ -83,6 +87,8 @@
 		dump_cur_tlb_regs();
 	}
 	printk("\n");
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
 }
 
 void local_flush_tlb_all(void)
@@ -102,12 +108,12 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);	
+	__restore_flags(flags);
 }
 
 
 /*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
  * Use increments of the maximum page size (16MB), and check for duplicate
  * entries before doing a given write.  Then, when we're safe from collisions
  * with the firmware, go back and give all the entries invalid addresses with
@@ -209,7 +215,7 @@
 		set_entrylo1(0);
 		if(idx < 0)
 			goto finish;
-		/* Make sure all entries differ. */  
+		/* Make sure all entries differ. */
 		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
 		tlb_write_indexed();
 	finish:
@@ -299,7 +305,7 @@
 	/*
 	 * We don't know what state the firmware left the TLB's in, so this is
 	 * the ultra-conservative way to flush the TLB's and avoid machine
-	 * check exceptions due to duplicate TLB entries 
+	 * check exceptions due to duplicate TLB entries
 	 */
 	sb1_sanitize_tlb();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/tlbex-r3k.S linux-2.4.20/arch/mips/mm/tlbex-r3k.S
--- linux-2.4.19/arch/mips/mm/tlbex-r3k.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/tlbex-r3k.S	2002-10-04 00:41:14.000000000 +0000
@@ -112,7 +112,7 @@
 	.set	push;       \
 	.set	reorder;    \
 	 lw	pte, (ptr); \
-	.set	pop; 
+	.set	pop;
 
 	/* Make PTE valid, store result in PTR. */
 #define PTE_MAKEVALID(pte, ptr) \
@@ -130,7 +130,7 @@
 	.set    reorder;    \
 	lw      pte, (ptr); \
 	.set    pop;
- 
+
 
 	/* Make PTE writable, update software status bits as well,
 	 * then store at PTR.
@@ -160,7 +160,7 @@
 	nop; \
 	jr	reg; \
 	 rfe
-			
+
 	.set	noreorder
 
 	.align	5
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/tlbex-r4k.S linux-2.4.20/arch/mips/mm/tlbex-r4k.S
--- linux-2.4.19/arch/mips/mm/tlbex-r4k.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/tlbex-r4k.S	2002-10-04 00:41:15.000000000 +0000
@@ -56,7 +56,7 @@
 #define GET_PTE_OFF(reg)	srl	reg, reg, 1
 #endif
 
-/*	
+/*
  * These handlers much be written in a relocatable manner
  * because based upon the cpu type an arbitrary one of the
  * following pieces of code will be copied to the KSEG0
@@ -74,9 +74,9 @@
 	sll	k1, 2				# log2(sizeof(pgd_t)
 	addu	k1, k0, k1
 	lw	k1, (k1)
-#else 
+#else
 	lw	k1, pgd_current			# get pgd pointer
-#endif	
+#endif
 	mfc0	k0, CP0_BADVADDR		# Get faulting address
 	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
 
@@ -295,29 +295,6 @@
 	END(except_vec0_r4k_MP250MHZhwbug)
 #endif
 
-#ifdef CONFIG_MIPS_AU1000
-	/* TLB refill, EXL == 0, Au1000 version */
-        /* we'll worry about smp later */
-	.set	noreorder
-	.set	noat
-	LEAF(except_vec0_au1000)
-	.set	mips3
-	mfc0	k0, CP0_BADVADDR		# Get faulting address
-	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
-	lw	k1, pgd_current			# get pgd pointer
-	sll	k0, k0, 2			# log2(sizeof(pgd_t)
-	addu	k1, k1, k0			# add in pgd offset
-	mfc0	k0, CP0_CONTEXT			# get context reg
-	lw	k1, (k1)
-#ifndef CONFIG_64BIT_PHYS_ADDR
-	srl	k0, k0, 1			# get pte offset
-#endif
-	and	k0, k0, PTEP_INDX_MSK
-	addu	k1, k1, k0			# add in offset
-	j	translate_pte
-	nop
-	END(except_vec0_au1000)
-#endif
 
 
 	__FINIT
@@ -337,7 +314,7 @@
 	srl     ptr, 23;             \
 	sll     ptr, 2;              \
 	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);          
+	lw      ptr, (ptr);
 #else
 #define GET_PGD(scratch, ptr)    \
 	lw	ptr, pgd_current;
@@ -461,7 +438,7 @@
 	 tlbwi
 1:
 	nop
-	.set	mips3	
+	.set	mips3
 	eret
 	.set	mips0
 #endif
@@ -527,184 +504,3 @@
 	DO_FAULT(1)
 	END(handle_mod)
 
-#ifdef CONFIG_MIPS_AU1000
-
-#ifdef CONFIG_MIPS_PB1500
-#define PSEUDO_ADDR_BASE 0x20000000
-#endif
-
-#ifdef CONFIG_MIPS_PB1000
-#define PSEUDO_ADDR_BASE 0xC0000000
-#endif
-
-/*
- * On entry k0 contains the pte with the pseudo address.
- * On exit, k0 contains the "real" address, which is a
- * 36 bit physicall address.
- * This function is called only after it has been 
- * determined that the pte is a pseudo physical address.
- *
- * Destroys k0, k1, and at. It's assumed that the calling
- * function will preserve those.
- */
-LEAF(get_real_pte)
-	.set	mips3
-	.set	at
-
-	li	k1, 0xe0000000          # check lcd 
-	bltu	k0, k1, check_pcmcia_socket_1
-	nop
-	# lcd pseudo access
-	li	k1, 0x0fffffff
-	and	k0, k0, k1              # get offset
-#ifdef CONFIG_MIPS_PB1500
-	lui	k1, 0x1b00
-	addu	k0, k0, k1
-#endif
-	srl	k0, k0, 6
-	lui	k1, 0xe000>>2
-	or	k0, k0, k1
-	j	ra
-	nop
-check_pcmcia_socket_1:
-	li	k1, 0xD0000000
-	bltu	k0, k1, pcmcia_socket_0
-	nop
-	# famous last words, should not happen ...
-1:	
-	b 1b       # fixme -- to something a little more useful
-	# pcmcia socket 1 pseudo access
-
-pcmcia_socket_0:
-	# check mem access
-	li	k1, 0xC8000000
-	bltu	k0, k1, check_attr
-	# handle pseudo memory access
-	li	k1, 0x00ffffff
-	and	k1, k0, k1              # get access offset
-	lui	k0, 0x8000
-	or	k0, k0, k1              
-	# now we have the correct even pte ... bits 31:0
-	srl	k0, k0, 6
-	lui	k1, 0xf000>>2
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-check_attr:
-	li	k1, 0xC4000000
-	bltu	k0, k1, io_access
-	# handle pseudo attribute access
-	li	k1, 0x00ffffff
-	and	k1, k0, k1              # get access offset
-	lui	k0, 0x4000
-	or	k0, k0, k1              
-	# now we have the correct even pte ... bits 31:0
-	srl	k0, k0, 6
-	lui	k1, 0xf000>>2
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-io_access:
-#ifdef CONFIG_MIPS_PB1500
-	li	k1, 0xC0000000
-	bltu	k0, k1, pci_access
-#endif
-	# handle pseudo io access
-	li	k1, 0x00ffffff
-	and	k0, k0, k1              # get access offset
-	# now we have the correct even pte ... bits 31:0
-	srl	k0, k0, 6
-	lui	k1, 0xf000>>2
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-#ifdef CONFIG_MIPS_PB1500
-pci_access:
-	li	k1, 0x80000000
-	bltu	k0, k1, pci_io_access
-	lui	k1, 0x4000>>2
-	# handle pseudo pci mem access
-	srl	k0, k0, 6
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-pci_io_access:
-	li	k1, 0x70000000
-	bltu	k0, k1, pci_cfg_access
-	lui	k1, 0x5000>>2
-	# handle pseudo pci io access
-	srl	k0, k0, 6
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-pci_cfg_access:
-	# handle pseudo pci ext cfg access
-	li	k1, 0x0fffffff
-	and	k0, k0, k1              # get access offset
-	srl	k0, k0, 6
-	lui	k1, 0x6000>>2
-	or	k0, k0, k1
-	j	ra                      # done
-	nop
-#endif
-	.set	noat
-END(get_real_pte)
-
-/*
- * On entry k1 contains pte pointer. Clobbers only k0 and k1.
- */
-	LEAF(translate_pte)
-	.set	mips3
-	lui	k0, %hi(__saved_at)
-	.set	noat
-	sw	$at, %lo(__saved_at)(k0)	# save at
-	.set	at
-	sw	k1, %lo(__saved_pte)(k0)	# save pte pointer
-	sw	ra, %lo(__saved_ra)(k0)		# save ra
-	lw	k0, 0(k1)			# get even pte
-
-	li	k1, PSEUDO_ADDR_BASE   		# check pseudo addr
-	bltu	k0, k1, 1f
-	nop
-	bal	get_real_pte
-	nop
-	b	2f
-	nop
-1:
-	srl	k0, k0, 6
-2:
-	mtc0	k0, CP0_ENTRYLO0		# load it
-
-	lui	k1, %hi(__saved_pte)
-	lw	k1, %lo(__saved_pte)(k1)	# recover pte pointer
-	lw	k0, 4(k1)			# get odd pte
-
-	li	k1, PSEUDO_ADDR_BASE   		# check pseudo addr
-	bltu	k0, k1, 1f
-	nop
-	bal	get_real_pte
-	nop
-	b	2f
-	nop
-
-1:
-	srl	k0, k0, 6			# convert to entrylo0
-2:
-	mtc0	k0, CP0_ENTRYLO1		# load it
-	nop
-	b	1f
-	tlbwr					# write random tlb entry
-1:
-	lui	k0, %hi(__saved_at)
-	.set	noat
-	lw	$at, %lo(__saved_at)(k0)	# restore at
-	.set	at
-	lw	ra, %lo(__saved_ra)(k0)		# restore ra
-	eret					# return from trap
-	.set	noat
-	END(translate_pte)
-
-__saved_at:	PTR	0
-__saved_pte:	PTR	0
-__saved_ra:	PTR	0
-#endif	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/mm/umap.c linux-2.4.20/arch/mips/mm/umap.c
--- linux-2.4.19/arch/mips/mm/umap.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/mm/umap.c	2002-10-04 00:41:15.000000000 +0000
@@ -53,7 +53,7 @@
 		address += PAGE_SIZE;
 		pte++;
 	} while (address < end);
-						  
+
 }
 
 static inline void
@@ -80,7 +80,7 @@
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
-		
+
 }
 
 /*
@@ -138,7 +138,7 @@
 
 /*
  * maps a range of vmalloc()ed memory into the requested pages. the old
- * mappings are removed. 
+ * mappings are removed.
  */
 static inline void
 vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr)
@@ -147,7 +147,7 @@
 	pgd_t *vdir;
 	pmd_t *vpmd;
 	pte_t *vpte;
-	
+
 	address &= ~PMD_MASK;
 	end = address + size;
 	if (end > PMD_SIZE)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/Makefile linux-2.4.20/arch/mips/momentum/ocelot_g/Makefile
--- linux-2.4.19/arch/mips/momentum/ocelot_g/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/Makefile	2002-10-04 00:41:17.000000000 +0000
@@ -0,0 +1,20 @@
+#
+# Makefile for Momentum Computer's Ocelot-G board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= ocelot_g.o
+
+obj-y	 += gt-irq.o pci-irq.o pci.o int-handler.o irq.o prom.o reset.o setup.o
+
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/dbg_io.c linux-2.4.20/arch/mips/momentum/ocelot_g/dbg_io.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/dbg_io.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_REMOTE_DEBUG)
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [jsun] we use the second serial port for kdb */
+#define         BASE                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* register offset */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* memory-mapped read/write of the port */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/gt-irq.c linux-2.4.20/arch/mips/momentum/ocelot_g/gt-irq.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/gt-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/gt-irq.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,294 @@
+/*
+ *
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ *
+ * arch/mips/momentum/ocelot_g/gt_irq.c
+ *     Interrupt routines for gt64240.  Currently it only handles timer irq.
+ *
+ * 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 <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include "gt64240.h"
+
+unsigned long bus_clock;
+
+/*
+ * These are interrupt handlers for the GT on-chip interrupts.  They
+ * all come in to the MIPS on a single interrupt line, and have to
+ * be handled and ack'ed differently than other MIPS interrupts.
+ */
+
+#if CURRENTLY_UNUSED
+
+struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
+
+/*
+ * Hooks IRQ handler to the system. When the system is interrupted
+ * the interrupt service routine is called.
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ * isr_ptr   - Pointer to the interrupt service routine
+ */
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+	irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/*
+ * Enables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int enable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			     (1 << bit_num));
+	else
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Disables the IRQ on Galileo Chip
+ *
+ * Inputs :
+ * int_cause - The interrupt cause number. In EVB64120 two parameters
+ *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ * bit_num   - Indicates which bit number in the cause register
+ *
+ * Outputs :
+ * 1 if succesful, 0 if failure
+ */
+int disable_galileo_irq(int int_cause, int bit_num)
+{
+	if (int_cause == INT_CAUSE_MAIN)
+		RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else if (int_cause == INT_CAUSE_HIGH)
+		RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+			       (1 << bit_num));
+	else
+		return 0;
+	return 1;
+}
+#endif				/*  UNUSED  */
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
+ *
+ * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
+ * routine can handle, for now.
+ *
+ * In the future, we'll route more interrupts to this pin, and that's why
+ * we keep this particular structure in the function.
+ */
+
+static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	uint32_t irq_src, irq_src_mask;
+	int handled;
+
+	/* get the low interrupt cause register */
+	GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src);
+
+	/* get the mask register for this pin */
+	GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask);
+
+	/* mask off only the interrupts we're interested in */
+	irq_src = irq_src & irq_src_mask;
+
+	handled = 0;
+
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000100) {
+		handled = 1;
+		irq_src &= ~0x00000100;
+
+		/* Clear any pending cause bits */
+		GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+		/* handle the timer call */
+		do_timer(regs);
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
+		       irq_src);
+	}
+}
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip.
+ * It could be built in ethernet ports etc...
+ */
+static void gt64240_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int irq_src, int_high_src, irq_src_mask,
+	    int_high_src_mask;
+	int handled;
+
+#if 0
+	GT_READ(GT_INTRCAUSE_OFS, &irq_src);
+	GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
+	GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
+	GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
+#endif
+	irq_src = irq_src & irq_src_mask;
+	int_high_src = int_high_src & int_high_src_mask;
+
+	handled = 0;
+
+	/* Execute all interrupt handlers */
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000800) {
+		handled = 1;
+		irq_src &= ~0x00000800;
+		//    RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
+		do_timer(regs);
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "Other Galileo interrupt received irq_src %x\n",
+		       irq_src);
+#if CURRENTLY_UNUSED
+		for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
+			if (irq_src & (1 << count)) {
+				if (irq_handlers[INT_CAUSE_MAIN][count].
+				    routine) {
+					queue_task(&irq_handlers
+						   [INT_CAUSE_MAIN][count],
+						   &tq_immediate);
+					mark_bh(IMMEDIATE_BH);
+					handled = 1;
+				}
+			}
+		}
+#endif				/*  UNUSED  */
+	}
+#if 0
+	GT_WRITE(GT_INTRCAUSE_OFS, 0);
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+#endif
+
+#undef GALILEO_I2O
+#ifdef GALILEO_I2O
+	/*
+	 * Future I2O support.  We currently attach I2O interrupt handlers to
+	 * the Galileo interrupt (int 4) and handle them in do_IRQ.
+	 */
+	if (isInBoundDoorBellInterruptSet()) {
+		printk(KERN_INFO "I2O doorbell interrupt received.\n");
+		handled = 1;
+	}
+
+	if (isInBoundPostQueueInterruptSet()) {
+		printk(KERN_INFO "I2O Queue interrupt received.\n");
+		handled = 1;
+	}
+
+	/*
+	 * This normally would be outside of the ifdef, but since we're
+	 * handling I2O outside of this handler, this printk shows up every
+	 * time we get a valid I2O interrupt.  So turn this off for now.
+	 */
+	if (handled == 0) {
+		if (counter < 50) {
+			printk("Spurious Galileo interrupt...\n");
+			counter++;
+		}
+	}
+#endif
+}
+
+/*
+ * Initializes timer using galileo's built in timer.
+ */
+
+/*
+ * This will ignore the standard MIPS timer interrupt handler
+ * that is passed in as *irq (=irq0 in ../kernel/time.c).
+ * We will do our own timer interrupt handling.
+ */
+void gt64240_time_init(void)
+{
+	extern irq_desc_t irq_desc[NR_IRQS];
+	static struct irqaction timer;
+
+	/* Stop the timer -- we'll use timer #0 */
+	GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);
+
+	/* Load timer value for 100 Hz */
+	GT_WRITE(TIMER_COUNTER0, bus_clock / 100);
+
+	/*
+	 * Create the IRQ structure entry for the timer.  Since we're too early
+	 * in the boot process to use the "request_irq()" call, we'll hard-code
+	 * the values to the correct interrupt line.
+	 */
+	timer.handler = &gt64240_p0int_irq;
+	timer.flags = SA_SHIRQ | SA_INTERRUPT;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = 0;
+	irq_desc[6].action = &timer;
+
+	enable_irq(6);
+
+	/* Clear any pending cause bits */
+	GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+	/* Enable the interrupt for timer 0 */
+	GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);
+
+	/* Enable the timer interrupt for GT-64240 pin P0_INT# */
+	GT_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);
+
+	/* Configure and start the timer */
+	GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
+}
+
+void gt64240_irq_init(void)
+{
+#if CURRENTLY_UNUSED
+	int i, j;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = 0; i < MAX_CAUSE_REGS; i++) {
+		for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
+			irq_handlers[i][j].next = NULL;
+			irq_handlers[i][j].sync = 0;
+			irq_handlers[i][j].routine = NULL;
+			irq_handlers[i][j].data = NULL;
+		}
+	}
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/gt64240.h linux-2.4.20/arch/mips/momentum/ocelot_g/gt64240.h
--- linux-2.4.19/arch/mips/momentum/ocelot_g/gt64240.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/gt64240.h	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,1238 @@
+/* gt64240r.h - GT-64240 Internal registers definition file */
+
+/* Copyright - Galileo technology. */
+
+#ifndef __INCgt64240rh
+#define __INCgt64240rh
+
+#define GTREG(v)        (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \
+                        (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00)
+
+#if 0
+#define GTREG_SHORT(X)	(((X) << 8) | ((X) >> 8))
+
+#define LONG_GTREG(X)	((l64) \
+			(((X)&0x00000000000000ffULL) << 56) | \
+			(((X)&0x000000000000ff00ULL) << 40) | \
+			(((X)&0x0000000000ff0000ULL) << 24) | \
+			(((X)&0x00000000ff000000ULL) << 8)  | \
+			(((X)&0x000000ff00000000ULL) >> 8)  | \
+			(((X)&0x0000ff0000000000ULL) >> 24) | \
+			(((X)&0x00ff000000000000ULL) >> 40) | \
+			(((X)&0xff00000000000000ULL) >> 56))
+#endif
+
+#include "gt64240_dep.h"
+
+/****************************************/
+/* CPU Control Registers		*/
+/****************************************/
+
+#define CPU_CONFIGURATION					0x000
+#define CPU_MODE						0x120
+#define CPU_READ_RESPONSE_CROSSBAR_LOW				0x170
+#define CPU_READ_RESPONSE_CROSSBAR_HIGH				0x178
+
+/****************************************/
+/* Processor Address Space		*/
+/****************************************/
+
+/* Sdram's BAR'S */
+#define SCS_0_LOW_DECODE_ADDRESS				0x008
+#define SCS_0_HIGH_DECODE_ADDRESS				0x010
+#define SCS_1_LOW_DECODE_ADDRESS				0x208
+#define SCS_1_HIGH_DECODE_ADDRESS				0x210
+#define SCS_2_LOW_DECODE_ADDRESS				0x018
+#define SCS_2_HIGH_DECODE_ADDRESS				0x020
+#define SCS_3_LOW_DECODE_ADDRESS				0x218
+#define SCS_3_HIGH_DECODE_ADDRESS				0x220
+/* Devices BAR'S */
+#define CS_0_LOW_DECODE_ADDRESS					0x028
+#define CS_0_HIGH_DECODE_ADDRESS				0x030
+#define CS_1_LOW_DECODE_ADDRESS					0x228
+#define CS_1_HIGH_DECODE_ADDRESS				0x230
+#define CS_2_LOW_DECODE_ADDRESS					0x248
+#define CS_2_HIGH_DECODE_ADDRESS				0x250
+#define CS_3_LOW_DECODE_ADDRESS					0x038
+#define CS_3_HIGH_DECODE_ADDRESS				0x040
+#define BOOTCS_LOW_DECODE_ADDRESS				0x238
+#define BOOTCS_HIGH_DECODE_ADDRESS				0x240
+
+#define PCI_0I_O_LOW_DECODE_ADDRESS				0x048
+#define PCI_0I_O_HIGH_DECODE_ADDRESS				0x050
+#define PCI_0MEMORY0_LOW_DECODE_ADDRESS				0x058
+#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS			0x060
+#define PCI_0MEMORY1_LOW_DECODE_ADDRESS				0x080
+#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS			0x088
+#define PCI_0MEMORY2_LOW_DECODE_ADDRESS				0x258
+#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS			0x260
+#define PCI_0MEMORY3_LOW_DECODE_ADDRESS				0x280
+#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS			0x288
+
+#define PCI_1I_O_LOW_DECODE_ADDRESS				0x090
+#define PCI_1I_O_HIGH_DECODE_ADDRESS				0x098
+#define PCI_1MEMORY0_LOW_DECODE_ADDRESS				0x0a0
+#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS			0x0a8
+#define PCI_1MEMORY1_LOW_DECODE_ADDRESS				0x0b0
+#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS			0x0b8
+#define PCI_1MEMORY2_LOW_DECODE_ADDRESS				0x2a0
+#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS			0x2a8
+#define PCI_1MEMORY3_LOW_DECODE_ADDRESS				0x2b0
+#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS			0x2b8
+
+#define INTERNAL_SPACE_DECODE					0x068
+
+#define CPU_0_LOW_DECODE_ADDRESS                            0x290
+#define CPU_0_HIGH_DECODE_ADDRESS                           0x298
+#define CPU_1_LOW_DECODE_ADDRESS                            0x2c0
+#define CPU_1_HIGH_DECODE_ADDRESS                           0x2c8
+
+#define PCI_0I_O_ADDRESS_REMAP					0x0f0
+#define PCI_0MEMORY0_ADDRESS_REMAP  				0x0f8
+#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP				0x320
+#define PCI_0MEMORY1_ADDRESS_REMAP  				0x100
+#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP				0x328
+#define PCI_0MEMORY2_ADDRESS_REMAP  				0x2f8
+#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP				0x330
+#define PCI_0MEMORY3_ADDRESS_REMAP  			  	0x300
+#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP			   	0x338
+
+#define PCI_1I_O_ADDRESS_REMAP					0x108
+#define PCI_1MEMORY0_ADDRESS_REMAP  				0x110
+#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP				0x340
+#define PCI_1MEMORY1_ADDRESS_REMAP  				0x118
+#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP				0x348
+#define PCI_1MEMORY2_ADDRESS_REMAP  				0x310
+#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP				0x350
+#define PCI_1MEMORY3_ADDRESS_REMAP  				0x318
+#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP				0x358
+
+/****************************************/
+/* CPU Sync Barrier             		*/
+/****************************************/
+
+#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER			0x0c0
+#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER			0x0c8
+
+
+/****************************************/
+/* CPU Access Protect             		*/
+/****************************************/
+
+#define CPU_LOW_PROTECT_ADDRESS_0                           0X180
+#define CPU_HIGH_PROTECT_ADDRESS_0                          0X188
+#define CPU_LOW_PROTECT_ADDRESS_1                           0X190
+#define CPU_HIGH_PROTECT_ADDRESS_1                          0X198
+#define CPU_LOW_PROTECT_ADDRESS_2                           0X1a0
+#define CPU_HIGH_PROTECT_ADDRESS_2                          0X1a8
+#define CPU_LOW_PROTECT_ADDRESS_3                           0X1b0
+#define CPU_HIGH_PROTECT_ADDRESS_3                          0X1b8
+#define CPU_LOW_PROTECT_ADDRESS_4                           0X1c0
+#define CPU_HIGH_PROTECT_ADDRESS_4                          0X1c8
+#define CPU_LOW_PROTECT_ADDRESS_5                           0X1d0
+#define CPU_HIGH_PROTECT_ADDRESS_5                          0X1d8
+#define CPU_LOW_PROTECT_ADDRESS_6                           0X1e0
+#define CPU_HIGH_PROTECT_ADDRESS_6                          0X1e8
+#define CPU_LOW_PROTECT_ADDRESS_7                           0X1f0
+#define CPU_HIGH_PROTECT_ADDRESS_7                          0X1f8
+
+
+/****************************************/
+/*          Snoop Control          		*/
+/****************************************/
+
+#define SNOOP_BASE_ADDRESS_0                                0x380
+#define SNOOP_TOP_ADDRESS_0                                 0x388
+#define SNOOP_BASE_ADDRESS_1                                0x390
+#define SNOOP_TOP_ADDRESS_1                                 0x398
+#define SNOOP_BASE_ADDRESS_2                                0x3a0
+#define SNOOP_TOP_ADDRESS_2                                 0x3a8
+#define SNOOP_BASE_ADDRESS_3                                0x3b0
+#define SNOOP_TOP_ADDRESS_3                                 0x3b8
+
+/****************************************/
+/*          CPU Error Report       		*/
+/****************************************/
+
+#define CPU_ERROR_ADDRESS_LOW 				    0x070
+#define CPU_ERROR_ADDRESS_HIGH 				    0x078
+#define CPU_ERROR_DATA_LOW                                  0x128
+#define CPU_ERROR_DATA_HIGH                                 0x130
+#define CPU_ERROR_PARITY                                    0x138
+#define CPU_ERROR_CAUSE                                     0x140
+#define CPU_ERROR_MASK                                      0x148
+
+/****************************************/
+/*          Pslave Debug           		*/
+/****************************************/
+
+#define X_0_ADDRESS                                         0x360
+#define X_0_COMMAND_ID                                      0x368
+#define X_1_ADDRESS                                         0x370
+#define X_1_COMMAND_ID                                      0x378
+#define WRITE_DATA_LOW                                      0x3c0
+#define WRITE_DATA_HIGH                                     0x3c8
+#define WRITE_BYTE_ENABLE                                   0X3e0
+#define READ_DATA_LOW                                       0x3d0
+#define READ_DATA_HIGH                                      0x3d8
+#define READ_ID                                             0x3e8
+
+
+/****************************************/
+/* SDRAM and Device Address Space	*/
+/****************************************/
+
+
+/****************************************/
+/* SDRAM Configuration			*/
+/****************************************/
+
+#define SDRAM_CONFIGURATION	 			0x448
+#define SDRAM_OPERATION_MODE				0x474
+#define SDRAM_ADDRESS_DECODE				0x47C
+#define SDRAM_TIMING_PARAMETERS                         0x4b4
+#define SDRAM_UMA_CONTROL                               0x4a4
+#define SDRAM_CROSS_BAR_CONTROL_LOW                     0x4a8
+#define SDRAM_CROSS_BAR_CONTROL_HIGH                    0x4ac
+#define SDRAM_CROSS_BAR_TIMEOUT                         0x4b0
+
+
+/****************************************/
+/* SDRAM Parameters			*/
+/****************************************/
+
+#define SDRAM_BANK0PARAMETERS				0x44C
+#define SDRAM_BANK1PARAMETERS				0x450
+#define SDRAM_BANK2PARAMETERS				0x454
+#define SDRAM_BANK3PARAMETERS				0x458
+
+
+/****************************************/
+/* SDRAM Error Report 			*/
+/****************************************/
+
+#define SDRAM_ERROR_DATA_LOW                            0x484
+#define SDRAM_ERROR_DATA_HIGH                           0x480
+#define SDRAM_AND_DEVICE_ERROR_ADDRESS                  0x490
+#define SDRAM_RECEIVED_ECC                              0x488
+#define SDRAM_CALCULATED_ECC                            0x48c
+#define SDRAM_ECC_CONTROL                               0x494
+#define SDRAM_ECC_ERROR_COUNTER                         0x498
+
+
+/****************************************/
+/* SDunit Debug (for internal use)	*/
+/****************************************/
+
+#define X0_ADDRESS                                      0x500
+#define X0_COMMAND_AND_ID                               0x504
+#define X0_WRITE_DATA_LOW                               0x508
+#define X0_WRITE_DATA_HIGH                              0x50c
+#define X0_WRITE_BYTE_ENABLE                            0x518
+#define X0_READ_DATA_LOW                                0x510
+#define X0_READ_DATA_HIGH                               0x514
+#define X0_READ_ID                                      0x51c
+#define X1_ADDRESS                                      0x520
+#define X1_COMMAND_AND_ID                               0x524
+#define X1_WRITE_DATA_LOW                               0x528
+#define X1_WRITE_DATA_HIGH                              0x52c
+#define X1_WRITE_BYTE_ENABLE                            0x538
+#define X1_READ_DATA_LOW                                0x530
+#define X1_READ_DATA_HIGH                               0x534
+#define X1_READ_ID                                      0x53c
+#define X0_SNOOP_ADDRESS                                0x540
+#define X0_SNOOP_COMMAND                                0x544
+#define X1_SNOOP_ADDRESS                                0x548
+#define X1_SNOOP_COMMAND                                0x54c
+
+
+/****************************************/
+/* Device Parameters			*/
+/****************************************/
+
+#define DEVICE_BANK0PARAMETERS				0x45c
+#define DEVICE_BANK1PARAMETERS				0x460
+#define DEVICE_BANK2PARAMETERS				0x464
+#define DEVICE_BANK3PARAMETERS				0x468
+#define DEVICE_BOOT_BANK_PARAMETERS			0x46c
+#define DEVICE_CONTROL                                  0x4c0
+#define DEVICE_CROSS_BAR_CONTROL_LOW                    0x4c8
+#define DEVICE_CROSS_BAR_CONTROL_HIGH                   0x4cc
+#define DEVICE_CROSS_BAR_TIMEOUT                        0x4c4
+
+
+/****************************************/
+/* Device Interrupt 			*/
+/****************************************/
+
+#define DEVICE_INTERRUPT_CAUSE                              0x4d0
+#define DEVICE_INTERRUPT_MASK                               0x4d4
+#define DEVICE_ERROR_ADDRESS                                0x4d8
+
+/****************************************/
+/* DMA Record				*/
+/****************************************/
+
+#define CHANNEL0_DMA_BYTE_COUNT					0x800
+#define CHANNEL1_DMA_BYTE_COUNT	 				0x804
+#define CHANNEL2_DMA_BYTE_COUNT	 				0x808
+#define CHANNEL3_DMA_BYTE_COUNT	 				0x80C
+#define CHANNEL4_DMA_BYTE_COUNT					0x900
+#define CHANNEL5_DMA_BYTE_COUNT	 				0x904
+#define CHANNEL6_DMA_BYTE_COUNT	 				0x908
+#define CHANNEL7_DMA_BYTE_COUNT	 				0x90C
+#define CHANNEL0_DMA_SOURCE_ADDRESS				0x810
+#define CHANNEL1_DMA_SOURCE_ADDRESS				0x814
+#define CHANNEL2_DMA_SOURCE_ADDRESS				0x818
+#define CHANNEL3_DMA_SOURCE_ADDRESS				0x81C
+#define CHANNEL4_DMA_SOURCE_ADDRESS				0x910
+#define CHANNEL5_DMA_SOURCE_ADDRESS				0x914
+#define CHANNEL6_DMA_SOURCE_ADDRESS				0x918
+#define CHANNEL7_DMA_SOURCE_ADDRESS				0x91C
+#define CHANNEL0_DMA_DESTINATION_ADDRESS			0x820
+#define CHANNEL1_DMA_DESTINATION_ADDRESS			0x824
+#define CHANNEL2_DMA_DESTINATION_ADDRESS			0x828
+#define CHANNEL3_DMA_DESTINATION_ADDRESS			0x82C
+#define CHANNEL4_DMA_DESTINATION_ADDRESS			0x920
+#define CHANNEL5_DMA_DESTINATION_ADDRESS			0x924
+#define CHANNEL6_DMA_DESTINATION_ADDRESS			0x928
+#define CHANNEL7_DMA_DESTINATION_ADDRESS			0x92C
+#define CHANNEL0NEXT_RECORD_POINTER				0x830
+#define CHANNEL1NEXT_RECORD_POINTER				0x834
+#define CHANNEL2NEXT_RECORD_POINTER				0x838
+#define CHANNEL3NEXT_RECORD_POINTER				0x83C
+#define CHANNEL4NEXT_RECORD_POINTER				0x930
+#define CHANNEL5NEXT_RECORD_POINTER				0x934
+#define CHANNEL6NEXT_RECORD_POINTER				0x938
+#define CHANNEL7NEXT_RECORD_POINTER				0x93C
+#define CHANNEL0CURRENT_DESCRIPTOR_POINTER			0x870
+#define CHANNEL1CURRENT_DESCRIPTOR_POINTER			0x874
+#define CHANNEL2CURRENT_DESCRIPTOR_POINTER			0x878
+#define CHANNEL3CURRENT_DESCRIPTOR_POINTER			0x87C
+#define CHANNEL4CURRENT_DESCRIPTOR_POINTER			0x970
+#define CHANNEL5CURRENT_DESCRIPTOR_POINTER			0x974
+#define CHANNEL6CURRENT_DESCRIPTOR_POINTER			0x978
+#define CHANNEL7CURRENT_DESCRIPTOR_POINTER			0x97C
+#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS			0x890
+#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS			0x894
+#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS			0x898
+#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS			0x89c
+#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS			0x990
+#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS			0x994
+#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS			0x998
+#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS			0x99c
+#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a0
+#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a4
+#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a8
+#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8ac
+#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a0
+#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a4
+#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a8
+#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9ac
+#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b0
+#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b4
+#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b8
+#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8bc
+#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b0
+#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b4
+#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b8
+#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9bc
+
+/****************************************/
+/* DMA Channel Control			*/
+/****************************************/
+
+#define CHANNEL0CONTROL 					0x840
+#define CHANNEL0CONTROL_HIGH					0x880
+
+#define CHANNEL1CONTROL 					0x844
+#define CHANNEL1CONTROL_HIGH					0x884
+
+#define CHANNEL2CONTROL 					0x848
+#define CHANNEL2CONTROL_HIGH					0x888
+
+#define CHANNEL3CONTROL 					0x84C
+#define CHANNEL3CONTROL_HIGH					0x88C
+
+#define CHANNEL4CONTROL 					0x940
+#define CHANNEL4CONTROL_HIGH					0x980
+
+#define CHANNEL5CONTROL 					0x944
+#define CHANNEL5CONTROL_HIGH					0x984
+
+#define CHANNEL6CONTROL 					0x948
+#define CHANNEL6CONTROL_HIGH					0x988
+
+#define CHANNEL7CONTROL 					0x94C
+#define CHANNEL7CONTROL_HIGH					0x98C
+
+
+/****************************************/
+/* DMA Arbiter				*/
+/****************************************/
+
+#define ARBITER_CONTROL_0_3					0x860
+#define ARBITER_CONTROL_4_7					0x960
+
+
+/****************************************/
+/* DMA Interrupt			*/
+/****************************************/
+
+#define CHANELS0_3_INTERRUPT_CAUSE				0x8c0
+#define CHANELS0_3_INTERRUPT_MASK				0x8c4
+#define CHANELS0_3_ERROR_ADDRESS				0x8c8
+#define CHANELS0_3_ERROR_SELECT					0x8cc
+#define CHANELS4_7_INTERRUPT_CAUSE				0x9c0
+#define CHANELS4_7_INTERRUPT_MASK				0x9c4
+#define CHANELS4_7_ERROR_ADDRESS				0x9c8
+#define CHANELS4_7_ERROR_SELECT					0x9cc
+
+
+/****************************************/
+/* DMA Debug (for internal use)         */
+/****************************************/
+
+#define DMA_X0_ADDRESS                                      0x8e0
+#define DMA_X0_COMMAND_AND_ID                               0x8e4
+#define DMA_X0_WRITE_DATA_LOW                               0x8e8
+#define DMA_X0_WRITE_DATA_HIGH                              0x8ec
+#define DMA_X0_WRITE_BYTE_ENABLE                            0x8f8
+#define DMA_X0_READ_DATA_LOW                                0x8f0
+#define DMA_X0_READ_DATA_HIGH                               0x8f4
+#define DMA_X0_READ_ID                                      0x8fc
+#define DMA_X1_ADDRESS                                      0x9e0
+#define DMA_X1_COMMAND_AND_ID                               0x9e4
+#define DMA_X1_WRITE_DATA_LOW                               0x9e8
+#define DMA_X1_WRITE_DATA_HIGH                              0x9ec
+#define DMA_X1_WRITE_BYTE_ENABLE                            0x9f8
+#define DMA_X1_READ_DATA_LOW                                0x9f0
+#define DMA_X1_READ_DATA_HIGH                               0x9f4
+#define DMA_X1_READ_ID                                      0x9fc
+
+/****************************************/
+/* Timer_Counter 						*/
+/****************************************/
+
+#define TIMER_COUNTER0						0x850
+#define TIMER_COUNTER1						0x854
+#define TIMER_COUNTER2						0x858
+#define TIMER_COUNTER3						0x85C
+#define TIMER_COUNTER_0_3_CONTROL				0x864
+#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE			0x868
+#define TIMER_COUNTER_0_3_INTERRUPT_MASK      			0x86c
+#define TIMER_COUNTER4						0x950
+#define TIMER_COUNTER5						0x954
+#define TIMER_COUNTER6						0x958
+#define TIMER_COUNTER7						0x95C
+#define TIMER_COUNTER_4_7_CONTROL				0x964
+#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE			0x968
+#define TIMER_COUNTER_4_7_INTERRUPT_MASK      			0x96c
+
+/****************************************/
+/* PCI Slave Address Decoding           */
+/****************************************/
+
+#define PCI_0SCS_0_BANK_SIZE					0xc08
+#define PCI_1SCS_0_BANK_SIZE					0xc88
+#define PCI_0SCS_1_BANK_SIZE					0xd08
+#define PCI_1SCS_1_BANK_SIZE					0xd88
+#define PCI_0SCS_2_BANK_SIZE					0xc0c
+#define PCI_1SCS_2_BANK_SIZE					0xc8c
+#define PCI_0SCS_3_BANK_SIZE					0xd0c
+#define PCI_1SCS_3_BANK_SIZE					0xd8c
+#define PCI_0CS_0_BANK_SIZE				    	0xc10
+#define PCI_1CS_0_BANK_SIZE				    	0xc90
+#define PCI_0CS_1_BANK_SIZE				    	0xd10
+#define PCI_1CS_1_BANK_SIZE				    	0xd90
+#define PCI_0CS_2_BANK_SIZE				    	0xd18
+#define PCI_1CS_2_BANK_SIZE				    	0xd98
+#define PCI_0CS_3_BANK_SIZE			       		0xc14
+#define PCI_1CS_3_BANK_SIZE			       		0xc94
+#define PCI_0CS_BOOT_BANK_SIZE					0xd14
+#define PCI_1CS_BOOT_BANK_SIZE					0xd94
+#define PCI_0P2P_MEM0_BAR_SIZE                              0xd1c
+#define PCI_1P2P_MEM0_BAR_SIZE                              0xd9c
+#define PCI_0P2P_MEM1_BAR_SIZE                              0xd20
+#define PCI_1P2P_MEM1_BAR_SIZE                              0xda0
+#define PCI_0P2P_I_O_BAR_SIZE                               0xd24
+#define PCI_1P2P_I_O_BAR_SIZE                               0xda4
+#define PCI_0CPU_BAR_SIZE                                   0xd28
+#define PCI_1CPU_BAR_SIZE                                   0xda8
+#define PCI_0DAC_SCS_0_BANK_SIZE                            0xe00
+#define PCI_1DAC_SCS_0_BANK_SIZE                            0xe80
+#define PCI_0DAC_SCS_1_BANK_SIZE                            0xe04
+#define PCI_1DAC_SCS_1_BANK_SIZE                            0xe84
+#define PCI_0DAC_SCS_2_BANK_SIZE                            0xe08
+#define PCI_1DAC_SCS_2_BANK_SIZE                            0xe88
+#define PCI_0DAC_SCS_3_BANK_SIZE                            0xe0c
+#define PCI_1DAC_SCS_3_BANK_SIZE                            0xe8c
+#define PCI_0DAC_CS_0_BANK_SIZE                             0xe10
+#define PCI_1DAC_CS_0_BANK_SIZE                             0xe90
+#define PCI_0DAC_CS_1_BANK_SIZE                             0xe14
+#define PCI_1DAC_CS_1_BANK_SIZE                             0xe94
+#define PCI_0DAC_CS_2_BANK_SIZE                             0xe18
+#define PCI_1DAC_CS_2_BANK_SIZE                             0xe98
+#define PCI_0DAC_CS_3_BANK_SIZE                             0xe1c
+#define PCI_1DAC_CS_3_BANK_SIZE                             0xe9c
+#define PCI_0DAC_BOOTCS_BANK_SIZE                           0xe20
+#define PCI_1DAC_BOOTCS_BANK_SIZE                           0xea0
+#define PCI_0DAC_P2P_MEM0_BAR_SIZE                          0xe24
+#define PCI_1DAC_P2P_MEM0_BAR_SIZE                          0xea4
+#define PCI_0DAC_P2P_MEM1_BAR_SIZE                          0xe28
+#define PCI_1DAC_P2P_MEM1_BAR_SIZE                          0xea8
+#define PCI_0DAC_CPU_BAR_SIZE                               0xe2c
+#define PCI_1DAC_CPU_BAR_SIZE                               0xeac
+#define PCI_0EXPANSION_ROM_BAR_SIZE                         0xd2c
+#define PCI_1EXPANSION_ROM_BAR_SIZE                         0xdac
+#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 			0xc3c
+#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 			0xcbc
+#define PCI_0SCS_0_BASE_ADDRESS_REMAP				0xc48
+#define PCI_1SCS_0_BASE_ADDRESS_REMAP				0xcc8
+#define PCI_0SCS_1_BASE_ADDRESS_REMAP				0xd48
+#define PCI_1SCS_1_BASE_ADDRESS_REMAP				0xdc8
+#define PCI_0SCS_2_BASE_ADDRESS_REMAP				0xc4c
+#define PCI_1SCS_2_BASE_ADDRESS_REMAP				0xccc
+#define PCI_0SCS_3_BASE_ADDRESS_REMAP				0xd4c
+#define PCI_1SCS_3_BASE_ADDRESS_REMAP				0xdcc
+#define PCI_0CS_0_BASE_ADDRESS_REMAP				0xc50
+#define PCI_1CS_0_BASE_ADDRESS_REMAP				0xcd0
+#define PCI_0CS_1_BASE_ADDRESS_REMAP				0xd50
+#define PCI_1CS_1_BASE_ADDRESS_REMAP				0xdd0
+#define PCI_0CS_2_BASE_ADDRESS_REMAP				0xd58
+#define PCI_1CS_2_BASE_ADDRESS_REMAP				0xdd8
+#define PCI_0CS_3_BASE_ADDRESS_REMAP           			0xc54
+#define PCI_1CS_3_BASE_ADDRESS_REMAP           			0xcd4
+#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP      			0xd54
+#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP      			0xdd4
+#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW                0xd5c
+#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW                0xddc
+#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH               0xd60
+#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH               0xde0
+#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW                0xd64
+#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW                0xde4
+#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH               0xd68
+#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH               0xde8
+#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP                     0xd6c
+#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP                     0xdec
+#define PCI_0CPU_BASE_ADDRESS_REMAP                         0xd70
+#define PCI_1CPU_BASE_ADDRESS_REMAP                         0xdf0
+#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP                   0xf00
+#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP                   0xff0
+#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP                   0xf04
+#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP                   0xf84
+#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP                   0xf08
+#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP                   0xf88
+#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP                   0xf0c
+#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP                   0xf8c
+#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP                    0xf10
+#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP                    0xf90
+#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP                    0xf14
+#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP                    0xf94
+#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP                    0xf18
+#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP                    0xf98
+#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP                    0xf1c
+#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP                    0xf9c
+#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP                  0xf20
+#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP                  0xfa0
+#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW            0xf24
+#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW            0xfa4
+#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH           0xf28
+#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH           0xfa8
+#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW            0xf2c
+#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW            0xfac
+#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH           0xf30
+#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH           0xfb0
+#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP                     0xf34
+#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP                     0xfb4
+#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP               0xf38
+#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP               0xfb8
+#define PCI_0ADDRESS_DECODE_CONTROL                         0xd3c
+#define PCI_1ADDRESS_DECODE_CONTROL                         0xdbc
+
+/****************************************/
+/* PCI Control                          */
+/****************************************/
+
+#define PCI_0COMMAND						0xc00
+#define PCI_1COMMAND						0xc80
+#define PCI_0MODE                                           0xd00
+#define PCI_1MODE                                           0xd80
+#define PCI_0TIMEOUT_RETRY					0xc04
+#define PCI_1TIMEOUT_RETRY					0xc84
+#define PCI_0READ_BUFFER_DISCARD_TIMER                      0xd04
+#define PCI_1READ_BUFFER_DISCARD_TIMER                      0xd84
+#define MSI_0TRIGGER_TIMER                                  0xc38
+#define MSI_1TRIGGER_TIMER                                  0xcb8
+#define PCI_0ARBITER_CONTROL                                0x1d00
+#define PCI_1ARBITER_CONTROL                                0x1d80
+/* changing untill here */
+#define PCI_0CROSS_BAR_CONTROL_LOW                           0x1d08
+#define PCI_0CROSS_BAR_CONTROL_HIGH                          0x1d0c
+#define PCI_0CROSS_BAR_TIMEOUT                               0x1d04
+#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW             0x1d18
+#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH            0x1d1c
+#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER                   0x1d10
+#define PCI_0P2P_CONFIGURATION                               0x1d14
+#define PCI_0ACCESS_CONTROL_BASE_0_LOW                       0x1e00
+#define PCI_0ACCESS_CONTROL_BASE_0_HIGH                      0x1e04
+#define PCI_0ACCESS_CONTROL_TOP_0                            0x1e08
+#define PCI_0ACCESS_CONTROL_BASE_1_LOW                       0c1e10
+#define PCI_0ACCESS_CONTROL_BASE_1_HIGH                      0x1e14
+#define PCI_0ACCESS_CONTROL_TOP_1                            0x1e18
+#define PCI_0ACCESS_CONTROL_BASE_2_LOW                       0c1e20
+#define PCI_0ACCESS_CONTROL_BASE_2_HIGH                      0x1e24
+#define PCI_0ACCESS_CONTROL_TOP_2                            0x1e28
+#define PCI_0ACCESS_CONTROL_BASE_3_LOW                       0c1e30
+#define PCI_0ACCESS_CONTROL_BASE_3_HIGH                      0x1e34
+#define PCI_0ACCESS_CONTROL_TOP_3                            0x1e38
+#define PCI_0ACCESS_CONTROL_BASE_4_LOW                       0c1e40
+#define PCI_0ACCESS_CONTROL_BASE_4_HIGH                      0x1e44
+#define PCI_0ACCESS_CONTROL_TOP_4                            0x1e48
+#define PCI_0ACCESS_CONTROL_BASE_5_LOW                       0c1e50
+#define PCI_0ACCESS_CONTROL_BASE_5_HIGH                      0x1e54
+#define PCI_0ACCESS_CONTROL_TOP_5                            0x1e58
+#define PCI_0ACCESS_CONTROL_BASE_6_LOW                       0c1e60
+#define PCI_0ACCESS_CONTROL_BASE_6_HIGH                      0x1e64
+#define PCI_0ACCESS_CONTROL_TOP_6                            0x1e68
+#define PCI_0ACCESS_CONTROL_BASE_7_LOW                       0c1e70
+#define PCI_0ACCESS_CONTROL_BASE_7_HIGH                      0x1e74
+#define PCI_0ACCESS_CONTROL_TOP_7                            0x1e78
+#define PCI_1CROSS_BAR_CONTROL_LOW                           0x1d88
+#define PCI_1CROSS_BAR_CONTROL_HIGH                          0x1d8c
+#define PCI_1CROSS_BAR_TIMEOUT                               0x1d84
+#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW             0x1d98
+#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH            0x1d9c
+#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER                   0x1d90
+#define PCI_1P2P_CONFIGURATION                               0x1d94
+#define PCI_1ACCESS_CONTROL_BASE_0_LOW                       0x1e80
+#define PCI_1ACCESS_CONTROL_BASE_0_HIGH                      0x1e84
+#define PCI_1ACCESS_CONTROL_TOP_0                            0x1e88
+#define PCI_1ACCESS_CONTROL_BASE_1_LOW                       0c1e90
+#define PCI_1ACCESS_CONTROL_BASE_1_HIGH                      0x1e94
+#define PCI_1ACCESS_CONTROL_TOP_1                            0x1e98
+#define PCI_1ACCESS_CONTROL_BASE_2_LOW                       0c1ea0
+#define PCI_1ACCESS_CONTROL_BASE_2_HIGH                      0x1ea4
+#define PCI_1ACCESS_CONTROL_TOP_2                            0x1ea8
+#define PCI_1ACCESS_CONTROL_BASE_3_LOW                       0c1eb0
+#define PCI_1ACCESS_CONTROL_BASE_3_HIGH                      0x1eb4
+#define PCI_1ACCESS_CONTROL_TOP_3                            0x1eb8
+#define PCI_1ACCESS_CONTROL_BASE_4_LOW                       0c1ec0
+#define PCI_1ACCESS_CONTROL_BASE_4_HIGH                      0x1ec4
+#define PCI_1ACCESS_CONTROL_TOP_4                            0x1ec8
+#define PCI_1ACCESS_CONTROL_BASE_5_LOW                       0c1ed0
+#define PCI_1ACCESS_CONTROL_BASE_5_HIGH                      0x1ed4
+#define PCI_1ACCESS_CONTROL_TOP_5                            0x1ed8
+#define PCI_1ACCESS_CONTROL_BASE_6_LOW                       0c1ee0
+#define PCI_1ACCESS_CONTROL_BASE_6_HIGH                      0x1ee4
+#define PCI_1ACCESS_CONTROL_TOP_6                            0x1ee8
+#define PCI_1ACCESS_CONTROL_BASE_7_LOW                       0c1ef0
+#define PCI_1ACCESS_CONTROL_BASE_7_HIGH                      0x1ef4
+#define PCI_1ACCESS_CONTROL_TOP_7                            0x1ef8
+
+/****************************************/
+/* PCI Snoop Control                    */
+/****************************************/
+
+#define PCI_0SNOOP_CONTROL_BASE_0_LOW                        0x1f00
+#define PCI_0SNOOP_CONTROL_BASE_0_HIGH                       0x1f04
+#define PCI_0SNOOP_CONTROL_TOP_0                             0x1f08
+#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW                      0x1f10
+#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH                     0x1f14
+#define PCI_0SNOOP_CONTROL_TOP_1                             0x1f18
+#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW                      0x1f20
+#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH                     0x1f24
+#define PCI_0SNOOP_CONTROL_TOP_2                             0x1f28
+#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW                      0x1f30
+#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH                     0x1f34
+#define PCI_0SNOOP_CONTROL_TOP_3                             0x1f38
+#define PCI_1SNOOP_CONTROL_BASE_0_LOW                        0x1f80
+#define PCI_1SNOOP_CONTROL_BASE_0_HIGH                       0x1f84
+#define PCI_1SNOOP_CONTROL_TOP_0                             0x1f88
+#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW                      0x1f90
+#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH                     0x1f94
+#define PCI_1SNOOP_CONTROL_TOP_1                             0x1f98
+#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW                      0x1fa0
+#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH                     0x1fa4
+#define PCI_1SNOOP_CONTROL_TOP_2                             0x1fa8
+#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW                      0x1fb0
+#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH                     0x1fb4
+#define PCI_1SNOOP_CONTROL_TOP_3                             0x1fb8
+
+/****************************************/
+/* PCI Configuration Address            */
+/****************************************/
+
+#define PCI_0CONFIGURATION_ADDRESS 				0xcf8
+#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER           	0xcfc
+#define PCI_1CONFIGURATION_ADDRESS 				0xc78
+#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER           	0xc7c
+#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER		0xc34
+#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER		0xcb4
+
+/****************************************/
+/* PCI Error Report                     */
+/****************************************/
+
+#define PCI_0SERR_MASK						 0xc28
+#define PCI_0ERROR_ADDRESS_LOW                               0x1d40
+#define PCI_0ERROR_ADDRESS_HIGH                              0x1d44
+#define PCI_0ERROR_DATA_LOW                                  0x1d48
+#define PCI_0ERROR_DATA_HIGH                                 0x1d4c
+#define PCI_0ERROR_COMMAND                                   0x1d50
+#define PCI_0ERROR_CAUSE                                     0x1d58
+#define PCI_0ERROR_MASK                                      0x1d5c
+
+#define PCI_1SERR_MASK						 0xca8
+#define PCI_1ERROR_ADDRESS_LOW                               0x1dc0
+#define PCI_1ERROR_ADDRESS_HIGH                              0x1dc4
+#define PCI_1ERROR_DATA_LOW                                  0x1dc8
+#define PCI_1ERROR_DATA_HIGH                                 0x1dcc
+#define PCI_1ERROR_COMMAND                                   0x1dd0
+#define PCI_1ERROR_CAUSE                                     0x1dd8
+#define PCI_1ERROR_MASK                                      0x1ddc
+
+
+/****************************************/
+/* Lslave Debug  (for internal use)     */
+/****************************************/
+
+#define L_SLAVE_X0_ADDRESS                                  0x1d20
+#define L_SLAVE_X0_COMMAND_AND_ID                           0x1d24
+#define L_SLAVE_X1_ADDRESS                                  0x1d28
+#define L_SLAVE_X1_COMMAND_AND_ID                           0x1d2c
+#define L_SLAVE_WRITE_DATA_LOW                              0x1d30
+#define L_SLAVE_WRITE_DATA_HIGH                             0x1d34
+#define L_SLAVE_WRITE_BYTE_ENABLE                           0x1d60
+#define L_SLAVE_READ_DATA_LOW                               0x1d38
+#define L_SLAVE_READ_DATA_HIGH                              0x1d3c
+#define L_SLAVE_READ_ID                                     0x1d64
+
+/****************************************/
+/* PCI Configuration Function 0         */
+/****************************************/
+
+#define PCI_DEVICE_AND_VENDOR_ID 				0x000
+#define PCI_STATUS_AND_COMMAND					0x004
+#define PCI_CLASS_CODE_AND_REVISION_ID			        0x008
+#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 		0x00C
+#define PCI_SCS_0_BASE_ADDRESS	    				0x010
+#define PCI_SCS_1_BASE_ADDRESS 					0x014
+#define PCI_SCS_2_BASE_ADDRESS 					0x018
+#define PCI_SCS_3_BASE_ADDRESS      				0x01C
+#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS	0x020
+#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS		0x024
+#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID		0x02C
+#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER			0x030
+#define PCI_CAPABILTY_LIST_POINTER                          0x034
+#define PCI_INTERRUPT_PIN_AND_LINE 			    0x03C
+#define PCI_POWER_MANAGEMENT_CAPABILITY                     0x040
+#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL             0x044
+#define PCI_VPD_ADDRESS                                     0x048
+#define PCI_VPD_DATA                                        0X04c
+#define PCI_MSI_MESSAGE_CONTROL                             0x050
+#define PCI_MSI_MESSAGE_ADDRESS                             0x054
+#define PCI_MSI_MESSAGE_UPPER_ADDRESS                       0x058
+#define PCI_MSI_MESSAGE_DATA                                0x05c
+#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY                 0x058
+
+/****************************************/
+/* PCI Configuration Function 1         */
+/****************************************/
+
+#define PCI_CS_0_BASE_ADDRESS	    				0x110
+#define PCI_CS_1_BASE_ADDRESS 					0x114
+#define PCI_CS_2_BASE_ADDRESS 					0x118
+#define PCI_CS_3_BASE_ADDRESS     				0x11c
+#define PCI_BOOTCS_BASE_ADDRESS                     	    0x120
+
+/****************************************/
+/* PCI Configuration Function 2         */
+/****************************************/
+
+#define PCI_P2P_MEM0_BASE_ADDRESS	    			0x210
+#define PCI_P2P_MEM1_BASE_ADDRESS 				0x214
+#define PCI_P2P_I_O_BASE_ADDRESS 				0x218
+#define PCI_CPU_BASE_ADDRESS      				0x21c
+
+/****************************************/
+/* PCI Configuration Function 4         */
+/****************************************/
+
+#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 				0x410
+#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH			 	0x414
+#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW   			0x418
+#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH  		    0x41c
+#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW              	    0x420
+#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH             	    0x424
+
+
+/****************************************/
+/* PCI Configuration Function 5         */
+/****************************************/
+
+#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 				0x510
+#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH				0x514
+#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW   		 	0x518
+#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH  		 	0x51c
+#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW              	    0x520
+#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH             	    0x524
+
+
+/****************************************/
+/* PCI Configuration Function 6         */
+/****************************************/
+
+#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 				0x610
+#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH				0x614
+#define PCI_DAC_CS_1_BASE_ADDRESS_LOW   			0x618
+#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH  			0x61c
+#define PCI_DAC_CS_2_BASE_ADDRESS_LOW            	        0x620
+#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH           	        0x624
+
+/****************************************/
+/* PCI Configuration Function 7         */
+/****************************************/
+
+#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 				0x710
+#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH			 	0x714
+#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW   		 	0x718
+#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH  			0x71c
+#define PCI_DAC_CPU_BASE_ADDRESS_LOW            	        0x720
+#define PCI_DAC_CPU_BASE_ADDRESS_HIGH           	        0x724
+
+/****************************************/
+/* Interrupts	  			*/
+/****************************************/
+
+#define LOW_INTERRUPT_CAUSE_REGISTER   				0xc18
+#define HIGH_INTERRUPT_CAUSE_REGISTER				0xc68
+#define CPU_INTERRUPT_MASK_REGISTER_LOW				0xc1c
+#define CPU_INTERRUPT_MASK_REGISTER_HIGH			0xc6c
+#define CPU_SELECT_CAUSE_REGISTER				0xc70
+#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW			0xc24
+#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH			0xc64
+#define PCI_0SELECT_CAUSE                                   0xc74
+#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW			0xca4
+#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH			0xce4
+#define PCI_1SELECT_CAUSE                                   0xcf4
+#define CPU_INT_0_MASK                                      0xe60
+#define CPU_INT_1_MASK                                      0xe64
+#define CPU_INT_2_MASK                                      0xe68
+#define CPU_INT_3_MASK                                      0xe6c
+
+/****************************************/
+/* I20 Support registers		*/
+/****************************************/
+
+#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE			0x010
+#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE  			0x014
+#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 			0x018
+#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE  			0x01C
+#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE  			0x020
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE  		0x024
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE		0x028
+#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 			0x02C
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE   		0x030
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE   		0x034
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE  		0x040
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE   	0x044
+#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 			0x050
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 			0x054
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE		0x060
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE  		0x064
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 		0x068
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 		0x06C
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE		0x070
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE		0x074
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE		0x0F8
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE		0x0FC
+
+#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE				0x090
+#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE  				0x094
+#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 				0x098
+#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE  				0x09C
+#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE  				0x0A0
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE  		0x0A4
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE			0x0A8
+#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 				0x0AC
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE   		0x0B0
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE   		0x0B4
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE  		0x0C0
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE   	0x0C4
+#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 				0x0D0
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 				0x0D4
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE		0x0E0
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE  		0x0E4
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 		0x0E8
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 		0x0EC
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE		0x0F0
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE		0x0F4
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE		0x078
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE		0x07C
+
+#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE				0X1C10
+#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE  				0X1C14
+#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 				0X1C18
+#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE  				0X1C1C
+#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE  				0X1C20
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE  		0X1C24
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE			0X1C28
+#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 				0X1C2C
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE   		0X1C30
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE   		0X1C34
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE  		0X1C40
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE   	0X1C44
+#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 				0X1C50
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 				0X1C54
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1C60
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE  		0X1C64
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 		0X1C68
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 		0X1C6C
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1C70
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE		0X1C74
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1CF8
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE		0X1CFC
+
+#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE				0X1C90
+#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE  				0X1C94
+#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 				0X1C98
+#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE  				0X1C9C
+#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE  				0X1CA0
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE  		0X1CA4
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE			0X1CA8
+#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 				0X1CAC
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE   		0X1CB0
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE   		0X1CB4
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE  		0X1CC0
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE   	0X1CC4
+#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 				0X1CD0
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 				0X1CD4
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1CE0
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE  		0X1CE4
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 		0X1CE8
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 		0X1CEC
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1CF0
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE		0X1CF4
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1C78
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE		0X1C7C
+
+/****************************************/
+/* Communication Unit Registers         */
+/****************************************/
+
+#define ETHERNET_0_ADDRESS_CONTROL_LOW
+#define ETHERNET_0_ADDRESS_CONTROL_HIGH                     0xf204
+#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf208
+#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf20c
+#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf210
+#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf214
+#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS              0xf218
+#define ETHERNET_1_ADDRESS_CONTROL_LOW                      0xf220
+#define ETHERNET_1_ADDRESS_CONTROL_HIGH                     0xf224
+#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf228
+#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf22c
+#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf230
+#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf234
+#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS              0xf238
+#define ETHERNET_2_ADDRESS_CONTROL_LOW                      0xf240
+#define ETHERNET_2_ADDRESS_CONTROL_HIGH                     0xf244
+#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf248
+#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf24c
+#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf250
+#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf254
+#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS              0xf258
+#define MPSC_0_ADDRESS_CONTROL_LOW                          0xf280
+#define MPSC_0_ADDRESS_CONTROL_HIGH                         0xf284
+#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf288
+#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf28c
+#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf290
+#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf294
+#define MPSC_1_ADDRESS_CONTROL_LOW                          0xf2a0
+#define MPSC_1_ADDRESS_CONTROL_HIGH                         0xf2a4
+#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf2a8
+#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf2ac
+#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf2b0
+#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf2b4
+#define MPSC_2_ADDRESS_CONTROL_LOW                          0xf2c0
+#define MPSC_2_ADDRESS_CONTROL_HIGH                         0xf2c4
+#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf2c8
+#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf2cc
+#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf2d0
+#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf2d4
+#define SERIAL_INIT_PCI_HIGH_ADDRESS                        0xf320
+#define SERIAL_INIT_LAST_DATA                               0xf324
+#define SERIAL_INIT_STATUS_AND_CONTROL                      0xf328
+#define COMM_UNIT_ARBITER_CONTROL                           0xf300
+#define COMM_UNIT_CROSS_BAR_TIMEOUT                         0xf304
+#define COMM_UNIT_INTERRUPT_CAUSE                           0xf310
+#define COMM_UNIT_INTERRUPT_MASK                            0xf314
+#define COMM_UNIT_ERROR_ADDRESS                             0xf314
+
+/****************************************/
+/* Cunit Debug  (for internal use)     */
+/****************************************/
+
+#define CUNIT_ADDRESS                                       0xf340
+#define CUNIT_COMMAND_AND_ID                                0xf344
+#define CUNIT_WRITE_DATA_LOW                                0xf348
+#define CUNIT_WRITE_DATA_HIGH                               0xf34c
+#define CUNIT_WRITE_BYTE_ENABLE                             0xf358
+#define CUNIT_READ_DATA_LOW                                 0xf350
+#define CUNIT_READ_DATA_HIGH                                0xf354
+#define CUNIT_READ_ID                                       0xf35c
+
+/****************************************/
+/* Fast Ethernet Unit Registers         */
+/****************************************/
+
+/* Ethernet */
+
+#define ETHERNET_PHY_ADDRESS_REGISTER                       0x2000
+#define ETHERNET_SMI_REGISTER                               0x2010
+
+/* Ethernet 0 */
+
+#define ETHERNET0_PORT_CONFIGURATION_REGISTER               0x2400
+#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER        0x2408
+#define ETHERNET0_PORT_COMMAND_REGISTER                     0x2410
+#define ETHERNET0_PORT_STATUS_REGISTER                      0x2418
+#define ETHERNET0_SERIAL_PARAMETRS_REGISTER                 0x2420
+#define ETHERNET0_HASH_TABLE_POINTER_REGISTER               0x2428
+#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2430
+#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2438
+#define ETHERNET0_SDMA_CONFIGURATION_REGISTER               0x2440
+#define ETHERNET0_SDMA_COMMAND_REGISTER                     0x2448
+#define ETHERNET0_INTERRUPT_CAUSE_REGISTER                  0x2450
+#define ETHERNET0_INTERRUPT_MASK_REGISTER                   0x2458
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0              0x2480
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1              0x2484
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2              0x2488
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3              0x248c
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0            0x24a0
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1            0x24a4
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2            0x24a8
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3            0x24ac
+#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0            0x24e0
+#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1            0x24e4
+#define ETHERNET0_MIB_COUNTER_BASE                          0x2500
+
+/* Ethernet 1 */
+
+#define ETHERNET1_PORT_CONFIGURATION_REGISTER               0x2800
+#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER        0x2808
+#define ETHERNET1_PORT_COMMAND_REGISTER                     0x2810
+#define ETHERNET1_PORT_STATUS_REGISTER                      0x2818
+#define ETHERNET1_SERIAL_PARAMETRS_REGISTER                 0x2820
+#define ETHERNET1_HASH_TABLE_POINTER_REGISTER               0x2828
+#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2830
+#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2838
+#define ETHERNET1_SDMA_CONFIGURATION_REGISTER               0x2840
+#define ETHERNET1_SDMA_COMMAND_REGISTER                     0x2848
+#define ETHERNET1_INTERRUPT_CAUSE_REGISTER                  0x2850
+#define ETHERNET1_INTERRUPT_MASK_REGISTER                   0x2858
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0              0x2880
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1              0x2884
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2              0x2888
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3              0x288c
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0            0x28a0
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1            0x28a4
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2            0x28a8
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3            0x28ac
+#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0            0x28e0
+#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1            0x28e4
+#define ETHERNET1_MIB_COUNTER_BASE                          0x2900
+
+/* Ethernet 2 */
+
+#define ETHERNET2_PORT_CONFIGURATION_REGISTER               0x2c00
+#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER        0x2c08
+#define ETHERNET2_PORT_COMMAND_REGISTER                     0x2c10
+#define ETHERNET2_PORT_STATUS_REGISTER                      0x2c18
+#define ETHERNET2_SERIAL_PARAMETRS_REGISTER                 0x2c20
+#define ETHERNET2_HASH_TABLE_POINTER_REGISTER               0x2c28
+#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2c30
+#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2c38
+#define ETHERNET2_SDMA_CONFIGURATION_REGISTER               0x2c40
+#define ETHERNET2_SDMA_COMMAND_REGISTER                     0x2c48
+#define ETHERNET2_INTERRUPT_CAUSE_REGISTER                  0x2c50
+#define ETHERNET2_INTERRUPT_MASK_REGISTER                   0x2c58
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0              0x2c80
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1              0x2c84
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2              0x2c88
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3              0x2c8c
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0            0x2ca0
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1            0x2ca4
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2            0x2ca8
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3            0x2cac
+#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0            0x2ce0
+#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1            0x2ce4
+#define ETHERNET2_MIB_COUNTER_BASE                          0x2d00
+
+/****************************************/
+/* SDMA Registers                       */
+/****************************************/
+
+#define SDMA_GROUP_CONFIGURATION_REGISTER                   0xb1f0
+#define CHANNEL0_CONFIGURATION_REGISTER                     0x4000
+#define CHANNEL0_COMMAND_REGISTER                           0x4008
+#define CHANNEL0_RX_CMD_STATUS                              0x4800
+#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES                 0x4804
+#define CHANNEL0_RX_BUFFER_POINTER                          0x4808
+#define CHANNEL0_RX_NEXT_POINTER                            0x480c
+#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER              0x4810
+#define CHANNEL0_TX_CMD_STATUS                              0x4C00
+#define CHANNEL0_TX_PACKET_SIZE                             0x4C04
+#define CHANNEL0_TX_BUFFER_POINTER                          0x4C08
+#define CHANNEL0_TX_NEXT_POINTER                            0x4C0c
+#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER              0x4c10
+#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER                0x4c14
+#define CHANNEL1_CONFIGURATION_REGISTER                     0x6000
+#define CHANNEL1_COMMAND_REGISTER                           0x6008
+#define CHANNEL1_RX_CMD_STATUS                              0x6800
+#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES                 0x6804
+#define CHANNEL1_RX_BUFFER_POINTER                          0x6808
+#define CHANNEL1_RX_NEXT_POINTER                            0x680c
+#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER              0x6810
+#define CHANNEL1_TX_CMD_STATUS                              0x6C00
+#define CHANNEL1_TX_PACKET_SIZE                             0x6C04
+#define CHANNEL1_TX_BUFFER_POINTER                          0x6C08
+#define CHANNEL1_TX_NEXT_POINTER                            0x6C0c
+#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER              0x6810
+#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER              0x6c10
+#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER                0x6c14
+
+/* SDMA Interrupt */
+
+#define SDMA_CAUSE                                          0xb820
+#define SDMA_MASK                                           0xb8a0
+
+
+/****************************************/
+/* Baude Rate Generators Registers      */
+/****************************************/
+
+/* BRG 0 */
+
+#define BRG0_CONFIGURATION_REGISTER                         0xb200
+#define BRG0_BAUDE_TUNING_REGISTER                          0xb204
+
+/* BRG 1 */
+
+#define BRG1_CONFIGURATION_REGISTER                         0xb208
+#define BRG1_BAUDE_TUNING_REGISTER                          0xb20c
+
+/* BRG 2 */
+
+#define BRG2_CONFIGURATION_REGISTER                         0xb210
+#define BRG2_BAUDE_TUNING_REGISTER                          0xb214
+
+/* BRG Interrupts */
+
+#define BRG_CAUSE_REGISTER                                  0xb834
+#define BRG_MASK_REGISTER                                   0xb8b4
+
+/* MISC */
+
+#define MAIN_ROUTING_REGISTER                               0xb400
+#define RECEIVE_CLOCK_ROUTING_REGISTER                      0xb404
+#define TRANSMIT_CLOCK_ROUTING_REGISTER                     0xb408
+#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER            0xb40c
+#define WATCHDOG_CONFIGURATION_REGISTER                     0xb410
+#define WATCHDOG_VALUE_REGISTER                             0xb414
+
+
+/****************************************/
+/* Flex TDM Registers                   */
+/****************************************/
+
+/* FTDM Port */
+
+#define FLEXTDM_TRANSMIT_READ_POINTER                       0xa800
+#define FLEXTDM_RECEIVE_READ_POINTER                        0xa804
+#define FLEXTDM_CONFIGURATION_REGISTER                      0xa808
+#define FLEXTDM_AUX_CHANNELA_TX_REGISTER                    0xa80c
+#define FLEXTDM_AUX_CHANNELA_RX_REGISTER                    0xa810
+#define FLEXTDM_AUX_CHANNELB_TX_REGISTER                    0xa814
+#define FLEXTDM_AUX_CHANNELB_RX_REGISTER                    0xa818
+
+/* FTDM Interrupts */
+
+#define FTDM_CAUSE_REGISTER                                 0xb830
+#define FTDM_MASK_REGISTER                                  0xb8b0
+
+
+/****************************************/
+/* GPP Interface Registers              */
+/****************************************/
+
+#define GPP_IO_CONTROL                                      0xf100
+#define GPP_LEVEL_CONTROL                                   0xf110
+#define GPP_VALUE                                           0xf104
+#define GPP_INTERRUPT_CAUSE                                 0xf108
+#define GPP_INTERRUPT_MASK                                  0xf10c
+
+#define MPP_CONTROL0                                        0xf000
+#define MPP_CONTROL1                                        0xf004
+#define MPP_CONTROL2                                        0xf008
+#define MPP_CONTROL3                                        0xf00c
+#define DEBUG_PORT_MULTIPLEX                                0xf014
+#define SERIAL_PORT_MULTIPLEX                               0xf010
+
+/****************************************/
+/* I2C Registers                        */
+/****************************************/
+
+#define I2C_SLAVE_ADDRESS                                   0xc000
+#define I2C_EXTENDED_SLAVE_ADDRESS                          0xc040
+#define I2C_DATA                                            0xc004
+#define I2C_CONTROL                                         0xc008
+#define I2C_STATUS_BAUDE_RATE                               0xc00C
+#define I2C_SOFT_RESET                                      0xc01c
+
+/****************************************/
+/* MPSC Registers                       */
+/****************************************/
+
+/* MPSC0  */
+
+#define MPSC0_MAIN_CONFIGURATION_LOW                        0x8000
+#define MPSC0_MAIN_CONFIGURATION_HIGH                       0x8004
+#define MPSC0_PROTOCOL_CONFIGURATION                        0x8008
+#define CHANNEL0_REGISTER1                                  0x800c
+#define CHANNEL0_REGISTER2                                  0x8010
+#define CHANNEL0_REGISTER3                                  0x8014
+#define CHANNEL0_REGISTER4                                  0x8018
+#define CHANNEL0_REGISTER5                                  0x801c
+#define CHANNEL0_REGISTER6                                  0x8020
+#define CHANNEL0_REGISTER7                                  0x8024
+#define CHANNEL0_REGISTER8                                  0x8028
+#define CHANNEL0_REGISTER9                                  0x802c
+#define CHANNEL0_REGISTER10                                 0x8030
+#define CHANNEL0_REGISTER11                                 0x8034
+
+/* MPSC1  */
+
+#define MPSC1_MAIN_CONFIGURATION_LOW                        0x9000
+#define MPSC1_MAIN_CONFIGURATION_HIGH                       0x9004
+#define MPSC1_PROTOCOL_CONFIGURATION                        0x9008
+#define CHANNEL1_REGISTER1                                  0x900c
+#define CHANNEL1_REGISTER2                                  0x9010
+#define CHANNEL1_REGISTER3                                  0x9014
+#define CHANNEL1_REGISTER4                                  0x9018
+#define CHANNEL1_REGISTER5                                  0x901c
+#define CHANNEL1_REGISTER6                                  0x9020
+#define CHANNEL1_REGISTER7                                  0x9024
+#define CHANNEL1_REGISTER8                                  0x9028
+#define CHANNEL1_REGISTER9                                  0x902c
+#define CHANNEL1_REGISTER10                                 0x9030
+#define CHANNEL1_REGISTER11                                 0x9034
+
+/* MPSCs Interupts  */
+
+#define MPSC0_CAUSE                                         0xb804
+#define MPSC0_MASK                                          0xb884
+#define MPSC1_CAUSE                                         0xb80c
+#define MPSC1_MASK                                          0xb88c
+
+#endif /* __INCgt64240rh */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/gt64240_dep.h linux-2.4.20/arch/mips/momentum/ocelot_g/gt64240_dep.h
--- linux-2.4.19/arch/mips/momentum/ocelot_g/gt64240_dep.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/gt64240_dep.h	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,57 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/gt64240/gt64240-dep.h
+ *     Board-dependent definitions for GT-64120 chip.
+ *
+ * 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.
+ ***********************************************************************
+ */
+
+#ifndef _ASM_GT64240_DEP_H
+#define _ASM_GT64240_DEP_H
+
+#include <asm/addrspace.h>		/* for KSEG1ADDR() */
+#include <asm/byteorder.h>		/* for cpu_to_le32() */
+
+/*
+ * PCI address allocation
+ */
+#if 0
+#define GT_PCI_MEM_BASE    (0x22000000)
+#define GT_PCI_MEM_SIZE    GT_DEF_PCI0_MEM0_SIZE
+#define GT_PCI_IO_BASE     (0x20000000)
+#define GT_PCI_IO_SIZE     GT_DEF_PCI0_IO_SIZE
+#endif
+
+extern unsigned long gt64240_base;
+
+#define GT64240_BASE       (gt64240_base)
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
+ * bytes when running bigendian.
+ */
+
+#define GT_WRITE(ofs, data)  \
+        *(volatile u32 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data)
+#define GT_READ(ofs, data)   \
+        *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs)))
+#define GT_READ_DATA(ofs)    \
+        le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs)))
+
+#define GT_WRITE_16(ofs, data)  \
+        *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data)
+#define GT_READ_16(ofs, data)   \
+        *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs)))
+
+#define GT_WRITE_8(ofs, data)  \
+        *(volatile u8 *)(GT64240_BASE+(ofs)) = data
+#define GT_READ_8(ofs, data)   \
+        *(data) = *(volatile u8 *)(GT64240_BASE+(ofs))
+
+#endif  /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/int-handler.S linux-2.4.20/arch/mips/momentum/ocelot_g/int-handler.S
--- linux-2.4.19/arch/mips/momentum/ocelot_g/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/int-handler.S	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ocelot board.
+ *
+ * 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.
+ */
+#define __ASSEMBLY__
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * first level interrupt dispatcher for ocelot board -
+ * We check for the timer first, then check PCI ints A and D.
+ * Then check for serial IRQ and fall through.
+ */
+		.align	5
+		NESTED(ocelot_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		 andi	t1, t0, STATUSF_IP2	/* int0 hardware line */
+		bnez	t1, ll_pri_enet_irq
+		 andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_sec_enet_irq
+		 andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_uart_irq
+		 andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_irq
+		 andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_galileo_p0_irq
+		 andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at the extended interrupts */
+		mfc0	t0, CP0_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		 sll	t2, t1, 8
+
+		 and	t0, t2
+		 srl	t0, t0, 16
+
+		 andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_galileo_p1_irq
+		 andi	t1, t0, STATUSF_IP9	/* int7 hardware line */
+		bnez	t1, ll_pmc_irq
+		 andi	t1, t0, STATUSF_IP10	/* int8 hardware line */
+		bnez	t1, ll_cpci_abcd_irq
+		 andi	t1, t0, STATUSF_IP11	/* int9 hardware line */
+		bnez	t1, ll_testpoint_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_pri_enet_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sec_enet_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p0_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p1_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc_irq:
+		li	a0, 9
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_abcd_irq:
+		li	a0, 10
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_testpoint_irq:
+		li	a0, 11
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/irq.c linux-2.4.20/arch/mips/momentum/ocelot_g/irq.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/irq.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+
+static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
+{
+	unsigned long status;
+	unsigned clr_mask;
+	unsigned set_mask;
+
+	/* do the low 8 bits first */
+	clr_mask = 0xff & clr_mask_in;
+	set_mask = 0xff & set_mask_in;
+	status = read_32bit_cp0_register(CP0_STATUS);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_register(CP0_STATUS, status);
+
+	/* do the high 8 bits */
+	clr_mask = 0xff & (clr_mask_in >> 8);
+	set_mask = 0xff & (set_mask_in >> 8);
+	status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
+}
+
+static inline void mask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(irq, 0);
+}
+
+static inline void unmask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(0, irq);
+}
+
+static void enable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	unmask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+static unsigned int startup_cp7000_irq(unsigned int irq)
+{
+	enable_cp7000_irq(irq);
+
+	return 0;				/* never anything pending */
+}
+
+static void disable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	mask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+#define shutdown_cp7000_irq disable_cp7000_irq
+
+static void mask_and_ack_cp7000_irq(unsigned int irq)
+{
+	mask_irq(1 << irq);
+}
+
+static void end_cp7000_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_irq(1 << irq);
+}
+
+static struct hw_interrupt_type cp7000_hpcdma_irq_type = {
+	"CP7000",
+	startup_cp7000_irq,
+	shutdown_cp7000_irq,
+	enable_cp7000_irq,
+	disable_cp7000_irq,
+	mask_and_ack_cp7000_irq,
+	end_cp7000_irq,
+	NULL
+};
+
+
+extern asmlinkage void ocelot_handle_int(void);
+extern void gt64240_irq_init(void);
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_cp0_status(ST0_IM | ST0_BEV);
+	__cli();
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+	init_generic_irq();
+
+	for (i = 0; i <= 15; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &cp7000_hpcdma_irq_type;
+	}
+
+	gt64240_irq_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("start kgdb ...\n");
+	set_debug_traps();
+	breakpoint();	/* you may move this line to whereever you want :-) */
+#endif
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/ocelot_pld.h linux-2.4.20/arch/mips/momentum/ocelot_g/ocelot_pld.h
--- linux-2.4.19/arch/mips/momentum/ocelot_g/ocelot_pld.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/ocelot_pld.h	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,34 @@
+/*
+ * Ocelot Board Register Definitions
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ */
+#ifndef __MOMENCO_OCELOT_PLD_H__
+#define __MOMENCO_OCELOT_PLD_H__
+
+#if 0
+#define OCELOT_CS0_ADDR (0xe0020000)
+#else
+#define OCELOT_CS0_ADDR (0xfc000000)
+#endif
+
+#define OCELOT_REG_BOARDREV (0)
+#define OCELOT_REG_PLD1_ID (1)
+#define OCELOT_REG_PLD2_ID (2)
+#define OCELOT_REG_RESET_STATUS (3)
+#define OCELOT_REG_BOARD_STATUS (4)
+#define OCELOT_REG_CPCI_ID (5)
+#define OCELOT_REG_I2C_CTRL (8)
+#define OCELOT_REG_EEPROM_MODE (9)
+#define OCELOT_REG_INTMASK (10)
+#define OCELOT_REG_INTSTATUS (11)
+#define OCELOT_REG_INTSET (12)
+#define OCELOT_REG_INTCLR (13)
+
+#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
+#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
+
+
+#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/pci-irq.c linux-2.4.20/arch/mips/momentum/ocelot_g/pci-irq.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/pci-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/pci-irq.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on work for the Linux port to the Ocelot board, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/momentum/ocelot_g/pci.c
+ *     Board-specific PCI routines for gt64240 controller.
+ *
+ * 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 <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+
+void __init gt64240_board_pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+	u16 cmd;
+
+	/* loop over all known devices on this bus */
+	list_for_each(devices_link, &(current_bus->devices)) {
+
+		devices = pci_dev_b(devices_link);
+		if (devices == NULL)
+			continue;
+
+		if ((current_bus->number == 0) &&
+				PCI_SLOT(devices->devfn) == 1) {
+			/* Intel 82543 Gigabit MAC */
+			devices->irq = 2;       /* irq_nr is 2 for INT0 */
+		} else if ((current_bus->number == 0) &&
+				PCI_SLOT(devices->devfn) == 2) {
+			/* Intel 82543 Gigabit MAC */
+			devices->irq = 3;       /* irq_nr is 3 for INT1 */
+		} else if ((current_bus->number == 1) &&
+				PCI_SLOT(devices->devfn) == 3) {
+			/* Intel 21555 bridge */
+			devices->irq = 5;       /* irq_nr is 8 for INT6 */
+		} else if ((current_bus->number == 1) &&
+				PCI_SLOT(devices->devfn) == 4) {
+			/* PMC Slot */
+			devices->irq = 9;       /* irq_nr is 9 for INT7 */
+		} else {
+			/* We don't have assign interrupts for other devices. */
+			devices->irq = 0xff;
+		}
+
+		/* Assign an interrupt number for the device */
+		bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq);
+
+		/* enable master for everything but the GT-64240 */
+		if (((current_bus->number != 0) && (current_bus->number != 1))
+				|| (PCI_SLOT(devices->devfn) != 0)) {
+			bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+			cmd |= PCI_COMMAND_MASTER;
+			bus->ops->write_word(devices, PCI_COMMAND, cmd);
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/pci.c linux-2.4.20/arch/mips/momentum/ocelot_g/pci.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/pci.c	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,568 @@
+/*
+ * Copyright 2002 Momentum Computer
+ * Author: Matthew Dharm <mdharm@momenco.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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include "gt64240.h"
+
+#include <linux/init.h>
+
+#ifdef CONFIG_PCI
+
+#define SELF 0
+#define MASTER_ABORT_BIT 0x100
+
+/*
+ * These functions and structures provide the BIOS scan and mapping of the PCI
+ * devices.
+ */
+
+#define MAX_PCI_DEVS 10
+
+void gt64240_board_pcibios_fixup_bus(struct pci_bus* c);
+
+/*  Functions to implement "pci ops"  */
+static int galileo_pcibios_read_config_word(struct pci_dev *dev,
+					    int offset, u16 * val);
+static int galileo_pcibios_read_config_byte(struct pci_dev *dev,
+					    int offset, u8 * val);
+static int galileo_pcibios_read_config_dword(struct pci_dev *dev,
+					     int offset, u32 * val);
+static int galileo_pcibios_write_config_byte(struct pci_dev *dev,
+					     int offset, u8 val);
+static int galileo_pcibios_write_config_word(struct pci_dev *dev,
+					     int offset, u16 val);
+static int galileo_pcibios_write_config_dword(struct pci_dev *dev,
+					      int offset, u32 val);
+static void galileo_pcibios_set_master(struct pci_dev *dev);
+
+/*
+ *  General-purpose PCI functions.
+ */
+
+
+/*
+ * pci_range_ck -
+ *
+ * Check if the pci device that are trying to access does really exists
+ * on the evaluation board.
+ *
+ * Inputs :
+ * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
+ * dev - number of device on the specific pci bus
+ *
+ * Outpus :
+ * 0 - if OK , 1 - if failure
+ */
+static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+	/* Accessing device 31 crashes the GT-64240. */
+	if (dev < 5)
+		return 0;
+	return -1;
+}
+
+/*
+ * galileo_pcibios_(read/write)_config_(dword/word/byte) -
+ *
+ * reads/write a dword/word/byte register from the configuration space
+ * of a device.
+ *
+ * Note that bus 0 and bus 1 are local, and we assume all other busses are
+ * bridged from bus 1.  This is a safe assumption, since any other
+ * configuration will require major modifications to the CP7000G
+ *
+ * Inputs :
+ * bus - bus number
+ * dev - device number
+ * offset - register offset in the configuration space
+ * val - value to be written / read
+ *
+ * Outputs :
+ * PCIBIOS_SUCCESSFUL when operation was succesfull
+ * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
+ * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
+ */
+
+static int galileo_pcibios_read_config_dword(struct pci_dev *device,
+					      int offset, u32* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT);
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT);
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* read the data */
+	GT_READ(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_read_config_word(struct pci_dev *device,
+					     int offset, u16* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT);
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT);
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* read the data */
+	GT_READ_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_byte(struct pci_dev *device,
+					     int offset, u8* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_READ_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_dword(struct pci_dev *device,
+					      int offset, u32 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_write_config_word(struct pci_dev *device,
+					     int offset, u16 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_byte(struct pci_dev *device,
+					     int offset, u8 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void galileo_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+/*  Externally-expected functions.  Do not change function names  */
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because of "
+			       "resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+
+	/*
+	 * Let's fix up the latency timer and cache line size here.  Cache
+	 * line size = 32 bytes / sizeof dword (4) = 8.
+	 * Latency timer must be > 8.  32 is random but appears to work.
+	 */
+	galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+	if (tmp1 != 8) {
+		printk(KERN_WARNING "PCI setting cache line size to 8 from "
+		       "%d\n", tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+						  8);
+	}
+	galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+	if (tmp1 < 32) {
+		printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+		       tmp1);
+		galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER,
+						  32);
+	}
+
+	return 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	return pcibios_enable_resources(dev);
+}
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	return;
+
+#if 0
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/*
+		 * Somebody might have asked allocation of a non-standard
+		 * resource
+		 */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) &
+	    ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+	     PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+#endif
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		/* We need to avoid collisions with `mirrored' VGA ports
+		   and other strange ISA hardware, so we always want the
+		   addresses kilobyte aligned.  */
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+			       " (%ld bytes)\n", dev->slot_name,
+			        dev->resource - res, size);
+		}
+
+		start = (start + 1024 - 1) & ~(1024 - 1);
+		res->start = start;
+	}
+}
+
+struct pci_ops galileo_pci_ops = {
+	galileo_pcibios_read_config_byte,
+	galileo_pcibios_read_config_word,
+	galileo_pcibios_read_config_dword,
+	galileo_pcibios_write_config_byte,
+	galileo_pcibios_write_config_word,
+	galileo_pcibios_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	gt64240_board_pcibios_fixup_bus(c);
+}
+
+
+/********************************************************************
+* pci0P2PConfig - This function set the PCI_0 P2P configurate.
+*                 For more information on the P2P read PCI spec.
+*
+* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
+*                                      Boundry.
+*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
+*                                      Boundry.
+*          unsigned int busNum - The CPI bus number to which the PCI interface
+*                                      is connected.
+*          unsigned int devNum - The PCI interface's device number.
+*
+* Returns:  true.
+*/
+void pci0P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
+                   unsigned int busNum,unsigned int devNum)
+{
+	uint32_t regData;
+
+	regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
+			((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
+	GT_WRITE(PCI_0P2P_CONFIGURATION, regData);
+}
+
+/********************************************************************
+* pci1P2PConfig - This function set the PCI_1 P2P configurate.
+*                 For more information on the P2P read PCI spec.
+*
+* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
+*               Boundry.
+*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
+*               Boundry.
+*          unsigned int busNum - The CPI bus number to which the PCI interface
+*               is connected.
+*          unsigned int devNum - The PCI interface's device number.
+*
+* Returns:  true.
+*/
+void pci1P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
+                   unsigned int busNum,unsigned int devNum)
+{
+	uint32_t regData;
+
+	regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
+			((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
+	GT_WRITE(PCI_1P2P_CONFIGURATION, regData);
+}
+
+#define PCI0_STATUS_COMMAND_REG                 0x4
+#define PCI1_STATUS_COMMAND_REG                 0x84
+
+void __init pcibios_init(void)
+{
+	/* Reset PCI I/O and PCI MEM values */
+	ioport_resource.start = 0xe0000000;
+	ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+	iomem_resource.start  = 0xc0000000;
+	iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	pci_scan_bus(0, &galileo_pci_ops, NULL);
+	pci_scan_bus(1, &galileo_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+        printk(KERN_INFO "rr: pcibios_setup\n");
+        /* Nothing to do for now.  */
+
+        return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+#endif	/* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/prom.c linux-2.4.20/arch/mips/momentum/ocelot_g/prom.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/prom.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * 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 <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include "gt64240.h"
+#include "ocelot_pld.h"
+
+struct callvectors {
+	int	(*open) (char*, int, int);
+	int	(*close) (int);
+	int	(*read) (int, void*, int);
+	int	(*write) (int, void*, int);
+	off_t	(*lseek) (int, off_t, int);
+	int	(*printf) (const char*, ...);
+	void	(*cacheflush) (void);
+	char*	(*gets) (char*);
+};
+
+struct callvectors* debug_vectors;
+char arcs_cmdline[CL_SIZE];
+
+extern unsigned long gt64240_base;
+extern unsigned long bus_clock;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+const char *get_system_type(void)
+{
+	return "Momentum Ocelot";
+}
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv)
+{
+	int i;
+	uint32_t tmp;
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT_G;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
+#endif
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			gt64240_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("busclock", *env, strlen("busclock")) == 0) {
+			bus_clock = simple_strtol(*env + strlen("busclock="),
+							NULL, 10);
+		}
+		*env++;
+	}
+
+	debug_vectors->printf("Booting Linux kernel...\n");
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/reset.c linux-2.4.20/arch/mips/momentum/ocelot_g/reset.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/reset.c	2002-10-04 00:41:12.000000000 +0000
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	void *nvram = ioremap_nocache(0x2c807000, 0x1000);
+
+	if (!nvram) {
+		printk(KERN_NOTICE "ioremap of reset register failed\n");
+		return;
+	}
+	writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
+					assert reset in 1/16 second */
+	mdelay(10+(1000/16));
+	iounmap(nvram);
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void momenco_ocelot_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/momentum/ocelot_g/setup.c linux-2.4.20/arch/mips/momentum/ocelot_g/setup.c
--- linux-2.4.19/arch/mips/momentum/ocelot_g/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/momentum/ocelot_g/setup.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,258 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines
+ *
+ * Copyright (C) 1996, 1997, 2001  Ralf Baechle
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2002 Momentum Computer
+ *
+ * Author: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/mc146818rtc.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include "gt64240.h"
+#include "ocelot_pld.h"
+
+extern struct rtc_ops no_rtc_ops;
+
+unsigned long gt64240_base;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+extern void gt64240_time_init(void);
+extern void momenco_ocelot_irq_setup(void);
+
+static char reset_reason;
+
+#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1)
+
+static void __init setup_l3cache(unsigned long size);
+
+void __init bus_error_init(void) { /* nothing */ }
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup(void)
+{
+	/* A wired TLB entry for the GT64240 and the serial port. The
+	   GT64240 is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64240 Internal Regs	0xf4000000	0xe0000000
+		UARTs (CS2)		0xfd000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
+	add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K);
+
+	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
+	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
+
+		Ocelot PLD (CS0)	0xfc000000	0xe0020000
+		NVRAM (CS1)		0xfc800000	0xe0030000
+	*/
+	add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K);
+	add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K);
+
+	gt64240_base = 0xf4000000;
+}
+
+void __init momenco_ocelot_g_setup(void)
+{
+	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
+	unsigned int tmpword;
+
+	board_time_init = gt64240_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+	rtc_ops = &no_rtc_ops;
+
+	/* do handoff reconfiguration */
+	PMON_v2_setup();
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_PLD_WRITE(0x80, INTCLR);
+
+	tmpword = OCELOT_PLD_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
+	else
+		printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);
+
+	tmpword = OCELOT_PLD_READ(PLD1_ID);
+	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(PLD2_ID);
+	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	reset_reason = tmpword;
+	OCELOT_PLD_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	if (tmpword&12)
+		l3func((1<<(((tmpword&12) >> 2)+20)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB -- two banks of 256MiB */
+		add_memory_region(  0x0<<20, 0x100<<20, BOOT_MEM_RAM);
+/*
+		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
+*/
+		break;
+	case 2:
+		/* 256MiB -- two banks of 128MiB */
+		add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
+		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
+		break;
+	case 1:
+		/* 128MiB -- 64MiB per bank */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	case 0:
+		/* 64MiB */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	}
+
+	/* FIXME: Fix up the DiskOnChip mapping */
+	GT_WRITE(0x468, 0xfef73);
+}
+
+extern int rm7k_tcache_enabled;
+/*
+ * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+ */
+#define Page_Invalidate_T 0x16
+static void __init setup_l3cache(unsigned long size)
+{
+	int register i;
+	unsigned long tmp;
+
+	printk("Enabling L3 cache...");
+
+	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+	GT_READ(0, &tmp);
+	GT_WRITE(0, tmp | (1<<14));
+
+	/* Enable the L3 cache in the CPU */
+	set_cp0_config(1<<12 /* CONF_TE */);
+
+	/* Clear the cache */
+	set_taglo(0);
+	set_taghi(0);
+
+	for (i=0; i < size; i+= 4096) {
+		__asm__ __volatile__ (
+			".set noreorder\n\t"
+			".set mips3\n\t"
+			"cache %1, (%0)\n\t"
+			".set mips0\n\t"
+			".set reorder"
+			:
+			: "r" (KSEG0ADDR(i)),
+			  "i" (Page_Invalidate_T));
+	}
+
+	/* Let the RM7000 MM code know that the tertiary cache is enabled */
+	rm7k_tcache_enabled = 1;
+
+	printk("Done\n");
+}
+
+
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+
+static int io_base_ioremap(void)
+{
+	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
+	void *io_remap_range = ioremap(0xc0000000, 0x30000000);
+
+	if (!io_remap_range) {
+		panic("Could not ioremap I/O port range");
+	}
+	printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range);
+	set_io_port_base(io_remap_range - 0xc0000000);
+
+	return 0;
+}
+
+module_init(io_base_ioremap);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/Makefile linux-2.4.20/arch/mips/sgi-ip22/Makefile
--- linux-2.4.19/arch/mips/sgi-ip22/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/Makefile	2002-10-04 00:41:30.000000000 +0000
@@ -18,6 +18,7 @@
          ip22-gio.o ip22-rtc.o ip22-reset.o ip22-system.o ip22-setup.o
 
 obj-$(CONFIG_BOARD_SCACHE)	+= ip22-sc.o
+obj-$(CONFIG_IP22_EISA)		+= ip22-eisa.o
 
 ip22-irq.o: ip22-irq.S
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-berr.c linux-2.4.20/arch/mips/sgi-ip22/ip22-berr.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-berr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-berr.c	2002-10-04 00:41:30.000000000 +0000
@@ -24,7 +24,7 @@
 
 static void save_and_clear_buserr(void)
 {
-	/* save memory controler's error status registers */ 
+	/* save memory controler's error status registers */
 	cpu_err_addr = mcmisc_regs->cerr;
 	cpu_err_stat = mcmisc_regs->cstat;
 	gio_err_addr = mcmisc_regs->gerr;
@@ -34,8 +34,8 @@
 }
 
 /*
- * MC sends an interrupt whenever bus or parity errors occur. In addition, 
- * if the error happened during a CPU read, it also asserts the bus error 
+ * MC sends an interrupt whenever bus or parity errors occur. In addition,
+ * if the error happened during a CPU read, it also asserts the bus error
  * pin on the R4K. Code in bus error handler save the MC bus error registers
  * and then clear the interrupt when this happens.
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-eisa.c linux-2.4.20/arch/mips/sgi-ip22/ip22-eisa.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-eisa.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-eisa.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,300 @@
+/*
+ * Basic EISA bus support for the SGI Indigo-2.
+ *
+ * (C) 2002 Pascal Dameme <netinet@freesurf.fr>
+ *      and Marc Zyngier <mzyngier@freesurf.fr>
+ *
+ * This code is released under both the GPL version 2 and BSD
+ * licenses.  Either license may be used.
+ *
+ * This code offers a very basic support for this EISA bus present in
+ * the SGI Indigo-2. It currently only supports PIO (forget about DMA
+ * for the time being). This is enough for a low-end ethernet card,
+ * but forget about your favorite SCSI card...
+ *
+ * TODO :
+ * - Fix bugs...
+ * - Add ISA support
+ * - Add DMA (yeah, right...).
+ * - Fix more bugs.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/sgi/sgint23.h>
+
+extern int EISA_bus;
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+#define EISA_MAX_SLOTS		  4
+#define EISA_MAX_IRQ             16
+
+#define EISA_TO_PHYS(x)  (0x00080000 | (x))
+#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
+
+#define EIU_MODE_REG     0x0009ffc0
+#define EIU_STAT_REG     0x0009ffc4
+#define EIU_PREMPT_REG   0x0009ffc8
+#define EIU_QUIET_REG    0x0009ffcc
+#define EIU_INTRPT_ACK   0x00090004
+
+#define EISA_DMA1_STATUS            8
+#define EISA_INT1_CTRL           0x20
+#define EISA_INT1_MASK           0x21
+#define EISA_INT2_CTRL           0xA0
+#define EISA_INT2_MASK           0xA1
+#define EISA_DMA2_STATUS         0xD0
+#define EISA_DMA2_WRITE_SINGLE   0xD4
+#define EISA_EXT_NMI_RESET_CTRL 0x461
+#define EISA_INT1_EDGE_LEVEL    0x4D0
+#define EISA_INT2_EDGE_LEVEL    0x4D1
+#define EISA_VENDOR_ID_OFFSET   0xC80
+
+#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
+#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
+#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
+#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
+
+static char *decode_eisa_sig(u8 * sig)
+{
+	static char sig_str[8];
+	u16 rev;
+
+	if (sig[0] & 0x80)
+		return NULL;
+
+	sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+	sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+	sig_str[2] = (sig[1] & 0x1f) + ('A' - 1);
+	rev = (sig[2] << 8) | sig[3];
+	sprintf(sig_str + 3, "%04X", rev);
+
+	return sig_str;
+}
+
+static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u8 eisa_irq;
+	u8 dma1, dma2;
+
+	eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
+	dma1 = EISA_READ_8(EISA_DMA1_STATUS);
+	dma2 = EISA_READ_8(EISA_DMA2_STATUS);
+
+	if (eisa_irq >= EISA_MAX_IRQ) {
+		/* Oops, Bad Stuff Happened... */
+		printk("eisa_irq %d out of bound\n", eisa_irq);
+
+		EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+		EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+	} else
+		do_IRQ(eisa_irq, regs);
+}
+
+static void enable_eisa1_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	save_and_cli(flags);
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+
+	restore_flags(flags);
+}
+
+static unsigned int startup_eisa1_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
+	edge &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
+
+	enable_eisa1_irq(irq);
+	return 0;
+}
+
+static void disable_eisa1_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask |= ((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+}
+
+#define shutdown_eisa1_irq	disable_eisa1_irq
+
+static void mask_and_ack_eisa1_irq(unsigned int irq)
+{
+	disable_eisa1_irq(irq);
+
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa1_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa1_irq_type = {
+	"IP22 EISA",
+	startup_eisa1_irq,
+	shutdown_eisa1_irq,
+	enable_eisa1_irq,
+	disable_eisa1_irq,
+	mask_and_ack_eisa1_irq,
+	end_eisa1_irq,
+	NULL
+};
+
+static void enable_eisa2_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	save_and_cli(flags);
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+
+	restore_flags(flags);
+}
+
+static unsigned int startup_eisa2_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
+	edge &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
+
+	enable_eisa2_irq(irq);
+	return 0;
+}
+
+static void disable_eisa2_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask |= ((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+}
+
+#define shutdown_eisa2_irq	disable_eisa2_irq
+
+static void mask_and_ack_eisa2_irq(unsigned int irq)
+{
+	disable_eisa2_irq(irq);
+
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa2_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa2_irq_type = {
+	"IP22 EISA",
+	startup_eisa2_irq,
+	shutdown_eisa2_irq,
+	enable_eisa2_irq,
+	disable_eisa2_irq,
+	mask_and_ack_eisa2_irq,
+	end_eisa2_irq,
+	NULL
+};
+
+static struct irqaction eisa_action = {
+	ip22_eisa_intr, 0, 0, "EISA", NULL, NULL
+};
+
+static struct irqaction cascade_action = {
+	no_action, 0, 0, "EISA cascade", NULL, NULL
+};
+
+int __init ip22_eisa_init(void)
+{
+	int i, c;
+	char *str;
+	u8 *slot_addr;
+
+	printk("EISA: Probing bus...\n");
+	for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
+		slot_addr =
+		    (u8 *) EISA_TO_KSEG1((0x1000 * i) +
+					 EISA_VENDOR_ID_OFFSET);
+		if ((str = decode_eisa_sig(slot_addr))) {
+			printk("EISA: slot %d : %s detected.\n", i, str);
+			c++;
+		}
+	}
+	printk("EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+#ifdef CONFIG_ISA
+	printk("ISA support compiled in.\n");
+#endif
+
+	/* Warning : BlackMagicAhead(tm).
+	   Please wave your favorite dead chicken over the busses */
+
+	/* First say hello to the EIU */
+	EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
+	EIU_WRITE_32(EIU_QUIET_REG, 1);
+	EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
+
+	/* Now be nice to the EISA chipset */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
+	for (i = 0; i < 10000; i++);	/* Wait long enough for the dust to settle */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT1_MASK, 0);
+	EISA_WRITE_8(EISA_INT2_MASK, 8);
+	EISA_WRITE_8(EISA_INT1_MASK, 4);
+	EISA_WRITE_8(EISA_INT2_MASK, 2);
+	EISA_WRITE_8(EISA_INT1_MASK, 1);
+	EISA_WRITE_8(EISA_INT2_MASK, 1);
+	EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
+	EISA_WRITE_8(EISA_INT2_MASK, 0xff);
+	EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
+
+	for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		if (i < (SGINT_EISA + 8))
+			irq_desc[i].handler = &ip22_eisa1_irq_type;
+		else
+			irq_desc[i].handler = &ip22_eisa2_irq_type;
+	}
+
+	/* Cannot use request_irq because of kmalloc not being ready at such
+	 * an early stage. Yes, I've been bitten... */
+	setup_irq(SGI_EISA_IRQ, &eisa_action);
+	setup_irq(SGINT_EISA + 2, &cascade_action);
+
+	EISA_bus = 1;
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-gio.c linux-2.4.20/arch/mips/sgi-ip22/ip22-gio.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-gio.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-gio.c	2002-10-04 00:41:14.000000000 +0000
@@ -1,6 +1,6 @@
-/* 
+/*
  * ip22-gio.c: Support for GIO64 bus (inspired by PCI code)
- * 
+ *
  * Copyright (C) 2002 Ladislav Michl
  */
 
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 
+#include <asm/addrspace.h>
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgigio.h>
 
@@ -67,7 +68,7 @@
 {
 	int i;
 	char *p = buf;
-	
+
 	p += sprintf(p, "GIO devices found:\n");
 	for (i = 0; i < GIO_NUM_SLOTS; i++) {
 		if (gio_slot[i].flags & GIO_NO_DEVICE)
@@ -77,7 +78,7 @@
 		p += sprintf(p, "    BaseAddr 0x%08lx, MapSize 0x%08x\n",
 			     gio_slot[i].base_addr, gio_slot[i].map_size);
 	}
-	
+
 	return p - buf;
 }
 
@@ -92,7 +93,7 @@
  * @from: Previous GIO device found in search, or %NULL for new search.
  *
  * Iterates through the list of known GIO devices. If a GIO device is found
- * with a matching @device, a pointer to its device structure is returned. 
+ * with a matching @device, a pointer to its device structure is returned.
  * Otherwise, %NULL is returned.
  * A new search is initiated by passing %NULL to the @from argument.
  * Otherwise if @from is not %NULL, searches continue from next device.
@@ -101,12 +102,12 @@
 gio_find_device(unsigned char device, const struct gio_dev *from)
 {
 	int i;
-	
+
 	for (i = (from) ? from->slot_number : 0; i < GIO_NUM_SLOTS; i++)
-		if (!(gio_slot[i].flags & GIO_NO_DEVICE) && 
+		if (!(gio_slot[i].flags & GIO_NO_DEVICE) &&
 		   (device == GIO_ANY_ID || device == gio_slot[i].device))
 			return &gio_slot[i];
-	
+
 	return NULL;
 }
 
@@ -119,7 +120,7 @@
 
 extern int ip22_baddr(unsigned int *val, unsigned long addr);
 
-/** 
+/**
  * sgigio_init - scan the GIO space and figure out what hardware is actually
  * present.
  */
@@ -146,7 +147,7 @@
 		printk("GIO: Card 0x%02x @ 0x%08lx\n", gio_slot[i].device,
 			gio_slot[i].base_addr);
 	}
-	
+
 	if (!found)
 		printk("GIO: No GIO cards present.\n");
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-int.c linux-2.4.20/arch/mips/sgi-ip22/ip22-int.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-int.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-int.c	2002-10-04 00:41:14.000000000 +0000
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
  *                    - Indigo2 changes
  *                    - Interrupt handling fixes
  * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
@@ -20,7 +20,6 @@
 
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
-#include <asm/gdb-stub.h>
 
 #include <asm/sgi/sgint23.h>
 #include <asm/sgi/sgihpc.h>
@@ -41,6 +40,7 @@
 
 extern asmlinkage void indyIRQ(void);
 extern void do_IRQ(int irq, struct pt_regs *regs);
+extern int ip22_eisa_init (void);
 
 static void enable_local0_irq(unsigned int irq)
 {
@@ -187,7 +187,7 @@
 {
 #ifdef I_REALLY_NEED_THIS_IRQ
 	unsigned long flags;
-	
+
 	save_and_cli(flags);
 	ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
 	ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
@@ -276,7 +276,7 @@
 	/* if irq == 0, then the interrupt has already been cleared */
 	if (irq)
 		do_IRQ(irq, regs);
-	return;	
+	return;
 }
 
 extern void be_ip22_interrupt(int irq, struct pt_regs *regs);
@@ -292,11 +292,11 @@
 	irq_exit(cpu, irq);
 }
 
-static struct irqaction local0_cascade = 
+static struct irqaction local0_cascade =
 	{ no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL };
-static struct irqaction local1_cascade = 
+static struct irqaction local1_cascade =
 	{ no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL };
-static struct irqaction buserr = 
+static struct irqaction buserr =
 	{ no_action, SA_INTERRUPT, 0, "Bus Error", NULL, NULL };
 static struct irqaction map0_cascade =
 	{ no_action, SA_INTERRUPT, 0, "mappable0 cascade", NULL, NULL };
@@ -409,10 +409,14 @@
 	setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
 	setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
 	setup_irq(SGI_BUSERR_IRQ, &buserr);
-	
+
 	/* cascade in cascade. i love Indy ;-) */
 	setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
 #ifdef I_REALLY_NEED_THIS_IRQ
 	setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
 #endif
+#ifdef CONFIG_IP22_EISA
+	if (!sgi_guiness)	/* Only Indigo-2 have EISA stuff */
+	        ip22_eisa_init ();
+#endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-irq.S linux-2.4.20/arch/mips/sgi-ip22/ip22-irq.S
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-irq.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-irq.S	2002-10-04 00:41:20.000000000 +0000
@@ -65,10 +65,8 @@
 	 andi	a0, s0, CAUSEF_IP2	# delay slot, check local level zero
 
 	/* Wheee, a timer interrupt. */
-	move	a0, sp
 	jal	indy_r4k_timer_interrupt
-	 nop				# delay slot
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
 	 nop				# delay slot
 
@@ -88,38 +86,33 @@
 	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
 
 	/* Wheee, local level one interrupt. */
-	move	a0, sp
 	jal	indy_local1_irqdispatch
-	 nop
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 
 1:
 	beq	a0, zero, 1f
-	 nop
+	 andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)	# delay slot
 
 	/* Wheee, an asynchronous bus error... */
-	move	a0, sp
 	jal	indy_buserror_irq
-	 nop
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 
 1:
 	/* Here by mistake? It is possible, that by the time we take
-	 * the exception the IRQ pin goes low, so just leave if this 
+	 * the exception the IRQ pin goes low, so just leave if this
 	 * is the case.
 	 */
-	andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
 	beq	a0, zero, 1f
+	 nop			  	# delay slot
 
 	/* Must be one of the 8254 timers... */
-	move	a0, sp
 	jal	indy_8254timer_irq
-	 nop
+	 move	a0, sp			# delay slot
 1:
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 	END(indyIRQ)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-mc.c linux-2.4.20/arch/mips/sgi-ip22/ip22-mc.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-mc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-mc.c	2002-10-04 00:41:09.000000000 +0000
@@ -16,10 +16,15 @@
 
 /* #define DEBUG_SGIMC */
 
+#ifdef DEBUG_SGIMC
+extern void prom_printf(char *fmt, ...);
+#endif
+
 struct sgimc_misc_ctrl *mcmisc_regs;
 struct sgimc_dma_ctrl *dmactrlregs;
 u32 *rpsscounter;
 
+#ifdef DEBUG_SGIMC
 static inline char *mconfig_string(unsigned long val)
 {
 	switch(val & SGIMC_MCONFIG_RMASK) {
@@ -45,6 +50,7 @@
 		return "wheee, unknown";
 	}
 }
+#endif
 
 void __init sgimc_init(void)
 {
@@ -82,12 +88,12 @@
 	/* Place the MC into a known state.  This must be done before
 	 * interrupts are first enabled etc.
 	 */
-	
+
 	/* Step 0: Make sure we turn off the watchdog in case it's
 	 *         still running (which might be the case after a
 	 *         soft reboot).
 	 */
-	tmpreg = mcmisc_regs->cpuctrl0; 
+	tmpreg = mcmisc_regs->cpuctrl0;
 	tmpreg &= ~SGIMC_CCTRL0_WDOG;
 	mcmisc_regs->cpuctrl0 = tmpreg;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-reset.c linux-2.4.20/arch/mips/sgi-ip22/ip22-reset.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-reset.c	2002-10-04 00:41:15.000000000 +0000
@@ -58,7 +58,7 @@
 static void sgi_machine_power_off(void)
 {
 	unsigned char val;
-	
+
 	cli();
 
 	/* Disable watchdog */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-sc.c linux-2.4.20/arch/mips/sgi-ip22/ip22-sc.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-sc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-sc.c	2002-10-04 00:41:14.000000000 +0000
@@ -34,7 +34,8 @@
 	unsigned long tmp;
 
 	__asm__ __volatile__(
-	".set\tnoreorder\t\t\t# indy_sc_wipe\n\t"
+	".set\tpush\t\t\t# indy_sc_wipe\n\t"
+	".set\tnoreorder\n\t"
 	".set\tmips3\n\t"
 	".set\tnoat\n\t"
 	"mfc0\t%2, $12\n\t"
@@ -48,12 +49,11 @@
 
 	"1:\tsw\t$0, 0(%0)\n\t"
 	"bne\t%0, %1, 1b\n\t"
-	"daddu\t%0, 32\n\t"
+	" daddu\t%0, 32\n\t"
 
 	"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
 	"nop; nop; nop; nop;\n\t"
-	".set\tmips0\n\t"
-	".set\treorder"
+	".set\tpop"
 	: "=r" (first), "=r" (last), "=&r" (tmp)
 	: "0" (first), "1" (last));
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.20/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-setup.c	2002-10-04 00:41:11.000000000 +0000
@@ -28,6 +28,7 @@
 #include <asm/sgi/sgint23.h>
 #include <asm/time.h>
 #include <asm/gdb-stub.h>
+#include <asm/io.h>
 #include <asm/traps.h>
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -133,9 +134,7 @@
 
 void __init ip22_setup(void)
 {
-#ifdef CONFIG_SERIAL_CONSOLE
 	char *ctype;
-#endif
 #ifdef CONFIG_REMOTE_DEBUG
 	char *kgdb_ttyd;
 #endif
@@ -155,19 +154,27 @@
 #endif
 	conswitchp = NULL;
 
-#ifdef CONFIG_SERIAL_CONSOLE
+	/* Set the IO space to some sane value */
+	set_io_port_base (KSEG1ADDR (0x00080000));
+
 	/* ARCS console environment variable is set to "g?" for
 	 * graphics console, it is set to "d" for the first serial
 	 * line and "d2" for the second serial line.
 	 */
 	ctype = ArcGetEnvironmentVariable("console");
-	if(*ctype == 'd') {
-		if(*(ctype+1)=='2')
-			console_setup ("ttyS1");
+	if (*ctype == 'd') {
+#ifdef CONFIG_SERIAL_CONSOLE
+		if(*(ctype + 1) == '2')
+			console_setup("ttyS1");
 		else
-			console_setup ("ttyS0");
-	}
+			console_setup("ttyS0");
+#endif
+	} else {
+#ifdef CONFIG_ARC_CONSOLE
+		prom_flags &= PROM_FLAG_USE_AS_CONSOLE;
+		console_setup("ttyS0");
 #endif
+	}
 
 #ifdef CONFIG_REMOTE_DEBUG
 	kgdb_ttyd = prom_getcmdline();
@@ -190,20 +197,19 @@
 	}
 #endif
 
-#ifdef CONFIG_ARC_CONSOLE
-	console_setup("ttyS0");
-#endif
- 
 	sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10));
 
-	{
-	  unsigned long *gfxinfo;
-	  long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20);
-	  gfxinfo = (unsigned long *)__vec();
-	  sgi_gfxaddr = gfxinfo[1] >= 0xa0000000 && gfxinfo[1] <= 0xc0000000 ? gfxinfo[1] - 0xa0000000 : 0;
-	}
 #ifdef CONFIG_VT
 #ifdef CONFIG_SGI_NEWPORT_CONSOLE
+	{
+		unsigned long *gfxinfo;
+		long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20);
+
+		gfxinfo = (unsigned long *)__vec();
+		sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000
+			       && gfxinfo[1] <= 0xc0000000)
+			       ? gfxinfo[1] - 0xa0000000 : 0);
+	}
 	/* newport addresses? */
 	if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
 		conswitchp = &newport_con;
@@ -223,9 +229,11 @@
 		conswitchp = &dummy_con;
 	}
 #else
+#ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
 #endif
+#endif
 
 	rtc_ops = &indy_rtc_ops;
 	kbd_ops = &sgi_kbd_ops;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-system.c linux-2.4.20/arch/mips/sgi-ip22/ip22-system.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-system.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-system.c	2002-10-04 00:41:12.000000000 +0000
@@ -34,7 +34,7 @@
 
 static int __init string_to_cpu(char *s)
 {
-	long cnt;
+	ULONG cnt;
 	char c;
 	int i;
 
@@ -57,7 +57,7 @@
 {
 	pcomponent *p, *toplev, *cpup = 0;
 	int cputype = -1;
-	long cnt;
+	ULONG cnt;
 	char c;
 
 
@@ -79,9 +79,9 @@
 				ArcRead(0, &c, 1, &cnt);
 				ArcEnterInteractiveMode();
 			}
-			printk("CPU: %s ", p->iname);
+			printk("CPU: %s ", (char *)p->iname);
 			cpup = p;
-			cputype = string_to_cpu(cpup->iname);
+			cputype = string_to_cpu((char *)cpup->iname);
 		}
 		p = ArcGetPeer(p);
 	}
@@ -97,7 +97,7 @@
 		case processor:
 			switch(p->type) {
 			case Fpu:
-				printk("FPU<%s> ", p->iname);
+				printk("FPU<%s> ", (char *)p->iname);
 				break;
 
 			default:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip22/ip22-time.c linux-2.4.20/arch/mips/sgi-ip22/ip22-time.c
--- linux-2.4.19/arch/mips/sgi-ip22/ip22-time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip22/ip22-time.c	2002-10-04 00:41:21.000000000 +0000
@@ -3,10 +3,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Time operations for IP22 machines. Original code may come from 
+ * Time operations for IP22 machines. Original code may come from
  * Ralf Baechle or David S. Miller (sorry guys, i'm really not sure)
  *
- * Copyright (C) 2001 by Ladislav Michl 
+ * Copyright (C) 2001 by Ladislav Michl
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
@@ -28,7 +28,7 @@
  * uses 0 to 11.
  */
 static unsigned long indy_rtc_get_time(void)
-{	
+{
 	unsigned char yrs, mon, day, hrs, min, sec;
 	unsigned char save_control;
 
@@ -97,8 +97,8 @@
 static unsigned long dosample(volatile unsigned char *tcwp,
 			      volatile unsigned char *tc2p)
 {
-	unsigned long ct0, ct1;
-	unsigned char msb, lsb;
+	u32 ct0, ct1;
+	volatile u8 msb, lsb;
 
 	/* Start the counter. */
 	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
@@ -127,8 +127,8 @@
 	return ((ct1 - ct0) / 5000) * 5000;
 }
 
-/* 
- * Here we need to calibrate the cycle counter to at least be close. 
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
  */
 void indy_time_init(void)
 {
@@ -165,7 +165,7 @@
 	if (r4k_ticks[0] != r4k_ticks[1]) {
 		printk ("warning: timer counts differ, retrying...");
 		r4k_ticks[2] = dosample (tcwp, tc2p);
-		if (r4k_ticks[2] == r4k_ticks[0] 
+		if (r4k_ticks[2] == r4k_ticks[0]
 		    || r4k_ticks[2] == r4k_ticks[1])
 			r4k_tick = r4k_ticks[2];
 		else {
@@ -179,12 +179,12 @@
 	printk("%d [%d.%02d MHz CPU]\n", (int) r4k_tick,
 		(int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50);
 
-	mips_counter_frequency = r4k_tick * HZ;	
-	
+	mips_counter_frequency = r4k_tick * HZ;
+
 	/* HACK ALERT! This get's called after traps initialization
 	 * We piggyback the initialization of GIO bus here even though
 	 * it is technically not related with the timer in any way.
-	 * Doing it from ip22_setup wouldn't work since traps aren't 
+	 * Doing it from ip22_setup wouldn't work since traps aren't
 	 * initialized yet.
 	 */
 	sgigio_init();
@@ -225,7 +225,7 @@
 static void indy_timer_setup(struct irqaction *irq)
 {
 	unsigned long count;
-	
+
 	/* over-write the handler, we use our own way */
 	irq->handler = no_action;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/Makefile linux-2.4.20/arch/mips/sgi-ip27/Makefile
--- linux-2.4.19/arch/mips/sgi-ip27/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,15 @@
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET = ip27.o
+
+export-objs		= ip27-rtc.o
+
+obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
+	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
+	   ip27-reset.o ip27-setup.o ip27-timer.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/TODO linux-2.4.20/arch/mips/sgi-ip27/TODO
--- linux-2.4.19/arch/mips/sgi-ip27/TODO	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/TODO	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,23 @@
+1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
+not to write to the IOC3 ever.
+2. Need to figure out RRB allocation in bridge_startup().
+3. Need to figure out why address swaizzling is needed in inw/outw for
+Qlogic scsi controllers.
+4. Need to integrate ip27-klconfig.c:find_lboard and
+ip27-init.c:find_lbaord_real. DONE
+5. Is it okay to set calias space on all nodes as 0, instead of 8k as
+in irix?
+6. Investigate why things do not work without the setup_test() call
+being invoked on all nodes in ip27-memory.c.
+7. Too many CLIs in the locore handlers :
+For the low level handlers set up by set_except_vector(),
+__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
+investigate whether the code should do CLI, STI or KMODE.
+8. Too many do_page_faults invoked - investigate.
+9. start_thread must turn off UX64 ... and define tlb_refill_debug.
+10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
+does not agree with pgd_bad/pmd_bad.
+11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
+This might need to change later. Only the timer intr is set up to be
+received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
+13. Cache flushing (specially the SMP version) has to be investigated.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-berr.c linux-2.4.20/arch/mips/sgi-ip27/ip27-berr.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-berr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-berr.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,93 @@
+/*
+ * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+extern void dump_tlb_addr(unsigned long addr);
+extern void dump_tlb_all(void);
+
+static void dump_hub_information(unsigned long errst0, unsigned long errst1)
+{
+	static char *err_type[2][8] = {
+		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
+		  NULL, NULL, NULL, NULL },
+		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
+		  NULL, NULL, NULL, NULL }
+	};
+	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
+
+	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
+		printk("Hub does not contain valid error information\n");
+		return;
+	}
+
+
+	printk("Hub has valid error information:\n");
+	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
+		printk("Overrun is set.  Error stack may contain additional "
+		       "information.\n");
+	printk("Hub error address is %08lx\n",
+	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
+	printk("Incoming message command 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
+	printk("Supplemental field of incoming message is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
+	printk("T5 Rn (for RRB only) is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
+	printk("Error type is %s\n", err_type[wrb]
+	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
+		? : "invalid");
+}
+
+int be_ip27_handler(struct pt_regs *regs, int is_fixup)
+{
+	unsigned long errst0, errst1;
+	int data = regs->cp0_cause & 4;
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
+	       regs->cp0_epc);
+	printk("Hub information:\n");
+	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
+	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
+	dump_hub_information(errst0, errst1);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init bus_error_init(void)
+{
+	/* XXX Initialize all the Hub & Bridge error handling here.  */
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+	int cpuoff = cpu << 8;
+
+	be_board_handler = be_ip27_handler;
+
+	LOCAL_HUB_S(PI_ERR_INT_PEND,
+	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
+	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
+	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-console.c linux-2.4.20/arch/mips/sgi-ip27/ip27-console.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-console.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-console.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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) 2001 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+void prom_putchar(char c)
+{
+	struct ioc3 *ioc3;
+	struct ioc3_uartregs *uart;
+
+	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base;
+	uart = &ioc3->sregs.uarta;
+
+	while ((uart->iu_lsr & 0x20) == 0);
+	uart->iu_thr = c;
+}
+
+char __init prom_getchar(void)
+{
+	return 0;
+}
+
+static void
+ip27prom_console_write(struct console *con, const char *s, unsigned n)
+{
+	prom_printf("%s", s);
+}
+
+static kdev_t
+ip27prom_console_dev(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console ip27_prom_console = {
+    name:	"prom",
+    write:	ip27prom_console_write,
+    device:	ip27prom_console_dev,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+__init void ip27_setup_console(void)
+{
+	register_console(&ip27_prom_console);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-init.c linux-2.4.20/arch/mips/sgi-ip27/ip27-init.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-init.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,838 @@
+/*
+ * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mmzone.h>	/* for numnodes */
+#include <linux/mm.h>
+#include <asm/cpu.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/intr.h>
+#include <asm/current.h>
+#include <asm/smp.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/gda.h>
+
+#define CPU_NONE		(cpuid_t)-1
+
+/*
+ * The following should work till 64 nodes, ie 128p SN0s.
+ */
+#define CNODEMASK_CLRALL(p)	(p) = 0
+#define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
+#define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
+
+cpumask_t	boot_cpumask;
+hubreg_t	region_mask = 0;
+static int	fine_mode = 0;
+int		maxcpus;
+static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
+static cnodemask_t hub_init_mask;
+static atomic_t numstarted = ATOMIC_INIT(1);
+static int router_distance;
+nasid_t master_nasid = INVALID_NASID;
+
+cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
+nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
+cnodeid_t	cpuid_to_compact_node[MAXCPUS];
+char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+
+hubreg_t get_region(cnodeid_t cnode)
+{
+	if (fine_mode)
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
+	else
+		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
+}
+
+static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
+{
+	cnodeid_t cnode;
+
+	(*region_mask) = 0;
+	for (cnode = 0; cnode < maxnodes; cnode++) {
+		(*region_mask) |= 1ULL << get_region(cnode);
+	}
+}
+
+int is_fine_dirmode(void)
+{
+	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
+		>> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
+}
+
+nasid_t get_actual_nasid(lboard_t *brd)
+{
+	klhub_t *hub;
+
+	if (!brd)
+		return INVALID_NASID;
+
+	/* find out if we are a completely disabled brd. */
+	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+	if (!hub)
+		return INVALID_NASID;
+	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
+		return hub->hub_info.physid;
+	else
+		return brd->brd_nasid;
+}
+
+/* Tweak this for maximum number of CPUs to activate */
+static int max_cpus = NR_CPUS;
+
+int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask,
+							int *highest)
+{
+	static int tot_cpus_found = 0;
+	lboard_t *brd;
+	klcpu_t *acpu;
+	int cpus_found = 0;
+	cpuid_t cpuid;
+
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+
+	do {
+		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
+		while (acpu) {
+			cpuid = acpu->cpu_info.virtid;
+			/* cnode is not valid for completely disabled brds */
+			if (get_actual_nasid(brd) == brd->brd_nasid)
+				cpuid_to_compact_node[cpuid] = cnode;
+			if (cpuid > *highest)
+				*highest = cpuid;
+			/* Only let it join in if it's marked enabled */
+			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
+						(tot_cpus_found != max_cpus)) {
+				CPUMASK_SETB(*boot_cpumask, cpuid);
+				cpus_found++;
+				tot_cpus_found++;
+			}
+			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU);
+		}
+		brd = KLCF_NEXT(brd);
+		if (brd)
+			brd = find_lboard(brd,KLTYPE_IP27);
+		else
+			break;
+	} while (brd);
+
+	return cpus_found;
+}
+
+cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
+{
+	int i, cpus = 0, highest = 0;
+	gda_t *gdap = GDA;
+	nasid_t nasid;
+
+	/*
+	 * Initialize the arrays to invalid nodeid (-1)
+	 */
+	for (i = 0; i < MAX_COMPACT_NODES; i++)
+		compact_to_nasid_node[i] = INVALID_NASID;
+	for (i = 0; i < MAX_NASIDS; i++)
+		nasid_to_compact_node[i] = INVALID_CNODEID;
+	for (i = 0; i < MAXCPUS; i++)
+		cpuid_to_compact_node[i] = INVALID_CNODEID;
+
+	*numnodes = 0;
+	for (i = 0; i < MAX_COMPACT_NODES; i++) {
+		if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) {
+			break;
+		} else {
+			compact_to_nasid_node[i] = nasid;
+			nasid_to_compact_node[nasid] = i;
+			(*numnodes)++;
+			cpus += do_cpumask(i, nasid, boot_cpumask, &highest);
+		}
+	}
+
+	/*
+	 * Cpus are numbered in order of cnodes. Currently, disabled
+	 * cpus are not numbered.
+	 */
+
+	return(highest + 1);
+}
+
+int cpu_enabled(cpuid_t cpu)
+{
+	if (cpu == CPU_NONE)
+		return 0;
+	return (CPUMASK_TSTB(boot_cpumask, cpu) != 0);
+}
+
+void mlreset (void)
+{
+	int i;
+	void init_topology_matrix(void);
+	void dump_topology(void);
+
+
+	master_nasid = get_nasid();
+	fine_mode = is_fine_dirmode();
+
+	/*
+	 * Probe for all CPUs - this creates the cpumask and
+	 * sets up the mapping tables.
+	 */
+	CPUMASK_CLRALL(boot_cpumask);
+	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
+	printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
+
+	init_topology_matrix();
+	dump_topology();
+
+	gen_region_mask(&region_mask, numnodes);
+	CNODEMASK_CLRALL(hub_init_mask);
+
+	setup_replication_mask(numnodes);
+
+	/*
+	 * Set all nodes' calias sizes to 8k
+	 */
+	for (i = 0; i < numnodes; i++) {
+		nasid_t nasid;
+
+		nasid = COMPACT_TO_NASID_NODEID(i);
+
+		/*
+		 * Always have node 0 in the region mask, otherwise
+		 * CALIAS accesses get exceptions since the hub
+		 * thinks it is a node 0 address.
+		 */
+		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
+#else
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
+#endif
+
+#ifdef LATER
+		/*
+		 * Set up all hubs to have a big window pointing at
+		 * widget 0. Memory mode, widget 0, offset 0
+		 */
+		REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
+			((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
+			(0 << IIO_ITTE_WIDGET_SHIFT)));
+#endif
+	}
+}
+
+
+void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
+							char *name)
+{
+	volatile hubreg_t bits;
+	int i;
+
+	/* Check pending interrupts */
+	if ((bits = HUB_L(pend)) != 0)
+		for (i = 0; i < N_INTPEND_BITS; i++)
+			if (bits & (1 << i))
+				LOCAL_HUB_CLR_INTR(base_level + i);
+}
+
+void intr_clear_all(nasid_t nasid)
+{
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
+		INT_PEND0_BASELVL, "INT_PEND0");
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
+		INT_PEND1_BASELVL, "INT_PEND1");
+}
+
+void sn_mp_setup(void)
+{
+	cnodeid_t	cnode;
+#if 0
+	cpuid_t		cpu;
+#endif
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+#if 0
+		init_platform_nodepda();
+#endif
+		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+	}
+#if 0
+	for (cpu = 0; cpu < maxcpus; cpu++) {
+		init_platform_pda();
+	}
+#endif
+}
+
+void per_hub_init(cnodeid_t cnode)
+{
+	extern void pcibr_setup(cnodeid_t);
+	cnodemask_t	done;
+	nasid_t		nasid;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	spin_lock(&hub_mask_lock);
+	/* Test our bit. */
+	if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) {
+		/* Turn our bit on in the mask. */
+		CNODEMASK_SETB(hub_init_mask, cnode);
+		/*
+	 	 * Do the actual initialization if it hasn't been done yet.
+	 	 * We don't need to hold a lock for this work.
+	 	 */
+		/*
+		 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
+		 */
+		REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
+		REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+		hub_rtc_init(cnode);
+		pcibr_setup(cnode);
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+		/*
+		 * If this is not a headless node initialization,
+		 * copy over the caliased exception handlers.
+		 */
+		if (get_compact_nodeid() == cnode) {
+			extern char except_vec0, except_vec1_r10k;
+			extern char except_vec2_generic, except_vec3_generic;
+
+			memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic,
+								0x80);
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+								0x80);
+			memcpy((void *)KSEG0, &except_vec0, 0x80);
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
+			memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+								0x100);
+			flush_cache_l1();
+			flush_cache_l2();
+		}
+#endif
+	}
+	spin_unlock(&hub_mask_lock);
+}
+
+/*
+ * This is similar to hard_smp_processor_id().
+ */
+cpuid_t getcpuid(void)
+{
+	klcpu_t *klcpu;
+
+	klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
+	return klcpu->cpu_info.virtid;
+}
+
+void per_cpu_init(void)
+{
+	extern void install_cpu_nmi_handler(int slice);
+	extern void load_mmu(void);
+	static int is_slave = 0;
+	int cpu = smp_processor_id();
+	cnodeid_t cnode = get_compact_nodeid();
+
+	TLBMISS_HANDLER_SETUP();
+#if 0
+	intr_init();
+#endif
+	clear_cp0_status(ST0_IM);
+	per_hub_init(cnode);
+	cpu_time_init();
+	if (smp_processor_id())	/* master can't do this early, no kmalloc */
+		install_cpuintr(cpu);
+	/* Install our NMI handler if symmon hasn't installed one. */
+	install_cpu_nmi_handler(cputoslice(cpu));
+#if 0
+	install_tlbintr(cpu);
+#endif
+	set_cp0_status(SRB_DEV0 | SRB_DEV1);
+	if (is_slave) {
+		clear_cp0_status(ST0_BEV);
+		if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
+			set_cp0_status(ST0_XX);
+		set_cp0_status(ST0_KX|ST0_SX|ST0_UX);
+		sti();
+		load_mmu();
+		atomic_inc(&numstarted);
+	} else {
+		is_slave = 1;
+	}
+}
+
+cnodeid_t get_compact_nodeid(void)
+{
+	nasid_t nasid;
+
+	nasid = get_nasid();
+	/*
+	 * Map the physical node id to a virtual node id (virtual node ids
+	 * are contiguous).
+	 */
+	return NASID_TO_COMPACT_NODEID(nasid);
+}
+
+#ifdef CONFIG_SMP
+
+/*
+ * Takes as first input the PROM assigned cpu id, and the kernel
+ * assigned cpu id as the second.
+ */
+static void alloc_cpupda(cpuid_t cpu, int cpunum)
+{
+	cnodeid_t	node;
+	nasid_t		nasid;
+
+	node = get_cpu_cnode(cpu);
+	nasid = COMPACT_TO_NASID_NODEID(node);
+
+	cputonasid(cpunum) = nasid;
+	cputocnode(cpunum) = node;
+	cputoslice(cpunum) = get_cpu_slice(cpu);
+	cpu_data[cpunum].p_cpuid = cpu;
+}
+
+static volatile cpumask_t boot_barrier;
+
+void __init start_secondary(void)
+{
+	CPUMASK_CLRB(boot_barrier, getcpuid());	/* needs atomicity */
+	per_cpu_init();
+	per_cpu_trap_init();
+#if 0
+	ecc_init();
+	bte_lateinit();
+	init_mfhi_war();
+#endif
+	local_flush_tlb_all();
+	flush_cache_l1();
+	flush_cache_l2();
+	start_secondary();
+}
+
+__init void allowboot(void)
+{
+	int		num_cpus = 0;
+	cpuid_t		cpu, mycpuid = getcpuid();
+	cnodeid_t	cnode;
+	extern void	smp_bootstrap(void);
+
+	sn_mp_setup();
+	/* Master has already done per_cpu_init() */
+	install_cpuintr(smp_processor_id());
+#if 0
+	bte_lateinit();
+	ecc_init();
+#endif
+
+	replicate_kernel_text(numnodes);
+	boot_barrier = boot_cpumask;
+	/* Launch slaves. */
+	for (cpu = 0; cpu < maxcpus; cpu++) {
+		if (cpu == mycpuid) {
+			alloc_cpupda(cpu, num_cpus);
+			num_cpus++;
+			/* We're already started, clear our bit */
+			CPUMASK_CLRB(boot_barrier, cpu);
+			continue;
+		}
+
+		/* Skip holes in CPU space */
+		if (CPUMASK_TSTB(boot_cpumask, cpu)) {
+			struct task_struct *p;
+
+			/*
+			 * The following code is purely to make sure
+			 * Linux can schedule processes on this slave.
+			 */
+			kernel_thread(0, NULL, CLONE_PID);
+			p = init_task.prev_task;
+			sprintf(p->comm, "%s%d", "Idle", num_cpus);
+			init_tasks[num_cpus] = p;
+			alloc_cpupda(cpu, num_cpus);
+			del_from_runqueue(p);
+			p->processor = num_cpus;
+			p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */
+			unhash_process(p);
+			/* Attach to the address space of init_task. */
+			atomic_inc(&init_mm.mm_count);
+			p->active_mm = &init_mm;
+
+			/*
+		 	 * Launch a slave into smp_bootstrap().
+		 	 * It doesn't take an argument, and we
+			 * set sp to the kernel stack of the newly
+			 * created idle process, gp to the proc struct
+			 * (so that current-> works).
+		 	 */
+			LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus),
+				(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
+				0, (void *)((unsigned long)p +
+				KERNEL_STACK_SIZE - 32), (void *)p);
+
+			/*
+			 * Now optimistically set the mapping arrays. We
+			 * need to wait here, verify the cpu booted up, then
+			 * fire up the next cpu.
+			 */
+			__cpu_number_map[cpu] = num_cpus;
+			__cpu_logical_map[num_cpus] = cpu;
+			CPUMASK_SETB(cpu_online_map, cpu);
+			num_cpus++;
+			/*
+			 * Wait this cpu to start up and initialize its hub,
+			 * and discover the io devices it will control.
+			 *
+			 * XXX: We really want to fire up launch all the CPUs
+			 * at once.  We have to preserve the order of the
+			 * devices on the bridges first though.
+			 */
+			while(atomic_read(&numstarted) != num_cpus);
+		}
+	}
+
+
+#ifdef LATER
+	Wait logic goes here.
+#endif
+	for (cnode = 0; cnode < numnodes; cnode++) {
+#if 0
+		if (cnodetocpu(cnode) == -1) {
+			printk("Initializing headless hub,cnode %d", cnode);
+			per_hub_init(cnode);
+		}
+#endif
+	}
+#if 0
+	cpu_io_setup();
+	init_mfhi_war();
+#endif
+	smp_num_cpus = num_cpus;
+}
+
+void __init smp_boot_cpus(void)
+{
+	extern void allowboot(void);
+
+	init_new_context(current, &init_mm);
+	current->processor = 0;
+	init_idle();
+	smp_tune_scheduling();
+	allowboot();
+}
+
+#else /* CONFIG_SMP */
+void __init start_secondary(void)
+{
+	/* XXX Why do we need this empty definition at all?  */
+}
+#endif /* CONFIG_SMP */
+
+
+#define	rou_rflag	rou_flags
+
+void
+router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
+{
+	klrou_t *router;
+	lboard_t *brd;
+	int	port;
+
+	if (router_a->rou_rflag == 1)
+		return;
+
+	if (depth >= router_distance)
+		return;
+
+	router_a->rou_rflag = 1;
+
+	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
+			continue;
+
+		brd = (lboard_t *)NODE_OFFSET_TO_K0(
+			router_a->rou_port[port].port_nasid,
+			router_a->rou_port[port].port_offset);
+
+		if (brd->brd_type == KLTYPE_ROUTER) {
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			if (router == router_b) {
+				if (depth < router_distance)
+					router_distance = depth;
+			}
+			else
+				router_recurse(router, router_b, depth + 1);
+		}
+	}
+
+	router_a->rou_rflag = 0;
+}
+
+int
+node_distance(nasid_t nasid_a, nasid_t nasid_b)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	klrou_t *router, *router_a = NULL, *router_b = NULL;
+
+	/* Figure out which routers nodes in question are connected to */
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			router->rou_rflag = 0;
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27) {
+					if (dest_brd->brd_nasid == nasid_a)
+						router_a = router;
+					if (dest_brd->brd_nasid == nasid_b)
+						router_b = router;
+				}
+			}
+
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+
+	if (router_a == NULL) {
+		printk("node_distance: router_a NULL\n");
+		return -1;
+	}
+	if (router_b == NULL) {
+		printk("node_distance: router_b NULL\n");
+		return -1;
+	}
+
+	if (nasid_a == nasid_b)
+		return 0;
+
+	if (router_a == router_b)
+		return 1;
+
+	router_distance = 100;
+	router_recurse(router_a, router_b, 2);
+
+	return router_distance;
+}
+
+void
+init_topology_matrix(void)
+{
+	nasid_t nasid, nasid2;
+	cnodeid_t row, col;
+
+	for (row = 0; row < MAX_COMPACT_NODES; row++)
+		for (col = 0; col < MAX_COMPACT_NODES; col++)
+			node_distances[row][col] = -1;
+
+	for (row = 0; row < numnodes; row++) {
+		nasid = COMPACT_TO_NASID_NODEID(row);
+		for (col = 0; col < numnodes; col++) {
+			nasid2 = COMPACT_TO_NASID_NODEID(col);
+			node_distances[row][col] = node_distance(nasid, nasid2);
+		}
+	}
+}
+
+void
+dump_topology(void)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	int router_num = 0;
+	klrou_t *router;
+	cnodeid_t row, col;
+
+	printk("************** Topology ********************\n");
+
+	printk("    ");
+	for (col = 0; col < numnodes; col++)
+		printk("%02d ", col);
+	printk("\n");
+	for (row = 0; row < numnodes; row++) {
+		printk("%02d  ", row);
+		for (col = 0; col < numnodes; col++)
+			printk("%2d ", node_distances[row][col]);
+		printk("\n");
+	}
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+			printk("Router %d:", router_num);
+			router_num++;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27)
+					printk(" %d", dest_brd->brd_nasid);
+				if (dest_brd->brd_type == KLTYPE_ROUTER)
+					printk(" r");
+			}
+			printk("\n");
+
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+}
+
+#if 0
+#define		brd_widgetnum	brd_slot
+#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
+void
+dump_klcfg(void)
+{
+	cnodeid_t       cnode;
+	int i;
+	nasid_t         nasid;
+	lboard_t        *lbptr;
+	gda_t           *gdap;
+
+	gdap = (gda_t *)GDA_ADDR(get_nasid());
+	if (gdap->g_magic != GDA_MAGIC) {
+		printk("dumpklcfg_cmd: Invalid GDA MAGIC\n");
+		return;
+	}
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		nasid = gdap->g_nasidtable[cnode];
+
+		if (nasid == INVALID_NASID)
+			continue;
+
+		printk("\nDumpping klconfig Nasid %d:\n", nasid);
+
+		lbptr = KL_CONFIG_INFO(nasid);
+
+		while (lbptr) {
+			printk("    %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx",
+				"board name here", /* BOARD_NAME(lbptr->brd_type), */
+				lbptr->brd_nasid, lbptr->brd_module,
+				lbptr->brd_widgetnum,
+				lbptr->brd_partition,
+				(lbptr->brd_nic), lbptr);
+			if (lbptr->brd_flags & DUPLICATE_BOARD)
+				printk(" -D");
+			printk("\n");
+			for (i = 0; i < lbptr->brd_numcompts; i++) {
+				klinfo_t *kli;
+				kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]);
+				printk("        type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n",
+					kli->struct_type,
+					kli->flags,
+					kli->diagval,
+					kli->physid,
+					kli->virtid,
+					"comp. name here");
+					/* COMPONENT_NAME(kli->struct_type)); */
+			}
+			lbptr = KLCF_NEXT(lbptr);
+		}
+	}
+	printk("\n");
+
+	/* Useful to print router maps also */
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		klrou_t *kr;
+		int i;
+
+        	nasid = gdap->g_nasidtable[cnode];
+        	if (nasid == INVALID_NASID)
+            		continue;
+        	lbptr = KL_CONFIG_INFO(nasid);
+
+        	while (lbptr) {
+
+			lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER);
+			if(!lbptr)
+				break;
+			if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) {
+				printk("%llx -> \n", lbptr->brd_nic);
+				kr = (klrou_t *)find_first_component(lbptr,
+					KLSTRUCT_ROU);
+				for (i = 1; i <= MAX_ROUTER_PORTS; i++) {
+					printk("[%d, %llx]; ",
+						kr->rou_port[i].port_nasid,
+						kr->rou_port[i].port_offset);
+				}
+				printk("\n");
+			}
+			lbptr = KLCF_NEXT(lbptr);
+        	}
+        	printk("\n");
+    	}
+
+	dump_topology();
+}
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-irq-glue.S linux-2.4.20/arch/mips/sgi-ip27/ip27-irq-glue.S
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-irq-glue.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-irq-glue.S	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,64 @@
+/*
+ * 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) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	noat
+	.align	5
+NESTED(ip27_irq, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+
+	/* IP27 may signal interrupt which we're not interested in.
+	   Mask them out.  */
+	mfc0	s0, CP0_CAUSE
+	mfc0	t0, CP0_STATUS
+	and	s0, t0
+
+	/* First check for RT interrupt.  */
+	andi	a0, s0, CAUSEF_IP4
+	beqz	a0, 1f
+
+	/* Ok, a timer interrupt. */
+	move	a0, sp
+	jal	rt_timer_interrupt
+
+	j	ret_from_irq
+
+1:	andi	a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
+	beqz	a0, 1f
+
+	/* ... a device interrupt ...  */
+	move	a0, sp
+	jal	ip27_do_irq
+
+	j	ret_from_irq
+
+1:
+#if 1
+	mfc0	a1, CP0_STATUS
+	srl	a1, a1, 8
+	andi	a1, 0xff
+
+	mfc0	a2, CP0_CAUSE
+	srl	a2, a2, 8
+	andi	a2, 0xff
+
+	move	a3, s0
+	PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
+	ld	a1, PT_EPC(sp)
+0:	b	0b
+#endif
+
+	j	ret_from_irq
+	END(ip27_irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-irq.c linux-2.4.20/arch/mips/sgi-ip27/ip27-irq.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-irq.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,487 @@
+/*
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/intr_public.h>
+
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* These should die */
+unsigned char bus_to_wid[256];	/* widget id for linux pci bus */
+unsigned char bus_to_nid[256];	/* nasid for linux pci bus */
+unsigned char num_bridges;	/* number of bridges in the system */
+
+/*
+ * Linux has a controller-independent x86 interrupt architecture.
+ * every controller has a 'controller-template', that is used
+ * by the main code to do the right thing. Each driver-visible
+ * interrupt source is transparently wired to the apropriate
+ * controller. Thus drivers need not be aware of the
+ * interrupt-controller.
+ *
+ * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
+ * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
+ * (IO-APICs assumed to be messaging to Pentium local-APICs)
+ *
+ * the code is designed to be easily extended with new/different
+ * interrupt controllers, without having to do assembly magic.
+ */
+
+extern asmlinkage void ip27_irq(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[];
+int intr_connect_level(int cpu, int bit);
+int intr_disconnect_level(int cpu, int bit);
+
+/*
+ * There is a single intpend register per node, and we want to have
+ * distinct levels for intercpu intrs for both cpus A and B on a node.
+ */
+int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
+
+/*
+ * use these macros to get the encoded nasid and widget id
+ * from the irq value
+ */
+#define IRQ_TO_BUS(i)			irq_to_bus[(i)]
+#define IRQ_TO_CPU(i)			bus_to_cpu[IRQ_TO_BUS(i)]
+#define NASID_FROM_PCI_IRQ(i)		bus_to_nid[IRQ_TO_BUS(i)]
+#define WID_FROM_PCI_IRQ(i)		bus_to_wid[IRQ_TO_BUS(i)]
+#define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
+
+static inline int alloc_level(cpuid_t cpunum, int irq)
+{
+	cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum);
+	int j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+
+	while (++j < PERNODE_LEVELS) {
+		if (node_level_to_irq[nodenum][j] == -1) {
+			node_level_to_irq[nodenum][j] = irq;
+			return j;
+		}
+	}
+	printk("Cpu %ld flooded with devices\n", cpunum);
+	while(1);
+	return -1;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+	int j;
+	cnodeid_t nodenum = INVALID_CNODEID;
+
+	while (++nodenum < MAX_COMPACT_NODES) {
+		j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+		while (++j < PERNODE_LEVELS)
+			if (node_level_to_irq[nodenum][j] == irq) {
+				*cpunum = 0;	/* XXX Fixme */
+				return(j);
+			}
+	}
+	printk("Could not identify cpu/level for irq %d\n", irq);
+	while(1);
+	return(-1);
+}
+
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+	int b = 0, s;
+
+	s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
+	s =  8; if (x >>  8 == 0) s = 0; b += s; x >>= s;
+	s =  4; if (x >>  4 == 0) s = 0; b += s; x >>= s;
+	s =  2; if (x >>  2 == 0) s = 0; b += s; x >>= s;
+	s =  1; if (x >>  1 == 0) s = 0; b += s;
+
+	return b;
+}
+
+/*
+ * This code is unnecessarily complex, because we do SA_INTERRUPT
+ * intr enabling. Basically, once we grab the set of intrs we need
+ * to service, we must mask _all_ these interrupts; firstly, to make
+ * sure the same intr does not intr again, causing recursion that
+ * can lead to stack overflow. Secondly, we can not just mask the
+ * one intr we are do_IRQing, because the non-masked intrs in the
+ * first set might intr again, causing multiple servicings of the
+ * same intr. This effect is mostly seen for intercpu intrs.
+ * Kanoj 05.13.00
+ */
+void ip27_do_irq(struct pt_regs *regs)
+{
+	int irq, swlevel;
+	hubreg_t pend0, mask0;
+	cpuid_t thiscpu = smp_processor_id();
+	int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ?
+					PI_INT_MASK0_A : PI_INT_MASK0_B);
+
+	/* copied from Irix intpend0() */
+	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) &
+				(mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) {
+		pend0 &= mask0;		/* Pick intrs we should look at */
+		if (pend0) {
+			/* Prevent any of the picked intrs from recursing */
+			LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0));
+			do {
+				swlevel = ms1bit(pend0);
+				LOCAL_HUB_CLR_INTR(swlevel);
+				/* "map" swlevel to irq */
+				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
+				do_IRQ(irq, regs);
+				/* clear bit in pend0 */
+				pend0 ^= 1ULL << swlevel;
+			} while(pend0);
+			/* Now allow the set of serviced intrs again */
+			LOCAL_HUB_S(pi_int_mask0, mask0);
+			LOCAL_HUB_L(PI_INT_PEND0);
+		}
+	}
+}
+
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int startup_bridge_irq(unsigned int irq)
+{
+	bridgereg_t device;
+	bridge_t *bridge;
+	int pin, swlevel;
+	cpuid_t cpu;
+	nasid_t master = NASID_FROM_PCI_IRQ(irq);
+
+	if (irq < BASE_PCI_IRQ)
+		return 0;
+
+        bridge = (bridge_t *) NODE_SWIN_BASE(master, WID_FROM_PCI_IRQ(irq));
+	pin = SLOT_FROM_PCI_IRQ(irq);
+	cpu = IRQ_TO_CPU(irq);
+
+	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = alloc_level(cpu, irq);
+	intr_connect_level(cpu, swlevel);
+
+	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8));
+	bridge->b_int_enable |= (1 << pin);
+	/* more stuff in int_enable reg */
+	bridge->b_int_enable |= 0x7ffffe00;
+
+	/*
+	 * XXX This only works if b_int_device is initialized to 0!
+	 * We program the bridge to have a 1:1 mapping between devices
+	 * (slots) and intr pins.
+	 */
+	device = bridge->b_int_device;
+	device |= (pin << (pin*3));
+	bridge->b_int_device = device;
+
+        bridge->b_widget.w_tflush;                      /* Flush */
+
+        return 0;       /* Never anything pending.  */
+}
+
+/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int shutdown_bridge_irq(unsigned int irq)
+{
+	bridge_t *bridge;
+	int pin, swlevel;
+	cpuid_t cpu;
+
+	if (irq < BASE_PCI_IRQ)
+		return 0;
+
+	bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq),
+	                                     WID_FROM_PCI_IRQ(irq));
+	DBG("bridge_shutdown: irq 0x%x\n", irq);
+	pin = SLOT_FROM_PCI_IRQ(irq);
+
+	/*
+	 * map irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, irq);
+	intr_disconnect_level(cpu, swlevel);
+	LEVEL_TO_IRQ(cpu, swlevel) = -1;
+
+	bridge->b_int_enable &= ~(1 << pin);
+	bridge->b_widget.w_tflush;                      /* Flush */
+
+	return 0;       /* Never anything pending.  */
+}
+
+static inline void enable_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void disable_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void mask_and_ack_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void end_bridge_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_bridge_irq(irq);
+}
+
+static struct hw_interrupt_type bridge_irq_type = {
+	"bridge",
+	startup_bridge_irq,
+	shutdown_bridge_irq,
+	enable_bridge_irq,
+	disable_bridge_irq,
+	mask_and_ack_bridge_irq,
+	end_bridge_irq
+};
+
+void irq_debug(void)
+{
+	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+
+	printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
+	printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
+	printk("PI_INT_PEND0   = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0));
+	printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A));
+}
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	set_except_vector(0, ip27_irq);
+
+	/*
+	 * Right now the bridge irq is our kitchen sink interrupt type
+	 */
+	for (i = 0; i <= NR_IRQS; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &bridge_irq_type;
+	}
+}
+
+/*
+ * Get values that vary depending on which CPU and bit we're operating on.
+ */
+static hub_intmasks_t *intr_get_ptrs(cpuid_t cpu, int bit, int *new_bit,
+				hubreg_t **intpend_masks, int *ip)
+{
+	hub_intmasks_t *hub_intmasks;
+
+	hub_intmasks = &cpu_data[cpu].p_intmasks;
+	if (bit < N_INTPEND_BITS) {
+		*intpend_masks = hub_intmasks->intpend0_masks;
+		*ip = 0;
+		*new_bit = bit;
+	} else {
+		*intpend_masks = hub_intmasks->intpend1_masks;
+		*ip = 1;
+		*new_bit = bit - N_INTPEND_BITS;
+	}
+	return hub_intmasks;
+}
+
+int intr_connect_level(int cpu, int bit)
+{
+	int ip;
+	int slice = cputoslice(cpu);
+	volatile hubreg_t *mask_reg;
+	hubreg_t *intpend_masks;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+
+	/* Make sure it's not already pending when we connect it. */
+	REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS);
+
+	intpend_masks[0] |= (1ULL << (u64)bit);
+
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+				PI_INT_MASK_OFFSET * slice);
+	} else {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+				PI_INT_MASK_OFFSET * slice);
+	}
+	HUB_S(mask_reg, intpend_masks[0]);
+	return(0);
+}
+
+int intr_disconnect_level(int cpu, int bit)
+{
+	int ip;
+	int slice = cputoslice(cpu);
+	volatile hubreg_t *mask_reg;
+	hubreg_t *intpend_masks;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+	intpend_masks[0] &= ~(1ULL << (u64)bit);
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+				PI_INT_MASK_OFFSET * slice);
+	} else {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+				PI_INT_MASK_OFFSET * slice);
+	}
+	HUB_S(mask_reg, intpend_masks[0]);
+	return(0);
+}
+
+
+void handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Nothing, the return from intr will work for us */
+}
+
+#ifdef CONFIG_SMP
+
+void core_send_ipi(int destid, unsigned int action)
+{
+	int irq;
+
+#if (CPUS_PER_NODE == 2)
+	switch (action) {
+		case SMP_RESCHEDULE_YOURSELF:
+			irq = CPU_RESCHED_A_IRQ;
+			break;
+		case SMP_CALL_FUNCTION:
+			irq = CPU_CALL_A_IRQ;
+			break;
+		default:
+			panic("sendintr");
+	}
+	irq += cputoslice(destid);
+
+	/*
+	 * Convert the compact hub number to the NASID to get the correct
+	 * part of the address space.  Then set the interrupt bit associated
+	 * with the CPU we want to send the interrupt to.
+	 */
+	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)),
+			FAST_IRQ_TO_LEVEL(irq));
+#else
+	<< Bomb!  Must redefine this for more than 2 CPUS. >>
+#endif
+}
+
+#endif
+
+extern void smp_call_function_interrupt(void);
+
+void install_cpuintr(int cpu)
+{
+#ifdef CONFIG_SMP
+#if (CPUS_PER_NODE == 2)
+	static int done = 0;
+
+	/*
+	 * This is a hack till we have a pernode irqlist. Currently,
+	 * just have the master cpu set up the handlers for the per
+	 * cpu irqs.
+	 */
+	if (done == 0) {
+		int j;
+
+		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr,
+							0, "resched", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr,
+							0, "resched", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible");
+
+		for (j = 0; j < PERNODE_LEVELS; j++)
+			LEVEL_TO_IRQ(0, j) = -1;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) =
+							CPU_RESCHED_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) =
+							CPU_RESCHED_B_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) =
+							CPU_CALL_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) =
+							CPU_CALL_B_IRQ;
+		for (j = 1; j < MAX_COMPACT_NODES; j++)
+			memcpy(&node_level_to_irq[j][0],
+			&node_level_to_irq[0][0],
+			sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS);
+
+		done = 1;
+	}
+
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ +
+							cputoslice(cpu)));
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ +
+							cputoslice(cpu)));
+#else /* CPUS_PER_NODE */
+#error Must redefine this for more than 2 CPUS.
+#endif /* CPUS_PER_NODE */
+#endif /* CONFIG_SMP */
+}
+
+void install_tlbintr(int cpu)
+{
+#if 0
+	int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
+
+	intr_connect_level(cpu, intr_bit);
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-klconfig.c linux-2.4.20/arch/mips/sgi-ip27/ip27-klconfig.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-klconfig.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-klconfig.c	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+
+klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
+{
+	int index, j;
+
+	if (kli == (klinfo_t *)NULL) {
+		index = 0;
+	} else {
+		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
+			if (kli == KLCF_COMP(brd, j))
+				break;
+		index = j;
+		if (index == KLCF_NUM_COMPS(brd)) {
+			printk("find_component: Bad pointer: 0x%p\n", kli);
+			return (klinfo_t *)NULL;
+		}
+		index++;		/* next component */
+	}
+
+	for (; index < KLCF_NUM_COMPS(brd); index++) {
+		kli = KLCF_COMP(brd, index);
+		if (KLCF_COMP_TYPE(kli) == struct_type)
+			return kli;
+	}
+
+	/* Didn't find it. */
+	return (klinfo_t *)NULL;
+}
+
+klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
+{
+	return find_component(brd, (klinfo_t *)NULL, struct_type);
+}
+
+lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (start->brd_type == brd_type)
+			return start;
+		start = KLCF_NEXT(start);
+	}
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
+			return start;
+		start = KLCF_NEXT(start);
+	}
+
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+cnodeid_t get_cpu_cnode(cpuid_t cpu)
+{
+	return CPUID_TO_COMPACT_NODEID(cpu);
+}
+
+klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+{
+	lboard_t *brd;
+	klcpu_t *acpu;
+
+	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
+		return (klcpu_t *)NULL;
+
+	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
+		return (klcpu_t *)NULL;
+
+	do {
+		if ((acpu->cpu_info.physid) == slice)
+			return acpu;
+	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU)));
+	return (klcpu_t *)NULL;
+}
+
+klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
+{
+	nasid_t nasid;
+	int slice;
+	klcpu_t *acpu;
+	gda_t *gdap = GDA;
+	cnodeid_t cnode;
+
+	if (!(cpu < MAXCPUS)) {
+		printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
+		return NULL;
+	}
+
+	cnode = get_cpu_cnode(cpu);
+	if (cnode == INVALID_CNODEID)
+		return NULL;
+
+	if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
+		return NULL;
+
+	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+		acpu = nasid_slice_to_cpuinfo(nasid, slice);
+		if (acpu && acpu->cpu_info.virtid == cpu)
+			return acpu;
+	}
+	return NULL;
+}
+
+int get_cpu_slice(cpuid_t cpu)
+{
+	klcpu_t *acpu;
+
+	if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
+		return -1;
+	return acpu->cpu_info.physid;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-klnuma.c linux-2.4.20/arch/mips/sgi-ip27/ip27-klnuma.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-klnuma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-klnuma.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,143 @@
+/*
+ * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
+ * Copyright 2000 - 2001 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mmzone.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/smp.h>
+#include <asm/sn/types.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/mmzone.h>
+#include <asm/sn/klkernvars.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+
+extern char _end;
+static cpumask_t ktext_repmask;
+
+/*
+ * XXX - This needs to be much smarter about where it puts copies of the
+ * kernel.  For example, we should never put a copy on a headless node,
+ * and we should respect the topology of the machine.
+ */
+void __init setup_replication_mask(int maxnodes)
+{
+	static int 	numa_kernel_replication_ratio;
+	cnodeid_t	cnode;
+
+	/* Set only the master cnode's bit.  The master cnode is always 0. */
+	CPUMASK_CLRALL(ktext_repmask);
+	CPUMASK_SETB(ktext_repmask, 0);
+
+	numa_kernel_replication_ratio = 0;
+#ifdef CONFIG_REPLICATE_KTEXT
+#ifndef CONFIG_MAPPED_KERNEL
+#error Kernel replication works with mapped kernel support. No calias support.
+#endif
+	numa_kernel_replication_ratio = 1;
+#endif
+
+	for (cnode = 1; cnode < numnodes; cnode++) {
+		/* See if this node should get a copy of the kernel */
+		if (numa_kernel_replication_ratio &&
+		    !(cnode % numa_kernel_replication_ratio)) {
+
+			/* Advertise that we have a copy of the kernel */
+			CPUMASK_SETB(ktext_repmask, cnode);
+		}
+	}
+
+	/* Set up a GDA pointer to the replication mask. */
+	GDA->g_ktext_repmask = &ktext_repmask;
+}
+
+
+static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
+{
+	kern_vars_t *kvp;
+	cnodeid_t client_cnode;
+
+	client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
+
+	kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars);
+
+	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
+
+	kvp->kv_magic = KV_MAGIC;
+
+	kvp->kv_ro_nasid = server_nasid;
+	kvp->kv_rw_nasid = master_nasid;
+	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
+	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
+	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
+}
+
+/* XXX - When the BTE works, we should use it instead of this. */
+static __init void copy_kernel(nasid_t dest_nasid)
+{
+	extern char _stext, _etext;
+	unsigned long dest_kern_start, source_start, source_end, kern_size;
+
+	source_start = (unsigned long)&_stext;
+	source_end = (unsigned long)&_etext;
+	kern_size = source_end - source_start;
+
+	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
+					    dest_nasid);
+	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
+}
+
+void __init replicate_kernel_text(int maxnodes)
+{
+	cnodeid_t cnode;
+	nasid_t client_nasid;
+	nasid_t server_nasid;
+
+	server_nasid = master_nasid;
+
+	/* Record where the master node should get its kernel text */
+	set_ktext_source(master_nasid, master_nasid);
+
+	for (cnode = 1; cnode < maxnodes; cnode++) {
+		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		/* Check if this node should get a copy of the kernel */
+		if (CPUMASK_TSTB(ktext_repmask, cnode)) {
+			server_nasid = client_nasid;
+			copy_kernel(server_nasid);
+		}
+
+		/* Record where this node should get its kernel text */
+		set_ktext_source(client_nasid, server_nasid);
+	}
+}
+
+/*
+ * Return pfn of first free page of memory on a node. PROM may allocate
+ * data structures on the first couple of pages of the first slot of each
+ * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
+ */
+pfn_t node_getfirstfree(cnodeid_t cnode)
+{
+	unsigned long loadbase = CKSEG0;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+	unsigned long offset;
+
+#ifdef CONFIG_MAPPED_KERNEL
+	loadbase = CKSSEG + 16777216;
+#endif
+	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
+	if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode)))
+		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
+	else
+		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
+								PAGE_SHIFT);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-memory.c linux-2.4.20/arch/mips/sgi-ip27/ip27-memory.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-memory.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-memory.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,344 @@
+/*
+ * 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) 2000 by Ralf Baechle
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/mmzone.h>
+
+/* ip27-klnuma.c   */
+extern pfn_t node_getfirstfree(cnodeid_t cnode);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define SLOT_IGNORED	0xffff
+
+short slot_lastfilled_cache[MAX_COMPACT_NODES];
+unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
+static pfn_t numpages;
+
+plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
+bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
+
+int numa_debug(void)
+{
+	printk("NUMA debug\n");
+	*(int *)0 = 0;
+	return(0);
+}
+
+/*
+ * Return the number of pages of memory provided by the given slot
+ * on the specified node.
+ */
+pfn_t slot_getsize(cnodeid_t node, int slot)
+{
+	return (pfn_t) slot_psize_cache[node][slot];
+}
+
+/*
+ * Return highest slot filled
+ */
+int node_getlastslot(cnodeid_t node)
+{
+	return (int) slot_lastfilled_cache[node];
+}
+
+/*
+ * Return the pfn of the last free page of memory on a node.
+ */
+pfn_t node_getmaxclick(cnodeid_t node)
+{
+	pfn_t	slot_psize;
+	int	slot;
+
+	/*
+	 * Start at the top slot. When we find a slot with memory in it,
+	 * that's the winner.
+	 */
+	for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) {
+		if ((slot_psize = slot_getsize(node, slot))) {
+			if (slot_psize == SLOT_IGNORED)
+				continue;
+			/* Return the basepfn + the slot size, minus 1. */
+			return slot_getbasepfn(node, slot) + slot_psize - 1;
+		}
+	}
+
+	/*
+	 * If there's no memory on the node, return 0. This is likely
+	 * to cause problems.
+	 */
+	return (pfn_t)0;
+}
+
+static pfn_t slot_psize_compute(cnodeid_t node, int slot)
+{
+	nasid_t nasid;
+	lboard_t *brd;
+	klmembnk_t *banks;
+	unsigned long size;
+
+	nasid = COMPACT_TO_NASID_NODEID(node);
+	/* Find the node board */
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	if (!brd)
+		return 0;
+
+	/* Get the memory bank structure */
+	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
+	if (!banks)
+		return 0;
+
+	/* Size in _Megabytes_ */
+	size = (unsigned long)banks->membnk_bnksz[slot/4];
+
+	/* hack for 128 dimm banks */
+	if (size <= 128) {
+		if (slot%4 == 0) {
+			size <<= 20;		/* size in bytes */
+			return(size >> PAGE_SHIFT);
+		} else {
+			return 0;
+		}
+	} else {
+		size /= 4;
+		size <<= 20;
+		return(size >> PAGE_SHIFT);
+	}
+}
+
+pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
+{
+	cnodeid_t node;
+	int slot, numslots;
+	pfn_t num_pages = 0, slot_psize;
+	pfn_t slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
+	int ignore;
+
+	for (node = 0; node < numnodes; node++) {
+		numslots = node_getnumslots(node);
+		ignore = nodebytes = 0;
+		for (slot = 0; slot < numslots; slot++) {
+			slot_psize = slot_psize_compute(node, slot);
+			if (slot == 0) slot0sz = slot_psize;
+			/*
+			 * We need to refine the hack when we have replicated
+			 * kernel text.
+			 */
+			nodebytes += SLOT_SIZE;
+			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
+						(slot0sz << PAGE_SHIFT))
+				ignore = 1;
+			if (ignore && slot_psize) {
+				printk("Ignoring slot %d onwards on node %d\n",
+								slot, node);
+				slot_psize_cache[node][slot] = SLOT_IGNORED;
+				slot = numslots;
+				continue;
+			}
+			num_pages += slot_psize;
+			slot_psize_cache[node][slot] =
+					(unsigned short) slot_psize;
+			if (slot_psize)
+				slot_lastfilled_cache[node] = slot;
+		}
+	}
+	if (maxpmem)
+		return((maxpmem > num_pages) ? num_pages : maxpmem);
+	else
+		return num_pages;
+}
+
+/*
+ * Currently, the intranode memory hole support assumes that each slot
+ * contains at least 32 MBytes of memory. We assume all bootmem data
+ * fits on the first slot.
+ */
+void __init prom_meminit(void)
+{
+	extern void mlreset(void);
+	cnodeid_t node;
+	pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn;
+	unsigned long bootmap_size;
+	int node_datasz;
+
+	node_datasz = PFN_UP(sizeof(plat_pg_data_t));
+	mlreset();
+	numpages = szmem(0, 0);
+	for (node = (numnodes - 1); node >= 0; node--) {
+		slot_firstpfn = slot_getbasepfn(node, 0);
+		slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
+		slot_freepfn = node_getfirstfree(node);
+		/* Foll line hack for non discontigmem; remove once discontigmem
+		 * becomes the default. */
+		max_low_pfn = (slot_lastpfn - slot_firstpfn);
+
+		/*
+		 * Allocate the node data structure on the node first.
+		 */
+		plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \
+							<< PAGE_SHIFT));
+		NODE_DATA(node)->bdata = plat_node_bdata + node;
+		slot_freepfn += node_datasz;
+	  	bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
+						slot_firstpfn, slot_lastpfn);
+		free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+				(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
+		reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+		  ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
+	}
+	printk("Total memory probed : 0x%lx pages\n", numpages);
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+        return 1;
+}
+
+void __init
+prom_free_prom_memory (void)
+{
+	/* We got nothing to free here ...  */
+}
+
+#ifdef CONFIG_DISCONTIGMEM
+
+static pfn_t pagenr = 0;
+
+void __init paging_init(void)
+{
+	pmd_t *pmd = kpmdtbl;
+	pte_t *pte = kptbl;
+
+	cnodeid_t node;
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	int i;
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
+
+	/* This is for vmalloc  */
+	memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER);
+	memset((void *)kpmdtbl, 0, PAGE_SIZE);
+	pgd_set(swapper_pg_dir, kpmdtbl);
+	for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+		pmd_val(*pmd) = (unsigned long)pte;
+
+	for (node = 0; node < numnodes; node++) {
+		pfn_t start_pfn = slot_getbasepfn(node, 0);
+		pfn_t end_pfn = node_getmaxclick(node);
+
+		zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
+		free_area_init_node(node, NODE_DATA(node), 0, zones_size,
+						start_pfn << PAGE_SHIFT, 0);
+		if ((PLAT_NODE_DATA_STARTNR(node) +
+					PLAT_NODE_DATA_SIZE(node)) > pagenr)
+			pagenr = PLAT_NODE_DATA_STARTNR(node) +
+					PLAT_NODE_DATA_SIZE(node);
+	}
+}
+
+void __init mem_init(void)
+{
+	extern char _stext, _etext, _fdata, _edata;
+	extern char __init_begin, __init_end;
+	extern unsigned long totalram_pages;
+	extern unsigned long setup_zero_pages(void);
+	cnodeid_t nid;
+	unsigned long tmp;
+	unsigned long codesize, datasize, initsize;
+	int slot, numslots;
+	struct page *pg, *pslot;
+	pfn_t pgnr;
+
+	num_physpages = numpages;	/* memory already sized by szmem */
+	max_mapnr = pagenr;		/* already found during paging_init */
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+
+	for (nid = 0; nid < numnodes; nid++) {
+
+		/*
+		 * Hack till free_area_init_core() zeroes free_pages
+		 */
+		for (tmp = 0; tmp < MAX_NR_ZONES; tmp++)
+			PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0;
+		/*
+	 	 * This will free up the bootmem, ie, slot 0 memory.
+	 	 */
+		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
+
+		/*
+		 * We need to manually do the other slots.
+		 */
+		pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
+		pgnr = PLAT_NODE_DATA_STARTNR(nid) + slot_getsize(nid, 0);
+		numslots = node_getlastslot(nid);
+		for (slot = 1; slot <= numslots; slot++) {
+			pslot = NODE_DATA(nid)->node_mem_map +
+			   slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
+
+			/*
+			 * Mark holes in previous slot. May also want to
+			 * free up the pages that hold the memmap entries.
+			 */
+			while (pg < pslot) {
+				pg++; pgnr++;
+			}
+
+			/*
+			 * Free valid memory in current slot.
+			 */
+			pslot += slot_getsize(nid, slot);
+			while (pg < pslot) {
+				if (!page_is_ram(pgnr))
+					continue;
+				ClearPageReserved(pg);
+				atomic_set(&pg->count, 1);
+				__free_page(pg);
+				totalram_pages++;
+				pg++; pgnr++;
+			}
+		}
+	}
+
+	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	tmp = (unsigned long) nr_free_pages();
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+		"%ldk data, %ldk init)\n",
+		tmp << (PAGE_SHIFT-10),
+		num_physpages << (PAGE_SHIFT-10),
+		codesize >> 10,
+		(num_physpages - tmp) << (PAGE_SHIFT-10),
+		datasize >> 10,
+		initsize >> 10);
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-nmi.c linux-2.4.20/arch/mips/sgi-ip27/ip27-nmi.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-nmi.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-nmi.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,168 @@
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/atomic.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/nmi.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+
+#if 0
+#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)
+#else
+#define NODE_NUM_CPUS(n)	CPUS_PER_NODE
+#endif
+
+#define CNODEID_NONE (cnodeid_t)-1
+#define enter_panic_mode()	spin_lock(&nmi_lock)
+
+typedef unsigned long machreg_t;
+
+spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Lets see what else we need to do here. Set up sp, gp?
+ */
+void nmi_dump(void)
+{
+	void cont_nmi_dump(void);
+
+	cont_nmi_dump();
+}
+
+void install_cpu_nmi_handler(int slice)
+{
+	nmi_t *nmi_addr;
+
+	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
+	if (nmi_addr->call_addr)
+		return;
+	nmi_addr->magic = NMI_MAGIC;
+	nmi_addr->call_addr = (void *)nmi_dump;
+	nmi_addr->call_addr_c =
+		(void *)(~((unsigned long)(nmi_addr->call_addr)));
+	nmi_addr->call_parm = 0;
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+
+void
+nmi_cpu_eframe_save(nasid_t nasid,
+		    int	    slice)
+{
+	int 		i, numberof_nmi_cpu_regs;
+	machreg_t	*prom_format;
+
+	/* Get the total number of registers being saved by the prom */
+	numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t);
+
+	/* Get the pointer to the current cpu's register set. */
+	prom_format =
+	    (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
+			  slice * IP27_NMI_KREGS_CPU_SIZE);
+
+	printk("NMI nasid %d: slice %d\n", nasid, slice);
+	for (i = 0; i < numberof_nmi_cpu_regs; i++)
+		printk("0x%lx  ", prom_format[i]);
+	printk("\n\n");
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+void
+nmi_node_eframe_save(cnodeid_t  cnode)
+{
+	int		cpu;
+	nasid_t		nasid;
+
+	/* Make sure that we have a valid node */
+	if (cnode == CNODEID_NONE)
+		return;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+	if (nasid == INVALID_NASID)
+		return;
+
+	/* Save the registers into eframe for each cpu */
+	for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++)
+		nmi_cpu_eframe_save(nasid, cpu);
+}
+
+/*
+ * Save the nmi cpu registers for all cpus in the system.
+ */
+void
+nmi_eframes_save(void)
+{
+	cnodeid_t	cnode;
+
+	for(cnode = 0 ; cnode < numnodes; cnode++)
+		nmi_node_eframe_save(cnode);
+}
+
+void
+cont_nmi_dump(void)
+{
+#ifndef REAL_NMI_SIGNAL
+	static atomic_t nmied_cpus = ATOMIC_INIT(0);
+
+	atomic_inc(&nmied_cpus);
+#endif
+	/*
+	 * Use enter_panic_mode to allow only 1 cpu to proceed
+	 */
+	enter_panic_mode();
+
+#ifdef REAL_NMI_SIGNAL
+	/*
+	 * Wait up to 15 seconds for the other cpus to respond to the NMI.
+	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
+	 * This is for 2 reasons:
+	 *	- sometimes a MMSC fail to NMI all cpus.
+	 *	- on 512p SN0 system, the MMSC will only send NMIs to
+	 *	  half the cpus. Unfortunately, we dont know which cpus may be
+	 *	  NMIed - it depends on how the site chooses to configure.
+	 *
+	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
+	 * send NMIs to all cpus on a 256p system.
+	 */
+	for (i=0; i < 1500; i++) {
+		for (node=0; node < numnodes; node++)
+			if (NODEPDA(node)->dump_count == 0)
+				break;
+		if (node == numnodes)
+			break;
+		if (i == 1000) {
+			for (node=0; node < numnodes; node++)
+				if (NODEPDA(node)->dump_count == 0) {
+					cpu = CNODE_TO_CPU_BASE(node);
+					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
+						CPUMASK_SETB(nmied_cpus, cpu);
+						/*
+						 * cputonasid, cputoslice
+						 * needs kernel cpuid
+						 */
+						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
+					}
+				}
+
+		}
+		udelay(10000);
+	}
+#else
+	while (atomic_read(&nmied_cpus) != smp_num_cpus);
+#endif
+
+	/*
+	 * Save the nmi cpu registers for all cpu in the eframe format.
+	 */
+	nmi_eframes_save();
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-pci.c linux-2.4.20/arch/mips/sgi-ip27/ip27-pci.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-pci.c	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,429 @@
+/*
+ * 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) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/sn/arch.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * Max #PCI busses we can handle; ie, max #PCI bridges.
+ */
+#define MAX_PCI_BUSSES		40
+
+/*
+ * Max #PCI devices (like scsi controllers) we handle on a bus.
+ */
+#define MAX_DEVICES_PER_PCIBUS	8
+
+/*
+ * No locking needed until PCI initialization is done parallely.
+ */
+int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS];
+int lastirq = BASE_PCI_IRQ;
+
+/*
+ * Translate from irq to software PCI bus number and PCI slot.
+ */
+int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ */
+#define CF0_READ_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge;                                               \
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+	unsigned int bus_id = (unsigned) dev->bus->number;              \
+									\
+	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
+                                             bus_to_wid[bus_id]);       \
+                                                                        \
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) {	\
+		*value = 0;						\
+		return PCIBIOS_SUCCESSFUL;				\
+	}								\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	*value = (cf >> __bit) & (mask);				\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge;                                               \
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+	unsigned int bus_id = (unsigned) dev->bus->number;              \
+									\
+	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
+                                             bus_to_wid[bus_id]);       \
+                                                                        \
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48)))	\
+		return PCIBIOS_SUCCESSFUL;				\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	cf &= (~mask);							\
+	cf |= (value);							\
+	put_dbe(cf, addr);						\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+
+static struct pci_ops bridge_pci_ops = {
+	pci_conf0_read_config_byte,
+	pci_conf0_read_config_word,
+	pci_conf0_read_config_dword,
+	pci_conf0_write_config_byte,
+	pci_conf0_write_config_word,
+	pci_conf0_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+	struct pci_ops *ops = &bridge_pci_ops;
+	int	i;
+
+	ioport_resource.end = ~0UL;
+	iomem_resource.end = ~0UL;
+
+	for (i=0; i<num_bridges; i++) {
+		printk("PCI: Probing PCI hardware on host bus %2d.\n", i);
+		pci_scan_bus(i, ops, NULL);
+	}
+}
+
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+static u8 __init
+pci_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	u8 pin = *pinp;
+
+	while (dev->bus->self) {	/* Move up the chain of bridges. */
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		dev = dev->bus->self;
+	}
+	*pinp = pin;
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * All observed requests have pin == 1. We could have a global here, that
+ * gets incremented and returned every time - unfortunately, pci_map_irq
+ * may be called on the same device over and over, and need to return the
+ * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
+ *
+ * A given PCI device, in general, should be able to intr any of the cpus
+ * on any one of the hubs connected to its xbow.
+ */
+static int __init
+pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if ((dev->bus->number >= MAX_PCI_BUSSES)
+	    || (pin != 1)
+	    || (slot >= MAX_DEVICES_PER_PCIBUS))
+		panic("Increase supported PCI busses %d,%d,%d",
+		      dev->bus->number, slot, pin);
+
+	/*
+	 * Already assigned? Then return previously assigned value ...
+	 */
+	if (irqstore[dev->bus->number][slot])
+		return irqstore[dev->bus->number][slot];
+
+	irq_to_bus[lastirq] = dev->bus->number;
+	irq_to_slot[lastirq] = slot;
+	irqstore[dev->bus->number][slot] = lastirq;
+	lastirq++;
+	return lastirq - 1;
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+                        struct resource *res, int resource)
+{
+	unsigned long where, size;
+	u32 reg;
+
+	where = PCI_BASE_ADDRESS_0 + (resource * 4);
+	size = res->end - res->start;
+	pci_read_config_dword(dev, where, &reg);
+	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+	pci_write_config_dword(dev, where, reg);
+}
+
+void __init
+pcibios_fixup_bus(struct pci_bus *b)
+{
+	pci_fixup_irqs(pci_swizzle, pci_map_irq);
+}
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+                          struct pbus_set_ranges_data * ranges)
+{
+	ranges->io_start  -= bus->resource[0]->start;
+	ranges->io_end    -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end   -= bus->resource[1]->start;
+}
+
+int __init
+pcibios_enable_device(struct pci_dev *dev)
+{
+	/* Not needed, since we enable all devices at startup.  */
+	return 0;
+}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
+{
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+/*
+ * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
+ * to find the slot number in sense of the bridge device register.
+ * XXX This also means multiple devices might rely on conflicting bridge
+ * settings.
+ */
+
+static void __init
+pci_disable_swapping(struct pci_dev *dev)
+{
+	unsigned int bus_id = (unsigned) dev->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+	                                               bus_to_wid[bus_id]);
+	int		slot = PCI_SLOT(dev->devfn);
+
+	/* Turn off byte swapping */
+	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;		/* Flush */
+}
+
+static void __init
+pci_enable_swapping(struct pci_dev *dev)
+{
+	unsigned int bus_id = (unsigned) dev->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+	                                               bus_to_wid[bus_id]);
+	int		slot = PCI_SLOT(dev->devfn);
+
+	/* Turn on byte swapping */
+	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;		/* Flush */
+}
+
+static void __init
+pci_fixup_ioc3(struct pci_dev *d)
+{
+	unsigned long bus_id = (unsigned) d->bus->number;
+
+	printk("PCI: Fixing base addresses for IOC3 device %s\n", d->slot_name);
+
+	d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]);
+	d->resource[0].end   |= NODE_OFFSET(bus_to_nid[bus_id]);
+
+	pci_disable_swapping(d);
+}
+
+static void __init
+pci_fixup_isp1020(struct pci_dev *d)
+{
+	unsigned short command;
+
+	d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32);
+	printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name);
+
+	/*
+	 * Configure device to allow bus mastering, i/o and memory mapping.
+	 * Older qlogicisp driver expects to have the IO space enable
+	 * bit set. Things stop working if we program the controllers as not
+	 * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
+	 */
+
+	pci_set_master(d);
+	pci_read_config_word(d, PCI_COMMAND, &command);
+	command |= PCI_COMMAND_MEMORY;
+	command |= PCI_COMMAND_IO;
+	pci_write_config_word(d, PCI_COMMAND, command);
+	d->resource[1].flags |= 1;
+
+	pci_enable_swapping(d);
+}
+
+static void __init
+pci_fixup_isp2x00(struct pci_dev *d)
+{
+	unsigned int bus_id = (unsigned) d->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+				     bus_to_wid[bus_id]);
+	bridgereg_t 	devreg;
+	int		i;
+	int		slot = PCI_SLOT(d->devfn);
+	unsigned int	start;
+	unsigned short command;
+
+	printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name);
+
+	/* set the resource struct for this device */
+	start = (u32) (u64)bridge;	/* yes, we want to lose the upper 32 bits here */
+	start |= BRIDGE_DEVIO(slot);
+
+	d->resource[0].start = start;
+	d->resource[0].end = d->resource[0].start + 0xff;
+	d->resource[0].flags = IORESOURCE_IO;
+
+	d->resource[1].start = start;
+	d->resource[1].end = d->resource[0].start + 0xfff;
+	d->resource[1].flags = IORESOURCE_MEM;
+
+	/*
+	 * set the bridge device(x) reg for this device
+	 */
+	devreg = bridge->b_device[slot].reg;
+	/* point device(x) to it appropriate small window */
+	devreg &= ~BRIDGE_DEV_OFF_MASK;
+	devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK;
+	bridge->b_device[slot].reg = devreg;
+
+	pci_enable_swapping(d);
+
+	/* set card's base addr reg */
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001);
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000);
+	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000);
+
+	/* I got these from booting irix on system...*/
+	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001);
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000);
+	pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS,   0x10200000);
+
+	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, start);
+	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000));
+
+	/* set cache line size */
+	pci_conf0_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080);
+
+	/* set pci bus timeout */
+	bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3);
+	bridge->b_wid_tflush;
+	printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout);
+
+	/* set host error field */
+	bridge->b_int_host_err = 0x44;
+	bridge->b_wid_tflush;
+
+	bridge->b_wid_tflush;   	/* wait until Bridge PIO complete */
+	for (i=0; i<8; i++)
+		printk("PCI: device(%d)= 0x%x\n",i,bridge->b_device[i].reg);
+
+	/* configure device to allow bus mastering, i/o and memory mapping */
+	pci_set_master(d);
+	pci_read_config_word(d, PCI_COMMAND, &command);
+	command |= PCI_COMMAND_MEMORY;
+	command |= PCI_COMMAND_IO;
+	pci_write_config_word(d, PCI_COMMAND, command);
+	/*d->resource[1].flags |= 1;*/
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+	  pci_fixup_ioc3 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
+	  pci_fixup_isp1020 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
+	  pci_fixup_isp2x00 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
+	  pci_fixup_isp2x00 },
+	{ 0 }
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-reset.c linux-2.4.20/arch/mips/sgi-ip27/ip27-reset.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-reset.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ *
+ * Reset an IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/mmzone.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/sn0/hub.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+#define noreturn while(1);				/* Silence gcc.  */
+
+/* XXX How to pass the reboot command to the firmware??? */
+static void ip27_machine_restart(char *command)
+{
+#if 0
+	int i;
+#endif
+
+	printk("Reboot started from CPU %d\n", smp_processor_id());
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+#if 0
+	for (i = 0; i < numnodes; i++)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_REBOOT);
+#else
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+#endif
+	noreturn;
+}
+
+static void ip27_machine_halt(void)
+{
+	int i;
+
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	for (i = 0; i < numnodes; i++)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_RESTART);
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+	noreturn;
+}
+
+static void ip27_machine_power_off(void)
+{
+	/* To do ...  */
+	noreturn;
+}
+
+void ip27_reboot_setup(void)
+{
+	_machine_restart = ip27_machine_restart;
+	_machine_halt = ip27_machine_halt;
+	_machine_power_off = ip27_machine_power_off;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-rtc.c linux-2.4.20/arch/mips/sgi-ip27/ip27-rtc.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-rtc.c	2002-10-04 00:41:19.000000000 +0000
@@ -0,0 +1,334 @@
+/*
+ *	Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
+ *
+ *	Real Time Clock interface for Linux
+ *
+ *	TODO: Implement periodic interrupts.
+ *
+ *	Copyright (C) 2000 Silicon Graphics, Inc.
+ *	Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ *
+ *	Based on code written by Paul Gortmaker.
+ *
+ *	This driver allows use of the real time clock (built into
+ *	nearly all computers) from user space. It exports the /dev/rtc
+ *	interface supporting various ioctl() and also the /proc/rtc
+ *	pseudo-file for status information.
+ *
+ *	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.
+ *
+ */
+
+#define RTC_VERSION		"1.09b"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+
+#include <asm/m48t35.h>
+#include <asm/sn/ioc3.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+static int rtc_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg);
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                         int count, int *eof, void *data);
+
+static void get_rtc_time(struct rtc_time *rtc_tm);
+
+/*
+ *	Bits in rtc_status. (6 bits of room for future expansion)
+ */
+
+#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
+#define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
+
+static unsigned char rtc_status;	/* bitmapped status byte.	*/
+static spinlock_t rtc_status_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long rtc_freq;	/* Current periodic IRQ rate	*/
+static struct m48t35_rtc *rtc;
+
+/*
+ *	If this driver ever becomes modularised, it will be really nice
+ *	to make the epoch retain its value across module reload...
+ */
+
+static unsigned long epoch = 1970;	/* year corresponding to 0x00	*/
+
+static const unsigned char days_in_mo[] =
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+
+	struct rtc_time wtime;
+
+	switch (cmd) {
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+	{
+		get_rtc_time(&wtime);
+		break;
+	}
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		struct rtc_time rtc_tm;
+		unsigned char mon, day, hrs, min, sec, leap_yr;
+		unsigned int yrs;
+		unsigned long flags;
+
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
+				   sizeof(struct rtc_time)))
+			return -EFAULT;
+
+		yrs = rtc_tm.tm_year + 1900;
+		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
+		day = rtc_tm.tm_mday;
+		hrs = rtc_tm.tm_hour;
+		min = rtc_tm.tm_min;
+		sec = rtc_tm.tm_sec;
+
+		if (yrs < 1970)
+			return -EINVAL;
+
+		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+		if ((mon > 12) || (day == 0))
+			return -EINVAL;
+
+		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+			return -EINVAL;
+
+		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+			return -EINVAL;
+
+		if ((yrs -= epoch) > 255)    /* They are unsigned */
+			return -EINVAL;
+
+		save_flags(flags);
+		cli();
+		if (yrs > 169) {
+			restore_flags(flags);
+			return -EINVAL;
+		}
+		if (yrs >= 100)
+			yrs -= 100;
+
+		BIN_TO_BCD(sec);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(hrs);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(mon);
+		BIN_TO_BCD(yrs);
+
+		rtc->control &= ~M48T35_RTC_SET;
+		rtc->year = yrs;
+		rtc->month = mon;
+		rtc->date = day;
+		rtc->hour = hrs;
+		rtc->min = min;
+		rtc->sec = sec;
+		rtc->control &= ~M48T35_RTC_SET;
+
+		restore_flags(flags);
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	spin_lock(rtc_status_lock);
+
+	if (rtc_status & RTC_IS_OPEN) {
+		spin_unlock(rtc_status_lock);
+		return -EBUSY;
+	}
+
+	rtc_status |= RTC_IS_OPEN;
+	spin_unlock(rtc_status_lock);
+
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	/*
+	 * Turn off all interrupts once the device is no longer
+	 * in use, and clear the data.
+	 */
+
+	spin_lock(rtc_status_lock);
+	rtc_status &= ~RTC_IS_OPEN;
+	spin_unlock(rtc_status_lock);
+
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		rtc_ioctl,
+	open:		rtc_open,
+	release:	rtc_release,
+};
+
+static struct miscdevice rtc_dev=
+{
+	RTC_MINOR,
+	"rtc",
+	&rtc_fops
+};
+
+static int __init rtc_init(void)
+{
+	unsigned long flags;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)
+	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+
+	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
+	if (misc_register(&rtc_dev))
+		return -ENODEV;
+	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
+
+	save_flags(flags);
+	cli();
+	restore_flags(flags);
+	rtc_freq = 1024;
+	return 0;
+}
+
+static void __exit rtc_exit (void)
+{
+	/* interrupts and timer disabled at this point by rtc_release */
+
+	remove_proc_entry ("rtc", NULL);
+	misc_deregister(&rtc_dev);
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+EXPORT_NO_SYMBOLS;
+
+/*
+ *	Info exported via "/proc/rtc".
+ */
+
+static int rtc_get_status(char *buf)
+{
+	char *p;
+	struct rtc_time tm;
+
+	/*
+	 * Just emulate the standard /proc/rtc
+	 */
+
+	p = buf;
+
+	get_rtc_time(&tm);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n"
+	 	     "rtc_epoch\t: %04lu\n"
+		     "24hr\t\t: yes\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
+
+	return  p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+        int len = rtc_get_status(page);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+static void get_rtc_time(struct rtc_time *rtc_tm)
+{
+
+	unsigned long flags;
+
+	/*
+	 * Do we need to wait for the last update to finish?
+	 */
+
+	/*
+	 * Only the values that we read from the RTC are set. We leave
+	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
+	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+	 * by the RTC when initially set to a non-zero value.
+	 */
+	save_flags(flags);
+	cli();
+        rtc->control |= M48T35_RTC_READ;
+	rtc_tm->tm_sec = rtc->sec;
+	rtc_tm->tm_min = rtc->min;
+	rtc_tm->tm_hour = rtc->hour;
+	rtc_tm->tm_mday = rtc->date;
+	rtc_tm->tm_mon = rtc->month;
+	rtc_tm->tm_year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+	restore_flags(flags);
+
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	/*
+	 * Account for differences between how the RTC uses the values
+	 * and how they are defined in a struct rtc_time;
+	 */
+	if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
+		rtc_tm->tm_year += 100;
+
+	rtc_tm->tm_mon--;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-setup.c linux-2.4.20/arch/mips/sgi-ip27/ip27-setup.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-setup.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,314 @@
+/*
+ * 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.
+ *
+ * SGI IP27 specific setup.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/io.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn_private.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/sn0/ip27.h>
+
+/* Check against user dumbness.  */
+#ifdef CONFIG_VT
+#error CONFIG_VT not allowed for IP27.
+#endif
+
+#undef DEBUG_SETUP
+#ifdef DEBUG_SETUP
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+	                 >> NSRI_NODEID_SHFT);
+}
+
+/* Extracted from the IOC3 meta driver.  FIXME.  */
+static inline void ioc3_sio_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+        long loops;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
+	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
+	ioc3->sio_iec = ~0;
+	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
+
+	loops=1000000; while(loops--);
+	ioc3->sregs.uarta.iu_fcr = 0;
+	ioc3->sregs.uartb.iu_fcr = 0;
+	loops=1000000; while(loops--);
+}
+
+static inline void ioc3_eth_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->eier = 0;
+}
+
+/* Try to catch kernel missconfigurations and give user an indication what
+   option to select.  */
+static void __init verify_mode(void)
+{
+	int n_mode;
+
+	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
+	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
+#ifdef CONFIG_SGI_SN0_N_MODE
+	if (!n_mode)
+		panic("Kernel compiled for M mode.");
+#else
+	if (n_mode)
+		panic("Kernel compiled for N mode.");
+#endif
+}
+
+#define XBOW_WIDGET_PART_NUM    0x0
+#define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */
+#define BASE_XBOW_PORT  	8     /* Lowest external port */
+
+unsigned int bus_to_cpu[256];
+unsigned long bus_to_baddr[256];
+
+void __init pcibr_setup(cnodeid_t nid)
+{
+	int 			i, start, num;
+	unsigned long		masterwid;
+	bridge_t 		*bridge;
+	volatile u64 		hubreg;
+	nasid_t	 		nasid, masternasid;
+	xwidget_part_num_t	partnum;
+	widgetreg_t 		widget_id;
+	static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
+
+	/*
+	 * If the master is doing this for headless node, nothing to do.
+	 * This is because currently we require at least one of the hubs
+	 * (master hub) connected to the xbow to have at least one enabled
+	 * cpu to receive intrs. Else we need an array bus_to_intrnasid[]
+	 * that bridge_startup() needs to use to target intrs. All dma is
+	 * routed thru the widget of the master hub. The master hub wid
+	 * is selectable by WIDGET_A below.
+	 */
+	if (nid != get_compact_nodeid())
+		return;
+	/*
+	 * find what's on our local node
+	 */
+	spin_lock(&pcibr_setup_lock);
+	start = num_bridges;		/* Remember where we start from */
+	nasid = COMPACT_TO_NASID_NODEID(nid);
+	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (hubreg & IIO_LLP_CSR_IS_UP) {
+		/* link is up */
+		widget_id = *(volatile widgetreg_t *)
+                        (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
+		partnum = XWIDGET_PART_NUM(widget_id);
+		printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
+					smp_processor_id(), nasid, partnum);
+		if (partnum == BRIDGE_WIDGET_PART_NUM) {
+			/*
+			 * found direct connected bridge so must be Origin200
+			 */
+			printk("...is bridge\n");
+			num_bridges = 1;
+        		bus_to_wid[0] = 0x8;
+			bus_to_nid[0] = 0;
+			masterwid = 0xa;
+			bus_to_baddr[0] = 0xa100000000000000UL;
+		} else if (partnum == XBOW_WIDGET_PART_NUM) {
+			lboard_t *brd;
+			klxbow_t *xbow_p;
+			/*
+			 * found xbow, so may have multiple bridges
+			 * need to probe xbow
+			 */
+			printk("...is xbow\n");
+
+			if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
+                                   KLTYPE_MIDPLANE8)) == NULL)
+				printk("argh\n");
+			else
+				printk("brd = 0x%lx\n", (unsigned long) brd);
+			if ((xbow_p = (klxbow_t *)
+			     find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
+				printk("argh\n");
+			else {
+			   /*
+			    * Okay, here's a xbow. Lets arbitrate and find
+			    * out if we should initialize it. Set enabled
+			    * hub connected at highest or lowest widget as
+			    * master.
+			    */
+#ifdef WIDGET_A
+			   i = HUB_WIDGET_ID_MAX + 1;
+			   do {
+				i--;
+			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#else
+			   i = HUB_WIDGET_ID_MIN - 1;
+			   do {
+				i++;
+			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#endif
+			   masterwid = i;
+			   masternasid = XBOW_PORT_NASID(xbow_p, i);
+			   if (nasid == masternasid)
+			   for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
+				if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
+					continue;
+				if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
+				   widget_id = *(volatile widgetreg_t *)
+                        		   (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
+				   partnum = XWIDGET_PART_NUM(widget_id);
+				   if (partnum == BRIDGE_WIDGET_PART_NUM) {
+					printk("widget 0x%x is a bridge\n", i);
+					bus_to_wid[num_bridges] = i;
+					bus_to_nid[num_bridges] = nasid;
+					bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */
+					num_bridges++;
+				   }
+				}
+			   }
+			}
+		} else if (partnum == XXBOW_WIDGET_PART_NUM) {
+			/*
+			 * found xbridge, assume ibrick for now
+			 */
+			printk("...is xbridge\n");
+        		bus_to_wid[0] = 0xb;
+        		bus_to_wid[1] = 0xe;
+        		bus_to_wid[2] = 0xf;
+
+        		bus_to_nid[0] = 0;
+        		bus_to_nid[1] = 0;
+        		bus_to_nid[2] = 0;
+
+			bus_to_baddr[0] = 0xa100000000000000UL;
+			bus_to_baddr[1] = 0xa100000000000000UL;
+			bus_to_baddr[2] = 0xa100000000000000UL;
+			masterwid = 0xa;
+			num_bridges = 3;
+		}
+	}
+	num = num_bridges - start;
+	spin_unlock(&pcibr_setup_lock);
+	/*
+         * set bridge registers
+         */
+	for (i = start; i < (start + num); i++) {
+
+		DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",
+                        i, i, bus_to_wid[i], i, bus_to_nid[i]);
+
+		bus_to_cpu[i] = smp_processor_id();
+		/*
+		 * point to this bridge
+		 */
+		bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
+		/*
+	 	 * Clear all pending interrupts.
+	 	 */
+		bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
+		/*
+	 	 * Until otherwise set up, assume all interrupts are from slot 0
+	 	 */
+		bridge->b_int_device = (u32) 0x0;
+		/*
+	 	 * swap pio's to pci mem and io space (big windows)
+	 	 */
+		bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
+		bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
+
+		/*
+		 * Hmm...  IRIX sets additional bits in the address which
+		 * are documented as reserved in the bridge docs.
+		 */
+		bridge->b_int_mode = 0x0;		/* Don't clear ints */
+		bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
+		bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
+		bridge->b_dir_map = (masterwid << 20);	/* DMA */
+		bridge->b_int_enable = 0;
+
+		bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
+	}
+}
+
+extern void ip27_setup_console(void);
+extern void ip27_time_init(void);
+
+void __init ip27_setup(void)
+{
+	nasid_t nid;
+	hubreg_t p, e;
+
+	ip27_setup_console();
+
+	num_bridges = 0;
+	/*
+	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
+	 */
+	DBG("ip27_setup(): Entered.\n");
+	nid = get_nasid();
+	printk("IP27: Running on node %d.\n", nid);
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+	printk("Node %d has %s primary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+	printk("Node %d has %s secondary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	verify_mode();
+	ioc3_sio_init();
+	ioc3_eth_init();
+	per_cpu_init();
+
+	mips_io_port_base = IO_BASE;
+	board_time_init = ip27_time_init;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip27/ip27-timer.c linux-2.4.20/arch/mips/sgi-ip27/ip27-timer.c
--- linux-2.4.19/arch/mips/sgi-ip27/ip27-timer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip27/ip27-timer.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,239 @@
+/*
+ * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/sn/ioc3.h>
+#include <asm/m48t35.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE		800
+#define NSEC_PER_SEC		1000000000
+#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
+
+static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
+static long last_rtc_update;		/* Last time the rtc clock got updated */
+
+extern rwlock_t xtime_lock;
+extern volatile unsigned long wall_jiffies;
+
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	cmos_minutes = rtc->min;
+	BCD_TO_BIN(cmos_minutes);
+	rtc->control &= ~M48T35_RTC_READ;
+
+	/*
+	 * 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) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		rtc->control |= M48T35_RTC_SET;
+		rtc->sec = real_seconds;
+		rtc->min = real_minutes;
+		rtc->control &= ~M48T35_RTC_SET;
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	return retval;
+}
+
+void rt_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int cpuA = ((cputoslice(cpu)) == 0);
+	int irq = 9;				/* XXX Assign number */
+
+	irq_enter(cpu, irq);
+	write_lock(&xtime_lock);
+
+again:
+	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
+	ct_cur[cpu] += CYCLES_PER_JIFFY;
+	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
+
+	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
+		goto again;
+
+	kstat.irqs[cpu][irq]++;		/* kstat only for bootcpu? */
+
+	if (cpu == 0)
+		do_timer(regs);
+
+#ifdef CONFIG_SMP
+	update_process_times(user_mode(regs));
+#endif /* CONFIG_SMP */
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to when a second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660) {
+		if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
+			if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else
+				last_rtc_update = xtime.tv_sec - 600;
+		} else if (xtime.tv_usec <= ((unsigned) tick) / 2) {
+			if (set_rtc_mmss(xtime.tv_sec) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else
+				last_rtc_update = xtime.tv_sec - 600;
+		}
+        }
+
+	write_unlock(&xtime_lock);
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+unsigned long ip27_do_gettimeoffset(void)
+{
+	unsigned long ct_cur1;
+	ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
+	return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
+}
+
+/* Includes for ioc3_init().  */
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/pci/bridge.h>
+
+static __init unsigned long get_m48t35_time(void)
+{
+        unsigned int year, month, date, hour, min, sec;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	sec = rtc->sec;
+	min = rtc->min;
+	hour = rtc->hour;
+	date = rtc->date;
+	month = rtc->month;
+	year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+
+        BCD_TO_BIN(sec);
+        BCD_TO_BIN(min);
+        BCD_TO_BIN(hour);
+        BCD_TO_BIN(date);
+        BCD_TO_BIN(month);
+        BCD_TO_BIN(year);
+
+        year += 1970;
+
+        return mktime(year, month, date, hour, min, sec);
+}
+
+void __init ip27_time_init(void)
+{
+	xtime.tv_sec = get_m48t35_time();
+	xtime.tv_usec = 0;
+
+	do_gettimeoffset = ip27_do_gettimeoffset;
+}
+
+void __init cpu_time_init(void)
+{
+	lboard_t *board;
+	klcpu_t *cpu;
+	int cpuid;
+
+	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
+	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
+	if (!board)
+		panic("Can't find board info for myself.");
+
+	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
+	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
+	if (!cpu)
+		panic("No information about myself?");
+
+	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
+
+	set_cp0_status(SRB_TIMOCLK);
+}
+
+void __init hub_rtc_init(cnodeid_t cnode)
+{
+	/*
+	 * We only need to initialize the current node.
+	 * If this is not the current node then it is a cpuless
+	 * node and timeouts will not happen there.
+	 */
+	if (get_compact_nodeid() == cnode) {
+		int cpu = smp_processor_id();
+		LOCAL_HUB_S(PI_RT_EN_A, 1);
+		LOCAL_HUB_S(PI_RT_EN_B, 1);
+		LOCAL_HUB_S(PI_PROF_EN_A, 0);
+		LOCAL_HUB_S(PI_PROF_EN_B, 0);
+		ct_cur[cpu] = CYCLES_PER_JIFFY;
+		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_A, 0);
+		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_B, 0);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/Makefile linux-2.4.20/arch/mips/sgi-ip32/Makefile
--- linux-2.4.19/arch/mips/sgi-ip32/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/Makefile	2002-10-04 00:41:21.000000000 +0000
@@ -0,0 +1,22 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := ip32-kern.a
+
+all: ip32-kern.a ip32-irq-glue.o
+
+obj-y	+= ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \
+	   ip32-timer.o crime.o ip32-reset.o
+
+obj-$(CONFIG_PCI)   += ip32-pci.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/crime.c linux-2.4.20/arch/mips/sgi-ip32/crime.c
--- linux-2.4.19/arch/mips/sgi-ip32/crime.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/crime.c	2002-10-04 00:41:12.000000000 +0000
@@ -0,0 +1,49 @@
+/*
+ * 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) 2001 Keith M Wesolowski
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/ip32/crime.h>
+#include <asm/ptrace.h>
+
+void __init crime_init (void)
+{
+	u64 id = crime_read_64 (CRIME_ID);
+	u64 rev = id & CRIME_ID_REV;
+
+	id = (id & CRIME_ID_IDBITS) >> 4;
+
+	printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev,
+		(unsigned long) CRIME_BASE);
+}
+
+/* XXX Like on Sun, these give us various useful information to printk. */
+void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
+	memerr &= CRIME_MEM_ERROR_STAT_MASK;
+
+	printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
+		addr << 2, memerr);
+
+	crime_write_64 (CRIME_MEM_ERROR_STAT, 0);
+}
+
+void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR);
+	cpuerr &= CRIME_CPU_ERROR_MASK;
+	addr <<= 2UL;
+
+	printk ("CRIME CPU interface error detected at %09lx status %08lx\n",
+		addr, cpuerr);
+
+	crime_write_64 (CRIME_CPU_ERROR_STAT, 0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-berr.c linux-2.4.20/arch/mips/sgi-ip32/ip32-berr.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-berr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-berr.c	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
+int
+be_ip32_handler(struct pt_regs *regs, int is_fixup)
+{
+	int data = regs->cp0_cause & 4;
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init
+bus_error_init(void)
+{
+	be_board_handler = be_ip32_handler;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-irq-glue.S linux-2.4.20/arch/mips/sgi-ip32/ip32-irq-glue.S
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-irq-glue.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-irq-glue.S	2002-10-04 00:41:17.000000000 +0000
@@ -0,0 +1,87 @@
+/*
+ * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
+ *
+ * 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) 2000 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+#include <asm/ip32/ip32_ints.h>
+
+		.text
+		.set    noreorder
+		.set    noat
+		.align  5
+		NESTED(ip32_handle_int, PT_SIZE, ra)
+		.set    noat
+		SAVE_ALL
+		CLI			# TEST: interrupts should be off
+		.set    at
+		.set    noreorder
+
+		mfc0	s0,CP0_CAUSE
+
+		andi	t1, s0, IE_IRQ0
+		bnez	t1, handle_irq0
+		 andi	t1, s0, IE_IRQ1
+		bnez	t1, handle_irq1
+		 andi	t1, s0, IE_IRQ2
+		bnez	t1, handle_irq2
+		 andi	t1, s0, IE_IRQ3
+		bnez	t1, handle_irq3
+		 andi	t1, s0, IE_IRQ4
+		bnez	t1, handle_irq4
+		 andi	t1, s0, IE_IRQ5
+		bnez	t1, handle_irq5
+		 nop
+
+		/* Either someone has triggered the "software interrupts"
+		 * or we lost an interrupt somehow.  Ignore it.
+		 */
+		j	ret_from_irq
+		 nop
+
+handle_irq0:
+		jal	ip32_irq0
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq1:
+		jal	ip32_irq1
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq2:
+		jal	ip32_irq2
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq3:
+		jal	ip32_irq3
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq4:
+		jal	ip32_irq4
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq5:
+		jal	ip32_irq5
+		move	a0, sp
+		j	ret_from_irq
+		 nop
+
+		END(ip32_handle_int)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-irq.c linux-2.4.20/arch/mips/sgi-ip32/ip32-irq.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-irq.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,584 @@
+/*
+ * Code to handle IP32 IRQs
+ *
+ * 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) 2000 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/bitops.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/signal.h>
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* O2 irq map
+ *
+ * IP0 -> software (ignored)
+ * IP1 -> software (ignored)
+ * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
+ * IP3 -> (irq1) X unknown
+ * IP4 -> (irq2) X unknown
+ * IP5 -> (irq3) X unknown
+ * IP6 -> (irq4) X unknown
+ * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ *
+ * crime: (C)
+ *
+ * CRIME_INT_STAT 31:0:
+ *
+ * 0 -> 1 Video in 1
+ * 1 -> 2 Video in 2
+ * 2 -> 3 Video out
+ * 3 -> 4 Mace ethernet
+ * 4 -> S  SuperIO sub-interrupt
+ * 5 -> M  Miscellaneous sub-interrupt
+ * 6 -> A  Audio sub-interrupt
+ * 7 -> 8  PCI bridge errors
+ * 8 -> 9  PCI SCSI aic7xxx 0
+ * 9 -> 10  PCI SCSI aic7xxx 1
+ * 10 -> 11 PCI slot 0
+ * 11 -> 12 unused (PCI slot 1)
+ * 12 -> 13 unused (PCI slot 2)
+ * 13 -> 14 unused (PCI shared 0)
+ * 14 -> 15 unused (PCI shared 1)
+ * 15 -> 16 unused (PCI shared 2)
+ * 16 -> 17 GBE0 (E)
+ * 17 -> 18 GBE1 (E)
+ * 18 -> 19 GBE2 (E)
+ * 19 -> 20 GBE3 (E)
+ * 20 -> 21 CPU errors
+ * 21 -> 22 Memory errors
+ * 22 -> 23 RE empty edge (E)
+ * 23 -> 24 RE full edge (E)
+ * 24 -> 25 RE idle edge (E)
+ * 25 -> 26 RE empty level
+ * 26 -> 27 RE full level
+ * 27 -> 28 RE idle level
+ * 28 -> 29  unused (software 0) (E)
+ * 29 -> 30  unused (software 1) (E)
+ * 30 -> 31  unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 32 VICE
+ *
+ * S, M, A: Use the MACE ISA interrupt register
+ * MACE_ISA_INT_STAT 31:0
+ *
+ * 0-7 -> 33-40 Audio
+ * 8 -> 41 RTC
+ * 9 -> 42 Keyboard
+ * 10 -> X Keyboard polled
+ * 11 -> 44 Mouse
+ * 12 -> X Mouse polled
+ * 13-15 -> 46-48 Count/compare timers
+ * 16-19 -> 49-52 Parallel (16 E)
+ * 20-25 -> 53-58 Serial 1 (22 E)
+ * 26-31 -> 59-64 Serial 2 (28 E)
+ *
+ * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
+ * different IRQ map than IRIX uses, but that's OK as Linux irq handling
+ * is quite different anyway.
+ */
+
+/* Some initial interrupts to set up */
+extern void crime_memerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+extern void crime_cpuerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+
+struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
+			       0, "CRIME memory error", NULL,
+			       NULL };
+struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
+			       0, "CRIME CPU error", NULL,
+			       NULL };
+
+extern void ip32_handle_int (void);
+asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+/*
+ * For interrupts wired from a single device to the CPU.  Only the clock
+ * uses this it seems, which is IRQ 0 and IP7.
+ */
+
+static void enable_cpu_irq(unsigned int irq)
+{
+	set_cp0_status(STATUSF_IP7);
+}
+
+static unsigned int startup_cpu_irq(unsigned int irq)
+{
+	enable_cpu_irq(irq);
+	return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+	clear_cp0_status(STATUSF_IP7);
+}
+
+static void end_cpu_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cpu_irq (irq);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static struct hw_interrupt_type ip32_cpu_interrupt = {
+	"IP32 CPU",
+	startup_cpu_irq,
+	shutdown_cpu_irq,
+	enable_cpu_irq,
+	disable_cpu_irq,
+	mask_and_ack_cpu_irq,
+	end_cpu_irq,
+	NULL
+};
+
+/*
+ * This is for pure CRIME interrupts - ie not MACE.  The advantage?
+ * We get to split the register in half and do faster lookups.
+ */
+
+static void enable_crime_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_crime_irq(unsigned int irq)
+{
+	enable_crime_irq(irq);
+	return 0; /* This is probably not right; we could have pending irqs */
+}
+
+static void disable_crime_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_mask &= ~(1 << (irq - 1));
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static void mask_and_ack_crime_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	/* Edge triggered interrupts must be cleared. */
+	if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
+	    || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ)
+	    || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
+		save_and_cli(flags);
+		crime_mask = crime_read_64(CRIME_HARD_INT);
+		crime_mask &= ~(1 << (irq - 1));
+		crime_write_64(CRIME_HARD_INT, crime_mask);
+		restore_flags(flags);
+	}
+	disable_crime_irq(irq);
+}
+
+static void end_crime_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_crime_irq (irq);
+}
+
+#define shutdown_crime_irq disable_crime_irq
+
+static struct hw_interrupt_type ip32_crime_interrupt = {
+	"IP32 CRIME",
+	startup_crime_irq,
+	shutdown_crime_irq,
+	enable_crime_irq,
+	disable_crime_irq,
+	mask_and_ack_crime_irq,
+	end_crime_irq,
+	NULL
+};
+
+/*
+ * This is for MACE PCI interrupts.  We can decrease bus traffic by masking
+ * as close to the source as possible.  This also means we can take the
+ * next chunk of the CRIME register in one piece.
+ */
+
+static void enable_macepci_irq(unsigned int irq)
+{
+	u32 mace_mask;
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	mace_mask = mace_read_32(MACEPCI_CONTROL);
+	mace_mask |= MACEPCI_CONTROL_INT(irq - 9);
+	mace_write_32(MACEPCI_CONTROL, mace_mask);
+	/*
+	 * In case the CRIME interrupt isn't enabled, we must enable it;
+	 * however, we never disable interrupts at that level.
+	 */
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_macepci_irq(unsigned int irq)
+{
+	enable_macepci_irq (irq);
+
+	return 0; /* XXX */
+}
+
+static void disable_macepci_irq(unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	save_and_cli(flags);
+	mace_mask = mace_read_32(MACEPCI_CONTROL);
+	mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+	mace_write_32(MACEPCI_CONTROL, mace_mask);
+	restore_flags(flags);
+}
+
+static void end_macepci_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq (irq);
+}
+
+#define shutdown_macepci_irq disable_macepci_irq
+#define mask_and_ack_macepci_irq disable_macepci_irq
+
+static struct hw_interrupt_type ip32_macepci_interrupt = {
+	"IP32 MACE PCI",
+	startup_macepci_irq,
+	shutdown_macepci_irq,
+	enable_macepci_irq,
+	disable_macepci_irq,
+	mask_and_ack_macepci_irq,
+	end_macepci_irq,
+	NULL
+};
+
+/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
+ * CRIME register.
+ */
+
+static void enable_maceisa_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	u32 mace_mask;
+	unsigned int crime_int = 0;
+	unsigned long flags;
+
+	DBG ("maceisa enable: %u\n", irq);
+
+	switch (irq) {
+	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
+		crime_int = MACE_AUDIO_INT;
+		break;
+	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
+		crime_int = MACE_MISC_INT;
+		break;
+	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
+		crime_int = MACE_SUPERIO_INT;
+		break;
+	}
+	DBG ("crime_int %016lx enabled\n", crime_int);
+	save_and_cli(flags);
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_mask |= crime_int;
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	mace_mask = mace_read_32(MACEISA_INT_MASK);
+	mace_mask |= 1 << (irq - 33);
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_maceisa_irq (unsigned int irq)
+{
+	enable_maceisa_irq(irq);
+	return 0;
+}
+
+static void disable_maceisa_irq(unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	mace_mask = mace_read_32(MACEISA_INT_MASK);
+	mace_mask &= ~(1 << (irq - 33));
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
+}
+
+static void mask_and_ack_maceisa_irq(unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	switch (irq) {
+	case MACEISA_PARALLEL_IRQ:
+	case MACEISA_SERIAL1_TDMAPR_IRQ:
+	case MACEISA_SERIAL2_TDMAPR_IRQ:
+		save_and_cli(flags);
+		mace_mask = mace_read_32(MACEISA_INT_STAT);
+		mace_mask &= ~(1 << (irq - 33));
+		mace_write_32(MACEISA_INT_STAT, mace_mask);
+		restore_flags(flags);
+		break;
+	}
+	disable_maceisa_irq(irq);
+}
+
+static void end_maceisa_irq(unsigned irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_maceisa_irq (irq);
+}
+
+#define shutdown_maceisa_irq disable_maceisa_irq
+
+static struct hw_interrupt_type ip32_maceisa_interrupt = {
+	"IP32 MACE ISA",
+	startup_maceisa_irq,
+	shutdown_maceisa_irq,
+	enable_maceisa_irq,
+	disable_maceisa_irq,
+	mask_and_ack_maceisa_irq,
+	end_maceisa_irq,
+	NULL
+};
+
+/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
+ * bits 0-3 and 7 in the CRIME register.
+ */
+
+static void enable_mace_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+static unsigned int startup_mace_irq(unsigned int irq)
+{
+	enable_mace_irq(irq);
+	return 0;
+}
+
+static void disable_mace_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	crime_mask = crime_read_64 (CRIME_INT_MASK);
+	crime_mask &= ~(1 << (irq - 1));
+	crime_write_64 (CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static void end_mace_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq (irq);
+}
+
+#define shutdown_mace_irq disable_mace_irq
+#define mask_and_ack_mace_irq disable_mace_irq
+
+static struct hw_interrupt_type ip32_mace_interrupt = {
+	"IP32 MACE",
+	startup_mace_irq,
+	shutdown_mace_irq,
+	enable_mace_irq,
+	disable_mace_irq,
+	mask_and_ack_mace_irq,
+	end_mace_irq,
+	NULL
+};
+
+static void ip32_unknown_interrupt (struct pt_regs *regs)
+{
+	u64 crime;
+	u32 mace;
+
+	printk ("Unknown interrupt occurred!\n");
+	printk ("cp0_status: %08x\tcp0_cause: %08x\n",
+		read_32bit_cp0_register (CP0_STATUS),
+		read_32bit_cp0_register (CP0_CAUSE));
+	crime = crime_read_64 (CRIME_INT_MASK);
+	printk ("CRIME interrupt mask: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_INT_STAT);
+	printk ("CRIME interrupt status: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_HARD_INT);
+	printk ("CRIME hardware interrupt register: %016lx\n", crime);
+	mace = mace_read_32 (MACEISA_INT_MASK);
+	printk ("MACE ISA interrupt mask: %08x\n", mace);
+	mace = mace_read_32 (MACEISA_INT_STAT);
+	printk ("MACE ISA interrupt status: %08x\n", mace);
+	mace = mace_read_32 (MACEPCI_CONTROL);
+	printk ("MACE PCI control register: %08x\n", mace);
+
+	printk("Register dump:\n");
+	show_regs(regs);
+
+	printk("Please mail this report to linux-mips@oss.sgi.com\n");
+	printk("Spinning...");
+	while(1) ;
+}
+
+/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
+void ip32_irq0(struct pt_regs *regs)
+{
+	u64 crime_int;
+	u64 crime_mask;
+	int irq = 0;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	/* disable crime interrupts */
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_write_64(CRIME_INT_MASK, 0);
+
+	crime_int = crime_read_64(CRIME_INT_STAT);
+
+	if (crime_int & CRIME_MACE_INT_MASK) {
+		crime_int &= CRIME_MACE_INT_MASK;
+		irq = ffs (crime_int);
+	} else if (crime_int & CRIME_MACEISA_INT_MASK) {
+		u32 mace_int;
+		mace_int = mace_read_32 (MACEISA_INT_STAT);
+		if (mace_int == 0)
+			irq = 0;
+		else
+			irq = ffs (mace_int) + 32;
+	} else if (crime_int & CRIME_MACEPCI_INT_MASK) {
+		crime_int &= CRIME_MACEPCI_INT_MASK;
+		crime_int >>= 8;
+		irq = ffs (crime_int) + 8;
+	} else if (crime_int & 0xffff0000) {
+		crime_int >>= 16;
+		irq = ffs (crime_int) + 16;
+	}
+	if (irq == 0)
+		ip32_unknown_interrupt(regs);
+	DBG("*irq %u*\n", irq);
+	do_IRQ(irq, regs);
+
+	/* enable crime interrupts */
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+void ip32_irq1(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq2(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq3(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq4(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq5(struct pt_regs *regs)
+{
+	do_IRQ (CLOCK_IRQ, regs);
+}
+
+void __init init_IRQ(void)
+{
+	unsigned int irq;
+	int i;
+
+	/* Install our interrupt handler, then clear and disable all
+	 * CRIME and MACE interrupts.
+	 */
+	crime_write_64(CRIME_INT_MASK, 0);
+	crime_write_64(CRIME_HARD_INT, 0);
+	crime_write_64(CRIME_SOFT_INT, 0);
+	mace_write_32(MACEISA_INT_STAT, 0);
+	mace_write_32(MACEISA_INT_MASK, 0);
+	set_except_vector(0, ip32_handle_int);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].status  = IRQ_DISABLED;
+		irq_desc[i].action  = NULL;
+		irq_desc[i].depth   = 1;
+		irq_desc[i].handler = &no_irq_type;
+	}
+
+	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
+		hw_irq_controller *controller;
+
+		if (irq == CLOCK_IRQ)
+			controller = &ip32_cpu_interrupt;
+		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
+			controller = &ip32_mace_interrupt;
+		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
+			controller = &ip32_macepci_interrupt;
+		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
+			controller = &ip32_crime_interrupt;
+		else
+			controller = &ip32_maceisa_interrupt;
+
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = 0;
+		irq_desc[irq].depth = 0;
+		irq_desc[irq].handler = controller;
+	}
+	setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
+	setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-pci.c linux-2.4.20/arch/mips/sgi-ip32/ip32-pci.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-pci.c	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,460 @@
+/*
+ * 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) 2000, 2001 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+#include <linux/delay.h>
+
+#undef DEBUG_MACE_PCI
+
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
+ * map looks like this:
+ *
+ * 0  aic7xxx 0
+ * 1  aic7xxx 1
+ * 2  expansion slot
+ * 3  N/C
+ * 4  N/C
+ */
+
+#define chkslot(dev)							\
+do {									\
+	if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1	\
+	    || PCI_SLOT ((dev)->devfn) > 3)				\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+} while (0)
+
+#define mkaddr(dev, where) \
+((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
+
+void macepci_error (int irq, void *dev, struct pt_regs *regs);
+
+static int macepci_read_config_byte (struct pci_dev *dev, int where,
+				     u8 *val)
+{
+	*val = 0xff;
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_word (struct pci_dev *dev, int where,
+				     u16 *val)
+{
+	*val = 0xffff;
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+ 	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_dword (struct pci_dev *dev, int where,
+				      u32 *val)
+{
+	*val = 0xffffffff;
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_32 (MACEPCI_CONFIG_DATA);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_byte (struct pci_dev *dev, int where,
+				      u8 val)
+{
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_word (struct pci_dev *dev, int where,
+				      u16 val)
+{
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_dword (struct pci_dev *dev, int where,
+                                          u32 val)
+{
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_32 (MACEPCI_CONFIG_DATA, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops macepci_ops = {
+	macepci_read_config_byte,
+	macepci_read_config_word,
+	macepci_read_config_dword,
+	macepci_write_config_byte,
+	macepci_write_config_word,
+	macepci_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = { { 0 } };
+
+void __init pcibios_init (void)
+{
+	struct pci_dev *dev;
+	u32 start, size;
+	u16 cmd;
+	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
+	u32 base_mem = 0x80100000; /* Likewise */
+	u32 rev = mace_read_32 (MACEPCI_REV);
+	int i;
+
+	printk ("MACE: PCI rev %d detected at %016lx\n", rev,
+		(u64) MACE_BASE + MACE_PCI);
+
+	/* These are *bus* addresses */
+	ioport_resource.start = 0;
+	ioport_resource.end = 0xffffffffUL;
+	iomem_resource.start = 0x80000000UL;
+	iomem_resource.end = 0xffffffffUL;
+
+	/* Clear any outstanding errors and enable interrupts */
+	mace_write_32 (MACEPCI_ERROR_ADDR, 0);
+	mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
+	mace_write_32 (MACEPCI_CONTROL, 0xff008500);
+	crime_write_64 (CRIME_HARD_INT, 0UL);
+	crime_write_64 (CRIME_SOFT_INT, 0UL);
+	crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
+
+	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+			 "MACE PCI error", NULL))
+		panic("PCI bridge can't get interrupt; can't happen.");
+
+	pci_scan_bus (0, &macepci_ops, NULL);
+
+#ifdef DEBUG_MACE_PCI
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+	/*
+	 * Assign sane resources to and enable all devices.  The requirement
+	 * for the SCSI controllers is well-known: a 256-byte I/O region
+	 * which we must assign, and a 1-page memory region which is
+	 * assigned by the system firmware.
+	 */
+	pci_for_each_dev (dev) {
+		switch (PCI_SLOT (dev->devfn)) {
+		case 1: /* SCSI bus 0 */
+			dev->resource[0].start = 0x1000UL;
+			dev->resource[0].end = 0x10ffUL;
+			break;
+		case 2: /* SCSI bus 1 */
+			dev->resource[0].start = 0x2000UL;
+			dev->resource[0].end = 0x20ffUL;
+			break;
+		default: /* Slots - I guess we have only 1 */
+			for (i=0; i < 6; i++) {
+				size = dev->resource[i].end
+					- dev->resource[i].start;
+				if (!size
+				    || !(dev->resource[i].flags
+					 & (IORESOURCE_IO|IORESOURCE_MEM))) {
+					dev->resource[i].start
+						= dev->resource[i].end = 0UL;
+					continue;
+				}
+				if (dev->resource[i].flags & IORESOURCE_IO) {
+					dev->resource[i].start = base_io;
+					base_io += PAGE_ALIGN (size);
+				} else {
+					dev->resource[i].start = base_mem;
+					base_mem += 0x100000UL;
+				}
+				dev->resource[i].end =
+					dev->resource[i].start + size;
+			}
+			break;
+		}
+		for (i=0; i < 6; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			start = dev->resource[i].start;
+			if (dev->resource[i].flags & IORESOURCE_IO)
+				start |= 1;
+			pci_write_config_dword (dev,
+				PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
+		}
+		pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
+		pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
+		pci_read_config_word (dev, PCI_COMMAND, &cmd);
+		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
+		pci_write_config_word (dev, PCI_COMMAND, cmd);
+		pci_set_master (dev);
+	}
+        /*
+         * Fixup O2 PCI slot. Bad hack.
+         */
+/*        devtag = pci_make_tag(0, 0, 3, 0);
+
+        slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG);
+        slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
+        macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot);
+
+        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START);
+        if (slot == 0xffffffe1)
+                macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000);
+
+        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2));
+        if ((slot & 0xffff0000) == 0) {
+                slot += 0x00010000;
+                macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2),
+                    0x00000000);
+        }
+ */
+#ifdef DEBUG_MACE_PCI
+	printk ("Triggering PCI bridge interrupt...\n");
+	mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
+
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d final bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+}
+
+/*
+ * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
+ * the device (1-4 => A-D), tell what irq to use.  Note that we don't
+ * in theory have slots 4 and 5, and we never normally use the shared
+ * irqs.  I suppose a device without a pin A will thank us for doing it
+ * right if there exists such a broken piece of crap.
+ */
+static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
+{
+	chkslot (dev);
+	if (pin == 0)
+		pin = 1;
+	switch (slot) {
+	case 1:
+		return MACEPCI_SCSI0_IRQ;
+	case 2:
+		return MACEPCI_SCSI1_IRQ;
+	case 3:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED0_IRQ;
+		case 3:
+			return MACEPCI_SHARED1_IRQ;
+		case 4:
+			return MACEPCI_SHARED2_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT0_IRQ;
+		}
+	case 4:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED2_IRQ;
+		case 3:
+			return MACEPCI_SHARED0_IRQ;
+		case 4:
+			return MACEPCI_SHARED1_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT1_IRQ;
+		}
+		return MACEPCI_SLOT1_IRQ;
+	case 5:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED1_IRQ;
+		case 3:
+			return MACEPCI_SHARED2_IRQ;
+		case 4:
+			return MACEPCI_SHARED0_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT2_IRQ;
+		}
+	default:
+		return 0;
+	}
+}
+
+/*
+ * It's not entirely clear what this does in a system with no bridges.
+ * In any case, bridges are not supported by Linux in O2.
+ */
+static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
+{
+	if (PCI_SLOT (dev->devfn) == 2)
+		*pinp = 2;
+	else
+		*pinp = 1;
+	return PCI_SLOT (dev->devfn);
+}
+
+/* All devices are enabled during initialization. */
+int pcibios_enable_device (struct pci_dev *dev)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+char * __init pcibios_setup (char *str)
+{
+	return str;
+}
+
+void __init pcibios_align_resource (void *data, struct resource *res,
+				    unsigned long size, unsigned long align)
+{
+}
+
+void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+				     struct resource *res, int resource)
+{
+}
+
+void __init pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init pcibios_fixup_bus (struct pci_bus *b)
+{
+	pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
+}
+
+/* XXX anybody know what this is supposed to do? */
+void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+				      struct pbus_set_ranges_data * ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
+/*
+ * Handle errors from the bridge.  This includes master and target aborts,
+ * various command and address errors, and the interrupt test.  This gets
+ * registered on the bridge error irq.  It's conceivable that some of these
+ * conditions warrant a panic.  Anybody care to say which ones?
+ */
+void macepci_error (int irq, void *dev, struct pt_regs *regs) {
+	u32 flags, error_addr;
+	char space;
+
+	flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
+	error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
+
+	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
+		space = 'M';
+	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
+		space = 'C';
+	else space = 'X';
+
+	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
+		printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_MASTER_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
+		printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_TARGET_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
+		printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_DATA_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_RETRY_ERR) {
+		printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_RETRY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
+		printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS,
+			       flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
+	}
+	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
+		printk ("MACEPCI: System error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SYSTEM_ERR);
+	}
+	if (flags & MACEPCI_ERROR_PARITY_ERR) {
+		printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_OVERRUN) {
+		printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_OVERRUN);
+	}
+	if (flags & MACEPCI_ERROR_SIG_TABORT) {
+		printk ("MACEPCI: Signaled target abort (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SIG_TABORT);
+	}
+	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
+		printk ("MACEPCI: Interrupt test triggered (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
+	}
+}
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-reset.c linux-2.4.20/arch/mips/sgi-ip32/ip32-reset.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-reset.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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) 2001 Keith M Wesolowski
+ * Copyright (C) 2001 Paul Mundt
+ */
+#include <linux/init.h>
+
+#include <asm/reboot.h>
+#include <asm/sgialib.h>
+
+static void ip32_machine_restart(char *cmd)
+{
+	ArcReboot();
+}
+
+static inline void ip32_machine_halt(void)
+{
+	ArcEnterInteractiveMode();
+}
+
+static void ip32_machine_power_off(void)
+{
+	ip32_machine_halt();
+}
+
+void __init ip32_reboot_setup(void)
+{
+	_machine_restart = ip32_machine_restart;
+	_machine_halt = ip32_machine_halt;
+	_machine_power_off = ip32_machine_power_off;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-rtc.c linux-2.4.20/arch/mips/sgi-ip32/ip32-rtc.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-rtc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-rtc.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * RTC routines for IP32 style attached Dallas chip.
+ *
+ * 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) 2000 Harald Koerfgen
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/ip32/mace.h>
+
+static unsigned char ip32_rtc_read_data(unsigned long addr)
+{
+	return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8));
+}
+
+static void ip32_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data);
+}
+
+static int ip32_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops ip32_rtc_ops = {
+	&ip32_rtc_read_data,
+	&ip32_rtc_write_data,
+	&ip32_rtc_bcd_mode
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-setup.c linux-2.4.20/arch/mips/sgi-ip32/ip32-setup.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-setup.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,102 @@
+/*
+ * IP32 basic setup
+ *
+ * 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) 2000 Harald Koerfgen
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+#include <linux/init.h>
+
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/sgialib.h>
+
+extern struct rtc_ops ip32_rtc_ops;
+extern u32 cc_interval;
+
+#ifdef CONFIG_SGI_O2MACE_ETH
+
+/*
+ * This is taken care of in here 'cause they say using Arc later on is
+ * problematic
+ */
+extern char o2meth_eaddr[8];
+static inline unsigned char str2hexnum(unsigned char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	if (c >= 'a' && c <= 'f')
+		return c - 'a' + 10;
+	return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		unsigned char num;
+
+		if(*str == ':')
+			str++;
+		num = str2hexnum(*str++) << 4;
+		num |= (str2hexnum(*str++));
+		ea[i] = num;
+	}
+}
+#endif
+
+extern void ip32_time_init(void);
+
+void __init ip32_setup(void)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+	char *ctype;
+#endif
+	TLBMISS_HANDLER_SETUP ();
+
+	mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	ctype = ArcGetEnvironmentVariable("console");
+	if (*ctype == 'd') {
+		if (ctype[1] == '2')
+			console_setup ("ttyS1");
+		else
+			console_setup ("ttyS0");
+	}
+#endif
+#ifdef CONFIG_SGI_O2MACE_ETH
+	{
+		char *mac=ArcGetEnvironmentVariable("eaddr");
+		str2eaddr(o2meth_eaddr, mac);
+	}
+#endif
+
+#ifdef CONFIG_VT
+	conswitchp = &dummy_con;
+#endif
+
+	rtc_ops = &ip32_rtc_ops;
+	board_time_init = ip32_time_init;
+
+	crime_init ();
+}
+
+int __init page_is_ram (unsigned long pagenr)
+{
+	/* XXX: to do? */
+	return 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sgi-ip32/ip32-timer.c linux-2.4.20/arch/mips/sgi-ip32/ip32-timer.c
--- linux-2.4.19/arch/mips/sgi-ip32/ip32-timer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sgi-ip32/ip32-timer.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,238 @@
+/*
+ * IP32 timer calibration
+ *
+ * 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) 2001 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+#include <asm/mipsregs.h>
+#include <asm/param.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+extern volatile unsigned long wall_jiffies;
+extern rwlock_t xtime_lock;
+
+u32 cc_interval;
+
+/* Cycle counter value at the previous timer interrupt.. */
+static unsigned int timerhi, timerlo;
+
+/* An arbitrary time; this can be decreased if reliability looks good */
+#define WAIT_MS 10
+#define PER_MHZ (1000000 / 2 / HZ)
+/*
+ * Change this if you have some constant time drift
+ */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+
+void __init ip32_timer_setup (struct irqaction *irq)
+{
+	u64 crime_time;
+	u32 cc_tick;
+
+	printk("Calibrating system timer... ");
+
+	crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT);
+
+	while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time
+		< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
+		;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
+	cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
+	/* The round-off seems unnecessary; in testing, the error of the
+	 * above procedure is < 100 ticks, which means it gets filtered
+	 * out by the HZ adjustment.
+	 */
+	cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
+
+	printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
+
+	setup_irq (CLOCK_IRQ, irq);
+}
+
+struct irqaction irq0  = { NULL, SA_INTERRUPT, 0,
+			   "timer", NULL, NULL};
+
+void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	u32 count;
+
+	/*
+	 * The cycle counter is only 32 bit which is good for about
+	 * a minute at current count rates of upto 150MHz or so.
+	 */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	timerhi += (count < timerlo);	/* Wrap around */
+	timerlo = count;
+
+	write_32bit_cp0_register (CP0_COMPARE,
+				  (u32) (count + cc_interval));
+	kstat.irqs[0][irq]++;
+	do_timer (regs);
+
+	if (!jiffies)
+	{
+		/*
+		 * If jiffies has overflowed in this timer_interrupt we must
+		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
+		 * quotient calc still valid. -arca
+		 */
+		timerhi = timerlo = 0;
+	}
+}
+
+/*
+ * On MIPS only R4000 and better have a cycle counter.
+ *
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_gettimeoffset(void)
+{
+	u32 count;
+	unsigned long res, tmp;
+
+	/* Last jiffy when do_fast_gettimeoffset() was called. */
+	static unsigned long last_jiffies;
+	u32 quotient;
+
+	/*
+	 * Cached "1/(clocks per usec)*2^32" value.
+	 * It has to be recalculated once each jiffy.
+	 */
+	static u32 cached_quotient;
+
+	tmp = jiffies;
+
+	quotient = cached_quotient;
+
+	if (tmp && last_jiffies != tmp) {
+		last_jiffies = tmp;
+		__asm__(".set\tnoreorder\n\t"
+			".set\tnoat\n\t"
+			".set\tmips3\n\t"
+			"lwu\t%0,%2\n\t"
+			"dsll32\t$1,%1,0\n\t"
+			"or\t$1,$1,%0\n\t"
+			"ddivu\t$0,$1,%3\n\t"
+			"mflo\t$1\n\t"
+			"dsll32\t%0,%4,0\n\t"
+			"nop\n\t"
+			"ddivu\t$0,%0,$1\n\t"
+			"mflo\t%0\n\t"
+			".set\tmips0\n\t"
+			".set\tat\n\t"
+			".set\treorder"
+			:"=&r" (quotient)
+			:"r" (timerhi),
+			 "m" (timerlo),
+			 "r" (tmp),
+			 "r" (USECS_PER_JIFFY)
+			:"$1");
+		cached_quotient = quotient;
+	}
+
+	/* Get last timer tick in absolute kernel time */
+	count = read_32bit_cp0_register(CP0_COUNT);
+
+	/* .. relative to previous jiffy (32 bits is enough) */
+	count -= timerlo;
+
+	__asm__("multu\t%1,%2\n\t"
+		"mfhi\t%0"
+		:"=r" (res)
+		:"r" (count),
+		 "r" (quotient));
+
+	/*
+ 	 * Due to possible jiffies inconsistencies, we need to check
+	 * the result so that we'll get a timer that is monotonic.
+	 */
+	if (res >= USECS_PER_JIFFY)
+		res = USECS_PER_JIFFY-1;
+
+	return res;
+}
+
+void __init ip32_time_init(void)
+{
+	unsigned int epoch = 0, year, mon, day, hour, min, sec;
+	int i;
+
+	/* 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;
+	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));
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+
+	/* Attempt to guess the epoch.  This is the same heuristic as in
+	 * rtc.c so no stupid things will happen to timekeeping.  Who knows,
+	 * maybe Ultrix also uses 1952 as epoch ...
+	 */
+	if (year > 10 && year < 44)
+		epoch = 1980;
+	else if (year < 96)
+		epoch = 1952;
+	year += epoch;
+
+	write_lock_irq (&xtime_lock);
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+	write_unlock_irq (&xtime_lock);
+
+	write_32bit_cp0_register(CP0_COUNT, 0);
+	irq0.handler = cc_timer_interrupt;
+
+	ip32_timer_setup (&irq0);
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+	/* Set ourselves up for future interrupts */
+        write_32bit_cp0_register(CP0_COMPARE,
+				 read_32bit_cp0_register(CP0_COUNT)
+				 + cc_interval);
+        change_cp0_status(ST0_IM, ALLINTS);
+	sti ();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/Makefile linux-2.4.20/arch/mips/sibyte/cfe/Makefile
--- linux-2.4.19/arch/mips/sibyte/cfe/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/Makefile	2002-10-04 00:41:19.000000000 +0000
@@ -0,0 +1,8 @@
+USE_STANDARD_AS_RULE := true
+
+L_TARGET = cfe.a
+
+obj-y			= cfe_api.o setup.o
+obj-$(CONFIG_SMP)	+= smp.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/cfe_api.c linux-2.4.20/arch/mips/sibyte/cfe/cfe_api.c
--- linux-2.4.19/arch/mips/sibyte/cfe/cfe_api.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/cfe_api.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Device Function stubs			File: cfe_api.c
+    *
+    *  This module contains device function stubs (small routines to
+    *  call the standard "iocb" interface entry point to CFE).
+    *  There should be one routine here per iocb function call.
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *
+    ********************************************************************* */
+
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+
+static long cfe_console_handle = -1;
+static int (*cfe_dispfunc)(long handle,cfe_xiocb_t *xiocb) = 0;
+static cfe_xuint_t cfe_handle = 0;
+
+/*
+ * This macro makes a "signed 64-bit pointer" - basically extending a regular
+ * pointer to its 64-bit compatibility space equivalent.
+ */
+#define BIGPTR(x) (long long) (long) (x)
+
+typedef unsigned long intptr_t;
+
+int cfe_init(cfe_xuint_t handle)
+{
+	if ((*((unsigned int *) (int) CFE_APISEAL) == CFE_EPTSEAL) ||
+	    (*((unsigned int *) (int) CFE_APISEAL_RE) == CFE_EPTSEAL) ||
+	    (*((unsigned int *) (int) CFE_APISEAL_OLD) == CFE_EPTSEAL)) {
+		cfe_dispfunc = (cfe_xptr_t) (int) CFE_APIENTRY;
+		if (handle) cfe_handle = handle;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+int cfe_iocb_dispatch(cfe_xiocb_t *xiocb);
+int cfe_iocb_dispatch(cfe_xiocb_t *xiocb)
+{
+	if (!cfe_dispfunc) return -1;
+	return (*cfe_dispfunc)(cfe_handle,xiocb);
+}
+
+static int cfe_strlen(char *name)
+{
+	int count = 0;
+
+	while (*name) {
+		count++;
+		name++;
+	}
+
+	return count;
+}
+
+int cfe_open(char *name)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = 0;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
+}
+
+int cfe_close(int handle)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status);
+
+}
+
+int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
+}
+
+int cfe_read(int handle,unsigned char *buffer,int length)
+{
+	return cfe_readblk(handle,0,buffer,length);
+}
+
+
+int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_offset = offset;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
+}
+
+int cfe_write(int handle,unsigned char *buffer,int length)
+{
+	return cfe_writeblk(handle,0,buffer,length);
+}
+
+
+int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
+	xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum;
+	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
+	xiocb.plist.xiocb_buffer.buf_length = length;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
+	return xiocb.xiocb_status;
+}
+
+int cfe_inpstat(int handle)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = handle;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
+	xiocb.plist.xiocb_inpstat.inp_status = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
+
+	return xiocb.plist.xiocb_inpstat.inp_status;
+
+}
+
+long long cfe_getticks(void)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_time_t);
+	xiocb.plist.xiocb_time.ticks = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.plist.xiocb_time.ticks;
+
+}
+
+int cfe_getenv(char *name,char *dest,int destlen)
+{
+	cfe_xiocb_t xiocb;
+
+	*dest = 0;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(dest);
+	xiocb.plist.xiocb_envbuf.val_length = destlen;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+int cfe_setenv(char *name,char *val)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = 0;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
+	xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type)
+{
+	cfe_xiocb_t xiocb;
+	xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
+	xiocb.plist.xiocb_meminfo.mi_idx = idx;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	(*addr) = xiocb.plist.xiocb_meminfo.mi_addr;
+	(*size) = xiocb.plist.xiocb_meminfo.mi_size;
+	(*type) = xiocb.plist.xiocb_meminfo.mi_type;
+
+	return xiocb.xiocb_status;
+}
+
+
+int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
+	xiocb.plist.xiocb_envbuf.enum_idx = idx;
+	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
+	xiocb.plist.xiocb_envbuf.name_length = namelen;
+	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
+	xiocb.plist.xiocb_envbuf.val_length = vallen;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+int cfe_exit(int warm, int status)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
+	xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
+	xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status);
+}
+
+int cfe_flushcache(int flg)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+int cfe_getstdhandle(int flg)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags = flg;
+	xiocb.xiocb_psize = 0;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
+
+}
+
+int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags  = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
+	xiocb.plist.xiocb_cpuctl.gp_val = gp;
+	xiocb.plist.xiocb_cpuctl.sp_val = sp;
+	xiocb.plist.xiocb_cpuctl.a1_val = a1;
+	xiocb.plist.xiocb_cpuctl.start_addr = (long)fn;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+
+int cfe_stop_cpu(int cpu)
+{
+	cfe_xiocb_t xiocb;
+
+	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+	xiocb.xiocb_status = 0;
+	xiocb.xiocb_handle = 0;
+	xiocb.xiocb_flags  = 0;
+	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
+	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
+
+	cfe_iocb_dispatch(&xiocb);
+
+	return xiocb.xiocb_status;
+}
+
+void cfe_open_console()
+{
+	cfe_console_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+}
+
+void cfe_console_print(const char *str, int len)
+{
+	int res;
+
+	if (cfe_console_handle != -1) {
+		do {
+			res = cfe_writeblk(cfe_console_handle, 0, str, len);
+			if (res < 0)
+				break;
+			str += res;
+			len -= res;
+		} while (len);
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/cfe_api.h linux-2.4.20/arch/mips/sibyte/cfe/cfe_api.h
--- linux-2.4.19/arch/mips/sibyte/cfe/cfe_api.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/cfe_api.h	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Device function prototypes		File: cfe_api.h
+    *
+    *  This module contains prototypes for cfe_devfuncs.c, a set
+    *  of wrapper routines to the IOCB interface.  This file,
+    *  along with cfe_api.c, can be incorporated into programs
+    *  that need to call CFE.
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *
+    ********************************************************************* */
+
+#include <linux/config.h>
+
+#define CFE_EPTSEAL 0x43464531
+#ifdef CONFIG_MIPS_UNCACHED
+#define CFE_APIENTRY    0xBFC00500
+#define CFE_APISEAL     0xBFC004E0
+#define CFE_APISEAL_RE  0xBFC004E8
+#define CFE_APISEAL_OLD 0xBFC00508
+#else
+#define CFE_APIENTRY    0x9FC00500
+#define CFE_APISEAL     0x9FC004E0
+#define CFE_APISEAL_RE  0x9FC004E8
+#define CFE_APISEAL_OLD 0x9FC00508
+#endif
+
+#ifndef __ASSEMBLER__
+int cfe_init(cfe_xuint_t handle);
+int cfe_open(char *name);
+int cfe_close(int handle);
+int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
+int cfe_read(int handle,unsigned char *buffer,int length);
+int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
+int cfe_write(int handle,unsigned char *buffer,int length);
+int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen);
+int cfe_inpstat(int handle);
+int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen);
+int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type);
+int cfe_setenv(char *name,char *val);
+int cfe_getenv(char *name,char *dest,int destlen);
+long long cfe_getticks(void);
+int cfe_exit(int warm, int status);
+int cfe_flushcache(int flg);
+int cfe_getstdhandle(int flg);
+int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1);
+int cfe_stop_cpu(int cpu);
+
+void cfe_open_console(void);
+void cfe_console_print(const char *, int);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/cfe_error.h linux-2.4.20/arch/mips/sibyte/cfe/cfe_error.h
--- linux-2.4.19/arch/mips/sibyte/cfe/cfe_error.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/cfe_error.h	2002-10-04 00:41:13.000000000 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  Error codes				File: cfe_error.h
+    *
+    *  CFE's global error code list is here.
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *
+    ********************************************************************* */
+
+
+
+
+#define CFE_OK			 0
+#define CFE_ERR                 -1	/* generic error */
+#define CFE_ERR_INV_COMMAND	-2
+#define CFE_ERR_EOF		-3
+#define CFE_ERR_IOERR		-4
+#define CFE_ERR_NOMEM		-5
+#define CFE_ERR_DEVNOTFOUND	-6
+#define CFE_ERR_DEVOPEN		-7
+#define CFE_ERR_INV_PARAM	-8
+#define CFE_ERR_ENVNOTFOUND	-9
+#define CFE_ERR_ENVREADONLY	-10
+
+#define CFE_ERR_NOTELF		-11
+#define CFE_ERR_NOT32BIT 	-12
+#define CFE_ERR_WRONGENDIAN 	-13
+#define CFE_ERR_BADELFVERS 	-14
+#define CFE_ERR_NOTMIPS 	-15
+#define CFE_ERR_BADELFFMT 	-16
+#define CFE_ERR_BADADDR 	-17
+
+#define CFE_ERR_FILENOTFOUND	-18
+#define CFE_ERR_UNSUPPORTED	-19
+
+#define CFE_ERR_HOSTUNKNOWN	-20
+
+#define CFE_ERR_TIMEOUT		-21
+
+#define CFE_ERR_PROTOCOLERR	-22
+
+#define CFE_ERR_NETDOWN		-23
+#define CFE_ERR_NONAMESERVER	-24
+
+#define CFE_ERR_NOHANDLES	-25
+#define CFE_ERR_ALREADYBOUND	-26
+
+#define CFE_ERR_CANNOTSET	-27
+#define CFE_ERR_NOMORE		-28
+#define CFE_ERR_BADFILESYS	-29
+#define CFE_ERR_FSNOTAVAIL	-30
+
+#define CFE_ERR_INVBOOTBLOCK	-31
+#define CFE_ERR_WRONGDEVTYPE	-32
+#define CFE_ERR_BBCHECKSUM	-33
+#define CFE_ERR_BOOTPROGCHKSUM	-34
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/cfe_xiocb.h linux-2.4.20/arch/mips/sibyte/cfe/cfe_xiocb.h
--- linux-2.4.19/arch/mips/sibyte/cfe/cfe_xiocb.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/cfe_xiocb.h	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*  *********************************************************************
+    *  Broadcom Common Firmware Environment (CFE)
+    *
+    *  IOCB definitions				File: cfe_iocb.h
+    *
+    *  This module describes CFE's IOCB structure, the main
+    *  data structure used to communicate API requests with CFE.
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
+    *
+    ********************************************************************* */
+
+/*  *********************************************************************
+    *  Constants
+    ********************************************************************* */
+
+#define CFE_CMD_FW_GETINFO	0
+#define CFE_CMD_FW_RESTART	1
+#define CFE_CMD_FW_BOOT		2
+#define CFE_CMD_FW_CPUCTL	3
+#define CFE_CMD_FW_GETTIME      4
+#define CFE_CMD_FW_MEMENUM	5
+#define CFE_CMD_FW_FLUSHCACHE	6
+
+#define CFE_CMD_DEV_GETHANDLE	9
+#define CFE_CMD_DEV_ENUM	10
+#define CFE_CMD_DEV_OPEN	11
+#define CFE_CMD_DEV_INPSTAT	12
+#define CFE_CMD_DEV_READ	13
+#define CFE_CMD_DEV_WRITE	14
+#define CFE_CMD_DEV_IOCTL	15
+#define CFE_CMD_DEV_CLOSE	16
+#define CFE_CMD_DEV_GETINFO	17
+
+#define CFE_CMD_ENV_ENUM	20
+#define CFE_CMD_ENV_GET		22
+#define CFE_CMD_ENV_SET		23
+#define CFE_CMD_ENV_DEL		24
+
+#define CFE_CMD_MAX		32
+
+#define CFE_MI_RESERVED	0		/* memory is reserved, do not use */
+#define CFE_MI_AVAILABLE 1		/* memory is available */
+
+#define CFE_FLG_WARMSTART 0x00000001
+
+#define CFE_FLG_ENV_PERMANENT 0x00000001
+
+#define CFE_CPU_CMD_START 1
+#define CFE_CPU_CMD_STOP 0
+
+#define CFE_STDHANDLE_CONSOLE	0
+
+#define CFE_DEV_NETWORK 	1
+#define CFE_DEV_DISK		2
+#define CFE_DEV_FLASH		3
+#define CFE_DEV_SERIAL		4
+#define CFE_DEV_CPU		5
+#define CFE_DEV_NVRAM		6
+#define CFE_DEV_OTHER		7
+#define CFE_DEV_MASK		0x0F
+
+#define CFE_CACHE_FLUSH_D	1
+#define CFE_CACHE_INVAL_I	2
+#define CFE_CACHE_INVAL_D	4
+#define CFE_CACHE_INVAL_L2	8
+
+/*  *********************************************************************
+    *  Structures
+    ********************************************************************* */
+
+typedef unsigned long long cfe_xuint_t;
+typedef long long cfe_xint_t;
+typedef long long cfe_xptr_t;
+
+typedef struct xiocb_buffer_s {
+    cfe_xuint_t   buf_offset;		/* offset on device (bytes) */
+    cfe_xptr_t 	  buf_ptr;		/* pointer to a buffer */
+    cfe_xuint_t   buf_length;		/* length of this buffer */
+    cfe_xuint_t   buf_retlen;		/* returned length (for read ops) */
+    cfe_xuint_t   buf_ioctlcmd;		/* IOCTL command (used only for IOCTLs) */
+} xiocb_buffer_t;
+
+#define buf_devflags buf_ioctlcmd	/* returned device info flags */
+
+typedef struct xiocb_inpstat_s {
+    cfe_xuint_t inp_status;		/* 1 means input available */
+} xiocb_inpstat_t;
+
+typedef struct xiocb_envbuf_s {
+    cfe_xint_t enum_idx;		/* 0-based enumeration index */
+    cfe_xptr_t name_ptr;		/* name string buffer */
+    cfe_xint_t name_length;		/* size of name buffer */
+    cfe_xptr_t val_ptr;			/* value string buffer */
+    cfe_xint_t val_length;		/* size of value string buffer */
+} xiocb_envbuf_t;
+
+typedef struct xiocb_cpuctl_s {
+    cfe_xuint_t  cpu_number;		/* cpu number to control */
+    cfe_xuint_t  cpu_command;		/* command to issue to CPU */
+    cfe_xuint_t  start_addr;		/* CPU start address */
+    cfe_xuint_t  gp_val;		/* starting GP value */
+    cfe_xuint_t  sp_val;		/* starting SP value */
+    cfe_xuint_t  a1_val;		/* starting A1 value */
+} xiocb_cpuctl_t;
+
+typedef struct xiocb_time_s {
+    cfe_xint_t ticks;			/* current time in ticks */
+} xiocb_time_t;
+
+typedef struct xiocb_exitstat_s {
+    cfe_xint_t status;
+} xiocb_exitstat_t;
+
+typedef struct xiocb_meminfo_s {
+    cfe_xint_t  mi_idx;			/* 0-based enumeration index */
+    cfe_xint_t  mi_type;		/* type of memory block */
+    cfe_xuint_t mi_addr;		/* physical start address */
+    cfe_xuint_t mi_size;		/* block size */
+} xiocb_meminfo_t;
+
+#define CFE_FWI_64BIT		0x00000001
+#define CFE_FWI_32BIT		0x00000002
+#define CFE_FWI_RELOC		0x00000004
+#define CFE_FWI_UNCACHED	0x00000008
+#define CFE_FWI_MULTICPU	0x00000010
+#define CFE_FWI_FUNCSIM		0x00000020
+#define CFE_FWI_RTLSIM		0x00000040
+
+typedef struct xiocb_fwinfo_s {
+    cfe_xint_t fwi_version;		/* major, minor, eco version */
+    cfe_xint_t fwi_totalmem;		/* total installed mem */
+    cfe_xint_t fwi_flags;		/* various flags */
+    cfe_xint_t fwi_boardid;		/* board ID */
+    cfe_xint_t fwi_bootarea_va;		/* VA of boot area */
+    cfe_xint_t fwi_bootarea_pa;		/* PA of boot area */
+    cfe_xint_t fwi_bootarea_size;	/* size of boot area */
+    cfe_xint_t fwi_reserved1;
+    cfe_xint_t fwi_reserved2;
+    cfe_xint_t fwi_reserved3;
+} xiocb_fwinfo_t,cfe_fwinfo_t;
+
+typedef struct cfe_xiocb_s {
+    cfe_xuint_t xiocb_fcode;		/* IOCB function code */
+    cfe_xint_t  xiocb_status;		/* return status */
+    cfe_xint_t  xiocb_handle;		/* file/device handle */
+    cfe_xuint_t xiocb_flags;		/* flags for this IOCB */
+    cfe_xuint_t xiocb_psize;		/* size of parameter list */
+    union {
+	xiocb_buffer_t  xiocb_buffer;	/* buffer parameters */
+	xiocb_inpstat_t xiocb_inpstat;	/* input status parameters */
+	xiocb_envbuf_t  xiocb_envbuf;	/* environment function parameters */
+	xiocb_cpuctl_t  xiocb_cpuctl;	/* CPU control parameters */
+	xiocb_time_t    xiocb_time;	/* timer parameters */
+	xiocb_meminfo_t xiocb_meminfo;	/* memory arena info parameters */
+	xiocb_fwinfo_t  xiocb_fwinfo;	/* firmware information */
+	xiocb_exitstat_t xiocb_exitstat; /* Exit status */
+    } plist;
+} cfe_xiocb_t;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/setup.c linux-2.4.20/arch/mips/sibyte/cfe/setup.c
--- linux-2.4.19/arch/mips/sibyte/cfe/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/setup.c	2002-10-04 00:41:19.000000000 +0000
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+#include <linux/console.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/sibyte/board.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+/* Max ram addressable in 32-bit segments */
+#ifdef CONFIG_MIPS64
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0xffffffffULL)
+#endif
+#else
+#define MAX_RAM_SIZE (0x1fffffffULL)
+#endif
+#endif
+
+#define SB1250_DUART_MINOR_BASE		192 /* XXXKW put this somewhere sane */
+#define SB1250_PROMICE_MINOR_BASE	191 /* XXXKW put this somewhere sane */
+kdev_t cfe_consdev;
+
+#define SIBYTE_MAX_MEM_REGIONS 8
+phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
+phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
+unsigned int board_mem_region_count;
+
+/* This is the kernel command line.  Actually, it's
+   copied, eventually, to command_line, and looks to be
+   quite redundant.  But not something to fix just now */
+extern char arcs_cmdline[];
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+/* These are symbols defined by the ramdisk linker script */
+extern unsigned char __rd_start;
+extern unsigned char __rd_end;
+#endif
+
+#ifdef CONFIG_SMP
+static int reboot_smp = 0;
+#endif
+
+static void cfe_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		if (reboot_smp) {
+			/* Don't repeat the process from another CPU */
+			for (;;);
+		} else {
+			/* Get CPU 0 to do the cfe_exit */
+			reboot_smp = 1;
+			smp_call_function((void *)_machine_restart, NULL, 1, 0);
+			for (;;);
+		}
+	}
+#endif
+	printk("passing control back to CFE\n");
+	cfe_exit(1, 0);
+	printk("cfe_exit returned??\n");
+	while(1);
+}
+
+static __init void prom_meminit(void)
+{
+	u64 addr, size; /* regardless of 64BIT_PHYS_ADDR */
+	long type;
+	unsigned int idx;
+	int rd_flag;
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long initrd_pstart;
+	unsigned long initrd_pend;
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+	/* If we're using an embedded ramdisk, then __rd_start and __rd_end
+	   are defined by the linker to be on either side of the ramdisk
+	   area.  Otherwise, initrd_start should be defined by kernel command
+	   line arguments */
+	if (initrd_start == 0) {
+		initrd_start = (unsigned long)&__rd_start;
+		initrd_end = (unsigned long)&__rd_end;
+	}
+#endif
+
+	initrd_pstart = __pa(initrd_start);
+	initrd_pend = __pa(initrd_end);
+	if (initrd_start &&
+	    ((initrd_pstart > MAX_RAM_SIZE)
+	     || (initrd_pend > MAX_RAM_SIZE))) {
+		panic("initrd out of addressable memory");
+	}
+
+#endif /* INITRD */
+
+	for (idx = 0; cfe_enummem(idx, &addr, &size, &type) != CFE_ERR_NOMORE;
+	     idx++) {
+		rd_flag = 0;
+		if (type == CFE_MI_AVAILABLE) {
+			/*
+			 * See if this block contains (any portion of) the
+			 * ramdisk
+			 */
+#ifdef CONFIG_BLK_DEV_INITRD
+			if (initrd_start) {
+				if ((initrd_pstart > addr) &&
+				    (initrd_pstart < (addr + size))) {
+					add_memory_region(addr,
+					                  initrd_pstart - addr,
+					                  BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+				if ((initrd_pend > addr) &&
+				    (initrd_pend < (addr + size))) {
+					add_memory_region(initrd_pend,
+						(addr + size) - initrd_pend,
+						 BOOT_MEM_RAM);
+					rd_flag = 1;
+				}
+			}
+#endif
+			if (!rd_flag) {
+				if (addr > MAX_RAM_SIZE)
+					continue;
+				if (addr+size > MAX_RAM_SIZE)
+					size = MAX_RAM_SIZE - (addr+size) + 1;
+				/*
+				 * memcpy/__copy_user prefetch, which
+				 * will cause a bus error for
+				 * KSEG/KUSEG addrs not backed by RAM.
+				 * Hence, reserve some padding for the
+				 * prefetch distance.
+				 */
+				if (size > 512)
+					size -= 512;
+				add_memory_region(addr, size, BOOT_MEM_RAM);
+			}
+			board_mem_region_addrs[board_mem_region_count] = addr;
+			board_mem_region_sizes[board_mem_region_count] = size;
+			board_mem_region_count++;
+			if (board_mem_region_count ==
+			    SIBYTE_MAX_MEM_REGIONS) {
+				/*
+				 * Too many regions.  Need to configure more
+				 */
+				while(1);
+			}
+		}
+	}
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start) {
+		add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+				  BOOT_MEM_RESERVED);
+	}
+#endif
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int __init initrd_setup(char *str)
+{
+	/*
+	 *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
+	 *  e.g. initrd=3abfd@80010000.  This is set up by the loader.
+	 */
+	char *tmp, *endptr;
+	unsigned long initrd_size;
+	for (tmp = str; *tmp != '@'; tmp++) {
+		if (!*tmp) {
+			goto fail;
+		}
+	}
+	*tmp = 0;
+	tmp++;
+	if (!*tmp) {
+		goto fail;
+	}
+	initrd_size = simple_strtol(str, &endptr, 16);
+	if (*endptr) {
+		*(tmp-1) = '@';
+		goto fail;
+	}
+	*(tmp-1) = '@';
+	initrd_start = simple_strtol(tmp, &endptr, 16);
+	if (*endptr) {
+		goto fail;
+	}
+	initrd_end = initrd_start + initrd_size;
+	printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
+	return 1;
+ fail:
+	printk("Bad initrd argument.  Disabling initrd\n");
+	initrd_start = 0;
+	initrd_end = 0;
+	return 1;
+}
+
+#endif
+
+/*
+ * prom_init is called just after the cpu type is determined, from init_arch()
+ */
+__init int prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	_machine_restart   = (void (*)(char *))cfe_linux_exit;
+	_machine_halt      = cfe_linux_exit;
+	_machine_power_off = cfe_linux_exit;
+
+	/*
+	 * This should go away.  Detect if we're booting
+	 * straight from cfe without a loader.  If we
+	 * are, then we've got a prom vector in a0.  Otherwise,
+	 * argc (and argv and envp, for that matter) will be 0)
+	 */
+	if (argc < 0) {
+		prom_vec = (int *)argc;
+	}
+	cfe_init((long)prom_vec);
+	cfe_open_console();
+	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
+		if (argc < 0) {
+			/*
+			 * It's OK for direct boot to not provide a
+			 *  command line
+			 */
+			strcpy(arcs_cmdline, "root=/dev/ram0 ");
+#ifdef CONFIG_SIBYTE_PTSWARM
+			strcat(arcs_cmdline, "console=ttyS0,115200 ");
+#endif
+		} else {
+			/* The loader should have set the command line */
+			panic("LINUX_CMDLINE not defined in cfe.");
+		}
+	}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	{
+		char *ptr;
+		/* Need to find out early whether we've got an initrd.  So scan
+		   the list looking now */
+		for (ptr = arcs_cmdline; *ptr; ptr++) {
+			while (*ptr == ' ') {
+				ptr++;
+			}
+			if (!strncmp(ptr, "initrd=", 7)) {
+				initrd_setup(ptr+7);
+				break;
+			} else {
+				while (*ptr && (*ptr != ' ')) {
+					ptr++;
+				}
+			}
+		}
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/* Not sure this is needed, but it's the safe way. */
+	arcs_cmdline[CL_SIZE-1] = 0;
+
+	mips_machgroup = MACH_GROUP_SIBYTE;
+	prom_meminit();
+
+	return 0;
+}
+
+void prom_free_prom_memory(void)
+{
+	/* Not sure what I'm supposed to do here.  Nothing, I think */
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+	phys_t addr = pagenr << PAGE_SHIFT;
+	int i;
+	for (i = 0; i < board_mem_region_count; i++) {
+		if ((addr >= board_mem_region_addrs[i])
+		    && (addr < (board_mem_region_addrs[i] + board_mem_region_sizes[i]))) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_SIBYTE_CFE_CONSOLE
+
+static void cfe_console_write(struct console *cons, const char *str,
+                              unsigned int count)
+{
+	int i, last;
+
+	for (i=0,last=0; i<count; i++) {
+		if (!str[i])
+			/* XXXKW can/should this ever happen? */
+			panic("cfe_console_write with NULL");
+		if (str[i] == '\n') {
+			cfe_console_print(&str[last], i-last);
+			cfe_console_print("\r", 1);
+			last = i;
+		}
+	}
+	if (last != count)
+		cfe_console_print(&str[last], count-last);
+}
+
+static kdev_t cfe_console_device(struct console *c)
+{
+	return cfe_consdev;
+}
+
+static int cfe_console_setup(struct console *cons, char *str)
+{
+	char consdev[32];
+	cfe_open_console();
+	/* XXXKW think about interaction with 'console=' cmdline arg */
+	/* If none of the console options are configured, the build will break. */
+	if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) {
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+		if (!strcmp(consdev, "uart0")) {
+			setleds("u0cn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 0);
+#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+		} else if (!strcmp(consdev, "uart1")) {
+			setleds("u1cn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 1);
+#endif
+#endif
+#ifdef CONFIG_VGA_CONSOLE
+		} else if (!strcmp(consdev, "pcconsole0")) {
+			setleds("pccn");
+			cfe_consdev = MKDEV(TTY_MAJOR, 0);
+#endif
+#ifdef CONFIG_PROMICE
+		} else if (!strcmp(consdev, "promice0")) {
+			setleds("picn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_PROMICE_MINOR_BASE);
+#endif
+		} else
+			return -ENODEV;
+	}
+	return 0;
+}
+
+static struct console sb1250_cfe_cons = {
+	name:		"cfe",
+	write:		cfe_console_write,
+	device:		cfe_console_device,
+	setup:		cfe_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init sb1250_cfe_console_init(void)
+{
+	register_console(&sb1250_cfe_cons);
+}
+
+#endif /* CONFIG_SIBYTE_CFE_CONSOLE */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/cfe/smp.c linux-2.4.20/arch/mips/sibyte/cfe/smp.c
--- linux-2.4.19/arch/mips/sibyte/cfe/smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/cfe/smp.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/mipsregs.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+extern void asmlinkage smp_bootstrap(void);
+
+/* Boot all other cpus in the system, initialize them, and
+   bring them into the boot fn */
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
+{
+	int retval;
+
+	retval = cfe_start_cpu(cpu, &smp_bootstrap, sp, gp, 0);
+	if (retval != 0) {
+		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+void prom_init_secondary(void)
+{
+	/* Set up kseg0 to be cachable coherent */
+	clear_cp0_config(CONF_CM_CMASK);
+	set_cp0_config(0x5);
+
+	/* Enable interrupts for lines 0-4 */
+	clear_cp0_status(0xe000);
+	set_cp0_status(0x1f01);
+}
+
+/*
+ * Set up state, return the total number of cpus in the system, including
+ * the master
+ */
+int prom_setup_smp(void)
+{
+	int i;
+	int num_cpus = 1;
+
+	/* Use CFE to find out how many CPUs are available */
+	for (i=1; i<NR_CPUS; i++) {
+		if (cfe_stop_cpu(i) == 0) {
+			num_cpus++;
+		}
+	}
+	printk("Detected %i available CPU(s)\n", num_cpus);
+	return num_cpus;
+}
+
+void prom_smp_finish(void)
+{
+	extern void sb1250_smp_finish(void);
+	sb1250_smp_finish();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1/cache_err_handler.S linux-2.4.20/arch/mips/sibyte/sb1/cache_err_handler.S
--- linux-2.4.19/arch/mips/sibyte/sb1/cache_err_handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1/cache_err_handler.S	2002-10-04 00:41:29.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -20,6 +20,7 @@
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/sibyte/board.h>
 
 	.text
 	/* Special Cache Error handler for SB1 for now */
@@ -36,13 +37,12 @@
 	#.set	mips64
 	.set	mips4
 	.set	reorder
-	# look for signature of spurious CErr
+#ifdef CONFIG_SB1_CERR_IGNORE_RECOVERABLE
 	mfc0	k1, $26				# mfc0	k1, $26, 0
 	# check if error was recoverable
 	# XXXKW - count them
 	bltz	k1, leave_cerr
-	 nop
-
+#endif
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 	# look for signature of spurious CErr
 	lui	k0, 0x4000
@@ -51,13 +51,32 @@
 	lui	k0, 0xffe0
 	and	k1, k0, k1
 	lui	k0, 0x0200
-	bne	k0, k1, real_cerr
-	 nop
+	beq	k0, k1, leave_cerr
+	# XXXKW - count them
+#endif
+
+real_cerr:
+#ifdef CONFIG_SB1_CERR_SPIN
+        setleds(k0,k1,'C','E','R','R')
+
+1:	b	1b
 #else
-	j	real_cerr
-	 nop
+	mfc0	k0,CP0_CONFIG
+	li	k1,~CONF_CM_CMASK
+	and	k0,k0,k1
+	ori	k0,k0,CONF_CM_UNCACHED
+	mtc0	k0,CP0_CONFIG
+
+	SSNOP
+	SSNOP
+	SSNOP
+	SSNOP
+	bnezl	$0, 1f
+1:
+	j	sb1_cache_error
 #endif
-	# XXXKW - count spurious errors
+
+#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || defined(CONFIG_SB1_CERR_IGNORE_RECOVERABLE)
 leave_cerr:
 	# clear/unlock the registers
 	mtc0	zero, $26			# mtc0	zero, $26, 0
@@ -65,23 +84,7 @@
 	.word	0x4080d801			# mtc0	zero, $27, 1
 	.word	0x4080d803			# mtc0	zero, $27, 3
 	eret
-
-real_cerr:
-	mfc0	k0, CP0_CONFIG
-	li	k1, ~CONF_CM_CMASK
-	and	k0, k0, k1
-	ori	k0, k0, CONF_CM_UNCACHED
-	mtc0	k0, CP0_CONFIG
-	/* Give it a few cycles to sink in... */
-	sll     zero, zero, 0x1			# ssnop
-	sll     zero, zero, 0x1			# ssnop
-	sll     zero, zero, 0x1			# ssnop
-	sll     zero, zero, 0x1			# ssnop
-	sll     zero, zero, 0x1			# ssnop
-	sll     zero, zero, 0x1			# ssnop
-
-	j	sb1_cache_error
-	 nop
+#endif
 
 	.set	pop
 	END(except_vec2_sb1)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1/cache_error.c linux-2.4.20/arch/mips/sibyte/sb1/cache_error.c
--- linux-2.4.19/arch/mips/sibyte/sb1/cache_error.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1/cache_error.c	2002-10-04 00:41:29.000000000 +0000
@@ -16,10 +16,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <linux/kernel.h>
+#include <linux/sched.h>
 #include <asm/mipsregs.h>
 
 /* SB1 definitions */
+
+/* XXX should come from config1 XXX */
+#define SB1_CACHE_INDEX_MASK   0x1fe0
+
 #define CP0_ERRCTL_RECOVERABLE (1 << 31)
 #define CP0_ERRCTL_DCACHE      (1 << 30)
 #define CP0_ERRCTL_ICACHE      (1 << 29)
@@ -30,7 +34,9 @@
 #define CP0_CERRI_TAG_PARITY   (1 << 29)
 #define CP0_CERRI_DATA_PARITY  (1 << 28)
 #define CP0_CERRI_EXTERNAL     (1 << 26)
-#define CP0_CERRI_CACHE_IDX    (0xff << 5)
+
+#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
+#define CP0_CERRI_DATA         (CP0_CERRI_DATA_PARITY)
 
 #define CP0_CERRD_MULTIPLE     (1 << 31)
 #define CP0_CERRD_TAG_STATE    (1 << 30)
@@ -43,38 +49,463 @@
 #define CP0_CERRD_FILLWB       (1 << 23)
 #define CP0_CERRD_COHERENCY    (1 << 22)
 #define CP0_CERRD_DUPTAG       (1 << 21)
-#define CP0_CERRD_CACHE_IDX    (0xff << 5)
 
-asmlinkage void sb1_cache_error(void)
+#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
+#define CP0_CERRD_IDX_VALID(c) \
+   (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
+#define CP0_CERRD_CAUSES \
+   (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
+#define CP0_CERRD_TYPES \
+   (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
+#define CP0_CERRD_DATA         (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
+
+static uint32_t	extract_ic(unsigned short addr, int data);
+static uint32_t	extract_dc(unsigned short addr, int data);
+
+spinlock_t in_cacheerr = SPIN_LOCK_UNLOCKED;
+
+static inline void breakout_errctl(unsigned int val)
 {
-	unsigned int errctl, cerr_i, cerr_d, cerr_dpa;
-	unsigned long eepc;
+	if (val & CP0_ERRCTL_RECOVERABLE)
+		printk(" recoverable");
+	if (val & CP0_ERRCTL_DCACHE)
+		printk(" dcache");
+	if (val & CP0_ERRCTL_ICACHE)
+		printk(" icache");
+	if (val & CP0_ERRCTL_MULTIBUS)
+		printk(" multiple-buserr");
+	printk("\n");
+}
 
-	eepc = get_errorepc();
+static inline void breakout_cerri(unsigned int val)
+{
+	if (val & CP0_CERRI_TAG_PARITY)
+		printk(" tag-parity");
+	if (val & CP0_CERRI_DATA_PARITY)
+		printk(" data-parity");
+	if (val & CP0_CERRI_EXTERNAL)
+		printk(" external");
+	printk("\n");
+}
+
+static inline void breakout_cerrd(unsigned int val)
+{
+	switch (val & CP0_CERRD_CAUSES) {
+	case CP0_CERRD_LOAD:
+		printk(" load,");
+		break;
+	case CP0_CERRD_STORE:
+		printk(" store,");
+		break;
+	case CP0_CERRD_FILLWB:
+		printk(" fill/wb,");
+		break;
+	case CP0_CERRD_COHERENCY:
+		printk(" coherency,");
+		break;
+	case CP0_CERRD_DUPTAG:
+		printk(" duptags,");
+		break;
+	default:
+		printk(" NO CAUSE,");
+		break;
+	}
+	if (!(val & CP0_CERRD_TYPES))
+		printk(" NO TYPE");
+	else {
+		if (val & CP0_CERRD_MULTIPLE)
+			printk(" multi-err");
+		if (val & CP0_CERRD_TAG_STATE)
+			printk(" tag-state");
+		if (val & CP0_CERRD_TAG_ADDRESS)
+			printk(" tag-address");
+		if (val & CP0_CERRD_DATA_SBE)
+			printk(" data-SBE");
+		if (val & CP0_CERRD_DATA_DBE)
+			printk(" data-DBE");
+		if (val & CP0_CERRD_EXTERNAL)
+			printk(" external");
+	}
+	printk("\n");
+}
 
+asmlinkage void sb1_cache_error(void)
+{
+	uint64_t cerr_dpa;
+	uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+
+	/* Prevent re-entrance in the SMP case */
+	spin_lock(&in_cacheerr);
+	printk("Cache error exception on CPU %x:\n",
+	       (read_32bit_cp0_register(CP0_PRID) >> 25) & 0x7);
 	__asm__ __volatile__ (
-		".set push\n"
-		"#.set mips64\n"
-		".set mips4\n"
-		".word 0x4001D000; move %0, $1; # mfc0 %0, $26, 0\n"
-		".word 0x4001D800; move %1, $1; # mfc0 %1, $27, 0\n"
-		".word 0x4001D801; move %2, $1; # mfc0 %2, $27, 1\n"
-		".word 0x4001D803; move %3, $1; # mfc0 %3, $27, 3\n"
+		".set push\n\t"
+		".set mips64\n\t"
+		".set noat\n\t"
+		"mfc0   %0, $26, 0\n\t"
+		"mfc0   %1, $27, 0\n\t"
+		"mfc0   %2, $27, 1\n\t"
+		"dmfc0  $1, $27, 3\n\t"
+		"dsrl32 %3, $1, 0 \n\t"
+		"sll    %4, $1, 0 \n\t"
+		"mfc0   %5, $30\n\t"
 		".set pop\n"
-		: "=r" (errctl), "=r" (cerr_i),
-		  "=r" (cerr_d), "=r" (cerr_dpa));
+		: "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d),
+		  "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
+	cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
+	printk(" cp0_errorepc ==   %08x\n", eepc);
+	printk(" cp0_errctl   ==   %08x", errctl);
+	breakout_errctl(errctl);
+	if (errctl & CP0_ERRCTL_ICACHE) {
+		printk(" cp0_cerr_i   ==   %08x", cerr_i);
+		breakout_cerri(cerr_i);
+		if (CP0_CERRI_IDX_VALID(cerr_i)) {
+			if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK))
+				printk(" cerr_i idx doesn't match eepc\n");
+			else {
+				res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
+						 (cerr_i & CP0_CERRI_DATA) != 0);
+				if (!(res & cerr_i))
+					printk("...didn't see indicated icache problem\n");
+			}
+		}
+	}
+	if (errctl & CP0_ERRCTL_DCACHE) {
+		printk(" cp0_cerr_d   ==   %08x", cerr_d);
+		breakout_cerrd(cerr_d);
+		if (CP0_CERRD_DPA_VALID(cerr_d)) {
+			printk(" cp0_cerr_dpa == %010llx\n", cerr_dpa);
+			if (!CP0_CERRD_IDX_VALID(cerr_d)) {
+				res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
+						 (cerr_d & CP0_CERRD_DATA) != 0);
+				if (!(res & cerr_d))
+					printk("...didn't see indicated dcache problem\n");
+			} else {
+				if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
+					printk(" cerr_d idx doesn't match cerr_dpa\n");
+				else {
+					res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
+							 (cerr_d & CP0_CERRD_DATA) != 0);
+					if (!(res & cerr_d))
+						printk("...didn't see indicated problem\n");
+				}
+			}
+		}
+	}
 
-	printk("Cache error exception:\n");
-	printk(" cp0_errorepc == 0x%0lx\n", eepc);
-	printk(" cp0_errctl   == 0x%08x\n", errctl);
+	while (1);
+	/*
+	 * This tends to make things get really ugly; let's just stall instead.
+	 *    panic("Can't handle the cache error!");
+	 */
+}
 
-	if (errctl & CP0_ERRCTL_DCACHE) {
-		printk(" cp0_cerr_d   == 0x%08x\n", cerr_d);
-		printk(" cp0_cerr_dpa == 0x%08x\n", cerr_dpa);
+
+/* Parity lookup table. */
+static const uint8_t parity[256] = {
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
+};
+
+/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
+static const uint64_t mask_72_64[8] = {
+	0x0738C808099264FFL,
+	0x38C808099264FF07L,
+	0xC808099264FF0738L,
+	0x08099264FF0738C8L,
+	0x099264FF0738C808L,
+	0x9264FF0738C80809L,
+	0x64FF0738C8080992L,
+	0xFF0738C808099264L
+};
+
+/* Calculate the parity on a range of bits */
+static char range_parity(uint64_t dword, int max, int min)
+{
+	char parity = 0;
+	int i;
+	dword >>= min;
+	for (i=max-min; i>=0; i--) {
+		if (dword & 0x1)
+			parity = !parity;
+		dword >>= 1;
 	}
-	if (errctl & CP0_ERRCTL_ICACHE) {
-		printk(" cp0_cerr_i   == 0x%08x\n", cerr_i);
+	return parity;
+}
+
+/* Calculate the 4-bit even byte-parity for an instruction */
+static unsigned char inst_parity(uint32_t word)
+{
+	int i, j;
+	char parity = 0;
+	for (j=0; j<4; j++) {
+		char byte_parity = 0;
+		for (i=0; i<8; i++) {
+			if (word & 0x80000000)
+				byte_parity = !byte_parity;
+			word <<= 1;
+		}
+		parity <<= 1;
+		parity |= byte_parity;
 	}
+	return parity;
+}
+
+static uint32_t extract_ic(unsigned short addr, int data)
+{
+	unsigned short way;
+	int valid;
+	uint64_t taglo, va, tlo_tmp;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t lru;
+	int res = 0;
+
+	printk("Icache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		/* Index-load-tag-I */
+		__asm__ __volatile__ (
+			".set push        \n\t"
+			".set noreorder   \n\t"
+			".set mips64      \n\t"
+			".set noat        \n\t"
+			"cache  4, 0(%3)  \n\t"
+			"mfc0   %0, $29, 0\n\t"
+			"dmfc0  $1, $28, 0\n\t"
+			"dsrl32 %1, $1, 0 \n\t"
+			"sll    %2, $1, 0 \n\t"
+			".set pop         \n"
+			: "=r" (taghi), "=r" (taglohi),
+			  "=r" (taglolo)
+			: "r" ((way << 13) | addr));
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+			       ((addr >> 5) & 0x3), /* bank */
+			       ((addr >> 7) & 0x3f), /* index */
+			       (lru & 0x3),
+			       ((lru >> 2) & 0x3),
+			       ((lru >> 4) & 0x3),
+			       ((lru >> 6) & 0x3));
+		}
+		va = (taglo & 0xC0000FFFFFFFE000) | addr;
+		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
+			va |= 0x3FFFF00000000000;
+		valid = ((taghi >> 29) & 1);
+		if (valid) {
+			tlo_tmp = taglo & 0xfff3ff;
+			if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
+				printk("   ** bad parity in VTag0/G/ASID\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
+				printk("   ** bad parity in R/VTag1\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+		}
+		if (valid ^ ((taghi >> 27) & 1)) {
+			printk("   ** bad parity for valid bit\n");
+			res |= CP0_CERRI_TAG_PARITY;
+		}
+		printk(" %d  [VA %016llx]  [Vld? %d]  raw tags: %08X-%016llX\n",
+		       way, va, valid, taghi, taglo);
+
+		if (data) {
+			uint32_t datahi, insta, instb;
+			uint8_t predecode;
+			int offset;
 
-	panic("Can't handle the cache error!");
+			/* (hit all banks and ways) */
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-I */
+				__asm__ __volatile__ (
+					".set push        \n\t"
+					".set noreorder   \n\t"
+					".set mips64      \n\t"
+					".set noat        \n\t"
+					"cache  6, 0(%3)  \n\t"
+					"mfc0   %0, $29, 1\n\t"
+					"dmfc0  $1, $28, 1\n\t"
+					"dsrl32 %1, $1, 0 \n\t"
+					"sll    %2, $1, 0 \n\t"
+					".set pop         \n"
+					: "=r" (datahi), "=r" (insta),
+					  "=r" (instb)
+					: "r" ((way << 13) | addr | (offset << 3)));
+				predecode = (datahi >> 8) & 0xff;
+				if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
+					printk("   ** bad parity in predecode\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				/* XXXKW should/could check predecode bits themselves */
+				if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
+					printk("   ** bad parity in instruction a\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				if ((datahi & 0xf) ^ inst_parity(instb)) {
+					printk("   ** bad parity in instruction b\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				printk("  %05X-%08X%08X", datahi, insta, instb);
+			}
+			printk("\n");
+		}
+	}
+	return res;
+}
+
+/* Compute the ECC for a data doubleword */
+static uint8_t dc_ecc(uint64_t dword)
+{
+	uint64_t t;
+	uint32_t w;
+	uint8_t  p;
+	int      i;
+
+	p = 0;
+	for (i = 7; i >= 0; i--)
+	{
+		p <<= 1;
+		t = dword & mask_72_64[i];
+		w = (uint32_t)(t >> 32);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+		w = (uint32_t)(t & 0xFFFFFFFF);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+	}
+	return p;
+}
+
+struct dc_state {
+	unsigned char val;
+	char *name;
+};
+
+static struct dc_state dc_states[] = {
+	{ 0x00, "INVALID" },
+	{ 0x0f, "COH-SHD" },
+	{ 0x13, "NCO-E-C" },
+	{ 0x19, "NCO-E-D" },
+	{ 0x16, "COH-E-C" },
+	{ 0x1c, "COH-E-D" },
+	{ 0xff, "*ERROR*" }
+};
+
+#define DC_TAG_VALID(state) \
+    (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
+
+static char *dc_state_str(unsigned char state)
+{
+	struct dc_state *dsc = dc_states;
+	while (dsc->val != 0xff) {
+		if (dsc->val == state)
+			break;
+		dsc++;
+	}
+	return dsc->name;
+}
+
+static uint32_t extract_dc(unsigned short addr, int data)
+{
+	int valid, way;
+	unsigned char state;
+	uint64_t taglo, pa;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t ecc, lru;
+	int res = 0;
+
+	printk("Dcache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		/* Index-load-tag-D */
+		__asm__ __volatile__ (
+			".set push        \n\t"
+			".set noreorder   \n\t"
+			".set mips64      \n\t"
+			".set noat        \n\t"
+			"cache  5, 0(%3)  \n\t"
+			"mfc0   %0, $29, 2\n\t"
+			"dmfc0  $1, $28, 2\n\t"
+			"dsrl32 %1, $1, 0 \n\t"
+			"sll    %2, $1, 0 \n\t"
+			".set pop         \n"
+			: "=r" (taghi), "=r" (taglohi),
+			  "=r" (taglolo)
+			: "r" ((way << 13) | addr));
+
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		pa = (taglo & 0xFFFFFFE000) | addr;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+			       ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
+			       ((addr >> 6) & 0x3f), /* index */
+			       (lru & 0x3),
+			       ((lru >> 2) & 0x3),
+			       ((lru >> 4) & 0x3),
+			       ((lru >> 6) & 0x3));
+		}
+		state = (taghi >> 25) & 0x1f;
+		valid = DC_TAG_VALID(state);
+		printk(" %d  [PA %010llx]  [state %s (%02x)]  raw tags: %08X-%016llX\n",
+		       way, pa, dc_state_str(state), state, taghi, taglo);
+		if (valid) {
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
+				printk("   ** bad parity in PTag1\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+			if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
+				printk("   ** bad parity in PTag0\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+		} else {
+			res |= CP0_CERRD_TAG_STATE;
+		}
+
+		if (data) {
+			uint64_t datalo;
+			uint32_t datalohi, datalolo, datahi;
+			int offset;
+
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-D */
+				__asm__ __volatile__ (
+					".set push        \n\t"
+					".set noreorder   \n\t"
+					".set mips64      \n\t"
+					".set noat        \n\t"
+					"cache  7, 0(%3)  \n\t"
+					"mfc0   %0, $29, 3\n\t"
+					"dmfc0  $1, $28, 3\n\t"
+					"dsrl32 %1, $1, 0 \n\t"
+					"sll    %2, $1, 0 \n\t"
+					".set pop         \n"
+					: "=r" (datahi), "=r" (datalohi),
+					"=r" (datalolo)
+					: "r" ((way << 13) | addr | (offset << 3)));
+				datalo = ((unsigned long long)datalohi << 32) | datalolo;
+				ecc = dc_ecc(datalo);
+				if (ecc != datahi) {
+					int bits = 0;
+					printk("  ** bad ECC (%02x %02x) ->",
+					       datahi, ecc);
+					ecc ^= datahi;
+					while (ecc) {
+						if (ecc & 1) bits++;
+						ecc >>= 1;
+					}
+					res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
+				}
+				printk("  %02X-%016llX", datahi, datalo);
+			}
+			printk("\n");
+		}
+	}
+	return res;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/Makefile linux-2.4.20/arch/mips/sibyte/sb1250/Makefile
--- linux-2.4.19/arch/mips/sibyte/sb1250/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/Makefile	2002-10-04 00:41:11.000000000 +0000
@@ -2,11 +2,12 @@
 
 O_TARGET := sb1250.o
 
-obj-y := irq.o irq_handler.o time.o
+obj-y := setup.o irq.o irq_handler.o time.o
 
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_BCM1250_TBPROF)	+= bcm1250_tbprof.o
 obj-$(CONFIG_MIPS32)		+= lib_hssubr.o
+obj-$(CONFIG_SIBYTE_STANDALONE)	+= prom.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2002-10-04 00:41:11.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -50,20 +50,26 @@
  * overflow.
  *
  * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
- * 
+ *
  ************************************************************************/
 
-/* Once per second on a 500 Mhz 1250 */
-#define TB_PERIOD 250000000ULL
+/* 100 samples per second on a 500 Mhz 1250 */
+#define TB_PERIOD 2500000ULL
 
 static void arm_tb(void)
 {
+        unsigned long long scdperfcnt;
 	unsigned long long next = (1ULL << 40) - TB_PERIOD;
 	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
 	   trigger start of trace.  XXX vary sampling period */
 	out64(0, KSEG1 + A_SCD_PERF_CNT_1);
-	out64(in64(KSEG1 + A_SCD_PERF_CNT_CFG) | // keep counters 0,2,3 as is
+	scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG);
+	/* Unfortunately, in Pass 2 we must clear all counters to knock down
+	   a previous interrupt request.  This means that bus profiling
+	   requires ALL of the SCD perf counters. */
+	out64((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
 		   M_SPC_CFG_ENABLE |		 // enable counting
+		   M_SPC_CFG_CLEAR |		 // clear all counters
 		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
 	      KSEG1 + A_SCD_PERF_CNT_CFG);
 	out64(next, KSEG1 + A_SCD_PERF_CNT_1);
@@ -150,17 +156,17 @@
 	out64(0, KSEG1 + A_ADDR_TRAP_UP_1);
 	out64(0, KSEG1 + A_ADDR_TRAP_UP_2);
 	out64(0, KSEG1 + A_ADDR_TRAP_UP_3);
-	
+
 	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_0);
 	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_1);
 	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_2);
 	out64(0, KSEG1 + A_ADDR_TRAP_DOWN_3);
-	
+
 	out64(0, KSEG1 + A_ADDR_TRAP_CFG_0);
 	out64(0, KSEG1 + A_ADDR_TRAP_CFG_1);
 	out64(0, KSEG1 + A_ADDR_TRAP_CFG_2);
 	out64(0, KSEG1 + A_ADDR_TRAP_CFG_3);
-	
+
 	/* Initialize Trace Event 0-7 */
 	//				when interrupt
 	out64(M_SCD_TREVT_INTERRUPT, KSEG1 + A_SCD_TRACE_EVENT_0);
@@ -171,7 +177,7 @@
 	out64(0, KSEG1 + A_SCD_TRACE_EVENT_5);
 	out64(0, KSEG1 + A_SCD_TRACE_EVENT_6);
 	out64(0, KSEG1 + A_SCD_TRACE_EVENT_7);
-	
+
 	/* Initialize Trace Sequence 0-7 */
 	//				     Start on event 0 (interrupt)
 	out64(V_SCD_TRSEQ_FUNC_START|0x0fff,
@@ -252,7 +258,7 @@
 static int sbprof_tb_release(struct inode *inode, struct file *filp)
 {
 	int minor;
-	
+
 	minor = MINOR(inode->i_rdev);
 	if (minor != 0 || sbp == NULL) {
 		return -ENODEV;
@@ -269,7 +275,7 @@
 	return 0;
 }
 
-static ssize_t sbprof_tb_read(struct file *filp, char *buf, 
+static ssize_t sbprof_tb_read(struct file *filp, char *buf,
 			   size_t size, loff_t *offp)
 {
 	int cur_sample, sample_off, cur_count, sample_left;
@@ -309,9 +315,9 @@
 #define SBPROF_ZBSTOP	_IOW('s', 1, int)
 #define SBPROF_ZBFULL	_IOW('s', 2, int)
 
-static int sbprof_tb_ioctl(struct inode *inode, 
+static int sbprof_tb_ioctl(struct inode *inode,
 			struct file *filp,
-			unsigned int command, 
+			unsigned int command,
 			unsigned long arg)
 {
 	int error = 0;
@@ -346,7 +352,7 @@
 
 static devfs_handle_t devfs_handle;
 
-static int __init sbprof_tb_init(void) 
+static int __init sbprof_tb_init(void)
 {
 	if (devfs_register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
 		printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.h linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.h
--- linux-2.4.19/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	2002-10-04 00:41:11.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/irq.c linux-2.4.20/arch/mips/sibyte/sb1250/irq.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/irq.c	2002-10-04 00:41:30.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -23,21 +23,24 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+
 #include <asm/errno.h>
 #include <asm/signal.h>
 #include <asm/system.h>
 #include <asm/ptrace.h>
+
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_uart.h>
 #include <asm/sibyte/sb1250_scd.h>
 #include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/64bit.h>
 
 /*
- * These are the routines that handle all the low level interrupt stuff. 
+ * These are the routines that handle all the low level interrupt stuff.
  * Actions handled here are: initialization of the interrupt map, requesting of
  * interrupt lines by handlers, dispatching if interrupts to handlers, probing
- * for interrupt lines 
+ * for interrupt lines
  */
 
 
@@ -50,6 +53,15 @@
 
 #ifdef CONFIG_REMOTE_DEBUG
 extern void breakpoint(void);
+extern void set_debug_traps(void);
+
+/* kgdb is on when configured.  Pass "nokgdb" kernel arg to turn it off */
+static int kgdb_flag = 1;
+static int __init nokgdb(char *str)
+{
+	kgdb_flag = 0;
+}
+__setup("nokgdb", nokgdb);
 #endif
 
 #define NR_IRQS 64
@@ -155,11 +167,44 @@
 }
 
 
+static void sb1250_dummy_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+}
+
+static struct irqaction sb1250_dummy_action = {
+	handler: sb1250_dummy_handler,
+	flags:   0,
+	mask:    0,
+	name:    "sb1250-private",
+	next:    NULL,
+	dev_id:  0
+};
+
+int sb1250_steal_irq(int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+	int retval = 0;
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&desc->lock,flags);
+	/* Don't allow sharing at all for these */
+	if (desc->action != NULL)
+		retval = -EBUSY;
+	else {
+		desc->action = &sb1250_dummy_action;
+		desc->depth = 0;
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+}
+
 /*
  *  init_IRQ is called early in the boot sequence from init/main.c.  It
  *  is responsible for setting up the interrupt mapper and installing the
  *  handler that will be responsible for dispatching interrupts to the
- *  "right" place. 
+ *  "right" place.
  */
 /*
  * For now, map all interrupts to IP[2].  We could save
@@ -167,10 +212,10 @@
  * IP lines, but keep it simple for bringup.  We'll also direct
  * all interrupts to a single CPU; we should probably route
  * PCI and LDT to one cpu and everything else to the other
- * to balance the load a bit. 
- * 
+ * to balance the load a bit.
+ *
  * On the second cpu, everything is set to IP5, which is
- * ignored, EXCEPT the mailbox interrupt.  That one is 
+ * ignored, EXCEPT the mailbox interrupt.  That one is
  * set to IP[2] so it is handled.  This is needed so we
  * can do cross-cpu function calls, as requred by SMP
  */
@@ -178,12 +223,16 @@
 #define IMR_IP2_VAL	K_INT_MAP_I0
 #define IMR_IP3_VAL	K_INT_MAP_I1
 #define IMR_IP4_VAL	K_INT_MAP_I2
+#define IMR_IP5_VAL	K_INT_MAP_I3
+#define IMR_IP6_VAL	K_INT_MAP_I4
 
 void __init init_IRQ(void)
 {
 
 	unsigned int i;
 	u64 tmp;
+	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+		STATUSF_IP1 | STATUSF_IP0;
 
 	/* Default everything to IP2 */
 	for (i = 0; i < NR_IRQS; i++) {	/* was I0 */
@@ -220,26 +269,60 @@
 	out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
 	out64(tmp, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK));
 
+	sb1250_steal_irq(K_INT_MBOX_0);
+
 	/*
-	 * Note that the timer interrupts are also mapped, but this is 
+	 * Note that the timer interrupts are also mapped, but this is
 	 * done in sb1250_time_init()
 	 */
 
-#ifdef CONFIG_SIBYTE_SB1250_PROF
-	/* Enable IP[7,4:0], disable the rest */
-	clear_cp0_status(0x6000);
-	set_cp0_status(0x9f00);
-#else
-	/* Enable IP[4:0], disable the rest */
-	clear_cp0_status(0xe000);
-	set_cp0_status(0x1f00);
+#ifdef CONFIG_BCM1250_PROF
+	imask |= STATUSF_IP7;
+#endif
+#ifdef CONFIG_REMOTE_DEBUG
+	imask |= STATUSF_IP6;
 #endif
+	/* Enable necessary IPs, disable the rest */
+	change_cp0_status(ST0_IM, imask);
 	set_except_vector(0, sb1250_irq_handler);
 
 #ifdef CONFIG_REMOTE_DEBUG
-	/* If local serial I/O used for debug port, enter kgdb at once */
-//      puts("Waiting for kgdb to connect...");
-	set_debug_traps();
-	breakpoint();
+	if (kgdb_flag) {
+		/* Setup uart 1 settings, mapper */
+		out64(M_DUART_IMR_BRK, KSEG1 + A_DUART + R_DUART_IMR_B);
+
+		out64(IMR_IP6_VAL,
+			KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_UART_1<<3));
+		tmp = in64(KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
+		tmp &= ~(1<<K_INT_UART_1);
+		out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
+
+		set_debug_traps();
+		breakpoint();
+	}
 #endif
 }
+
+#ifdef CONFIG_REMOTE_DEBUG
+
+#include <linux/delay.h>
+
+extern void set_async_breakpoint(unsigned int epc);
+
+#define duart_out(reg, val)     out64(val, KSEG1 + A_DUART_CHANREG(1,reg))
+#define duart_in(reg)           in64(KSEG1 + A_DUART_CHANREG(1,reg))
+
+void sb1250_kgdb_interrupt(struct pt_regs *regs)
+{
+	/*
+	 * Clear break-change status (allow some time for the remote
+	 * host to stop the break, since we would see another
+	 * interrupt on the end-of-break too)
+	 */
+	mdelay(500);
+	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+				M_DUART_RX_EN | M_DUART_TX_EN);
+	if (!user_mode(regs))
+		set_async_breakpoint(regs->cp0_epc);
+}
+#endif 	/* CONFIG_REMOTE_DEBUG */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/irq_handler.S linux-2.4.20/arch/mips/sibyte/sb1250/irq_handler.S
--- linux-2.4.19/arch/mips/sibyte/sb1250/irq_handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/irq_handler.S	2002-10-04 00:41:14.000000000 +0000
@@ -10,12 +10,12 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
- 
+
 /*
  * sb1250_handle_int() is the routine that is actually called when an interrupt
  * occurs.  It is installed as the exception vector handler in init_IRQ() in
@@ -23,10 +23,10 @@
  *
  * In the handle we figure out which interrupts need handling, and use that to
  * call the dispatcher, which will take care of actually calling registered
- * handlers 
- * 
+ * handlers
+ *
  * Note that we take care of all raised interrupts in one go at the handler.
- * This is more BSDish than the Indy code, and also, IMHO, more sane. 
+ * This is more BSDish than the Indy code, and also, IMHO, more sane.
  */
 #include <linux/config.h>
 
@@ -40,15 +40,15 @@
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_int.h>
 
-/* 
+/*
  * What a pain. We have to be really careful saving the upper 32 bits of any
- * register across function calls if we don't want them trashed--since were 
+ * register across function calls if we don't want them trashed--since were
  * running in -o32, the calling routing never saves the full 64 bits of a
  * register across a function call.  Being the interrupt handler, we're
  * guaranteed that interrupts are disabled during this code so we don't have
  * to worry about random interrupts blasting the high 32 bits.
  */
- 
+
 	.text
 	.set	push
 	.set	noreorder
@@ -77,8 +77,13 @@
 	mfc0	a0, CP0_EPC
 	jal	sbprof_cpu_intr
 	 addu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
+	/* Re-enable interrupts here so that events due to sbprof_cpu_intr
+	   get charged to ret_from_irq (via a recursive interrupt)
+	   rather than the restart pc. */
+	mfc0	t0, CP0_STATUS
+	or	t0, ST0_IE
 	j	ret_from_irq
-	 nop				# delay slot
+	 mtc0	t0, CP0_STATUS		# delay slot
 0:
 #endif
 	/* Timer interrupt is routed to IP[4] */
@@ -97,12 +102,24 @@
 	beqz	 t1, 2f
          nop
 	jal	 sb1250_mailbox_interrupt
-	 move    a0, sp		
+	 move    a0, sp
 	j	ret_from_irq
 	 nop				# delay slot
 2:
 #endif
 
+#ifdef CONFIG_REMOTE_DEBUG
+	/* KGDB (uart 1) interrupt is routed to IP[6] */
+	andi	t1, s0, CAUSEF_IP6
+	beqz	t1, 1f
+	nop                            # delay slot
+	jal	sb1250_kgdb_interrupt
+         move	a0, sp
+	j	ret_from_irq
+	nop                            # delay slot
+1:
+#endif
+
 	and      t1, s0, CAUSEF_IP2
 	beqz     t1, 4f
 	 nop
@@ -120,7 +137,7 @@
 3:	#dclz	s1, s0		/* Find the next interrupt */
 	.word   0x72118824	# dclz s1, s0
 	dsubu	a0, zero, s1
-	daddiu	a0, a0, 63     
+	daddiu	a0, a0, 63
 	jal	 do_IRQ
 	 nop
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/lib_hssubr.S linux-2.4.20/arch/mips/sibyte/sb1250/lib_hssubr.S
--- linux-2.4.19/arch/mips/sibyte/sb1250/lib_hssubr.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/lib_hssubr.S	2002-10-04 00:41:11.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -22,7 +22,7 @@
 
 		 .set mips64
 
-#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP 
+#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP
 
 
 /*  *********************************************************************
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/lib_hssubr.h linux-2.4.20/arch/mips/sibyte/sb1250/lib_hssubr.h
--- linux-2.4.19/arch/mips/sibyte/sb1250/lib_hssubr.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/lib_hssubr.h	2002-10-04 00:41:22.000000000 +0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2000, 2001 Broadcom Corporation
+ * Copyright (C) 2002 Ralf Baechle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,45 +11,71 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
-
 #ifndef _LIB_HSSUBR_H
 #define _LIB_HSSUBR_H
 
-/*
- * If __long64 we can do this via macros.  Otherwise, call
- * the magic functions.
- */
-
-#if __long64
+#include <linux/config.h>
+#include <asm/addrspace.h>
 
 typedef long hsaddr_t;
 
-#define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
-#define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
-#define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
-#define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
-#define hs_read8(a) *((volatile uint8_t *) (a))
-#define hs_read16(a) *((volatile uint16_t *) (a))
-#define hs_read32(a) *((volatile uint32_t *) (a))
-#define hs_read64(a) *((volatile uint64_t *) (a))
+#ifdef CONFIG_MIPS64
 
-#else	/* not __long64 */
-
-typedef long hsaddr_t;
-
-extern void hs_write8(hsaddr_t a,uint8_t b);
-extern void hs_write16(hsaddr_t a,uint16_t b);
-extern void hs_write32(hsaddr_t a,uint32_t b);
-extern void hs_write64(hsaddr_t a,uint64_t b);
+static inline void hs_write8(hsaddr_t a, uint8_t b)
+{
+	*(volatile uint8_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write16(hsaddr_t a, uint16_t b)
+{
+	*(volatile uint16_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write32(hsaddr_t a, uint32_t b)
+{
+	*(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write64(hsaddr_t a, uint64_t b)
+{
+	*(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline uint8_t hs_read8(hsaddr_t a)
+{
+	return *(volatile uint8_t *) a;
+}
+
+static inline uint16_t hs_read16(hsaddr_t a)
+{
+	return *(volatile uint16_t *) a;
+}
+
+static inline uint32_t hs_read32(hsaddr_t a)
+{
+	return *(volatile uint32_t *) a;
+}
+
+static inline uint64_t hs_read64(hsaddr_t a)
+{
+	return *(volatile uint64_t *) a;
+}
+
+#else	/* just CONFIG_MIPS32 */
+
+extern void hs_write8(hsaddr_t a, uint8_t b);
+extern void hs_write16(hsaddr_t a, uint16_t b);
+extern void hs_write32(hsaddr_t a, uint32_t b);
+extern void hs_write64(hsaddr_t a, uint64_t b);
 extern uint8_t hs_read8(hsaddr_t a);
 extern uint16_t hs_read16(hsaddr_t a);
 extern uint32_t hs_read32(hsaddr_t a);
 extern uint64_t hs_read64(hsaddr_t a);
 #endif
 
-#endif
+#endif /* _LIB_HSSUBR_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/pci.c linux-2.4.20/arch/mips/sibyte/sb1250/pci.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/pci.c	2002-10-04 00:41:11.000000000 +0000
@@ -10,20 +10,20 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 /*
- * SB1250-specific PCI support
+ * BCM1250-specific PCI support
  *
  * This module provides the glue between Linux's PCI subsystem
  * and the hardware.  We basically provide glue for accessing
  * configuration space, and set up the translation for I/O
  * space accesses.
- * 
+ *
  * To access configuration space, we call some assembly-level
  * stubs that flip the KX bit on and off in the status
  * register, and do XKSEG addressed memory accesses there.
@@ -41,9 +41,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/console.h>
 
 #include <asm/sibyte/sb1250_defs.h>
 #include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
 #include <asm/io.h>
 
 #include "lib_hssubr.h"
@@ -56,11 +58,8 @@
 #define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
 
 /*
- * Using the above offset, this macro calcuates the actual
- * address.  Note that the physical address is not accessible
- * without remapping or setting KX.  We use 'match bits'
- * as our endian policy to guarantee that 32-bit accesses
- * look the same from either endianness.
+ * Using the above offset, this macro calcuates the physical address in the
+ * config space.
  */
 #define CFGADDR(dev,where) (A_PHYS_LDTPCI_CFG_MATCH_BITS + \
 			    CFGOFFSET(dev->bus->number,dev->devfn,where))
@@ -68,17 +67,22 @@
 /*
  * Read/write 32-bit values in config space.
  */
+static inline u32 READCFG32(u32 addr)
+{
+	hs_read32(addr & ~3);
+}
 
-#define READCFG32(addr) hs_read32((addr)&~3)
-#define WRITECFG32(addr,data) hs_write32(((addr)&~3),(data))
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+	return hs_write32(addr & ~3,(data));
+}
 
 /*
- * This variable is the KSEG2 (kernel virtual) mapping
- * of the ISA/PCI I/O space area.  We map 64K here and
- * the offsets from this address get treated with "match bytes" 
- * policy to make everything look little-endian.  So, 
- * you need to also set CONFIG_SWAP_IO_SPACE, but this is the 
- * combination that works correctly with most of Linux's drivers.
+ * This variable is the KSEG2 (kernel virtual) mapping of the ISA/PCI I/O
+ * space area.  We map 64K here and the offsets from this address get treated
+ * with "match bytes" policy to make everything look little-endian.  So, you
+ * need to also set CONFIG_SWAP_IO_SPACE, but this is the combination that
+ * works correctly with most of Linux's drivers.
  */
 
 #define PCI_BUS_ENABLED	1
@@ -153,7 +157,6 @@
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-
 	data = READCFG32(cfgaddr);
 
 	/*
@@ -232,12 +235,14 @@
 void __init pcibios_init(void)
 {
 	uint32_t cmdreg;
+	uint64_t reg;
 
 	/*
 	 * See if the PCI bus has been configured by the firmware.
 	 */
 
-	cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) + PCI_COMMAND);
+	cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) +
+			   PCI_COMMAND);
 
 	if (!(cmdreg & PCI_COMMAND_MASTER)) {
 		printk
@@ -245,22 +250,31 @@
 		return;
 	}
 
+	reg = *((volatile uint64_t *) KSEG1ADDR(A_SCD_SYSTEM_CFG));
+	if (!(reg & M_SYS_PCI_HOST)) {
+		printk("PCI: Skipping PCI probe.  Processor is in PCI device mode.\n");
+		return;
+	}
+
 	sb1250_bus_status |= PCI_BUS_ENABLED;
 
-	/* 
-	 * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space 
+	/*
+	 * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space
 	 * Use "match bytes", even though this exposes endianness.
 	 * big-endian Linuxes will have CONFIG_SWAP_IO_SPACE set.
 	 */
 
 	set_io_port_base(ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536));
+	isa_slot_offset = (unsigned long)
+		ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024*1024);
 
 	/*
 	 * Also check the LDT bridge's enable, just in case we didn't
 	 * initialize that one.
 	 */
 
-	cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) + PCI_COMMAND);
+	cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) +
+			   PCI_COMMAND);
 
 	if (cmdreg & PCI_COMMAND_MASTER) {
 		sb1250_bus_status |= LDT_BUS_ENABLED;
@@ -271,6 +285,9 @@
 	printk("PCI: Probing PCI hardware on host bus 0.\n");
 	pci_scan_bus(0, &sb1250_pci_ops, NULL);
 
+#ifdef CONFIG_VGA_CONSOLE
+	take_over_console(&vga_con,0,MAX_NR_CONSOLES-1,1);
+#endif
 }
 
 int pcibios_enable_device(struct pci_dev *dev)
@@ -280,7 +297,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-                            unsigned long size)
+		       unsigned long size, unsigned long align)
 {
 }
 
@@ -296,7 +313,7 @@
 };
 
 void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
+	struct resource *res, int resource)
 {
 	unsigned long where, size;
 	u32 reg;
@@ -312,7 +329,7 @@
  *  Called after each bus is probed, but before its children
  *  are examined.
  */
-void pcibios_fixup_bus(struct pci_bus *b)
+void __devinit pcibios_fixup_bus(struct pci_bus *b)
 {
 	pci_read_bridge_bases(b);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/prom.c linux-2.4.20/arch/mips/sibyte/sb1250/prom.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/prom.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+
+extern char arcs_cmdline[];
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+/* These are symbols defined by the ramdisk linker script */
+extern unsigned char __rd_start;
+extern unsigned char __rd_end;
+#endif
+
+#define MAX_RAM_SIZE ((CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - 1)
+
+static __init void prom_meminit(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long initrd_pstart;
+	unsigned long initrd_pend;
+
+#ifdef CONFIG_EMBEDDED_RAMDISK
+	/* If we're using an embedded ramdisk, then __rd_start and __rd_end
+	   are defined by the linker to be on either side of the ramdisk
+	   area.  Otherwise, initrd_start should be defined by kernel command
+	   line arguments */
+	if (initrd_start == 0) {
+		initrd_start = (unsigned long)&__rd_start;
+		initrd_end = (unsigned long)&__rd_end;
+	}
+#endif
+
+	initrd_pstart = __pa(initrd_start);
+	initrd_pend = __pa(initrd_end);
+	if (initrd_start &&
+	    ((initrd_pstart > MAX_RAM_SIZE)
+	     || (initrd_pend > MAX_RAM_SIZE))) {
+		panic("initrd out of addressable memory");
+	}
+
+	add_memory_region(0, initrd_pstart,
+			  BOOT_MEM_RAM);
+	add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+			  BOOT_MEM_RESERVED);
+	add_memory_region(initrd_pend,
+			  (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - initrd_pend,
+			  BOOT_MEM_RAM);
+#else
+	add_memory_region(0, CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024,
+			  BOOT_MEM_RAM);
+#endif
+}
+
+void prom_cpu0_exit(void *unused)
+{
+        while (1) ;
+}
+
+static void prom_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		smp_call_function(prom_cpu0_exit,NULL,1,1);
+	}
+#endif
+	while(1);
+}
+
+/*
+ * prom_init is called just after the cpu type is determined, from init_arch()
+ */
+__init int prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+	_machine_restart   = (void (*)(char *))prom_linux_exit;
+	_machine_halt      = prom_linux_exit;
+	_machine_power_off = prom_linux_exit;
+
+	strcpy(arcs_cmdline, "root=/dev/ram0 ");
+
+	mips_machgroup = MACH_GROUP_SIBYTE;
+	prom_meminit();
+
+	return 0;
+}
+
+void prom_free_prom_memory(void)
+{
+	/* Not sure what I'm supposed to do here.  Nothing, I think */
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+	phys_t addr = pagenr << PAGE_SHIFT;
+	return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/setup.c linux-2.4.20/arch/mips/sibyte/sb1250/setup.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/setup.c	2002-10-04 00:41:17.000000000 +0000
@@ -10,58 +10,45 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-/* Setup code likely to be common to all SB1250 platforms */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/hdreg.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/utsname.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/bootmem.h>
-#ifdef CONFIG_BLK_DEV_RAM
-#include <linux/blk.h>
-#endif
-#include <linux/ide.h>
-#ifdef CONFIG_RTC
-#include <linux/timex.h>
-#endif
-
-#include <asm/asm.h>
-#include <asm/bootinfo.h>
-#include <asm/cachectl.h>
-#include <asm/cpu.h>
-#include <asm/io.h>
-#include <asm/stackframe.h>
-#include <asm/system.h>
-#include <asm/cpu.h>
-#include <asm/mmu_context.h>
-#include <asm/sibyte/swarm.h>
-#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/sb1250_regs.h>
- 
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/64bit.h>
 
-/* 
- *
- */
+/* Setup code likely to be common to all BCM1250 platforms */
 
+unsigned int sb1250_pass;
 
 void sb1250_setup(void)
 {
+	int bad_config = 0;
+
+	sb1250_pass = G_SYS_REVISION(in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION));
+	/* sb1250_pass is more specific than "1", "2" etc.  There are
+           many revision numbers corresponding to "Pass 2". */
+	switch(sb1250_pass) {
+	case 1:
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+		printk("@@@@ This is a pass 1 board, and the kernel doesn't have the proper workarounds compiled in. @@@@");
+		bad_config = 1;
+#endif
+		break;
+	default:
+#if defined(CONFIG_CPU_HAS_PREFETCH) || !defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
+		printk("@@@@ This is a pass 2 board, and the kernel doesn't have the proper workarounds compiled in. @@@@");
+		printk("@@@@ Prefetches are enabled in this kernel, but are buggy on this board.  @@@@");
+		bad_config = 1;
+#endif
+		break;
+	}
+	/* XXXKW this is too early for panic/printk to actually do much! */
+	if (bad_config) {
+		panic("Invalid configuration for this pass.");
+	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/smp.c linux-2.4.20/arch/mips/sibyte/sb1250/smp.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/smp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/smp.c	2002-10-04 00:41:18.000000000 +0000
@@ -10,18 +10,24 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
 #include <asm/sibyte/64bit.h>
 #include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/sb1250_regs.h>
-#include <asm/addrspace.h>
-#include <asm/smp.h>
-#include <linux/sched.h>
+#include <asm/sibyte/sb1250_int.h>
+
+extern void smp_call_function_interrupt(void);
 
 /*
  * These are routines for dealing with the sb1250 smp capabilities
@@ -29,17 +35,17 @@
  */
 
 static u64 mailbox_set_regs[] = {
-	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU, 
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU,
 	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU
 };
 
 static u64 mailbox_clear_regs[] = {
-	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU, 
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU,
 	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU
 };
 
 static u64 mailbox_regs[] = {
-	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU, 
+	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU,
 	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU
 };
 
@@ -66,7 +72,8 @@
 {
 	int cpu = smp_processor_id();
 	unsigned int action;
-	
+
+	kstat.irqs[cpu][K_INT_MBOX_0]++;
 	/* Load the mailbox register to figure out what we're supposed to do */
 	action = (in64(mailbox_regs[cpu]) >> 48) & 0xffff;
 
@@ -82,3 +89,68 @@
 		smp_call_function_interrupt();
 	}
 }
+
+extern atomic_t cpus_booted;
+extern int prom_setup_smp(void);
+extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+
+void __init smp_boot_cpus(void)
+{
+	int i;
+	int cur_cpu = 0;
+
+	smp_num_cpus = prom_setup_smp();
+	init_new_context(current, &init_mm);
+	current->processor = 0;
+	cpu_data[0].udelay_val = loops_per_jiffy;
+	cpu_data[0].asid_cache = ASID_FIRST_VERSION;
+	CPUMASK_CLRALL(cpu_online_map);
+	CPUMASK_SETB(cpu_online_map, 0);
+	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
+	init_idle();
+
+	/*
+	 * This loop attempts to compensate for "holes" in the CPU
+	 * numbering.  It's overkill, but general.
+	 */
+	for (i = 1; i < smp_num_cpus; ) {
+		struct task_struct *p;
+		struct pt_regs regs;
+		int retval;
+		printk("Starting CPU %d... ", i);
+
+		/* Spawn a new process normally.  Grab a pointer to
+		   its task struct so we can mess with it */
+		do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
+		p = init_task.prev_task;
+
+		/* Schedule the first task manually */
+		p->processor = i;
+		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
+
+		/* Attach to the address space of init_task. */
+		atomic_inc(&init_mm.mm_count);
+		p->active_mm = &init_mm;
+		init_tasks[i] = p;
+
+		del_from_runqueue(p);
+		unhash_process(p);
+
+		do {
+			/* Iterate until we find a CPU that comes up */
+			cur_cpu++;
+			retval = prom_boot_secondary(cur_cpu,
+					    (unsigned long)p + KERNEL_STACK_SIZE - 32,
+					    (unsigned long)p);
+		} while (!retval && (cur_cpu < NR_CPUS));
+		if (retval) {
+			i++;
+		} else {
+			panic("CPU discovery disaster");
+		}
+	}
+
+	/* Wait for everyone to come up */
+	while (atomic_read(&cpus_booted) != smp_num_cpus);
+	smp_threads_ready = 1;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/sb1250/time.c linux-2.4.20/arch/mips/sibyte/sb1250/time.c
--- linux-2.4.19/arch/mips/sibyte/sb1250/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/sb1250/time.c	2002-10-04 00:41:14.000000000 +0000
@@ -10,17 +10,17 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-/* 
+/*
  * These are routines to set up and handle interrupts from the
  * sb1250 general purpose timer 0.  We're using the timer as a
  * system clock, so we set it up to run at 100 Hz.  On every
- * interrupt, we update our idea of what the time of day is, 
+ * interrupt, we update our idea of what the time of day is,
  * then call do_timer() in the architecture-independent kernel
  * code to do general bookkeeping (e.g. update jiffies, run
  * bottom halves, etc.)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -46,6 +47,8 @@
 #define IMR_IP3_VAL	K_INT_MAP_I1
 #define IMR_IP4_VAL	K_INT_MAP_I2
 
+extern int sb1250_steal_irq(int irq);
+
 void sb1250_time_init(void)
 {
 	int cpu = smp_processor_id();
@@ -55,11 +58,16 @@
 		BUG();
 	}
 
+	if (!cpu) {
+		/* Use our own gettimeoffset() routine */
+		do_gettimeoffset = sb1250_gettimeoffset;
+	}
+
 	sb1250_mask_irq(cpu, K_INT_TIMER_0 + cpu);
-	
+
 	/* Map the timer interrupt to ip[4] of this cpu */
-	out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) 
-	      + ((K_INT_TIMER_0 + cpu)<<3)); 
+	out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE)
+	      + ((K_INT_TIMER_0 + cpu)<<3));
 
 	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
 	/* Disable the timer and set up the count */
@@ -77,6 +85,7 @@
 	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
 	sb1250_unmask_irq(cpu, K_INT_TIMER_0 + cpu);
+	sb1250_steal_irq(K_INT_TIMER_0 + cpu);
 	/*
 	 * This interrupt is "special" in that it doesn't use the request_irq
 	 * way to hook the irq line.  The timer interrupt is initialized early
@@ -91,9 +100,10 @@
 {
 	int cpu = smp_processor_id();
 
+	kstat.irqs[cpu][K_INT_TIMER_0+cpu]++;
 	/* Reset the timer */
 	out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));  
+	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
 	/*
 	 * CPU 0 handles the global timer interrupt job
@@ -107,3 +117,17 @@
 	 */
 	ll_local_timer_interrupt(0, regs);
 }
+
+/*
+ * We use our own do_gettimeoffset() instead of the generic one,
+ * because the generic one does not work for SMP case.
+ * In addition, since we use general timer 0 for system time,
+ * we can get accurate intra-jiffy offset without calibration.
+ */
+unsigned long sb1250_gettimeoffset(void)
+{
+	unsigned long count =
+		in64(KSEG1 + A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT));
+
+	return 1000000/HZ - count;
+ }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/Makefile linux-2.4.20/arch/mips/sibyte/swarm/Makefile
--- linux-2.4.19/arch/mips/sibyte/swarm/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/Makefile	2002-10-04 00:41:10.000000000 +0000
@@ -2,9 +2,7 @@
 
 all: sbswarm.a
 
-OBJS-y                   = setup.o cmdline.o memory.o cfe_api.o rtc_xicor1241.o
-
-OBJS-$(CONFIG_SMP)      += smp.o
+OBJS-y                   = setup.o cmdline.o rtc_xicor1241.o
 
 OBJS-$(CONFIG_L3DEMO)   += procl3switch.o l3procbootstrap.o l3proc.o
 OBJS-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/cfe_api.c linux-2.4.20/arch/mips/sibyte/swarm/cfe_api.c
--- linux-2.4.19/arch/mips/sibyte/swarm/cfe_api.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/cfe_api.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*  *********************************************************************
-    *  Broadcom Common Firmware Environment (CFE)
-    *  
-    *  Device Function stubs			File: cfe_api.c
-    *  
-    *  This module contains device function stubs (small routines to
-    *  call the standard "iocb" interface entry point to CFE).
-    *  There should be one routine here per iocb function call.
-    *  
-    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
-    *  
-    ********************************************************************* */
-
-
-#include "cfe_xiocb.h"
-#include "cfe_api.h"
-#include <linux/string.h>
-
-static long cfe_console_handle = -1;
-static int (*cfe_dispfunc)(long handle,cfe_xiocb_t *xiocb) = 0;
-static cfe_xuint_t cfe_handle = 0;
-
-/*
- * This macro makes a "signed 64-bit pointer" - basically extending a regular
- * pointer to its 64-bit compatibility space equivalent. 
- */
-#define BIGPTR(x) (long long) (long) (x)
-
-typedef unsigned long intptr_t;
-
-int cfe_init(cfe_xuint_t handle)
-{
-	unsigned int *sealloc = (unsigned int *) (intptr_t) (int)  CFE_APISEAL;
-	if (*sealloc != CFE_EPTSEAL) return -1;
-	cfe_dispfunc = (void *) (cfe_xptr_t) (int) CFE_APIENTRY;
-	if (handle) cfe_handle = handle;
-	return 0;
-}
-
-int cfe_iocb_dispatch(cfe_xiocb_t *xiocb);
-int cfe_iocb_dispatch(cfe_xiocb_t *xiocb)
-{
-	if (!cfe_dispfunc) return -1;
-	return (*cfe_dispfunc)(cfe_handle,xiocb);
-}
-
-static int cfe_strlen(char *name)
-{
-	int count = 0;
-	
-	while (*name) {
-		count++;
-		name++;
-	}
-	
-	return count;
-}
-
-int cfe_open(char *name)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
-	xiocb.plist.xiocb_buffer.buf_offset = 0;
-	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(name);
-	xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
-}
-
-int cfe_close(int handle)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = handle;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = 0;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status);
-	
-}
-
-int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = handle;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
-	xiocb.plist.xiocb_buffer.buf_offset = offset;
-	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
-	xiocb.plist.xiocb_buffer.buf_length = length;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
-}
-
-int cfe_read(int handle,unsigned char *buffer,int length)
-{
-	return cfe_readblk(handle,0,buffer,length);
-}
-
-
-int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = handle;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
-	xiocb.plist.xiocb_buffer.buf_offset = offset;
-	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
-	xiocb.plist.xiocb_buffer.buf_length = length;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
-}
-
-int cfe_write(int handle,unsigned char *buffer,int length)
-{
-	return cfe_writeblk(handle,0,buffer,length);
-}
-
-
-int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = handle;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
-	xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum;
-	xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer);
-	xiocb.plist.xiocb_buffer.buf_length = length;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
-	return xiocb.xiocb_status;
-}
-
-int cfe_inpstat(int handle)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = handle;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
-	xiocb.plist.xiocb_inpstat.inp_status = 0;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
-	
-	return xiocb.plist.xiocb_inpstat.inp_status;
-	
-}
-
-long long cfe_getticks(void)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_time_t);
-	xiocb.plist.xiocb_time.ticks = 0;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.plist.xiocb_time.ticks;
-	
-}
-
-int cfe_getenv(char *name,char *dest,int destlen)
-{
-	cfe_xiocb_t xiocb;
-	
-	*dest = 0;
-	
-	xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
-	xiocb.plist.xiocb_envbuf.enum_idx = 0;
-	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
-	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
-	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(dest);
-	xiocb.plist.xiocb_envbuf.val_length = destlen;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-int cfe_setenv(char *name,char *val)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
-	xiocb.plist.xiocb_envbuf.enum_idx = 0;
-	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
-	xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
-	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
-	xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type)
-{
-	cfe_xiocb_t xiocb;
-	xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
-	xiocb.plist.xiocb_meminfo.mi_idx = idx;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	(*addr) = xiocb.plist.xiocb_meminfo.mi_addr;
-	(*size) = xiocb.plist.xiocb_meminfo.mi_size;
-	(*type) = xiocb.plist.xiocb_meminfo.mi_type;
-
-	return xiocb.xiocb_status;
-}
-
-
-int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
-	xiocb.plist.xiocb_envbuf.enum_idx = idx;
-	xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name);
-	xiocb.plist.xiocb_envbuf.name_length = namelen;
-	xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val);
-	xiocb.plist.xiocb_envbuf.val_length = vallen;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-int cfe_exit(int warm, int status)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
-	xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
-	xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status);
-}
-
-int cfe_flushcache(int flg)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = flg;
-	xiocb.xiocb_psize = 0;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-int cfe_getstdhandle(int flg)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags = flg;
-	xiocb.xiocb_psize = 0;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
-	
-}
-
-int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags  = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
-	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
-	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
-	xiocb.plist.xiocb_cpuctl.gp_val = gp;
-	xiocb.plist.xiocb_cpuctl.sp_val = sp;
-	xiocb.plist.xiocb_cpuctl.a1_val = a1;
-	xiocb.plist.xiocb_cpuctl.start_addr = (long)fn;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-
-int cfe_stop_cpu(int cpu)
-{
-	cfe_xiocb_t xiocb;
-	
-	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
-	xiocb.xiocb_status = 0;
-	xiocb.xiocb_handle = 0;
-	xiocb.xiocb_flags  = 0;
-	xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
-	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
-	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
-	
-	cfe_iocb_dispatch(&xiocb);
-	
-	return xiocb.xiocb_status;
-}
-
-void cfe_open_console()
-{
-	cfe_console_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
-}
-
-void cfe_console_print(char *str)
-{
-	int len = strlen(str);
-	int res;
-
-	if (cfe_console_handle != -1) {
-		do {
-			res = cfe_writeblk(cfe_console_handle, 0, str, len);
-			if (res < 0)
-				break;
-			str += res;
-			len -= res;
-		} while (len);
-	}
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/cfe_api.h linux-2.4.20/arch/mips/sibyte/swarm/cfe_api.h
--- linux-2.4.19/arch/mips/sibyte/swarm/cfe_api.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/cfe_api.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*  *********************************************************************
-    *  Broadcom Common Firmware Environment (CFE)
-    *  
-    *  Device function prototypes		File: cfe_api.h
-    *  
-    *  This module contains prototypes for cfe_devfuncs.c, a set
-    *  of wrapper routines to the IOCB interface.  This file,
-    *  along with cfe_api.c, can be incorporated into programs
-    *  that need to call CFE.
-    *  
-    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
-    *  
-    ********************************************************************* */
-
-
-#define CFE_EPTSEAL 0x43464531
-#define CFE_APIENTRY 0x9FC00500
-#define CFE_APISEAL  0x9FC00508
-
-#ifndef __ASSEMBLY__
-int cfe_init(cfe_xuint_t handle);
-int cfe_open(char *name);
-int cfe_close(int handle);
-int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
-int cfe_read(int handle,unsigned char *buffer,int length);
-int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length);
-int cfe_write(int handle,unsigned char *buffer,int length);
-int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen);
-int cfe_inpstat(int handle);
-int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen);
-int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type);
-int cfe_setenv(char *name,char *val);
-int cfe_getenv(char *name,char *dest,int destlen);
-long long cfe_getticks(void);
-int cfe_exit(int warm, int status);
-int cfe_flushcache(int flg);
-int cfe_getstdhandle(int flg);
-int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1);
-int cfe_stop_cpu(int cpu);
-
-void cfe_open_console(void);
-void cfe_console_print(char *);
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/cfe_error.h linux-2.4.20/arch/mips/sibyte/swarm/cfe_error.h
--- linux-2.4.19/arch/mips/sibyte/swarm/cfe_error.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/cfe_error.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*  *********************************************************************
-    *  Broadcom Common Firmware Environment (CFE)
-    *  
-    *  Error codes				File: cfe_error.h
-    *  
-    *  CFE's global error code list is here.
-    *  
-    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
-    *  
-    ********************************************************************* */
-
-
-
-
-#define CFE_OK			 0
-#define CFE_ERR                 -1	/* generic error */
-#define CFE_ERR_INV_COMMAND	-2
-#define CFE_ERR_EOF		-3
-#define CFE_ERR_IOERR		-4
-#define CFE_ERR_NOMEM		-5
-#define CFE_ERR_DEVNOTFOUND	-6
-#define CFE_ERR_DEVOPEN		-7
-#define CFE_ERR_INV_PARAM	-8
-#define CFE_ERR_ENVNOTFOUND	-9
-#define CFE_ERR_ENVREADONLY	-10
-
-#define CFE_ERR_NOTELF		-11
-#define CFE_ERR_NOT32BIT 	-12
-#define CFE_ERR_WRONGENDIAN 	-13
-#define CFE_ERR_BADELFVERS 	-14
-#define CFE_ERR_NOTMIPS 	-15
-#define CFE_ERR_BADELFFMT 	-16
-#define CFE_ERR_BADADDR 	-17
-
-#define CFE_ERR_FILENOTFOUND	-18
-#define CFE_ERR_UNSUPPORTED	-19
-
-#define CFE_ERR_HOSTUNKNOWN	-20
-
-#define CFE_ERR_TIMEOUT		-21
-
-#define CFE_ERR_PROTOCOLERR	-22
-
-#define CFE_ERR_NETDOWN		-23
-#define CFE_ERR_NONAMESERVER	-24
-
-#define CFE_ERR_NOHANDLES	-25
-#define CFE_ERR_ALREADYBOUND	-26
-
-#define CFE_ERR_CANNOTSET	-27
-#define CFE_ERR_NOMORE		-28
-#define CFE_ERR_BADFILESYS	-29
-#define CFE_ERR_FSNOTAVAIL	-30
-
-#define CFE_ERR_INVBOOTBLOCK	-31
-#define CFE_ERR_WRONGDEVTYPE	-32
-#define CFE_ERR_BBCHECKSUM	-33
-#define CFE_ERR_BOOTPROGCHKSUM	-34
-
-
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/cfe_xiocb.h linux-2.4.20/arch/mips/sibyte/swarm/cfe_xiocb.h
--- linux-2.4.19/arch/mips/sibyte/swarm/cfe_xiocb.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/cfe_xiocb.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*  *********************************************************************
-    *  Broadcom Common Firmware Environment (CFE)
-    *  
-    *  IOCB definitions				File: cfe_iocb.h
-    *  
-    *  This module describes CFE's IOCB structure, the main
-    *  data structure used to communicate API requests with CFE.
-    *  
-    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
-    *  
-    ********************************************************************* */
-
-/*  *********************************************************************
-    *  Constants
-    ********************************************************************* */
-
-#define CFE_CMD_FW_GETINFO	0
-#define CFE_CMD_FW_RESTART	1
-#define CFE_CMD_FW_BOOT		2
-#define CFE_CMD_FW_CPUCTL	3
-#define CFE_CMD_FW_GETTIME      4
-#define CFE_CMD_FW_MEMENUM	5
-#define CFE_CMD_FW_FLUSHCACHE	6
-
-#define CFE_CMD_DEV_GETHANDLE	9
-#define CFE_CMD_DEV_ENUM	10
-#define CFE_CMD_DEV_OPEN	11
-#define CFE_CMD_DEV_INPSTAT	12
-#define CFE_CMD_DEV_READ	13
-#define CFE_CMD_DEV_WRITE	14
-#define CFE_CMD_DEV_IOCTL	15
-#define CFE_CMD_DEV_CLOSE	16
-#define CFE_CMD_DEV_GETINFO	17
-
-#define CFE_CMD_ENV_ENUM	20
-#define CFE_CMD_ENV_GET		22
-#define CFE_CMD_ENV_SET		23
-#define CFE_CMD_ENV_DEL		24
-
-#define CFE_CMD_MAX		32
-
-#define CFE_MI_RESERVED	0		/* memory is reserved, do not use */
-#define CFE_MI_AVAILABLE 1		/* memory is available */
-
-#define CFE_FLG_WARMSTART 0x00000001
-
-#define CFE_FLG_ENV_PERMANENT 0x00000001
-
-#define CFE_CPU_CMD_START 1
-#define CFE_CPU_CMD_STOP 0
-
-#define CFE_STDHANDLE_CONSOLE	0
-
-#define CFE_DEV_NETWORK 	1
-#define CFE_DEV_DISK		2
-#define CFE_DEV_FLASH		3
-#define CFE_DEV_SERIAL		4
-#define CFE_DEV_CPU		5
-#define CFE_DEV_NVRAM		6
-#define CFE_DEV_OTHER		7
-#define CFE_DEV_MASK		0x0F
-
-#define CFE_CACHE_FLUSH_D	1
-#define CFE_CACHE_INVAL_I	2
-#define CFE_CACHE_INVAL_D	4
-#define CFE_CACHE_INVAL_L2	8
-
-/*  *********************************************************************
-    *  Structures
-    ********************************************************************* */
-
-typedef unsigned long long cfe_xuint_t;
-typedef long long cfe_xint_t;
-typedef long long cfe_xptr_t;
-
-typedef struct xiocb_buffer_s {
-    cfe_xuint_t   buf_offset;		/* offset on device (bytes) */
-    cfe_xptr_t 	  buf_ptr;		/* pointer to a buffer */
-    cfe_xuint_t   buf_length;		/* length of this buffer */
-    cfe_xuint_t   buf_retlen;		/* returned length (for read ops) */
-    cfe_xuint_t   buf_ioctlcmd;		/* IOCTL command (used only for IOCTLs) */
-} xiocb_buffer_t;
-
-#define buf_devflags buf_ioctlcmd	/* returned device info flags */
-
-typedef struct xiocb_inpstat_s {
-    cfe_xuint_t inp_status;		/* 1 means input available */
-} xiocb_inpstat_t;
-
-typedef struct xiocb_envbuf_s {
-    cfe_xint_t enum_idx;		/* 0-based enumeration index */
-    cfe_xptr_t name_ptr;		/* name string buffer */
-    cfe_xint_t name_length;		/* size of name buffer */
-    cfe_xptr_t val_ptr;			/* value string buffer */
-    cfe_xint_t val_length;		/* size of value string buffer */
-} xiocb_envbuf_t;
-
-typedef struct xiocb_cpuctl_s {
-    cfe_xuint_t  cpu_number;		/* cpu number to control */
-    cfe_xuint_t  cpu_command;		/* command to issue to CPU */
-    cfe_xuint_t  start_addr;		/* CPU start address */
-    cfe_xuint_t  gp_val;		/* starting GP value */
-    cfe_xuint_t  sp_val;		/* starting SP value */
-    cfe_xuint_t  a1_val;		/* starting A1 value */
-} xiocb_cpuctl_t;
-
-typedef struct xiocb_time_s {
-    cfe_xint_t ticks;			/* current time in ticks */
-} xiocb_time_t;
-
-typedef struct xiocb_exitstat_s {
-    cfe_xint_t status;
-} xiocb_exitstat_t;
-
-typedef struct xiocb_meminfo_s {
-    cfe_xint_t  mi_idx;			/* 0-based enumeration index */
-    cfe_xint_t  mi_type;		/* type of memory block */
-    cfe_xuint_t mi_addr;		/* physical start address */
-    cfe_xuint_t mi_size;		/* block size */
-} xiocb_meminfo_t;
-
-#define CFE_FWI_64BIT		0x00000001
-#define CFE_FWI_32BIT		0x00000002
-#define CFE_FWI_RELOC		0x00000004
-#define CFE_FWI_UNCACHED	0x00000008
-#define CFE_FWI_MULTICPU	0x00000010
-#define CFE_FWI_FUNCSIM		0x00000020
-#define CFE_FWI_RTLSIM		0x00000040
-
-typedef struct xiocb_fwinfo_s {
-    cfe_xint_t fwi_version;		/* major, minor, eco version */
-    cfe_xint_t fwi_totalmem;		/* total installed mem */
-    cfe_xint_t fwi_flags;		/* various flags */
-    cfe_xint_t fwi_boardid;		/* board ID */
-    cfe_xint_t fwi_bootarea_va;		/* VA of boot area */
-    cfe_xint_t fwi_bootarea_pa;		/* PA of boot area */
-    cfe_xint_t fwi_bootarea_size;	/* size of boot area */
-    cfe_xint_t fwi_reserved1;
-    cfe_xint_t fwi_reserved2;
-    cfe_xint_t fwi_reserved3;
-} xiocb_fwinfo_t,cfe_fwinfo_t;
-
-typedef struct cfe_xiocb_s {
-    cfe_xuint_t xiocb_fcode;		/* IOCB function code */
-    cfe_xint_t  xiocb_status;		/* return status */
-    cfe_xint_t  xiocb_handle;		/* file/device handle */
-    cfe_xuint_t xiocb_flags;		/* flags for this IOCB */
-    cfe_xuint_t xiocb_psize;		/* size of parameter list */
-    union {
-	xiocb_buffer_t  xiocb_buffer;	/* buffer parameters */
-	xiocb_inpstat_t xiocb_inpstat;	/* input status parameters */
-	xiocb_envbuf_t  xiocb_envbuf;	/* environment function parameters */
-	xiocb_cpuctl_t  xiocb_cpuctl;	/* CPU control parameters */
-	xiocb_time_t    xiocb_time;	/* timer parameters */
-	xiocb_meminfo_t xiocb_meminfo;	/* memory arena info parameters */
-	xiocb_fwinfo_t  xiocb_fwinfo;	/* firmware information */
-	xiocb_exitstat_t xiocb_exitstat; /* Exit status */
-    } plist;
-} cfe_xiocb_t;
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/cmdline.c linux-2.4.20/arch/mips/sibyte/swarm/cmdline.c
--- linux-2.4.19/arch/mips/sibyte/swarm/cmdline.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/cmdline.c	2002-10-04 00:41:10.000000000 +0000
@@ -10,7 +10,7 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/memory.c linux-2.4.20/arch/mips/sibyte/swarm/memory.c
--- linux-2.4.19/arch/mips/sibyte/swarm/memory.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/memory.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- * Memory related routines 
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/page.h>
-
-extern phys_t swarm_mem_region_addrs[];
-extern phys_t swarm_mem_region_sizes[];
-extern unsigned int swarm_mem_region_count;
-
-int page_is_ram(unsigned long pagenr)
-{
-	phys_t addr = pagenr << PAGE_SHIFT;
-#ifdef CONFIG_SWARM_STANDALONE
-	if (addr < (CONFIG_SIBYTE_SWARM_RAM_SIZE * 1024 * 1024)) {
-		return 1;
-	}
-#else
-	int i;
-	for (i = 0; i < swarm_mem_region_count; i++) {
-		if ((addr >= swarm_mem_region_addrs[i]) 
-		    && (addr < (swarm_mem_region_addrs[i] + swarm_mem_region_sizes[i]))) {
-			return 1;
-		}
-	}
-#endif
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/rtc.c linux-2.4.20/arch/mips/sibyte/swarm/rtc.c
--- linux-2.4.19/arch/mips/sibyte/swarm/rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- *  Not really sure what is supposed to be here, yet 
- */
-
-#include <linux/spinlock.h>
-#include <linux/mc146818rtc.h>
-
-static unsigned char swarm_rtc_read_data(unsigned long addr)
-{
-	return 0;
-}
-
-static void swarm_rtc_write_data(unsigned char data, unsigned long addr)
-{
-}
-
-static int swarm_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops swarm_rtc_ops = {
-	&swarm_rtc_read_data,
-	&swarm_rtc_write_data,
-	&swarm_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/rtc_xicor1241.c linux-2.4.20/arch/mips/sibyte/swarm/rtc_xicor1241.c
--- linux-2.4.19/arch/mips/sibyte/swarm/rtc_xicor1241.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/rtc_xicor1241.c	2002-10-04 00:41:14.000000000 +0000
@@ -125,7 +125,7 @@
 	/* trivial ones */
 	BIN_TO_BCD(tm.tm_sec);
 	xicor_write(X1241REG_SC, tm.tm_sec);
-	
+
 	BIN_TO_BCD(tm.tm_min);
 	xicor_write(X1241REG_MN, tm.tm_min);
 
@@ -189,7 +189,7 @@
 	mon = xicor_read(X1241REG_MO);
 	year = xicor_read(X1241REG_YR);
 	y2k = xicor_read(X1241REG_Y2K);
- 
+
 	BCD_TO_BIN(day);
 	BCD_TO_BIN(mon);
 	BCD_TO_BIN(year);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/setup.c linux-2.4.20/arch/mips/sibyte/swarm/setup.c
--- linux-2.4.19/arch/mips/sibyte/swarm/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/setup.c	2002-10-04 00:41:10.000000000 +0000
@@ -10,219 +10,58 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
 /*
- * Setup code for the SWARM board 
+ * Setup code for the SWARM board
  */
-#include <linux/config.h>
+
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/blk.h>
 #include <linux/init.h>
 #include <linux/ide.h>
+#include <linux/console.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/bootinfo.h>
-#include <asm/addrspace.h>
-#include <asm/sibyte/swarm.h>
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_defs.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/swarm_ide.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/swarm.h>
 
-#include "cfe_xiocb.h"
-#include "cfe_api.h"
-#include "cfe_error.h"
-
-extern int cfe_console_handle;
+extern struct rtc_ops *rtc_ops;
+extern struct rtc_ops swarm_rtc_ops;
 
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
-extern struct ide_ops *ide_ops;
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+#ifdef CONFIG_BLK_DEV_IDE_SIBYTE
+extern struct ide_ops sibyte_ide_ops;
+#endif
 #endif
-
 
 #ifdef CONFIG_L3DEMO
 extern void *l3info;
 #endif
 
-/* Max ram addressable in 32-bit segments */
-#ifdef CONFIG_HIGHMEM
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define MAX_RAM_SIZE (~0ULL)
-#else
-#define MAX_RAM_SIZE (0xffffffffULL)
-#endif
-#else
-#ifdef CONFIG_MIPS64
-#define MAX_RAM_SIZE (~0ULL)
-#else
-#define MAX_RAM_SIZE (0x1fffffffULL)
-#endif
-#endif
-
-
-#ifndef CONFIG_SWARM_STANDALONE
-
-phys_t swarm_mem_region_addrs[CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS];
-phys_t swarm_mem_region_sizes[CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS];
-unsigned int swarm_mem_region_count;
-
-#endif
+static unsigned char *led_ptr;
+#define LED_BASE_ADDR (A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, LEDS_CS)))
+#define setled(index, c) led_ptr[(3-((index)&3)) << 3] = (c)
 
 const char *get_system_type(void)
 {
 	return "SiByte Swarm";
 }
 
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
-static int swarm_ide_default_irq(ide_ioreg_t base)
-{
-        return 0;
-}
-
-static ide_ioreg_t swarm_ide_default_io_base(int index)
-{
-        return 0;
-}
-
-static void swarm_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
-                                     ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int swarm_ide_request_irq(unsigned int irq,
-                                void (*handler)(int,void *, struct pt_regs *),
-                                unsigned long flags, const char *device,
-                                void *dev_id)
-{
-	return request_irq(irq, handler, flags, device, dev_id);
-}			
-
-static void swarm_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int swarm_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-    /* Note: "check_region" and friends do conflict management on ISA I/O
-       space.  Our disk is not in that space, so this check won't work */
-    /* return check_region(from, extent); */
-    return 0;
-}
-
-static void swarm_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                    const char *name)
-{
-    /* request_region(from, extent, name); */
-}
-
-static void swarm_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-    /* release_region(from, extent); */
-}
-
-
-void swarm_ideproc(ide_ide_action_t action, ide_drive_t *drive,
-		   void *buffer, unsigned int count)
-{
-	/*  slow? vlb_sync? */
-	switch (action) {
-	case ideproc_ide_input_data:
-		if (drive->io_32bit) {
-			swarm_insl(IDE_DATA_REG, buffer, count);
-		} else {
-			swarm_insw(IDE_DATA_REG, buffer, count<<1);
-		}
-		break;
-	case ideproc_ide_output_data:
-		if (drive->io_32bit) {
-			swarm_outsl(IDE_DATA_REG, buffer, count);
-		} else {
-			swarm_outsw(IDE_DATA_REG, buffer, count<<1);
-		}
-		break;
-	case ideproc_atapi_input_bytes:
-		count++;
-		if (drive->io_32bit) {
-			swarm_insl(IDE_DATA_REG, buffer, count>>2);
-		} else {
-			swarm_insw(IDE_DATA_REG, buffer, count>>1);
-		}
-		if ((count & 3) >= 2)
-			swarm_insw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
-		break;
-	case ideproc_atapi_output_bytes:
-		count++;
-		if (drive->io_32bit) {
-			swarm_outsl(IDE_DATA_REG, buffer, count>>2);
-		} else {
-			swarm_outsw(IDE_DATA_REG, buffer, count>>1);
-		}
-		if ((count & 3) >= 2)
-			swarm_outsw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
-		break;
-	}
-}
-
-struct ide_ops swarm_ide_ops = {
-	&swarm_ide_default_irq,
-	&swarm_ide_default_io_base,
-	&swarm_ide_init_hwif_ports,
-	&swarm_ide_request_irq,
-	&swarm_ide_free_irq,
-	&swarm_ide_check_region,
-	&swarm_ide_request_region,
-	&swarm_ide_release_region
-};
-#endif
-
-
-#ifdef CONFIG_SMP
-static void smp_cpu0_exit(void *unused)
-{
-	printk("swarm_linux_exit called (cpu1) - passing control back to CFE\n");
-	cfe_exit(1,0);
-}
-#endif
-
-static void swarm_linux_exit(void)
-{
-#ifdef CONFIG_SMP
-	if (smp_processor_id()) {
-		smp_call_function(smp_cpu0_exit,NULL,1,1);
-		while(1);
-	}
-#endif
-	printk("swarm_linux_exit called...passing control back to CFE\n");
-	cfe_exit(1, 0);
-	printk("cfe_exit returned??\n");
-	while(1);
-}
 
 void __init bus_error_init(void)
 {
@@ -230,7 +69,7 @@
 
 void __init swarm_timer_setup(struct irqaction *irq)
 {
-        /* 
+        /*
          * we don't set up irqaction, because we will deliver timer
          * interrupts through low-level (direct) meachanism.
          */
@@ -240,12 +79,15 @@
 }
 
 extern int xicor_set_time(unsigned long);
-extern unsigned int xicor_get_time(void);
+extern unsigned long xicor_get_time(void);
+extern void sb1250_setup(void);
 
 void __init swarm_setup(void)
 {
 	extern int panic_timeout;
 
+	sb1250_setup();
+
 	panic_timeout = 5;  /* For debug.  */
 
         board_timer_setup = swarm_timer_setup;
@@ -253,10 +95,6 @@
         rtc_get_time = xicor_get_time;
         rtc_set_time = xicor_set_time;
 
-	_machine_restart   = (void (*)(char *))swarm_linux_exit;
-	_machine_halt      = swarm_linux_exit;
-	_machine_power_off = swarm_linux_exit;
-
 #ifdef CONFIG_L3DEMO
 	if (l3info != NULL) {
 		printk("\n");
@@ -268,231 +106,58 @@
 #else
 	       "board"
 #endif
-	       " runs\n");
-
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
-	ide_ops = &swarm_ide_ops;
+	       " runs "
+#ifdef CONFIG_SIBYTE_CFE
+	       "with"
+#else
+	       "without"
 #endif
-}  
+	       " CFE\n");
 
-/* This is the kernel command line.  Actually, it's 
-   copied, eventually, to command_line, and looks to be
-   quite redundant.  But not something to fix just now */
-extern char arcs_cmdline[];
-
-#ifdef CONFIG_EMBEDDED_RAMDISK
-/* These are symbols defined by the ramdisk linker script */
-extern unsigned char __rd_start;
-extern unsigned char __rd_end;  
+#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_SIBYTE
+	ide_ops = &sibyte_ide_ops;
+#else
+	ide_ops = &std_ide_ops;
 #endif
-
-static __init void prom_meminit(void)
-{
-	u64 addr, size; /* regardless of 64BIT_PHYS_ADDR */
-	long type;
-	unsigned int idx;
-	int rd_flag;
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long initrd_pstart; 
-	unsigned long initrd_pend; 
-
-#ifdef CONFIG_EMBEDDED_RAMDISK
-	/* If we're using an embedded ramdisk, then __rd_start and __rd_end
-	   are defined by the linker to be on either side of the ramdisk
-	   area.  Otherwise, initrd_start should be defined by kernel command
-	   line arguments */
-	if (initrd_start == 0) {
-		initrd_start = (unsigned long)&__rd_start;
-		initrd_end = (unsigned long)&__rd_end;
-	}
 #endif
 
-	initrd_pstart = __pa(initrd_start);
-	initrd_pend = __pa(initrd_end);
-	if (initrd_start &&
-	    ((initrd_pstart > MAX_RAM_SIZE)
-	     || (initrd_pend > MAX_RAM_SIZE))) {
-		setleds("INRD");
-		panic("initrd out of addressable memory");
-	}
-       
-#endif /* INITRD */
-		
-	for (idx = 0; cfe_enummem(idx, &addr, &size, &type) != CFE_ERR_NOMORE;
-	     idx++) {
-		rd_flag = 0;
-		if (type == CFE_MI_AVAILABLE) {
-			/*
-			 * See if this block contains (any portion of) the
-			 * ramdisk
-			 */
-#ifdef CONFIG_BLK_DEV_INITRD
-			if (initrd_start) {
-				if ((initrd_pstart > addr) &&
-				    (initrd_pstart < (addr + size))) {
-					add_memory_region(addr,
-					                  initrd_pstart - addr,
-					                  BOOT_MEM_RAM);
-					rd_flag = 1;
-				}
-				if ((initrd_pend > addr) &&
-				    (initrd_pend < (addr + size))) {
-					add_memory_region(initrd_pend,
-						(addr + size) - initrd_pend,
-						 BOOT_MEM_RAM);
-					rd_flag = 1;
-				}
-			}
-#endif
-			if (!rd_flag) {
-				if (addr > MAX_RAM_SIZE)
-					continue;
-				if (addr+size > MAX_RAM_SIZE)
-					size = MAX_RAM_SIZE - (addr+size) + 1;
-				add_memory_region(addr, size, BOOT_MEM_RAM);
-			}
-			swarm_mem_region_addrs[swarm_mem_region_count] = addr;
-			swarm_mem_region_sizes[swarm_mem_region_count] = size;
-			swarm_mem_region_count++;
-			if (swarm_mem_region_count ==
-			    CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS) {
-				/*
-				 * Too many regions.  Need to configure more
-				 */
-				while(1);
-			}
-		}
-	}
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start) {
-		add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
-		                 BOOT_MEM_RESERVED);
-	}
+	/* Set up the LED base address */
+#ifdef __MIPSEL__
+	/* Pass1 workaround (bug 1624) */
+	if (sb1250_pass == K_SYS_REVISION_PASS1)
+		led_ptr = (unsigned char *)
+			((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(4+(KSEG1|LED_BASE_ADDR))) << S_IO_ADDRBASE))+0x20);
+	else
+#endif
+		led_ptr = (unsigned char *)
+			((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(KSEG1|LED_BASE_ADDR)) << S_IO_ADDRBASE))+0x20);
+
+#ifdef CONFIG_VT
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+	screen_info = (struct screen_info) {
+		0, 0,           /* orig-x, orig-y */
+		0,              /* unused */
+		52,             /* orig_video_page */
+		3,              /* orig_video_mode */
+		80,             /* orig_video_cols */
+		4626, 3, 9,     /* unused, ega_bx, unused */
+		25,             /* orig_video_lines */
+		0x22,           /* orig_video_isVGA */
+		16              /* orig_video_points */
+       };
+       /* XXXKW for CFE, get lines/cols from environment */
 #endif
 }
 
-
-#ifdef CONFIG_BLK_DEV_INITRD
-static int __init initrd_setup(char *str)
-{
-	/* 
-	 *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
-	 *  e.g. initrd=3abfd@80010000.  This is set up by the loader.
-	 */
-	char *tmp, *endptr;
-	unsigned long initrd_size;
-	for (tmp = str; *tmp != '@'; tmp++) {
-		if (!*tmp) {
-			goto fail;
-		}
-	}
-	*tmp = 0;
-	tmp++;
-	if (!*tmp) {
-		goto fail;
-	}
-	initrd_size = simple_strtol(str, &endptr, 16);
-	if (*endptr) {
-		goto fail;
-	}
-	initrd_start = simple_strtol(tmp, &endptr, 16);
-	if (*endptr) {
-		goto fail;
-	}
-	initrd_end = initrd_start + initrd_size;
-	printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
-	return 1;
- fail:
-	printk("Bad initrd argument.  Disabling initrd\n");
-	initrd_start = 0;
-	initrd_end = 0;
-	return 1;
-}
-
-#endif
-
-/*
- * prom_init is called just after the cpu type is determined, from init_arch()
- */
-__init int prom_init(int argc, char **argv, char **envp, int *prom_vec)
-{
-	/* 
-	 * This should go away.  Detect if we're booting
-	 * straight from cfe without a loader.  If we
-	 * are, then we've got a prom vector in a0.  Otherwise,
-	 * argc (and argv and envp, for that matter) will be 0) 
-	 */
-	if (argc < 0) {
-		prom_vec = (int *)argc;
-	}
-	cfe_init((long)prom_vec);
-	cfe_open_console();
-	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
-		if (argc < 0) {
-			/*
-			 * It's OK for direct boot to not provide a
-			 *  command line
-			 */
-			strcpy(arcs_cmdline, "root=/dev/ram0 ");
-		} else {
-			/* The loader should have set the command line */
-			setleds("CMDL");
-			panic("LINUX_CMDLINE not defined in cfe.");
-		}
-	}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	{
-		char *ptr;
-		/* Need to find out early whether we've got an initrd.  So scan
-		   the list looking now */
-		for (ptr = arcs_cmdline; *ptr; ptr++) {
-			while (*ptr == ' ') {
-				ptr++;
-			}
-			if (!strncmp(ptr, "initrd=", 7)) {
-				initrd_setup(ptr+7);
-				break;
-			} else {
-				while (*ptr && (*ptr != ' ')) {
-					ptr++;
-				}
-			}
-		}
-	}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
-	/* Not sure this is needed, but it's the safe way. */
-	arcs_cmdline[CL_SIZE-1] = 0;
-
-	mips_machgroup = MACH_GROUP_SIBYTE;
-	prom_meminit();
-
-	return 0;
-}
-
-void prom_free_prom_memory(void)
-{
-	/* Not sure what I'm supposed to do here.  Nothing, I think */
-}
-
-static void setled(unsigned int index, char c) 
-{
-	volatile unsigned char *led_ptr;
-
-	led_ptr = (unsigned char *)(IO_SPACE_BASE | LED_BASE_ADDR);
-	if (index < 4) {
-		led_ptr[(3-index)<<3] = c;
-	}
-}
-
 void setleds(char *str)
 {
 	int i;
 	for (i = 0; i < 4; i++) {
 		if (!str[i]) {
-			for (; i < 4; i++) { 
+			for (; i < 4; i++) {
 				setled(' ', str[i]);
 			}
 		} else {
@@ -516,27 +181,27 @@
 	setleds("    ");
 }
 
-static void move_leds(unsigned long arg) 
+static void move_leds(unsigned long arg)
 {
 	int i;
 	unsigned char *tmp = led_msg_ptr;
 	for (i = 0; i < 4; i++) {
 		setled(i, *tmp);
 		tmp++;
-		if (!*tmp) { 
-			tmp = led_msg; 
+		if (!*tmp) {
+			tmp = led_msg;
 		}
 	}
 	led_msg_ptr++;
-	if (!*led_msg_ptr) { 
- 		led_msg_ptr = led_msg; 
+	if (!*led_msg_ptr) {
+ 		led_msg_ptr = led_msg;
 	}
 	del_timer(&led_timer);
 	led_timer.expires = jiffies + (HZ/8);
 	add_timer(&led_timer);
 }
 
-void hack_leds(void) 
+void hack_leds(void)
 {
 	init_timer(&led_timer);
 	led_timer.expires = jiffies + (HZ/8);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/smp.c linux-2.4.20/arch/mips/sibyte/swarm/smp.c
--- linux-2.4.19/arch/mips/sibyte/swarm/smp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/smp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_int.h>
-#include <asm/mipsregs.h>
-#include <asm/mmu_context.h>
-
-#include "cfe_xiocb.h"
-#include "cfe_api.h"
-
-extern void asmlinkage smp_bootstrap(void);
-
-/* Boot all other cpus in the system, initialize them, and
-   bring them into the boot fn */
-int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
-{
-	int retval;
-	
-	retval = cfe_start_cpu(cpu, &smp_bootstrap, sp, gp, 0);
-	if (retval != 0) {
-		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
-		return 0;
-	} else {
-		return 1;
-	}
-}
-
-
-void prom_init_secondary(void)
-{
-	/* Set up kseg0 to be cachable coherent */
-	clear_cp0_config(CONF_CM_CMASK);
-	set_cp0_config(0x5);
-
-	/* Enable interrupts for lines 0-4 */
-	clear_cp0_status(0xe000);
-	set_cp0_status(0x1f01);
-}
-
-
-/*
- * Set up state, return the total number of cpus in the system, including
- * the master
- */
-int prom_setup_smp(void)
-{
-	int i;
-	int num_cpus = 1;
-
-	/* Use CFE to find out how many CPUs are available */
-	for (i=1; i<NR_CPUS; i++) {
-		if (cfe_stop_cpu(i) == 0) {
-			num_cpus++;
-		}
-	}
-	printk("Detected %i available CPU(s)\n", num_cpus);
-	return num_cpus;
-}
-
-void prom_smp_finish(void)
-{
-	extern void sb1250_smp_finish(void);
-	sb1250_smp_finish();
-}
-
-/*
- * XXX This is really halfway portable code and halfway system specific code.
- * XXX Seems like some of this is CPU-specific, too - rather than board/system.
- */
-extern atomic_t cpus_booted;
-
-void __init smp_boot_cpus(void)
-{
-	int i;
-	int cur_cpu = 0;
-
-	smp_num_cpus = prom_setup_smp();
-	init_new_context(current, &init_mm);
-	current->processor = 0;
-	cpu_data[0].udelay_val = loops_per_jiffy;
-	cpu_data[0].asid_cache = ASID_FIRST_VERSION;
-	CPUMASK_CLRALL(cpu_online_map);
-	CPUMASK_SETB(cpu_online_map, 0);
-	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
-	__cpu_number_map[0] = 0;
-	__cpu_logical_map[0] = 0;
-	init_idle();
-
-	/* 
-	 * This loop attempts to compensate for "holes" in the CPU
-	 * numbering.  It's overkill, but general.
-	 */
-	for (i = 1; i < smp_num_cpus; ) {
-		struct task_struct *p;
-		struct pt_regs regs;
-		int retval;
-		printk("Starting CPU %d... ", i);
-
-		/* Spawn a new process normally.  Grab a pointer to
-		   its task struct so we can mess with it */
-		do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
-		p = init_task.prev_task;
-
-		/* Schedule the first task manually */
-		p->processor = i;
-		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
-
-		/* Attach to the address space of init_task. */
-		atomic_inc(&init_mm.mm_count);
-		p->active_mm = &init_mm;
-		init_tasks[i] = p;
-
-		del_from_runqueue(p);
-		unhash_process(p);
-
-		do {
-			/* Iterate until we find a CPU that comes up */
-			cur_cpu++;
-			retval = prom_boot_secondary(cur_cpu,
-					    (unsigned long)p + KERNEL_STACK_SIZE - 32,
-					    (unsigned long)p);
-			__cpu_number_map[i] = i;
-			__cpu_logical_map[i] = i;
-		} while (!retval && (cur_cpu < NR_CPUS));
-		if (retval) {
-			i++;
-		} else {
-			panic("CPU discovery disaster");
-		}
-
-#if 0
-		/* This is copied from the ip-27 code in the mips64 tree */
-
-		struct task_struct *p;
-
-		/*
-		 * The following code is purely to make sure
-		 * Linux can schedule processes on this slave.
-		 */
-		kernel_thread(0, NULL, CLONE_PID);
-		p = init_task.prev_task;
-		sprintf(p->comm, "%s%d", "Idle", i);
-		init_tasks[i] = p;
-		p->processor = i;
-		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
-		del_from_runqueue(p);
-		unhash_process(p);
-		/* Attach to the address space of init_task. */
-		atomic_inc(&init_mm.mm_count);
-		p->active_mm = &init_mm;
-		prom_boot_secondary(i, 
-				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
-				    (unsigned long)p);
-#endif
-	}
-
-	/* Wait for everyone to come up */
-	while (atomic_read(&cpus_booted) != smp_num_cpus);
-
-	smp_threads_ready = 1;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sibyte/swarm/time.c linux-2.4.20/arch/mips/sibyte/swarm/time.c
--- linux-2.4.19/arch/mips/sibyte/swarm/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sibyte/swarm/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/* 
- * Time routines for the swarm board.  We pass all the hard stuff
- * through to the sb1250 handling code.  Only thing we really keep
- * track of here is what time of day we think it is.  And we don't
- * really even do a good job of that...
- */
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <asm/addrspace.h>
-
-#include <asm/sibyte/64bit.h>
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_smbus.h>
-
-extern rwlock_t xtime_lock;
-
-/* Xicor 1241 definitions */
-
-/*
- * Register bits
- */
-
-#define X1241REG_SR_BAT	0x80		/* currently on battery power */
-#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
-#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
-#define X1241REG_SR_RTCF 0x01		/* clock failed */
-#define X1241REG_BL_BP2 0x80		/* block protect 2 */
-#define X1241REG_BL_BP1 0x40		/* block protect 1 */
-#define X1241REG_BL_BP0 0x20		/* block protect 0 */
-#define X1241REG_BL_WD1	0x10
-#define X1241REG_BL_WD0	0x08
-#define X1241REG_HR_MIL 0x80		/* military time format */
-
-/*
- * Register numbers
- */
-
-#define X1241REG_BL	0x10		/* block protect bits */
-#define X1241REG_INT	0x11		/*  */
-#define X1241REG_SC	0x30		/* Seconds */
-#define X1241REG_MN	0x31		/* Minutes */
-#define X1241REG_HR	0x32		/* Hours */
-#define X1241REG_DT	0x33		/* Day of month */
-#define X1241REG_MO	0x34		/* Month */
-#define X1241REG_YR	0x35		/* Year */
-#define X1241REG_DW	0x36		/* Day of Week */
-#define X1241REG_Y2K	0x37		/* Year 2K */
-#define X1241REG_SR	0x3F		/* Status register */
-
-#define X1241_CCR_ADDRESS	0x6F
-
-#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg))
-
-static int xicor_read(uint8_t addr)
-{
-        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	out64((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
-	out64((addr & 0xff), SMB_CSR(R_SMB_DATA));
-	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
-
-        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
-
-        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        }
-
-	return (in64(SMB_CSR(R_SMB_DATA)) & 0xff);
-}
-
-static int xicor_write(uint8_t addr, int b)
-{
-        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	out64(addr, SMB_CSR(R_SMB_CMD));
-	out64((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
-	out64(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
-	      SMB_CSR(R_SMB_START));
-
-        while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        } else {
-		return 0;
-	}
-}
-
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-
-/*
- * 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.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-
-	cmos_minutes = xicor_read(X1241REG_MN);
-	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;
-
-	/* unlock writes to the CCR */
-	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
-	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		BIN_TO_BCD(real_seconds);
-		BIN_TO_BCD(real_minutes);
-		xicor_write(X1241REG_SC, real_seconds);
-		xicor_write(X1241REG_MN, real_minutes);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	xicor_write(X1241REG_SR, 0);
-
-	printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
-
-	return retval;
-}
-
-static unsigned long __init get_swarm_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec, y2k;
-
-	sec = xicor_read(X1241REG_SC);
-	min = xicor_read(X1241REG_MN);
-	hour = xicor_read(X1241REG_HR);
-
-	if (hour & X1241REG_HR_MIL) {
-		hour &= 0x3f;
-	} else {
-		if (hour & 0x20)
-			hour = (hour & 0xf) + 0x12;
-	}
-
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hour);
-
-	day = xicor_read(X1241REG_DT);
-	mon = xicor_read(X1241REG_MO);
-	year = xicor_read(X1241REG_YR);
-	y2k = xicor_read(X1241REG_Y2K);
- 
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(year);
-	BCD_TO_BIN(y2k);
-
-	year += (y2k * 100);
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-/*
- *  Bring up the timer at 100 Hz.  
- */
-void __init swarm_time_init(void)
-{
-	unsigned int flags;
-	int status;
-
-	/* Set up the scd general purpose timer 0 to cpu 0 */
-	sb1250_time_init();
-
-	/* Establish communication with the Xicor 1241 RTC */
-	/* XXXKW how do I share the SMBus with the I2C subsystem? */
-
-	out64(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
-	out64(0, SMB_CSR(R_SMB_CONTROL));
-
-	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
-		printk("x1241: couldn't detect on SWARM SMBus 1\n");
-	} else {
-		if (status & X1241REG_SR_RTCF)
-			printk("x1241: battery failed -- time is probably wrong\n");
-		write_lock_irqsave (&xtime_lock, flags);
-		xtime.tv_sec = get_swarm_time();
-		xtime.tv_usec = 0;
-		write_unlock_irqrestore(&xtime_lock, flags);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/sni/pci.c linux-2.4.20/arch/mips/sni/pci.c
--- linux-2.4.19/arch/mips/sni/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/sni/pci.c	2002-10-04 00:41:20.000000000 +0000
@@ -199,7 +199,8 @@
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/tools/Makefile linux-2.4.20/arch/mips/tools/Makefile
--- linux-2.4.19/arch/mips/tools/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/tools/Makefile	2002-10-04 00:41:12.000000000 +0000
@@ -17,9 +17,8 @@
 
 clean:
 	rm -f offset.[hs] $(TARGET).new
-	
-mrproper:	
-	rm -f offset.[hs] $(TARGET).new
+
+mrproper: clean
 	rm -f $(TARGET)
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/tools/offset.c linux-2.4.20/arch/mips/tools/offset.c
--- linux-2.4.19/arch/mips/tools/offset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips/tools/offset.c	2002-10-04 00:41:13.000000000 +0000
@@ -2,8 +2,8 @@
  * offset.c: Calculate pt_regs and task_struct offsets.
  *
  * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  *
  * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
@@ -82,15 +82,16 @@
 	text("/* MIPS task_struct offsets. */");
 	offset("#define TASK_STATE         ", struct task_struct, state);
 	offset("#define TASK_FLAGS         ", struct task_struct, flags);
+	constant("  #define _PT_TRACESYS        ", PT_TRACESYS);
 	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
 	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
 	offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
 	offset("#define TASK_COUNTER       ", struct task_struct, counter);
 	offset("#define TASK_NICE          ", struct task_struct, nice);
 	offset("#define TASK_MM            ", struct task_struct, mm);
+	offset("#define TASK_PROCESSOR     ", struct task_struct, processor);
 	offset("#define TASK_PID           ", struct task_struct, pid);
 	size(  "#define TASK_STRUCT_SIZE   ", struct task_struct);
-	constant("#define PT_TRACESYS        ", PT_TRACESYS);
 	linefeed;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/Makefile linux-2.4.20/arch/mips/vr41xx/common/Makefile
--- linux-2.4.19/arch/mips/vr41xx/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/Makefile	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,21 @@
+#
+# Makefile for common code of the NEC VR4100 series.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+USE_STANDARD_AS_RULE := true
+
+all: vr41xx.o
+
+O_TARGET := vr41xx.o
+
+obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o
+
+obj-$(CONFIG_PCI)		+= pciu.o
+obj-$(CONFIG_SERIAL)		+= serial.o
+obj-$(CONFIG_VR41XX_TIME_C)	+= time.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/bcu.c linux-2.4.20/arch/mips/vr41xx/common/bcu.c
--- linux-2.4.19/arch/mips/vr41xx/common/bcu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/bcu.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,206 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/bcu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Bus Control Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Calculate mips_counter_frequency properly on VR4131.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define VR4111_CLKSPEEDREG	KSEG1ADDR(0x0b000014)
+#define VR4122_CLKSPEEDREG	KSEG1ADDR(0x0f000014)
+#define VR4131_CLKSPEEDREG	VR4122_CLKSPEEDREG
+ #define CLKSP(x)		((x) & 0x001f)
+
+ #define DIV2B			0x8000
+ #define DIV3B			0x4000
+ #define DIV4B			0x2000
+
+ #define DIVT(x)		(((x) & 0xf000) >> 12)
+ #define DIVVT(x)		(((x) & 0x0f00) >> 8)
+
+ #define TDIVMODE(x)		(2 << (((x) & 0x1000) >> 12))
+ #define VTDIVMODE(x)		(((x) & 0x0700) >> 8)
+
+unsigned long vr41xx_vtclock = 0;
+
+static inline u16 read_clkspeed(void)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121: return readw(VR4111_CLKSPEEDREG);
+	case CPU_VR4122: return readw(VR4122_CLKSPEEDREG);
+	case CPU_VR4131: return readw(VR4131_CLKSPEEDREG);
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return 0;
+}
+
+static inline unsigned long calculate_pclock(u16 clkspeed)
+{
+	unsigned long pclock = 0;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		pclock = 18432000 * 64;
+		break;
+	case CPU_VR4122:
+		pclock = 18432000 * 98;
+		break;
+	case CPU_VR4131:
+		pclock = 18432000 * 108;
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	pclock /= CLKSP(clkspeed);
+	printk(KERN_INFO "PClock: %ldHz\n", pclock);
+
+	return pclock;
+}
+
+static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+		/* The NEC VR4111 doesn't have the VTClock. */
+		break;
+	case CPU_VR4121:
+		vr41xx_vtclock = pclock;
+		/* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
+		if (DIVVT(clkspeed) == 9)
+			vr41xx_vtclock = pclock * 6;
+		/* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
+		else if (DIVVT(clkspeed) == 10)
+			vr41xx_vtclock = pclock * 4;
+		vr41xx_vtclock /= DIVVT(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	case CPU_VR4122:
+		if(VTDIVMODE(clkspeed) == 7)
+			vr41xx_vtclock = pclock / 1;
+		else if(VTDIVMODE(clkspeed) == 1)
+			vr41xx_vtclock = pclock / 2;
+		else
+			vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	case CPU_VR4131:
+		vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return vr41xx_vtclock;
+}
+
+static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock,
+                                             unsigned long vtclock)
+{
+	unsigned long tclock = 0;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+		if (!(clkspeed & DIV2B))
+        		tclock = pclock / 2;
+		else if (!(clkspeed & DIV3B))
+        		tclock = pclock / 3;
+		else if (!(clkspeed & DIV4B))
+        		tclock = pclock / 4;
+		break;
+	case CPU_VR4121:
+		tclock = pclock / DIVT(clkspeed);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		tclock = vtclock / TDIVMODE(clkspeed);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	printk(KERN_INFO "TClock: %ldHz\n", tclock);
+
+	return tclock;
+}
+
+static inline unsigned long calculate_mips_counter_frequency(unsigned long tclock)
+{
+	/*
+	 * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2).
+	 */
+	if ((mips_cpu.processor_id == PRID_VR4131_REV2_0) ||
+	    (mips_cpu.processor_id == PRID_VR4131_REV2_1))
+		tclock /= 2;
+	else
+		tclock /= 4;
+
+	return tclock;
+}
+
+void __init vr41xx_bcu_init(void)
+{
+	unsigned long pclock, vtclock, tclock;
+	u16 clkspeed;
+
+	clkspeed = read_clkspeed();
+
+	pclock = calculate_pclock(clkspeed);
+	vtclock = calculate_vtclock(clkspeed, pclock);
+	tclock = calculate_tclock(clkspeed, pclock, vtclock);
+
+	mips_counter_frequency = calculate_mips_counter_frequency(tclock);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/cmu.c linux-2.4.20/arch/mips/vr41xx/common/cmu.c
--- linux-2.4.19/arch/mips/vr41xx/common/cmu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/cmu.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/cmu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Clock Mask Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+
+#define VR4111_CMUCLKMSK	KSEG1ADDR(0x0b000060)
+#define VR4122_CMUCLKMSK	KSEG1ADDR(0x0f000060)
+
+static u32 vr41xx_cmu_base;
+static u16 cmuclkmsk;
+
+#define write_cmu(mask)	writew((mask), vr41xx_cmu_base)
+
+void vr41xx_clock_supply(u16 mask)
+{
+	cmuclkmsk |= mask;
+	write_cmu(cmuclkmsk);
+}
+
+void vr41xx_clock_mask(u16 mask)
+{
+	cmuclkmsk &= ~mask;
+	write_cmu(cmuclkmsk);
+}
+
+void __init vr41xx_cmu_init(u16 mask)
+{
+	switch (mips_cpu.cputype) {
+        case CPU_VR4111:
+        case CPU_VR4121:
+                vr41xx_cmu_base = VR4111_CMUCLKMSK;
+                break;
+        case CPU_VR4122:
+        case CPU_VR4131:
+                vr41xx_cmu_base = VR4122_CMUCLKMSK;
+                break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+        }
+
+	cmuclkmsk = mask;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/giu.c linux-2.4.20/arch/mips/vr41xx/common/giu.c
--- linux-2.4.19/arch/mips/vr41xx/common/giu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/giu.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,270 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/giu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	General-purpose I/O Unit Interrupt routines for NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define VR4111_GIUIOSELL	KSEG1ADDR(0x0b000100)
+#define VR4122_GIUIOSELL	KSEG1ADDR(0x0f000140)
+
+#define GIUIOSELL	0x00
+#define GIUIOSELH	0x02
+#define GIUINTSTATL	0x08
+#define GIUINTSTATH	0x0a
+#define GIUINTENL	0x0c
+#define GIUINTENH	0x0e
+#define GIUINTTYPL	0x10
+#define GIUINTTYPH	0x12
+#define GIUINTALSELL	0x14
+#define GIUINTALSELH	0x16
+#define GIUINTHTSELL	0x18
+#define GIUINTHTSELH	0x1a
+
+u32 vr41xx_giu_base = 0;
+
+#define read_giuint(offset)		readw(vr41xx_giu_base + (offset))
+#define write_giuint(val, offset)	writew((val), vr41xx_giu_base + (offset))
+
+static inline u16 set_giuint(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_giuint(offset);
+	res |= set;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_giuint(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_giuint(offset);
+	res &= ~clear;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+void vr41xx_enable_giuint(u8 pin)
+{
+	if (pin < 16)
+		set_giuint(GIUINTENL, (u16)1 << pin);
+	else
+		set_giuint(GIUINTENH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_disable_giuint(u8 pin)
+{
+	if (pin < 16)
+		clear_giuint(GIUINTENL, (u16)1 << pin);
+	else
+		clear_giuint(GIUINTENH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_clear_giuint(u8 pin)
+{
+	if (pin < 16)
+		write_giuint(GIUINTSTATL, (u16)1 << pin);
+	else
+		write_giuint(GIUINTSTATH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_set_irq_trigger(u8 pin, u8 trigger, u8 hold)
+{
+	u16 mask;
+
+	if (pin < 16) {
+		mask = (u16)1 << pin;
+		if (trigger == TRIGGER_EDGE) {
+        		set_giuint(GIUINTTYPL, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELL, mask);
+			else
+				clear_giuint(GIUINTHTSELL, mask);
+		} else {
+			clear_giuint(GIUINTTYPL, mask);
+			clear_giuint(GIUINTHTSELL, mask);
+		}
+	} else {
+		mask = (u16)1 << (pin - 16);
+		if (trigger == TRIGGER_EDGE) {
+			set_giuint(GIUINTTYPH, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELH, mask);
+			else
+				clear_giuint(GIUINTHTSELH, mask);
+		} else {
+			clear_giuint(GIUINTTYPH, mask);
+			clear_giuint(GIUINTHTSELH, mask);
+		}
+	}
+
+	vr41xx_clear_giuint(pin);
+}
+
+void vr41xx_set_irq_level(u8 pin, u8 level)
+{
+	u16 mask;
+
+	if (pin < 16) {
+		mask = (u16)1 << pin;
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELL, mask);
+		else
+			clear_giuint(GIUINTALSELL, mask);
+	} else {
+		mask = (u16)1 << (pin - 16);
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELH, mask);
+		else
+			clear_giuint(GIUINTALSELH, mask);
+	}
+
+	vr41xx_clear_giuint(pin);
+}
+
+#define GIUINT_CASCADE_IRQ	16
+#define GIUINT_NR_IRQS		32
+
+enum {
+	GIUINT_NO_CASCADE,
+	GIUINT_CASCADE
+};
+
+struct vr41xx_giuint_cascade {
+	unsigned int flag;
+	int (*get_irq_number)(int irq);
+};
+
+static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS];
+static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL};
+
+static int no_irq_number(int irq)
+{
+	return -EINVAL;
+}
+
+int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq))
+{
+	unsigned int pin;
+	int retval;
+
+	if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31))
+		return -EINVAL;
+
+	if(!get_irq_number)
+		return -EINVAL;
+
+	pin = irq - GIU_IRQ(0);
+	giuint_cascade[pin].flag = GIUINT_CASCADE;
+	giuint_cascade[pin].get_irq_number = get_irq_number;
+
+	retval = setup_irq(irq, &giu_cascade);
+	if (retval) {
+		giuint_cascade[pin].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[pin].get_irq_number = no_irq_number;
+	}
+
+	return retval;
+}
+
+extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs)
+{
+	struct vr41xx_giuint_cascade *cascade;
+	unsigned int retval = 0;
+	int giuint_irq, cascade_irq;
+
+	disable_irq(GIUINT_CASCADE_IRQ);
+	cascade = &giuint_cascade[pin];
+	giuint_irq = pin + GIU_IRQ(0);
+	if (cascade->flag == GIUINT_CASCADE) {
+		cascade_irq = cascade->get_irq_number(giuint_irq);
+		disable_irq(giuint_irq);
+		if (cascade_irq > 0)
+			retval = do_IRQ(cascade_irq, regs);
+		enable_irq(giuint_irq);
+	} else
+		retval = do_IRQ(giuint_irq, regs);
+	enable_irq(GIUINT_CASCADE_IRQ);
+
+	return retval;
+}
+
+void (*board_irq_init)(void) = NULL;
+
+void __init vr41xx_giuint_init(void)
+{
+	int i;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_giu_base = VR4111_GIUIOSELL;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		vr41xx_giu_base = VR4122_GIUIOSELL;
+		break;
+	default:
+		panic("GIU: Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+
+	for (i = 0; i < GIUINT_NR_IRQS; i++) {
+                vr41xx_disable_giuint(i);
+		giuint_cascade[i].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[i].get_irq_number = no_irq_number;
+	}
+
+	if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade))
+		printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ);
+
+	if (board_irq_init)
+		board_irq_init();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/icu.c linux-2.4.20/arch/mips/vr41xx/common/icu.c
--- linux-2.4.19/arch/mips/vr41xx/common/icu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/icu.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,422 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/vr4122/common/icu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt Control Unit routines for the NEC VR4122 and VR4131.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - kgdb support.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/gdb-stub.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define MIPS_CPU_IRQ_BASE	0
+#define SYSINT1_IRQ_BASE	8
+#define SYSINT1_IRQ_LAST	23
+#define SYSINT2_IRQ_BASE	24
+#define SYSINT2_IRQ_LAST	39
+#define GIUINT_IRQ_BASE		GIU_IRQ(0)
+#define GIUINT_IRQ_LAST		GIU_IRQ(31)
+
+#define ICU_CASCADE_IRQ		(MIPS_CPU_IRQ_BASE + 2)
+
+extern asmlinkage void vr41xx_handle_interrupt(void);
+
+extern void __init init_generic_irq(void);
+extern void mips_cpu_irq_init(u32 irq_base);
+extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+extern void vr41xx_giuint_init(void);
+extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs);
+
+static u32 vr41xx_icu1_base = 0;
+static u32 vr41xx_icu2_base = 0;
+
+#define VR4111_SYSINT1REG	KSEG1ADDR(0x0b000080)
+#define VR4111_SYSINT2REG	KSEG1ADDR(0x0b000200)
+
+#define VR4122_SYSINT1REG	KSEG1ADDR(0x0f000080)
+#define VR4122_SYSINT2REG	KSEG1ADDR(0x0f0000a0)
+
+#define SYSINT1REG	0x00
+#define GIUINTLREG	0x08
+#define MSYSINT1REG	0x0c
+#define MGIUINTLREG	0x14
+#define NMIREG		0x18
+#define SOFTREG		0x1a
+
+#define SYSINT2REG	0x00
+#define GIUINTHREG	0x02
+#define MSYSINT2REG	0x06
+#define MGIUINTHREG	0x08
+
+#define read_icu1(offset)	readw(vr41xx_icu1_base + (offset))
+#define write_icu1(val, offset)	writew((val), vr41xx_icu1_base + (offset))
+
+#define read_icu2(offset)	readw(vr41xx_icu2_base + (offset))
+#define write_icu2(val, offset)	writew((val), vr41xx_icu2_base + (offset))
+
+static inline u16 set_icu1(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_icu1(offset);
+	res |= set;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_icu1(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_icu1(offset);
+	res &= ~clear;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline u16 set_icu2(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_icu2(offset);
+	res |= set;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_icu2(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_icu2(offset);
+	res &= ~clear;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+/*=======================================================================*/
+
+static void enable_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static void disable_sysint1_irq(unsigned int irq)
+{
+	clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static unsigned int startup_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sysint1_irq	disable_sysint1_irq
+#define ack_sysint1_irq		disable_sysint1_irq
+
+static void end_sysint1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static struct hw_interrupt_type sysint1_irq_type = {
+	"SYSINT1",
+	startup_sysint1_irq,
+	shutdown_sysint1_irq,
+	enable_sysint1_irq,
+	disable_sysint1_irq,
+	ack_sysint1_irq,
+	end_sysint1_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+static void enable_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static void disable_sysint2_irq(unsigned int irq)
+{
+	clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static unsigned int startup_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sysint2_irq	disable_sysint2_irq
+#define ack_sysint2_irq		disable_sysint2_irq
+
+static void end_sysint2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static struct hw_interrupt_type sysint2_irq_type = {
+	"SYSINT2",
+	startup_sysint2_irq,
+	shutdown_sysint2_irq,
+	enable_sysint2_irq,
+	disable_sysint2_irq,
+	ack_sysint2_irq,
+	end_sysint2_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+extern void vr41xx_enable_giuint(u8 pin);
+extern void vr41xx_disable_giuint(u8 pin);
+extern void vr41xx_clear_giuint(u8 pin);
+
+static void enable_giuint_irq(unsigned int irq)
+{
+	u8 pin;
+
+	pin = irq - GIUINT_IRQ_BASE;
+	if (pin < 16)
+		set_icu1(MGIUINTLREG, (u16)1 << pin);
+	else
+		set_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
+
+	vr41xx_enable_giuint(pin);
+}
+
+static void disable_giuint_irq(unsigned int irq)
+{
+	u8 pin;
+
+	pin = irq - GIUINT_IRQ_BASE;
+	vr41xx_disable_giuint(pin);
+
+	if (pin < 16)
+		clear_icu1(MGIUINTLREG, (u16)1 << pin);
+	else
+		clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
+}
+
+static unsigned int startup_giuint_irq(unsigned int irq)
+{
+	vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE);
+
+	enable_giuint_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_giuint_irq	disable_giuint_irq
+
+static void ack_giuint_irq(unsigned int irq)
+{
+	disable_giuint_irq(irq);
+
+	vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE);
+}
+
+static void end_giuint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_giuint_irq(irq);
+}
+
+static struct hw_interrupt_type giuint_irq_type = {
+	"GIUINT",
+	startup_giuint_irq,
+	shutdown_giuint_irq,
+	enable_giuint_irq,
+	disable_giuint_irq,
+	ack_giuint_irq,
+	end_giuint_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL};
+
+static void __init vr41xx_icu_init(void)
+{
+	int i;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_icu1_base = VR4111_SYSINT1REG;
+		vr41xx_icu2_base = VR4111_SYSINT2REG;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		vr41xx_icu1_base = VR4122_SYSINT1REG;
+		vr41xx_icu2_base = VR4122_SYSINT2REG;
+		break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+
+	write_icu1(0, MSYSINT1REG);
+	write_icu1(0, MGIUINTLREG);
+
+	write_icu2(0, MSYSINT2REG);
+	write_icu2(0, MGIUINTHREG);
+
+	for (i = SYSINT1_IRQ_BASE; i <= GIUINT_IRQ_LAST; i++) {
+		if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST)
+			irq_desc[i].handler = &sysint1_irq_type;
+		else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST)
+			irq_desc[i].handler = &sysint2_irq_type;
+		else if (i >= GIUINT_IRQ_BASE && i <= GIUINT_IRQ_LAST)
+			irq_desc[i].handler = &giuint_irq_type;
+	}
+
+	setup_irq(ICU_CASCADE_IRQ, &icu_cascade);
+}
+
+void __init init_IRQ(void)
+{
+	memset(irq_desc, 0, sizeof(irq_desc));
+
+	init_generic_irq();
+	mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
+	vr41xx_icu_init();
+
+	vr41xx_giuint_init();
+
+	set_except_vector(0, vr41xx_handle_interrupt);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("Setting debug traps - please connect the remote debugger.\n");
+	set_debug_traps();
+	breakpoint();
+#endif
+}
+
+/*=======================================================================*/
+
+static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs)
+{
+	int i;
+
+	if (pendl) {
+		for (i = 0; i < 16; i++) {
+			if (pendl & (0x0001 << i)) {
+				giuint_do_IRQ(i, regs);
+				return;
+			}
+		}
+	}
+	else if (pendh) {
+		for (i = 0; i < 16; i++) {
+			if (pendh & (0x0001 << i)) {
+				giuint_do_IRQ(i + 16, regs);
+				return;
+			}
+		}
+	}
+}
+
+asmlinkage void icu_irqdispatch(struct pt_regs *regs)
+{
+	u16 pend1, pend2, pendl, pendh;
+	u16 mask1, mask2, maskl, maskh;
+	int i;
+
+	pend1 = read_icu1(SYSINT1REG);
+	mask1 = read_icu1(MSYSINT1REG);
+
+	pend2 = read_icu2(SYSINT2REG);
+	mask2 = read_icu2(MSYSINT2REG);
+
+	pendl = read_icu1(GIUINTLREG);
+	maskl = read_icu1(MGIUINTLREG);
+
+	pendh = read_icu2(GIUINTHREG);
+	maskh = read_icu2(MGIUINTHREG);
+
+	pend1 &= mask1;
+	pend2 &= mask2;
+	pendl &= maskl;
+	pendh &= maskh;
+
+	if (pend1) {
+		if ((pend1 & 0x01ff) == 0x0100) {
+			giuint_irqdispatch(pendl, pendh, regs);
+		}
+		else {
+			for (i = 0; i < 16; i++) {
+				if (pend1 & (0x0001 << i)) {
+					do_IRQ(SYSINT1_IRQ_BASE + i, regs);
+					break;
+				}
+			}
+		}
+		return;
+	}
+	else if (pend2) {
+		for (i = 0; i < 16; i++) {
+			if (pend2 & (0x0001 << i)) {
+				do_IRQ(SYSINT2_IRQ_BASE + i, regs);
+				break;
+			}
+		}
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/int-handler.S linux-2.4.20/arch/mips/vr41xx/common/int-handler.S
--- linux-2.4.19/arch/mips/vr41xx/common/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/int-handler.S	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,114 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/int-handler.S
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt dispatcher for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4100 series are supported.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+		.text
+		.set	noreorder
+
+		.align	5
+		NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI
+		.set	at
+		.set	noreorder
+
+		/*
+		 * Get the pending interrupts
+		 */
+		mfc0	t0, CP0_CAUSE
+		mfc0	t1, CP0_STATUS
+		andi	t0, 0xff00
+		and	t0, t0, t1
+
+		andi	t1, t0, CAUSEF_IP7	# timer interrupt
+		beqz	t1, 1f
+		li	a0, 7
+		jal	ll_timer_interrupt
+		move	a1, sp
+		j	ret_from_irq
+
+1:
+		andi	t1, t0, 0x7800		# check for IP3-6
+		beqz	t1, 2f
+
+		andi	t1, t0, CAUSEF_IP3	# check for IP3
+		bnez	t1, handle_it
+		li	a0, 3
+
+		andi	t1, t0, CAUSEF_IP4	# check for IP4
+		bnez	t1, handle_it
+		li	a0, 4
+
+		andi	t1, t0, CAUSEF_IP5	# check for IP5
+		bnez	t1, handle_it
+		li	a0, 5
+
+		andi	t1, t0, CAUSEF_IP6	# check for IP6
+		bnez	t1, handle_it
+		li	a0, 6
+
+2:
+		andi	t1, t0, CAUSEF_IP2	# check for IP2
+		beqz	t1, 3f
+		move	a0, sp
+		jal	icu_irqdispatch
+		nop
+		j	ret_from_irq
+		nop
+
+3:
+		andi	t1, t0, CAUSEF_IP0	# check for IP0
+		bnez	t1, handle_it
+		li	a0, 0
+
+		andi	t1, t0, CAUSEF_IP1	# check for IP1
+		bnez	t1, handle_it
+		li	a0, 1
+
+		j	spurious_interrupt
+		nop
+
+handle_it:
+		jal	do_IRQ
+		move	a1, sp
+		j	ret_from_irq
+		END(vr41xx_handle_interrupt)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/pciu.c linux-2.4.20/arch/mips/vr41xx/common/pciu.c
--- linux-2.4.19/arch/mips/vr41xx/common/pciu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/pciu.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,280 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/pciu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PCI Control Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Fix deadlock-causing PCIU access race for VR4131.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/pci_channel.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#include "pciu.h"
+
+extern unsigned long vr41xx_vtclock;
+
+static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned int dev_fn = dev->devfn;
+
+	if (bus == 0) {
+		/*
+		 * Type 0 configuration
+		 */
+		if (PCI_SLOT(dev_fn) < 11 || PCI_SLOT(dev_fn) > 31 || where > 255)
+			return -1;
+
+		writel((1UL << PCI_SLOT(dev_fn))|
+		       (PCI_FUNC(dev_fn) << 8)	|
+		       (where & 0xfc),
+		       PCICONFAREG);
+	}
+	else {
+		/*
+		 * Type 1 configuration
+		 */
+		if (bus > 255 || PCI_SLOT(dev_fn) > 31 || where > 255)
+			return -1;
+
+		writel((bus << 16)	|
+		       (dev_fn << 8)	|
+		       (where & 0xfc)	|
+		       1UL,
+		       PCICONFAREG);
+	}
+
+	return 0;
+}
+
+static int vr41xx_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+	u32 data;
+
+	*val = 0xff;
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	*val = (u8)(data >> ((where & 3) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int vr41xx_pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+	u32 data;
+
+	*val = 0xffff;
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	*val = (u16)(data >> ((where & 2) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+{
+	*val = 0xffffffff;
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*val = readl(PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	u32 data;
+	int shift;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	shift = (where & 3) << 3;
+	data &= ~(0xff << shift);
+	data |= (((u32)val) << shift);
+
+	writel(data, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+	u32 data;
+	int shift;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	shift = (where & 2) << 3;
+	data &= ~(0xffff << shift);
+	data |= (((u32)val) << shift);
+	writel(data, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	writel(val, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops vr41xx_pci_ops = {
+	vr41xx_pci_read_config_byte,
+	vr41xx_pci_read_config_word,
+	vr41xx_pci_read_config_dword,
+	vr41xx_pci_write_config_byte,
+	vr41xx_pci_write_config_word,
+	vr41xx_pci_write_config_dword
+};
+
+void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map)
+{
+	struct vr41xx_pci_address_space *s;
+	u32 config;
+	int n;
+
+	if (!map)
+		return;
+
+	/* Disable PCI interrupt */
+	writew(0, MPCIINTREG);
+
+	/* Supply VTClock to PCIU */
+	vr41xx_clock_supply(PCIU_CLOCK);
+
+	/*
+	 * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK
+	 * before doing any PCIU access to avoid deadlock on VR4131.
+	 */
+	udelay(1);
+
+	/* Select PCI clock */
+	if (vr41xx_vtclock < MAX_PCI_CLOCK)
+		writel(EQUAL_VTCLOCK, PCICLKSELREG);
+	else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK)
+		writel(HALF_VTCLOCK, PCICLKSELREG);
+	else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK)
+		writel(QUARTER_VTCLOCK, PCICLKSELREG);
+	else
+		printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n");
+
+	/* Supply PCI clock by PCI bus */
+	vr41xx_clock_supply(PCI_CLOCK);
+
+	/*
+	 * Set PCI memory & I/O space address conversion registers
+	 * for master transaction.
+	 */
+	if (map->mem1 != NULL) {
+		s = map->mem1;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMMAW1REG);
+	}
+	if (map->mem2 != NULL) {
+		s = map->mem2;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMMAW2REG);
+	}
+	if (map->io != NULL) {
+		s = map->io;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMIOAWREG);
+	}
+
+	/* Set target memory windows */
+	writel(0x00081000, PCITAW1REG);
+	writel(0UL, PCITAW2REG);
+	pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL);
+	pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL);
+
+	/* Clear bus error */
+	n = readl(BUSERRADREG);
+
+	if (mips_cpu.cputype == CPU_VR4122) {
+		writel(0UL, PCITRDYVREG);
+		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804);
+	} else {
+		writel(100UL, PCITRDYVREG);
+		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004);
+	}
+
+	writel(CONFIG_DONE, PCIENREG);
+	pciu_write_config_dword(PCI_COMMAND,
+	                        PCI_COMMAND_IO |
+	                        PCI_COMMAND_MEMORY |
+	                        PCI_COMMAND_MASTER |
+	                        PCI_COMMAND_PARITY |
+	                        PCI_COMMAND_SERR);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/pciu.h linux-2.4.20/arch/mips/vr41xx/common/pciu.h
--- linux-2.4.19/arch/mips/vr41xx/common/pciu.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/pciu.h	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,167 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/pciu.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for PCI Control Unit of the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#ifndef __VR41XX_PCIU_H
+#define __VR41XX_PCIU_H
+
+#include <linux/config.h>
+#include <asm/addrspace.h>
+
+#define BIT(x)	(1 << (x))
+
+#define PCIMMAW1REG			KSEG1ADDR(0x0f000c00)
+#define PCIMMAW2REG			KSEG1ADDR(0x0f000c04)
+#define PCITAW1REG			KSEG1ADDR(0x0f000c08)
+#define PCITAW2REG			KSEG1ADDR(0x0f000c0c)
+#define PCIMIOAWREG			KSEG1ADDR(0x0f000c10)
+#define INTERNAL_BUS_BASE_ADDRESS	0xff000000
+#define ADDRESS_MASK			0x000fe000
+#define PCI_ACCESS_ENABLE		BIT(12)
+#define PCI_ADDRESS_SETTING		0x000000ff
+
+#define PCICONFDREG			KSEG1ADDR(0x0f000c14)
+#define PCICONFAREG			KSEG1ADDR(0x0f000c18)
+#define PCIMAILREG			KSEG1ADDR(0x0f000c1c)
+
+#define BUSERRADREG			KSEG1ADDR(0x0f000c24)
+#define ERROR_ADDRESS			0xfffffffc
+
+#define INTCNTSTAREG			KSEG1ADDR(0x0f000c28)
+#define MABTCLR				BIT(31)
+#define TRDYCLR				BIT(30)
+#define PARCLR				BIT(29)
+#define MBCLR				BIT(28)
+#define SERRCLR				BIT(27)
+
+#define PCIEXACCREG			KSEG1ADDR(0x0f000c2c)
+#define UNLOCK				BIT(1)
+#define EAREQ				BIT(0)
+
+#define PCIRECONTREG			KSEG1ADDR(0x0f000c30)
+#define RTRYCNT				0x000000ff
+
+#define PCIENREG			KSEG1ADDR(0x0f000c34)
+#define CONFIG_DONE			BIT(2)
+
+#define PCICLKSELREG			KSEG1ADDR(0x0f000c38)
+#define EQUAL_VTCLOCK			0x00000002
+#define HALF_VTCLOCK			0x00000000
+#define QUARTER_VTCLOCK			0x00000001
+
+#define PCITRDYVREG			KSEG1ADDR(0x0f000c3c)
+
+#define PCICLKRUNREG			KSEG1ADDR(0x0f000c60)
+
+#define PCIU_CONFIGREGS_BASE		KSEG1ADDR(0x0f000d00)
+#define VENDORIDREG			KSEG1ADDR(0x0f000d00)
+#define DEVICEIDREG			KSEG1ADDR(0x0f000d00)
+#define COMMANDREG			KSEG1ADDR(0x0f000d04)
+#define STATUSREG			KSEG1ADDR(0x0f000d04)
+#define REVIDREG			KSEG1ADDR(0x0f000d08)
+#define CLASSREG			KSEG1ADDR(0x0f000d08)
+#define CACHELSREG			KSEG1ADDR(0x0f000d0c)
+#define LATTIMEREG			KSEG1ADDR(0x0f000d0c)
+#define MAILBAREG			KSEG1ADDR(0x0f000d10)
+#define PCIMBA1REG			KSEG1ADDR(0x0f000d14)
+#define PCIMBA2REG			KSEG1ADDR(0x0f000d18)
+#define INTLINEREG			KSEG1ADDR(0x0f000d3c)
+#define INTPINREG			KSEG1ADDR(0x0f000d3c)
+#define RETVALREG			KSEG1ADDR(0x0f000d40)
+#define PCIAPCNTREG			KSEG1ADDR(0x0f000d40)
+
+#define MPCIINTREG			KSEG1ADDR(0x0f0000b2)
+
+#define MAX_PCI_CLOCK			33333333
+
+#define PCIU_CLOCK			0x0080
+#define PCI_CLOCK			0x2000
+
+static inline int pciu_read_config_byte(int where, u8 *val)
+{
+	u32 data;
+
+	data = readl(PCIU_CONFIGREGS_BASE + where);
+	*val = (u8)(data >> ((where & 3) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_read_config_word(int where, u16 *val)
+{
+	u32 data;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = readl(PCIU_CONFIGREGS_BASE + where);
+	*val = (u16)(data >> ((where & 2) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_read_config_dword(int where, u32 *val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	*val = readl(PCIU_CONFIGREGS_BASE + where);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_write_config_byte(int where, u8 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+static inline int pciu_write_config_word(int where, u16 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+static inline int pciu_write_config_dword(int where, u32 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+#endif /* __VR41XX_PCIU_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/reset.c linux-2.4.20/arch/mips/vr41xx/common/reset.c
--- linux-2.4.19/arch/mips/vr41xx/common/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/reset.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void vr41xx_restart(char *command)
+{
+	change_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL));
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	flush_cache_all();
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void vr41xx_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1);
+}
+
+void vr41xx_power_off(void)
+{
+	vr41xx_halt();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/serial.c linux-2.4.20/arch/mips/vr41xx/common/serial.c
--- linux-2.4.19/arch/mips/vr41xx/common/serial.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/serial.c	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,178 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/serial.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Serial Interface Unit routines for NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+/* VR4111 and VR4121 SIU Registers */
+#define VR4111_SIURB		KSEG1ADDR(0x0c000000)
+#define VR4111_SIUIRSEL		KSEG1ADDR(0x0c000008)
+
+/* VR4122 and VR4131 SIU Registers */
+#define VR4122_SIURB		KSEG1ADDR(0x0f000800)
+#define VR4122_SIUIRSEL		KSEG1ADDR(0x0f000808)
+
+ #define USE_RS232C		0x00
+ #define USE_IRDA		0x01
+ #define SIU_USES_IRDA		0x00
+ #define FIR_USES_IRDA		0x02
+ #define IRDA_MODULE_SHARP	0x00
+ #define IRDA_MODULE_TEMIC	0x04
+ #define IRDA_MODULE_HP		0x08
+ #define TMICTX			0x10
+ #define TMICMODE		0x20
+
+#define SIU_BASE_BAUD		1152000
+#define SIU_CLOCK		0x0102
+#define SIU_IRQ			17
+
+/* VR4122 and VR4131 DSIU Registers */
+#define DSIURB			KSEG1ADDR(0x0f000820)
+
+#define MDSIUINTREG		KSEG1ADDR(0x0f000096)
+ #define INTDSIU		0x0800
+
+#define DSIU_BASE_BAUD		1152000
+#define DSIU_CLOCK		0x0802
+#define DSIU_IRQ		29
+
+int vr41xx_serial_ports = 0;
+
+void vr41xx_siu_ifselect(int interface, int module)
+{
+	u16 val = USE_RS232C;	/* Select RS-232C */
+
+	/* Select IrDA */
+	if (interface == SIU_IRDA) {
+		switch (module) {
+		case IRDA_SHARP:
+			val = IRDA_MODULE_SHARP;
+			break;
+		case IRDA_TEMIC:
+			val = IRDA_MODULE_TEMIC;
+			break;
+		case IRDA_HP:
+			val = IRDA_MODULE_HP;
+			break;
+		}
+		val |= USE_IRDA | SIU_USES_IRDA;
+	}
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		writew(val, VR4111_SIUIRSEL);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		writew(val, VR4122_SIUIRSEL);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+}
+
+void __init vr41xx_siu_init(int interface, int module)
+{
+	struct serial_struct s;
+
+	vr41xx_siu_ifselect(interface, module);
+
+	memset(&s, 0, sizeof(s));
+
+	s.line = vr41xx_serial_ports;
+	s.baud_base = SIU_BASE_BAUD;
+	s.irq = SIU_IRQ;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		s.iomem_base = (unsigned char *)VR4111_SIURB;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		s.iomem_base = (unsigned char *)VR4122_SIURB;
+		break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0)
+		printk(KERN_ERR "SIU setup failed!\n");
+
+	vr41xx_clock_supply(SIU_CLOCK);
+
+	vr41xx_serial_ports++;
+}
+
+void __init vr41xx_dsiu_init(void)
+{
+	struct serial_struct s;
+
+	if (mips_cpu.cputype != CPU_VR4122 && mips_cpu.cputype != CPU_VR4131)
+		return;
+
+	memset(&s, 0, sizeof(s));
+
+	s.line = vr41xx_serial_ports;
+	s.baud_base = DSIU_BASE_BAUD;
+	s.irq = DSIU_IRQ;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	s.iomem_base = (unsigned char *)DSIURB;
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0)
+		printk(KERN_ERR "DSIU setup failed!\n");
+
+	vr41xx_clock_supply(DSIU_CLOCK);
+
+	writew(INTDSIU, MDSIUINTREG);
+
+	vr41xx_serial_ports++;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/common/time.c linux-2.4.20/arch/mips/vr41xx/common/time.c
--- linux-2.4.19/arch/mips/vr41xx/common/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/common/time.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/time.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Timer routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4100 series RTC Unit.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4100 series are supported.
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/param.h>
+#include <asm/time.h>
+
+#define MIPS_COUNTER_TIMER_IRQ	7
+
+#define VR4111_ETIMELREG	KSEG1ADDR(0x0b0000c0)
+#define VR4122_ETIMELREG	KSEG1ADDR(0x0f000100)
+
+u32 vr41xx_rtc_base = 0;
+
+#ifdef CONFIG_VR41XX_RTC
+extern unsigned long vr41xx_rtc_get_time(void);
+extern int vr41xx_rtc_set_time(unsigned long sec);
+#endif
+
+void vr41xx_time_init(void)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_rtc_base = VR4111_ETIMELREG;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+                vr41xx_rtc_base = VR4122_ETIMELREG;
+                break;
+        default:
+                panic("Unexpected CPU of NEC VR4100 series");
+                break;
+        }
+
+#ifdef CONFIG_VR41XX_RTC
+        rtc_get_time = vr41xx_rtc_get_time;
+        rtc_set_time = vr41xx_rtc_set_time;
+#endif
+}
+
+void vr41xx_timer_setup(struct irqaction *irq)
+{
+	u32 count;
+
+	setup_irq(MIPS_COUNTER_TIMER_IRQ, irq);
+
+	count = read_32bit_cp0_register(CP0_COUNT);
+	write_32bit_cp0_register (CP0_COMPARE, count + (mips_counter_frequency / HZ));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/Makefile linux-2.4.20/arch/mips/vr41xx/nec-eagle/Makefile
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/Makefile	2002-10-04 00:41:30.000000000 +0000
@@ -0,0 +1,25 @@
+#
+# Makefile for the NEC Eagle/Hawk specific parts of the kernel
+#
+# Author: Yoichi Yuasa
+#         yyuasa@mvista.com or source@mvista.com
+#
+# Copyright 2001,2002 MontaVista Software Inc.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := eagle.o
+
+all: eagle.o
+
+obj-y	:= init.o irq.o setup.o
+
+obj-$(CONFIG_IDE)	+= ide-eagle.o
+obj-$(CONFIG_PCI)	+= pci_fixup.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/ide-eagle.c linux-2.4.20/arch/mips/vr41xx/nec-eagle/ide-eagle.c
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/ide-eagle.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/ide-eagle.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ *
+ * IDE routines for typical pc-like standard configurations
+ * for the NEC Eagle/Hawk board.
+ *
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  Fri,  5 Apr 2002
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  Fri,  1 Mar 2002
+ *  - Added support for NEC Eagle.
+ */
+#include <linux/sched.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <asm/ptrace.h>
+#include <asm/hdreg.h>
+
+static int eagle_ide_default_irq(ide_ioreg_t base)
+{
+	return 0;
+}
+
+static ide_ioreg_t eagle_ide_default_io_base(int index)
+{
+	return 0;
+}
+
+static void eagle_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
+                                      ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static int eagle_ide_request_irq(unsigned int irq,
+                                 void (*handler)(int,void *, struct pt_regs *),
+                                 unsigned long flags, const char *device,
+                                 void *dev_id)
+{
+	return request_irq(irq, handler, SA_SHIRQ, device, dev_id);
+}
+
+static void eagle_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int eagle_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return check_region(from, extent);
+}
+
+static void eagle_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                     const char *name)
+{
+	request_region(from, extent, name);
+}
+
+static void eagle_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	release_region(from, extent);
+}
+
+struct ide_ops eagle_ide_ops = {
+	&eagle_ide_default_irq,
+	&eagle_ide_default_io_base,
+	&eagle_ide_init_hwif_ports,
+	&eagle_ide_request_irq,
+	&eagle_ide_free_irq,
+	&eagle_ide_check_region,
+	&eagle_ide_request_region,
+	&eagle_ide_release_region
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/init.c linux-2.4.20/arch/mips/vr41xx/nec-eagle/init.c
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/init.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/init.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Initialisation code for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "NEC Eagle/Hawk";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec)
+{
+	int i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_EAGLE;
+}
+
+void __init prom_free_prom_memory (void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/irq.c linux-2.4.20/arch/mips/vr41xx/nec-eagle/irq.c
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/irq.c	2002-10-04 00:41:17.000000000 +0000
@@ -0,0 +1,186 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/irq.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt routines for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/eagle.h>
+
+static void enable_pciint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_PCIINTMSKREG);
+	val |= (u8)1 << (irq - PCIINT_IRQ_BASE);
+	writeb(val, NEC_EAGLE_PCIINTMSKREG);
+}
+
+static void disable_pciint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_PCIINTMSKREG);
+	val &= ~((u8)1 << (irq - PCIINT_IRQ_BASE));
+	writeb(val, NEC_EAGLE_PCIINTMSKREG);
+}
+
+static unsigned int startup_pciint_irq(unsigned int irq)
+{
+	enable_pciint_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_pciint_irq	disable_pciint_irq
+#define ack_pciint_irq		disable_pciint_irq
+
+static void end_pciint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_pciint_irq(irq);
+}
+
+static struct hw_interrupt_type pciint_irq_type = {
+	"PCIINT",
+	startup_pciint_irq,
+	shutdown_pciint_irq,
+       	enable_pciint_irq,
+	disable_pciint_irq,
+	ack_pciint_irq,
+	end_pciint_irq,
+	NULL
+};
+
+static void enable_sdbint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_SDBINTMSK);
+	val |= (u8)1 << (irq - SDBINT_IRQ_BASE);
+	writeb(val, NEC_EAGLE_SDBINTMSK);
+}
+
+static void disable_sdbint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_SDBINTMSK);
+	val &= ~((u8)1 << (irq - SDBINT_IRQ_BASE));
+	writeb(val, NEC_EAGLE_SDBINTMSK);
+}
+
+static unsigned int startup_sdbint_irq(unsigned int irq)
+{
+	enable_sdbint_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sdbint_irq	disable_sdbint_irq
+#define ack_sdbint_irq		disable_sdbint_irq
+
+static void end_sdbint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_sdbint_irq(irq);
+}
+
+static struct hw_interrupt_type sdbint_irq_type = {
+	"SDBINT",
+	startup_sdbint_irq,
+	shutdown_sdbint_irq,
+       	enable_sdbint_irq,
+	disable_sdbint_irq,
+	ack_sdbint_irq,
+	end_sdbint_irq,
+	NULL
+};
+
+static int eagle_get_irq_number(int irq)
+{
+	u8 sdbint, pciint;
+	int i;
+
+	sdbint = readb(NEC_EAGLE_SDBINT);
+	sdbint &= (NEC_EAGLE_SDBINT_DEG | NEC_EAGLE_SDBINT_ENUM |
+	           NEC_EAGLE_SDBINT_SIO1INT | NEC_EAGLE_SDBINT_SIO2INT |
+	           NEC_EAGLE_SDBINT_PARINT);
+	pciint = readb(NEC_EAGLE_PCIINTREG);
+	pciint &= (NEC_EAGLE_PCIINT_CP_INTA | NEC_EAGLE_PCIINT_CP_INTB |
+	           NEC_EAGLE_PCIINT_CP_INTC | NEC_EAGLE_PCIINT_CP_INTD |
+	           NEC_EAGLE_PCIINT_LANINT);
+
+	for (i = 1; i < 6; i++)
+		if (sdbint & (0x01 << i))
+			return SDBINT_IRQ_BASE + i;
+
+	for (i = 0; i < 5; i++)
+		if (pciint & (0x01 << i))
+			return PCIINT_IRQ_BASE + i;
+
+	return -EINVAL;
+}
+
+void __init eagle_irq_init(void)
+{
+	int i;
+
+	writeb(0, NEC_EAGLE_SDBINTMSK);
+	writeb(0, NEC_EAGLE_PCIINTMSKREG);
+
+	vr41xx_set_irq_trigger(VRC4173_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(VRC4173_PIN, LEVEL_LOW);
+
+	vr41xx_set_irq_trigger(PCISLOT_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(PCISLOT_PIN, LEVEL_HIGH);
+
+	vr41xx_set_irq_trigger(FPGA_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(FPGA_PIN, LEVEL_HIGH);
+
+	vr41xx_set_irq_trigger(DCD_PIN, TRIGGER_EDGE, SIGNAL_HOLD);
+	vr41xx_set_irq_level(DCD_PIN, LEVEL_LOW);
+
+	for (i = SDBINT_IRQ_BASE; i <= SDBINT_IRQ_LAST; i++)
+		irq_desc[i].handler = &sdbint_irq_type;
+
+	for (i = PCIINT_IRQ_BASE; i <= PCIINT_IRQ_LAST; i++)
+		irq_desc[i].handler = &pciint_irq_type;
+
+	vr41xx_cascade_irq(FPGA_CASCADE_IRQ, eagle_get_irq_number);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/pci_fixup.c linux-2.4.20/arch/mips/vr41xx/nec-eagle/pci_fixup.c
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/pci_fixup.c	2002-10-04 00:41:12.000000000 +0000
@@ -0,0 +1,166 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/pci_fixup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	The NEC Eagle/Hawk Board specific PCI fixups.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Moved mips_pci_channels[] to arch/mips/vr41xx/vr4122/eagle/setup.c.
+ *  - Added support for NEC Hawk.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Fix empty break statements, remove useless CONFIG_PCI.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/eagle.h>
+#ifdef CONFIG_VRC4173
+#include <asm/vr41xx/vrc4173.h>
+#endif
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 slot, func, pin;
+
+	pci_for_each_dev(dev) {
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		dev->irq = 0;
+
+		switch (slot) {
+		case 8:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			}
+			break;
+		case 9:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			}
+			break;
+		case 10:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			}
+			break;
+#ifdef CONFIG_VRC4173
+		case 12:
+			dev->irq = VRC4173_CARDU1_IRQ;
+			break;
+		case 13:
+			dev->irq = VRC4173_CARDU2_IRQ;
+			break;
+		case 24:
+			dev->irq = VRC4173_CARDU1_IRQ;
+			break;
+		case 25:
+			dev->irq = VRC4173_CARDU2_IRQ;
+			break;
+#endif
+		case 28:
+			dev->irq = LANINTA_IRQ;
+			break;
+		case 29:
+			dev->irq = PCISLOT_IRQ;
+			break;
+#ifdef CONFIG_VRC4173
+		case 30:
+			switch (func) {
+			case 0:
+				dev->irq = VRC4173_IRQ;
+				break;
+			case 1:
+				dev->irq = VRC4173_AC97U_IRQ;
+				break;
+			case 2:
+				dev->irq = VRC4173_USBU_IRQ;
+				break;
+			}
+			break;
+#endif
+		}
+
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.20/arch/mips/vr41xx/nec-eagle/setup.c
--- linux-2.4.19/arch/mips/vr41xx/nec-eagle/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/nec-eagle/setup.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,156 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Setup for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 MontaVista Software Inc.
+ *
+ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Moved mips_pci_channels[] from arch/mips/vr41xx/vr4122/eagle/setup.c.
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/pci_channel.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/eagle.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops eagle_ide_ops;
+#endif
+
+extern void eagle_irq_init(void);
+
+#ifdef CONFIG_PCI
+static struct resource vr41xx_pci_io_resource = {
+	"PCI I/O space",
+	VR41XX_PCI_IO_START,
+	VR41XX_PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource vr41xx_pci_mem_resource = {
+	"PCI memory space",
+	VR41XX_PCI_MEM_START,
+	VR41XX_PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops vr41xx_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
+	{NULL, NULL, NULL, 0, 0}
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem1 = {
+	VR41XX_PCI_MEM1_BASE,
+	VR41XX_PCI_MEM1_MASK,
+	IO_MEM1_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem2 = {
+	VR41XX_PCI_MEM2_BASE,
+	VR41XX_PCI_MEM2_MASK,
+	IO_MEM2_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_io = {
+	VR41XX_PCI_IO_BASE,
+	VR41XX_PCI_IO_MASK,
+	IO_PORT_RESOURCE_START
+};
+
+static struct vr41xx_pci_address_map pci_address_map = {
+	&vr41xx_pci_mem1,
+	&vr41xx_pci_mem2,
+	&vr41xx_pci_io
+};
+#endif
+
+void __init nec_eagle_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+	iomem_resource.start = IO_MEM1_RESOURCE_START;
+	iomem_resource.end = IO_MEM2_RESOURCE_END;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+
+	board_time_init = vr41xx_time_init;
+	board_timer_setup = vr41xx_timer_setup;
+
+	board_irq_init = eagle_irq_init;
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &eagle_ide_ops;
+#endif
+
+	vr41xx_bcu_init();
+
+	vr41xx_cmu_init(0);
+
+	vr41xx_dsiu_init();
+	vr41xx_siu_init(SIU_RS232C, 0);
+
+#ifdef CONFIG_PCI
+	vr41xx_pciu_init(&pci_address_map);
+#endif
+
+#ifdef CONFIG_VRC4173
+	vrc4173_init();
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/zao-capcella/Makefile linux-2.4.20/arch/mips/vr41xx/zao-capcella/Makefile
--- linux-2.4.19/arch/mips/vr41xx/zao-capcella/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/zao-capcella/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,20 @@
+#
+# Makefile for the ZAO Networks Capcella  specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := capcella.o
+
+all: capcella.o
+
+obj-y	:= init.o setup.o
+
+obj-$(CONFIG_IDE)	+= ide-capcella.o
+obj-$(CONFIG_PCI)	+= pci_fixup.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/zao-capcella/ide-capcella.c linux-2.4.20/arch/mips/vr41xx/zao-capcella/ide-capcella.c
--- linux-2.4.19/arch/mips/vr41xx/zao-capcella/ide-capcella.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/zao-capcella/ide-capcella.c	2002-10-04 00:41:19.000000000 +0000
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ *
+ * IDE routines for typical pc-like standard configurations
+ * for the ZAO Networks Capcella.
+ *
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
+ */
+/*
+ * Changes:
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Sun, 24 Feb 2002
+ *  - Added ZAO Networks Capcella support.
+ */
+#include <linux/sched.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <asm/ptrace.h>
+#include <asm/hdreg.h>
+
+static int capcella_ide_default_irq(ide_ioreg_t base)
+{
+	switch (base) {
+	case 0x8300: return 42;
+	}
+
+	return 0;
+}
+
+static ide_ioreg_t capcella_ide_default_io_base(int index)
+{
+	switch (index) {
+	case 0: return 0x8300;
+	}
+
+	return 0;
+}
+
+static void capcella_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
+                                         ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = 0;
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+static int capcella_ide_request_irq(unsigned int irq,
+                                    void (*handler)(int,void *, struct pt_regs *),
+                                    unsigned long flags, const char *device,
+                                    void *dev_id)
+{
+	return request_irq(irq, handler, flags, device, dev_id);
+}
+
+static void capcella_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int capcella_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return check_region(from, extent);
+}
+
+static void capcella_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                        const char *name)
+{
+	request_region(from, extent, name);
+}
+
+static void capcella_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	release_region(from, extent);
+}
+
+struct ide_ops capcella_ide_ops = {
+	&capcella_ide_default_irq,
+	&capcella_ide_default_io_base,
+	&capcella_ide_init_hwif_ports,
+	&capcella_ide_request_irq,
+	&capcella_ide_free_irq,
+	&capcella_ide_check_region,
+	&capcella_ide_request_region,
+	&capcella_ide_release_region
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/zao-capcella/init.c linux-2.4.20/arch/mips/vr41xx/zao-capcella/init.c
--- linux-2.4.19/arch/mips/vr41xx/zao-capcella/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/zao-capcella/init.c	2002-10-04 00:41:22.000000000 +0000
@@ -0,0 +1,68 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/init.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Initialisation code for the ZAO Networks Capcella.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  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 <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/vr41xx/vr41xx.h>
+
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "ZAO Networks Capcella";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec)
+{
+	u32 config;
+	int i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_ZAO_CAPCELLA;
+
+	switch (mips_cpu.processor_id) {
+	case PRID_VR4131_REV1_2:
+		config = read_32bit_cp0_register(CP0_CONFIG);
+		config &= ~0x00000030UL;
+		config |= 0x00410000UL;
+		write_32bit_cp0_register(CP0_CONFIG, config);
+		break;
+	default:
+		break;
+	}
+}
+
+void __init prom_free_prom_memory (void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/zao-capcella/pci_fixup.c linux-2.4.20/arch/mips/vr41xx/zao-capcella/pci_fixup.c
--- linux-2.4.19/arch/mips/vr41xx/zao-capcella/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/zao-capcella/pci_fixup.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,73 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/pci_fixup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	The ZAO Networks Capcella specific PCI fixups.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  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 <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/capcella.h>
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 slot, func, pin;
+
+	pci_for_each_dev(dev) {
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+		dev->irq = 0;
+
+		switch (slot) {
+		case 11:
+			dev->irq = RTL8139_1_IRQ;
+			break;
+		case 12:
+			dev->irq = RTL8139_2_IRQ;
+			break;
+		case 14:
+			pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+			switch (pin) {
+			case 1:
+				dev->irq = PC104PLUS_INTA_IRQ;
+				break;
+			case 2:
+				dev->irq = PC104PLUS_INTB_IRQ;
+				break;
+			case 3:
+				dev->irq = PC104PLUS_INTC_IRQ;
+				break;
+			case 4:
+				dev->irq = PC104PLUS_INTD_IRQ;
+				break;
+			}
+			break;
+		}
+
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.20/arch/mips/vr41xx/zao-capcella/setup.c
--- linux-2.4.19/arch/mips/vr41xx/zao-capcella/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips/vr41xx/zao-capcella/setup.c	2002-10-04 00:41:16.000000000 +0000
@@ -0,0 +1,121 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Setup for the ZAO Networks Capcella.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  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 <linux/config.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/pci_channel.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/capcella.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops capcella_ide_ops;
+#endif
+
+#ifdef CONFIG_PCI
+static struct resource vr41xx_pci_io_resource = {
+	"PCI I/O space",
+	VR41XX_PCI_IO_START,
+	VR41XX_PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource vr41xx_pci_mem_resource = {
+	"PCI memory space",
+	VR41XX_PCI_MEM_START,
+	VR41XX_PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops vr41xx_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
+	{NULL, NULL, NULL, 0, 0}
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem1 = {
+	VR41XX_PCI_MEM1_BASE,
+	VR41XX_PCI_MEM1_MASK,
+	IO_MEM1_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem2 = {
+	VR41XX_PCI_MEM2_BASE,
+	VR41XX_PCI_MEM2_MASK,
+	IO_MEM2_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_io = {
+	VR41XX_PCI_IO_BASE,
+	VR41XX_PCI_IO_MASK,
+	IO_PORT_RESOURCE_START
+};
+
+static struct vr41xx_pci_address_map pci_address_map = {
+	&vr41xx_pci_mem1,
+	&vr41xx_pci_mem2,
+	&vr41xx_pci_io
+};
+#endif
+
+void __init zao_capcella_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+	iomem_resource.start = IO_MEM1_RESOURCE_START;
+	iomem_resource.end = IO_MEM2_RESOURCE_END;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+
+	board_time_init = vr41xx_time_init;
+	board_timer_setup = vr41xx_timer_setup;
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &capcella_ide_ops;
+#endif
+
+	vr41xx_bcu_init();
+
+	vr41xx_cmu_init(0x0102);
+
+	vr41xx_siu_init(SIU_RS232C, 0);
+
+#ifdef CONFIG_PCI
+	vr41xx_pciu_init(&pci_address_map);
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/Makefile linux-2.4.20/arch/mips64/Makefile
--- linux-2.4.19/arch/mips64/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -25,7 +25,7 @@
 endif
 
 #
-# The ELF GCC uses -G0 -mabicalls -fpic as default.  We don't need PIC
+# The ELF GCC uses -G 0 -mabicalls -fpic as default.  We don't need PIC
 # code in the kernel since it only slows down the whole thing.  For the
 # old GCC these options are just the defaults.  At some point we might
 # make use of global pointer optimizations.
@@ -67,10 +67,10 @@
 ifdef CONFIG_CPU_SB1
 GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
-
-AFLAGS		+= $(GCCFLAGS)
-CFLAGS		+= $(GCCFLAGS)
-
+ifdef CONFIG_CPU_MIPS64
+#CFLAGS		+= -mips64	# Should be used then we get a MIPS64 compiler
+CFLAGS		+= -mcpu=r8000 -mips4
+endif
 
 #
 # We unconditionally build the math emulator
@@ -104,12 +104,22 @@
 endif
 
 #
+# MIPS SEAD board
+#
+ifdef CONFIG_MIPS_SEAD
+LIBS		+= arch/mips/mips-boards/sead/sead.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/sead
+LOADADDR	:= 0x80100000
+endif
+
+#
 # SGI IP22 (Indy/Indigo2)
 #
 ifdef CONFIG_SGI_IP22
 CORE_FILES	+= arch/mips/sgi-ip22/ip22-kern.o
-LIBS		+= arch/mips64/arc/arclib.a 
-SUBDIRS		+= arch/mips/sgi-ip22 arch/mips64/arc
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip22 arch/mips/arc
 #
 # Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
 # 0x88004000 for production kernels.  Note that the value must be
@@ -122,9 +132,9 @@
 # SGI-IP27 (Origin200/2000)
 #
 ifdef CONFIG_SGI_IP27
-CORE_FILES	+= arch/mips64/sgi-ip27/ip27.o
-LIBS		+= arch/mips64/arc/arclib.a
-SUBDIRS		+= arch/mips64/sgi-ip27 arch/mips64/arc
+CORE_FILES	+= arch/mips/sgi-ip27/ip27.o
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip27 arch/mips/arc
 #
 # Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
 # symmon, 0xc00000000001c000 for production kernels.  Note that the value
@@ -142,9 +152,9 @@
 # SGI-IP32 (O2)
 #
 ifdef CONFIG_SGI_IP32
-CORE_FILES	+= arch/mips64/sgi-ip32/ip32-kern.a
-LIBS		+= arch/mips64/arc/arclib.a
-SUBDIRS		+= arch/mips64/sgi-ip32 arch/mips64/arc
+CORE_FILES	+= arch/mips/sgi-ip32/ip32-kern.a
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip32 arch/mips/arc
 #
 # Set LOADADDR to >= 0x????????? if you want to leave space for symmon,
 # 0x80002000 for production kernels.  Note that the value must be
@@ -174,6 +184,14 @@
 endif
 
 #
+# Sibyte CFE firmware
+#
+ifdef CONFIG_SIBYTE_CFE
+LIBS		+= arch/mips/sibyte/cfe/cfe.a
+SUBDIRS		+= arch/mips/sibyte/cfe
+endif
+
+#
 # SB1 Cache Error handler
 #
 ifdef CONFIG_SB1_CACHE_ERROR
@@ -188,8 +206,7 @@
 # convert to ECOFF using elf2ecoff.
 #
 ifdef CONFIG_BOOT_ELF32
-CFLAGS += -Wa,-32
-AFLAGS += -Wa,-32
+GCCFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 endif
 #
@@ -197,19 +214,23 @@
 # ELF files from 32-bit files by conversion.
 #
 ifdef CONFIG_BOOT_ELF64
-CFLAGS += -Wa,-32
-AFLAGS += -Wa,-32
+GCCFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 #AS += -64
 #LD += -m elf64bmip
 #LINKFLAGS += -T arch/mips64/ld.script.elf64
 endif
 
+
+AFLAGS		+= $(GCCFLAGS)
+CFLAGS		+= $(GCCFLAGS)
+
+
 LINKFLAGS += -Ttext $(LOADADDR)
 
 HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
 
-SUBDIRS := $(addprefix arch/mips64/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
+SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
 CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES)
 LIBS := arch/mips64/lib/lib.a $(LIBS)
 
@@ -243,12 +264,12 @@
 
 archclean:
 	@$(MAKEBOOT) clean
-	$(MAKE) -C arch/$(ARCH)/tools clean
+	$(MAKE) -C arch/mips/tools clean
 	rm -f vmlinux.64 arch/$(ARCH)/ld.script.elf32
 
 archmrproper:
 	@$(MAKEBOOT) mrproper
-	$(MAKE) -C arch/$(ARCH)/tools mrproper
+	$(MAKE) -C arch/mips/tools mrproper
 
 archdep:
 	if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/Makefile linux-2.4.20/arch/mips64/arc/Makefile
--- linux-2.4.19/arch/mips64/arc/Makefile	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-#
-# Makefile for the ARC prom monitor library routines under Linux.
-#
-
-L_TARGET = arclib.a
-obj-y	:= console.o init.o identify.o tree.o env.o cmdline.o misc.o time.o \
-	   file.o
-
-obj-$(CONFIG_ARC_MEMORY) += memory.o
-obj-$(CONFIG_ARC_CONSOLE) += arc_con.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/arc_con.c linux-2.4.20/arch/mips64/arc/arc_con.c
--- linux-2.4.19/arch/mips64/arc/arc_con.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/arc_con.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,62 +0,0 @@
-/*
- * Wrap-around code for a console using the
- * ARC io-routines.
- *
- * Copyright (c) 1998 Harald Koerfgen 
- * Copyright (c) 2001 Ralf Baechle
- */
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/ptrace.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/fs.h>
-
-#include <asm/sgialib.h>
-
-extern void prom_printf (char *, ...);
-
-void prom_putchar(char c)
-{
-	ULONG cnt;
-	CHAR it = c;
-
-	ArcWrite(1, &it, 1, &cnt);
-}
-
-static void prom_console_write(struct console *co, const char *s,
-			       unsigned count)
-{
-	unsigned i;
-
-	/*
-	 *    Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		if (*s == 10)
-			prom_printf("%c", 13);
-		prom_printf("%c", *s++);
-	}
-}
-
-static kdev_t prom_console_device(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static struct console arc_cons = {
-    name:	"ttyS",
-    write:	prom_console_write,
-    device:	prom_console_device,
-    flags:	CON_PRINTBUFFER,
-    index:	-1,
-};
-
-/*
- *    Register console.
- */
-
-void __init arc_console_init(void)
-{
-	register_console(&arc_cons);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/cmdline.c linux-2.4.20/arch/mips64/arc/cmdline.c
--- linux-2.4.19/arch/mips64/arc/cmdline.c	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/cmdline.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,111 +0,0 @@
-/*
- * 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.
- *
- * cmdline.c: Kernel command line creation using ARCS argc/argv.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-/* #define DEBUG_CMDLINE */
-
-char arcs_cmdline[CL_SIZE];
-
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
-static char *ignored[] = {
-	"ConsoleIn=",
-	"ConsoleOut=",
-	"SystemPartition=",
-	"OSLoader=",
-	"OSLoadPartition=",
-	"OSLoadFilename=",
-	"OSLoadOptions="
-};
-#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
-
-static char *used_arc[][2] = {
-	{ "OSLoadPartition=", "root=" },
-	{ "OSLoadOptions=", "" }
-};
-
-static char * __init move_firmware_args(char* cp)
-{
-	char *s;
-	int actr, i;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	while (actr < prom_argc) {
-		for(i = 0; i < NENTS(used_arc); i++) {
-			int len = strlen(used_arc[i][0]);
-
-			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
-			/* Ok, we want it. First append the replacement... */
-				strcat(cp, used_arc[i][1]);
-				cp += strlen(used_arc[i][1]);
-				/* ... and now the argument */
-				s = strstr(prom_argv(actr), "=");
-				if (s) {
-					s++;
-					strcpy(cp, s);
-					cp += strlen(s);
-				}
-				*cp++ = ' ';
-				break;
-			}
-		}
-		actr++;
-	}
-
-	return cp;
-}
-
-
-void __init prom_init_cmdline(void)
-{
-	char *cp;
-	int actr, i;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	cp = &(arcs_cmdline[0]);
-	/* 
-	 * Move ARC variables to the beginning to make sure they can be
-	 * overridden by later arguments.
-	 */
-	cp = move_firmware_args(cp);
-
-	while (actr < prom_argc) {
-		for (i = 0; i < NENTS(ignored); i++) {
-			int len = strlen(ignored[i]);
-
-			if (!strncmp(prom_argv(actr), ignored[i], len))
-				goto pic_cont;
-		}
-		/* Ok, we want it. */
-		strcpy(cp, prom_argv(actr));
-		cp += strlen(prom_argv(actr));
-		*cp++ = ' ';
-
-	pic_cont:
-		actr++;
-	}
-	if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
-		--cp;
-	*cp = '\0';
-
-#ifdef DEBUG_CMDLINE
-	prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/console.c linux-2.4.20/arch/mips64/arc/console.c
--- linux-2.4.19/arch/mips64/arc/console.c	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/console.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-/*
- * 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) 1996 David S. Miller (dm@sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/sgialib.h>
-
-static char ppbuf[1024];
-
-void prom_printf(char *fmt, ...)
-{
-	va_list args;
-	char ch, *bptr;
-	int i;
-
-	va_start(args, fmt);
-	i = vsprintf(ppbuf, fmt, args);
-
-	bptr = ppbuf;
-
-	while((ch = *(bptr++)) != 0) {
-		if(ch == '\n')
-			prom_putchar('\r');
-
-		prom_putchar(ch);
-	}
-	va_end(args);
-	return;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/env.c linux-2.4.20/arch/mips64/arc/env.c
--- linux-2.4.19/arch/mips64/arc/env.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/env.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,27 +0,0 @@
-/*
- * 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.
- *
- * env.c: ARCS environment variable routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/arc/types.h>
-#include <asm/sgialib.h>
-
-PCHAR __init
-ArcGetEnvironmentVariable(CHAR *name)
-{
-	return (CHAR *) ARC_CALL1(get_evar, name);
-}
-
-LONG __init
-ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
-{
-	return ARC_CALL2(set_evar, name, value);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/file.c linux-2.4.20/arch/mips64/arc/file.c
--- linux-2.4.19/arch/mips64/arc/file.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/file.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,75 +0,0 @@
-/*
- * 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.
- *
- * ARC firmware interface.
- *
- * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-
-#include <asm/arc/types.h>
-#include <asm/sgialib.h>
-
-LONG __init
-ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
-                     ULONG N, ULONG *Count)
-{
-	return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
-{
-	return ARC_CALL3(open, Path, OpenMode, FileID);
-}
-
-LONG __init
-ArcClose(ULONG FileID)
-{
-	return ARC_CALL1(close, FileID);
-}
-
-LONG __init
-ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
-{
-	return ARC_CALL4(read, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcGetReadStatus(ULONG FileID)
-{
-	return ARC_CALL1(get_rstatus, FileID);
-}
-
-LONG __init
-ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
-{
-	return ARC_CALL4(write, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
-{
-	return ARC_CALL3(seek, FileID, Position, SeekMode);
-}
-
-LONG __init
-ArcMount(char *name, enum linux_mountops op)
-{
-	return ARC_CALL2(mount, name, op);
-}
-
-LONG __init
-ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
-{
-	return ARC_CALL2(get_finfo, FileID, Information);
-}
-
-LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
-                                  ULONG AttributeMask)
-{
-	return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/identify.c linux-2.4.20/arch/mips64/arc/identify.c
--- linux-2.4.19/arch/mips64/arc/identify.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/identify.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,117 +0,0 @@
-/*
- * 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.
- *
- * identify.c: identify machine by looking up system identifier
- *
- * Copyright (C) 1998 Thomas Bogendoerfer
- * 
- * This code is based on arch/mips/sgi/kernel/system.c, which is
- * 
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-struct smatch {
-	char *arcname;
-	char *liname;
-	int group;
-	int type;
-	int flags;
-};
-
-static struct smatch mach_table[] = {
-	{	"SGI-IP22",
-		"SGI Indy",
-		MACH_GROUP_SGI,
-		MACH_SGI_INDY,
-		PROM_FLAG_ARCS
-	}, {	"SGI-IP27",
-		"SGI Origin",
-		MACH_GROUP_SGI,
-		MACH_SGI_IP27,
-		PROM_FLAG_ARCS
-	}, {	"SGI-IP28",
-		"SGI IP28",
-		MACH_GROUP_SGI,
-		MACH_SGI_IP28,
-		PROM_FLAG_ARCS
-	}, {	"SGI-IP32",
-		"SGI IP32",
-		MACH_GROUP_SGI,
-		MACH_SGI_IP32,
-		PROM_FLAG_ARCS
-	}, {	"Microsoft-Jazz",
-		"Jazz MIPS_Magnum_4000",
-		MACH_GROUP_JAZZ,
-		MACH_MIPS_MAGNUM_4000,
-		0
-	}, {	"PICA-61",
-		"Jazz Acer_PICA_61",
-		MACH_GROUP_JAZZ,
-		MACH_ACER_PICA_61,
-		0
-	}, {	"RM200PCI",
-		"SNI RM200_PCI",
-		MACH_GROUP_SNI_RM,
-		MACH_SNI_RM200_PCI,
-		0
-	}
-};
-
-int prom_flags;
-
-static struct smatch * __init string_to_mach(const char *s)
-{
-	int i;
-    
-	for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) {
-		if(!strcmp(s, mach_table[i].arcname))
-			return &mach_table[i];
-	}
-	panic("Yeee, could not determine architecture type <%s>", s);
-
-	return NULL;
-}
-
-char *system_type;
-
-const char *get_system_type(void)
-{
-	return system_type;
-}
-
-void __init prom_identify_arch(void)
-{
-	pcomponent *p;
-	struct smatch *mach;
-	const char *iname;
-
-	/* The root component tells us what machine architecture we
-	   have here.  */
-	p = ArcGetChild(PROM_NULL_COMPONENT);
-	if (p == NULL) {
-#ifdef CONFIG_SGI_IP27
-		/* IP27 PROM bisbehaves, seems to not implement ARC
-		   GetChild().  So we just assume it's an IP27.  */
-		iname = "SGI-IP27";
-#endif
-	} else
-		iname = (char *) (long) p->iname;
-
-	printk(KERN_INFO "ARCH: %s\n", iname);
-	mach = string_to_mach(iname);
-	system_type = mach->liname;
-
-	mips_machgroup = mach->group;
-	mips_machtype = mach->type;
-	prom_flags = mach->flags;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/init.c linux-2.4.20/arch/mips64/arc/init.c
--- linux-2.4.19/arch/mips64/arc/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,49 +0,0 @@
-/*
- * 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.
- *
- * PROM library initialisation code.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/sgialib.h>
-
-#undef DEBUG_PROM_INIT
-
-/* Master romvec interface. */
-struct linux_romvec *romvec;
-int prom_argc;
-LONG *_prom_argv, *_prom_envp;
-
-int __init prom_init(int argc, char **argv, char **envp)
-{
-	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
-	romvec = ROMVECTOR;
-	prom_argc = argc;
-	_prom_argv = (LONG *) argv;
-	_prom_envp = (LONG *) envp;
-
-	if(pb->magic != 0x53435241) {
-		prom_printf("Aieee, bad prom vector magic %08lx\n",
-			    pb->magic);
-		while(1)
-			;
-	}
-
-	prom_init_cmdline();
-	prom_identify_arch();
-	printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
-	       pb->ver, pb->rev);
-	prom_meminit();
-
-#ifdef DEBUG_PROM_INIT
-	prom_printf("Press a key to reboot\n");
-	prom_getchar();
-	ArcEnterInteractiveMode();
-#endif
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/memory.c linux-2.4.20/arch/mips64/arc/memory.c
--- linux-2.4.19/arch/mips64/arc/memory.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/memory.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,159 +0,0 @@
-/*
- * memory.c: PROM library functions for acquiring/using memory descriptors
- *           given to us from the ARCS firmware.
- *
- * Copyright (C) 1996 by David S. Miller
- * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
- *
- * PROM library functions for acquiring/using memory descriptors given to us
- * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
- * because on some machines like SGI IP27 the ARC memory configuration data
- * completly bogus and alternate easier to use mechanisms are available.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/swap.h>
-
-#include <asm/sgialib.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/bootinfo.h>
-
-#undef DEBUG
-
-struct linux_mdesc* __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
-{
-	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
-}
-
-#ifdef DEBUG /* convenient for debugging */
-static char *arcs_mtypes[8] = {
-	"Exception Block",
-	"ARCS Romvec Page",
-	"Free/Contig RAM",
-	"Generic Free RAM",
-	"Bad Memory",
-	"Standalone Program Pages",
-	"ARCS Temp Storage Area",
-	"ARCS Permanent Storage Area"
-};
-
-static char *arc_mtypes[8] = {
-	"Exception Block",
-	"SystemParameterBlock",
-	"FreeMemory",
-	"Bad Memory",
-	"LoadedProgram",
-	"FirmwareTemporary",
-	"FirmwarePermanent",
-	"FreeContiguous"
-};
-#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
-						: arc_mtypes[a.arc]
-#endif
-
-static inline int memtype_classify_arcs (union linux_memtypes type)
-{
-	switch (type.arcs) {
-	case arcs_fcontig:
-	case arcs_free:
-		return BOOT_MEM_RAM;
-	case arcs_atmp:
-		return BOOT_MEM_ROM_DATA;
-	case arcs_eblock:
-	case arcs_rvpage:
-	case arcs_bmem:
-	case arcs_prog:
-	case arcs_aperm:
-		return BOOT_MEM_RESERVED;
-	default:
-		BUG();
-	}
-	while(1);				/* Nuke warning.  */
-}
-
-static inline int memtype_classify_arc (union linux_memtypes type)
-{
-	switch (type.arc) {
-	case arc_free:
-	case arc_fcontig:
-		return BOOT_MEM_RAM;
-	case arc_atmp:
-		return BOOT_MEM_ROM_DATA;
-	case arc_eblock:
-	case arc_rvpage:
-	case arc_bmem:
-	case arc_prog:
-	case arc_aperm:
-		return BOOT_MEM_RESERVED;
-	default:
-		BUG();
-	}
-	while(1);				/* Nuke warning.  */
-}
-
-static int __init prom_memtype_classify (union linux_memtypes type)
-{
-	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
-		return memtype_classify_arcs(type);
-
-	return memtype_classify_arc(type);
-}
-
-void __init prom_meminit(void)
-{
-	struct linux_mdesc *p;
-
-#ifdef DEBUG
-	int i = 0;
-
-	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
-	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
-	while(p) {
-		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
-			    i, p, p->base, p->pages, mtypes(p->type));
-		p = ArcGetMemoryDescriptor(p);
-		i++;
-	}
-#endif
-
-	p = PROM_NULL_MDESC;
-	while ((p = ArcGetMemoryDescriptor(p))) {
-		unsigned long base, size;
-		long type;
-
-		base = p->base << PAGE_SHIFT;
-		size = p->pages << PAGE_SHIFT;
-		type = prom_memtype_classify(p->type);
-
-		add_memory_region(base, size, type);
-	}
-}
-
-void __init prom_free_prom_memory (void)
-{
-	unsigned long freed = 0;
-	unsigned long addr;
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
-		while (addr < boot_mem_map.map[i].addr
-			      + boot_mem_map.map[i].size) {
-			ClearPageReserved(virt_to_page(__va(addr)));
-			set_page_count(virt_to_page(__va(addr)), 1);
-			free_page((unsigned long)__va(addr));
-			addr += PAGE_SIZE;
-			freed += PAGE_SIZE;
-		}
-	}
-	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/misc.c linux-2.4.20/arch/mips64/arc/misc.c
--- linux-2.4.19/arch/mips64/arc/misc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/misc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,103 +0,0 @@
-/*
- * 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.
- *
- * Miscellaneous ARCS PROM routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/bcache.h>
-
-#include <asm/arc/types.h>
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-#include <asm/system.h>
-
-extern void *sgiwd93_host;
-extern void reset_wd33c93(void *instance);
-
-VOID
-ArcHalt(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(halt);
-never:	goto never;
-}
-
-VOID
-ArcPowerDown(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(pdown);
-never:	goto never;
-}
-
-/* XXX is this a soft reset basically? XXX */
-VOID
-ArcRestart(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(restart);
-never:	goto never;
-}
-
-VOID
-ArcReboot(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(reboot);
-never:	goto never;
-}
-
-VOID
-ArcEnterInteractiveMode(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(imode);
-never:	goto never;
-}
-
-LONG
-ArcSaveConfiguration(VOID)
-{
-	return ARC_CALL0(cfg_save);
-}
-
-struct linux_sysid *
-ArcGetSystemId(VOID)
-{
-	return (struct linux_sysid *) ARC_CALL0(get_sysid);
-}
-
-VOID __init
-ArcFlushAllCaches(VOID)
-{
-	ARC_CALL0(cache_flush);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/salone.c linux-2.4.20/arch/mips64/arc/salone.c
--- linux-2.4.19/arch/mips64/arc/salone.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/salone.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,27 +0,0 @@
-/*
- * Routines to load into memory and execute stand-along program images using
- * ARCS PROM firmware.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <asm/sgialib.h>
-
-LONG __init
-ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
-{
-	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
-}
-
-LONG __init
-ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
-          CHAR *Envp[])
-{
-	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
-}
-
-LONG __init
-ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
-{
-	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/time.c linux-2.4.20/arch/mips64/arc/time.c
--- linux-2.4.19/arch/mips64/arc/time.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-/*
- * 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.
- *
- * Extracting time information from ARCS prom.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-
-#include <asm/arc/types.h>
-#include <asm/sgialib.h>
-
-struct linux_tinfo * __init
-ArcGetTime(VOID)
-{
-	return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
-}
-
-ULONG __init
-ArcGetRelativeTime(VOID)
-{
-	return ARC_CALL0(get_rtime);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/arc/tree.c linux-2.4.20/arch/mips64/arc/tree.c
--- linux-2.4.19/arch/mips64/arc/tree.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/arc/tree.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,129 +0,0 @@
-/*
- * 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.
- *
- * PROM component device tree code.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-
-#include <asm/arc/types.h>
-#include <asm/sgialib.h>
-#include <asm/sgiarcs.h>
-
-#undef DEBUG_PROM_TREE
-
-pcomponent * __init
-ArcGetPeer(pcomponent *Current)
-{
-	if (Current == PROM_NULL_COMPONENT)
-		return PROM_NULL_COMPONENT;
-
-	return (pcomponent *) ARC_CALL1(next_component, Current);
-}
-
-pcomponent * __init
-ArcGetChild(pcomponent *Current)
-{
-	return (pcomponent *) ARC_CALL1(child_component, Current);
-}
-
-pcomponent * __init
-ArcGetParent(pcomponent *Current)
-{
-	if (Current == PROM_NULL_COMPONENT)
-		return PROM_NULL_COMPONENT;
-
-	return (pcomponent *) ARC_CALL1(parent_component, Current);
-}
-
-LONG __init
-ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
-{
-	return ARC_CALL2(component_data, Buffer, Current);
-}
-
-pcomponent * __init
-ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
-{
-	return (pcomponent *)
-	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
-}
-
-LONG __init
-ArcDeleteComponent(pcomponent *ComponentToDelete)
-{
-	return ARC_CALL1(comp_del, ComponentToDelete);
-}
-
-pcomponent * __init
-ArcGetComponent(CHAR *Path)
-{
-	return (pcomponent *)ARC_CALL1(component_by_path, Path);
-}
-
-#ifdef DEBUG_PROM_TREE
-
-static char *classes[] = {
-	"system", "processor", "cache", "adapter", "controller", "peripheral",
-	"memory"
-};
-
-static char *types[] = {
-	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
-	"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
-	"dti adapter", "multi-func adapter", "disk controller",
-	"tp controller", "cdrom controller", "worm controller",
-	"serial controller", "net controller", "display controller",
-	"parallel controller", "pointer controller", "keyboard controller",
-	"audio controller", "misc controller", "disk peripheral",
-	"floppy peripheral", "tp peripheral", "modem peripheral",
-	"monitor peripheral", "printer peripheral", "pointer peripheral",
-	"keyboard peripheral", "terminal peripheral", "line peripheral",
-	"net peripheral", "misc peripheral", "anonymous"
-};
-
-static char *iflags[] = {
-	"bogus", "read only", "removable", "console in", "console out",
-	"input", "output"
-};
-
-static void __init
-dump_component(pcomponent *p)
-{
-	prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
-		    p, classes[p->class], types[p->type],
-		    iflags[p->iflags], p->vers, p->rev);
-	prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
-		    p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
-}
-
-static void __init
-traverse(pcomponent *p, int op)
-{
-	dump_component(p);
-	if(ArcGetChild(p))
-		traverse(ArcGetChild(p), 1);
-	if(ArcGetPeer(p) && op)
-		traverse(ArcGetPeer(p), 1);
-}
-
-void __init
-prom_testtree(void)
-{
-	pcomponent *p;
-
-	p = ArcGetChild(PROM_NULL_COMPONENT);
-	dump_component(p);
-	p = ArcGetChild(p);
-	while(p) {
-		dump_component(p);
-		p = ArcGetPeer(p);
-	}
-}
-
-#endif /* DEBUG_PROM_TREE  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/config.in linux-2.4.20/arch/mips64/config.in
--- linux-2.4.19/arch/mips64/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/config.in	2002-10-04 00:41:11.000000000 +0000
@@ -3,336 +3,7 @@
 # see Documentation/kbuild/config-language.txt.
 #
 define_bool CONFIG_MIPS y
+define_bool CONFIG_MIPS32 n
 define_bool CONFIG_MIPS64 y
 
-mainmenu_name "Linux/MIPS64 Kernel Configuration"
-
-mainmenu_option next_comment
-comment 'Code maturity level options'
-bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
-endmenu
-
-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 module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'Machine selection'
-dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL
-dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL
-dep_bool 'Support for SGI-IP22 (Indy/Indigo2) (EXPERIMENTAL)' CONFIG_SGI_IP22 $CONFIG_EXPERIMENTAL
-bool 'Support for SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27
-if [ "$CONFIG_SGI_IP27" = "y" ]; then
-   bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
-   bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
-   bool '  NUMA support' CONFIG_NUMA
-   bool '  Mapped kernel support' CONFIG_MAPPED_KERNEL
-   bool '  Kernel text replication support' CONFIG_REPLICATE_KTEXT
-   bool '  Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS
-   bool '  Multi-Processing support' CONFIG_SMP
-   #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
-fi
-dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL
-bool 'Support for SiByte SB1250 SOC' CONFIG_SIBYTE_SB1250
-if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
-   bool '  Support for SB1250 onchip PCI controller' CONFIG_PCI
-   bool '  Support for SB1250 profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
-   bool '  Support for BCM1250 profiling using trace buffer' CONFIG_BCM1250_TBPROF
-   bool '  Remote debugging (kgdb over UART 1)' CONFIG_REMOTE_DEBUG
-   bool '  Support for SiByte SWARM board' CONFIG_SIBYTE_SWARM
-   if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
-      bool '    Running under simulation' CONFIG_SIMULATION
-      bool '    Configure for L3proc Demo' CONFIG_L3DEMO
-      int '    Maximum memory chunks' CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS 16
-      bool '    Multi-Processing support' CONFIG_SMP
-   fi
-fi
-
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
-
-#
-# Select some configuration options automatically based on user selections.
-#
-
-if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
-   define_bool CONFIG_BOOT_ELF32 y
-   define_int CONFIG_L1_CACHE_SHIFT 5
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
-if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
-   define_bool CONFIG_BOOT_ELF32 y
-   define_bool CONFIG_I8259 y
-   define_int CONFIG_L1_CACHE_SHIFT 5
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_SWAP_IO_SPACE y
-fi
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_ARC_CONSOLE y
-   define_bool CONFIG_ARC_MEMORY y
-   define_bool CONFIG_BOARD_SCACHE y
-   define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_BOOT_ELF32 y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_SGI y
-   define_int CONFIG_L1_CACHE_SHIFT 5
-fi
-if [ "$CONFIG_SGI_IP27" = "y" ]; then
-   define_bool CONFIG_BOOT_ELF64 y
-   define_bool CONFIG_ARC64 y
-   define_bool CONFIG_MAPPED_PCI_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_QL_ISP_A64 y
-   define_int CONFIG_L1_CACHE_SHIFT 7
-fi
-if [ "$CONFIG_SGI_IP32" = "y" ]; then
-   define_bool CONFIG_BOOT_ELF32 y
-   define_bool CONFIG_ARC32 y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
-   #define_bool CONFIG_BOARD_SCACHE y
-   define_bool CONFIG_MAPPED_PCI_IO n
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_ARC_MEMORY y
-   define_int CONFIG_L1_CACHE_SHIFT 5
-fi
-if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
-   define_bool CONFIG_BOOT_ELF32 y
-   define_bool CONFIG_SWAP_IO_SPACE y
-   define_bool CONFIG_CFE y
-   define_bool CONFIG_SIBYTE_SB1250 y
-   define_int CONFIG_L1_CACHE_SHIFT 5
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'CPU selection'
-
-choice 'CPU type' \
-	"R4300	CONFIG_CPU_R4300 \
-	 R4x00	CONFIG_CPU_R4X00 \
-	 R5000	CONFIG_CPU_R5000 \
-	 R52x0	CONFIG_CPU_NEVADA \
-	 R8000	CONFIG_CPU_R8000 \
-	 R10000	CONFIG_CPU_R10000 \
-	 SB1	CONFIG_CPU_SB1" R4x00
-endmenu
-
-if [ "$CONFIG_CPU_SB1" = "y" ]; then
-   bool '  Workarounds for pass 1 sb1 bugs' CONFIG_SB1_PASS_1_WORKAROUNDS
-   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
-   define_bool CONFIG_VTAG_ICACHE y
-fi
-
-define_bool CONFIG_CPU_HAS_LLSC y
-define_bool CONFIG_CPU_HAS_LLDSCD y
-
-mainmenu_option next_comment
-comment 'General setup'
-
-if [ "$CONFIG_CPU_R10000" = "y" ]; then
-   bool 'Support for large 64-bit configurations' CONFIG_MIPS_INSANE_LARGE
-fi
-bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
-
-if [ "$CONFIG_ARC32" = "y" ]; then
-   bool 'ARC console support' CONFIG_ARC_CONSOLE
-fi
-
-bool 'Networking support' CONFIG_NET
-
-if [ "$CONFIG_PCI" != "y" ]; then
-   define_bool CONFIG_PCI n
-fi
-
-source drivers/pci/Config.in
-
-if [ "$CONFIG_ISA" != "y" ]; then
-   define_bool CONFIG_ISA n
-   define_bool CONFIG_EISA n
-else
-   define_bool CONFIG_EISA y
-fi
-
-define_bool CONFIG_MCA n
-define_bool CONFIG_SBUS n
-
-bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
-
-if [ "$CONFIG_HOTPLUG" = "y" ] ; then
-   source drivers/pcmcia/Config.in
-   source drivers/hotplug/Config.in
-else
-   define_bool CONFIG_PCMCIA n
-   define_bool CONFIG_HOTPLUG_PCI n
-fi
-
-bool 'System V IPC' CONFIG_SYSVIPC
-bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
-bool 'Sysctl support' CONFIG_SYSCTL
-define_bool CONFIG_KCORE_ELF y
-define_bool CONFIG_KCORE_AOUT n
-tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
-bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
-define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-endmenu
-
-source drivers/mtd/Config.in
-
-source drivers/parport/Config.in
-
-source drivers/pnp/Config.in
-
-source drivers/block/Config.in
-
-source drivers/md/Config.in
-
-if [ "$CONFIG_NET" = "y" ]; then
-   source net/Config.in
-fi
-
-source drivers/telephony/Config.in
-
-if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
-
-   mainmenu_option next_comment
-   comment 'ATA/IDE/MFM/RLL support'
-
-   tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
-
-   if [ "$CONFIG_IDE" != "n" ]; then
-      source drivers/ide/Config.in
-   else
-      define_bool CONFIG_BLK_DEV_IDE_MODES n
-      define_bool CONFIG_BLK_DEV_HD n
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'SCSI support'
-
-tristate 'SCSI support' CONFIG_SCSI
-
-if [ "$CONFIG_SCSI" != "n" ]; then
-   source drivers/scsi/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_PCI" = "y" ]; then
-   source drivers/message/i2o/Config.in
-fi
-
-if [ "$CONFIG_NET" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Network device support'
-
-   bool 'Network device support' CONFIG_NETDEVICES
-   if [ "$CONFIG_NETDEVICES" = "y" ]; then
-      source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
-	 source drivers/atm/Config.in
-      fi
-   fi
-   endmenu
-fi
-
-source net/ax25/Config.in
-
-source net/irda/Config.in
-
-if [ "$CONFIG_NET" != "n" ]; then
-   mainmenu_option next_comment
-   comment 'ISDN subsystem'
-
-   tristate 'ISDN support' CONFIG_ISDN
-   if [ "$CONFIG_ISDN" != "n" ]; then
-      source drivers/isdn/Config.in
-   fi
-   endmenu
-fi
-
-if [ "$CONFIG_ISA" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-
-   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
-   endmenu
-fi
-
-source drivers/char/Config.in
-
-#source drivers/misc/Config.in
-
-source drivers/media/Config.in
-
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'SGI Character devices'
-   if [ "$CONFIG_VT" = "y" ]; then
-      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
-      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
-         define_bool CONFIG_FONT_8x16 y
-      fi
-      define_bool CONFIG_DUMMY_CONSOLE y
-   fi
-   endmenu
-fi
-
-source fs/Config.in
-
-if [ "$CONFIG_VT" = "y" ]; then
-   mainmenu_option next_comment
-   comment 'Console drivers'
-   bool 'VGA text console' CONFIG_VGA_CONSOLE
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
-      source drivers/video/Config.in
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'Sound'
-
-tristate 'Sound card support' CONFIG_SOUND
-if [ "$CONFIG_SOUND" != "n" ]; then
-   source drivers/sound/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   source drivers/sgi/Config.in
-fi
-
-source drivers/usb/Config.in
-
-source net/bluetooth/Config.in
-
-source drivers/input/Config.in
-
-mainmenu_option next_comment
-comment 'Kernel hacking'
-
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
-bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-if [ "$CONFIG_SMP" != "y" ]; then
-   bool 'Run uncached' CONFIG_MIPS_UNCACHED
-fi
-endmenu
+source arch/mips/config-shared.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig linux-2.4.20/arch/mips64/defconfig
--- linux-2.4.19/arch/mips64/defconfig	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig	2002-10-04 00:41:13.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,8 +18,32 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -29,38 +54,58 @@
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
-# CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_MIPS_INSANE_LARGE is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -71,10 +116,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -107,6 +154,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -298,6 +346,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -341,6 +390,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -394,11 +452,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -411,6 +464,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -428,6 +483,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -458,6 +516,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -472,7 +531,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -492,10 +550,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -511,17 +575,16 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-atlas linux-2.4.20/arch/mips64/defconfig-atlas
--- linux-2.4.19/arch/mips64/defconfig-atlas	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-atlas	2002-10-04 00:41:11.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,41 +18,89 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 CONFIG_MIPS_ATLAS=y
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
 CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -59,13 +108,15 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -99,6 +150,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -115,8 +167,9 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -302,6 +355,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -348,6 +402,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -401,11 +464,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -418,6 +476,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -435,6 +495,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -465,6 +528,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -478,7 +542,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -489,6 +552,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -504,18 +572,17 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-ip22 linux-2.4.20/arch/mips64/defconfig-ip22
--- linux-2.4.19/arch/mips64/defconfig-ip22	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-ip22	2002-10-04 00:41:10.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -19,47 +20,98 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 CONFIG_SGI_IP22=y
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
 CONFIG_ARC_CONSOLE=y
 CONFIG_ARC_MEMORY=y
 CONFIG_BOARD_SCACHE=y
-CONFIG_IRQ_CPU=y
-CONFIG_PC_KEYB=y
 CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_IRQ_CPU=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
 CONFIG_SGI=y
-CONFIG_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -70,10 +122,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -106,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -185,6 +240,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -287,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -333,6 +396,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -381,7 +453,6 @@
 # CONFIG_EUROTECH_WDT is not set
 # CONFIG_IB700_WDT is not set
 # CONFIG_WAFER_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_I810_TCO is not set
 # CONFIG_MIXCOMWD is not set
 # CONFIG_60XX_WDT is not set
@@ -392,6 +463,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -406,11 +478,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -430,6 +497,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -447,6 +516,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -477,6 +549,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -490,7 +563,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -510,10 +582,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -548,18 +626,15 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-ip27 linux-2.4.20/arch/mips64/defconfig-ip27
--- linux-2.4.19/arch/mips64/defconfig-ip27	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-ip27	2002-10-04 00:41:20.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,8 +18,32 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -29,38 +54,58 @@
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
-# CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_MIPS_INSANE_LARGE is not set
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -71,10 +116,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -107,6 +154,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -298,6 +346,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -341,6 +390,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -394,11 +452,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -411,6 +464,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -428,6 +483,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -458,6 +516,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -472,7 +531,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -492,10 +550,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -511,17 +575,16 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-ip32 linux-2.4.20/arch/mips64/defconfig-ip32
--- linux-2.4.19/arch/mips64/defconfig-ip32	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-ip32	2002-10-04 00:41:30.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,45 +18,90 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 CONFIG_SGI_IP32=y
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_BOOT_ELF32=y
+CONFIG_ARC_MEMORY=y
 CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_PCI=y
-# CONFIG_MAPPED_PCI_IO is not set
-CONFIG_NONCOHERENT_IO=y
-CONFIG_ARC_MEMORY=y
-CONFIG_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -66,10 +112,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 CONFIG_BINFMT_MISC=y
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -102,6 +150,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -312,6 +361,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -358,6 +408,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -415,11 +474,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -432,6 +486,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -449,6 +505,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -479,6 +538,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -493,7 +553,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -509,10 +568,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -528,18 +593,17 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_MIPS_UNCACHED=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-malta linux-2.4.20/arch/mips64/defconfig-malta
--- linux-2.4.19/arch/mips64/defconfig-malta	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-malta	2002-10-04 00:41:17.000000000 +0000
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,33 +18,79 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 CONFIG_MIPS_MALTA=y
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 CONFIG_I8259=y
 CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_PC_KEYB=y
+CONFIG_PCI=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -53,6 +100,7 @@
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -60,13 +108,15 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -100,6 +150,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -303,6 +354,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -349,6 +401,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -402,11 +463,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -419,6 +475,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -436,6 +494,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -466,6 +527,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -479,7 +541,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -490,6 +551,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -505,18 +571,17 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
 # CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-sb1250-swarm linux-2.4.20/arch/mips64/defconfig-sb1250-swarm
--- linux-2.4.19/arch/mips64/defconfig-sb1250-swarm	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-sb1250-swarm	2002-10-04 00:41:12.000000000 +0000
@@ -2,82 +2,138 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
 
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
 CONFIG_SIBYTE_SB1250=y
-# CONFIG_PCI is not set
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_BCM1250_TBPROF is not set
-# CONFIG_REMOTE_DEBUG is not set
-CONFIG_SIBYTE_SWARM=y
-# CONFIG_SIMULATION is not set
-# CONFIG_L3DEMO is not set
-CONFIG_SIBYTE_SWARM_MAX_MEM_REGIONS=16
 CONFIG_SMP=y
+# CONFIG_PCI is not set
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_BOOT_ELF32=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
-CONFIG_CFE=y
-CONFIG_SIBYTE_SB1250=y
-CONFIG_L1_CACHE_SHIFT=5
+CONFIG_BOOT_ELF32=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 # CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_SB1=y
+CONFIG_CPU_SB1_PASS_1=y
+# CONFIG_CPU_SB1_PASS_2 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_SB1_CACHE_ERROR=y
+CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y
+# CONFIG_SB1_CERR_SPIN is not set
 CONFIG_VTAG_ICACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
+# CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 # CONFIG_HOTPLUG_PCI is not set
-# CONFIG_SYSVIPC is not set
+CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
-CONFIG_MIPS32_COMPAT=y
-CONFIG_BINFMT_ELF32=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -110,6 +166,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -134,14 +191,15 @@
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 
 #
@@ -156,6 +214,14 @@
 # CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
@@ -175,6 +241,13 @@
 # CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
 # SCSI support
 #
 # CONFIG_SCSI is not set
@@ -192,13 +265,13 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_SB1250_MAC=y
-CONFIG_NET_SB1250_MAC=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
@@ -216,6 +289,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -223,6 +297,7 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -237,6 +312,8 @@
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
 
 #
 # Wan interfaces
@@ -259,6 +336,15 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -273,7 +359,9 @@
 # CONFIG_ESPSERIAL is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -282,14 +370,14 @@
 # CONFIG_STALDRV is not set
 # CONFIG_SERIAL_TX3912 is not set
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
-# CONFIG_AU1000_UART is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_SIBYTE_SB1250_DUART=y
 CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024
 # CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -334,11 +422,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -351,9 +434,11 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
@@ -363,11 +448,14 @@
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -377,11 +465,11 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
@@ -395,9 +483,10 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
+# CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -412,30 +501,21 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
+# CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -451,17 +531,14 @@
 # CONFIG_BLUEZ is not set
 
 #
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
 # Kernel hacking
 #
 CONFIG_CROSSCOMPILE=y
-# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/defconfig-sead linux-2.4.20/arch/mips64/defconfig-sead
--- linux-2.4.19/arch/mips64/defconfig-sead	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/defconfig-sead	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,361 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
+CONFIG_MIPS64=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+CONFIG_MIPS_SEAD=y
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_PCI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_NET is not set
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# MIPS initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/Makefile linux-2.4.20/arch/mips64/kernel/Makefile
--- linux-2.4.19/arch/mips64/kernel/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/Makefile	2002-10-04 00:41:16.000000000 +0000
@@ -12,11 +12,12 @@
 
 O_TARGET := kernel.o
 
-export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o
+export-objs	= irq.o mips64_ksyms.o pci-dma.o setup.o smp.o
 
-obj-y	:= branch.o entry.o irq.o proc.o process.o ptrace.o r4k_cache.o \
-	   r4k_fpu.o r4k_genex.o r4k_switch.o reset.o scall_64.o semaphore.o \
-	   setup.o signal.o syscall.o time.o traps.o unaligned.o
+obj-y		:= branch.o cpu-probe.o entry.o irq.o proc.o process.o \
+		   ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \
+		   reset.o scall_64.o semaphore.o setup.o signal.o syscall.o \
+		   time.o traps.o unaligned.o
 
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
@@ -30,6 +31,6 @@
 obj-y				+= pci-dma.o
 endif
 
-CFLAGS_r4k_genex.o := -P
+AFLAGS_r4k_genex.o := -P
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/binfmt_elf32.c linux-2.4.20/arch/mips64/kernel/binfmt_elf32.c
--- linux-2.4.19/arch/mips64/kernel/binfmt_elf32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/binfmt_elf32.c	2002-10-04 00:41:14.000000000 +0000
@@ -27,8 +27,26 @@
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
-#define elf_check_arch(x)	\
-	((x)->e_machine == EM_MIPS)
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr)						\
+({									\
+	int __res = 1;							\
+	struct elfhdr *__h = (hdr);					\
+									\
+	if (__h->e_machine != EM_MIPS)					\
+		__res = 0;						\
+	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
+		__res = 0;						\
+	if ((__h->e_flags & EF_MIPS_ABI2) != 0)				\
+		__res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ABI) != 0) &&			\
+	    ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))		\
+		__res = 0;						\
+									\
+	__res;								\
+})
 
 #define TASK32_SIZE		0x80000000UL
 #undef ELF_ET_DYN_BASE
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/cpu-probe.c linux-2.4.20/arch/mips64/kernel/cpu-probe.c
--- linux-2.4.19/arch/mips64/kernel/cpu-probe.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/cpu-probe.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,489 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void) = NULL;
+
+static void r3081_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
+static void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+void au1k_wait(void)
+{
+#ifdef CONFIG_PM
+	/* using the wait instruction makes CP0 counter unusable */
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
+#else
+	__asm__("nop\n\t" "nop\n\t");
+#endif
+}
+
+static inline void check_wait(void)
+{
+	printk("Checking for 'wait' instruction... ");
+	switch(mips_cpu.cputype) {
+	case CPU_R3081:
+	case CPU_R3081E:
+		cpu_wait = r3081_wait;
+		printk(" available.\n");
+		break;
+	case CPU_TX3927:
+	case CPU_TX39XX:
+		cpu_wait = r39xx_wait;
+		printk(" available.\n");
+		break;
+	case CPU_R4200:
+/*	case CPU_R4300: */
+	case CPU_R4600:
+	case CPU_R4640:
+	case CPU_R4650:
+	case CPU_R4700:
+	case CPU_R5000:
+	case CPU_NEVADA:
+	case CPU_RM7000:
+	case CPU_TX49XX:
+	case CPU_4KC:
+	case CPU_4KEC:
+	case CPU_4KSC:
+	case CPU_5KC:
+/*	case CPU_20KC:*/
+		cpu_wait = r4k_wait;
+		printk(" available.\n");
+		break;
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+		cpu_wait = au1k_wait;
+		printk(" available.\n");
+		break;
+	default:
+		printk(" unavailable.\n");
+		break;
+	}
+}
+
+void __init check_bugs(void)
+{
+	check_wait();
+}
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+	extern unsigned long r3k_cache_size(unsigned long);
+	unsigned long size1, size2;
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+
+	size1 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
+	size2 = r3k_cache_size(ST0_ISC);
+	write_32bit_cp0_register(CP0_CONF, cfg);
+	return size1 != size2;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+	unsigned long tmp, fpu_id;
+
+	tmp = read_32bit_cp0_register(CP0_STATUS);
+	__enable_fpu();
+	fpu_id = read_32bit_cp1_register(CP1_REVISION);
+	write_32bit_cp0_register(CP0_STATUS, tmp);
+	return fpu_id;
+}
+
+/*
+ * Check the CPU has an FPU the official way.
+ */
+static inline int cpu_has_fpu(void)
+{
+	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+}
+
+/* declaration of the global struct */
+struct mips_cpu mips_cpu = {
+    processor_id:	PRID_IMP_UNKNOWN,
+    fpu_id:		FPIR_IMP_NONE,
+    cputype:		CPU_UNKNOWN
+};
+
+/* Shortcut for assembler access to mips_cpu.options */
+int *cpuoptions = &mips_cpu.options;
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
+__init void cpu_probe(void)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long config1;
+
+        if (config0 & (1 << 31)) {
+		/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+			mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+			mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & (1 << 1))
+			mips_cpu.options |= MIPS_CPU_EJTAG;
+		if (config1 & 1) {
+			mips_cpu.options |= MIPS_CPU_FPU;
+#if defined(CONFIG_CPU_MIPS64)
+			mips_cpu.options |= MIPS_CPU_32FPR;
+#endif
+		}
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+	}
+#endif
+	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
+	switch (mips_cpu.processor_id & 0xff0000) {
+	case PRID_COMP_LEGACY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_R2000:
+			mips_cpu.cputype = CPU_R2000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R3000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
+				if (cpu_has_confreg())
+					mips_cpu.cputype = CPU_R3081E;
+				else
+					mips_cpu.cputype = CPU_R3000A;
+			else
+				mips_cpu.cputype = CPU_R3000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R4000:
+			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
+				mips_cpu.cputype = CPU_R4400SC;
+			else
+				mips_cpu.cputype = CPU_R4000SC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
+			                   MIPS_CPU_VCE;
+			mips_cpu.tlbsize = 48;
+			break;
+                case PRID_IMP_VR41XX:
+			switch (mips_cpu.processor_id & 0xf0) {
+#ifndef CONFIG_VR4181
+			case PRID_REV_VR4111:
+				mips_cpu.cputype = CPU_VR4111;
+				break;
+#else
+			case PRID_REV_VR4181:
+				mips_cpu.cputype = CPU_VR4181;
+				break;
+#endif
+			case PRID_REV_VR4121:
+				mips_cpu.cputype = CPU_VR4121;
+				break;
+			case PRID_REV_VR4122:
+				if ((mips_cpu.processor_id & 0xf) < 0x3)
+					mips_cpu.cputype = CPU_VR4122;
+				else
+					mips_cpu.cputype = CPU_VR4181A;
+				break;
+			case PRID_REV_VR4131:
+				mips_cpu.cputype = CPU_VR4131;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+				break;
+			default:
+				printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+				mips_cpu.cputype = CPU_VR41XX;
+				break;
+			}
+                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
+                        mips_cpu.options = R4K_OPTS;
+                        mips_cpu.tlbsize = 32;
+                        break;
+		case PRID_IMP_R4300:
+			mips_cpu.cputype = CPU_R4300;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+					   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R4600:
+			mips_cpu.cputype = CPU_R4600;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 48;
+			break;
+		#if 0
+ 		case PRID_IMP_R4650:
+			/*
+			 * This processor doesn't have an MMU, so it's not
+			 * "real easy" to run Linux on it. It is left purely
+			 * for documentation.  Commented out because it shares
+			 * it's c0_prid id number with the TX3900.
+			 */
+	 		mips_cpu.cputype = CPU_R4650;
+		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+		        mips_cpu.tlbsize = 48;
+			break;
+		#endif
+		case PRID_IMP_TX39:
+			mips_cpu.isa_level = MIPS_CPU_ISA_I;
+			mips_cpu.options = MIPS_CPU_TLB;
+
+			if ((mips_cpu.processor_id & 0xf0) ==
+			    (PRID_REV_TX3927 & 0xf0)) {
+				mips_cpu.cputype = CPU_TX3927;
+				mips_cpu.tlbsize = 64;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+			} else {
+				switch (mips_cpu.processor_id & 0xff) {
+				case PRID_REV_TX3912:
+					mips_cpu.cputype = CPU_TX3912;
+					mips_cpu.tlbsize = 32;
+					break;
+				case PRID_REV_TX3922:
+					mips_cpu.cputype = CPU_TX3922;
+					mips_cpu.tlbsize = 64;
+					break;
+				default:
+					mips_cpu.cputype = CPU_UNKNOWN;
+					break;
+				}
+			}
+			break;
+		case PRID_IMP_R4700:
+			mips_cpu.cputype = CPU_R4700;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_TX49:
+			mips_cpu.cputype = CPU_TX49XX;
+			mips_cpu.isa_level = MIPS_CPU_ISA_III;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 4;
+			mips_cpu.dcache.ways = 4;
+			break;
+		case PRID_IMP_R5000:
+			mips_cpu.cputype = CPU_R5000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5432:
+			mips_cpu.cputype = CPU_R5432;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_R5500:
+			mips_cpu.cputype = CPU_R5500;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 48;
+			break;
+		case PRID_IMP_NEVADA:
+			mips_cpu.cputype = CPU_NEVADA;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
+			mips_cpu.tlbsize = 48;
+			mips_cpu.icache.ways = 2;
+			mips_cpu.dcache.ways = 2;
+			break;
+		case PRID_IMP_R6000:
+			mips_cpu.cputype = CPU_R6000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_R6000A:
+			mips_cpu.cputype = CPU_R6000A;
+			mips_cpu.isa_level = MIPS_CPU_ISA_II;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+			mips_cpu.tlbsize = 32;
+			break;
+		case PRID_IMP_RM7000:
+			mips_cpu.cputype = CPU_RM7000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
+			                   MIPS_CPU_32FPR;
+			/*
+			 * Undocumented RM7000:  Bit 29 in the info register of
+			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
+			 * entries.
+			 *
+			 * 29      1 =>    64 entry JTLB
+			 *         0 =>    48 entry JTLB
+			 */
+			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
+			break;
+		case PRID_IMP_R8000:
+			mips_cpu.cputype = CPU_R8000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR;
+			mips_cpu.tlbsize = 384;      /* has weird TLB: 3-way x 128 */
+			break;
+		case PRID_IMP_R10000:
+			mips_cpu.cputype = CPU_R10000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR |
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		case PRID_IMP_R12000:
+			mips_cpu.cputype = CPU_R12000;
+			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+				           MIPS_CPU_FPU | MIPS_CPU_32FPR |
+				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+			mips_cpu.tlbsize = 64;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	case PRID_COMP_MIPS:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_4KC:
+			mips_cpu.cputype = CPU_4KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KEC:
+			mips_cpu.cputype = CPU_4KEC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KSC:
+			mips_cpu.cputype = CPU_4KSC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_5KC:
+			mips_cpu.cputype = CPU_5KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		case PRID_IMP_20KC:
+			mips_cpu.cputype = CPU_20KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	case PRID_COMP_ALCHEMY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			switch ((mips_cpu.processor_id >> 24) & 0xff) {
+			case 0:
+ 				mips_cpu.cputype = CPU_AU1000;
+				break;
+			case 1:
+				mips_cpu.cputype = CPU_AU1500;
+				break;
+			case 2:
+				mips_cpu.cputype = CPU_AU1100;
+				break;
+			default:
+				panic("Unknown Au Core!");
+				break;
+			}
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+ 			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+#endif /* CONFIG_CPU_MIPS32 */
+	case PRID_COMP_SIBYTE:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_SB1:
+			mips_cpu.cputype = CPU_SB1;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
+			                   MIPS_CPU_MCHECK;
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+			/* FPU in pass1 is known to have issues. */
+			mips_cpu.options |= MIPS_CPU_FPU;
+#endif
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		mips_cpu.cputype = CPU_UNKNOWN;
+	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
+}
+
+__init void cpu_report(void)
+{
+	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/entry.S linux-2.4.20/arch/mips64/kernel/entry.S
--- linux-2.4.19/arch/mips64/kernel/entry.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/entry.S	2002-10-04 00:41:11.000000000 +0000
@@ -12,11 +12,9 @@
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/offset.h>
 #include <asm/stackframe.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002		/* tracing system calls */
-
 #define KU_USER 0x10
 
 		.text
@@ -24,8 +22,8 @@
 FEXPORT(ret_from_fork)
 		move	a0, v0			# prev
 		jal	schedule_tail
-		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
+		ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+		andi	t0, _PT_TRACESYS
 		bnez	t0, tracesys_exit
 		j	ret_from_sys_call
 
@@ -40,13 +38,14 @@
 		bnez	t0, ret_from_sys_call
 		j	restore_all
 
-reschedule:	jal	schedule 
+reschedule:	jal	schedule
 
 FEXPORT(ret_from_sys_call)
 		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
+		SSNOP; SSNOP; SSNOP
 
 		ld	v0, TASK_NEED_RESCHED($28)
 		lw	v1, TASK_SIGPENDING($28)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/head.S linux-2.4.20/arch/mips64/kernel/head.S
--- linux-2.4.19/arch/mips64/kernel/head.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/head.S	2002-10-04 00:41:15.000000000 +0000
@@ -26,7 +26,7 @@
 #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
 	/* We get launched at a XKPHYS address but the kernel is linked to
 	   run at a KSEG0 address, so jump there.  */
-	la	t0, \@f
+	PTR_LA	t0, \@f
 	jr	t0
 \@:
 #endif
@@ -105,10 +105,23 @@
 
 	CLI					# disable interrupts
 
-	la	$28, init_task_union		# init current pointer
+	PTR_LA	$28, init_task_union		# init current pointer
 	daddiu	sp, $28, KERNEL_STACK_SIZE-32
 	set_saved_sp	sp, t0
 
+	/* The firmware/bootloader passes argc/argp/envp
+	 * to us as arguments.  But clear bss first because
+	 * the romvec and other important info is stored there
+	 * by prom_init().
+	 */
+	PTR_LA	t0, _edata
+	sd	zero, (t0)
+	PTR_LA	t1, (_end - 8)
+1:
+	daddiu	t0, 8
+	sd	zero, (t0)
+	bne	t0, t1, 1b
+
 	dsubu	sp, 4*SZREG			# init stack pointer
 
 	j	init_arch
@@ -117,7 +130,7 @@
 #ifdef CONFIG_SMP
 /*
  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
- * function after setting up the stack and gp registers. 
+ * function after setting up the stack and gp registers.
  */
 NESTED(smp_bootstrap, 16, sp)
 #ifdef CONFIG_SGI_IP27
@@ -171,7 +184,7 @@
 	page	swapper_pg_dir, 1
 	page	invalid_pte_table, 0
 	page	invalid_pmd_table, 1
-	page	kptbl, KPTBL_PAGE_ORDER
+	page	kptbl, _PGD_ORDER
 	.globl	ekptbl
 	page	kpmdtbl, 0
 ekptbl:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/i8259.c linux-2.4.20/arch/mips64/kernel/i8259.c
--- linux-2.4.19/arch/mips64/kernel/i8259.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/i8259.c	2002-10-04 00:41:14.000000000 +0000
@@ -42,7 +42,7 @@
 void mask_and_ack_8259A(unsigned int);
 
 static unsigned int startup_8259A_irq(unsigned int irq)
-{ 
+{
 	enable_8259A_irq(irq);
 
 	return 0; /* never anything pending */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/ioctl32.c linux-2.4.20/arch/mips64/kernel/ioctl32.c
--- linux-2.4.19/arch/mips64/kernel/ioctl32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/ioctl32.c	2002-10-04 00:41:20.000000000 +0000
@@ -10,12 +10,18 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/if.h>
 #include <linux/mm.h>
 #include <linux/mtio.h>
 #include <linux/init.h>
 #include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
 #include <linux/vt.h>
 #include <linux/kd.h>
 #include <linux/netdevice.h>
@@ -27,6 +33,7 @@
 #include <linux/auto_fs.h>
 #include <linux/ext2_fs.h>
 #include <linux/raid/md_u.h>
+
 #include <scsi/scsi.h>
 #undef __KERNEL__		/* This file was born to be ugly ...  */
 #include <scsi/scsi_ioctl.h>
@@ -34,6 +41,8 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
+#include <linux/rtc.h>
+
 long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -41,7 +50,7 @@
 	mm_segment_t old_fs = get_fs();
 	int err;
 	unsigned long val;
-	
+
 	set_fs (KERNEL_DS);
 	err = sys_ioctl(fd, cmd, (unsigned long)&val);
 	set_fs (old_fs);
@@ -197,7 +206,7 @@
 
 	old_fs = get_fs();
 	set_fs (KERNEL_DS);
-	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);	
+	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
 	set_fs (old_fs);
 	if (err)
 		goto out;
@@ -224,28 +233,26 @@
 	return err;
 }
 
-static inline int dev_ifsioc(unsigned int fd, unsigned int cmd,
-			     unsigned long arg)
+static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct ifreq32 *uifr = (struct ifreq32 *)arg;
 	struct ifreq ifr;
 	mm_segment_t old_fs;
 	int err;
 	
 	switch (cmd) {
 	case SIOCSIFMAP:
-		err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name));
-		err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
-		err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
-		err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
-		err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
-		err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
-		err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
+		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
+		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
 		if (err)
 			return -EFAULT;
 		break;
 	default:
-		if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32)))
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
 			return -EFAULT;
 		break;
 	}
@@ -266,17 +273,17 @@
 		case SIOCGIFDSTADDR:
 		case SIOCGIFNETMASK:
 		case SIOCGIFTXQLEN:
-			if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32)))
+			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
 				return -EFAULT;
 			break;
 		case SIOCGIFMAP:
-			err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name));
-			err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
-			err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
-			err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
-			err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
-			err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
-			err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
+			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
+			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
 			if (err)
 				err = -EFAULT;
 			break;
@@ -313,7 +320,7 @@
 	u32 rtdev;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-	
+
 	ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));
 	ret |= __get_user (r.rt_flags, &(ur->rt_flags));
 	ret |= __get_user (r.rt_metric, &(ur->rt_metric));
@@ -411,7 +418,7 @@
 	struct blkpg_partition p;
 	int err;
 	mm_segment_t old_fs = get_fs();
-	
+
 	err = get_user(a.op, &arg->op);
 	err |= __get_user(a.flags, &arg->flags);
 	err |= __get_user(a.datalen, &arg->datalen);
@@ -430,7 +437,7 @@
 		set_fs (old_fs);
 	default:
 		return -EINVAL;
-	}                                        
+	}
 	return err;
 }
 
@@ -699,7 +706,95 @@
 	IOCTL32_DEFAULT(SIOCDRARP),
 	IOCTL32_DEFAULT(SIOCADDDLCI),
 	IOCTL32_DEFAULT(SIOCDELDLCI),
+	/* SG stuff */
+	IOCTL32_DEFAULT(SG_SET_TIMEOUT),
+	IOCTL32_DEFAULT(SG_GET_TIMEOUT),
+	IOCTL32_DEFAULT(SG_EMULATED_HOST),
+	IOCTL32_DEFAULT(SG_SET_TRANSFORM),
+	IOCTL32_DEFAULT(SG_GET_TRANSFORM),
+	IOCTL32_DEFAULT(SG_SET_RESERVED_SIZE),
+	IOCTL32_DEFAULT(SG_GET_RESERVED_SIZE),
+	IOCTL32_DEFAULT(SG_GET_SCSI_ID),
+	IOCTL32_DEFAULT(SG_SET_FORCE_LOW_DMA),
+	IOCTL32_DEFAULT(SG_GET_LOW_DMA),
+	IOCTL32_DEFAULT(SG_SET_FORCE_PACK_ID),
+	IOCTL32_DEFAULT(SG_GET_PACK_ID),
+	IOCTL32_DEFAULT(SG_GET_NUM_WAITING),
+	IOCTL32_DEFAULT(SG_SET_DEBUG),
+	IOCTL32_DEFAULT(SG_GET_SG_TABLESIZE),
+	IOCTL32_DEFAULT(SG_GET_COMMAND_Q),
+	IOCTL32_DEFAULT(SG_SET_COMMAND_Q),
+	IOCTL32_DEFAULT(SG_GET_VERSION_NUM),
+	IOCTL32_DEFAULT(SG_NEXT_CMD_LEN),
+	IOCTL32_DEFAULT(SG_SCSI_RESET),
+	IOCTL32_DEFAULT(SG_IO),
+	IOCTL32_DEFAULT(SG_GET_REQUEST_TABLE),
+	IOCTL32_DEFAULT(SG_SET_KEEP_ORPHAN),
+	IOCTL32_DEFAULT(SG_GET_KEEP_ORPHAN),
+	/* PPP stuff */
+	IOCTL32_DEFAULT(PPPIOCGFLAGS),
+	IOCTL32_DEFAULT(PPPIOCSFLAGS),
+	IOCTL32_DEFAULT(PPPIOCGASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCGUNIT),
+	IOCTL32_DEFAULT(PPPIOCGRASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSRASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCGMRU),
+	IOCTL32_DEFAULT(PPPIOCSMRU),
+	IOCTL32_DEFAULT(PPPIOCSMAXCID),
+	IOCTL32_DEFAULT(PPPIOCGXASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSXASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCXFERUNIT),
+	IOCTL32_DEFAULT(PPPIOCGNPMODE),
+	IOCTL32_DEFAULT(PPPIOCSNPMODE),
+	IOCTL32_DEFAULT(PPPIOCGDEBUG),
+	IOCTL32_DEFAULT(PPPIOCSDEBUG),
+	IOCTL32_DEFAULT(PPPIOCNEWUNIT),
+	IOCTL32_DEFAULT(PPPIOCATTACH),
+	IOCTL32_DEFAULT(PPPIOCGCHAN),
+	/* PPPOX */
+	IOCTL32_DEFAULT(PPPOEIOCSFWD),
+	IOCTL32_DEFAULT(PPPOEIOCDFWD),
+	/* CDROM stuff */
+	IOCTL32_DEFAULT(CDROMPAUSE),
+	IOCTL32_DEFAULT(CDROMRESUME),
+	IOCTL32_DEFAULT(CDROMPLAYMSF),
+	IOCTL32_DEFAULT(CDROMPLAYTRKIND),
+	IOCTL32_DEFAULT(CDROMREADTOCHDR),
+	IOCTL32_DEFAULT(CDROMREADTOCENTRY),
+	IOCTL32_DEFAULT(CDROMSTOP),
+	IOCTL32_DEFAULT(CDROMSTART),
+	IOCTL32_DEFAULT(CDROMEJECT),
+	IOCTL32_DEFAULT(CDROMVOLCTRL),
+	IOCTL32_DEFAULT(CDROMSUBCHNL),
+	IOCTL32_DEFAULT(CDROMEJECT_SW),
+	IOCTL32_DEFAULT(CDROMMULTISESSION),
+	IOCTL32_DEFAULT(CDROM_GET_MCN),
+	IOCTL32_DEFAULT(CDROMRESET),
+	IOCTL32_DEFAULT(CDROMVOLREAD),
+	IOCTL32_DEFAULT(CDROMSEEK),
+	IOCTL32_DEFAULT(CDROMPLAYBLK),
+	IOCTL32_DEFAULT(CDROMCLOSETRAY),
+	IOCTL32_DEFAULT(CDROM_SET_OPTIONS),
+	IOCTL32_DEFAULT(CDROM_CLEAR_OPTIONS),
+	IOCTL32_DEFAULT(CDROM_SELECT_SPEED),
+	IOCTL32_DEFAULT(CDROM_SELECT_DISC),
+	IOCTL32_DEFAULT(CDROM_MEDIA_CHANGED),
+	IOCTL32_DEFAULT(CDROM_DRIVE_STATUS),
+	IOCTL32_DEFAULT(CDROM_DISC_STATUS),
+	IOCTL32_DEFAULT(CDROM_CHANGER_NSLOTS),
+	IOCTL32_DEFAULT(CDROM_LOCKDOOR),
+	IOCTL32_DEFAULT(CDROM_DEBUG),
+	IOCTL32_DEFAULT(CDROM_GET_CAPABILITY),
+	/* DVD ioctls */
+	IOCTL32_DEFAULT(DVD_READ_STRUCT),
+	IOCTL32_DEFAULT(DVD_WRITE_STRUCT),
+	IOCTL32_DEFAULT(DVD_AUTH),
+	/* Big L */
+	IOCTL32_DEFAULT(LOOP_SET_FD),
+	IOCTL32_DEFAULT(LOOP_CLR_FD),
 
+	/* And these ioctls need translation */
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
 	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
@@ -727,6 +822,9 @@
 	IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPSTATS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPCSTATS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPVER, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
@@ -834,7 +932,25 @@
 	IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC),
 	IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER),
 	IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
-	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE)
+	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE),
+
+	/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+	IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */
+	IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */
+	IOCTL32_DEFAULT(RTC_AIE_ON),
+	IOCTL32_DEFAULT(RTC_AIE_OFF),
+	IOCTL32_DEFAULT(RTC_UIE_ON),
+	IOCTL32_DEFAULT(RTC_UIE_OFF),
+	IOCTL32_DEFAULT(RTC_PIE_ON),
+	IOCTL32_DEFAULT(RTC_PIE_OFF),
+	IOCTL32_DEFAULT(RTC_WIE_ON),
+	IOCTL32_DEFAULT(RTC_WIE_OFF),
+	IOCTL32_DEFAULT(RTC_ALM_SET),
+	IOCTL32_DEFAULT(RTC_ALM_READ),
+	IOCTL32_DEFAULT(RTC_RD_TIME),
+	IOCTL32_DEFAULT(RTC_SET_TIME),
+	IOCTL32_DEFAULT(RTC_WKALM_SET),
+	IOCTL32_DEFAULT(RTC_WKALM_RD)
 };
 
 #define NR_IOCTL32_HANDLERS	(sizeof(ioctl32_handler_table) /	\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/irq.c linux-2.4.20/arch/mips64/kernel/irq.c
--- linux-2.4.19/arch/mips64/kernel/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/irq.c	2002-10-04 00:41:09.000000000 +0000
@@ -31,6 +31,8 @@
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+static void register_irq_proc (unsigned int irq);
+
 /*
  * Special irq handlers.
  */
@@ -48,7 +50,7 @@
 {
 	/*
 	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesnt deserve
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("unexpected interrupt %d\n", irq);
@@ -87,7 +89,7 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
-		if (!action) 
+		if (!action)
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
@@ -198,12 +200,12 @@
 }
 
 /*
- * A global "cli()" while in an interrupt context turns into just a local 
- * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * A global "cli()" while in an interrupt context turns into just a local
+ * cli(). Interrupts should use spinlocks for the (very unlikely) case that
  * they ever want to protect against each other.
- * 
- * If we already have local interrupts disabled, this will not turn a local 
- * disable into a global one (problems with spinlocks: this makes 
+ *
+ * If we already have local interrupts disabled, this will not turn a local
+ * disable into a global one (problems with spinlocks: this makes
  * save_flags+cli+sti usable inside a spinlock).
  */
 
@@ -317,9 +319,9 @@
  * Generic enable/disable code: this just calls
  * down into the PIC-specific version for the actual
  * hardware disable after having gotten the irq
- * controller lock. 
+ * controller lock.
  */
- 
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -330,7 +332,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void inline disable_irq_nosync(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -356,7 +358,7 @@
  *
  *	This function may be called - with care - from IRQ context.
  */
- 
+
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
@@ -377,7 +379,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void enable_irq(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -412,7 +414,7 @@
  */
 asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
 {
-	/* 
+	/*
 	 * We ack quickly, we don't want the irq controller
 	 * thinking we're snobs just because some other CPU has
 	 * disabled global interrupts (we have already done the
@@ -472,7 +474,7 @@
 		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, regs, action);
 		spin_lock(&desc->lock);
-		
+
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -502,7 +504,7 @@
  *	This call allocates interrupt resources and enables the
  *	interrupt line and IRQ handling. From the point this
  *	call is made your handler function may be invoked. Since
- *	your handler function must clear any interrupt the board 
+ *	your handler function must clear any interrupt the board
  *	raises, you must take care both to initialise your hardware
  *	and to set up the interrupt handler in the right order.
  *
@@ -522,10 +524,10 @@
  *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  *
  */
- 
-int request_irq(unsigned int irq, 
+
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -580,12 +582,12 @@
  *	does not return until any executing interrupts for this IRQ
  *	have completed.
  *
- *	This function may be called from interrupt context. 
+ *	This function may be called from interrupt context.
  *
  *	Bugs: Attempting to free an irq in a handler for the same irq hangs
  *	      the machine.
  */
- 
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	irq_desc_t *desc;
@@ -646,7 +648,7 @@
  *	and a mask of potential interrupt lines is returned.
  *
  */
- 
+
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
@@ -655,15 +657,15 @@
 	unsigned long delay;
 
 	down(&probe_sem);
-	/* 
+	/*
 	 * something may have generated an irq long ago and we want to
-	 * flush such a longstanding irq before considering it as spurious. 
+	 * flush such a longstanding irq before considering it as spurious.
 	 */
 	for (i = NR_IRQS-1; i > 0; i--)  {
 		desc = irq_desc + i;
 
 		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
+		if (!irq_desc[i].action)
 			irq_desc[i].handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
@@ -725,7 +727,7 @@
  * Return a mask of triggered interrupts (this
  * can handle only legacy ISA interrupts).
  */
- 
+
 /**
  *	probe_irq_mask - scan a bitmap of interrupt lines
  *	@val:	mask of interrupts to consider
@@ -787,7 +789,7 @@
  *	nothing prevents two IRQ probe callers from overlapping. The
  *	results of this are non-optimal.
  */
- 
+
 int probe_irq_off(unsigned long val)
 {
 	int i, irq_found, nr_irqs;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/irq_cpu.c linux-2.4.20/arch/mips64/kernel/irq_cpu.c
--- linux-2.4.19/arch/mips64/kernel/irq_cpu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/irq_cpu.c	2002-10-04 00:41:21.000000000 +0000
@@ -2,6 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
+ * Copyright (C) 2001 Ralf Baechle
+ *
  * This file define the irq handler for MIPS CPU interrupts.
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -13,8 +15,11 @@
 /*
  * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
  * level triggered (i.e., cannot be cleared from CPU; must be cleared from
- * device).  The first two are software interrupts.  The last one is 
- * usually cpu timer interrupt if coutner register is present.
+ * device).  The first two are software interrupts which we don't really
+ * use or support.  The last one is usually cpu timer interrupt if a counter
+ * register is present.
+ *
+ * Don't even think about using this on SMP.  You have been warned.
  *
  * This file exports one global function:
  *	mips_cpu_irq_init(u32 irq_base);
@@ -24,18 +29,37 @@
 #include <linux/kernel.h>
 
 #include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int mips_cpu_irq_base;
+
+static inline void unmask_mips_irq(unsigned int irq)
+{
+	clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base));
+	set_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static int mips_cpu_irq_base = -1;
+static inline void mask_mips_irq(unsigned int irq)
+{
+	clear_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static void mips_cpu_irq_enable(unsigned int irq)
+static inline void mips_cpu_irq_enable(unsigned int irq)
 {
-	clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8));
-	set_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static void mips_cpu_irq_disable(unsigned int irq)
 {
-	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static unsigned int mips_cpu_irq_startup(unsigned int irq)
@@ -47,21 +71,22 @@
 
 #define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
 
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for mips_cpu_irq_end.
+ */
 static void mips_cpu_irq_ack(unsigned int irq)
 {
-	/* although we attemp to clear the IP bit in cause reigster, I think
-	 * usually it is cleared by device (irq source)
-	 */
+	/* Only necessary for soft interrupts */
 	clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8));
 
-	/* disable this interrupt - so that we safe proceed to the handler */
-	mips_cpu_irq_disable(irq);
+	mask_mips_irq(irq);
 }
 
 static void mips_cpu_irq_end(unsigned int irq)
 {
-	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		mips_cpu_irq_enable(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_mips_irq(irq);
 }
 
 static hw_irq_controller mips_cpu_irq_controller = {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/linux32.c linux-2.4.20/arch/mips64/kernel/linux32.c
--- linux-2.4.19/arch/mips64/kernel/linux32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/linux32.c	2002-10-04 00:41:10.000000000 +0000
@@ -1,10 +1,11 @@
-/* 
+/*
  * Conversion between 32-bit and 64-bit native system calls.
  *
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
  * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
  */
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/file.h>
@@ -12,6 +13,7 @@
 #include <linux/highuid.h>
 #include <linux/dirent.h>
 #include <linux/resource.h>
+#include <linux/filter.h>
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/poll.h>
@@ -21,6 +23,7 @@
 #include <linux/shm.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
+#include <linux/icmpv6.h>
 #include <linux/sysctl.h>
 #include <linux/utime.h>
 #include <linux/utsname.h>
@@ -34,8 +37,16 @@
 #include <asm/mman.h>
 #include <asm/ipc.h>
 
-
+/* Use this to get at 32-bit user passed pointers. */
+/* A() macro should be used for places where you e.g.
+   have some internal variable u32 and just want to get
+   rid of a compiler warning. AA() has to be used in
+   places where you want to convert a function argument
+   to 32bit pointer or when you e.g. access pt_regs
+   structure and want to consider 32bit registers only.
+ */
 #define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)((int)__x))
 
 #ifdef __MIPSEB__
 #define merge_64(r1,r2)	((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
@@ -202,7 +213,7 @@
 	mm_segment_t old_fs;
 	int ret;
 	char *filenam;
-	
+
 	if (!times)
 		return sys_utime(filename, NULL);
 	if (get_user (t.actime, &times->actime) ||
@@ -212,7 +223,7 @@
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		old_fs = get_fs();
-		set_fs (KERNEL_DS); 
+		set_fs (KERNEL_DS);
 		ret = sys_utime(filenam, &t);
 		set_fs (old_fs);
 		putname (filenam);
@@ -251,7 +262,7 @@
  * memory to free pages in kernel mem. These are in a format ready
  * to be put directly into the top of new user memory.
  */
-int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm) 
+int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
 {
 	while (argc-- > 0) {
 		u32 str;
@@ -259,13 +270,13 @@
 		unsigned long pos;
 
 		if (get_user(str, argv+argc) || !str ||
-		     !(len = strnlen_user((char *)A(str), bprm->p))) 
+		     !(len = strnlen_user((char *)A(str), bprm->p)))
 			return -EFAULT;
-		if (bprm->p < len) 
-			return -E2BIG; 
+		if (bprm->p < len)
+			return -E2BIG;
 
 		bprm->p -= len;
-		/* XXX: add architecture specific overflow check here. */ 
+		/* XXX: add architecture specific overflow check here. */
 
 		pos = bprm->p;
 		while (len > 0) {
@@ -302,7 +313,7 @@
 			kunmap(page);
 
 			if (err)
-				return -EFAULT; 
+				return -EFAULT;
 
 			pos += bytes_to_copy;
 			str += bytes_to_copy;
@@ -324,7 +335,7 @@
 	int i;
 
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
+	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
 
 	dentry = open_namei(filename, 0, 0);
 	retval = PTR_ERR(dentry);
@@ -347,21 +358,21 @@
 	}
 
 	retval = prepare_binprm(&bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	bprm.exec = bprm.p;
 	retval = copy_strings32(bprm.envc, envp, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = copy_strings32(bprm.argc, argv, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = search_binary_handler(&bprm,regs);
 	if (retval >= 0)
@@ -373,8 +384,8 @@
 	if (bprm.dentry)
 		dput(bprm.dentry);
 
-	/* Assumes that free_page() can take a NULL argument. */ 
-	/* I hope this is ok for all architectures */ 
+	/* Assumes that free_page() can take a NULL argument. */
+	/* I hope this is ok for all architectures */
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++)
 		if (bprm.page[i])
 			__free_page(bprm.page[i]);
@@ -403,12 +414,14 @@
 	return error;
 }
 #else
-static int
-nargs(unsigned int arg, char **ap)
+static int nargs(unsigned int arg, char **ap)
 {
 	char *ptr;
 	int n, ret;
 
+	if (!arg)
+		return 0;
+
 	n = 0;
 	do {
 		/* egcs is stupid */
@@ -422,10 +435,11 @@
 		arg += sizeof(unsigned int);
 		n++;
 	} while (ptr);
-	return(n - 1);
+
+	return n - 1;
 }
 
-asmlinkage int 
+asmlinkage int
 sys32_execve(abi64_no_regargs, struct pt_regs regs)
 {
 	extern asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs);
@@ -560,8 +574,8 @@
         int    ru_nswap;
         int    ru_inblock;
         int    ru_oublock;
-        int    ru_msgsnd; 
-        int    ru_msgrcv; 
+        int    ru_msgsnd;
+        int    ru_msgrcv;
         int    ru_nsignals;
         int    ru_nvcsw;
         int    ru_nivcsw;
@@ -571,7 +585,7 @@
 put_rusage (struct rusage32 *ru, struct rusage *r)
 {
 	int err;
-	
+
 	err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
 	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
 	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
@@ -604,8 +618,8 @@
 		int ret;
 		unsigned int status;
 		mm_segment_t old_fs = get_fs();
-	
-		set_fs(KERNEL_DS);	
+
+		set_fs(KERNEL_DS);
 		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
 		set_fs(old_fs);
 		if (put_rusage (ru, &r)) return -EFAULT;
@@ -637,7 +651,7 @@
 	struct rlimit r;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_old_getrlimit(resource, &r);
 	set_fs (old_fs);
@@ -657,7 +671,7 @@
 	int ret;
 	mm_segment_t old_fs = get_fs ();
 
-	if (resource >= RLIM_NLIMITS) return -EINVAL;	
+	if (resource >= RLIM_NLIMITS) return -EINVAL;
 	if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
 	    __get_user (r.rlim_max, &rlim->rlim_max))
 		return -EFAULT;
@@ -689,7 +703,7 @@
 put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
 {
 	int err;
-	
+
 	err = put_user (kbuf->f_type, &ubuf->f_type);
 	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
 	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
@@ -711,7 +725,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_statfs((const char *)path, &s);
 	set_fs (old_fs);
@@ -728,7 +742,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_fstatfs(fd, &s);
 	set_fs (old_fs);
@@ -746,7 +760,7 @@
 	struct rusage r;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_getrusage(who, &r);
 	set_fs (old_fs);
@@ -831,7 +845,7 @@
 	return 0;
 
 }
-asmlinkage unsigned long 
+asmlinkage unsigned long
 sys32_alarm(unsigned int seconds)
 {
 	struct itimerval it_new, it_old;
@@ -980,7 +994,7 @@
 	/* VERIFY_WRITE actually means a read, as we write to user space */
 	fn = file->f_op->read;
 	if (type == VERIFY_READ)
-		fn = (IO_fn_t) file->f_op->write;		
+		fn = (IO_fn_t) file->f_op->write;
 	ivp = iov;
 	while (count > 0) {
 		void * base;
@@ -1222,7 +1236,7 @@
 	/*
 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
 	 * since we used fdset we need to allocate memory in units of
-	 * long-words. 
+	 * long-words.
 	 */
 	ret = -ENOMEM;
 	size = FDS_BYTES(n);
@@ -1293,7 +1307,7 @@
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_sched_rr_get_interval(pid, &t);
 	set_fs (old_fs);
@@ -1305,7 +1319,7 @@
 
 
 extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
-				    struct timespec *rmtp); 
+				    struct timespec *rmtp);
 
 asmlinkage int
 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
@@ -1317,7 +1331,7 @@
 	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
 	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
 		return -EFAULT;
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
 	set_fs (old_fs);
@@ -1361,75 +1375,119 @@
 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
 				     char *optval, int optlen);
 
-asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+static int do_set_attach_filter(int fd, int level, int optname,
 				char *optval, int optlen)
 {
-	if (optname == SO_ATTACH_FILTER) {
-		struct sock_fprog32 {
-			__u16 len;
-			__u32 filter;
-		} *fprog32 = (struct sock_fprog32 *)optval;
-		struct sock_fprog kfprog;
-		struct sock_filter *kfilter;
-		unsigned int fsize;
-		mm_segment_t old_fs;
-		__u32 uptr;
-		int ret;
+	struct sock_fprog32 {
+		__u16 len;
+		__u32 filter;
+	} *fprog32 = (struct sock_fprog32 *)optval;
+	struct sock_fprog kfprog;
+	struct sock_filter *kfilter;
+	unsigned int fsize;
+	mm_segment_t old_fs;
+	__u32 uptr;
+	int ret;
 
-		if (get_user(kfprog.len, &fprog32->len) ||
-		    __get_user(uptr, &fprog32->filter))
-			return -EFAULT;
-		kfprog.filter = (struct sock_filter *)A(uptr);
-		fsize = kfprog.len * sizeof(struct sock_filter);
-		kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
-		if (kfilter == NULL)
-			return -ENOMEM;
-		if (copy_from_user(kfilter, kfprog.filter, fsize)) {
-			kfree(kfilter);
-			return -EFAULT;
-		}
-		kfprog.filter = kfilter;
-		old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		ret = sys_setsockopt(fd, level, optname,
-				     (char *)&kfprog, sizeof(kfprog));
-		set_fs(old_fs);
+	if (get_user(kfprog.len, &fprog32->len) ||
+	    __get_user(uptr, &fprog32->filter))
+		return -EFAULT;
+
+	kfprog.filter = (struct sock_filter *)A(uptr);
+	fsize = kfprog.len * sizeof(struct sock_filter);
+
+	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
+	if (kfilter == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(kfilter, kfprog.filter, fsize)) {
 		kfree(kfilter);
-		return ret;
+		return -EFAULT;
 	}
-	return sys_setsockopt(fd, level, optname, optval, optlen);
+
+	kfprog.filter = kfilter;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_setsockopt(fd, level, optname,
+			     (char *)&kfprog, sizeof(kfprog));
+	set_fs(old_fs);
+
+	kfree(kfilter);
+
+	return ret;
 }
 
-struct flock32 {
-	short l_type;
-	short l_whence;
-	__kernel_off_t32 l_start;
-	__kernel_off_t32 l_len;
-	__kernel_pid_t32 l_pid;
-	short __unused;
-};
+static int do_set_icmpv6_filter(int fd, int level, int optname,
+				char *optval, int optlen)
+{
+	struct icmp6_filter kfilter;
+	mm_segment_t old_fs;
+	int ret, i;
+
+	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
+		return -EFAULT;
+
+
+	for (i = 0; i < 8; i += 2) {
+		u32 tmp = kfilter.data[i];
+
+		kfilter.data[i] = kfilter.data[i + 1];
+		kfilter.data[i + 1] = tmp;
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_setsockopt(fd, level, optname,
+			     (char *) &kfilter, sizeof(kfilter));
+	set_fs(old_fs);
+
+	return ret;
+}
+
+asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+				char *optval, int optlen)
+{
+	if (optname == SO_ATTACH_FILTER)
+		return do_set_attach_filter(fd, level, optname,
+					    optval, optlen);
+	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
+		return do_set_icmpv6_filter(fd, level, optname,
+					    optval, optlen);
+
+	return sys_setsockopt(fd, level, optname, optval, optlen);
+}
 
 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
 {
 	int err;
-	
-	err = get_user(kfl->l_type, &ufl->l_type);
+
+	if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)))
+		return -EFAULT;
+
+	err = __get_user(kfl->l_type, &ufl->l_type);
 	err |= __get_user(kfl->l_whence, &ufl->l_whence);
 	err |= __get_user(kfl->l_start, &ufl->l_start);
 	err |= __get_user(kfl->l_len, &ufl->l_len);
 	err |= __get_user(kfl->l_pid, &ufl->l_pid);
+
 	return err;
 }
 
 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
 {
 	int err;
-	
+
+	if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)))
+		return -EFAULT;
+
 	err = __put_user(kfl->l_type, &ufl->l_type);
 	err |= __put_user(kfl->l_whence, &ufl->l_whence);
 	err |= __put_user(kfl->l_start, &ufl->l_start);
 	err |= __put_user(kfl->l_len, &ufl->l_len);
+	err |= __put_user(0, &ufl->l_sysid);
 	err |= __put_user(kfl->l_pid, &ufl->l_pid);
+
 	return err;
 }
 
@@ -1447,7 +1505,7 @@
 			struct flock f;
 			mm_segment_t old_fs;
 			long ret;
-			
+
 			if (get_flock(&f, (struct flock32 *)arg))
 				return -EFAULT;
 			old_fs = get_fs(); set_fs (KERNEL_DS);
@@ -1490,6 +1548,19 @@
         unsigned short  seq;
 };
 
+struct ipc64_perm32 {
+	key_t key;
+	__kernel_uid_t32 uid;
+	__kernel_gid_t32 gid;
+	__kernel_uid_t32 cuid;
+	__kernel_gid_t32 cgid;
+	__kernel_mode_t32 mode; 
+	unsigned short seq;
+	unsigned short __pad1;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
 struct semid_ds32 {
         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
         __kernel_time_t32 sem_otime;              /* last semop time */
@@ -1512,24 +1583,44 @@
         u32 wwait;
         u32 rwait;
         unsigned short msg_cbytes;
-        unsigned short msg_qnum;  
+        unsigned short msg_qnum;
         unsigned short msg_qbytes;
         __kernel_ipc_pid_t32 msg_lspid;
         __kernel_ipc_pid_t32 msg_lrpid;
 };
 
+struct msqid64_ds32 {
+	struct ipc64_perm32 msg_perm;
+	__kernel_time_t32 msg_stime;
+	unsigned int __unused1;
+	__kernel_time_t32 msg_rtime;
+	unsigned int __unused2;
+	__kernel_time_t32 msg_ctime;
+	unsigned int __unused3;
+	unsigned int msg_cbytes;
+	unsigned int msg_qnum;
+	unsigned int msg_qbytes;
+	__kernel_pid_t32 msg_lspid;
+	__kernel_pid_t32 msg_lrpid;
+	unsigned int __unused4;
+	unsigned int __unused5;
+};
+
 struct shmid_ds32 {
         struct ipc_perm32       shm_perm;
         int                     shm_segsz;
         __kernel_time_t32       shm_atime;
         __kernel_time_t32       shm_dtime;
         __kernel_time_t32       shm_ctime;
-        __kernel_ipc_pid_t32    shm_cpid; 
-        __kernel_ipc_pid_t32    shm_lpid; 
+        __kernel_ipc_pid_t32    shm_cpid;
+        __kernel_ipc_pid_t32    shm_lpid;
         unsigned short          shm_nattch;
 };
 
-#define IPCOP_MASK(__x)	(1UL << (__x))
+struct ipc_kludge32 {
+	u32 msgp;
+	s32 msgtyp;
+};
 
 static int
 do_sys32_semctl(int first, int second, int third, void *uptr)
@@ -1596,21 +1687,23 @@
 	return err;
 }
 
-static int
 do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
-				    + 4, GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+	struct msgbuf *p;
 	mm_segment_t old_fs;
 	int err;
 
+	if (second < 0)
+		return -EINVAL;
+	p = kmalloc (second + sizeof (struct msgbuf)
+				    + 4, GFP_USER);
 	if (!p)
 		return -ENOMEM;
 	err = get_user (p->mtype, &up->mtype);
 	if (err)
 		goto out;
-	err = __copy_from_user (p->mtext, &up->mtext, second);
+	err |= __copy_from_user (p->mtext, &up->mtext, second);
 	if (err)
 		goto out;
 	old_fs = get_fs ();
@@ -1619,6 +1712,7 @@
 	set_fs (old_fs);
 out:
 	kfree (p);
+
 	return err;
 }
 
@@ -1632,18 +1726,21 @@
 	int err;
 
 	if (!version) {
-		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
-		struct ipc_kludge ipck;
+		struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
+		struct ipc_kludge32 ipck;
 
 		err = -EINVAL;
 		if (!uptr)
 			goto out;
 		err = -EFAULT;
-		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
+		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
 			goto out;
-		uptr = (void *)A(ipck.msgp);
+		uptr = (void *)AA(ipck.msgp);
 		msgtyp = ipck.msgtyp;
 	}
+
+	if (second < 0)
+		return -EINVAL;
 	err = -ENOMEM;
 	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
 	if (!p)
@@ -1668,13 +1765,12 @@
 do_sys32_msgctl (int first, int second, void *uptr)
 {
 	int err = -EINVAL, err2;
-	struct msqid_ds m;
-	struct msqid64_ds m64;
-	struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+	struct msqid64_ds m;
+	struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
+	struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
 	mm_segment_t old_fs;
 
-	switch (second) {
-
+	switch (second & ~IPC_64) {
 	case IPC_INFO:
 	case IPC_RMID:
 	case MSG_INFO:
@@ -1682,15 +1778,30 @@
 		break;
 
 	case IPC_SET:
-		err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
-		err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
-		err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
-		err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
+		} else {
+			if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
+		}
 		if (err)
 			break;
 		old_fs = get_fs ();
 		set_fs (KERNEL_DS);
-		err = sys_msgctl (first, second, &m);
+		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
 		set_fs (old_fs);
 		break;
 
@@ -1698,27 +1809,54 @@
 	case MSG_STAT:
 		old_fs = get_fs ();
 		set_fs (KERNEL_DS);
-		err = sys_msgctl (first, second, (void *) &m64);
+		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
 		set_fs (old_fs);
-		err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
-		err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
-		err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
-		err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
-		err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
-		err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
-		err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
-		err2 |= __put_user(m64.msg_stime, &up->msg_stime);
-		err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
-		err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
-		err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
-		err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
-		err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
-		err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
-		err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
-		if (err2)
-			err = -EFAULT;
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up64->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up32->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		}
 		break;
-
 	}
 
 	return err;
@@ -1841,7 +1979,7 @@
 
 	case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		err = sys_semop (first, (struct sembuf *)A(ptr),
+		err = sys_semop (first, (struct sembuf *)AA(ptr),
 				 second);
 		break;
 	case SEMGET:
@@ -1849,36 +1987,36 @@
 		break;
 	case SEMCTL:
 		err = do_sys32_semctl (first, second, third,
-				       (void *)A(ptr));
+				       (void *)AA(ptr));
 		break;
 
 	case MSGSND:
 		err = do_sys32_msgsnd (first, second, third,
-				       (void *)A(ptr));
+				       (void *)AA(ptr));
 		break;
 	case MSGRCV:
 		err = do_sys32_msgrcv (first, second, fifth, third,
-				       version, (void *)A(ptr));
+				       version, (void *)AA(ptr));
 		break;
 	case MSGGET:
 		err = sys_msgget ((key_t) first, second);
 		break;
 	case MSGCTL:
-		err = do_sys32_msgctl (first, second, (void *)A(ptr));
+		err = do_sys32_msgctl (first, second, (void *)AA(ptr));
 		break;
 
 	case SHMAT:
 		err = do_sys32_shmat (first, second, third,
-				      version, (void *)A(ptr));
+				      version, (void *)AA(ptr));
 		break;
-	case SHMDT: 
+	case SHMDT:
 		err = sys_shmdt ((char *)A(ptr));
 		break;
 	case SHMGET:
 		err = sys_shmget (first, second, third);
 		break;
 	case SHMCTL:
-		err = do_sys32_shmctl (first, second, (void *)A(ptr));
+		err = do_sys32_shmctl (first, second, (void *)AA(ptr));
 		break;
 	default:
 		err = -EINVAL;
@@ -1911,7 +2049,7 @@
 	ret = -EFAULT;
 
 	memset(&kargs, 0, sizeof (kargs));
-	
+
 	err = get_user(kargs32.name, &uargs32->name);
 	err |= __get_user(kargs32.nlen, &uargs32->nlen);
 	err |= __get_user(kargs32.oldval, &uargs32->oldval);
@@ -1973,7 +2111,7 @@
 		kfree(kargs.oldval);
 	if (kargs.newval)
 		kfree(kargs.newval);
-	return ret; 
+	return ret;
 }
 
 asmlinkage long sys32_newuname(struct new_utsname * name)
@@ -2081,7 +2219,7 @@
 /*
  *  Declare the 32-bit version of the msghdr
  */
- 
+
 struct msghdr32 {
 	unsigned int    msg_name;	/* Socket name			*/
 	int		msg_namelen;	/* Length of name		*/
@@ -2129,7 +2267,7 @@
 {
 	int size, err, ct;
 	struct iovec32 *iov32;
-	
+
 	if(m->msg_namelen)
 	{
 		if(mode==VERIFY_READ)
@@ -2138,7 +2276,7 @@
 			if(err<0)
 				goto out;
 		}
-		
+
 		m->msg_name = address;
 	} else
 		m->msg_name = NULL;
@@ -2167,7 +2305,7 @@
 }
 
 /* XXX This really belongs in some header file... -DaveM */
-#define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
+#define MAX_SOCK_ADDR	128		/* 108 for Unix domain -
 					   16 for IP, 16 for IPX,
 					   24 for IPv6,
 					   about 80 for AX.25 */
@@ -2187,13 +2325,13 @@
 	unsigned char *ctl_buf = ctl;
 	struct msghdr msg_sys;
 	int err, ctl_len, iov_size, total_len;
-	
+
 	err = -EFAULT;
 	if (shape_msg(&msg_sys, msg))
-		goto out; 
+		goto out;
 
 	sock = sockfd_lookup(fd, &err);
-	if (!sock) 
+	if (!sock)
 		goto out;
 
 	/* do not move before msg_sys is valid */
@@ -2212,7 +2350,7 @@
 
 	/* This will also move the address data into kernel space */
 	err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
-	if (err < 0) 
+	if (err < 0)
 		goto out_freeiov;
 	total_len = err;
 
@@ -2220,14 +2358,14 @@
 
 	if (msg_sys.msg_controllen > INT_MAX)
 		goto out_freeiov;
-	ctl_len = msg_sys.msg_controllen; 
-	if (ctl_len) 
+	ctl_len = msg_sys.msg_controllen;
+	if (ctl_len)
 	{
 		if (ctl_len > sizeof(ctl))
 		{
 			err = -ENOBUFS;
 			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
-			if (ctl_buf == NULL) 
+			if (ctl_buf == NULL)
 				goto out_freeiov;
 		}
 		err = -EFAULT;
@@ -2242,14 +2380,14 @@
 	err = sock_sendmsg(sock, &msg_sys, total_len);
 
 out_freectl:
-	if (ctl_buf != ctl)    
+	if (ctl_buf != ctl)
 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
 out_freeiov:
 	if (iov != iovstack)
 		sock_kfree_s(sock->sk, iov, iov_size);
 out_put:
 	sockfd_put(sock);
-out:       
+out:
 	return err;
 }
 
@@ -2273,7 +2411,7 @@
 	/* user mode address pointers */
 	struct sockaddr *uaddr;
 	int *uaddr_len;
-	
+
 	err=-EFAULT;
 	if (shape_msg(&msg_sys, msg))
 		goto out;
@@ -2285,7 +2423,7 @@
 	err = -EINVAL;
 	if (msg_sys.msg_iovlen > UIO_MAXIOV)
 		goto out_put;
-	
+
 	/* Check whether to allocate the iovec area*/
 	err = -ENOMEM;
 	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
@@ -2299,7 +2437,7 @@
 	 *	Save the user-mode address (verify_iovec will change the
 	 *	kernel msghdr to use the kernel address space)
 	 */
-	 
+
 	uaddr = msg_sys.msg_name;
 	uaddr_len = &msg->msg_namelen;
 	err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
@@ -2309,7 +2447,7 @@
 
 	cmsg_ptr = (unsigned long)msg_sys.msg_control;
 	msg_sys.msg_flags = 0;
-	
+
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = sock_recvmsg(sock, &msg_sys, total_len, flags);
@@ -2325,7 +2463,7 @@
 	err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
 	if (err)
 		goto out_freeiov;
-	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, 
+	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
 							 &msg->msg_controllen);
 	if (err)
 		goto out_freeiov;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/mips64_ksyms.c linux-2.4.20/arch/mips64/kernel/mips64_ksyms.c
--- linux-2.4.19/arch/mips64/kernel/mips64_ksyms.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/mips64_ksyms.c	2002-10-04 00:41:16.000000000 +0000
@@ -39,7 +39,10 @@
 extern long __strnlen_user_asm(const char *s);
 
 EXPORT_SYMBOL(mips_machtype);
+
+#ifdef CONFIG_EISA
 EXPORT_SYMBOL(EISA_bus);
+#endif
 
 /*
  * String functions
@@ -90,21 +93,11 @@
 EXPORT_SYMBOL(invalid_pte_table);
 
 /*
- * Base address of ports for Intel style I/O.
- */
-#if defined (CONFIG_PCI) || defined (CONFIG_ISA)
-EXPORT_SYMBOL(mips_io_port_base);
-#endif
-
-/*
  * Kernel hacking ...
  */
 #include <asm/branch.h>
 #include <linux/sched.h>
 
-int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/pci-dma.c linux-2.4.20/arch/mips64/kernel/pci-dma.c
--- linux-2.4.19/arch/mips64/kernel/pci-dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/pci-dma.c	2002-10-04 00:41:20.000000000 +0000
@@ -4,17 +4,17 @@
  * for more details.
  *
  * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
  * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
  */
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/pci.h>
 
 #include <asm/io.h>
-#include <asm/addrspace.h>
 
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t * dma_handle)
@@ -22,24 +22,34 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (hwdev != NULL && hwdev->dma_mask != 0xffffffff)
+#ifdef CONFIG_ISA
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
+#endif
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
+		*dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret));
 #ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
-		ret = KSEG1ADDR(ret);
+		ret = UNCAC_ADDR(ret);
 #endif
-		*dma_handle = __pa(ret);
-		return ret;
 	}
-	return NULL;
+
+	return ret;
 }
 
 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	free_pages((unsigned long) KSEG0ADDR(vaddr), get_order(size));
+	unsigned long addr = (unsigned long) vaddr;
+
+#ifdef CONFIG_NONCOHERENT_IO
+	addr = CAC_ADDR(addr);
+#endif
+	free_pages(addr, get_order(size));
 }
+
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/proc.c linux-2.4.20/arch/mips64/kernel/proc.c
--- linux-2.4.19/arch/mips64/kernel/proc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/proc.c	2002-10-04 00:41:30.000000000 +0000
@@ -67,7 +67,13 @@
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
 	[CPU_TX39XX]	"TX39xx",
-	[CPU_20KC]	"MIPS 20Kc"
+	[CPU_20KC]	"MIPS 20Kc",
+	[CPU_VR4111]	"NEC VR4111",
+	[CPU_VR4121]	"NEC VR4121",
+	[CPU_VR4122]	"NEC VR4122",
+	[CPU_VR4131]	"NEC VR4131",
+	[CPU_VR4181]	"NEC VR4181",
+	[CPU_VR4181A]	"NEC VR4181A"
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/process.c linux-2.4.20/arch/mips64/kernel/process.c
--- linux-2.4.19/arch/mips64/kernel/process.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/process.c	2002-10-04 00:41:14.000000000 +0000
@@ -29,6 +29,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/elf.h>
+#include <asm/cpu.h>
 
 ATTRIB_NORET void cpu_idle(void)
 {
@@ -53,8 +54,10 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		__enable_fpu();
-		__asm__ __volatile__("cfc1\t$0,$31");
+		if (mips_cpu.options & MIPS_CPU_FPU) {
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t$0,$31");
+		}
 		CLEAR_FPU_OWNER();
 	}
 }
@@ -63,8 +66,10 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		__enable_fpu();
-		__asm__ __volatile__("cfc1\t$0,$31");
+		if (mips_cpu.options & MIPS_CPU_FPU) {
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t$0,$31");
+		}
 		CLEAR_FPU_OWNER();
 	}
 }
@@ -79,7 +84,8 @@
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
 	if (IS_FPU_OWNER()) {
-		save_fp(p);
+		if (mips_cpu.options & MIPS_CPU_FPU)
+			save_fp(p);
 	}
 	/* set up new TSS. */
 	childregs = (struct pt_regs *) childksp - 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/ptrace.c linux-2.4.20/arch/mips64/kernel/ptrace.c
--- linux-2.4.19/arch/mips64/kernel/ptrace.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/ptrace.c	2002-10-04 00:41:14.000000000 +0000
@@ -84,7 +84,7 @@
 
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned int tmp;
 		int copied;
@@ -203,7 +203,7 @@
 			fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
 			if (child->used_math) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) 
+				if (last_task_used_math == child)
 					if (mips_cpu.options & MIPS_CPU_FPU) {
 						__enable_fpu();
 						save_fp(child);
@@ -245,7 +245,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			if (mips_cpu.options & MIPS_CPU_FPU) 
+			if (mips_cpu.options & MIPS_CPU_FPU)
 				child->thread.fpu.hard.control = data;
 			else
 				child->thread.fpu.soft.sr = data;
@@ -273,8 +273,8 @@
 	}
 
 /*
- * 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 
+ * 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: {
@@ -355,7 +355,7 @@
 
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -546,8 +546,8 @@
 	}
 
 /*
- * 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 
+ * 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: {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/r4k_fpu.S linux-2.4.20/arch/mips64/kernel/r4k_fpu.S
--- linux-2.4.19/arch/mips64/kernel/r4k_fpu.S	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/r4k_fpu.S	2002-10-04 00:41:09.000000000 +0000
@@ -31,7 +31,7 @@
 
 	.set	noreorder
 	/* Save floating point context */
-LEAF(save_fp_context)
+LEAF(_save_fp_context)
 	mfc0	t1, CP0_STATUS
 	sll	t2, t1,5
 
@@ -79,7 +79,7 @@
 
 	jr	ra
 	 li	v0, 0					# success
-	END(save_fp_context)
+	END(_save_fp_context)
 
 /*
  * Restore FPU state:
@@ -90,7 +90,7 @@
  * frame on the current content of c0_status, not on the content of the
  * stack frame which might have been changed by the user.
  */
-LEAF(restore_fp_context)
+LEAF(_restore_fp_context)
 	mfc0	t1, CP0_STATUS
 	sll	t0, t1,5
 	bgez	t0, 1f
@@ -139,7 +139,7 @@
 	ctc1	t0, fcr31
 	jr	ra
 	 li	v0, 0					# success
-	END(restore_fp_context)
+	END(_restore_fp_context)
 
 	.type	fault@function
 	.ent	fault
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/r4k_genex.S linux-2.4.20/arch/mips64/kernel/r4k_genex.S
--- linux-2.4.19/arch/mips64/kernel/r4k_genex.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/r4k_genex.S	2002-10-04 00:41:10.000000000 +0000
@@ -40,6 +40,9 @@
  */
 	NESTED(except_vec3_r4000, 0, sp)
 	.set	noat
+#if defined(R5432_CP0_INTERRUPT_WAR)
+	mfc0    k0, CP0_INDEX
+#endif
 	mfc0	k1, CP0_CAUSE
 	andi	k1, k1, 0x7c
 	li	k0, 31<<2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/r4k_switch.S linux-2.4.20/arch/mips64/kernel/r4k_switch.S
--- linux-2.4.19/arch/mips64/kernel/r4k_switch.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/r4k_switch.S	2002-10-04 00:41:10.000000000 +0000
@@ -10,7 +10,6 @@
  */
 #include <asm/asm.h>
 #include <asm/cachectl.h>
-#include <asm/current.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
@@ -69,6 +68,7 @@
 	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
@@ -88,11 +88,11 @@
 
 	sll	t0, t0, 5			# load new fp state
 	bgez	t0, 1f
-	 ldc1	$f0, (THREAD_FPU + 0x00)($28)
-	fpu_restore_16odd $28
+	 ldc1	$f0, (THREAD_FPU + 0x00)(a1)
+	fpu_restore_16odd a1
 1:
 	.set	reorder
-	fpu_restore_16even $28, t0		# clobbers t0
+	fpu_restore_16even a1, t0		# clobbers t0
 3:
 	jr	ra
 	END(lazy_fpu_switch)
@@ -119,15 +119,15 @@
 LEAF(restore_fp)
 	mfc0	t0, CP0_STATUS
 	sll	t1, t0, 5
-	bgez	t0, 1f				# 16 register mode?
+	bgez	t1, 1f				# 16 register mode?
 	 nop
 
-	fpu_restore_16odd $28
+	fpu_restore_16odd a0
 1:
-	.set	reorder
-	fpu_restore_16even $28, t0		# clobbers t0
+	fpu_restore_16even a0, t0		# clobbers t0
 
 	jr	ra
+	 ldc1	$f0, (THREAD_FPU + 0x00)(a0)
 	END(restore_fp)
 
 /*
@@ -145,6 +145,7 @@
 	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 	sll	t0, t0, 5
 
 	li	t1, FPU_DEFAULT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/scall_64.S linux-2.4.20/arch/mips64/kernel/scall_64.S
--- linux-2.4.19/arch/mips64/kernel/scall_64.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/scall_64.S	2002-10-04 00:41:11.000000000 +0000
@@ -15,12 +15,7 @@
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/unistd.h>
-
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002	/* tracing system calls */
-
-/* This duplicates the definition from <asm/signal.h> */
-#define SIGILL		4		/* Illegal instruction (ANSI).  */
+#include <asm/offset.h>
 
 #ifndef CONFIG_MIPS32_COMPAT
 #define handle_sys64 handle_sys
@@ -49,7 +44,7 @@
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, trace_a_syscall
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -65,9 +60,10 @@
 
 ret_from_sys_call:
 	mfc0	t0, CP0_STATUS
-	xori	t0, t0, 1
 	ori	t0, t0, 1
+	xori	t0, t0, 1
 	mtc0	t0, CP0_STATUS
+	SSNOP; SSNOP; SSNOP
 
 	ld	t2, TASK_NEED_RESCHED($28)
 	bnez	t2, reschedule
@@ -132,6 +128,7 @@
 	j	ret_from_sys_call
 	END(handle_sys64)
 
+	.align	3
 sys_call_table:
 	PTR	sys_syscall				/* 5000 */
 	PTR	sys_exit
@@ -350,20 +347,20 @@
 	PTR	sys_ni_syscall
 	PTR	sys_gettid				/* 5215 */
 	PTR	sys_readahead
-	PTR	sys_ni_syscall			/* reserved for setxattr */
-	PTR	sys_ni_syscall			/* reserved for lsetxattr */
-	PTR	sys_ni_syscall			/* reserved for fsetxattr */
-	PTR	sys_ni_syscall			/* 5220 res. for getxattr */
-	PTR	sys_ni_syscall			/* reserved for lgetxattr */
-	PTR	sys_ni_syscall			/* reserved for fgetxattr */
-	PTR	sys_ni_syscall			/* reserved for listxattr */
-	PTR	sys_ni_syscall			/* reserved for llistxattr */
-	PTR	sys_ni_syscall			/* 5225 res. for flistxattr */
-	PTR	sys_ni_syscall			/* reserved for removexattr */
-	PTR	sys_ni_syscall			/* reserved for lremovexattr */
-	PTR	sys_ni_syscall			/* reserved for fremovexattr */
+	PTR	sys_setxattr
+	PTR	sys_lsetxattr
+	PTR	sys_fsetxattr
+	PTR	sys_getxattr				/* 5220 */
+	PTR	sys_lgetxattr
+	PTR	sys_fgetxattr
+	PTR	sys_listxattr
+	PTR	sys_llistxattr
+	PTR	sys_flistxattr				/* 5225 */
+	PTR	sys_removexattr
+	PTR	sys_lremovexattr
+	PTR	sys_fremovexattr
 	PTR	sys_tkill, 2
-	PTR	sys_ni_syscall, 0		/* res. for sendfile64 */
+	PTR	sys_ni_syscall, 0		/* 5230 res. for sendfile64 */
 	PTR	sys_ni_syscall, 0		/* res. for futex */
 	PTR	sys_ni_syscall, 0		/* res. for sched_setaffinity */
-	PTR	sys_ni_syscall, 0		/* 4240 res. for sched_getaffinity */
+	PTR	sys_ni_syscall, 0		/* res. for sched_getaffinity */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/scall_o32.S linux-2.4.20/arch/mips64/kernel/scall_o32.S
--- linux-2.4.19/arch/mips64/kernel/scall_o32.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/scall_o32.S	2002-10-04 00:41:13.000000000 +0000
@@ -16,17 +16,12 @@
 #include <linux/errno.h>
 #include <asm/current.h>
 #include <asm/mipsregs.h>
+#include <asm/offset.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/unistd.h>
 #include <asm/sysmips.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002	/* tracing system calls */
-
-/* This duplicates the definition from <asm/signal.h> */
-#define SIGILL		4		/* Illegal instruction (ANSI).  */
-
 /* Highest syscall used of any syscall flavour */
 #define MAX_SYSCALL_NO	__NR_Linux32 + __NR_Linux32_syscalls
 
@@ -61,7 +56,7 @@
 
 stack_done:
 		ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
+		andi	t0, _PT_TRACESYS
 		bnez	t0, trace_a_syscall
 
 		jalr	t2			# Do The Real Thing (TM)
@@ -80,6 +75,7 @@
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
+		SSNOP; SSNOP; SSNOP
 
 		ld	t2, TASK_NEED_RESCHED($28)
 		bnez	t2, o32_reschedule
@@ -156,16 +152,20 @@
 	bltz	t0, bad_stack		# -> sp is bad
 
 	ld	t0, PT_R29(sp)		# get old user stack pointer
-	la	t1, 3f			# copy 1 to 2 arguments
+	PTR_LA	t1, 3f			# copy 1 to 2 arguments
 	sll	t3, t3, 2
 	subu	t1, t3
 	jr	t1
 
 	/* Ok, copy the args from the luser stack to the kernel stack */
+	.set	push
+	.set	noreorder
+	.set	nomacro
 1:	lw	a5, 20(t0)		# argument #6 from usp
 2:	lw	a4, 16(t0)		# argument #5 from usp
+3:	.set	pop
 
-3:	j	stack_done		# go back
+	j	stack_done		# go back
 
 	.section __ex_table,"a"
 	PTR	1b, bad_stack
@@ -222,7 +222,7 @@
 
 	/* Success, so skip usual error handling garbage.  */
 	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, 1f
 	b	o32_ret_from_sys_call
 
@@ -245,8 +245,74 @@
 	j	sys_sysmips
 	END(sys32_sysmips)
 
+	LEAF(sys32_syscall)
+	ld	t0, PT_R29(sp)		# user sp
+
+	sltu	v0, a0, __NR_Linux + __NR_Linux_syscalls + 1
+	beqz	v0, enosys
+
+	dsll	v0, a0, 3
+	dla	v1, sys32_syscall
+	ld	t2, (sys_call_table - (__NR_Linux32 * 8))(v0)	# function pointer
+	lbu	t3, (sys_narg_table - __NR_Linux32)(a0)	# number of arguments
+
+	li	v0, -EINVAL
+	beq	t2, v1, out		# do not recurse
+
+	beqz	t2, enosys		# null function pointer?
+
+	andi	v0, t0, 0x3		# unaligned stack pointer?
+	bnez	v0, sigsegv
+
+	daddiu	v0, t0, 16		# v0 = usp + 16
+	daddu	t1, v0, 12		# 3 32-bit arguments
+	ld	v1, THREAD_CURDS($28)
+	or	v0, v0, t1
+	and	v1, v1, v0
+	bltz	v1, efault
+
+	move	a0, a1			# shift argument registers
+	move	a1, a2
+	move	a2, a3
+
+1:	lw	a3, 16(t0)
+2:	lw	t3, 20(t0)
+3:	lw	t1, 24(t0)
+
+	.section __ex_table,"a"
+	PTR	1b, efault
+	PTR	2b, efault
+	PTR	3b, efault
+	.previous
+
+	sw	t3, 16(sp)		# put into new stackframe
+	sw	t1, 20(sp)
+
+	bnez	t1, 1f			# zero arguments?
+	daddu	a0, sp, 32		# then pass sp in a0
+1:
+
+	sw	t3, 16(sp)
+	sw	v1, 20(sp)
+	jr	t2
+	/* Unreached */
+
+enosys:	li	v0, -ENOSYS
+	b	out
+
+sigsegv:
+	li	a0, _SIGSEGV
+	move	a1, $28
+	jal	force_sig
+	/* Fall through */
+
+efault:	li	v0, -EFAULT
+
+out:	jr	ra
+	END(sys32_syscall)
+
 	.macro	syscalltable
-	sys	sys_syscall	0			/* 4000 */
+	sys	sys32_syscall	0			/* 4000 */
 	sys	sys_exit	1
 	sys	sys_fork	0
 	sys	sys_read	3
@@ -453,7 +519,7 @@
 	sys	sys_capget	2
 	sys	sys_capset	2			/* 4205 */
 	sys	sys32_sigaltstack	0
-	sys	sys_sendfile	3
+	sys	sys_sendfile	4
 	sys	sys_ni_syscall	0
 	sys	sys_ni_syscall	0
 	sys	sys_mmap2	6			/* 4210 */
@@ -470,18 +536,18 @@
 	sys	sys_ni_syscall	0
 	sys	sys_gettid	0
 	sys	sys32_readahead	5
-	sys	sys_ni_syscall	0		/* reserved for setxattr */
-	sys	sys_ni_syscall	0		/* 4225 res. for lsetxattr */
-	sys	sys_ni_syscall	0		/* reserved for fsetxattr */
-	sys	sys_ni_syscall	0		/* reserved for getxattr */
-	sys	sys_ni_syscall	0		/* reserved for lgetxattr */
-	sys	sys_ni_syscall	0		/* reserved for fgetxattr */
-	sys	sys_ni_syscall	0		/* 4230 res. for listxattr */
-	sys	sys_ni_syscall	0		/* reserved for llistxattr */
-	sys	sys_ni_syscall	0		/* reserved for flistxattr */
-	sys	sys_ni_syscall	0		/* reserved for removexattr */
-	sys	sys_ni_syscall	0		/* reserved for lremovexattr */
-	sys	sys_ni_syscall	0		/* 4235 res. for fremovexattr */
+	sys	sys_setxattr	5
+	sys	sys_lsetxattr	5		/* 4225 */
+	sys	sys_fsetxattr	5
+	sys	sys_getxattr	4
+	sys	sys_lgetxattr	4
+	sys	sys_fgetxattr	4
+	sys	sys_listxattr	3		/* 4230 */
+	sys	sys_llistxattr	3
+	sys	sys_flistxattr	3
+	sys	sys_removexattr	2
+	sys	sys_lremovexattr 2
+	sys	sys_fremovexattr 2		/* 4235 */
 	sys	sys_tkill, 2
 	sys	sys_ni_syscall, 0		/* res. for sendfile64 */
 	sys	sys_ni_syscall, 0		/* res. for futex */
@@ -494,6 +560,7 @@
 	PTR	\function
 	.endm
 
+	.align	3
 sys_call_table:
 	syscalltable
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/setup.c linux-2.4.20/arch/mips64/kernel/setup.c
--- linux-2.4.19/arch/mips64/kernel/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/setup.c	2002-10-04 00:41:09.000000000 +0000
@@ -43,15 +43,6 @@
 struct cpuinfo_mips cpu_data[1];
 #endif
 
-/*
- * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
- * the implementation of the "wait" feature differs between CPU families. This
- * points to the function that implements CPU specific wait. 
- * The wait instruction stops the pipeline and reduces the power consumption of
- * the CPU very much.
- */
-void (*cpu_wait)(void) = NULL;
-
 #ifdef CONFIG_VT
 struct screen_info screen_info;
 #endif
@@ -66,7 +57,9 @@
 /*
  * Set if box has EISA slots.
  */
+#ifdef CONFIG_EISA
 int EISA_bus = 0;
+#endif
 
 #ifdef CONFIG_BLK_DEV_FD
 extern struct fd_ops no_fd_ops;
@@ -113,387 +106,19 @@
 extern void ip27_setup(void);
 extern void ip32_setup(void);
 
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.
+ */
+unsigned long isa_slot_offset;
+EXPORT_SYMBOL(isa_slot_offset);
+
 extern void sgi_sysinit(void);
 extern void SetUpBootInfo(void);
 extern void load_mmu(void);
 extern ATTRIB_NORET asmlinkage void start_kernel(void);
 extern void prom_init(int, char **, char **, int *);
 
-static inline void check_wait(void)
-{
-	printk("Checking for 'wait' instruction... ");
-	switch(mips_cpu.cputype) {
-	case CPU_R3081:
-	case CPU_R3081E:
-		cpu_wait = r3081_wait;
-		printk(" available.\n");
-		break;
-	case CPU_TX3927:
-	case CPU_TX39XX:
-		cpu_wait = r39xx_wait;
-		printk(" available.\n");
-		break;
-	case CPU_R4200: 
-/*	case CPU_R4300: */
-	case CPU_R4600: 
-	case CPU_R4640: 
-	case CPU_R4650: 
-	case CPU_R4700: 
-	case CPU_R5000: 
-	case CPU_NEVADA:
-	case CPU_RM7000:
-	case CPU_TX49XX:
-	case CPU_4KC:
-	case CPU_4KEC:
-	case CPU_4KSC:
-	case CPU_5KC:
-/*	case CPU_20KC:*/
-		cpu_wait = r4k_wait;
-		printk(" available.\n");
-		break;
-	default:
-		printk(" unavailable.\n");
-		break;
-	}
-}
-
-void __init check_bugs(void)
-{
-	check_wait();
-}
-
-/*
- * Probe whether cpu has config register by trying to play with
- * alternate cache bit and see whether it matters.
- * It's used by cpu_probe to distinguish between R3000A and R3081.
- */
-static inline int cpu_has_confreg(void)
-{
-#ifdef CONFIG_CPU_R3000
-	extern unsigned long r3k_cache_size(unsigned long);
-	unsigned long size1, size2;
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-
-	size1 = r3k_cache_size(ST0_ISC);
-	write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
-	size2 = r3k_cache_size(ST0_ISC);
-	write_32bit_cp0_register(CP0_CONF, cfg);
-	return size1 != size2;
-#else
-	return 0;
-#endif
-}
-
-/*
- * Get the FPU Implementation/Revision.
- */
-static inline unsigned long cpu_get_fpu_id(void)
-{
-	unsigned long tmp, fpu_id;
-
-	tmp = read_32bit_cp0_register(CP0_STATUS);
-	__enable_fpu();
-	fpu_id = read_32bit_cp1_register(CP1_REVISION);
-	write_32bit_cp0_register(CP0_STATUS, tmp);
-	return fpu_id;
-}
-
-/* declaration of the global struct */
-struct mips_cpu mips_cpu = {
-    processor_id:	PRID_IMP_UNKNOWN,
-    fpu_id:		FPIR_IMP_NONE,
-    cputype:		CPU_UNKNOWN
-};
-
-#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
-                | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
-
-static inline void cpu_probe(void)
-{
-#ifdef CONFIG_CPU_MIPS32
-	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
-	unsigned long config1;
-
-        if (config0 & (1 << 31)) {
-		/* MIPS32 compliant CPU. Read Config 1 register. */
-		mips_cpu.isa_level = MIPS_CPU_ISA_M32;
-		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-			MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC;
-		config1 = read_mips32_cp0_config1();
-		if (config1 & (1 << 3))
-			mips_cpu.options |= MIPS_CPU_WATCH;
-		if (config1 & (1 << 2))
-			mips_cpu.options |= MIPS_CPU_MIPS16;
-		if (config1 & (1 << 1))
-			mips_cpu.options |= MIPS_CPU_EJTAG;
-		if (config1 & 1)
-			mips_cpu.options |= MIPS_CPU_FPU;
-		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
-	}
-#endif
-	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
-	switch (mips_cpu.processor_id & 0xff0000) {
-	case PRID_COMP_LEGACY:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_R2000:
-			mips_cpu.cputype = CPU_R2000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R3000:
-			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
-				if (cpu_has_confreg())
-					mips_cpu.cputype = CPU_R3081E;
-				else
-					mips_cpu.cputype = CPU_R3000A;
-			else
-				mips_cpu.cputype = CPU_R3000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R4000:
-			if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
-				mips_cpu.cputype = CPU_R4400SC;
-			else
-				mips_cpu.cputype = CPU_R4000SC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH |
-			                   MIPS_CPU_VCE;
-			mips_cpu.tlbsize = 48;
-			break;
-                case PRID_IMP_VR41XX:
-                        mips_cpu.cputype = CPU_VR41XX;
-                        mips_cpu.isa_level = MIPS_CPU_ISA_III;
-                        mips_cpu.options = R4K_OPTS;
-                        mips_cpu.tlbsize = 32;
-                        break;
-		case PRID_IMP_R4300:
-			mips_cpu.cputype = CPU_R4300;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_R4600:
-			mips_cpu.cputype = CPU_R4600;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 48;
-			break;
-		#if 0
- 		case PRID_IMP_R4650:
-			/*
-			 * This processor doesn't have an MMU, so it's not
-			 * "real easy" to run Linux on it. It is left purely
-			 * for documentation.  Commented out because it shares
-			 * it's c0_prid id number with the TX3900.
-			 */
-	 		mips_cpu.cputype = CPU_R4650;
-		 	mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
-		        mips_cpu.tlbsize = 48;
-			break;
-		#endif
-		case PRID_IMP_TX39:
-			mips_cpu.isa_level = MIPS_CPU_ISA_I;
-			mips_cpu.options = MIPS_CPU_TLB;
-
-			if ((mips_cpu.processor_id & 0xf0) ==
-			    (PRID_REV_TX3927 & 0xf0)) {
-				mips_cpu.cputype = CPU_TX3927;
-				mips_cpu.tlbsize = 64;
-				mips_cpu.icache.ways = 2;
-				mips_cpu.dcache.ways = 2;
-			} else {
-				switch (mips_cpu.processor_id & 0xff) {
-				case PRID_REV_TX3912:
-					mips_cpu.cputype = CPU_TX3912;
-					mips_cpu.tlbsize = 32;
-					break;
-				case PRID_REV_TX3922:
-					mips_cpu.cputype = CPU_TX3922;
-					mips_cpu.tlbsize = 64;
-					break;
-				default:
-					mips_cpu.cputype = CPU_UNKNOWN;
-					break;
-				}
-			}
-			break;
-		case PRID_IMP_R4700:
-			mips_cpu.cputype = CPU_R4700;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_TX49:
-			mips_cpu.cputype = CPU_TX49XX;
-			mips_cpu.isa_level = MIPS_CPU_ISA_III;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			mips_cpu.icache.ways = 4;
-			mips_cpu.dcache.ways = 4;
-			break;
-		case PRID_IMP_R5000:
-			mips_cpu.cputype = CPU_R5000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_R5432:
-			mips_cpu.cputype = CPU_R5432;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_R5500:
-			mips_cpu.cputype = CPU_R5500;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 48;
-			break;
-		case PRID_IMP_NEVADA:
-			mips_cpu.cputype = CPU_NEVADA;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR | MIPS_CPU_DIVEC;
-			mips_cpu.tlbsize = 48;
-			mips_cpu.icache.ways = 2;
-			mips_cpu.dcache.ways = 2;
-			break;
-		case PRID_IMP_R6000:
-			mips_cpu.cputype = CPU_R6000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_II;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_R6000A:
-			mips_cpu.cputype = CPU_R6000A;
-			mips_cpu.isa_level = MIPS_CPU_ISA_II;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
-			mips_cpu.tlbsize = 32;
-			break;
-		case PRID_IMP_RM7000:
-			mips_cpu.cputype = CPU_RM7000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU |
-			                   MIPS_CPU_32FPR;
-			/*
-			 * Undocumented RM7000:  Bit 29 in the info register of
-			 * the RM7000 v2.0 indicates if the TLB has 48 or 64
-			 * entries.
-			 *
-			 * 29      1 =>    64 entry JTLB
-			 *         0 =>    48 entry JTLB
-			 */
-			mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48;
-			break;
-		case PRID_IMP_R8000:
-			mips_cpu.cputype = CPU_R8000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR;
-			mips_cpu.tlbsize = 384;      /* has wierd TLB: 3-way x 128 */
-			break;
-		case PRID_IMP_R10000:
-			mips_cpu.cputype = CPU_R10000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
-				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 64;
-			break;
-		case PRID_IMP_R12000:
-			mips_cpu.cputype = CPU_R12000;
-			mips_cpu.isa_level = MIPS_CPU_ISA_IV;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
-				           MIPS_CPU_FPU | MIPS_CPU_32FPR | 
-				           MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
-			mips_cpu.tlbsize = 64;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-#ifdef CONFIG_CPU_MIPS32
-	case PRID_COMP_MIPS:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_4KC:
-			mips_cpu.cputype = CPU_4KC;
-			break;
-		case PRID_IMP_4KEC:
-			mips_cpu.cputype = CPU_4KEC;
-			break;
-		case PRID_IMP_4KSC:
-			mips_cpu.cputype = CPU_4KSC;
-			break;
-		case PRID_IMP_5KC:
-			mips_cpu.cputype = CPU_5KC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-			break;
-		case PRID_IMP_20KC:
-			mips_cpu.cputype = CPU_20KC;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}		
-		break;
-	case PRID_COMP_ALCHEMY:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_AU1_REV1:
-		case PRID_IMP_AU1_REV2:
-			if (mips_cpu.processor_id & 0xff000000)
-				mips_cpu.cputype = CPU_AU1500;
-			else
-				mips_cpu.cputype = CPU_AU1000;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-#endif /* CONFIG_CPU_MIPS32 */
-	case PRID_COMP_SIBYTE:
-		switch (mips_cpu.processor_id & 0xff00) {
-		case PRID_IMP_SB1:
-			mips_cpu.cputype = CPU_SB1;
-			mips_cpu.isa_level = MIPS_CPU_ISA_M64;
-			mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-			                   MIPS_CPU_COUNTER | MIPS_CPU_DIVEC |
-			                   MIPS_CPU_MCHECK;
-#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
-			/* FPU in pass1 is known to have issues. */
-			mips_cpu.options |= MIPS_CPU_FPU;
-#endif
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}
-		break;
-	default:
-		mips_cpu.cputype = CPU_UNKNOWN;
-	}
-	if (mips_cpu.options & MIPS_CPU_FPU)
-		mips_cpu.fpu_id = cpu_get_fpu_id();
-}
-
-static inline void cpu_report(void)
-{
-	printk("CPU revision is: %08x\n", mips_cpu.processor_id);
-	if (mips_cpu.options & MIPS_CPU_FPU)
-		printk("FPU revision is: %08x\n", mips_cpu.fpu_id);
-}
-
 asmlinkage void __init init_arch(int argc, char **argv, char **envp,
 	int *prom_vec)
 {
@@ -547,7 +172,7 @@
 	int i;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		printk(" memory: %08Lx @ %08Lx ",
+		printk(" memory: %016Lx @ %016Lx ",
 			(unsigned long long) boot_mem_map.map[i].size,
 			(unsigned long long) boot_mem_map.map[i].addr);
 		switch (boot_mem_map.map[i].type) {
@@ -745,6 +370,9 @@
 #ifdef CONFIG_SIBYTE_SWARM
 	swarm_setup();
 #endif
+#ifdef CONFIG_MIPS_MALTA
+	malta_setup();
+#endif
 
 	strncpy(command_line, arcs_cmdline, CL_SIZE);
 	memcpy(saved_command_line, command_line, CL_SIZE);
@@ -759,25 +387,6 @@
 	paging_init();
 }
 
-void r3081_wait(void) 
-{
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
-}
-
-void r39xx_wait(void)
-{
-	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
-	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
-}
-
-void r4k_wait(void)
-{
-	__asm__(".set\tmips3\n\t"
-		"wait\n\t"
-		".set\tmips0");
-}
-
 int __init fpu_disable(char *s)
 {
 	mips_cpu.options &= ~MIPS_CPU_FPU;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/signal.c linux-2.4.20/arch/mips64/kernel/signal.c
--- linux-2.4.19/arch/mips64/kernel/signal.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/signal.c	2002-10-04 00:41:14.000000000 +0000
@@ -32,8 +32,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern asmlinkage int save_fp_context(struct sigcontext *sc);
-extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
 
 extern asmlinkage void syscall_trace(void);
 
@@ -72,35 +72,6 @@
 	}
 }
 
-static inline int store_fp_context(struct sigcontext *sc)
-{
-	unsigned int fcr0;
-	int err = 0;
-
-	err |= __copy_to_user(&sc->sc_fpregs[0], 
-		&current->thread.fpu.hard.fp_regs[0], NUM_FPU_REGS * 
-						sizeof(unsigned long));
-	err |= __copy_to_user(&sc->sc_fpc_csr, &current->thread.fpu.hard.control,
-						sizeof(unsigned int));
-	__asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0));
-	err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int));
-
-	return err;
-}
-
-static inline int refill_fp_context(struct sigcontext *sc)
-{
-	int err = 0;
-
-	if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
-		return -EFAULT;
-	err |= __copy_from_user(&current->thread.fpu.hard.fp_regs[0], 
-			&sc->sc_fpregs[0], NUM_FPU_REGS * sizeof(unsigned long));
-	err |= __copy_from_user(&current->thread.fpu.hard.control, &sc->sc_fpc_csr,
-							sizeof(unsigned int));
-	return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -165,7 +136,7 @@
 	}
 }
 
-asmlinkage int 
+asmlinkage int
 sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
 {
 	struct k_sigaction new_ka, old_ka;
@@ -214,6 +185,54 @@
 	return do_sigaltstack(uss, uoss, usp);
 }
 
+static inline int restore_thread_fp_context(struct sigcontext *sc)
+{
+     u64 *pfreg = &current->thread.fpu.soft.regs[0];
+     int err = 0;
+
+     /*
+      * Copy all 32 64-bit values.
+      */
+
+#define restore_fpr(i)                          \
+     do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+     restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3);
+     restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7);
+     restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11);
+     restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15);
+     restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19);
+     restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23);
+     restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27);
+     restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31);
+
+     err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+     return err;
+}
+
+static inline int save_thread_fp_context(struct sigcontext *sc)
+{
+     u64 *pfreg = &current->thread.fpu.soft.regs[0];
+     int err = 0;
+
+#define save_fpr(i)                                     \
+     do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+     save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3);
+     save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7);
+     save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11);
+     save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15);
+     save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19);
+     save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23);
+     save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27);
+     save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31);
+
+     err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+     return err;
+}
+
 asmlinkage int
 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
@@ -241,15 +260,24 @@
 #undef restore_gp_reg
 
 	err |= __get_user(owned_fp, &sc->sc_ownedfp);
+	err |= __get_user(current->used_math, &sc->sc_used_math);
+
 	if (owned_fp) {
-		if (IS_FPU_OWNER()) {
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		current->used_math = 1;
-		err |= refill_fp_context(sc);
+		err |= restore_fp_context(sc);
+		goto out;
+	}
+
+	if (IS_FPU_OWNER()) {
+		/* Signal handler acquired FPU - give it back */
+		CLEAR_FPU_OWNER();
+		regs->cp0_status &= ~ST0_CU1;
+	}
+	if (current->used_math) {
+		/* Undo possible contamination of thread state */
+		err |= restore_thread_fp_context(sc);
 	}
 
+out:
 	return err;
 }
 
@@ -347,9 +375,11 @@
 static int inline setup_sigcontext(struct pt_regs *regs,
 				   struct sigcontext *sc)
 {
+	int owned_fp;
 	int err = 0;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
 #define save_gp_reg(i) do {						\
 	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
@@ -370,20 +400,27 @@
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
-	if (current->used_math) {	/* fp is active.  */
-		if (IS_FPU_OWNER()) {
-			lazy_fpu_switch(current, 0);
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		err |= __put_user(1, &sc->sc_ownedfp);
-		err |= store_fp_context(sc);
-		current->used_math = 0;
-	} else {
-		err |= __put_user(0, &sc->sc_ownedfp);
+	owned_fp = IS_FPU_OWNER();
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(current->used_math, &sc->sc_used_math);
+
+	if (!current->used_math)
+		goto out;
+
+	/* There exists FP thread state that may be trashed by signal */
+	if (owned_fp) {
+		/* fp is active.  Save context from FPU */
+		err |= save_fp_context(sc);
+		goto out;
 	}
-	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
+	 */
+	err |= save_thread_fp_context(sc);
+
+out:
 	return err;
 }
 
@@ -398,6 +435,13 @@
 	/* Default to using normal stack */
 	sp = regs->regs[29];
 
+	/*
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
 		sp = current->sas_ss_sp + current->sas_ss_size;
@@ -456,8 +500,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->sf_code);
 #endif
         return;
 
@@ -532,8 +577,9 @@
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
-	       current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
+	       current->comm, current->pid,
+	       frame, regs->cp0_epc, frame->rs_code);
 #endif
 	return;
 
@@ -661,7 +707,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/signal32.c linux-2.4.20/arch/mips64/kernel/signal32.c
--- linux-2.4.19/arch/mips64/kernel/signal32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/signal32.c	2002-10-04 00:41:20.000000000 +0000
@@ -31,8 +31,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-extern asmlinkage int save_fp_context(struct sigcontext *sc);
-extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
 
 extern asmlinkage void syscall_trace(void);
 
@@ -63,38 +63,6 @@
 	int ss_flags;
 } stack32_t;
 
-
-static inline int store_fp_context(struct sigcontext *sc)
-{
-	unsigned int fcr0;
-	int err = 0;
-
-	err |= __copy_to_user(&sc->sc_fpregs[0],
-			      &current->thread.fpu.hard.fp_regs[0],
-			      NUM_FPU_REGS * sizeof(unsigned long));
-	err |= __copy_to_user(&sc->sc_fpc_csr,
-			      &current->thread.fpu.hard.control,
-			      sizeof(unsigned int));
-	__asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0));
-	err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int));
-
-	return err;
-}
-
-static inline int refill_fp_context(struct sigcontext *sc)
-{
-	int err = 0;
-
-	if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
-		return -EFAULT;
-	err |= __copy_from_user(&current->thread.fpu.hard.fp_regs[0],
-				&sc->sc_fpregs[0],
-				NUM_FPU_REGS * sizeof(unsigned long));
-	err |= __copy_from_user(&current->thread.fpu.hard.control,
-				&sc->sc_fpc_csr, sizeof(unsigned int));
-	return err;
-}
-
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
@@ -289,6 +257,54 @@
 	return ret;
 }
 
+static inline int restore_thread_fp_context(struct sigcontext *sc)
+{
+	u64 *pfreg = &current->thread.fpu.soft.regs[0];
+	int err = 0;
+
+	/*
+	 * Copy all 32 64-bit values.
+	 */
+
+#define restore_fpr(i) 						\
+	do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+	restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3);
+	restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7);
+	restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11);
+	restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15);
+	restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19);
+	restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23);
+	restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27);
+	restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31);
+
+	err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+	return err;
+}
+
+static inline int save_thread_fp_context(struct sigcontext *sc)
+{
+	u64 *pfreg = &current->thread.fpu.soft.regs[0];
+	int err = 0;
+
+#define save_fpr(i) 							\
+	do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0)
+
+	save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3);
+	save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7);
+	save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11);
+	save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15);
+	save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19);
+	save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23);
+	save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27);
+	save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31);
+
+	err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
+
+	return err;
+}
+
 static asmlinkage int restore_sigcontext(struct pt_regs *regs,
 					 struct sigcontext *sc)
 {
@@ -316,15 +332,24 @@
 #undef restore_gp_reg
 
 	err |= __get_user(owned_fp, &sc->sc_ownedfp);
+	err |= __get_user(current->used_math, &sc->sc_used_math);
+
 	if (owned_fp) {
-		if (IS_FPU_OWNER()) {
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		current->used_math = 1;
-		err |= refill_fp_context(sc);
+		err |= restore_fp_context(sc);
+		goto out;
+	}
+
+	if (IS_FPU_OWNER()) {
+		/* Signal handler acquired FPU - give it back */
+		CLEAR_FPU_OWNER();
+		regs->cp0_status &= ~ST0_CU1;
+	}
+	if (current->used_math) {
+		/* Undo possible contamination of thread state */
+		err |= restore_thread_fp_context(sc);
 	}
 
+out:
 	return err;
 }
 
@@ -335,13 +360,55 @@
 	sigset_t sf_mask;
 };
 
-struct rt_sigframe {
+struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_code[2];			/* signal trampoline */
-	struct siginfo rs_info;
+	struct siginfo32 rs_info;
 	struct ucontext rs_uc;
 };
 
+static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+{
+	int err;
+
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+		return -EFAULT;
+
+	/* If you change siginfo_t structure, please be sure
+	   this code is fixed accordingly.
+	   It should never copy any pad contained in the structure
+	   to avoid security leaks, but must copy the generic
+	   3 ints plus the relevant union member.
+	   This routine must convert siginfo from 64bit to 32bit as well
+	   at the same time.  */
+	err = __put_user(from->si_signo, &to->si_signo);
+	err |= __put_user(from->si_errno, &to->si_errno);
+	err |= __put_user((short)from->si_code, &to->si_code);
+	if (from->si_code < 0)
+		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+	else {
+		switch (from->si_code >> 16) {
+		case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
+		default:
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		case __SI_FAULT >> 16:
+			err |= __put_user((long)from->si_addr, &to->si_addr);
+			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band);
+			err |= __put_user(from->si_fd, &to->si_fd);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+	}
+	return err;
+}
+
 asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct sigframe *frame;
@@ -369,7 +436,7 @@
 		syscall_trace();
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\to32_ret_from_sys_call"
+		"j\tret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -380,11 +447,11 @@
 
 asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe32 *frame;
 	sigset_t set;
 	stack_t st;
 
-	frame = (struct rt_sigframe *) regs.regs[29];
+	frame = (struct rt_sigframe32 *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -410,7 +477,7 @@
 	 */
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\to32_ret_from_sys_call"
+		"j\tret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -422,9 +489,11 @@
 static int inline setup_sigcontext(struct pt_regs *regs,
 				   struct sigcontext *sc)
 {
+	int owned_fp;
 	int err = 0;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
 #define save_gp_reg(i) {						\
 	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
@@ -445,20 +514,27 @@
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
-	if (current->used_math) {	/* fp is active.  */
-		if (IS_FPU_OWNER()) {
-			lazy_fpu_switch(current, 0);
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		err |= __put_user(1, &sc->sc_ownedfp);
-		err |= store_fp_context(sc);
-		current->used_math = 0;
-	} else {
-		err |= __put_user(0, &sc->sc_ownedfp);
+	owned_fp = IS_FPU_OWNER();
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(current->used_math, &sc->sc_used_math);
+
+	if (!current->used_math)
+		goto out;
+
+	/* There exists FP thread state that may be trashed by signal */
+	if (owned_fp) {
+		/* fp is active.  Save context from FPU */
+		err |= save_fp_context(sc);
+		goto out;
 	}
-	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
+	 */
+	err |= save_thread_fp_context(sc);
+
+out:
 	return err;
 }
 
@@ -473,6 +549,13 @@
 	/* Default to using normal stack */
 	sp = regs->regs[29];
 
+	/*
+ 	 * FPU emulator may have it's own trampoline active just
+ 	 * above the user stack, 16-bytes before the next lowest
+ 	 * 16 byte boundary.  Try to avoid trashing it.
+ 	 */
+ 	sp -= 32;
+
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
 		sp = current->sas_ss_sp + current->sas_ss_size;
@@ -547,7 +630,7 @@
 				  struct pt_regs *regs, int signr,
 				  sigset_t *set, siginfo_t *info)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe32 *frame;
 	int err = 0;
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -572,8 +655,8 @@
 		flush_cache_sigtramp((unsigned long) frame->rs_code);
 	}
 
-	/* Create siginfo.  */
-	err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
+	/* Convert (siginfo_t -> siginfo_t32) and copy to user. */
+	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -598,7 +681,7 @@
 	 *   a2 = pointer to ucontext
 	 *
 	 * $25 and c0_epc point to the signal handler, $29 points to
-	 * the struct rt_sigframe.
+	 * the struct rt_sigframe32.
 	 */
 	regs->regs[ 4] = signr;
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
@@ -784,7 +867,7 @@
 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set,
 						old_sigset_t *oset);
 
-asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, 
+asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set,
 				 old_sigset_t32 *oset)
 {
 	old_sigset_t s;
@@ -878,7 +961,7 @@
 
 	if (set && get_sigset(&new_set, set))
 		return -EFAULT;
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
 				 oset ? &old_set : NULL, sigsetsize);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/smp.c linux-2.4.20/arch/mips64/kernel/smp.c
--- linux-2.4.19/arch/mips64/kernel/smp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/smp.c	2002-10-04 00:41:12.000000000 +0000
@@ -1,13 +1,25 @@
 /*
- * 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.
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
  * Copyright (C) 2000, 2001 Kanoj Sarcar
  * Copyright (C) 2000, 2001 Ralf Baechle
  * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001 Broadcom Corporation
  */
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -17,7 +29,6 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
-#include <linux/cache.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -26,14 +37,13 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
-#include <asm/irq.h>
+#include <asm/smp.h>
 
 /* The 'big kernel lock' */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 int smp_threads_ready;	/* Not used */
 atomic_t smp_commenced = ATOMIC_INIT(0);
 struct cpuinfo_mips cpu_data[NR_CPUS];
-void (*volatile smp_cpu0_finalize)(void);
 
 // static atomic_t cpus_booted = ATOMIC_INIT(0);
 atomic_t cpus_booted = ATOMIC_INIT(0);
@@ -44,8 +54,36 @@
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
 
-// static void smp_tune_scheduling (void)
-void smp_tune_scheduling (void)
+/* These are defined by the board-specific code. */
+
+/*
+ * Cause the function described by call_data to be executed on the passed
+ * cpu.  When the function has finished, increment the finished field of
+ * call_data.
+ */
+void core_send_ipi(int cpu, unsigned int action);
+
+/*
+ * Clear all undefined state in the cpu, set up sp and gp to the passed
+ * values, and kick the cpu into smp_bootstrap();
+ */
+void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+
+/*
+ *  After we've done initial boot, this function is called to allow the
+ *  board code to clean up state, if needed
+ */
+void prom_init_secondary(void);
+
+/*
+ * Do whatever setup needs to be done for SMP at the board level.  Return
+ * the number of cpus in the system, including this one
+ */
+int prom_setup_smp(void);
+
+void prom_smp_finish(void);
+
+static void smp_tune_scheduling(void)
 {
 }
 
@@ -100,12 +138,6 @@
 	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
 }
 
-/* Not really SMP stuff ... */
-int setup_profiling_timer(unsigned int multiplier)
-{
-	return 0;
-}
-
 static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
 
 struct call_data_struct *call_data;
@@ -121,8 +153,7 @@
  * Does not return until remote CPUs are nearly ready to execute <func>
  * or are or have executed.
  */
-
-int smp_call_function (void (*func) (void *info), void *info, int retry, 
+int smp_call_function (void (*func) (void *info), void *info, int retry,
 								int wait)
 {
 	struct call_data_struct data;
@@ -188,21 +219,32 @@
 
 static void stop_this_cpu(void *dummy)
 {
-	int cpu = smp_processor_id();
-	if (cpu)
-		for (;;);		/* XXX Use halt like i386 */
-
-	/* XXXKW this isn't quite there yet */
-	while (!smp_cpu0_finalize) ;
-	smp_cpu0_finalize();
+	/*
+	 * Remove this CPU:
+	 */
+	clear_bit(smp_processor_id(), &cpu_online_map);
+	/* May need to service _machine_restart IPI */
+	__sti();
+	/* XXXKW wait if available? */
+	for (;;);
 }
 
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	/*
+	 * Fix me: this prevents future IPIs, for example that would
+	 * cause a restart to happen on CPU0.
+	 */
 	smp_num_cpus = 1;
 }
 
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return 0;
+}
+
 static void flush_tlb_all_ipi(void *info)
 {
 	local_flush_tlb_all();
@@ -220,11 +262,11 @@
 }
 
 /*
- * The following tlb flush calls are invoked when old translations are 
+ * The following tlb flush calls are invoked when old translations are
  * being torn down, or pte attributes are changing. For single threaded
  * address spaces, a new context is obtained on the current cpu, and tlb
  * context on other cpus are invalidated to force a new context allocation
- * at switch_mm time, should the mm ever be used on other cpus. For 
+ * at switch_mm time, should the mm ever be used on other cpus. For
  * multithreaded address spaces, intercpu interrupts have to be sent.
  * Another case where intercpu interrupts are required is when the target
  * mm might be active on another cpu (eg debuggers doing the flushes on
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/softfp.S linux-2.4.20/arch/mips64/kernel/softfp.S
--- linux-2.4.19/arch/mips64/kernel/softfp.S	2000-07-10 05:18:16.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/softfp.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,666 +0,0 @@
-/*
- * 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) 1998, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
- *
- * For now it's just a crude hack good enough to run certain fp programs like
- * Mozilla.
- * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ...
- */
-#include <asm/regdef.h>
-#include <asm/asm.h>
-
-#ifndef __KERNEL__
-#define printk printf
-#endif
-
-#define LOCK_KERNEL
-#define UNLOCK_KERNEL
-
-/*
- * This duplicates definitions from <linux/kernel.h>.
- */
-#define KERN_EMERG      "<0>"   /* system is unusable                   */
-#define KERN_ALERT      "<1>"   /* action must be taken immediately     */
-#define KERN_CRIT       "<2>"   /* critical conditions                  */
-#define KERN_ERR        "<3>"   /* error conditions                     */
-#define KERN_WARNING    "<4>"   /* warning conditions                   */
-#define KERN_NOTICE     "<5>"   /* normal but significant condition     */
-#define KERN_INFO       "<6>"   /* informational                        */
-#define KERN_DEBUG      "<7>"   /* debug-level messages                 */
-
-/*
- * This duplicates definitions from <asm/signal.h>
- */
-#define SIGILL           4      /* Illegal instruction (ANSI).  */
-
-/*
- * Definitions about the instruction format
- */
-#define fd_shift	6
-#define fr_shift	21
-#define fs_shift	11
-#define ft_shift	16
-
-/*
- * NaNs as use by the MIPS architecture
- */
-#define S_QNaN		0x7fbfffff
-#define D_QNaN		0x7ff7ffffffffffff
-#define W_QNaN		0x7fffffff
-#define L_QNaN		0x7fffffffffffffff
-
-/*
- * Checking for NaNs
- */
-#define S_is_QNaN(reg,res)						\
-	sll	res, reg, S_F_size - S_F_bits
-#define D_is_QNaN(reg1,reg2,res)					\
-	sll	res, reg1, (D_F_size - 32) - (D_F_bits - 32);		\
-	or	res, reg2
-
-/*
- * Checking for Denorms
- */
-#define S_is_Denorm(reg,res)						\
-	li	res, 1 << (S_F_bits - 1);				\
-	and	reg, res
-
-/*
- * Some constants that define the properties of single precission numbers.
- */
-#define S_M_prec	24
-#define S_E_max		127
-#define S_E_min		-126
-#define S_E_bias	127
-#define S_E_bits	8
-#define S_F_bits	23
-#define S_F_size	32
-
-/* Set temp0, if exponent of reg is S_E_max + 1.  */
-#define S_is_E_max(reg,temp0,temp1)					\
-	li	temp0, (S_E_max + 1 + S_E_bias) << S_F_bits;		\
-	and	temp1, temp0, reg;					\
-	seq	temp0, temp1			/* temp0 != 0 if NaN */
-
-/* Clear temp0, if exponent of reg is S_E_min - 1.  */
-#define S_is_E_min(reg,temp0)						\
-	li	temp0, (S_E_min - 1 + S_E_bias) << S_F_bits;		\
-	and	temp0, reg	/* temp0 == 0 if denorm or zero */
-
-/* Set temp0 if reg is a NaN assuming S_is_E_max is true  */
-#define S_get_F(reg,temp0)						\
-	li	temp0, (1 << S_F_bits) - 1;				\
-	and	temp0, reg			/* temp0 != 0 if NaN */
-
-/* Set res if fraction of reg is != 0.  */
-#define S_is_Inf(reg,res)						\
-	li	res, (1 << S_F_bits) - 1;				\
-	and	res, reg			/* temp0 == 0 if Inf */
-
-
-/*
- * Some constants that define the properties of double precission numbers.
- */
-#define D_M_prec	53
-#define D_E_max		1023
-#define D_E_min		-1022
-#define D_E_bias	1023
-#define D_E_bits	8
-#define D_F_bits	52
-#define D_F_size	64
-
-/* Set temp0, if exponent of reg1/reg2 is D_E_max.  */
-#define D_is_E_max(reg1,reg2,temp0,temp1)				\
-	li	temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32);	\
-	and	temp1, temp0, reg1;					\
-	seq	temp0, temp1			/* temp0 != 0 if NaN */
-
-/* Clear temp0, if exponent of reg is D_E_min.  */
-#define D_is_E_min(reg1,reg2,res)					\
-	li	res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32);	\
-	and	res, reg1	/* temp0 == 0 if NaN or zero */
-
-/* Set res if reg is a NaN assuming S_is_E_max is true  */
-#define D_get_F(reg1,reg2,res)						\
-	li	res, (1 << (D_F_bits - 32)) - 1;			\
-	and	res, reg1			/* temp0 != 0 if NaN */
-
-/* Set temp0 if reg1/reg2 is a NaN  */
-#define D_is_NAN(reg1,reg2,temp0,temp1)					\
-	li	temp0, (1 << (D_F_bits - 32) - 1;			\
-	and	temp0, reg1;						\
-	or	temp0, reg2;						\
-	sne	temp0, zero, temp0		/* temp0 != 0 if NaN */
-
-/* Set res if fraction of reg1/reg2 is != 0.  */
-#define D_is_Inf(reg1,reg2,res)						\
-	li	res, (1 << (D_F_bits - 32)) - 1;			\
-	and	res, reg1;						\
-	or	res, reg2			/* temp0 == 0 if Inf */
-
-/* Complain about yet unhandled instruction.  */
-#define BITCH(insn)							\
-insn:	LOCK_KERNEL;							\
-	la	a1, 8f;							\
-	TEXT(#insn);							\
-	la	a0, nosim;						\
-	jal	printk;							\
-	UNLOCK_KERNEL;							\
-	j	done
-
-	.data
-nosim: .asciz	KERN_DEBUG "Don't know how to simulate %s instruction\n"
-	.previous
-
-/*
- * When we come here, we've saved some of the integer registers and
- * reenabled interrupts.
- */
-LEAF(simfp)
-	.set	noreorder
-	.cpload	$25
-	.set	reorder
-
-	dsubu	sp, 16
-	.cprestore 20
-	sd	ra, 0(sp)
-
-	/* For now we assume that we get the opcode to simulate passed in as
-	   an argument.  */
-	move	ta0, a0
-
-	/*
-	 * First table lookup using insn[5:0]
-	 */
-	la	ta1, lowtab
-	andi	ta2, ta0, 0x3f
-	sll	ta2, ta2, 3
-	daddu	ta1, ta2
-	ld	ta1, (ta1)
-	jr	ta1
-	END(simfp)
-
-/*
- * We only decode the lower 3 of the 5 bit in the fmt field.  That way we
- * can keep the jump table significantly shorter.
- */
-#define FMT_switch(insn,opc,temp0,temp1)				\
-insn:	srl	temp0, opc, 18;						\
-	andi	temp0, 0x1c;						\
-	la	temp1, insn##.tab;					\
-	daddu	temp0, temp1;						\
-	ld	temp0, (temp0);						\
-	jr	temp0;							\
-									\
-	.data;								\
-insn##.tab:								\
-	.dword	insn##.s, insn##.d, unimp, unimp;			\
-	.dword	insn##.w, insn##.l, unimp, unimp;			\
-	.previous
-
-	BITCH(add)
-	BITCH(sub)
-	BITCH(mul)
-	BITCH(div)
-	BITCH(sqrt)
-	BITCH(abs)
-	BITCH(mov)
-	BITCH(neg)
-	BITCH(round.l)
-	BITCH(trunc.l)
-	BITCH(ceil.l)
-	BITCH(floor.l)
-	BITCH(round.w)
-	BITCH(trunc.w)
-	BITCH(ceil.w)
-	BITCH(floor.w)
-	BITCH(cvt.s)
-	BITCH(cvt.d)
-
-/* ------------------------------------------------------------------------ */
-
-FMT_switch(cvt.w,ta0,ta1,ta2)
-
-/* Convert a single fp to a fixed point integer.  */
-cvt.w.s:
-	srl	ta1, ta0, fs_shift	# Get source register
-	andi	ta1, 31
-	jal	s_get_fpreg
-
-	S_is_E_max(ta1,ta2,ta3)
-	beqz	ta2, 3f
-	/* Might be a NaN or Inf.  */
-	S_get_F(ta1,ta2)
-	beqz	ta2, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	S_is_QNaN(ta1,ta2)
-	bltz	ta2, 1f
-
-	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
-	   For now we don't signal and supply a QNaN for result.  */
-
-1:	li	ta2, W_QNaN
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	S_is_Inf(ta1,ta2)
-	bnez	ta2, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	S_is_E_min(ta1,ta2)
-	bnez	ta2, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	S_get_F(ta1,ta2)
-	beqz	ta2, 1f
-
-	/* It's a denorm.  */
-	/* XXX Should be signaling inexact exception, if enabled.  */
-	/* Fall through.  */
-1:
-	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
-	move	ta2, zero
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	/* XXX Ok, it's a normal number.  We don't handle that case yet.
-	   If we have fp hardware this case is unreached.  Add this for
-	   full fp simulation.  */
-
-	/* Done, return.  */
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/* Convert a double fp to a fixed point integer.  */
-cvt.w.d:
-	srl	ta1, ta0, fs_shift	# Get source register
-	andi	ta1, 31
-	jal	d_get_fpreg
-
-	D_is_E_max(ta1,ta2,ta3,t0)
-	beqz	ta3, 3f
-
-	/* Might be a NaN or Inf.  */
-	D_get_F(ta1,ta2,ta3)
-	or	ta3, ta2
-	beqz	ta3, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	D_is_QNaN(ta1,ta2,ta3)
-	bltz	ta3, 1f
-
-	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
-	   For now we don't signal and supply a QNaN for result.  */
-
-1:	li	ta2, W_QNaN
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	D_is_Inf(ta1,ta2,ta3)
-	bnez	ta3, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	D_is_E_min(ta1,ta2,ta3)
-	bnez	ta3, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	D_get_F(ta1,ta2,ta3)
-	or	ta3, ta2
-	beqz	ta3, 1f
-
-	/* It's a denorm.  */
-	/* XXX Should be signaling inexact exception, if enabled.  */
-	/* Fall through.  */
-1:
-	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
-	move	ta2, zero
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	/* XXX Ok, it's a normal number.  We don't handle that case yet.
-	   If we have fp hardware this case is only reached if the value
-	   of the source register exceeds the range which is representable
-	   in a single precission register.  For now we kludge by returning
-	   +/- maxint and don't signal overflow. */
-
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-
-	/* Done, return.  */
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-cvt.w.w = unimp				# undefined result
-cvt.w.l = unimp				# undefined result
-
-/* MIPS III extension, no need to handle for 32bit OS.  */
-cvt.l = unimp
-
-/* ------------------------------------------------------------------------ */
-
-	BITCH(c.f)
-	BITCH(c.un)
-	BITCH(c.eq)
-	BITCH(c.ueq)
-	BITCH(c.olt)
-	BITCH(c.ult)
-	BITCH(c.ole)
-	BITCH(c.ule)
-	BITCH(c.sf)
-	BITCH(c.ngle)
-	BITCH(c.seq)
-	BITCH(c.ngl)
-	BITCH(c.lt)
-	BITCH(c.nge)
-	BITCH(c.le)
-	BITCH(c.ngt)
-
-/* Get the single precission register which's number is in ta1.  */
-s_get_fpreg:
-	.set	noat
-	sll	ta1, 3
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-
-1:	mfc1	ta1, $0
-	jr	ra
-	mfc1	ta1, $1
-	jr	ra
-	mfc1	ta1, $2
-	jr	ra
-	mfc1	ta1, $3
-	jr	ra
-	mfc1	ta1, $4
-	jr	ra
-	mfc1	ta1, $5
-	jr	ra
-	mfc1	ta1, $6
-	jr	ra
-	mfc1	ta1, $7
-	jr	ra
-	mfc1	ta1, $8
-	jr	ra
-	mfc1	ta1, $9
-	jr	ra
-	mfc1	ta1, $10
-	jr	ra
-	mfc1	ta1, $11
-	jr	ra
-	mfc1	ta1, $12
-	jr	ra
-	mfc1	ta1, $13
-	jr	ra
-	mfc1	ta1, $14
-	jr	ra
-	mfc1	ta1, $15
-	jr	ra
-	mfc1	ta1, $16
-	jr	ra
-	mfc1	ta1, $17
-	jr	ra
-	mfc1	ta1, $18
-	jr	ra
-	mfc1	ta1, $19
-	jr	ra
-	mfc1	ta1, $20
-	jr	ra
-	mfc1	ta1, $21
-	jr	ra
-	mfc1	ta1, $22
-	jr	ra
-	mfc1	ta1, $23
-	jr	ra
-	mfc1	ta1, $24
-	jr	ra
-	mfc1	ta1, $25
-	jr	ra
-	mfc1	ta1, $26
-	jr	ra
-	mfc1	ta1, $27
-	jr	ra
-	mfc1	ta1, $28
-	jr	ra
-	mfc1	ta1, $29
-	jr	ra
-	mfc1	ta1, $30
-	jr	ra
-	mfc1	ta1, $31
-	jr	ra
-
-/*
- * Put the value in ta2 into the single precission register which's number
- * is in ta1.
- */
-s_put_fpreg:
-	.set	noat
-	sll	ta1, 3
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-	
-1:	mtc1	ta2, $0
-	jr	ra
-	mtc1	ta2, $1
-	jr	ra
-	mtc1	ta2, $2
-	jr	ra
-	mtc1	ta2, $3
-	jr	ra
-	mtc1	ta2, $4
-	jr	ra
-	mtc1	ta2, $5
-	jr	ra
-	mtc1	ta2, $6
-	jr	ra
-	mtc1	ta2, $7
-	jr	ra
-	mtc1	ta2, $8
-	jr	ra
-	mtc1	ta2, $9
-	jr	ra
-	mtc1	ta2, $10
-	jr	ra
-	mtc1	ta2, $11
-	jr	ra
-	mtc1	ta2, $12
-	jr	ra
-	mtc1	ta2, $13
-	jr	ra
-	mtc1	ta2, $14
-	jr	ra
-	mtc1	ta2, $15
-	jr	ra
-	mtc1	ta2, $16
-	jr	ra
-	mtc1	ta2, $17
-	jr	ra
-	mtc1	ta2, $18
-	jr	ra
-	mtc1	ta2, $19
-	jr	ra
-	mtc1	ta2, $20
-	jr	ra
-	mtc1	ta2, $21
-	jr	ra
-	mtc1	ta2, $22
-	jr	ra
-	mtc1	ta2, $23
-	jr	ra
-	mtc1	ta2, $24
-	jr	ra
-	mtc1	ta2, $25
-	jr	ra
-	mtc1	ta2, $26
-	jr	ra
-	mtc1	ta2, $27
-	jr	ra
-	mtc1	ta2, $28
-	jr	ra
-	mtc1	ta2, $29
-	jr	ra
-	mtc1	ta2, $30
-	jr	ra
-	mtc1	ta2, $31
-	jr	ra
-
-/* Get the double precission register which's number is in ta1 into ta1/ta2.  */
-d_get_fpreg:
-	.set	noat
-	sll	AT, ta1, 1
-	sll	ta1, 2
-	daddu	ta1, AT
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-
-1:	mfc1	ta1, $0
-	mfc1	ta2, $1
-	jr	ra
-	mfc1	ta1, $2
-	mfc1	ta2, $3
-	jr	ra
-	mfc1	ta1, $4
-	mfc1	ta2, $5
-	jr	ra
-	mfc1	ta1, $6
-	mfc1	ta2, $7
-	jr	ra
-	mfc1	ta1, $8
-	mfc1	ta2, $9
-	jr	ra
-	mfc1	ta1, $10
-	mfc1	ta2, $11
-	jr	ra
-	mfc1	ta1, $12
-	mfc1	ta2, $13
-	jr	ra
-	mfc1	ta1, $14
-	mfc1	ta2, $15
-	jr	ra
-	mfc1	ta1, $16
-	mfc1	ta2, $17
-	jr	ra
-	mfc1	ta1, $18
-	mfc1	ta2, $19
-	jr	ra
-	mfc1	ta1, $20
-	mfc1	ta2, $21
-	jr	ra
-	mfc1	ta1, $22
-	mfc1	ta2, $23
-	jr	ra
-	mfc1	ta1, $24
-	mfc1	ta2, $25
-	jr	ra
-	mfc1	ta1, $26
-	mfc1	ta2, $27
-	jr	ra
-	mfc1	ta1, $28
-	mfc1	ta2, $29
-	jr	ra
-	mfc1	ta1, $30
-	mfc1	ta2, $31
-	jr	ra
-
-/*
- * Send an invalid operation exception.
- */
-invalid:
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/*
- * Done, just skip over the current instruction
- */
-done:
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-unimp:
-	/* We've run into an yet unknown instruction.  This happens either
-	   on new, yet unsupported CPU types or when the faulting instruction
-	   is being executed for cache but has been overwritten in memory.  */
-	LOCK_KERNEL
-	move	a1, ta0
-	PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ")
-	PRINT("please mail to ralf@gnu.org.\n")
-	UNLOCK_KERNEL
-
-	li	a0, SIGILL			# Die, sucker ...
-	move	a1, $28
-	jal	force_sig
-
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/*
- * Jump table for the lowest 6 bits of a cp1 instruction.
- */
-	.data
-lowtab:	.dword	add,   sub,   mul,   div,   sqrt,  abs,   mov,   neg
-	.dword	round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	c.f,   c.un,  c.eq,  c.ueq, c.olt, c.ult, c.ole, c.ule
-	.dword	c.sf,  c.ngle,c.seq, c.ngl, c.lt,  c.nge, c.le, c.ngt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/syscall.c linux-2.4.20/arch/mips64/kernel/syscall.c
--- linux-2.4.19/arch/mips64/kernel/syscall.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/syscall.c	2002-10-04 00:41:23.000000000 +0000
@@ -261,7 +261,7 @@
 	}
 
 	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
 				   second, third);
 	case MSGRCV:
 		switch (version) {
@@ -269,9 +269,9 @@
 			struct ipc_kludge tmp;
 			if (!ptr)
 				return -EINVAL;
-			
+
 			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr, 
+					   (struct ipc_kludge *) ptr,
 					   sizeof (tmp)))
 				return -EFAULT;
 			return sys_msgrcv (first, tmp.msgp, second,
@@ -301,7 +301,7 @@
 				return -EINVAL;
 			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	case SHMDT: 
+	case SHMDT:
 		return sys_shmdt ((char *)ptr);
 	case SHMGET:
 		return sys_shmget (first, second, third);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/time.c linux-2.4.20/arch/mips64/kernel/time.c
--- linux-2.4.19/arch/mips64/kernel/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/time.c	2002-10-04 00:41:17.000000000 +0000
@@ -2,8 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
- * Common time service routines for MIPS machines. See 
- * Documents/MIPS/README.txt. 
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
  *
  * 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
@@ -289,9 +289,9 @@
 
 /*
  * local_timer_interrupt() does profiling and process accounting
- * on a per-CPU basis.  
+ * on a per-CPU basis.
  *
- * In UP mode, it is invoked from the (global) timer_interrupt.  
+ * In UP mode, it is invoked from the (global) timer_interrupt.
  *
  * In SMP mode, it might invoked by per-CPU timer interrupt, or
  * a broadcasted inter-processor interrupt which itself is triggered
@@ -368,7 +368,7 @@
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
+			last_rtc_update = xtime.tv_sec - 600;
 			/* do it again in 60 s */
 		}
 	}
@@ -384,9 +384,9 @@
 	}
 
 #if !defined(CONFIG_SMP)
-	/* 
+	/*
 	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.  
+	 * and process accouting.
 	 *
 	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
 	 * low-level local timer interrupt handler.
@@ -396,7 +396,7 @@
 #else	/* CONFIG_SMP */
 
 	if (emulate_local_timer_interrupt) {
-		/* 
+		/*
 		 * this is the place where we send out inter-process
 		 * interrupts and let each CPU do its own profiling
 		 * and process accouting.
@@ -418,7 +418,7 @@
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -434,7 +434,7 @@
 
 	/* we keep interrupt disabled all the time */
 	local_timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -444,19 +444,19 @@
 /*
  * time_init() - it does the following things.
  *
- * 1) board_time_init() - 
- * 	a) (optional) set up RTC routines, 
+ * 1) board_time_init() -
+ * 	a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_counter_frequency
  *	    (only needed if you intended to use fixed_rate_gettimeoffset
  *	     or use cpu counter as timer interrupt source)
  * 2) setup xtime based on rtc_get_time().
  * 3) choose a appropriate gettimeoffset routine.
  * 4) calculate a couple of cached variables for later usage
- * 5) board_timer_setup() - 
+ * 5) board_timer_setup() -
  *	a) (optional) over-write any choices made above by time_init().
  *	b) machine specific code should setup the timer irqaction.
  *	c) enable the timer interrupt
- */ 
+ */
 
 void (*board_time_init)(void) = NULL;
 void (*board_timer_setup)(struct irqaction *irq) = NULL;
@@ -496,10 +496,12 @@
 		/* we need to calibrate the counter but we *do* have
 		 * 64-bit division. */
 		do_gettimeoffset = calibrate_div64_gettimeoffset;
-	}	
+	}
 
 	/* caclulate cache parameters */
 	if (mips_counter_frequency) {
+		u32 count;
+
 		cycles_per_jiffy = mips_counter_frequency / HZ;
 
 		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
@@ -507,16 +509,24 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
+
+		/*
+		 * For those using cpu counter as timer,  this sets up the
+		 * first interrupt
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
 	}
 
-	/* 
+	/*
 	 * Call board specific timer interrupt setup.
 	 *
-	 * this pointer must be setup in machine setup routine. 
+	 * this pointer must be setup in machine setup routine.
 	 *
 	 * Even if the machine choose to use low-level timer interrupt,
 	 * it still needs to setup the timer_irqaction.
-	 * In that case, it might be better to set timer_irqaction.handler 
+	 * In that case, it might be better to set timer_irqaction.handler
 	 * to be NULL function so that we are sure the high-level code
 	 * is not invoked accidentally.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/traps.c linux-2.4.20/arch/mips64/kernel/traps.c
--- linux-2.4.19/arch/mips64/kernel/traps.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/traps.c	2002-10-04 00:41:22.000000000 +0000
@@ -31,6 +31,7 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/cachectl.h>
+#include <asm/types.h>
 
 extern asmlinkage void __xtlb_mod(void);
 extern asmlinkage void __xtlb_tlbl(void);
@@ -50,7 +51,9 @@
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-extern int fpu_emulator_cop1Handler(struct pt_regs *);
+extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx);
+
 void fpu_emulator_init_fpu(void);
 
 char watch_available = 0;
@@ -66,61 +69,94 @@
  */
 #define MODULE_RANGE (8*1024*1024)
 
+#define OPCODE 0xfc000000
+
+/*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+	int retval = 0;
+	struct module *mod;
+
+	if (addr >= (long) &_stext && addr <= (long) &_etext)
+		return 1;
+
+	for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+		/* mod_bound tests for addr being inside the vmalloc'ed
+		 * module area. Of course it'd be better to test only
+		 * for the .text subset... */
+		if (mod_bound(addr, 0, mod)) {
+			retval = 1;
+			break;
+		}
+	}
+
+	return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+
+	return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
 /*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
  */
-void show_stack(unsigned long *sp)
+void show_stack(long *sp)
 {
 	int i;
-	unsigned long *stack;
-
-	stack = sp;
-	i = 0;
+	long stackdata;
 
 	printk("Stack:");
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long stackdata;
-
-		if (__get_user(stackdata, stack++)) {
-			printk(" (Bad stack address)");
+	i = 0;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % 4) == 0))
+			printk("\n      ");
+		if (i > 40) {
+			printk(" ...");
 			break;
 		}
 
-		printk(" %016lx", stackdata);
-
-		if (++i > 40) {
-			printk(" ...");
+		if (__get_user(stackdata, sp++)) {
+			printk(" (Bad stack address)");
 			break;
 		}
 
-		if (i % 4 == 0)
-			printk("\n      ");
+		printk(" %016lx", stackdata);
+		i++;
 	}
+	printk("\n");
 }
 
-void show_trace(unsigned long *sp)
+void show_trace(long *sp)
 {
 	int i;
-	unsigned long *stack;
-	unsigned long kernel_start, kernel_end;
-	unsigned long module_start, module_end;
-	extern char _stext, _etext;
+	long addr;
 
-	stack = sp;
+	printk("Call Trace:");
 	i = 0;
+	while ((long) sp & (PAGE_SIZE - 1)) {
 
-	kernel_start = (unsigned long) &_stext;
-	kernel_end = (unsigned long) &_etext;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
-
-	printk("\nCall Trace:");
-
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long addr;
-
-		if (__get_user(addr, stack++)) {
+		if (__get_user(addr, sp++)) {
+			if (i && ((i % 3) == 0))
+				printk("\n           ");
 			printk(" (Bad stack address)\n");
 			break;
 		}
@@ -134,25 +170,24 @@
 		 * out the call path that was taken.
 		 */
 
-		if ((addr >= kernel_start && addr < kernel_end) ||
-		    (addr >= module_start && addr < module_end)) { 
-
-			/* Since our kernel is still at KSEG0,
-			 * truncate the address so that ksymoops
-			 * understands it.
-			 */
-			printk(" [<%08x>]", (unsigned int) addr);
-			if (++i > 40) {
+		if (kernel_text_address(addr)) {
+			if (i && ((i % 3) == 0))
+				printk("\n           ");
+			if (i > 40) {
 				printk(" ...");
 				break;
 			}
+
+			printk(" [<%016lx>]", addr);
+			i++;
 		}
 	}
+	printk("\n");
 }
 
 void show_trace_task(struct task_struct *tsk)
 {
-	show_trace((unsigned long *)tsk->thread.reg29);
+	show_trace((long *)tsk->thread.reg29);
 }
 
 
@@ -216,31 +251,38 @@
 	printk("Cause   : %08x\n", (unsigned int) regs->cp0_cause);
 }
 
-static spinlock_t die_lock;
-
-void die(const char * str, struct pt_regs * regs)
+void show_registers(struct pt_regs *regs)
 {
-	if (user_mode(regs))	/* Just return if in user mode.  */
-		return;
-
-	console_verbose();
-	spin_lock_irq(&die_lock);
-	printk("%s\n", str);
 	show_regs(regs);
-	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+	printk("Process %s (pid: %d, stackpage=%016lx)\n",
 		current->comm, current->pid, (unsigned long) current);
-	show_stack((unsigned long *) regs->regs[29]);
-	show_trace((unsigned long *) regs->regs[29]);
+	show_stack((long *) regs->regs[29]);
+	show_trace((long *) regs->regs[29]);
 	show_code((unsigned int *) regs->cp0_epc);
 	printk("\n");
+}
+
+static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+
+void __die(const char * str, struct pt_regs * regs, const char * file,
+	   const char * func, unsigned long line)
+{
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s", str);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
+	printk(":\n");
+	show_registers(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char * str, struct pt_regs * regs)
+void __die_if_kernel(const char * str, struct pt_regs * regs,
+		     const char * file, const char * func, unsigned long line)
 {
 	if (!user_mode(regs))
-		die(str, regs);
+		__die(str, regs, file, func, line);
 }
 
 extern const struct exception_table_entry __start___dbe_table[];
@@ -353,11 +395,18 @@
 	force_sig(SIGBUS, current);
 }
 
-void do_ov(struct pt_regs *regs)
+asmlinkage void do_ov(struct pt_regs *regs)
 {
+	siginfo_t info;
+
 	if (compute_return_epc(regs))
 		return;
-	force_sig(SIGFPE, current);
+
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
 }
 
 /*
@@ -381,10 +430,11 @@
 		save_fp(current);
 
 		/* Run the emulator */
-		sig = fpu_emulator_cop1Handler(regs);
+		sig = fpu_emulator_cop1Handler (0, regs,
+			&current->thread.fpu.soft);
 
-		/* 
-		 * We can't allow the emulated instruction to leave any of 
+		/*
+		 * We can't allow the emulated instruction to leave any of
 		 * the cause bit set in $fcr31.
 		 */
 		current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X;
@@ -395,8 +445,8 @@
 		/* If something went wrong, signal */
 		if (sig)
 		{
-			/* 
-			 * Return EPC is not calculated in the FPU emulator, 
+			/*
+			 * Return EPC is not calculated in the FPU emulator,
 			 * if a signal is being send. So we calculate it here.
 			 */
 			compute_return_epc(regs);
@@ -411,16 +461,26 @@
 	force_sig(SIGFPE, current);
 }
 
-void do_bp(struct pt_regs *regs)
+static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
+{
+	unsigned long *epc;
+
+	epc = (unsigned long *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (!get_user(opcode, epc))
+		return 0;
+
+	force_sig(SIGSEGV, current);
+	return 1;
+}
+
+asmlinkage void do_bp(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
-	unsigned int *epc;
 	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
@@ -450,37 +510,30 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-
-	force_sig(SIGTRAP, current);
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
-void do_tr(struct pt_regs *regs)
+asmlinkage void do_tr(struct pt_regs *regs)
 {
-	unsigned int opcode, bcode;
-	unsigned int *epc;
+	unsigned int opcode, tcode = 0;
 	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
-	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+        /* Immediate versions don't provide a code.  */
+	if (!(opcode & OPCODE))
+		tcode = ((opcode >> 6) & ((1 << 20) - 1));
 
 	/*
-	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
-	 * insns, even for break codes that indicate arithmetic failures.
-	 * Wiered ...)
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
+	 * insns, even for trap codes that indicate arithmetic failures.
+	 * Weird ...)
 	 * But should we continue the brokenness???  --macro
 	 */
-	switch (bcode) {
+	switch (tcode) {
 	case 6:
 	case 7:
-		if (bcode == 7)
+		if (tcode == 7)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -492,23 +545,22 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
-void do_ri(struct pt_regs *regs)
+asmlinkage void do_ri(struct pt_regs *regs)
 {
+	die_if_kernel("Reserved instruction in kernel code", regs);
+
 	if (compute_return_epc(regs))
 		return;
 
 	force_sig(SIGILL, current);
 }
 
-void do_cpu(struct pt_regs *regs)
+asmlinkage void do_cpu(struct pt_regs *regs)
 {
-	u32 cpid;
+	unsigned int cpid;
+	void fpu_emulator_init_fpu(void);
 	int sig;
 
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -544,15 +596,17 @@
 	return;
 
 fp_emul:
-	if (!current->used_math) {
-		fpu_emulator_init_fpu();
-		current->used_math = 1;
+	if (last_task_used_math != current) {
+		if (!current->used_math) {
+			fpu_emulator_init_fpu();
+			current->used_math = 1;
+		}
 	}
-	sig = fpu_emulator_cop1Handler(regs);
-	if (sig)
-	{
-		/* 
-		 * Return EPC is not calculated in the FPU emulator, if 
+	sig = fpu_emulator_cop1Handler(0, regs, &current->thread.fpu.soft);
+	last_task_used_math = current;
+	if (sig) {
+		/*
+		 * Return EPC is not calculated in the FPU emulator, if
 		 * a signal is being send. So we calculate it here.
 		 */
 		compute_return_epc(regs);
@@ -565,12 +619,15 @@
 	force_sig(SIGILL, current);
 }
 
-void do_watch(struct pt_regs *regs)
+asmlinkage void do_watch(struct pt_regs *regs)
 {
+	extern void dump_tlb_all(void);
+
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
 	 */
+	dump_tlb_all();
 	show_regs(regs);
 	panic("Caught WATCH exception - probably caused by stack overflow.");
 }
@@ -578,11 +635,17 @@
 asmlinkage void do_mcheck(struct pt_regs *regs)
 {
 	show_regs(regs);
-	panic("Caught Machine Check exception - probably caused by multiple "
-	      "matching entries in the TLB.");
+	dump_tlb_all();
+	/*
+	 * Some chips may have other causes of machine check (e.g. SB1
+	 * graduation timer)
+	 */
+	panic("Caught Machine Check exception - %scaused by multiple "
+	      "matching entries in the TLB.",
+	      (regs->cp0_status & ST0_TS) ? "" : "not ");
 }
 
-void do_reserved(struct pt_regs *regs)
+asmlinkage void do_reserved(struct pt_regs *regs)
 {
 	/*
 	 * Game over - no way to handle this if it ever occurs.  Most probably
@@ -618,18 +681,28 @@
  * to interrupt handlers in the address range from
  * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
  */
-void set_except_vector(int n, void *addr)
+void *set_except_vector(int n, void *addr)
 {
 	unsigned long handler = (unsigned long) addr;
-	exception_handlers[n] = handler;
+	unsigned long old_handler = exception_handlers[n];
 
+	exception_handlers[n] = handler;
 	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
 		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
 	}
+	return (void *)old_handler;
 }
 
+asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int _save_fp_context(struct sigcontext *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
+
+extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
+extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
+
 void __init per_cpu_trap_init(void)
 {
 	unsigned int cpu = smp_processor_id();
@@ -653,6 +726,7 @@
 void __init trap_init(void)
 {
 	extern char except_vec0;
+	extern char except_vec1_r4k;
 	extern char except_vec1_r10k;
 	extern char except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
@@ -724,10 +798,17 @@
 	case CPU_R4600:
 	case CPU_R5000:
 	case CPU_NEVADA:
+	case CPU_5KC:
+	case CPU_20KC:
+	case CPU_RM7000:
 		/* Debug TLB refill handler.  */
 		memcpy((void *)KSEG0, &except_vec0, 0x80);
-		memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
-
+		if ((mips_cpu.options & MIPS_CPU_4KEX)
+		    && (mips_cpu.options & MIPS_CPU_4KTLB)) {
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80);
+		} else {
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
+		}
 		if (mips_cpu.options & MIPS_CPU_VCE) {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
 			       0x80);
@@ -764,6 +845,14 @@
 	}
 	flush_icache_range(KSEG0, KSEG0 + 0x200);
 
+	if (mips_cpu.options & MIPS_CPU_FPU) {
+	        save_fp_context = _save_fp_context;
+		restore_fp_context = _restore_fp_context;
+	} else {
+		save_fp_context = fpu_emulator_save_context;
+		restore_fp_context = fpu_emulator_restore_context;
+	}
+
 	if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
 		set_cp0_status(ST0_XX);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/kernel/unaligned.c linux-2.4.20/arch/mips64/kernel/unaligned.c
--- linux-2.4.19/arch/mips64/kernel/unaligned.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/kernel/unaligned.c	2002-10-04 00:41:14.000000000 +0000
@@ -41,7 +41,7 @@
  *
  * #include <stdio.h>
  * #include <asm/sysmips.h>
- * 
+ *
  * struct foo {
  *         unsigned char bar[8];
  * };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/ld.script.elf32.S linux-2.4.20/arch/mips64/ld.script.elf32.S
--- linux-2.4.19/arch/mips64/ld.script.elf32.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/ld.script.elf32.S	2002-10-04 00:41:19.000000000 +0000
@@ -102,7 +102,7 @@
   }
 
   /* Sections to be discarded */
-  /DISCARD/ : 
+  /DISCARD/ :
   {
         *(.text.exit)
         *(.data.exit)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/ld.script.elf64 linux-2.4.20/arch/mips64/ld.script.elf64
--- linux-2.4.19/arch/mips64/ld.script.elf64	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/ld.script.elf64	2002-10-04 00:41:14.000000000 +0000
@@ -8,7 +8,7 @@
   /* This is the value for an Origin kernel, taken from an IRIX kernel.  */
   /* . = 0xc00000000001c000; */
 
-  /* Set the vaddr for the text segment to a value 
+  /* Set the vaddr for the text segment to a value
         >= 0xa800 0000 0001 9000 if no symmon is going to configured
         >= 0xa800 0000 0030 0000 otherwise  */
 
@@ -111,7 +111,7 @@
   }
 
   /* Sections to be discarded */
-  /DISCARD/ : 
+  /DISCARD/ :
   {
         *(.text.exit)
         *(.data.exit)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/csum_partial_copy.c linux-2.4.20/arch/mips64/lib/csum_partial_copy.c
--- linux-2.4.19/arch/mips64/lib/csum_partial_copy.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/csum_partial_copy.c	2002-10-04 00:41:29.000000000 +0000
@@ -16,7 +16,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const char *src, char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -44,6 +44,6 @@
 		memset(dst + len - missing, 0, missing);
 		*err_ptr = -EFAULT;
 	}
-		
+
 	return csum_partial(dst, len, sum);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/floppy-std.c linux-2.4.20/arch/mips64/lib/floppy-std.c
--- linux-2.4.19/arch/mips64/lib/floppy-std.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/floppy-std.c	2002-10-04 00:41:21.000000000 +0000
@@ -111,8 +111,8 @@
 }
 
 static void std_fd_dma_mem_free(unsigned long addr, unsigned long size)
-{       
-	free_pages(addr, get_order(size));	
+{
+	free_pages(addr, get_order(size));
 }
 
 static unsigned long std_fd_drive_type(unsigned long n)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/ide-no.c linux-2.4.20/arch/mips64/lib/ide-no.c
--- linux-2.4.19/arch/mips64/lib/ide-no.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/ide-no.c	2002-10-04 00:41:09.000000000 +0000
@@ -35,7 +35,7 @@
                               void *dev_id)
 {
 	panic("no_no_ide_request_irq called - shouldn't happen");
-}			
+}
 
 static void no_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/ide-std.c linux-2.4.20/arch/mips64/lib/ide-std.c
--- linux-2.4.19/arch/mips64/lib/ide-std.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/ide-std.c	2002-10-04 00:41:09.000000000 +0000
@@ -68,7 +68,7 @@
                                 void *dev_id)
 {
 	return request_irq(irq, handler, flags, device, dev_id);
-}			
+}
 
 static void std_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/memcpy.S linux-2.4.20/arch/mips64/lib/memcpy.S
--- linux-2.4.19/arch/mips64/lib/memcpy.S	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/memcpy.S	2002-10-04 00:41:11.000000000 +0000
@@ -501,7 +501,7 @@
 r_word_align:
 	beqz	t8, r_dword_align
 	 sltiu	t8, a2, 56
-	
+
 	lh	ta0, -2(a1)
 	dsubu	a2, a2, 0x2
 	sh	ta0, -2(a0)
@@ -762,8 +762,18 @@
 	dsubu	a2, AT, ta0			# a2 bytes to go
 	daddu	a0, ta0				# compute start address in a1
 	dsubu	a0, a1
-	j	__bzero
-	 move	a1, zero
+	/*
+	 * Clear len bytes starting at dst.  Can't call __bzero because it
+	 * might modify len.  An inefficient loop for these rare times...
+	 */
+	beqz	a2, 2f
+	 dsubu	a1, a2, 1
+1:	sb	zero, 0(a0)
+	daddu	a0, a0, 1
+	bnez	a1, 1b
+	 dsubu	a1, a1, 1
+2:	jr	ra
+	 nop
 
 s_fixup:
 	jr	ra
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/memset.S linux-2.4.20/arch/mips64/lib/memset.S
--- linux-2.4.19/arch/mips64/lib/memset.S	2001-07-04 18:50:39.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/memset.S	2002-10-04 00:41:12.000000000 +0000
@@ -52,7 +52,6 @@
 1:
 
 FEXPORT(__bzero)
-	.type	__bzero, @function
 	sltiu	t0, a2, 8			/* very small region? */
 	bnez	t0, small_memset
 	 andi	t0, a0, 7			/* aligned? */
@@ -82,7 +81,7 @@
 	.set	noreorder
 
 memset_partial:
-	la	t1, 2f				/* where to start */
+	PTR_LA	t1, 2f				/* where to start */
 	.set	noat
 	dsrl	AT, t0, 1
 	dsubu	t1, AT
@@ -90,8 +89,12 @@
 	jr	t1
 	 daddu	a0, t0				/* dest ptr */
 
+	.set	push
+	.set	noreorder
+	.set	nomacro
 	F_FILL64(a0, -64, a1, partial_fixup)	/* ... but first do dwds ... */
-2:	andi	a2, 7				/* 0 <= n <= 7 to go */
+2:	.set	pop
+	andi	a2, 7				/* 0 <= n <= 7 to go */
 
 	beqz	a2, 1f
 	 daddu	a0, a2				/* What's left */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/strlen_user.S linux-2.4.20/arch/mips64/lib/strlen_user.S
--- linux-2.4.19/arch/mips64/lib/strlen_user.S	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/strlen_user.S	2002-10-04 00:41:15.000000000 +0000
@@ -36,9 +36,5 @@
 	jr	ra
 	END(__strlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/lib/strnlen_user.S linux-2.4.20/arch/mips64/lib/strnlen_user.S
--- linux-2.4.19/arch/mips64/lib/strnlen_user.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/lib/strnlen_user.S	2002-10-04 00:41:15.000000000 +0000
@@ -24,7 +24,7 @@
  */
 LEAF(__strnlen_user_asm)
 	ld	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, ta0
+	and	v0, a0
 	bltz	v0, fault
 
 FEXPORT(__strnlen_user_nocheck_asm)
@@ -38,9 +38,5 @@
 	jr	ra
 	END(__strnlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/Makefile linux-2.4.20/arch/mips64/math-emu/Makefile
--- linux-2.4.19/arch/mips64/math-emu/Makefile	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,24 +0,0 @@
-#
-# Makefile for the Linux/MIPS kernel FPU emulation.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-EXTRA_ASFLAGS = -mips2 -mcpu=r4000
-
-O_TARGET:= fpu_emulator.o
-
-obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
-	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
-	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
-	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
-	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
-	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
-	   dp_sqrt.o sp_sqrt.o kernel_linkage.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/cp1emu.c linux-2.4.20/arch/mips64/math-emu/cp1emu.c
--- linux-2.4.19/arch/mips64/math-emu/cp1emu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/cp1emu.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1812 +0,0 @@
-/*
- * MIPS floating point support
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
- * 
- * A complete emulator for MIPS coprocessor 1 instructions.  This is
- * required for #float(switch) or #float(trap), where it catches all
- * COP1 instructions via the "CoProcessor Unusable" exception.  
- *
- * More surprisingly it is also required for #float(ieee), to help out
- * the hardware fpu at the boundaries of the IEEE-754 representation
- * (denormalised values, infinities, underflow, etc).  It is made
- * quite nasty because emulation of some non-COP1 instructions is
- * required, e.g. in branch delay slots.
- * 
- * Notes: 
- *  1) the IEEE754 library (-le) performs the actual arithmetic;
- *  2) if you know that you won't have an fpu, then you'll get much 
- *     better performance by compiling with -msoft-float!
- *
- *  Nov 7, 2000
- *  Massive changes to integrate with Linux kernel.
- *
- *  Replace use of kernel data area with use of user stack 
- *  for execution of instructions in branch delay slots.
- *
- *  Replace use of static kernel variables with thread_struct elements.
- *
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000  MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/asm.h>
-#include <asm/branch.h>
-#include <asm/bootinfo.h>
-#include <asm/byteorder.h>
-#include <asm/cpu.h>
-#include <asm/inst.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
-#include <asm/fpu_emulator.h>
-
-#include "ieee754.h"
-
-/* Strap kernel emulator for full MIPS IV emulation */
-
-#ifdef __mips
-#undef __mips
-#endif
-#define __mips 4
-
-typedef void *vaddr_t;
-
-/* Function which emulates the instruction in a branch delay slot. */
-
-static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t);
-
-/* Function which emulates a floating point instruction. */
-
-static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
-	 mips_instruction);
-
-#if __mips >= 4 && __mips != 32
-static int fpux_emu(struct pt_regs *,
-		    struct mips_fpu_soft_struct *, mips_instruction);
-#endif
-
-/* Further private data for which no space exists in mips_fpu_soft_struct */
-
-struct mips_fpu_emulator_private fpuemuprivate;
-
-/* Control registers */
-
-#define FPCREG_RID	0	/* $0  = revision id */
-#define FPCREG_CSR	31	/* $31 = csr */
-
-/* Convert Mips rounding mode (0..3) to IEEE library modes. */
-static const unsigned char ieee_rm[4] = {
-	IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
-};
-
-#if __mips >= 4
-/* convert condition code register number to csr bit */
-static const unsigned int fpucondbit[8] = {
-	FPU_CSR_COND0,
-	FPU_CSR_COND1,
-	FPU_CSR_COND2,
-	FPU_CSR_COND3,
-	FPU_CSR_COND4,
-	FPU_CSR_COND5,
-	FPU_CSR_COND6,
-	FPU_CSR_COND7
-};
-#endif
-
-
-
-/* 
- * Redundant with logic already in kernel/branch.c,
- * embedded in compute_return_epc.  At some point,
- * a single subroutine should be used across both
- * modules.
- */
-static int isBranchInstr(mips_instruction * i)
-{
-	switch (MIPSInst_OPCODE(*i)) {
-	case spec_op:
-		switch (MIPSInst_FUNC(*i)) {
-		case jalr_op:
-		case jr_op:
-			return 1;
-		}
-		break;
-
-	case bcond_op:
-		switch (MIPSInst_RT(*i)) {
-		case bltz_op:
-		case bgez_op:
-		case bltzl_op:
-		case bgezl_op:
-		case bltzal_op:
-		case bgezal_op:
-		case bltzall_op:
-		case bgezall_op:
-			return 1;
-		}
-		break;
-
-	case j_op:
-	case jal_op:
-	case jalx_op:
-	case beq_op:
-	case bne_op:
-	case blez_op:
-	case bgtz_op:
-	case beql_op:
-	case bnel_op:
-	case blezl_op:
-	case bgtzl_op:
-		return 1;
-
-	case cop0_op:
-	case cop1_op:
-	case cop2_op:
-	case cop1x_op:
-		if (MIPSInst_RS(*i) == bc_op)
-			return 1;
-		break;
-	}
-
-	return 0;
-}
-
-#define REG_TO_VA (vaddr_t)
-#define VA_TO_REG (unsigned long)
-
-static unsigned long
-mips_get_word(struct pt_regs *xcp, void *va, int *perr)
-{
-	unsigned long temp;
-
-	if (!user_mode(xcp)) {
-		*perr = 0;
-		return (*(unsigned long *) va);
-	} else {
-		/* Use kernel get_user() macro */
-		*perr = (int) get_user(temp, (unsigned long *) va);
-		return temp;
-	}
-}
-
-static unsigned long long
-mips_get_dword(struct pt_regs *xcp, void *va, int *perr)
-{
-	unsigned long long temp;
-
-	if (!user_mode(xcp)) {
-		*perr = 0;
-		return (*(unsigned long long *) va);
-	} else {
-		/* Use kernel get_user() macro */
-		*perr = (int) get_user(temp, (unsigned long long *) va);
-		return temp;
-	}
-}
-
-static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val)
-{
-	if (!user_mode(xcp)) {
-		*(unsigned long *) va = val;
-		return 0;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) put_user(val, (unsigned long *) va);
-	}
-}
-
-static int mips_put_dword(struct pt_regs *xcp, void *va, long long val)
-{
-	if (!user_mode(xcp)) {
-		*(unsigned long long *) va = val;
-		return 0;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) put_user(val, (unsigned long long *) va);
-	}
-}
-
-
-/*
- * In the Linux kernel, we support selection of FPR format on the
- * basis of the Status.FR bit.  This does imply that, if a full 32
- * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position.  In any case, normal MIPS ABI uses
- * only the even FPRs (Status.FR = 0).
- */
-
-#define CP0_STATUS_FR_SUPPORT
-
-/*
- * Emulate the single floating point instruction pointed at by EPC.
- * Two instructions if the instruction is in a branch delay slot.
- */
-
-static int
-cop1Emulate(int xcptno, struct pt_regs *xcp,
-	    struct mips_fpu_soft_struct *ctx)
-{
-	mips_instruction ir;
-	vaddr_t emulpc;
-	vaddr_t contpc;
-	unsigned int cond;
-	int err = 0;
-
-
-	ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err);
-	if (err) {
-		fpuemuprivate.stats.errors++;
-		return SIGBUS;
-	}
-
-	/* XXX NEC Vr54xx bug workaround */
-	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
-		xcp->cp0_cause &= ~CAUSEF_BD;
-
-	if (xcp->cp0_cause & CAUSEF_BD) {
-		/*
-		 * The instruction to be emulated is in a branch delay slot
-		 * which means that we have to  emulate the branch instruction
-		 * BEFORE we do the cop1 instruction. 
-		 *
-		 * This branch could be a COP1 branch, but in that case we
-		 * would have had a trap for that instruction, and would not
-		 * come through this route.
-		 *
-		 * Linux MIPS branch emulator operates on context, updating the
-		 * cp0_epc.
-		 */
-		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
-
-		if (__compute_return_epc(xcp)) {
-#ifdef CP1DBG
-			printk("failed to emulate branch at %p\n",
-				    REG_TO_VA(xcp->cp0_epc));
-#endif
-			return SIGILL;;
-		}
-		ir = mips_get_word(xcp, emulpc, &err);
-		if (err) {
-			fpuemuprivate.stats.errors++;
-			return SIGBUS;
-		}
-		contpc = REG_TO_VA xcp->cp0_epc;
-	} else {
-		emulpc = REG_TO_VA xcp->cp0_epc;
-		contpc = REG_TO_VA xcp->cp0_epc + 4;
-	}
-
-      emul:
-	fpuemuprivate.stats.emulated++;
-	switch (MIPSInst_OPCODE(ir)) {
-#ifdef CP0_STATUS_FR_SUPPORT
-		/* R4000+ 64-bit fpu registers */
-#ifndef SINGLE_ONLY_FPU
-	case ldc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
-				ft &= ~1;
-			ctx->regs[ft] = mips_get_dword(xcp, va, &err);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case sdc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
-				ft &= ~1;
-			fpuemuprivate.stats.stores++;
-			if (mips_put_dword(xcp, va, ctx->regs[ft])) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#endif
-
-	case lwc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			fpureg_t val;
-			int ft = MIPSInst_RT(ir);
-			fpuemuprivate.stats.loads++;
-			val = mips_get_word(xcp, va, &err);
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-			if (xcp->cp0_status & ST0_FR) {
-				/* load whole register */
-				ctx->regs[ft] = val;
-			} else if (ft & 1) {
-				/* load to m.s. 32 bits */
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				ctx->regs[(ft & ~1)] &= 0xffffffff;
-				ctx->regs[(ft & ~1)] |= val << 32;
-#endif
-			} else {
-				/* load to l.s. 32 bits */
-				ctx->regs[ft] &= ~0xffffffffLL;
-				ctx->regs[ft] |= val;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			unsigned int val;
-			int ft = MIPSInst_RT(ir);
-			fpuemuprivate.stats.stores++;
-			if (xcp->cp0_status & ST0_FR) {
-				/* store whole register */
-				val = ctx->regs[ft];
-			} else if (ft & 1) {
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				/* store from m.s. 32 bits */
-				val = ctx->regs[(ft & ~1)] >> 32;
-#endif
-			} else {
-				/* store from l.s. 32 bits */
-				val = ctx->regs[ft];
-			}
-			if (mips_put_word(xcp, va, val)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#else				/* old 32-bit fpu registers */
-	case lwc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			ctx->regs[MIPSInst_RT(ir)] =
-			    mips_get_word(xcp, va, &err);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			fpuemuprivate.stats.stores++;
-			if (mips_put_word
-			    (xcp, va, ctx->regs[MIPSInst_RT(ir)])) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-	case ldc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			unsigned int rt = MIPSInst_RT(ir) & ~1;
-			int errs = 0;
-			fpuemuprivate.stats.loads++;
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			ctx->regs[rt + 1] =
-			    mips_get_word(xcp, va + 0, &err);
-			errs += err;
-			ctx->regs[rt + 0] =
-			    mips_get_word(xcp, va + 4, &err);
-			errs += err;
-#else
-			ctx->regs[rt + 0] =
-			    mips_get_word(xcp, va + 0, &err);
-			errs += err;
-			ctx->regs[rt + 1] =
-			    mips_get_word(xcp, va + 4, &err);
-			errs += err;
-#endif
-			if (err)
-				return SIGBUS;
-		}
-		break;
-
-	case sdc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			unsigned int rt = MIPSInst_RT(ir) & ~1;
-			fpuemuprivate.stats.stores++;
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 1]))
-				return SIGBUS;
-			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 0]))
-				return SIGBUS;
-#else
-			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 0]))
-				return SIGBUS;
-			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 1]))
-				return SIGBUS;
-#endif
-		}
-		break;
-#endif
-
-	case cop1_op:
-		switch (MIPSInst_RS(ir)) {
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case dmfc_op:
-			/* copregister fs -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
-					fs &= ~1;
-				xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
-			}
-			break;
-
-		case dmtc_op:
-			/* copregister fs <- rt */
-			{
-				fpureg_t value;
-				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
-					fs &= ~1;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
-				ctx->regs[fs] = value;
-			}
-			break;
-#endif
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				/* default value from l.s. 32 bits */
-				int value = ctx->regs[MIPSInst_RD(ir)];
-				if (MIPSInst_RD(ir) & 1) {
-#ifdef SINGLE_ONLY_FPU
-					/* illegal register in single-float mode */
-					return SIGILL;
-#else
-					if (!(xcp->cp0_status & ST0_FR)) {
-						/* move from m.s. 32 bits */
-						value =
-						    ctx->
-						    regs[MIPSInst_RD(ir) &
-							 ~1] >> 32;
-					}
-#endif
-				}
-				xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				fpureg_t value;
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value =
-					    (unsigned int) xcp->
-					    regs[MIPSInst_RT(ir)];
-				if (MIPSInst_RD(ir) & 1) {
-#ifdef SINGLE_ONLY_FPU
-					/* illegal register in single-float mode */
-					return SIGILL;
-#else
-					if (!(xcp->cp0_status & ST0_FR)) {
-						/* move to m.s. 32 bits */
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] |=
-						    value << 32;
-						break;
-					}
-#endif
-				}
-				/* move to l.s. 32 bits */
-				ctx->regs[MIPSInst_RD(ir)] &=
-				    ~0xffffffffLL;
-				ctx->regs[MIPSInst_RD(ir)] |= value;
-			}
-			break;
-#else
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				unsigned value =
-				    ctx->regs[MIPSInst_RD(ir)];
-				xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				unsigned value;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
-				ctx->regs[MIPSInst_RD(ir)] = value;
-			}
-			break;
-#endif
-
-		case cfc_op:
-			/* cop control register rd -> gpr[rt] */
-			{
-				unsigned value;
-
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-					value = ctx->sr;
-#ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]<-csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-				} else if (MIPSInst_RD(ir) == FPCREG_RID)
-					value = 0;
-				else
-					value = 0;
-				if (MIPSInst_RT(ir))
-					xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case ctc_op:
-			/* copregister rd <- rt */
-			{
-				unsigned value;
-
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value = xcp->regs[MIPSInst_RT(ir)];
-
-				/* we only have one writable control reg
-				 */
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-#ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]->csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-					ctx->sr = value;
-					/* copy new rounding mode to ieee library state! */
-					ieee754_csr.rm =
-					    ieee_rm[value & 0x3];
-				}
-			}
-			break;
-
-		case bc_op:
-			if (xcp->cp0_cause & CAUSEF_BD) {
-				return SIGILL;
-			}
-			{
-				int likely = 0;
-
-#if __mips >= 4
-				cond =
-				    ctx->
-				    sr & fpucondbit[MIPSInst_RT(ir) >> 2];
-#else
-				cond = ctx->sr & FPU_CSR_COND;
-#endif
-				switch (MIPSInst_RT(ir) & 3) {
-				case bcfl_op:
-					likely = 1;
-				case bcf_op:
-					cond = !cond;
-					break;
-				case bctl_op:
-					likely = 1;
-				case bct_op:
-					break;
-				default:
-					/* thats an illegal instruction */
-					return SIGILL;
-				}
-
-				xcp->cp0_cause |= CAUSEF_BD;
-				if (cond) {
-					/* branch taken: emulate dslot instruction */
-					xcp->cp0_epc += 4;
-					contpc =
-					    REG_TO_VA xcp->cp0_epc +
-					    (MIPSInst_SIMM(ir) << 2);
-
-					ir =
-					    mips_get_word(xcp,
-							  REG_TO_VA(xcp->
-								    cp0_epc),
-							  &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-
-					switch (MIPSInst_OPCODE(ir)) {
-					case lwc1_op:
-					case swc1_op:
-#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
-					case ldc1_op:
-					case sdc1_op:
-#endif
-					case cop1_op:
-#if __mips >= 4 && __mips != 32
-					case cop1x_op:
-#endif
-						/* its one of ours */
-						goto emul;
-#if __mips >= 4
-					case spec_op:
-						if (MIPSInst_FUNC(ir) ==
-						    movc_op) goto emul;
-						break;
-#endif
-					}
-
-					/* single step the non-cp1 instruction in the dslot */
-					return mips_dsemul(xcp, ir, contpc);
-				} else {
-					/* branch not taken */
-					if (likely)
-						/* branch likely nullifies dslot if not taken */
-						xcp->cp0_epc += 4;
-					/* else continue & execute dslot as normal insn */
-				}
-			}
-			break;
-
-		default:
-			if (!(MIPSInst_RS(ir) & 0x10)) {
-				return SIGILL;
-			}
-			/* a real fpu computation instruction */
-			{
-				int sig;
-				if ((sig = fpu_emu(xcp, ctx, ir)))
-					return sig;
-			}
-		}
-		break;
-
-#if __mips >= 4 && __mips != 32
-	case cop1x_op:
-		{
-			int sig;
-			if ((sig = fpux_emu(xcp, ctx, ir)))
-				return sig;
-		}
-		break;
-#endif
-
-#if __mips >= 4
-	case spec_op:
-		if (MIPSInst_FUNC(ir) != movc_op)
-			return SIGILL;
-		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
-		if (((ctx->sr & cond) != 0) !=
-		    ((MIPSInst_RT(ir) & 1) != 0)) return 0;
-		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
-		break;
-#endif
-
-	default:
-		return SIGILL;
-	}
-
-	/* we did it !! */
-	xcp->cp0_epc = VA_TO_REG(contpc);
-	xcp->cp0_cause &= ~CAUSEF_BD;
-	return 0;
-}
-
-/*
- * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
- * we have to emulate the instruction in a COP1 branch delay slot.  Do
- * not change cp0_epc due to the instruction
- *
- * According to the spec:
- * 1) it shouldnt be a branch :-)
- * 2) it can be a COP instruction :-(
- * 3) if we are tring to run a protected memory space we must take
- *    special care on memory access instructions :-(
- */
-
-/*
- * "Trampoline" return routine to catch exception following
- *  execution of delay-slot instruction execution.
- */
-
-int do_dsemulret(struct pt_regs *xcp)
-{
-#ifdef DSEMUL_TRACE
-	printk("desemulret\n");
-#endif
-	/* Set EPC to return to post-branch instruction */
-	xcp->cp0_epc = current->thread.dsemul_epc;
-	/*
-	 * Clear the state that got us here.
-	 */
-	current->thread.dsemul_aerpc = (unsigned long) 0;
-
-	return 0;
-}
-
-
-#define AdELOAD 0x8c000001	/* lw $0,1($0) */
-
-static int
-mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc)
-{
-	mips_instruction *dsemul_insns;
-	mips_instruction forcetrap;
-	extern asmlinkage void handle_dsemulret(void);
-
-	if (ir == 0) {		/* a nop is easy */
-		xcp->cp0_epc = VA_TO_REG(cpc);
-		return 0;
-	}
-#ifdef DSEMUL_TRACE
-	printk("desemul %p %p\n", REG_TO_VA(xcp->cp0_epc), cpc);
-#endif
-
-	/* 
-	 * The strategy is to push the instruction onto the user stack 
-	 * and put a trap after it which we can catch and jump to 
-	 * the required address any alternative apart from full 
-	 * instruction emulation!!.
-	 */
-	dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3);
-	dsemul_insns -= 3;	/* Two instructions, plus one for luck ;-) */
-	/* Verify that the stack pointer is not competely insane */
-	if (verify_area
-	    (VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction) * 2))
-		return SIGBUS;
-
-	if (mips_put_word(xcp, &dsemul_insns[0], ir)) {
-		fpuemuprivate.stats.errors++;
-		return (SIGBUS);
-	}
-
-	/* 
-	 * Algorithmics used a system call instruction, and
-	 * borrowed that vector.  MIPS/Linux version is a bit
-	 * more heavyweight in the interests of portability and
-	 * multiprocessor support.  We flag the thread for special
-	 * handling in the unaligned access handler and force an
-	 * address error excpetion.
-	 */
-
-	/* If one is *really* paranoid, one tests for a bad stack pointer */
-	if ((xcp->regs[29] & 0x3) == 0x3)
-		forcetrap = AdELOAD - 1;
-	else
-		forcetrap = AdELOAD;
-
-	if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) {
-		fpuemuprivate.stats.errors++;
-		return (SIGBUS);
-	}
-
-	/* Set thread state to catch and handle the exception */
-	current->thread.dsemul_epc = (unsigned long) cpc;
-	current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1];
-	xcp->cp0_epc = VA_TO_REG & dsemul_insns[0];
-	flush_cache_sigtramp((unsigned long) dsemul_insns);
-
-	return SIGILL;		/* force out of emulation loop */
-}
-
-/* 
- * Conversion table from MIPS compare ops 48-63
- * cond = ieee754dp_cmp(x,y,IEEE754_UN);
- */
-static const unsigned char cmptab[8] = {
-	0,					/* cmp_0 (sig) cmp_sf */
-	IEEE754_CUN,				/* cmp_un (sig) cmp_ngle */
-	IEEE754_CEQ,				/* cmp_eq (sig) cmp_seq */
-	IEEE754_CEQ | IEEE754_CUN,		/* cmp_ueq (sig) cmp_ngl  */
-	IEEE754_CLT,				/* cmp_olt (sig) cmp_lt */
-	IEEE754_CLT | IEEE754_CUN,		/* cmp_ult (sig) cmp_nge */
-	IEEE754_CLT | IEEE754_CEQ,		/* cmp_ole (sig) cmp_le */
-	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
-};
-
-#define SIFROMREG(si,x)	((si) = ctx->regs[x])
-#define SITOREG(si,x)	(ctx->regs[x] = (int)(si))
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-#define DIFROMREG(di,x)	((di) = ctx->regs[x])
-#define DITOREG(di,x)	(ctx->regs[x] = (di))
-#endif
-
-#define SPFROMREG(sp,x)	((sp).bits = ctx->regs[x])
-#define SPTOREG(sp,x)	(ctx->regs[x] = (sp).bits)
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#define DPFROMREG(dp,x)	((dp).bits = \
-			ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)])
-#define DPTOREG(dp,x)	(ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]\
-			= (dp).bits)
-#else
-/* Beware: MIPS COP1 doubles are always little_word endian in registers */
-#define DPFROMREG(dp,x)	\
-  ((dp).bits = ((unsigned long long)ctx->regs[(x)+1] << 32) | ctx->regs[x])
-#define DPTOREG(dp,x) \
-  (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
-#endif
-
-#if __mips >= 4 && __mips != 32
-
-/*
- * Additional MIPS4 instructions
- */
-
-static ieee754dp fpemu_dp_recip(ieee754dp d)
-{
-	return ieee754dp_div(ieee754dp_one(0), d);
-}
-
-static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
-{
-	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
-}
-
-static ieee754sp fpemu_sp_recip(ieee754sp s)
-{
-	return ieee754sp_div(ieee754sp_one(0), s);
-}
-
-static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
-{
-	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
-}
-
-
-static ieee754dp fpemu_dp_madd(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_add(ieee754dp_mul(s, t), r);
-}
-
-static ieee754dp fpemu_dp_msub(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_sub(ieee754dp_mul(s, t), r);
-}
-
-static ieee754dp fpemu_dp_nmadd(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_neg(ieee754dp_add(ieee754dp_mul(s, t), r));
-}
-
-static ieee754dp fpemu_dp_nmsub(ieee754dp r, ieee754dp s, ieee754dp t)
-{
-	return ieee754dp_neg(ieee754dp_sub(ieee754dp_mul(s, t), r));
-}
-
-
-static ieee754sp fpemu_sp_madd(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_add(ieee754sp_mul(s, t), r);
-}
-
-static ieee754sp fpemu_sp_msub(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_sub(ieee754sp_mul(s, t), r);
-}
-
-static ieee754sp fpemu_sp_nmadd(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_neg(ieee754sp_add(ieee754sp_mul(s, t), r));
-}
-
-static ieee754sp fpemu_sp_nmsub(ieee754sp r, ieee754sp s, ieee754sp t)
-{
-	return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r));
-}
-
-static int
-fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	 mips_instruction ir)
-{
-	unsigned rcsr = 0;	/* resulting csr */
-
-	fpuemuprivate.stats.cp1xops++;
-
-	switch (MIPSInst_FMA_FFMT(ir)) {
-	case s_fmt:		/* 0 */
-		{
-			ieee754sp(*handler) (ieee754sp, ieee754sp,
-					     ieee754sp);
-			ieee754sp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case lwxc1_op:
-				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					fpureg_t val;
-					int err = 0;
-					val = mips_get_word(xcp, va, &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-					if (xcp->cp0_status & ST0_FR) {
-						/* load whole register */
-						ctx->
-						    regs[MIPSInst_FD(ir)] =
-						    val;
-					} else if (MIPSInst_FD(ir) & 1) {
-						/* load to m.s. 32 bits */
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] |=
-						    val << 32;
-#endif
-					} else {
-						/* load to l.s. 32 bits */
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    &= ~0xffffffffLL;
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    |= val;
-					}
-				}
-				break;
-
-			case swxc1_op:
-				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					unsigned int val;
-					if (xcp->cp0_status & ST0_FR) {
-						/* store whole register */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
-					} else if (MIPSInst_FS(ir) & 1) {
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						/* store from m.s. 32 bits */
-						val =
-						    ctx->
-						    regs[
-							 (MIPSInst_FS(ir) &
-							  ~1)] >> 32;
-#endif
-					} else {
-						/* store from l.s. 32 bits */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
-					}
-					if (mips_put_word(xcp, va, val)) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-				}
-				break;
-
-			case madd_s_op:
-				handler = fpemu_sp_madd;
-				goto scoptop;
-			case msub_s_op:
-				handler = fpemu_sp_msub;
-				goto scoptop;
-			case nmadd_s_op:
-				handler = fpemu_sp_nmadd;
-				goto scoptop;
-			case nmsub_s_op:
-				handler = fpemu_sp_nmsub;
-				goto scoptop;
-
-			      scoptop:
-				SPFROMREG(fr, MIPSInst_FR(ir));
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				SPTOREG(fd, MIPSInst_FD(ir));
-
-			      copcsr:
-				if (ieee754_cxtest(IEEE754_INEXACT))
-					rcsr |=
-					    FPU_CSR_INE_X | FPU_CSR_INE_S;
-				if (ieee754_cxtest(IEEE754_UNDERFLOW))
-					rcsr |=
-					    FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-				if (ieee754_cxtest(IEEE754_OVERFLOW))
-					rcsr |=
-					    FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-				if (ieee754_cxtest
-				    (IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-
-				ctx->sr =
-				    (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
-				if ((ctx->sr >> 5) & ctx->
-				    sr & FPU_CSR_ALL_E) {
-		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
-					return SIGFPE;
-				}
-
-				break;
-
-			default:
-				return SIGILL;
-			}
-		}
-		break;
-
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:		/* 1 */
-		{
-			ieee754dp(*handler) (ieee754dp, ieee754dp,
-					     ieee754dp);
-			ieee754dp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case ldxc1_op:
-				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					int err = 0;
-					ctx->regs[MIPSInst_FD(ir)] =
-					    mips_get_dword(xcp, va, &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-				}
-				break;
-
-			case sdxc1_op:
-				{
-					void *va =
-					    REG_TO_VA(xcp->
-						      regs[MIPSInst_FR(ir)]
-						      +
-						      xcp->
-						      regs[MIPSInst_FT
-							   (ir)]);
-					if (mips_put_dword
-					    (xcp, va,
-					     ctx->regs[MIPSInst_FS(ir)])) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-				}
-				break;
-
-			case madd_d_op:
-				handler = fpemu_dp_madd;
-				goto dcoptop;
-			case msub_d_op:
-				handler = fpemu_dp_msub;
-				goto dcoptop;
-			case nmadd_d_op:
-				handler = fpemu_dp_nmadd;
-				goto dcoptop;
-			case nmsub_d_op:
-				handler = fpemu_dp_nmsub;
-				goto dcoptop;
-
-			      dcoptop:
-				DPFROMREG(fr, MIPSInst_FR(ir));
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				DPTOREG(fd, MIPSInst_FD(ir));
-				goto copcsr;
-
-			default:
-				return SIGILL;
-			}
-		}
-		break;
-#endif
-
-	case 0x7:		/* 7 */
-		{
-			if (MIPSInst_FUNC(ir) != pfetch_op) {
-				return SIGILL;
-			}
-			/* ignore prefx operation */
-		}
-		break;
-
-	default:
-		return SIGILL;
-	}
-
-	return 0;
-}
-#endif
-
-
-
-/*
- * Emulate a single COP1 arithmetic instruction.
- */
-static int
-fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	mips_instruction ir)
-{
-	int rfmt;		/* resulting format */
-	unsigned rcsr = 0;	/* resulting csr */
-	unsigned cond;
-	union {
-		ieee754dp d;
-		ieee754sp s;
-		int w;
-#if __mips64
-		long long l;
-#endif
-	} rv;			/* resulting value */
-
-	fpuemuprivate.stats.cp1ops++;
-	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
-
-	case s_fmt:{		/* 0 */
-		ieee754sp(*handler) ();
-
-		switch (MIPSInst_FUNC(ir)) {
-			/* binary ops */
-		case fadd_op:
-			handler = ieee754sp_add;
-			goto scopbop;
-		case fsub_op:
-			handler = ieee754sp_sub;
-			goto scopbop;
-		case fmul_op:
-			handler = ieee754sp_mul;
-			goto scopbop;
-		case fdiv_op:
-			handler = ieee754sp_div;
-			goto scopbop;
-
-			/* unary  ops */
-#if __mips >= 2 || __mips64
-		case fsqrt_op:
-			handler = ieee754sp_sqrt;
-			goto scopuop;
-#endif
-#if __mips >= 4 && __mips != 32
-		case frsqrt_op:
-			handler = fpemu_sp_rsqrt;
-			goto scopuop;
-		case frecip_op:
-			handler = fpemu_sp_recip;
-			goto scopuop;
-#endif
-#if __mips >= 4
-		case fmovc_op:
-			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) !=
-			    ((MIPSInst_FT(ir) & 1) != 0))
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-		case fmovz_op:
-			if (xcp->regs[MIPSInst_FT(ir)] != 0)
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-		case fmovn_op:
-			if (xcp->regs[MIPSInst_FT(ir)] == 0)
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-#endif
-		case fabs_op:
-			handler = ieee754sp_abs;
-			goto scopuop;
-		case fneg_op:
-			handler = ieee754sp_neg;
-			goto scopuop;
-		case fmov_op:
-			/* an easy one */
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-			/* binary op on handler */
-scopbop:
-			{
-				ieee754sp fs, ft;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-
-				rv.s = (*handler) (fs, ft);
-				goto copcsr;
-			}
-scopuop:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = (*handler) (fs);
-				goto copcsr;
-			}
-copcsr:
-			if (ieee754_cxtest(IEEE754_INEXACT))
-				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
-			if (ieee754_cxtest(IEEE754_UNDERFLOW))
-				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-			if (ieee754_cxtest(IEEE754_OVERFLOW))
-				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
-				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
-			if (ieee754_cxtest
-				(IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-				break;
-
-				/* unary conv ops */
-		case fcvts_op:
-			return SIGILL;	/* not defined */
-		case fcvtd_op:
-#if defined(SINGLE_ONLY_FPU)
-			return SIGILL;	/* not defined */
-#else
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = ieee754dp_fsp(fs);
-				rfmt = d_fmt;
-				goto copcsr;
-			}
-#endif
-		case fcvtw_op:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754sp_tint(fs);
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-
-#if __mips >= 2 || __mips64
-		case fround_op:
-		case ftrunc_op:
-		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754sp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-#endif			/* __mips >= 2 */
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754sp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-
-		case froundl_op:
-		case ftruncl_op:
-		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754sp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-#endif /* __mips64 && !fpu(single) */
-
-		default:
-			if (MIPSInst_FUNC(ir) >= fcmp_op) {
-				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-				ieee754sp fs, ft;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]);
-				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
-					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
-				} else {
-					return SIGILL;
-				}
-				break;
-			}
-			break;
-		}
-
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt: {
-		ieee754dp(*handler) ();
-
-		switch (MIPSInst_FUNC(ir)) {
-			/* binary ops */
-		case fadd_op:
-			handler = ieee754dp_add;
-			goto dcopbop;
-		case fsub_op:
-			handler = ieee754dp_sub;
-			goto dcopbop;
-		case fmul_op:
-			handler = ieee754dp_mul;
-			goto dcopbop;
-		case fdiv_op:
-			handler = ieee754dp_div;
-			goto dcopbop;
-
-			/* unary  ops */
-#if __mips >= 2 || __mips64
-		case fsqrt_op:
-			handler = ieee754dp_sqrt;
-			goto dcopuop;
-#endif
-#if __mips >= 4 && __mips != 32
-		case frsqrt_op:
-			handler = fpemu_dp_rsqrt;
-			goto dcopuop;
-		case frecip_op:
-			handler = fpemu_dp_recip;
-			goto dcopuop;
-#endif
-#if __mips >= 4
-		case fmovc_op:
-			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0))
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-		case fmovz_op:
-			if (xcp->regs[MIPSInst_FT(ir)] != 0)
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-		case fmovn_op:
-			if (xcp->regs[MIPSInst_FT(ir)] == 0)
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-#endif
-		case fabs_op:
-			handler = ieee754dp_abs;
-			goto dcopuop;
-		case fneg_op:
-			handler = ieee754dp_neg;
-			goto dcopuop;
-		case fmov_op:
-			/* an easy one */
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-
-			/* binary op on handler */
-dcopbop:
-			{
-				ieee754dp fs, ft;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-
-				rv.d = (*handler) (fs, ft);
-				goto copcsr;
-			}
-dcopuop:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = (*handler) (fs);
-				goto copcsr;
-			}
-
-		/* unary conv ops */
-		case fcvts_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = ieee754sp_fdp(fs);
-				rfmt = s_fmt;
-				goto copcsr;
-			}
-		case fcvtd_op:
-			return SIGILL;	/* not defined */
-		case fcvtw_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754dp_tint(fs);	/* wrong */
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-
-#if __mips >= 2 || __mips64
-		case fround_op:
-		case ftrunc_op:
-		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754dp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-#endif
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754dp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-
-		case froundl_op:
-		case ftruncl_op:
-		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754dp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-#endif /* __mips >= 3 && !fpu(single) */
-
-		default:
-			if (MIPSInst_FUNC(ir) >= fcmp_op) {
-				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-				ieee754dp fs, ft;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]);
-				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
-					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
-			} else {
-				return SIGILL;
-			}
-			break;
-		}
-		break;
-	}
-#endif				/* !defined(SINGLE_ONLY_FPU) */
-
-	case w_fmt: {
-		switch (MIPSInst_FUNC(ir)) {
-		case fcvts_op:
-			/* convert word to single precision real */
-			rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = s_fmt;
-			goto copcsr;
-#if !defined(SINGLE_ONLY_FPU)
-		case fcvtd_op:
-			/* convert word to double precision real */
-			rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = d_fmt;
-			goto copcsr;
-#endif
-		default:
-			return SIGILL;
-		}
-		break;
-	}
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt: {
-		switch (MIPSInst_FUNC(ir)) {
-		case fcvts_op:
-			/* convert long to single precision real */
-			rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = s_fmt;
-			goto copcsr;
-		case fcvtd_op:
-			/* convert long to double precision real */
-			rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = d_fmt;
-			goto copcsr;
-		default:
-			return SIGILL;
-		}
-		break;
-	}
-#endif
-
-	default:
-		return SIGILL;
-	}
-
-	/*
-	 * Update the fpu CSR register for this operation.
-	 * If an exception is required, generate a tidy SIGFPE exception,
-	 * without updating the result register.
-	 * Note: cause exception bits do not accumulate, they are rewritten
-	 * for each op; only the flag/sticky bits accumulate.
-	 */
-	ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
-	if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
-		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
-		return SIGFPE;
-	}
-
-	/* 
-	 * Now we can safely write the result back to the register file.
-	 */
-	switch (rfmt) {
-	case -1: {
-#if __mips >= 4
-		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
-#else
-		cond = FPU_CSR_COND;
-#endif
-		if (rv.w)
-			ctx->sr |= cond;
-		else
-			ctx->sr &= ~cond;
-		break;
-	}
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:
-		DPTOREG(rv.d, MIPSInst_FD(ir));
-		break;
-#endif
-	case s_fmt:
-		SPTOREG(rv.s, MIPSInst_FD(ir));
-		break;
-	case w_fmt:
-		SITOREG(rv.w, MIPSInst_FD(ir));
-		break;
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt:
-		DITOREG(rv.l, MIPSInst_FD(ir));
-		break;
-#endif
-	default:
-		return SIGILL;
-	}
-
-	return 0;
-}
-
-
-/*
- * Emulate the floating point instruction at EPC, and continue
- * to run until we hit a non-fp instruction, or a backward
- * branch.  This cuts down dramatically on the per instruction 
- * exception overhead.
- */
-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp)
-{
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned long oldepc, prevepc;
-	unsigned int insn;
-	int sig = 0;
-	int err = 0;
-
-	oldepc = xcp->cp0_epc;
-	do {
-		if (current->need_resched)
-			schedule();
-
-		prevepc = xcp->cp0_epc;
-		insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err);
-		if (err) {
-			fpuemuprivate.stats.errors++;
-			return SIGBUS;
-		}
-		if (insn != 0)
-			sig = cop1Emulate(xcptno, xcp, ctx);
-		else
-			xcp->cp0_epc += 4;	/* skip nops */
-
-		if (mips_cpu.options & MIPS_CPU_FPU)
-			break;
-	} while (xcp->cp0_epc > prevepc && sig == 0);
-
-	/* SIGILL indicates a non-fpu instruction */
-	if (sig == SIGILL && xcp->cp0_epc != oldepc)
-		/* but if epc has advanced, then ignore it */
-		sig = 0;
-
-	return sig;
-}
-
-
-#ifdef NOTDEF
-/*
- * Patch up the hardware fpu state when an f.p. exception occurs.  
- */
-static int cop1Patcher(int xcptno, struct pt_regs *xcp)
-{
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned sr;
-	int sig;
-
-	/* reenable Cp1, else fpe_save() will get nested exception */
-	sr = mips_bissr(ST0_CU1);
-
-	/* get fpu registers and status, then clear pending exceptions */
-	fpe_save(ctx);
-	fpe_setsr(ctx->sr &= ~FPU_CSR_ALL_X);
-
-	/* get current rounding mode for IEEE library, and emulate insn */
-	ieee754_csr.rm = ieee_rm[ctx->sr & 0x3];
-	sig = cop1Emulate(xcptno, xcp, ctx);
-
-	/* don't return with f.p. exceptions pending */
-	ctx->sr &= ~FPU_CSR_ALL_X;
-	fpe_restore(ctx);
-
-	mips_setsr(sr);
-	return sig;
-}
-
-void _cop1_init(int emulate)
-{
-	extern int _nofpu;
-
-	if (emulate) {
-		/* 
-		 * Install cop1 emulator to handle "coprocessor unusable" exception
-		 */
-		xcption(XCPTCPU, cop1Handler);
-		fpuemuactive = 1;	/* tell dbg.c that we are in charge */
-		_nofpu = 0;	/* tell setjmp() it "has" an fpu */
-	} else {
-		/* 
-		 * Install cop1 emulator for floating point exceptions only,
-		 * i.e. denormalised results, underflow, overflow etc, which
-		 * must be emulated in s/w.
-		 */
-#if 1
-		/* r4000 or above use dedicate exception */
-		xcption(XCPTFPE, cop1Patcher);
-#else
-		/* r3000 et al use interrupt */
-		extern int _sbd_getfpuintr(void);
-		int intno = _sbd_getfpuintr();
-		intrupt(intno, cop1Patcher, 0);
-		mips_bissr(SR_IM0 << intno);
-#endif
-
-#if (#cpu(r4640) || #cpu(r4650)) && !defined(SINGLE_ONLY_FPU)
-		/* For R4640/R4650 compiled *without* the -msingle-float flag,
-		   then we share responsibility: the h/w handles the single
-		   precision operations, and the trap emulator handles the
-		   double precision. We set fpuemuactive so that dbg.c first
-		   fetches the s/w state before saving the h/w state. */
-		fpuemuactive = 1;
-		{
-			int i;
-			/* initialise the unused d.p high order words to be NaN */
-			for (i = 0; i < 32; i++)
-				current->thread.fpu.soft.regs[i] =
-				    0x7ff80bad00000000LL;
-		}
-#endif				/* (r4640 || r4650) && !fpu(single) */
-	}
-}
-#endif
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_add.c linux-2.4.20/arch/mips64/math-emu/dp_add.c
--- linux-2.4.19/arch/mips64/math-emu/dp_add.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_add.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,186 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
-{
-	COMPXDP;
-	COMPYDP;
-
-	EXPLODEXDP;
-	EXPLODEYDP;
-
-	CLEARCX;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "add", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs == ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		else
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-		/* FALL THROUGH */
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		ym = XDPSRS(ym, s);
-		ye += s;
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		xm = XDPSRS(xm, s);
-		xe += s;
-	}
-	assert(xe == ye);
-	assert(xe <= DP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 * leaving result in xm,xs,xe
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
-			xm = XDPSRS1(xm);
-			xe++;
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-		/* normalize to rounding precision */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-
-	}
-	DPNORMRET2(xs, xe, xm, "add", x, y);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_cmp.c linux-2.4.20/arch/mips64/math-emu/dp_cmp.c
--- linux-2.4.19/arch/mips64/math-emu/dp_cmp.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_cmp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
-		if (cmp & IEEE754_CUN)
-			return 1;
-		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
-				return ieee754si_xcpt(0, "fcmpf", x);
-		}
-		return 0;
-	} else {
-		long long int vx = x.bits;
-		long long int vy = y.bits;
-
-		if (vx < 0)
-			vx = -vx ^ DP_SIGN_BIT;
-		if (vy < 0)
-			vy = -vy ^ DP_SIGN_BIT;
-
-		if (vx < vy)
-			return (cmp & IEEE754_CLT) != 0;
-		else if (vx == vy)
-			return (cmp & IEEE754_CEQ) != 0;
-		else
-			return (cmp & IEEE754_CGT) != 0;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_div.c linux-2.4.20/arch/mips64/math-emu/dp_div.c
--- linux-2.4.19/arch/mips64/math-emu/dp_div.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_div.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,160 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
-{
-	COMPXDP;
-	COMPYDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-	EXPLODEYDP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "div", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return ieee754dp_zero(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return ieee754dp_inf(xs ^ ys);
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_ZERO_DIVIDE);
-		return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return ieee754dp_zero(xs == ys ? 0 : 1);
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-	/* provide rounding space */
-	xm <<= 3;
-	ym <<= 3;
-
-	{
-		/* now the dirty work */
-
-		unsigned long long rm = 0;
-		int re = xe - ye;
-		unsigned long long bm;
-
-		for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
-			if (xm >= ym) {
-				xm -= ym;
-				rm |= bm;
-				if (xm == 0)
-					break;
-			}
-			xm <<= 1;
-		}
-		rm <<= 1;
-		if (xm)
-			rm |= 1;	/* have remainder, set sticky */
-
-		assert(rm);
-
-		/* normalise rm to rounding precision ?
-		 */
-		while ((rm >> (DP_MBITS + 3)) == 0) {
-			rm <<= 1;
-			re--;
-		}
-
-		DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_fint.c linux-2.4.20/arch/mips64/math-emu/dp_fint.c
--- linux-2.4.19/arch/mips64/math-emu/dp_fint.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_fint.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,78 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_fint(int x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754dp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754dp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754dp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1 << 31))
-			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-
-#if 1
-	/* normalize - result can never be inexact or overflow */
-	xe = DP_MBITS;
-	while ((xm >> DP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-#else
-	/* normalize */
-	xe = DP_MBITS + 3;
-	while ((xm >> (DP_MBITS + 3)) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	DPNORMRET1(xs, xe, xm, "fint", x);
-#endif
-}
-
-ieee754dp ieee754dp_funs(unsigned int u)
-{
-	if ((int) u < 0)
-		return ieee754dp_add(ieee754dp_1e31(),
-				     ieee754dp_fint(u & ~(1 << 31)));
-	return ieee754dp_fint(u);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_flong.c linux-2.4.20/arch/mips64/math-emu/dp_flong.c
--- linux-2.4.19/arch/mips64/math-emu/dp_flong.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_flong.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,76 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_flong(long long x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754dp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754dp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754dp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1ULL << 63))
-			xm = (1ULL << 63);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-
-	/* normalize */
-	xe = DP_MBITS + 3;
-	if (xm >> (DP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits */
-		while (xm >> (DP_MBITS + 1 + 3)) {
-			XDPSRSX1();
-		}
-	} else {
-		/* normalize in grs extended double precision */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	DPNORMRET1(xs, xe, xm, "dp_flong", x);
-}
-
-ieee754dp ieee754dp_fulong(unsigned long long u)
-{
-	if ((long long) u < 0)
-		return ieee754dp_add(ieee754dp_1e63(),
-				     ieee754dp_flong(u & ~(1ULL << 63)));
-	return ieee754dp_flong(u);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_frexp.c linux-2.4.20/arch/mips64/math-emu/dp_frexp.c
--- linux-2.4.19/arch/mips64/math-emu/dp_frexp.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_frexp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,53 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-/* close to ieeep754dp_logb 
-*/
-ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
-{
-	COMPXDP;
-	CLEARCX;
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*eptr = 0;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	*eptr = xe + 1;
-	return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_fsp.c linux-2.4.20/arch/mips64/math-emu/dp_fsp.c
--- linux-2.4.19/arch/mips64/math-emu/dp_fsp.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_fsp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,70 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_fsp(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(builddp(xs,
-						 DP_EMAX + 1 + DP_EBIAS,
-						 ((unsigned long long) xm
-						  << (DP_MBITS -
-						      SP_MBITS))), "fsp",
-					 x);
-	case IEEE754_CLASS_INF:
-		return ieee754dp_inf(xs);
-	case IEEE754_CLASS_ZERO:
-		return ieee754dp_zero(xs);
-	case IEEE754_CLASS_DNORM:
-		/* normalize */
-		while ((xm >> SP_MBITS) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-
-	/* CANT possibly overflow,underflow, or need rounding
-	 */
-
-	/* drop the hidden bit */
-	xm &= ~SP_HIDDEN_BIT;
-
-	return builddp(xs, xe + DP_EBIAS,
-		       (unsigned long long) xm << (DP_MBITS - SP_MBITS));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_logb.c linux-2.4.20/arch/mips64/math-emu/dp_logb.c
--- linux-2.4.19/arch/mips64/math-emu/dp_logb.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_logb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,54 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_logb(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(x, "logb", x);
-	case IEEE754_CLASS_QNAN:
-		return x;
-	case IEEE754_CLASS_INF:
-		return ieee754dp_inf(0);
-	case IEEE754_CLASS_ZERO:
-		return ieee754dp_inf(1);
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	return ieee754dp_fint(xe);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_modf.c linux-2.4.20/arch/mips64/math-emu/dp_modf.c
--- linux-2.4.19/arch/mips64/math-emu/dp_modf.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_modf.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,80 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-/* modf function is always exact for a finite number
-*/
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*ip = x;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		/* far to small */
-		*ip = ieee754dp_zero(xs);
-		return x;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe < 0) {
-		*ip = ieee754dp_zero(xs);
-		return x;
-	}
-	if (xe >= DP_MBITS) {
-		*ip = x;
-		return ieee754dp_zero(xs);
-	}
-	/* generate ipart mantissa by clearing bottom bits 
-	 */
-	*ip = builddp(xs, xe + DP_EBIAS,
-		      ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
-		      ~DP_HIDDEN_BIT);
-
-	/* generate fpart mantissa by clearing top bits
-	 * and normalizing (must be able to normalize)
-	 */
-	xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
-	if (xm == 0)
-		return ieee754dp_zero(xs);
-
-	while ((xm >> DP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_mul.c linux-2.4.20/arch/mips64/math-emu/dp_mul.c
--- linux-2.4.19/arch/mips64/math-emu/dp_mul.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_mul.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,180 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
-{
-	COMPXDP;
-	COMPYDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-	EXPLODEYDP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "mul", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754dp_inf(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return ieee754dp_zero(xs ^ ys);
-
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* rm = xm * ym, re = xe+ye basicly */
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-	{
-		int re = xe + ye;
-		int rs = xs ^ ys;
-		unsigned long long rm;
-
-		/* shunt to top of word */
-		xm <<= 64 - (DP_MBITS + 1);
-		ym <<= 64 - (DP_MBITS + 1);
-
-		/* multiply 32bits xm,ym to give high 32bits rm with stickness
-		 */
-
-		/* 32 * 32 => 64 */
-#define DPXMULT(x,y)	((unsigned long long)(x) * (unsigned long long)y)
-
-		{
-			unsigned lxm = xm;
-			unsigned hxm = xm >> 32;
-			unsigned lym = ym;
-			unsigned hym = ym >> 32;
-			unsigned long long lrm;
-			unsigned long long hrm;
-
-			lrm = DPXMULT(lxm, lym);
-			hrm = DPXMULT(hxm, hym);
-
-			{
-				unsigned long long t = DPXMULT(lxm, hym);
-				{
-					unsigned long long at =
-					    lrm + (t << 32);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 32);
-			}
-
-			{
-				unsigned long long t = DPXMULT(hxm, lym);
-				{
-					unsigned long long at =
-					    lrm + (t << 32);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 32);
-			}
-			rm = hrm | (lrm != 0);
-		}
-
-		/*
-		 * sticky shift down to normal rounding precision
-		 */
-		if ((signed long long) rm < 0) {
-			rm =
-			    (rm >> (64 - (DP_MBITS + 1 + 3))) |
-			    ((rm << (DP_MBITS + 1 + 3)) != 0);
-			re++;
-		} else {
-			rm =
-			    (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
-			    ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
-		}
-		assert(rm & (DP_HIDDEN_BIT << 3));
-		DPNORMRET2(rs, re, rm, "mul", x, y);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_scalb.c linux-2.4.20/arch/mips64/math-emu/dp_scalb.c
--- linux-2.4.19/arch/mips64/math-emu/dp_scalb.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_scalb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_scalb(ieee754dp x, int n)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(x, "scalb", x, n);
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
-}
-
-
-ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
-{
-	return ieee754dp_scalb(x, n);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_simple.c linux-2.4.20/arch/mips64/math-emu/dp_simple.c
--- linux-2.4.19/arch/mips64/math-emu/dp_simple.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_simple.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,66 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-int ieee754dp_finite(ieee754dp x)
-{
-	return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
-}
-
-ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
-{
-	CLEARCX;
-	DPSIGN(x) = DPSIGN(y);
-	return x;
-}
-
-
-ieee754dp ieee754dp_neg(ieee754dp x)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x))	/* but not infinity */
-		return ieee754dp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	DPSIGN(x) ^= 1;
-	return x;
-}
-
-
-ieee754dp ieee754dp_abs(ieee754dp x)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x))	/* but not infinity */
-		return ieee754dp_nanxcpt(x, "abs", x);
-
-	/* quick fix up */
-	DPSIGN(x) = 0;
-	return x;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_sqrt.c linux-2.4.20/arch/mips64/math-emu/dp_sqrt.c
--- linux-2.4.19/arch/mips64/math-emu/dp_sqrt.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_sqrt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,167 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision square root
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-static const struct ieee754dp_konst knan = {
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-	0, 0, DP_EBIAS + DP_EMAX + 1, 0
-#else
-	0, DP_EBIAS + DP_EMAX + 1, 0, 0
-#endif
-};
-
-#define nan	((ieee754dp)knan)
-
-static const unsigned table[] = {
-	0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
-	29598, 36145, 43202, 50740, 58733, 67158, 75992,
-	85215, 83599, 71378, 60428, 50647, 41945, 34246,
-	27478, 21581, 16499, 12183, 8588, 5674, 3403,
-	1742, 661, 130
-};
-
-ieee754dp ieee754dp_sqrt(ieee754dp x)
-{
-	struct ieee754_csr oldcsr;
-	ieee754dp y, z, t;
-	unsigned scalx, yh;
-	COMPXDP;
-
-	EXPLODEXDP;
-
-	/* x == INF or NAN? */
-	switch (xc) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		/* sqrt(Nan) = Nan */
-		return ieee754dp_nanxcpt(x, "sqrt");
-	case IEEE754_CLASS_ZERO:
-		/* sqrt(0) = 0 */
-		return x;
-	case IEEE754_CLASS_INF:
-		if (xs)
-			/* sqrt(-Inf) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
-		/* sqrt(+Inf) = Inf */
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		/* fall through */
-	case IEEE754_CLASS_NORM:
-		if (xs)
-			/* sqrt(-x) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
-		break;
-	}
-
-	/* save old csr; switch off INX enable & flag; set RN rounding */
-	oldcsr = ieee754_csr;
-	ieee754_csr.mx &= ~IEEE754_INEXACT;
-	ieee754_csr.sx &= ~IEEE754_INEXACT;
-	ieee754_csr.rm = IEEE754_RN;
-
-	/* adjust exponent to prevent overflow */
-	scalx = 0;
-	if (xe > 512) {		/* x > 2**-512? */
-		xe -= 512;	/* x = x / 2**512 */
-		scalx += 256;
-	} else if (xe < -512) {	/* x < 2**-512? */
-		xe += 512;	/* x = x * 2**512 */
-		scalx -= 256;
-	}
-
-	y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-
-	/* magic initial approximation to almost 8 sig. bits */
-	yh = y.bits >> 32;
-	yh = (yh >> 1) + 0x1ff80000;
-	yh = yh - table[(yh >> 15) & 31];
-	y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff);
-
-	/* Heron's rule once with correction to improve to ~18 sig. bits */
-	/* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
-	t = ieee754dp_div(x, y);
-	y = ieee754dp_add(y, t);
-	y.bits -= 0x0010000600000000LL;
-	y.bits &= 0xffffffff00000000LL;
-
-	/* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
-	/* t=y*y; z=t;  pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
-	z = t = ieee754dp_mul(y, y);
-	t.parts.bexp += 0x001;
-	t = ieee754dp_add(t, z);
-	z = ieee754dp_mul(ieee754dp_sub(x, z), y);
-
-	/* t=z/(t+x) ;  pt[n0]+=0x00100000; y+=t; */
-	t = ieee754dp_div(z, ieee754dp_add(t, x));
-	t.parts.bexp += 0x001;
-	y = ieee754dp_add(y, t);
-
-	/* twiddle last bit to force y correctly rounded */
-
-	/* set RZ, clear INEX flag */
-	ieee754_csr.rm = IEEE754_RZ;
-	ieee754_csr.sx &= ~IEEE754_INEXACT;
-
-	/* t=x/y; ...chopped quotient, possibly inexact */
-	t = ieee754dp_div(x, y);
-
-	if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) {
-
-		if (!(ieee754_csr.sx & IEEE754_INEXACT))
-			/* t = t-ulp */
-			t.bits -= 1;
-
-		/* add inexact to result status */
-		oldcsr.cx |= IEEE754_INEXACT;
-		oldcsr.sx |= IEEE754_INEXACT;
-
-		switch (oldcsr.rm) {
-		case IEEE754_RP:
-			y.bits += 1;
-			/* drop through */
-		case IEEE754_RN:
-			t.bits += 1;
-			break;
-		}
-
-		/* y=y+t; ...chopped sum */
-		y = ieee754dp_add(y, t);
-
-		/* adjust scalx for correctly rounded sqrt(x) */
-		scalx -= 1;
-	}
-
-	/* py[n0]=py[n0]+scalx; ...scale back y */
-	y.parts.bexp += scalx;
-
-	/* restore rounding mode, possibly set inexact */
-	ieee754_csr = oldcsr;
-
-	return y;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_sub.c linux-2.4.20/arch/mips64/math-emu/dp_sub.c
--- linux-2.4.19/arch/mips64/math-emu/dp_sub.c	2001-07-02 20:56:40.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_sub.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,194 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
-{
-	COMPXDP;
-	COMPYDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-	EXPLODEYDP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "sub", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(y, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754dp_nanxcpt(x, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754dp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs != ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-		return ieee754dp_inf(ys ^ 1);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs != ys)
-			return x;
-		else
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		/* quick fix up */
-		DPSIGN(y) ^= 1;
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-		/* FAAL THOROUGH */
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		/* normalize ym,ye */
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		/* normalize xm,xe */
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* flip sign of y and handle as add */
-	ys ^= 1;
-
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-
-	/* provide guard,round and stick bit dpace */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		ym = XDPSRS(ym, s);
-		ye += s;
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		xm = XDPSRS(xm, s);
-		xe += s;
-	}
-	assert(xe == ye);
-	assert(xe <= DP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
-			xm = XDPSRS1(xm);	/* shift preserving sticky */
-			xe++;
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0) {
-			if (ieee754_csr.rm == IEEE754_RD)
-				return ieee754dp_zero(1);	/* round negative inf. => sign = -1 */
-			else
-				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
-		}
-
-		/* normalize to rounding precision 
-		 */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	DPNORMRET2(xs, xe, xm, "sub", x, y);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_tint.c linux-2.4.20/arch/mips64/math-emu/dp_tint.c
--- linux-2.4.19/arch/mips64/math-emu/dp_tint.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_tint.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,88 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include <linux/kernel.h>
-#include "ieee754dp.h"
-
-int ieee754dp_tint(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754si_xcpt(ieee754si_indef(), "fixdp", x);
-	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fixdp", x);
-	case IEEE754_CLASS_ZERO:
-		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fixdp", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe >= 31) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fix", x);
-	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fix", x);
-	}
-	/* oh gawd */
-	if (xe > DP_MBITS) {
-		xm <<= xe - DP_MBITS;
-	} else if (xe < DP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= DP_MBITS - xe;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned int ieee754dp_tuns(ieee754dp x)
-{
-	ieee754dp hb = ieee754dp_1e31();
-
-	/* what if x < 0 ?? */
-	if (ieee754dp_lt(x, hb))
-		return (unsigned) ieee754dp_tint(x);
-
-	return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |
-	    ((unsigned) 1 << 31);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/dp_tlong.c linux-2.4.20/arch/mips64/math-emu/dp_tlong.c
--- linux-2.4.19/arch/mips64/math-emu/dp_tlong.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/dp_tlong.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,141 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-long long ieee754dp_tlong(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
-	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
-	case IEEE754_CLASS_ZERO:
-		return 0;
-	case IEEE754_CLASS_DNORM:	/* much too small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "dp_tlong", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
-	}
-	if (xe < 0) {
-		if (ieee754_csr.rm == IEEE754_RU) {
-			if (xs) {	/* Negative  */
-				return 0x0000000000000000LL;
-			} else {	/* Positive */
-				return 0x0000000000000001LL;
-			}
-		} else if (ieee754_csr.rm == IEEE754_RD) {
-			if (xs) {	/* Negative , return -1 */
-				return 0xffffffffffffffffLL;
-			} else {	/* Positive */
-				return 0x0000000000000000LL;
-			}
-		} else {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754di_xcpt(0, "dp_tlong", x);
-		}
-	}
-	/* oh gawd */
-	if (xe > DP_MBITS) {
-		xm <<= xe - DP_MBITS;
-	} else if (xe < DP_MBITS) {
-		unsigned long long residue;
-		unsigned long long mask = 0;
-		int i;
-		int round;
-		int sticky;
-		int odd;
-
-		/* compute mask */
-		for (i = 0; i < DP_MBITS - xe; i++) {
-			mask = mask << 1;
-			mask = mask | 0x1;
-		}
-		residue = (xm & mask) << (64 - (DP_MBITS - xe));
-		round =
-		    ((0x8000000000000000LL & residue) !=
-		     0x0000000000000000LL);
-		sticky =
-		    ((0x7fffffffffffffffLL & residue) !=
-		     0x0000000000000000LL);
-
-		xm >>= DP_MBITS - xe;
-
-		odd = ((xm & 0x1) != 0x0000000000000000LL);
-
-		/* Do the rounding */
-		if (!round && sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)) {
-				xm++;
-			}
-		} else if (round && !sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN && odd)) {
-				xm++;
-			}
-		} else if (round && sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN)) {
-				xm++;
-			}
-		}
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned long long ieee754dp_tulong(ieee754dp x)
-{
-	ieee754dp hb = ieee754dp_1e63();
-
-	/* what if x < 0 ?? */
-	if (ieee754dp_lt(x, hb))
-		return (unsigned long long) ieee754dp_tlong(x);
-
-	return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
-	    (1ULL << 63);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754.c linux-2.4.20/arch/mips64/math-emu/ieee754.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,138 +0,0 @@
-/* ieee754 floating point arithmetic
- * single and double precision
- *
- * BUGS
- * not much dp done
- * doesnt generate IEEE754_INEXACT
- *
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754int.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-
-/* indexed by class */
-const char *const ieee754_cname[] = {
-	"Normal",
-	"Zero",
-	"Denormal",
-	"Infinity",
-	"QNaN",
-	"SNaN",
-};
-
-/* the control status register 
-*/
-struct ieee754_csr ieee754_csr;
-
-/* special constants
-*/
-
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-#define SPSTR(s,b,m) {m,b,s}
-#define DPSTR(s,b,mh,ml) {ml,mh,b,s}
-#endif
-
-#ifdef __MIPSEB__
-#define SPSTR(s,b,m) {s,b,m}
-#define DPSTR(s,b,mh,ml) {s,b,mh,ml}
-#endif
-
-const struct ieee754dp_konst __ieee754dp_spcvals[] = {
-	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* + zero   */
-	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* - zero   */
-	DPSTR(0, DP_EBIAS, 0, 0),	/* + 1.0   */
-	DPSTR(1, DP_EBIAS, 0, 0),	/* - 1.0   */
-	DPSTR(0, 3 + DP_EBIAS, 0x40000, 0),	/* + 10.0   */
-	DPSTR(1, 3 + DP_EBIAS, 0x40000, 0),	/* - 10.0   */
-	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* + infinity */
-	DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0),	/* - infinity */
-	DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x40000, 0),	/* + indef quiet Nan */
-	DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* + max */
-	DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* - max */
-	DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0),	/* + min normal */
-	DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0),	/* - min normal */
-	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* + min denormal */
-	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* - min denormal */
-	DPSTR(0, 31 + DP_EBIAS, 0, 0),	/* + 1.0e31 */
-	DPSTR(0, 63 + DP_EBIAS, 0, 0),	/* + 1.0e63 */
-};
-
-const struct ieee754sp_konst __ieee754sp_spcvals[] = {
-	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0),	/* + zero   */
-	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0),	/* - zero   */
-	SPSTR(0, SP_EBIAS, 0),	/* + 1.0   */
-	SPSTR(1, SP_EBIAS, 0),	/* - 1.0   */
-	SPSTR(0, 3 + SP_EBIAS, 0x200000),	/* + 10.0   */
-	SPSTR(1, 3 + SP_EBIAS, 0x200000),	/* - 10.0   */
-	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0),	/* + infinity */
-	SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0),	/* - infinity */
-	SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x200000),	/* + indef quiet Nan  */
-	SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* + max normal */
-	SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* - max normal */
-	SPSTR(0, SP_EMIN + SP_EBIAS, 0),	/* + min normal */
-	SPSTR(1, SP_EMIN + SP_EBIAS, 0),	/* - min normal */
-	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1),	/* + min denormal */
-	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1),	/* - min denormal */
-	SPSTR(0, 31 + SP_EBIAS, 0),	/* + 1.0e31 */
-	SPSTR(0, 63 + SP_EBIAS, 0),	/* + 1.0e63 */
-};
-
-
-int ieee754si_xcpt(int r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-	ax.op = op;
-	ax.rt = IEEE754_RT_SI;
-	ax.rv.si = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.si;
-}
-
-long long ieee754di_xcpt(long long r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-	ax.op = op;
-	ax.rt = IEEE754_RT_DI;
-	ax.rv.di = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.di;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754.h linux-2.4.20/arch/mips64/math-emu/ieee754.h
--- linux-2.4.19/arch/mips64/math-emu/ieee754.h	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,490 +0,0 @@
-/* single and double precision fp ops
- * missing extended precision.
-*/
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Modification to allow integration with Linux kernel 
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
-
-#ifdef __KERNEL__
-/* Going from Algorithmics to Linux native environment, add this */
-#include <linux/types.h>
-
-/* 
- * Not very pretty, but the Linux kernel's normal va_list definition 
- * does not allow it to be used as a structure element, as it is here.
- */
-#ifndef _STDARG_H
-#include <stdarg.h>
-#endif
-
-#else
-
-/* Note that __KERNEL__ is taken to mean Linux kernel */
-
-#if #system(OpenBSD)
-#include <machine/types.h>
-#endif
-#include <machine/endian.h>
-
-#endif				/* __KERNEL__ */
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-struct ieee754dp_konst {
-	unsigned mantlo:32;
-	unsigned manthi:20;
-	unsigned bexp:11;
-	unsigned sign:1;
-};
-struct ieee754sp_konst {
-	unsigned mant:23;
-	unsigned bexp:8;
-	unsigned sign:1;
-};
-
-typedef union _ieee754dp {
-	struct ieee754dp_konst oparts;
-	struct {
-		unsigned long long mant:52;
-		unsigned int bexp:11;
-		unsigned int sign:1;
-	} parts;
-	unsigned long long bits;
-	double d;
-} ieee754dp;
-
-typedef union _ieee754sp {
-	struct ieee754sp_konst parts;
-	float f;
-	unsigned long bits;
-} ieee754sp;
-#endif
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-struct ieee754dp_konst {
-	unsigned sign:1;
-	unsigned bexp:11;
-	unsigned manthi:20;
-	unsigned mantlo:32;
-};
-typedef union _ieee754dp {
-	struct ieee754dp_konst oparts;
-	struct {
-		unsigned int sign:1;
-		unsigned int bexp:11;
-		unsigned long long mant:52;
-	} parts;
-	double d;
-	unsigned long long bits;
-} ieee754dp;
-
-struct ieee754sp_konst {
-	unsigned sign:1;
-	unsigned bexp:8;
-	unsigned mant:23;
-};
-
-typedef union _ieee754sp {
-	struct ieee754sp_konst parts;
-	float f;
-	unsigned long bits;
-} ieee754sp;
-#endif
-
-/*
- * single precision (often aka float)
-*/
-int ieee754sp_finite(ieee754sp x);
-int ieee754sp_class(ieee754sp x);
-
-ieee754sp ieee754sp_abs(ieee754sp x);
-ieee754sp ieee754sp_neg(ieee754sp x);
-ieee754sp ieee754sp_scalb(ieee754sp x, int);
-ieee754sp ieee754sp_logb(ieee754sp x);
-
-/* x with sign of y */
-ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
-
-ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
-
-ieee754sp ieee754sp_fint(int x);
-ieee754sp ieee754sp_funs(unsigned x);
-ieee754sp ieee754sp_flong(long long x);
-ieee754sp ieee754sp_fulong(unsigned long long x);
-ieee754sp ieee754sp_fdp(ieee754dp x);
-
-int ieee754sp_tint(ieee754sp x);
-unsigned int ieee754sp_tuns(ieee754sp x);
-long long ieee754sp_tlong(ieee754sp x);
-unsigned long long ieee754sp_tulong(ieee754sp x);
-
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop);
-/*
- * basic sp math
- */
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
-ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
-ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
-
-ieee754sp ieee754sp_ceil(ieee754sp x);
-ieee754sp ieee754sp_floor(ieee754sp x);
-ieee754sp ieee754sp_trunc(ieee754sp x);
-
-ieee754sp ieee754sp_sqrt(ieee754sp x);
-
-/*
- * double precision (often aka double)
-*/
-int ieee754dp_finite(ieee754dp x);
-int ieee754dp_class(ieee754dp x);
-
-/* x with sign of y */
-ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
-
-ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
-
-ieee754dp ieee754dp_abs(ieee754dp x);
-ieee754dp ieee754dp_neg(ieee754dp x);
-ieee754dp ieee754dp_scalb(ieee754dp x, int);
-
-/* return exponent as integer in floating point format 
- */
-ieee754dp ieee754dp_logb(ieee754dp x);
-
-ieee754dp ieee754dp_fint(int x);
-ieee754dp ieee754dp_funs(unsigned x);
-ieee754dp ieee754dp_flong(long long x);
-ieee754dp ieee754dp_fulong(unsigned long long x);
-ieee754dp ieee754dp_fsp(ieee754sp x);
-
-ieee754dp ieee754dp_ceil(ieee754dp x);
-ieee754dp ieee754dp_floor(ieee754dp x);
-ieee754dp ieee754dp_trunc(ieee754dp x);
-
-int ieee754dp_tint(ieee754dp x);
-unsigned int ieee754dp_tuns(ieee754dp x);
-long long ieee754dp_tlong(ieee754dp x);
-unsigned long long ieee754dp_tulong(ieee754dp x);
-
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop);
-/*
- * basic sp math
- */
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
-ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
-ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
-
-ieee754dp ieee754dp_ceil(ieee754dp x);
-ieee754dp ieee754dp_floor(ieee754dp x);
-ieee754dp ieee754dp_trunc(ieee754dp x);
-
-ieee754dp ieee754dp_sqrt(ieee754dp x);
-
-
-
-/* 5 types of floating point number 
-*/
-#define IEEE754_CLASS_NORM	0x00
-#define IEEE754_CLASS_ZERO	0x01
-#define IEEE754_CLASS_DNORM	0x02
-#define IEEE754_CLASS_INF	0x03
-#define IEEE754_CLASS_SNAN	0x04
-#define IEEE754_CLASS_QNAN	0x05
-extern const char *const ieee754_cname[];
-
-/* exception numbers */
-#define IEEE754_INEXACT			0x01
-#define IEEE754_UNDERFLOW		0x02
-#define IEEE754_OVERFLOW		0x04
-#define IEEE754_ZERO_DIVIDE		0x08
-#define IEEE754_INVALID_OPERATION	0x10
-
-/* cmp operators
-*/
-#define IEEE754_CLT	0x01
-#define IEEE754_CEQ	0x02
-#define IEEE754_CGT	0x04
-#define IEEE754_CUN	0x08
-
-/* rounding mode 
-*/
-#define IEEE754_RN	0	/* round to nearest */
-#define IEEE754_RZ	1	/* round toward zero  */
-#define IEEE754_RD	2	/* round toward -Infinity */
-#define IEEE754_RU	3	/* round toward +Infinity */
-
-/* other naming */
-#define IEEE754_RM	IEEE754_RD
-#define IEEE754_RP	IEEE754_RU
-
-/* "normal" comparisons
-*/
-static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CEQ);
-}
-
-static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
-}
-
-static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CLT);
-}
-
-static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
-}
-
-static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CGT);
-}
-
-
-static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
-}
-
-static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CLT);
-}
-
-static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CGT);
-}
-
-static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
-}
-
-
-/* like strtod
-*/
-ieee754dp ieee754dp_fstr(const char *s, char **endp);
-char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
-
-
-/* the control status register 
-*/
-struct ieee754_csr {
-	unsigned pad:13;
-	unsigned noq:1;		/* set 1 for no quiet NaN's */
-	unsigned nod:1;		/* set 1 for no denormalised numbers */
-	unsigned cx:5;		/* exceptions this operation */
-	unsigned mx:5;		/* exception enable  mask */
-	unsigned sx:5;		/* exceptions total */
-	unsigned rm:2;		/* current rounding mode */
-};
-extern struct ieee754_csr ieee754_csr;
-
-static __inline unsigned ieee754_getrm(void)
-{
-	return (ieee754_csr.rm);
-}
-static __inline unsigned ieee754_setrm(unsigned rm)
-{
-	return (ieee754_csr.rm = rm);
-}
-
-/*
- * get current exceptions
- */
-static __inline unsigned ieee754_getcx(void)
-{
-	return (ieee754_csr.cx);
-}
-
-/* test for current exception condition 
- */
-static __inline int ieee754_cxtest(unsigned n)
-{
-	return (ieee754_csr.cx & n);
-}
-
-/*
- * get sticky exceptions
- */
-static __inline unsigned ieee754_getsx(void)
-{
-	return (ieee754_csr.sx);
-}
-
-/* clear sticky conditions
-*/
-static __inline unsigned ieee754_clrsx(void)
-{
-	return (ieee754_csr.sx = 0);
-}
-
-/* test for sticky exception condition 
- */
-static __inline int ieee754_sxtest(unsigned n)
-{
-	return (ieee754_csr.sx & n);
-}
-
-/* debugging */
-ieee754sp ieee754sp_dump(char *s, ieee754sp x);
-ieee754dp ieee754dp_dump(char *s, ieee754dp x);
-
-#define IEEE754_SPCVAL_PZERO	0
-#define IEEE754_SPCVAL_NZERO	1
-#define IEEE754_SPCVAL_PONE	2
-#define IEEE754_SPCVAL_NONE	3
-#define IEEE754_SPCVAL_PTEN	4
-#define IEEE754_SPCVAL_NTEN	5
-#define IEEE754_SPCVAL_PINFINITY	6
-#define IEEE754_SPCVAL_NINFINITY	7
-#define IEEE754_SPCVAL_INDEF	8
-#define IEEE754_SPCVAL_PMAX	9	/* +max norm */
-#define IEEE754_SPCVAL_NMAX	10	/* -max norm */
-#define IEEE754_SPCVAL_PMIN	11	/* +min norm */
-#define IEEE754_SPCVAL_NMIN	12	/* +min norm */
-#define IEEE754_SPCVAL_PMIND	13	/* +min denorm */
-#define IEEE754_SPCVAL_NMIND	14	/* +min denorm */
-#define IEEE754_SPCVAL_P1E31	15	/* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63	16	/* + 1.0e63 */
-
-extern const struct ieee754dp_konst __ieee754dp_spcvals[];
-extern const struct ieee754sp_konst __ieee754sp_spcvals[];
-#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
-#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
-
-/* return infinity with given sign
-*/
-#define ieee754dp_inf(sn)	\
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754dp_zero(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754dp_one(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754dp_ten(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754dp_max(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754dp_min(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754dp_mind(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754dp_1e31() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754dp_1e63() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
-
-#define ieee754sp_inf(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754sp_zero(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754sp_one(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754sp_ten(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754sp_max(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754sp_min(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754sp_mind(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754sp_1e31() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754sp_1e63() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
-
-/* indefinite integer value 
-*/
-#define ieee754si_indef()	INT_MIN
-#ifdef LONG_LONG_MIN
-#define ieee754di_indef()	LONG_LONG_MIN
-#else
-#define ieee754di_indef()	(-9223372036854775807LL-1)
-#endif
-
-/* IEEE exception context, passed to handler */
-struct ieee754xctx {
-	const char *op;		/* operation name */
-	int rt;			/* result type */
-	union {
-		ieee754sp sp;	/* single precision */
-		ieee754dp dp;	/* double precision */
-#ifdef IEEE854_XP
-		ieee754xp xp;	/* extended precision */
-#endif
-		int si;		/* standard signed integer (32bits) */
-		long long di;	/* extended signed integer (64bits) */
-	} rv;			/* default result format implied by op */
-	va_list ap;
-};
-
-/* result types for xctx.rt */
-#define IEEE754_RT_SP	0
-#define IEEE754_RT_DP	1
-#define IEEE754_RT_XP	2
-#define IEEE754_RT_SI	3
-#define IEEE754_RT_DI	4
-
-extern void ieee754_xcpt(struct ieee754xctx *xcp);
-
-/* compat */
-#define ieee754dp_fix(x)	ieee754dp_tint(x)
-#define ieee754sp_fix(x)	ieee754sp_tint(x)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754d.c linux-2.4.20/arch/mips64/math-emu/ieee754d.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754d.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754d.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,142 +0,0 @@
-/* some debug functions
-*/
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Modified to build and operate in Linux kernel environment. 
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
-
-#include "ieee754.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-#define DP_FBITS	52
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-#define SP_FBITS	23
-
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
-#define DP_HIDDEN_BIT	DP_MBIT(DP_FBITS)
-#define DP_SIGN_BIT	DP_MBIT(63)
-
-
-#define SP_MBIT(x)	((unsigned long)1 << (x))
-#define SP_HIDDEN_BIT	SP_MBIT(SP_FBITS)
-#define SP_SIGN_BIT	SP_MBIT(31)
-
-
-#define SPSIGN(sp)	(sp.parts.sign)
-#define SPBEXP(sp)	(sp.parts.bexp)
-#define SPMANT(sp)	(sp.parts.mant)
-
-#define DPSIGN(dp)	(dp.parts.sign)
-#define DPBEXP(dp)	(dp.parts.bexp)
-#define DPMANT(dp)	(dp.parts.mant)
-
-ieee754dp ieee754dp_dump(char *m, ieee754dp x)
-{
-	int i;
-
-	printk("%s", m);
-	printk("<%08x,%08x>\n", (unsigned) (x.bits >> 32),
-	       (unsigned) x.bits);
-	printk("\t=");
-	switch (ieee754dp_class(x)) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		printk("Nan %c", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		break;
-	case IEEE754_CLASS_INF:
-		printk("%cInfinity", DPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_ZERO:
-		printk("%cZero", DPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_DNORM:
-		printk("%c0.", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		printk("e%d", DPBEXP(x) - DP_EBIAS);
-		break;
-	case IEEE754_CLASS_NORM:
-		printk("%c1.", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		printk("e%d", DPBEXP(x) - DP_EBIAS);
-		break;
-	default:
-		printk("Illegal/Unknown IEEE754 value class");
-	}
-	printk("\n");
-	return x;
-}
-
-ieee754sp ieee754sp_dump(char *m, ieee754sp x)
-{
-	int i;
-
-	printk("%s=", m);
-	printk("<%08x>\n", (unsigned) x.bits);
-	printk("\t=");
-	switch (ieee754sp_class(x)) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		printk("Nan %c", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		break;
-	case IEEE754_CLASS_INF:
-		printk("%cInfinity", SPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_ZERO:
-		printk("%cZero", SPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_DNORM:
-		printk("%c0.", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		printk("e%d", SPBEXP(x) - SP_EBIAS);
-		break;
-	case IEEE754_CLASS_NORM:
-		printk("%c1.", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		printk("e%d", SPBEXP(x) - SP_EBIAS);
-		break;
-	default:
-		printk("Illegal/Unknown IEEE754 value class");
-	}
-	printk("\n");
-	return x;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754dp.c linux-2.4.20/arch/mips64/math-emu/ieee754dp.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754dp.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754dp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,197 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754dp.h"
-
-int ieee754dp_class(ieee754dp x)
-{
-	COMPXDP;
-	EXPLODEXDP;
-	return xc;
-}
-
-int ieee754dp_isnan(ieee754dp x)
-{
-	return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
-}
-
-int ieee754dp_issnan(ieee754dp x)
-{
-	assert(ieee754dp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(DPMANT(x) & DP_MBIT(DP_MBITS - 1));
-}
-
-
-ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-	if (!TSTX())
-		return r;
-
-	ax.op = op;
-	ax.rt = IEEE754_RT_DP;
-	ax.rv.dp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.dp;
-}
-
-ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	assert(ieee754dp_isnan(r));
-
-	if (!ieee754dp_issnan(r))	/* QNAN does not cause invalid op !! */
-		return r;
-
-	if (!SETCX(IEEE754_INVALID_OPERATION)) {
-		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
-			return r;
-		DPMANT(r) |= DP_MBIT(DP_MBITS - 1);
-		return r;
-	}
-
-	ax.op = op;
-	ax.rt = 0;
-	ax.rv.dp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.dp;
-}
-
-ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
-{
-	assert(ieee754dp_isnan(x));
-	assert(ieee754dp_isnan(y));
-
-	if (DPMANT(x) > DPMANT(y))
-		return x;
-	else
-		return y;
-}
-
-
-/* generate a normal/denormal number with over,under handeling
- * sn is sign
- * xe is an unbiased exponent
- * xm is 3bit extended precision value.
- */
-ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
-{
-	assert(xm);		/* we dont gen exact zeros (probably should) */
-
-	assert((xm >> (DP_MBITS + 1 + 3)) == 0);	/* no execess */
-	assert(xm & (DP_HIDDEN_BIT << 3));
-
-	if (xe < DP_EMIN) {
-		/* strip lower bits */
-		int es = DP_EMIN - xe;
-
-		if (ieee754_csr.nod) {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754dp_zero(sn);
-		}
-
-		/* sticky right shift es bits 
-		 */
-		xm = XDPSRS(xm, es);
-		xe += es;
-
-		assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
-		assert(xe == DP_EMIN);
-	}
-	if (xm & (DP_MBIT(3) - 1)) {
-		SETCX(IEEE754_INEXACT);
-		/* inexact must round of 3 bits 
-		 */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RZ:
-			break;
-		case IEEE754_RN:
-			xm += 0x3 + ((xm >> 3) & 1);
-			/* xm += (xm&0x8)?0x4:0x3 */
-			break;
-		case IEEE754_RU:	/* toward +Infinity */
-			if (!sn)	/* ?? */
-				xm += 0x8;
-			break;
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn)	/* ?? */
-				xm += 0x8;
-			break;
-		}
-		/* adjust exponent for rounding add overflowing 
-		 */
-		if (xm >> (DP_MBITS + 3 + 1)) {	/* add causes mantissa overflow */
-			xm >>= 1;
-			xe++;
-		}
-	}
-	/* strip grs bits */
-	xm >>= 3;
-
-	assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
-	assert(xe >= DP_EMIN);
-
-	if (xe > DP_EMAX) {
-		SETCX(IEEE754_OVERFLOW);
-		/* -O can be table indexed by (rm,sn) */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RN:
-			return ieee754dp_inf(sn);
-		case IEEE754_RZ:
-			return ieee754dp_max(sn);
-		case IEEE754_RU:	/* toward +Infinity */
-			if (sn == 0)
-				return ieee754dp_inf(0);
-			else
-				return ieee754dp_max(1);
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn == 0)
-				return ieee754dp_max(0);
-			else
-				return ieee754dp_inf(1);
-		}
-	}
-	/* gen norm/denorm/zero */
-
-	if ((xm & DP_HIDDEN_BIT) == 0) {
-		/* we underflow (tiny/zero) */
-		assert(xe == DP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
-		return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
-	} else {
-		assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
-		assert(xm & DP_HIDDEN_BIT);
-
-		return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754dp.h linux-2.4.20/arch/mips64/math-emu/ieee754dp.h
--- linux-2.4.19/arch/mips64/math-emu/ieee754dp.h	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754dp.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,83 +0,0 @@
-/* 
- * IEEE754 floating point
- * double precision internal header file
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754int.h"
-
-#define assert(expr) ((void)0)
-
-/* 3bit extended double precision sticky right shift */
-#define XDPSRS(v,rs)	\
-  ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
-
-#define XDPSRSX1() \
-  (xe++, (xm = (xm >> 1) | (xm & 1)))
-
-#define XDPSRS1(v)	\
-  (((v) >> 1) | ((v) & 1))
-
-/* convert denormal to normalized with extended exponent */
-#define DPDNORMx(m,e) \
-  while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
-#define DPDNORMX	DPDNORMx(xm,xe)
-#define DPDNORMY	DPDNORMx(ym,ye)
-
-static __inline ieee754dp builddp(int s, int bx, unsigned long long m)
-{
-	ieee754dp r;
-
-	assert((s) == 0 || (s) == 1);
-	assert((bx) >= DP_EMIN - 1 + DP_EBIAS
-	       && (bx) <= DP_EMAX + 1 + DP_EBIAS);
-	assert(((m) >> DP_MBITS) == 0);
-
-	r.parts.sign = s;
-	r.parts.bexp = bx;
-	r.parts.mant = m;
-	return r;
-}
-
-extern int ieee754dp_isnan(ieee754dp);
-extern int ieee754dp_issnan(ieee754dp);
-extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
-extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
-extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
-extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
-extern ieee754dp ieee754dp_format(int, int, unsigned long long);
-
-
-#define DPNORMRET2(s,e,m,name,a0,a1) \
-{ \
-    ieee754dp V = ieee754dp_format(s,e,m); \
-    if(TSTX()) \
-      return ieee754dp_xcpt(V,name,a0,a1); \
-    else \
-      return V; \
-}
-
-#define DPNORMRET1(s,e,m,name,a0)  DPNORMRET2(s,e,m,name,a0,a0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754int.h linux-2.4.20/arch/mips64/math-emu/ieee754int.h
--- linux-2.4.19/arch/mips64/math-emu/ieee754int.h	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754int.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,135 +0,0 @@
-/* 
- * IEEE754 floating point
- * common internal header file
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-#define DP_MBITS	52
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-#define SP_MBITS	23
-
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
-#define DP_HIDDEN_BIT	DP_MBIT(DP_MBITS)
-#define DP_SIGN_BIT	DP_MBIT(63)
-
-#define SP_MBIT(x)	((unsigned long)1 << (x))
-#define SP_HIDDEN_BIT	SP_MBIT(SP_MBITS)
-#define SP_SIGN_BIT	SP_MBIT(31)
-
-
-#define SPSIGN(sp)	(sp.parts.sign)
-#define SPBEXP(sp)	(sp.parts.bexp)
-#define SPMANT(sp)	(sp.parts.mant)
-
-#define DPSIGN(dp)	(dp.parts.sign)
-#define DPBEXP(dp)	(dp.parts.bexp)
-#define DPMANT(dp)	(dp.parts.mant)
-
-#define CLPAIR(x,y)	((x)*6+(y))
-
-#define CLEARCX	\
-  (ieee754_csr.cx = 0)
-
-#define SETCX(x) \
-  (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x))
-
-#define TSTX()	\
-	(ieee754_csr.cx & ieee754_csr.mx)
-
-
-#define COMPXSP \
-  unsigned xm; int xe; int xs; int xc
-
-#define COMPYSP \
-  unsigned ym; int ye; int ys; int yc
-
-#define EXPLODESP(v,vc,vs,ve,vm) \
-{\
-    vs = SPSIGN(v);\
-    ve = SPBEXP(v);\
-    vm = SPMANT(v);\
-    if(ve == SP_EMAX+1+SP_EBIAS){\
-	if(vm == 0)\
-	  vc = IEEE754_CLASS_INF;\
-	else if(vm & SP_MBIT(SP_MBITS-1)) \
-	  vc = IEEE754_CLASS_QNAN;\
-	else \
-	  vc = IEEE754_CLASS_SNAN;\
-    } else if(ve == SP_EMIN-1+SP_EBIAS) {\
-	if(vm) {\
-	    ve = SP_EMIN;\
-	    vc = IEEE754_CLASS_DNORM;\
-	} else\
-	  vc = IEEE754_CLASS_ZERO;\
-    } else {\
-	ve -= SP_EBIAS;\
-	vm |= SP_HIDDEN_BIT;\
-	vc = IEEE754_CLASS_NORM;\
-    }\
-}
-#define EXPLODEXSP EXPLODESP(x,xc,xs,xe,xm)
-#define EXPLODEYSP EXPLODESP(y,yc,ys,ye,ym)
-
-
-#define COMPXDP \
-unsigned long long xm; int xe; int xs; int xc
-
-#define COMPYDP \
-unsigned long long ym; int ye; int ys; int yc
-
-#define EXPLODEDP(v,vc,vs,ve,vm) \
-{\
-    vm = DPMANT(v);\
-    vs = DPSIGN(v);\
-    ve = DPBEXP(v);\
-    if(ve == DP_EMAX+1+DP_EBIAS){\
-	if(vm == 0)\
-	  vc = IEEE754_CLASS_INF;\
-	else if(vm & DP_MBIT(DP_MBITS-1)) \
-	  vc = IEEE754_CLASS_QNAN;\
-	else \
-	  vc = IEEE754_CLASS_SNAN;\
-    } else if(ve == DP_EMIN-1+DP_EBIAS) {\
-	if(vm) {\
-	    ve = DP_EMIN;\
-	    vc = IEEE754_CLASS_DNORM;\
-	} else\
-	  vc = IEEE754_CLASS_ZERO;\
-    } else {\
-	ve -= DP_EBIAS;\
-	vm |= DP_HIDDEN_BIT;\
-	vc = IEEE754_CLASS_NORM;\
-    }\
-}
-#define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm)
-#define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754m.c linux-2.4.20/arch/mips64/math-emu/ieee754m.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754m.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754m.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,56 +0,0 @@
-/*
- * floor, trunc, ceil
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754.h"
-
-ieee754dp ieee754dp_floor(ieee754dp x)
-{
-	ieee754dp i;
-
-	if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
-		return ieee754dp_sub(i, ieee754dp_one(0));
-	else
-		return i;
-}
-
-ieee754dp ieee754dp_ceil(ieee754dp x)
-{
-	ieee754dp i;
-
-	if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
-		return ieee754dp_add(i, ieee754dp_one(0));
-	else
-		return i;
-}
-
-ieee754dp ieee754dp_trunc(ieee754dp x)
-{
-	ieee754dp i;
-
-	(void) ieee754dp_modf(x, &i);
-	return i;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754sp.c linux-2.4.20/arch/mips64/math-emu/ieee754sp.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754sp.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754sp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,197 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-int ieee754sp_class(ieee754sp x)
-{
-	COMPXSP;
-	EXPLODEXSP;
-	return xc;
-}
-
-int ieee754sp_isnan(ieee754sp x)
-{
-	return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
-}
-
-int ieee754sp_issnan(ieee754sp x)
-{
-	assert(ieee754sp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1));
-}
-
-
-ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-
-	ax.op = op;
-	ax.rt = IEEE754_RT_SP;
-	ax.rv.sp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.sp;
-}
-
-ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	assert(ieee754sp_isnan(r));
-
-	if (!ieee754sp_issnan(r))	/* QNAN does not cause invalid op !! */
-		return r;
-
-	if (!SETCX(IEEE754_INVALID_OPERATION)) {
-		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
-			return r;
-		SPMANT(r) |= SP_MBIT(SP_MBITS - 1);
-		return r;
-	}
-
-	ax.op = op;
-	ax.rt = 0;
-	ax.rv.sp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.sp;
-}
-
-ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
-{
-	assert(ieee754sp_isnan(x));
-	assert(ieee754sp_isnan(y));
-
-	if (SPMANT(x) > SPMANT(y))
-		return x;
-	else
-		return y;
-}
-
-
-/* generate a normal/denormal number with over,under handeling
- * sn is sign
- * xe is an unbiased exponent
- * xm is 3bit extended precision value.
- */
-ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
-{
-	assert(xm);		/* we dont gen exact zeros (probably should) */
-
-	assert((xm >> (SP_MBITS + 1 + 3)) == 0);	/* no execess */
-	assert(xm & (SP_HIDDEN_BIT << 3));
-
-	if (xe < SP_EMIN) {
-		/* strip lower bits */
-		int es = SP_EMIN - xe;
-
-		if (ieee754_csr.nod) {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754sp_zero(sn);
-		}
-
-		/* sticky right shift es bits 
-		 */
-		SPXSRSXn(es);
-
-		assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
-		assert(xe == SP_EMIN);
-	}
-	if (xm & (SP_MBIT(3) - 1)) {
-		SETCX(IEEE754_INEXACT);
-		/* inexact must round of 3 bits 
-		 */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RZ:
-			break;
-		case IEEE754_RN:
-			xm += 0x3 + ((xm >> 3) & 1);
-			/* xm += (xm&0x8)?0x4:0x3 */
-			break;
-		case IEEE754_RU:	/* toward +Infinity */
-			if (!sn)	/* ?? */
-				xm += 0x8;
-			break;
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn)	/* ?? */
-				xm += 0x8;
-			break;
-		}
-		/* adjust exponent for rounding add overflowing 
-		 */
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* add causes mantissa overflow */
-			xm >>= 1;
-			xe++;
-		}
-	}
-	/* strip grs bits */
-	xm >>= 3;
-
-	assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
-	assert(xe >= SP_EMIN);
-
-	if (xe > SP_EMAX) {
-		SETCX(IEEE754_OVERFLOW);
-		/* -O can be table indexed by (rm,sn) */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RN:
-			return ieee754sp_inf(sn);
-		case IEEE754_RZ:
-			return ieee754sp_max(sn);
-		case IEEE754_RU:	/* toward +Infinity */
-			if (sn == 0)
-				return ieee754sp_inf(0);
-			else
-				return ieee754sp_max(1);
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn == 0)
-				return ieee754sp_max(0);
-			else
-				return ieee754sp_inf(1);
-		}
-	}
-	/* gen norm/denorm/zero */
-
-	if ((xm & SP_HIDDEN_BIT) == 0) {
-		/* we underflow (tiny/zero) */
-		assert(xe == SP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
-		return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
-	} else {
-		assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
-		assert(xm & SP_HIDDEN_BIT);
-
-		return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754sp.h linux-2.4.20/arch/mips64/math-emu/ieee754sp.h
--- linux-2.4.19/arch/mips64/math-emu/ieee754sp.h	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754sp.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,89 +0,0 @@
-/* 
- * IEEE754 floating point
- * double precision internal header file
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754int.h"
-
-#define assert(expr) ((void)0)
-
-/* 3bit extended single precision sticky right shift */
-#define SPXSRSXn(rs) \
-  (xe += rs, \
-   xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
-
-#define SPXSRSX1() \
-  (xe++, (xm = (xm >> 1) | (xm & 1)))
-
-#define SPXSRSYn(rs) \
-   (ye+=rs, \
-    ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
-
-#define SPXSRSY1() \
-   (ye++, (ym = (ym >> 1) | (ym & 1)))
-
-/* convert denormal to normalized with extended exponent */
-#define SPDNORMx(m,e) \
-  while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
-#define SPDNORMX	SPDNORMx(xm,xe)
-#define SPDNORMY	SPDNORMx(ym,ye)
-
-static __inline ieee754sp buildsp(int s, int bx, unsigned m)
-{
-	ieee754sp r;
-
-	assert((s) == 0 || (s) == 1);
-	assert((bx) >= SP_EMIN - 1 + SP_EBIAS
-	       && (bx) <= SP_EMAX + 1 + SP_EBIAS);
-	assert(((m) >> SP_MBITS) == 0);
-
-	r.parts.sign = s;
-	r.parts.bexp = bx;
-	r.parts.mant = m;
-
-	return r;
-}
-
-extern int ieee754sp_isnan(ieee754sp);
-extern int ieee754sp_issnan(ieee754sp);
-extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
-extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
-extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
-extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
-extern ieee754sp ieee754sp_format(int, int, unsigned);
-
-
-#define SPNORMRET2(s,e,m,name,a0,a1) \
-{ \
-    ieee754sp V = ieee754sp_format(s,e,m); \
-    if(TSTX()) \
-      return ieee754sp_xcpt(V,name,a0,a1); \
-    else \
-      return V; \
-}
-
-#define SPNORMRET1(s,e,m,name,a0)  SPNORMRET2(s,e,m,name,a0,a0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/ieee754xcpt.c linux-2.4.20/arch/mips64/math-emu/ieee754xcpt.c
--- linux-2.4.19/arch/mips64/math-emu/ieee754xcpt.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/ieee754xcpt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,48 +0,0 @@
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Added preprocessor hacks to map to Linux kernel diagnostics. 
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-
-#include "ieee754.h"
-
-/*
- * Very naff exception handler (you can plug in your own and
- * override this).
- */
-
-static const char *const rtnames[] = {
-	"sp", "dp", "xp", "si", "di"
-};
-
-void ieee754_xcpt(struct ieee754xctx *xcp)
-{
-	printk("floating point exception in \"%s\", type=%s\n",
-		xcp->op, rtnames[xcp->rt]);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/kernel_linkage.c linux-2.4.20/arch/mips64/math-emu/kernel_linkage.c
--- linux-2.4.19/arch/mips64/math-emu/kernel_linkage.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/kernel_linkage.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,95 +0,0 @@
-/**************************************************************************
- *
- *  arch/mips/math_emu/kernel_linkage.c
- *
- *  Kevin D. Kissell, kevink@mips and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- *************************************************************************/
-/*
- * Routines corresponding to Linux kernel FP context
- * manipulation primitives for the Algorithmics MIPS
- * FPU Emulator
- */
-
-#include <linux/sched.h>
-#include <asm/processor.h>
-#include <asm/signal.h>
-#include <asm/uaccess.h>
-
-#include <asm/fpu_emulator.h>
-
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
-#define SIGNALLING_NAN 0x7ff800007ff80000LL
-
-void fpu_emulator_init_fpu(void)
-{
-	static int first = 1;
-	int i;
- 
-	if (first) {
-		first = 0;
-		printk("Algorithmics/MIPS FPU Emulator v1.4\n");
-	}
-
-	current->thread.fpu.soft.sr = 0;
-	for (i = 0; i < 32; i++) {
-		current->thread.fpu.soft.regs[i] = SIGNALLING_NAN;
-	}
-}
-
-
-/*
- * Emulator context save/restore to/from a signal context
- * presumed to be on the user stack, and therefore accessed
- * with appropriate macros from uaccess.h
- */
-
-int fpu_emulator_save_context(struct sigcontext *sc)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0; i < 32; i++) {
-		err |=
-		    __put_user(current->thread.fpu.soft.regs[i],
-			       &sc->sc_fpregs[i]);
-	}
-	err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
-	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
-
-	return err;
-}
-
-int fpu_emulator_restore_context(struct sigcontext *sc)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0; i < 32; i++) {
-		err |=
-		    __get_user(current->thread.fpu.soft.regs[i],
-			       &sc->sc_fpregs[i]);
-	}
-	err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
-	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
-
-	return err;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_add.c linux-2.4.20/arch/mips64/math-emu/sp_add.c
--- linux-2.4.19/arch/mips64/math-emu/sp_add.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_add.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,180 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
-{
-	COMPXSP;
-	COMPYSP;
-
-	EXPLODEXSP;
-	EXPLODEYSP;
-
-	CLEARCX;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "add", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs == ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		else
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		SPXSRSYn(s);
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		SPXSRSXn(s);
-	}
-	assert(xe == ye);
-	assert(xe <= SP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 * leaving result in xm,xs,xe
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
-			SPXSRSX1();
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-		/* normalize in extended single precision */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-
-	}
-	SPNORMRET2(xs, xe, xm, "add", x, y);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_cmp.c linux-2.4.20/arch/mips64/math-emu/sp_cmp.c
--- linux-2.4.19/arch/mips64/math-emu/sp_cmp.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_cmp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
-		if (cmp & IEEE754_CUN)
-			return 1;
-		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
-				return ieee754si_xcpt(0, "fcmpf", x);
-		}
-		return 0;
-	} else {
-		int vx = x.bits;
-		int vy = y.bits;
-
-		if (vx < 0)
-			vx = -vx ^ SP_SIGN_BIT;
-		if (vy < 0)
-			vy = -vy ^ SP_SIGN_BIT;
-
-		if (vx < vy)
-			return (cmp & IEEE754_CLT) != 0;
-		else if (vx == vy)
-			return (cmp & IEEE754_CEQ) != 0;
-		else
-			return (cmp & IEEE754_CGT) != 0;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_div.c linux-2.4.20/arch/mips64/math-emu/sp_div.c
--- linux-2.4.19/arch/mips64/math-emu/sp_div.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_div.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,160 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
-{
-	COMPXSP;
-	COMPYSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-	EXPLODEYSP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "div", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return ieee754sp_zero(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return ieee754sp_inf(xs ^ ys);
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_ZERO_DIVIDE);
-		return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return ieee754sp_zero(xs == ys ? 0 : 1);
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	/* provide rounding space */
-	xm <<= 3;
-	ym <<= 3;
-
-	{
-		/* now the dirty work */
-
-		unsigned rm = 0;
-		int re = xe - ye;
-		unsigned bm;
-
-		for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
-			if (xm >= ym) {
-				xm -= ym;
-				rm |= bm;
-				if (xm == 0)
-					break;
-			}
-			xm <<= 1;
-		}
-		rm <<= 1;
-		if (xm)
-			rm |= 1;	/* have remainder, set sticky */
-
-		assert(rm);
-
-		/* normalise rm to rounding precision ?
-		 */
-		while ((rm >> (SP_MBITS + 3)) == 0) {
-			rm <<= 1;
-			re--;
-		}
-
-		SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_fdp.c linux-2.4.20/arch/mips64/math-emu/sp_fdp.c
--- linux-2.4.19/arch/mips64/math-emu/sp_fdp.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_fdp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,69 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_fdp(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(buildsp(xs,
-						 SP_EMAX + 1 + SP_EBIAS,
-						 (unsigned long)
-						 (xm >>
-						  (DP_MBITS - SP_MBITS))),
-					 "fdp", x);
-	case IEEE754_CLASS_INF:
-		return ieee754sp_inf(xs);
-	case IEEE754_CLASS_ZERO:
-		return ieee754sp_zero(xs);
-	case IEEE754_CLASS_DNORM:
-		/* cant possibly be sp representable */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-
-	{
-		unsigned long rm;
-
-		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift 
-		 */
-		rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
-		    ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
-
-		SPNORMRET1(xs, xe, rm, "fdp", x);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_fint.c linux-2.4.20/arch/mips64/math-emu/sp_fint.c
--- linux-2.4.19/arch/mips64/math-emu/sp_fint.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_fint.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,78 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_fint(int x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754sp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754sp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754sp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1 << 31))
-			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-	xe = SP_MBITS + 3;
-
-	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
-		 */
-		while (xm >> (SP_MBITS + 1 + 3)) {
-			SPXSRSX1();
-		}
-	} else {
-		/* normalize in grs extended single precision 
-		 */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET1(xs, xe, xm, "fint", x);
-}
-
-
-ieee754sp ieee754sp_funs(unsigned int u)
-{
-	if ((int) u < 0)
-		return ieee754sp_add(ieee754sp_1e31(),
-				     ieee754sp_fint(u & ~(1 << 31)));
-	return ieee754sp_fint(u);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_flong.c linux-2.4.20/arch/mips64/math-emu/sp_flong.c
--- linux-2.4.19/arch/mips64/math-emu/sp_flong.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_flong.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_flong(long long x)
-{
-	COMPXDP;		/* <--- need 64-bit mantissa temp */
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754sp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754sp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754sp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1ULL << 63))
-			xm = (1ULL << 63);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-	xe = SP_MBITS + 3;
-
-	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
-		 */
-		while (xm >> (SP_MBITS + 1 + 3)) {
-			SPXSRSX1();
-		}
-	} else {
-		/* normalize in grs extended single precision */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET1(xs, xe, xm, "sp_flong", x);
-}
-
-
-ieee754sp ieee754sp_fulong(unsigned long long u)
-{
-	if ((long long) u < 0)
-		return ieee754sp_add(ieee754sp_1e63(),
-				     ieee754sp_flong(u & ~(1ULL << 63)));
-	return ieee754sp_flong(u);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_frexp.c linux-2.4.20/arch/mips64/math-emu/sp_frexp.c
--- linux-2.4.19/arch/mips64/math-emu/sp_frexp.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_frexp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,53 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-/* close to ieeep754sp_logb 
-*/
-ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
-{
-	COMPXSP;
-	CLEARCX;
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*eptr = 0;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	*eptr = xe + 1;
-	return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_logb.c linux-2.4.20/arch/mips64/math-emu/sp_logb.c
--- linux-2.4.19/arch/mips64/math-emu/sp_logb.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_logb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,54 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_logb(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(x, "logb", x);
-	case IEEE754_CLASS_QNAN:
-		return x;
-	case IEEE754_CLASS_INF:
-		return ieee754sp_inf(0);
-	case IEEE754_CLASS_ZERO:
-		return ieee754sp_inf(1);
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	return ieee754sp_fint(xe);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_modf.c linux-2.4.20/arch/mips64/math-emu/sp_modf.c
--- linux-2.4.19/arch/mips64/math-emu/sp_modf.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_modf.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,80 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-/* modf function is always exact for a finite number
-*/
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*ip = x;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		/* far to small */
-		*ip = ieee754sp_zero(xs);
-		return x;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe < 0) {
-		*ip = ieee754sp_zero(xs);
-		return x;
-	}
-	if (xe >= SP_MBITS) {
-		*ip = x;
-		return ieee754sp_zero(xs);
-	}
-	/* generate ipart mantissa by clearing bottom bits 
-	 */
-	*ip = buildsp(xs, xe + SP_EBIAS,
-		      ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
-		      ~SP_HIDDEN_BIT);
-
-	/* generate fpart mantissa by clearing top bits
-	 * and normalizing (must be able to normalize)
-	 */
-	xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
-	if (xm == 0)
-		return ieee754sp_zero(xs);
-
-	while ((xm >> SP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_mul.c linux-2.4.20/arch/mips64/math-emu/sp_mul.c
--- linux-2.4.19/arch/mips64/math-emu/sp_mul.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_mul.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,174 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
-{
-	COMPXSP;
-	COMPYSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-	EXPLODEYSP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "mul", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754sp_inf(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return ieee754sp_zero(xs ^ ys);
-
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* rm = xm * ym, re = xe+ye basicly */
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	{
-		int re = xe + ye;
-		int rs = xs ^ ys;
-		unsigned rm;
-
-		/* shunt to top of word */
-		xm <<= 32 - (SP_MBITS + 1);
-		ym <<= 32 - (SP_MBITS + 1);
-
-		/* multiply 32bits xm,ym to give high 32bits rm with stickness
-		 */
-		{
-			unsigned short lxm = xm & 0xffff;
-			unsigned short hxm = xm >> 16;
-			unsigned short lym = ym & 0xffff;
-			unsigned short hym = ym >> 16;
-			unsigned lrm;
-			unsigned hrm;
-
-			lrm = lxm * lym;	/* 16 * 16 => 32 */
-			hrm = hxm * hym;	/* 16 * 16 => 32 */
-
-			{
-				unsigned t = lxm * hym;	/* 16 * 16 => 32 */
-				{
-					unsigned at = lrm + (t << 16);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 16);
-			}
-
-			{
-				unsigned t = hxm * lym;	/* 16 * 16 => 32 */
-				{
-					unsigned at = lrm + (t << 16);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 16);
-			}
-			rm = hrm | (lrm != 0);
-		}
-
-		/*
-		 * sticky shift down to normal rounding precision
-		 */
-		if ((int) rm < 0) {
-			rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
-			    ((rm << (SP_MBITS + 1 + 3)) != 0);
-			re++;
-		} else {
-			rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
-			    ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
-		}
-		assert(rm & (SP_HIDDEN_BIT << 3));
-
-		SPNORMRET2(rs, re, rm, "mul", x, y);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_scalb.c linux-2.4.20/arch/mips64/math-emu/sp_scalb.c
--- linux-2.4.19/arch/mips64/math-emu/sp_scalb.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_scalb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_scalb(ieee754sp x, int n)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(x, "scalb", x, n);
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		return x;
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
-}
-
-
-ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
-{
-	return ieee754sp_scalb(x, n);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_simple.c linux-2.4.20/arch/mips64/math-emu/sp_simple.c
--- linux-2.4.19/arch/mips64/math-emu/sp_simple.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_simple.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,66 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-int ieee754sp_finite(ieee754sp x)
-{
-	return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
-}
-
-ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
-{
-	CLEARCX;
-	SPSIGN(x) = SPSIGN(y);
-	return x;
-}
-
-
-ieee754sp ieee754sp_neg(ieee754sp x)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x))	/* but not infinity */
-		return ieee754sp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	SPSIGN(x) ^= 1;
-	return x;
-}
-
-
-ieee754sp ieee754sp_abs(ieee754sp x)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x))	/* but not infinity */
-		return ieee754sp_nanxcpt(x, "abs", x);
-
-	/* quick fix up */
-	SPSIGN(x) = 0;
-	return x;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_sqrt.c linux-2.4.20/arch/mips64/math-emu/sp_sqrt.c
--- linux-2.4.19/arch/mips64/math-emu/sp_sqrt.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_sqrt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,115 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision square root
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-static const struct ieee754sp_konst knan = {
-	0, SP_EBIAS + SP_EMAX + 1, 0
-};
-
-#define nan	((ieee754sp)knan)
-
-ieee754sp ieee754sp_sqrt(ieee754sp x)
-{
-	int sign = (int) 0x80000000;
-	int ix, s, q, m, t, i;
-	unsigned int r;
-	COMPXDP;
-
-	/* take care of Inf and NaN */
-
-	EXPLODEXDP;
-
-	/* x == INF or NAN? */
-	switch (xc) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		/* sqrt(Nan) = Nan */
-		return ieee754sp_nanxcpt(x, "sqrt");
-	case IEEE754_CLASS_ZERO:
-		/* sqrt(0) = 0 */
-		return x;
-	case IEEE754_CLASS_INF:
-		if (xs)
-			/* sqrt(-Inf) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
-		/* sqrt(+Inf) = Inf */
-		return x;
-	case IEEE754_CLASS_DNORM:
-	case IEEE754_CLASS_NORM:
-		if (xs)
-			/* sqrt(-x) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
-		break;
-	}
-
-	ix = x.bits;
-
-	/* normalize x */
-	m = (ix >> 23);
-	if (m == 0) {		/* subnormal x */
-		for (i = 0; (ix & 0x00800000) == 0; i++)
-			ix <<= 1;
-		m -= i - 1;
-	}
-	m -= 127;		/* unbias exponent */
-	ix = (ix & 0x007fffff) | 0x00800000;
-	if (m & 1)		/* odd m, double x to make it even */
-		ix += ix;
-	m >>= 1;		/* m = [m/2] */
-
-	/* generate sqrt(x) bit by bit */
-	ix += ix;
-	q = s = 0;		/* q = sqrt(x) */
-	r = 0x01000000;		/* r = moving bit from right to left */
-
-	while (r != 0) {
-		t = s + r;
-		if (t <= ix) {
-			s = t + r;
-			ix -= t;
-			q += r;
-		}
-		ix += ix;
-		r >>= 1;
-	}
-
-	if (ix != 0) {
-		switch (ieee754_csr.rm) {
-		case IEEE754_RP:
-			q += 2;
-			break;
-		case IEEE754_RN:
-			q += (q & 1);
-			break;
-		}
-	}
-	ix = (q >> 1) + 0x3f000000;
-	ix += (m << 23);
-	x.bits = ix;
-	return x;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_sub.c linux-2.4.20/arch/mips64/math-emu/sp_sub.c
--- linux-2.4.19/arch/mips64/math-emu/sp_sub.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_sub.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,187 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
-{
-	COMPXSP;
-	COMPYSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-	EXPLODEYSP;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "sub", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(y, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-		return ieee754sp_nanxcpt(x, "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
-		return ieee754sp_bestnan(x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs != ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-		return ieee754sp_inf(ys ^ 1);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs != ys)
-			return x;
-		else
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		/* quick fix up */
-		DPSIGN(y) ^= 1;
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* flip sign of y and handle as add */
-	ys ^= 1;
-
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		SPXSRSYn(s);
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		SPXSRSXn(s);
-	}
-	assert(xe == ye);
-	assert(xe <= SP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
-			SPXSRSX1();	/* shift preserving sticky */
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			if (ieee754_csr.rm == IEEE754_RD)
-				return ieee754sp_zero(1);	/* round negative inf. => sign = -1 */
-			else
-				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
-
-		/* normalize to rounding precision 
-		 */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET2(xs, xe, xm, "sub", x, y);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_tint.c linux-2.4.20/arch/mips64/math-emu/sp_tint.c
--- linux-2.4.19/arch/mips64/math-emu/sp_tint.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_tint.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,88 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include <linux/kernel.h>
-#include "ieee754sp.h"
-
-int ieee754sp_tint(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754si_xcpt(ieee754si_indef(), "fixsp", x);
-	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fixsp", x);
-	case IEEE754_CLASS_ZERO:
-		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fixsp", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe >= 31) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754si_xcpt(ieee754si_indef(), "fix", x);
-	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754si_xcpt(0, "fix", x);
-	}
-	/* oh gawd */
-	if (xe > SP_MBITS) {
-		xm <<= xe - SP_MBITS;
-	} else if (xe < SP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= SP_MBITS - xe;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned int ieee754sp_tuns(ieee754sp x)
-{
-	ieee754sp hb = ieee754sp_1e31();
-
-	/* what if x < 0 ?? */
-	if (ieee754sp_lt(x, hb))
-		return (unsigned) ieee754sp_tint(x);
-
-	return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
-	    ((unsigned) 1 << 31);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/math-emu/sp_tlong.c linux-2.4.20/arch/mips64/math-emu/sp_tlong.c
--- linux-2.4.19/arch/mips64/math-emu/sp_tlong.c	2001-07-02 20:56:41.000000000 +0000
+++ linux-2.4.20/arch/mips64/math-emu/sp_tlong.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,87 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope 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.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- */
-
-
-#include "ieee754sp.h"
-
-long long ieee754sp_tlong(ieee754sp x)
-{
-	COMPXDP;		/* <-- need 64-bit mantissa tmp */
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
-	case IEEE754_CLASS_INF:
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
-	case IEEE754_CLASS_ZERO:
-		return 0;
-	case IEEE754_CLASS_DNORM:	/* much to small */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "sp_tlong", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
-		return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
-	}
-	if (xe < 0) {
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754di_xcpt(0, "sp_tlong", x);
-	}
-	/* oh gawd */
-	if (xe > SP_MBITS) {
-		xm <<= xe - SP_MBITS;
-	} else if (xe < SP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= SP_MBITS - xe;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned long long ieee754sp_tulong(ieee754sp x)
-{
-	ieee754sp hb = ieee754sp_1e63();
-
-	/* what if x < 0 ?? */
-	if (ieee754sp_lt(x, hb))
-		return (unsigned long long) ieee754sp_tlong(x);
-
-	return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
-	    (1ULL << 63);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/Makefile linux-2.4.20/arch/mips64/mm/Makefile
--- linux-2.4.19/arch/mips64/mm/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/Makefile	2002-10-04 00:41:09.000000000 +0000
@@ -11,11 +11,15 @@
 
 obj-$(CONFIG_CPU_R4300)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
 obj-$(CONFIG_CPU_R4X00)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o
+obj-$(CONFIG_CPU_R5000)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \
+				   r5k-sc.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \
+				   r5k-sc.o
 obj-$(CONFIG_CPU_R10000)	+= andes.o tlbex-r4k.o tlb-glue-r4k.o
 obj-$(CONFIG_CPU_SB1)		+= pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \
 				   tlb-glue-r4k.o
+obj-$(CONFIG_CPU_MIPS64)	+= pg-mips64.o c-mips64.o tlb-r4k.o \
+				   tlbex-r4k.o tlb-glue-r4k.o
 
 #
 # Debug TLB exception handler, currently unused
@@ -24,6 +28,6 @@
 
 obj-$(CONFIG_SGI_IP22)		+= umap.o
 
-CFLAGS_tlb-glue-r4k.o := -P
+AFLAGS_tlb-glue-r4k.o := -P
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/andes.c linux-2.4.20/arch/mips64/mm/andes.c
--- linux-2.4.19/arch/mips64/mm/andes.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/andes.c	2002-10-04 00:41:10.000000000 +0000
@@ -328,7 +328,7 @@
 			printk(KERN_EMERG "Unknown L2 line size\n");
 			while(1);
 	}
-    
+
 	_update_mmu_cache = andes_update_mmu_cache;
 
         flush_cache_l1();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/c-mips64.c linux-2.4.20/arch/mips64/mm/c-mips64.c
--- linux-2.4.19/arch/mips64/mm/c-mips64.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/c-mips64.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,670 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS64 CPU variant specific Cache routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/bcache.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+/* Primary cache parameters. */
+int icache_size, dcache_size; /* Size in bytes */
+int ic_lsize, dc_lsize;       /* LineSize in bytes */
+
+/* Secondary cache (if present) parameters. */
+unsigned int scache_size, sc_lsize;	/* Again, in bytes */
+
+#include <asm/cacheops.h>
+#include <asm/mips64_cache.h>
+
+#undef DEBUG_CACHE
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void no_sc_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+	(void *)no_sc_noop, (void *)no_sc_noop,
+	(void *)no_sc_noop, (void *)no_sc_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+
+static inline void mips64_flush_cache_all_sc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache(); blast_scache();
+	__restore_flags(flags);
+}
+
+static inline void mips64_flush_cache_all_pc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache();
+	__restore_flags(flags);
+}
+
+static void
+mips64_flush_cache_range_sc(struct mm_struct *mm,
+			 unsigned long start,
+			 unsigned long end)
+{
+	struct vm_area_struct *vma;
+	unsigned long flags;
+
+	if(mm->context == 0)
+		return;
+
+	start &= PAGE_MASK;
+#ifdef DEBUG_CACHE
+	printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+	vma = find_vma(mm, start);
+	if(vma) {
+		if(mm->context != current->mm->context) {
+			mips64_flush_cache_all_sc();
+		} else {
+			pgd_t *pgd;
+			pmd_t *pmd;
+			pte_t *pte;
+
+			__save_and_cli(flags);
+			while(start < end) {
+				pgd = pgd_offset(mm, start);
+				pmd = pmd_offset(pgd, start);
+				pte = pte_offset(pmd, start);
+
+				if(pte_val(*pte) & _PAGE_VALID)
+					blast_scache_page(start);
+				start += PAGE_SIZE;
+			}
+			__restore_flags(flags);
+		}
+	}
+}
+
+static void mips64_flush_cache_range_pc(struct mm_struct *mm,
+				     unsigned long start,
+				     unsigned long end)
+{
+	if(mm->context != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_CACHE
+		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+		__save_and_cli(flags);
+		blast_dcache(); blast_icache();
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * On architectures like the Sparc, we could get rid of lines in
+ * the cache created only by a certain context, but on the MIPS
+ * (and actually certain Sparc's) we cannot.
+ */
+static void mips64_flush_cache_mm_sc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips64_flush_cache_all_sc();
+	}
+}
+
+static void mips64_flush_cache_mm_pc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips64_flush_cache_all_pc();
+	}
+}
+
+static void mips64_flush_cache_page_sc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since R4k caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm->context != current->active_mm->context) {
+		/*
+		 * Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & (scache_size - 1)));
+		blast_dcache_page_indexed(page);
+		blast_scache_page_indexed(page);
+	} else
+		blast_scache_page(page);
+out:
+	__restore_flags(flags);
+}
+
+static void mips64_flush_cache_page_pc(struct vm_area_struct *vma,
+				    unsigned long page)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (mm->context == 0)
+		return;
+
+#ifdef DEBUG_CACHE
+	printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+	__save_and_cli(flags);
+	page &= PAGE_MASK;
+	pgdp = pgd_offset(mm, page);
+	pmdp = pmd_offset(pgdp, page);
+	ptep = pte_offset(pmdp, page);
+
+	/*
+	 * If the page isn't marked valid, the page cannot possibly be
+	 * in the cache.
+	 */
+	if (!(pte_val(*ptep) & _PAGE_VALID))
+		goto out;
+
+	/*
+	 * Doing flushes for another ASID than the current one is
+	 * too difficult since Mips64 caches do a TLB translation
+	 * for every cache flush operation.  So we do indexed flushes
+	 * in that case, which doesn't overly flush the cache too much.
+	 */
+	if (mm == current->active_mm) {
+		blast_dcache_page(page);
+	} else {
+		/* Do indexed flush, too much work to get the (possible)
+		 * tlb refills to work correctly.
+		 */
+		page = (KSEG0 + (page & ((unsigned long)dcache_size - 1)));
+		blast_dcache_page_indexed(page);
+	}
+out:
+	__restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ *    addresses all the time in kernel mode we can do a direct
+ *    flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void mips64_flush_page_to_ram_sc(struct page *page)
+{
+	blast_scache_page((unsigned long)page_address(page));
+}
+
+static void mips64_flush_page_to_ram_pc(struct page *page)
+{
+	blast_dcache_page((unsigned long)page_address(page));
+}
+
+static void
+mips64_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+mips64_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+mips64_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	unsigned long address;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & ((unsigned long)icache_size - 1));
+	blast_icache_page_indexed(address);
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+mips64_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= (unsigned long)dcache_size) {
+		blast_dcache();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)dc_lsize - 1);
+		while (1) {
+			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
+			if (a == end) break;
+			a += dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+	bc_wback_inv(addr, size);
+}
+
+static void
+mips64_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_scache();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		flush_scache_line(a);	/* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips64_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= (unsigned long)dcache_size) {
+		blast_dcache();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~((unsigned long)dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)dc_lsize - 1);
+		while (1) {
+			invalidate_dcache_line(a); /* Hit_Inv_D */
+			if (a == end) break;
+			a += (unsigned long)dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+mips64_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_scache();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		invalidate_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips64_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("mips64_dma_cache called - should not happen.\n");
+}
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case.  Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void mips64_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+static void
+mips64_flush_icache_all(void)
+{
+	if (mips_cpu.cputype == CPU_20KC) {
+		blast_icache();
+	}
+}
+
+
+/* Detect and size the various caches. */
+static void __init probe_icache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /*
+		 * Not a MIPS64 complainant CPU.
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+	        icache_size = 1 << (12 + ((config >> 9) & 7));
+		ic_lsize = 16 << ((config >> 5) & 1);
+		mips_cpu.icache.linesz = ic_lsize;
+
+		/*
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
+		mips_cpu.icache.sets =
+			(icache_size / ic_lsize) / mips_cpu.icache.ways;
+	} else {
+	       config1 = read_mips32_cp0_config1();
+
+	       if ((lsize = ((config1 >> 19) & 7)))
+		       mips_cpu.icache.linesz = 2 << lsize;
+	       else
+		       mips_cpu.icache.linesz = lsize;
+	       mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
+	       mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
+
+	       ic_lsize = mips_cpu.icache.linesz;
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
+		             ic_lsize;
+	}
+	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
+	       icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
+}
+
+static void __init probe_dcache(unsigned long config)
+{
+        unsigned long config1;
+	unsigned int lsize;
+
+        if (!(config & (1 << 31))) {
+	        /*
+		 * Not a MIPS64 complainant CPU.
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+		dcache_size = 1 << (12 + ((config >> 6) & 7));
+		dc_lsize = 16 << ((config >> 4) & 1);
+		mips_cpu.dcache.linesz = dc_lsize;
+		/*
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
+		mips_cpu.dcache.sets =
+			(dcache_size / dc_lsize) / mips_cpu.dcache.ways;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+
+		if ((lsize = ((config1 >> 10) & 7)))
+		        mips_cpu.dcache.linesz = 2 << lsize;
+		else
+		        mips_cpu.dcache.linesz= lsize;
+		mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
+		mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
+
+		dc_lsize = mips_cpu.dcache.linesz;
+		dcache_size =
+			mips_cpu.dcache.sets * mips_cpu.dcache.ways
+			* dc_lsize;
+	}
+	printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
+	       dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
+}
+
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly.  You have been warned.
+ */
+static int __init probe_scache(unsigned long config)
+{
+	extern unsigned long stext;
+	unsigned long flags, addr, begin, end, pow2;
+	int tmp;
+
+	if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
+		return 0;
+
+	tmp = ((config >> 17) & 1);
+	if(tmp)
+		return 0;
+	tmp = ((config >> 22) & 3);
+	switch(tmp) {
+	case 0:
+		sc_lsize = 16;
+		break;
+	case 1:
+		sc_lsize = 32;
+		break;
+	case 2:
+		sc_lsize = 64;
+		break;
+	case 3:
+		sc_lsize = 128;
+		break;
+	}
+
+	begin = (unsigned long) &stext;
+	begin &= ~((4 * 1024 * 1024) - 1);
+	end = begin + (4 * 1024 * 1024);
+
+	/* This is such a bitch, you'd think they would make it
+	 * easy to do this.  Away you daemons of stupidity!
+	 */
+	__save_and_cli(flags);
+
+	/* Fill each size-multiple cache line with a valid tag. */
+	pow2 = (64 * 1024);
+	for(addr = begin; addr < end; addr = (begin + pow2)) {
+		unsigned long *p = (unsigned long *) addr;
+		__asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+		pow2 <<= 1;
+	}
+
+	/* Load first line with zero (therefore invalid) tag. */
+	set_taglo(0);
+	set_taghi(0);
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 8, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 11, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+
+	/* Now search for the wrap around point. */
+	pow2 = (128 * 1024);
+	tmp = 0;
+	for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+		__asm__ __volatile__("\n\t.set noreorder\n\t"
+				     "cache 7, (%0)\n\t"
+				     ".set reorder\n\t" : : "r" (addr));
+		__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+		if(!get_taglo())
+			break;
+		pow2 <<= 1;
+	}
+	__restore_flags(flags);
+	addr -= begin;
+	printk("Secondary cache sized at %dK linesize %d bytes.\n",
+	       (int) (addr >> 10), sc_lsize);
+	scache_size = addr;
+	return 1;
+}
+
+static void __init setup_noscache_funcs(void)
+{
+	_clear_page = (void *)mips64_clear_page_dc;
+	_copy_page = (void *)mips64_copy_page_dc;
+	_flush_cache_all = mips64_flush_cache_all_pc;
+	___flush_cache_all = mips64_flush_cache_all_pc;
+	_flush_cache_mm = mips64_flush_cache_mm_pc;
+	_flush_cache_range = mips64_flush_cache_range_pc;
+	_flush_cache_page = mips64_flush_cache_page_pc;
+	_flush_page_to_ram = mips64_flush_page_to_ram_pc;
+
+	_flush_icache_page = mips64_flush_icache_page;
+
+	_dma_cache_wback_inv = mips64_dma_cache_wback_inv_pc;
+	_dma_cache_wback = mips64_dma_cache_wback;
+	_dma_cache_inv = mips64_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+        _flush_cache_all = mips64_flush_cache_all_sc;
+        ___flush_cache_all = mips64_flush_cache_all_sc;
+	_flush_cache_mm = mips64_flush_cache_mm_sc;
+	_flush_cache_range = mips64_flush_cache_range_sc;
+	_flush_cache_page = mips64_flush_cache_page_sc;
+	_flush_page_to_ram = mips64_flush_page_to_ram_sc;
+	_clear_page = (void *)mips64_clear_page_sc;
+	_copy_page = (void *)mips64_copy_page_sc;
+
+	_flush_icache_page = mips64_flush_icache_page_s;
+
+	_dma_cache_wback_inv = mips64_dma_cache_wback_inv_sc;
+	_dma_cache_wback = mips64_dma_cache_wback;
+	_dma_cache_inv = mips64_dma_cache_inv_sc;
+}
+
+typedef int (*probe_func_t)(unsigned long);
+
+static inline void __init setup_scache(unsigned int config)
+{
+	probe_func_t probe_scache_kseg1;
+	int sc_present = 0;
+
+	/* Maybe the cpu knows about a l2 cache? */
+	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+	sc_present = probe_scache_kseg1(config);
+
+	if (sc_present) {
+	  	mips_cpu.scache.linesz = sc_lsize;
+		/*
+		 * We cannot infer associativity - assume direct map
+		 * unless probe template indicates otherwise
+		 */
+		if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
+		mips_cpu.scache.sets =
+		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
+
+		setup_scache_funcs();
+		return;
+	}
+
+	setup_noscache_funcs();
+}
+
+void __init ld_mmu_mips64(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+
+	_flush_cache_sigtramp = mips64_flush_cache_sigtramp;
+	_flush_icache_range = mips64_flush_icache_range;	/* Ouch */
+	_flush_icache_all = mips64_flush_icache_all;
+	_flush_cache_l1 = _flush_cache_all;
+	_flush_cache_l2 = _flush_cache_all;
+
+	__flush_cache_all();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/c-sb1.c linux-2.4.20/arch/mips64/mm/c-sb1.c
--- linux-2.4.19/arch/mips64/mm/c-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/c-sb1.c	2002-10-04 00:41:14.000000000 +0000
@@ -12,11 +12,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <asm/mmu_context.h>
@@ -46,7 +46,7 @@
  * if we miss in the icache, and have dirty data in the
  * L1 dcache, then we'll go out to memory (or the L2) and
  * get the not-as-recent data.
- * 
+ *
  * So the only time we have to flush the dcache is when
  * we're flushing the icache.  Since the L2 is fully
  * coherent to everything, including I/O, we never have
@@ -63,7 +63,7 @@
 	 * Haven't worried too much about speed here; given that we're flushing
 	 * the icache, the time to invalidate is dwarfed by the time it's going
 	 * to take to refill it.  Register usage:
-	 * 
+	 *
 	 * $1 - moving cache index
 	 * $2 - set count
 	 */
@@ -87,7 +87,7 @@
 		".set noreorder             \n"
 		".set mips2                 \n"
 		"sync                       \n"
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
 		"sync                       \n"
 #endif
 		".set pop                   \n");
@@ -153,7 +153,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		"1:                         \n"
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 		".align 3                   \n"
@@ -192,7 +192,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		".align 3                   \n"
 		"1:   cache  %3, (0<<13)($1) \n" /* Index-inval this address */
 		"     cache  %3, (1<<13)($1) \n" /* Index-inval this address */
@@ -277,9 +277,9 @@
 static inline void protected_writeback_dcache_line(unsigned long addr)
 {
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
-	/* Have to be sure the TLB entry exists for the cache op, 
+	/* Have to be sure the TLB entry exists for the cache op,
 	   so we have to be sure that nothing happens in between the
-	   lw and the cache op 
+	   lw and the cache op
 	*/
 	unsigned long flags;
 	local_irq_save(flags);
@@ -370,7 +370,7 @@
 	 * Haven't worried too much about speed here; given that we're flushing
 	 * the icache, the time to invalidate is dwarfed by the time it's going
 	 * to take to refill it.  Register usage:
-	 * 
+	 *
 	 * $1 - moving cache index
 	 * $2 - set count
 	 */
@@ -402,23 +402,23 @@
 
 /*
  * This only needs to make sure stores done up to this
- * point are visible to other agents outside the CPU.  Given 
- * the coherent nature of the ZBbus, all that's required here is 
+ * point are visible to other agents outside the CPU.  Given
+ * the coherent nature of the ZBbus, all that's required here is
  * a sync to make sure the data gets out to the caches and is
- * visible to an arbitrary A Phase from an external agent 
- *   
+ * visible to an arbitrary A Phase from an external agent
+ *
  * Actually, I'm not even sure that's necessary; the semantics
  * of this function aren't clear.  If it's supposed to serve as
- * a memory barrier, this is needed.  If it's only meant to 
+ * a memory barrier, this is needed.  If it's only meant to
  * prevent data from being invisible to non-cpu memory accessors
- * for some indefinite period of time (e.g. in a non-coherent 
+ * for some indefinite period of time (e.g. in a non-coherent
  * dcache) then this function would be a complete nop.
  */
 static void sb1_flush_page_to_ram(struct page *page)
 {
 	__asm__ __volatile__(
 		"     sync  \n"  /* Short pipe */
-		:::"memory");	
+		:::"memory");
 }
 
 /*
@@ -432,13 +432,13 @@
  * 6 - 4096
  * 7 - Reserved
  */
-  
+
 static unsigned int decode_cache_sets(unsigned int config_field)
 {
 	if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 6));
 }
 
@@ -461,7 +461,7 @@
 	} else if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 1));
 }
 
@@ -518,6 +518,6 @@
 	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
 	_flush_icache_all = sb1_flush_icache_all;
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 	flush_cache_all();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/extable.c linux-2.4.20/arch/mips64/mm/extable.c
--- linux-2.4.19/arch/mips64/mm/extable.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/extable.c	2002-10-04 00:41:11.000000000 +0000
@@ -40,13 +40,13 @@
 unsigned long search_exception_table(unsigned long addr)
 {
 	unsigned long ret = 0;
-	unsigned long flags;
-	
+
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 	return ret;
 #else
+	unsigned long flags;
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/fault.c linux-2.4.20/arch/mips64/mm/fault.c
--- linux-2.4.19/arch/mips64/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/fault.c	2002-10-04 00:41:10.000000000 +0000
@@ -126,7 +126,7 @@
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
 	 */
-	if (in_interrupt() || mm == &init_mm)
+	if (in_interrupt() || !mm)
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
@@ -229,20 +229,18 @@
 	printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at "
 	       "address %016lx, epc == %016lx, ra == %016lx\n",
 	       smp_processor_id(), address, regs->cp0_epc, regs->regs[31]);
-	die("Oops", regs, write);
+	die("Oops", regs);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk(KERN_NOTICE "VM: killing process %s\n", tsk->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/init.c linux-2.4.20/arch/mips64/mm/init.c
--- linux-2.4.19/arch/mips64/mm/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/init.c	2002-10-04 00:41:11.000000000 +0000
@@ -226,10 +226,10 @@
 
 	free_area_init(zones_size);
 
-	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
+	memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER);
 	memset((void *)kpmdtbl, 0, PAGE_SIZE);
 	pgd_set(swapper_pg_dir, kpmdtbl);
-	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+	for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
 		pmd_val(*pmd) = (unsigned long)pte;
 }
 
@@ -243,17 +243,18 @@
 	int i;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
-	unsigned long addr, end;
+		unsigned long addr, end;
 
-	if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-		/* not usable memory */
-		continue;
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			/* not usable memory */
+			continue;
+
+		addr = PFN_UP(boot_mem_map.map[i].addr);
+		end = PFN_DOWN(boot_mem_map.map[i].addr +
+			       boot_mem_map.map[i].size);
 
-	addr = PFN_UP(boot_mem_map.map[i].addr);
-	end = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size);
-
-	if (pagenr >= addr && pagenr < end)
-		return 1;
+		if (pagenr >= addr && pagenr < end)
+			return 1;
 	}
 
 	return 0;
@@ -316,7 +317,7 @@
 	unsigned long addr, page;
 
 	prom_free_prom_memory();
-    
+
 	addr = (unsigned long)(&__init_begin);
 	while (addr < (unsigned long)&__init_end) {
 		page = PAGE_OFFSET | CPHYSADDR(addr);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/loadmmu.c linux-2.4.20/arch/mips64/mm/loadmmu.c
--- linux-2.4.19/arch/mips64/mm/loadmmu.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/loadmmu.c	2002-10-04 00:41:09.000000000 +0000
@@ -54,35 +54,29 @@
 extern void ld_mmu_andes(void);
 extern void ld_mmu_sb1(void);
 extern void sb1_tlb_init(void);
+extern void ld_mmu_mips64(void);
+extern void r4k_tlb_init(void);
 
 void __init load_mmu(void)
 {
-	switch(mips_cpu.cputype) {
+	if (mips_cpu.options & MIPS_CPU_4KTLB) {
 #if defined (CONFIG_CPU_R4300)						\
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
     || defined (CONFIG_CPU_NEVADA)
-	case CPU_R4000PC:
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4200:
-	case CPU_R4300:
-	case CPU_R4400PC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
-	case CPU_R4600:
-	case CPU_R4640:
-	case CPU_R4650:
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_NEVADA:
 		printk(KERN_INFO "Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
-		break;
 #endif
+#if defined(CONFIG_CPU_MIPS64)
+		printk(KERN_INFO "Loading MIPS64 MMU routines.\n");
+                ld_mmu_mips64();
+		r4k_tlb_init();
+#endif
+
+	} else switch(mips_cpu.cputype) {
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
+	case CPU_R12000:
 		printk(KERN_INFO "Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
@@ -95,6 +89,10 @@
 		break;
 #endif
 
+	case CPU_R8000:
+		panic("R8000 is unsupported");
+		break;
+
 	default:
 		/* XXX We need an generic routine in the MIPS port
 		 * XXX to jabber stuff onto the screen on all machines
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/pg-mips64.c linux-2.4.20/arch/mips64/mm/pg-mips64.c
--- linux-2.4.19/arch/mips64/mm/pg-mips64.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/pg-mips64.c	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,126 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS64 CPU variant specific Cache routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+
+extern int dc_lsize, ic_lsize, sc_lsize;
+
+/*
+ * Zero an entire page.
+ */
+
+void mips64_clear_page_dc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips64_clear_page_sc(unsigned long page)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=page; i<page+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=page; i<page+PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips64_copy_page_dc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=dc_lsize)
+		{
+		        __asm__ __volatile__(
+			        ".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+void mips64_copy_page_sc(unsigned long to, unsigned long from)
+{
+	unsigned long i;
+
+        if (mips_cpu.options & MIPS_CPU_CACHE_CDEX)
+	{
+	        for (i=to; i<to+PAGE_SIZE; i+=sc_lsize)
+		{
+		        __asm__ __volatile__(
+				".set\tnoreorder\n\t"
+				".set\tnoat\n\t"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/pg-sb1.c linux-2.4.20/arch/mips64/mm/pg-sb1.c
--- linux-2.4.19/arch/mips64/mm/pg-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/pg-sb1.c	2002-10-04 00:41:10.000000000 +0000
@@ -2,7 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000 Sibyte
- * 
+ *
  * Written by Justin Carlson (carlson@sibyte.com)
  *
  *
@@ -15,11 +15,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <asm/page.h>
 
@@ -40,7 +40,7 @@
 	 * performance model
 	 *
 	 * We prefetch 4 lines ahead.  We're also "cheating" slightly here...
-	 * since we know we're on an SB1, we force the assembler to take 
+	 * since we know we're on an SB1, we force the assembler to take
 	 * 64-bit operands to speed things up
 	 */
 	__asm__ __volatile__(
@@ -50,9 +50,9 @@
 		".set mips4                 \n"
 		"     daddiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"  
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"  
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"
 		"1:   sd        $0,  0(%0)  \n"  /* Throw out a cacheline of 0's */
 		"     sd        $0,  8(%0)  \n"
 		"     sd        $0, 16(%0)  \n"
@@ -72,7 +72,7 @@
 	/*
 	 * This should be optimized in assembly...can't use ld/sd, though,
 	 * because the top 32 bits could be nuked if we took an interrupt
-	 * during the routine.	And this is not a good place to be cli()'ing 
+	 * during the routine.	And this is not a good place to be cli()'ing
 	 *
 	 * The pref's used here are using "streaming" hints, which cause the
 	 * copied data to be kicked out of the cache sooner.  A page copy often
@@ -88,11 +88,11 @@
 		".set mips4                 \n"
 		"     daddiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)  \n"  /* Prefetch the first 3 lines */
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  0(%1)  \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  32(%1) \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"
 		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
 		"     lw        $3,  4(%0)  \n"
 		"     lw        $4,  8(%0)  \n"
@@ -103,20 +103,20 @@
 		"     lw        $9, 28(%0)  \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
-		"     sw        $2,  0(%1)  \n"  
+		"     sw        $2,  0(%1)  \n"
 		"     sw        $3,  4(%1)  \n"
 		"     sw        $4,  8(%1)  \n"
 		"     sw        $5, 12(%1)  \n"
 		"     sw        $6, 16(%1)  \n"
 		"     sw        $7, 20(%1)  \n"
 		"     sw        $8, 24(%1)  \n"
-		"     sw        $9, 28(%1)  \n"		
+		"     sw        $9, 28(%1)  \n"
 		"     daddiu     %1, %1, 32  \n"  /* Next cacheline */
 		"     nop                   \n"  /* Force next add to short pipe */
 		"     nop                   \n"  /* Force next add to short pipe */
 		"     bne       $1, %0, 1b  \n"
 		"     daddiu     %0, %0, 32  \n"  /* Next cacheline */
-		".set pop                   \n" 
+		".set pop                   \n"
 		: "=r" (to), "=r" (from)
 		: "0" (from), "1" (to), "I" (PAGE_SIZE-32)
 		: "$2","$3","$4","$5","$6","$7","$8","$9","memory");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/r4xx0.c linux-2.4.20/arch/mips64/mm/r4xx0.c
--- linux-2.4.19/arch/mips64/mm/r4xx0.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/r4xx0.c	2002-10-04 00:41:10.000000000 +0000
@@ -136,10 +136,10 @@
  *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
  *      executed if there is no other dcache activity. If the dcache is
  *      accessed for another instruction immeidately preceding when these
- *      cache instructions are executing, it is possible that the dcache 
- *      tag match outputs used by these cache instructions will be 
+ *      cache instructions are executing, it is possible that the dcache
+ *      tag match outputs used by these cache instructions will be
  *      incorrect. These cache instructions should be preceded by at least
- *      four instructions that are not any kind of load or store 
+ *      four instructions that are not any kind of load or store
  *      instruction.
  *
  *      This is not allowed:    lw
@@ -1237,7 +1237,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1285,7 +1285,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1335,7 +1335,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1385,7 +1385,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1434,7 +1434,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1746,11 +1746,6 @@
 	}
 }
 
-static void r4k_dma_cache_wback(unsigned long addr, unsigned long size)
-{
-	panic("r4k_dma_cache called - should not happen.");
-}
-
 /*
  * While we're protected against bad userland addresses we don't care
  * very much about what happens in that case.  Usually a segmentation
@@ -1877,7 +1872,7 @@
 		} else {
 			get_new_mmu_context(mm, smp_processor_id());
 			if(mm == current->mm)
-				set_entryhi(CPU_CONTEXT(smp_processor_id(), 
+				set_entryhi(CPU_CONTEXT(smp_processor_id(),
 								mm) & 0xff);
 		}
 		__restore_flags(flags);
@@ -2152,7 +2147,7 @@
 	}
 	_flush_icache_page = r4k_flush_icache_page_p;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc;
-	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_wback = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
 }
 
@@ -2241,11 +2236,12 @@
 	}
 	_flush_icache_page = r4k_flush_icache_page_s;
 	_dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc;
-	_dma_cache_wback = r4k_dma_cache_wback;
+	_dma_cache_wback = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
 }
 
 typedef int (*probe_func_t)(unsigned long);
+extern int r5k_sc_init(void);
 
 static inline void __init setup_scache(unsigned int config)
 {
@@ -2256,23 +2252,30 @@
 	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
 	sc_present = probe_scache_kseg1(config);
 
-	if (sc_present) {
-		setup_scache_funcs();
+	if (!sc_present) {
+		setup_noscache_funcs();
 		return;
 	}
 
-	setup_noscache_funcs();
+	switch(mips_cpu.cputype) {
+	case CPU_R5000:
+	case CPU_NEVADA:
+			setup_noscache_funcs();
+#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+			r5k_sc_init();
+#endif
+			break;
+	default:
+			setup_scache_funcs();
+	}
+
 }
 
 void __init ld_mmu_r4xx0(void)
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-#ifdef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-#else
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif /* UNCACHED */
+	change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/r5k-sc.c linux-2.4.20/arch/mips64/mm/r5k-sc.c
--- linux-2.4.19/arch/mips64/mm/r5k-sc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/r5k-sc.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcacheops.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+#define cache_op(base,op)                   \
+__asm__ __volatile__("				\
+		.set noreorder;                 \
+		.set mips3;                     \
+		cache %1, (%0);                 \
+		.set mips0;                     \
+		.set reorder"                   \
+		:                               \
+		: "r" (base),                   \
+		  "i" (op));
+
+static inline void blast_r5000_scache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache_op(start, R5K_Page_Invalidate_S);
+		start += SC_PAGE;
+	}
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_r5000_scache();
+		return;
+	}
+
+	/* On the R5000 secondary cache we cannot
+	 * invalidate less than a page at a time.
+	 * The secondary cache is physically indexed, write-through.
+	 */
+	a = addr & ~(SC_PAGE - 1);
+	end = (addr + size - 1) & ~(SC_PAGE - 1);
+	while (a <= end) {
+		cache_op(a, R5K_Page_Invalidate_S);
+		a += SC_PAGE;
+	}
+}
+
+static void r5k_sc_enable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	change_cp0_config(CONF_SE, CONF_SE);
+	blast_r5000_scache();
+	__restore_flags(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_r5000_scache();
+	change_cp0_config(CONF_SE, 0);
+	__restore_flags(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if(config & CONF_SC)
+		return(0);
+
+	scache_size = (512*1024) << ((config >> 20)&3);
+
+	printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+			scache_size >> 10);
+
+	return 1;
+}
+
+struct bcache_ops r5k_sc_ops = {
+	r5k_sc_enable,
+	r5k_sc_disable,
+	r5k_dma_cache_inv_sc,
+	r5k_dma_cache_inv_sc
+};
+
+void __init r5k_sc_init(void)
+{
+	if (r5k_sc_probe()) {
+		r5k_sc_enable();
+		bcops = &r5k_sc_ops;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/tlb-r4k.c linux-2.4.20/arch/mips64/mm/tlb-r4k.c
--- linux-2.4.19/arch/mips64/mm/tlb-r4k.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/tlb-r4k.c	2002-10-04 00:41:29.000000000 +0000
@@ -0,0 +1,407 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS64 CPU variant specific MMU routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+extern char except_vec1_r4k;
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+				     "nop; nop; nop; nop; nop; nop;\n\t" \
+				     ".set reorder\n\t")
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ctx;
+	int entry;
+
+#ifdef DEBUG_TLB
+	printk("[tlball]");
+#endif
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = (get_entryhi() & 0xff);
+	set_entryhi(KSEG0);
+	set_entrylo0(0);
+	set_entrylo1(0);
+	BARRIER;
+
+	entry = get_wired();
+
+	/* Blast 'em all away. */
+	while(entry < mips_cpu.tlbsize) {
+	        /* Make sure all entries differ. */
+	        set_entryhi(KSEG0+entry*0x2000);
+		set_index(entry);
+		BARRIER;
+		tlb_write_indexed();
+		BARRIER;
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
+		unsigned long flags;
+
+#ifdef DEBUG_TLB
+		printk("[tlbmm<%d>]", mm->context);
+#endif
+		__save_and_cli(flags);
+		get_new_mmu_context(mm, smp_processor_id());
+		if (mm == current->active_mm)
+			set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) &
+				    0xff);
+		__restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+				unsigned long end)
+{
+	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
+		unsigned long flags;
+		int size;
+
+#ifdef DEBUG_TLB
+		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+		       start, end);
+#endif
+		__save_and_cli(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if(size <= mips_cpu.tlbsize/2) {
+			int oldpid = (get_entryhi() & 0xff);
+			int newpid = (CPU_CONTEXT(smp_processor_id(), mm) &
+				      0xff);
+
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+			while(start < end) {
+				int idx;
+
+				set_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				BARRIER;
+				tlb_probe();
+				BARRIER;
+				idx = get_index();
+				set_entrylo0(0);
+				set_entrylo1(0);
+				if(idx < 0)
+					continue;
+				/* Make sure all entries differ. */
+				set_entryhi(KSEG0+idx*0x2000);
+				BARRIER;
+				tlb_write_indexed();
+				BARRIER;
+			}
+			set_entryhi(oldpid);
+		} else {
+			get_new_mmu_context(mm, smp_processor_id());
+			if (mm == current->active_mm)
+				set_entryhi(CPU_CONTEXT(smp_processor_id(),
+							mm) & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) {
+		unsigned long flags;
+		unsigned long oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
+		page &= (PAGE_MASK << 1);
+		__save_and_cli(flags);
+		oldpid = (get_entryhi() & 0xff);
+		set_entryhi(page | newpid);
+		BARRIER;
+		tlb_probe();
+		BARRIER;
+		idx = get_index();
+		set_entrylo0(0);
+		set_entrylo1(0);
+		if(idx < 0)
+			goto finish;
+		/* Make sure all entries differ. */
+		set_entryhi(KSEG0+idx*0x2000);
+		BARRIER;
+		tlb_write_indexed();
+	finish:
+		BARRIER;
+		set_entryhi(oldpid);
+		__restore_flags(flags);
+	}
+}
+
+/*
+ * Updates the TLB with the new pte(s).
+ */
+void mips64_update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+	if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
+	   (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
+		printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d
+			tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(),
+			vma->vm_mm) & 0xff), pid);
+	}
+#endif
+
+	__save_and_cli(flags);
+	address &= (PAGE_MASK << 1);
+	set_entryhi(address | (pid));
+	pgdp = pgd_offset(vma->vm_mm, address);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	pmdp = pmd_offset(pgdp, address);
+	idx = get_index();
+	ptep = pte_offset(pmdp, address);
+	BARRIER;
+	set_entrylo0(pte_val(*ptep++) >> 6);
+	set_entrylo1(pte_val(*ptep) >> 6);
+	set_entryhi(address | (pid));
+	BARRIER;
+	if(idx < 0) {
+		tlb_write_random();
+	} else {
+		tlb_write_indexed();
+	}
+	BARRIER;
+	set_entryhi(pid);
+	BARRIER;
+	__restore_flags(flags);
+}
+
+void dump_mm_page(unsigned long addr)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned long val;
+
+	page_dir = pgd_offset(current->mm, 0);
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	page = *pte;
+	printk("Memory Mapping: VA = %08x, PA = %08x ", addr, (unsigned int) pte_val(page));
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void show_tlb(void)
+{
+        unsigned int flags;
+        unsigned int old_ctx;
+	unsigned int entry;
+	unsigned int entrylo0, entrylo1, entryhi;
+
+	__save_and_cli(flags);
+
+	/* Save old context */
+	old_ctx = (get_entryhi() & 0xff);
+
+	printk("TLB content:\n");
+	entry = 0;
+	while(entry < mips_cpu.tlbsize) {
+		set_index(entry);
+		BARRIER;
+		tlb_read();
+		BARRIER;
+		entryhi = get_entryhi();
+		entrylo0 = get_entrylo0();
+		entrylo1 = get_entrylo1();
+		printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : "   ", entryhi & ~ASID_MASK);
+		printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : "");
+		printk("\t\t\t     PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : "");
+
+		dump_mm_page(entryhi & ~0xff);
+		dump_mm_page((entryhi & ~0xff) | 0x1000);
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+
+	__restore_flags(flags);
+}
+
+void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+				      unsigned long entryhi, unsigned long pagemask)
+{
+        unsigned long flags;
+        unsigned long wired;
+        unsigned long old_pagemask;
+        unsigned long old_ctx;
+
+        __save_and_cli(flags);
+        /* Save old context and create impossible VPN2 value */
+        old_ctx = (get_entryhi() & 0xff);
+        old_pagemask = get_pagemask();
+        wired = get_wired();
+        set_wired (wired + 1);
+        set_index (wired);
+        BARRIER;
+        set_pagemask (pagemask);
+        set_entryhi(entryhi);
+        set_entrylo0(entrylo0);
+        set_entrylo1(entrylo1);
+        BARRIER;
+        tlb_write_indexed();
+        BARRIER;
+
+        set_entryhi(old_ctx);
+        BARRIER;
+        set_pagemask (old_pagemask);
+        local_flush_tlb_all();
+        __restore_flags(flags);
+}
+
+/*
+ * Used for loading TLB entries before trap_init() has started, when we
+ * don't actually want to add a wired entry which remains throughout the
+ * lifetime of the system
+ */
+
+static int temp_tlb_entry __initdata;
+
+__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+			       unsigned long entryhi, unsigned long pagemask)
+{
+	int ret = 0;
+	unsigned long flags;
+	unsigned long wired;
+	unsigned long old_pagemask;
+	unsigned long old_ctx;
+
+	__save_and_cli(flags);
+	/* Save old context and create impossible VPN2 value */
+	old_ctx = get_entryhi() & 0xff;
+	old_pagemask = get_pagemask();
+	wired = get_wired();
+	if (--temp_tlb_entry < wired) {
+		printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
+		ret = -ENOSPC;
+		goto out;
+	}
+
+	set_index(temp_tlb_entry);
+	BARRIER;
+	set_pagemask(pagemask);
+	set_entryhi(entryhi);
+	set_entrylo0(entrylo0);
+	set_entrylo1(entrylo1);
+	BARRIER;
+	tlb_write_indexed();
+	BARRIER;
+
+	set_entryhi(old_ctx);
+	BARRIER;
+	set_pagemask(old_pagemask);
+out:
+	__restore_flags(flags);
+	return ret;
+}
+
+static void __init probe_tlb(unsigned long config)
+{
+        unsigned long config1;
+
+        if (!(config & (1 << 31))) {
+	        /*
+		 * Not a MIPS64 complainant CPU.
+		 * Config 1 register not supported, we assume R4k style.
+		 */
+	        mips_cpu.tlbsize = 48;
+	} else {
+	        config1 = read_mips32_cp0_config1();
+		if (!((config >> 7) & 3))
+		        panic("No MMU present");
+		else
+		        mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+	}
+
+	printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
+}
+
+void __init r4k_tlb_init(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	probe_tlb(config);
+	_update_mmu_cache = mips64_update_mmu_cache;
+	set_pagemask(PM_4K);
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	temp_tlb_entry = mips_cpu.tlbsize - 1;
+	local_flush_tlb_all();
+
+	memcpy((void *)(KSEG0 + 0x80), &except_vec1_r4k, 0x80);
+	flush_icache_range(KSEG0, KSEG0 + 0x80);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/tlb-sb1.c linux-2.4.20/arch/mips64/mm/tlb-sb1.c
--- linux-2.4.19/arch/mips64/mm/tlb-sb1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/tlb-sb1.c	2002-10-04 00:41:19.000000000 +0000
@@ -12,11 +12,11 @@
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */ 
+ */
 #include <linux/config.h>
 #include <asm/mmu_context.h>
 #include <asm/bootinfo.h>
@@ -37,13 +37,13 @@
 		"     tlbr             \n"
 		"     dmfc0  $1, $10   \n"
 		"     dsrl32 %0, $1, 0 \n"
-		"     sra    %1, $1, 0 \n"
+		"     sll    %1, $1, 0 \n"
 		"     dmfc0  $1, $2    \n"
 		"     dsrl32 %2, $1, 0 \n"
-		"     sra    %3, $1, 0 \n"
+		"     sll    %3, $1, 0 \n"
 		"     dmfc0  $1, $3    \n"
 		"     dsrl32 %4, $1, 0 \n"
-		"     sra    %5, $1, 0 \n"
+		"     sll    %5, $1, 0 \n"
 		"     mfc0   %6, $5    \n"
 		".set pop              \n"
 		: "=r" (entryhihi),
@@ -62,7 +62,11 @@
 
 void sb1_dump_tlb(void)
 {
+	unsigned long old_ctx;
+	unsigned long flags;
 	int entry;
+	__save_and_cli(flags);
+	old_ctx = get_entryhi();
 	printk("Current TLB registers state:\n"
 	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
 	       "--------------------------------------------------------------------\n");
@@ -83,6 +87,8 @@
 		dump_cur_tlb_regs();
 	}
 	printk("\n");
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
 }
 
 void local_flush_tlb_all(void)
@@ -102,12 +108,12 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);	
+	__restore_flags(flags);
 }
 
 
 /*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * Use a bogus region of memory (starting at 0) to sanitize the TLB's.
  * Use increments of the maximum page size (16MB), and check for duplicate
  * entries before doing a given write.  Then, when we're safe from collisions
  * with the firmware, go back and give all the entries invalid addresses with
@@ -209,7 +215,7 @@
 		set_entrylo1(0);
 		if(idx < 0)
 			goto finish;
-		/* Make sure all entries differ. */  
+		/* Make sure all entries differ. */
 		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
 		tlb_write_indexed();
 	finish:
@@ -299,7 +305,7 @@
 	/*
 	 * We don't know what state the firmware left the TLB's in, so this is
 	 * the ultra-conservative way to flush the TLB's and avoid machine
-	 * check exceptions due to duplicate TLB entries 
+	 * check exceptions due to duplicate TLB entries
 	 */
 	sb1_sanitize_tlb();
 	_update_mmu_cache = sb1_update_mmu_cache;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/tlbex-r4k.S linux-2.4.20/arch/mips64/mm/tlbex-r4k.S
--- linux-2.4.19/arch/mips64/mm/tlbex-r4k.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/tlbex-r4k.S	2002-10-04 00:41:09.000000000 +0000
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -20,10 +21,9 @@
 
 	/*
 	 * After this macro runs we have a pointer to the pte of the address
-	 * that caused the fault in in PTR.
+	 * that caused the fault in PTR.
 	 */
-
-	.macro	LOAD_PTE2, ptr, tmp
+	.macro	LOAD_PTE2, ptr, tmp, kaddr
 #ifdef CONFIG_SMP
 	dmfc0	\ptr, CP0_CONTEXT
 	dmfc0	\tmp, CP0_BADVADDR
@@ -32,8 +32,8 @@
 	dmfc0	\tmp, CP0_BADVADDR
 	dla	\ptr, pgd_current
 #endif
-	bltz	\tmp, kaddr
-	ld	\ptr, (\ptr)
+	bltz	\tmp, \kaddr
+	 ld	\ptr, (\ptr)
 	dsrl	\tmp, (PGDIR_SHIFT-3)		# get pgd offset in bytes
 	andi	\tmp, ((PTRS_PER_PGD - 1)<<3)
 	daddu	\ptr, \tmp			# add in pgd offset
@@ -48,6 +48,35 @@
 	daddu	\ptr, \tmp
 	.endm
 
+
+	/*
+	 * Ditto for the kernel table.
+	 */
+	.macro	LOAD_KPTE2, ptr, tmp, not_vmalloc
+	/*
+	 * First, determine that the address is in/above vmalloc range.
+	 */
+	dmfc0	\tmp, CP0_BADVADDR
+	dli	\ptr, VMALLOC_START
+
+	/*
+	 * Now find offset into kptbl.
+	 */
+	dsubu	\tmp, \tmp, \ptr
+	dla	\ptr, kptbl
+	dsrl	\tmp, (PAGE_SHIFT+1)		# get vpn2
+	dsll	\tmp, 4				# byte offset of pte
+	daddu	\ptr, \ptr, \tmp
+
+	/*
+	 * Determine that fault address is within vmalloc range.
+	 */
+	dla	\tmp, ekptbl
+	sltu	\tmp, \ptr, \tmp
+	beqz	\tmp, \not_vmalloc		# not vmalloc
+	.endm
+
+
 	/*
 	 * This places the even/odd pte pair in the page table at the pte
 	 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
@@ -59,6 +88,7 @@
 	dmtc0	\pte1, CP0_ENTRYLO1		# load it
 	.endm
 
+
 	.text
 	.set	noreorder
 	.set	mips3
@@ -66,69 +96,93 @@
 	__INIT
 
 	.align	5
-FEXPORT(except_vec0)
+LEAF(except_vec0)
 	.set	noat
 	PANIC("Unused vector called")
 1:	b	1b
 	 nop
+END(except_vec0)
+
 
 	/*
-	 * TLB refill handler for the R10000.
+	 * TLB refill handler for the R4000.
 	 * Attention:  We may only use 32 instructions / 128 bytes.
 	 */
+	.align  5
+LEAF(except_vec1_r4k)
+	.set    noat
+	dla     k0, handle_vec1_r4k
+	jr      k0
+	 nop
+END(except_vec1_r4k)
 
-	.align	5
-LEAF(except_vec1_r10k)
-	.set	noat
-	LOAD_PTE2 k1 k0
+	__FINIT
+
+	.align  5
+LEAF(handle_vec1_r4k)
+	.set    noat
+	LOAD_PTE2 k1 k0 9f
 	ld	k0, 0(k1)			# get even pte
 	ld	k1, 8(k1)			# get odd pte
 	PTE_RELOAD k0 k1
-	nop
-	tlbwr
+	b	1f
+	 tlbwr
+1:	nop
 	eret
-kaddr:
-	dla	k0, handle_vmalloc_address	# MAPPED kernel needs this
-	jr	k0
-	 nop
-	END(except_vec1_r10k)
 
-	__FINIT
+9:						# handle the vmalloc range
+	LOAD_KPTE2 k1 k0 invalid_vmalloc_address
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
+	PTE_RELOAD k0 k1
+	b	1f
+	 tlbwr
+1:	nop
+	eret
+END(handle_vec1_r4k)
 
-	.align	5
-LEAF(handle_vmalloc_address)
-	.set	noat
-	/*
-	 * First, determine that the address is in/above vmalloc range.
-	 */
-	dmfc0	k0, CP0_BADVADDR
-	dli	k1, VMALLOC_START
+	__INIT
 
 	/*
-	 * Now find offset into kptbl.
+	 * TLB refill handler for the R10000.
+	 * Attention:  We may only use 32 instructions / 128 bytes.
 	 */
-	dsubu	k0, k0, k1
-	dla	k1, kptbl
-	dsrl	k0, (PAGE_SHIFT+1)		# get vpn2
-	dsll	k0, 4				# byte offset of pte
-	daddu	k1, k1, k0
+	.align	5
+LEAF(except_vec1_r10k)
+	.set    noat
+	dla     k0, handle_vec1_r10k
+	jr      k0
+	 nop
+END(except_vec1_r10k)
 
-	/*
-	 * Determine that fault address is within vmalloc range.
-	 */
-	dla	k0, ekptbl
-	sltu	k0, k1, k0
-	beqz	k0, not_vmalloc
+	__FINIT
 
-	/*
-	 * Load cp0 registers.
-	 */
+	.align	5
+LEAF(handle_vec1_r10k)
+	.set	noat
+	LOAD_PTE2 k1 k0 9f
 	ld	k0, 0(k1)			# get even pte
 	ld	k1, 8(k1)			# get odd pte
+	PTE_RELOAD k0 k1
+	nop
+	tlbwr
+	eret
 
-not_vmalloc:
+9:						# handle the vmalloc range
+	LOAD_KPTE2 k1 k0 invalid_vmalloc_address
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
 	PTE_RELOAD k0 k1
 	nop
 	tlbwr
 	eret
-	END(handle_vmalloc_address)
+END(handle_vec1_r10k)
+
+
+	.align	5
+LEAF(invalid_vmalloc_address)
+	.set	noat
+	PANIC("Invalid kernel address")
+1:	b	1b
+	 nop
+END(invalid_vmalloc_address)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/mm/umap.c linux-2.4.20/arch/mips64/mm/umap.c
--- linux-2.4.19/arch/mips64/mm/umap.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/mm/umap.c	2002-10-04 00:41:11.000000000 +0000
@@ -51,7 +51,7 @@
 		address += PAGE_SIZE;
 		pte++;
 	} while (address < end);
-						  
+
 }
 
 static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address,
@@ -79,7 +79,7 @@
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
-		
+
 }
 
 /*
@@ -137,7 +137,7 @@
 
 /*
  * maps a range of vmalloc()ed memory into the requested pages. the old
- * mappings are removed. 
+ * mappings are removed.
  */
 static inline void vmap_pte_range (pte_t *pte, unsigned long address,
 				   unsigned long size, unsigned long vaddr)
@@ -146,7 +146,7 @@
 	pgd_t *vdir;
 	pmd_t *vpmd;
 	pte_t *vpte;
-	
+
 	address &= ~PMD_MASK;
 	end = address + size;
 	if (end > PMD_SIZE)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/Makefile linux-2.4.20/arch/mips64/sgi-ip27/Makefile
--- linux-2.4.19/arch/mips64/sgi-ip27/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,15 +0,0 @@
-#
-# Makefile for the IP27 specific kernel interface routines under Linux.
-#
-
-USE_STANDARD_AS_RULE := true
-
-O_TARGET = ip27.o
-
-export-objs		= ip27-rtc.o
-
-obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
-	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
-	   ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/TODO linux-2.4.20/arch/mips64/sgi-ip27/TODO
--- linux-2.4.19/arch/mips64/sgi-ip27/TODO	2000-05-13 15:30:17.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/TODO	1970-01-01 00:00:00.000000000 +0000
@@ -1,23 +0,0 @@
-1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
-not to write to the IOC3 ever.
-2. Need to figure out RRB allocation in bridge_startup().
-3. Need to figure out why address swaizzling is needed in inw/outw for 
-Qlogic scsi controllers.
-4. Need to integrate ip27-klconfig.c:find_lboard and 
-ip27-init.c:find_lbaord_real. DONE
-5. Is it okay to set calias space on all nodes as 0, instead of 8k as
-in irix?
-6. Investigate why things do not work without the setup_test() call
-being invoked on all nodes in ip27-memory.c.
-7. Too many CLIs in the locore handlers :
-For the low level handlers set up by set_except_vector(), 
-__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
-investigate whether the code should do CLI, STI or KMODE. 
-8. Too many do_page_faults invoked - investigate.
-9. start_thread must turn off UX64 ... and define tlb_refill_debug.
-10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
-does not agree with pgd_bad/pmd_bad.
-11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
-This might need to change later. Only the timer intr is set up to be
-received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
-13. Cache flushing (specially the SMP version) has to be investigated.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-berr.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-berr.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-berr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-berr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,93 +0,0 @@
-/*
- * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics
- * Copyright (C) 2002  Maciej W. Rozycki
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/module.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn0/hub.h>
-#include <asm/traps.h>
-#include <asm/uaccess.h>
-
-extern void dump_tlb_addr(unsigned long addr);
-extern void dump_tlb_all(void);
-
-static void dump_hub_information(unsigned long errst0, unsigned long errst1)
-{
-	static char *err_type[2][8] = {
-		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
-		  NULL, NULL, NULL, NULL },
-		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
-		  NULL, NULL, NULL, NULL }
-	};
-	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
-
-	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
-		printk("Hub does not contain valid error information\n");
-		return;
-	}
-
-	
-	printk("Hub has valid error information:\n");
-	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
-		printk("Overrun is set.  Error stack may contain additional "
-		       "information.\n");
-	printk("Hub error address is %08lx\n",
-	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
-	printk("Incoming message command 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
-	printk("Supplemental field of incoming message is 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
-	printk("T5 Rn (for RRB only) is 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
-	printk("Error type is %s\n", err_type[wrb]
-	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
-		? : "invalid");
-}
-
-int be_ip27_handler(struct pt_regs *regs, int is_fixup)
-{
-	unsigned long errst0, errst1;
-	int data = regs->cp0_cause & 4;
-	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
-
-	if (is_fixup)
-		return MIPS_BE_FIXUP;
-
-	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
-	       regs->cp0_epc);
-	printk("Hub information:\n");
-	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
-	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
-	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
-	dump_hub_information(errst0, errst1);
-	show_regs(regs);
-	dump_tlb_all();
-	while(1);
-	force_sig(SIGBUS, current);
-}
-
-void __init bus_error_init(void)
-{
-	/* XXX Initialize all the Hub & Bridge error handling here.  */
-	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
-	int cpuoff = cpu << 8;
-
-	be_board_handler = be_ip27_handler;
-
-	LOCAL_HUB_S(PI_ERR_INT_PEND,
-	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
-	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
-	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
-	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
-	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-console.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-console.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-console.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-console.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,58 +0,0 @@
-/*
- * 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) 2001 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn0/hub.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/sn_private.h>
-
-void prom_putchar(char c)
-{
-	struct ioc3 *ioc3;
-	struct ioc3_uartregs *uart;
-
-	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base;
-	uart = &ioc3->sregs.uarta;
-
-	while ((uart->iu_lsr & 0x20) == 0);
-	uart->iu_thr = c;
-}
-
-char __init prom_getchar(void)
-{
-	return 0;
-}
-
-static void
-ip27prom_console_write(struct console *con, const char *s, unsigned n)
-{
-	prom_printf("%s", s);
-}
-
-static kdev_t 
-ip27prom_console_dev(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static struct console ip27_prom_console = {
-    name:	"prom",
-    write:	ip27prom_console_write,
-    device:	ip27prom_console_dev,
-    flags:	CON_PRINTBUFFER,
-    index:	-1,
-};
-
-__init void ip27_setup_console(void)
-{
-	register_console(&ip27_prom_console);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-dbe-glue.S linux-2.4.20/arch/mips64/sgi-ip27/ip27-dbe-glue.S
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-dbe-glue.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-dbe-glue.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-/*
- * 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) 1994 - 1999 by Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics
- *
- * Low level exception handling
- */
-#define __ASSEMBLY__
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/exception.h>
-
-	BUILD_HANDLER ip27_ibe ip27_ibe cli silent		/* #6  */
-	BUILD_HANDLER ip27_dbe ip27_dbe cli silent		/* #7  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-init.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-init.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,838 +0,0 @@
-/*
- * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
- * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/mmzone.h>	/* for numnodes */
-#include <linux/mm.h>
-#include <asm/cpu.h>
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/sn0/hubio.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/mipsregs.h>
-#include <asm/sn/gda.h>
-#include <asm/sn/intr.h>
-#include <asm/current.h>
-#include <asm/smp.h>
-#include <asm/processor.h>
-#include <asm/mmu_context.h>
-#include <asm/sn/launch.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/mapped_kernel.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/gda.h>
-
-#define CPU_NONE		(cpuid_t)-1
-
-/*
- * The following should work till 64 nodes, ie 128p SN0s.
- */
-#define CNODEMASK_CLRALL(p)	(p) = 0
-#define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
-#define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
-
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-static int	fine_mode = 0;
-int		maxcpus;
-static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
-static cnodemask_t hub_init_mask;
-static atomic_t numstarted = ATOMIC_INIT(1);
-static int router_distance;
-nasid_t master_nasid = INVALID_NASID;
-
-cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
-nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
-cnodeid_t	cpuid_to_compact_node[MAXCPUS];
-char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
-
-hubreg_t get_region(cnodeid_t cnode)
-{
-	if (fine_mode)
-		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
-	else
-		return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
-}
-
-static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
-{
-	cnodeid_t cnode;
-
-	(*region_mask) = 0;
-	for (cnode = 0; cnode < maxnodes; cnode++) {
-		(*region_mask) |= 1ULL << get_region(cnode);
-	}
-}
-
-int is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
-		>> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
-}
-
-nasid_t get_actual_nasid(lboard_t *brd)
-{
-	klhub_t *hub;
-
-	if (!brd)
-		return INVALID_NASID;
-
-	/* find out if we are a completely disabled brd. */
-	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-		return INVALID_NASID;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid;
-	else
-		return brd->brd_nasid;
-}
-
-/* Tweak this for maximum number of CPUs to activate */
-static int max_cpus = NR_CPUS;
-
-int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, 
-							int *highest)
-{
-	static int tot_cpus_found = 0;
-	lboard_t *brd;
-	klcpu_t *acpu;
-	int cpus_found = 0;
-	cpuid_t cpuid;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
-
-	do {
-		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
-		while (acpu) {
-			cpuid = acpu->cpu_info.virtid;
-			/* cnode is not valid for completely disabled brds */
-			if (get_actual_nasid(brd) == brd->brd_nasid)
-				cpuid_to_compact_node[cpuid] = cnode;
-			if (cpuid > *highest)
-				*highest = cpuid;
-			/* Only let it join in if it's marked enabled */
-			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
-						(tot_cpus_found != max_cpus)) {
-				CPUMASK_SETB(*boot_cpumask, cpuid);
-				cpus_found++;
-				tot_cpus_found++;
-			}
-			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
-								KLSTRUCT_CPU);
-		}
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd,KLTYPE_IP27);
-		else
-			break;
-	} while (brd);
-
-	return cpus_found;
-}
-
-cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
-{
-	int i, cpus = 0, highest = 0;
-	gda_t *gdap = GDA;
-	nasid_t nasid;
-
-	/*
-	 * Initialize the arrays to invalid nodeid (-1)
-	 */
-	for (i = 0; i < MAX_COMPACT_NODES; i++)
-		compact_to_nasid_node[i] = INVALID_NASID;
-	for (i = 0; i < MAX_NASIDS; i++)
-		nasid_to_compact_node[i] = INVALID_CNODEID;
-	for (i = 0; i < MAXCPUS; i++)
-		cpuid_to_compact_node[i] = INVALID_CNODEID;
-
-	*numnodes = 0;
-	for (i = 0; i < MAX_COMPACT_NODES; i++) {
-		if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) {
-			break;
-		} else {
-			compact_to_nasid_node[i] = nasid;
-			nasid_to_compact_node[nasid] = i;
-			(*numnodes)++;
-			cpus += do_cpumask(i, nasid, boot_cpumask, &highest);
-		}
-	}
-
-	/*
-	 * Cpus are numbered in order of cnodes. Currently, disabled
-	 * cpus are not numbered.
-	 */
-
-	return(highest + 1);
-}
-
-int cpu_enabled(cpuid_t cpu)
-{
-	if (cpu == CPU_NONE)
-		return 0;
-	return (CPUMASK_TSTB(boot_cpumask, cpu) != 0);
-}
-
-void mlreset (void)
-{
-	int i;
-	void init_topology_matrix(void);
-	void dump_topology(void);
-
-
-	master_nasid = get_nasid();
-	fine_mode = is_fine_dirmode();
-
-	/*
-	 * Probe for all CPUs - this creates the cpumask and
-	 * sets up the mapping tables.
-	 */
-	CPUMASK_CLRALL(boot_cpumask);
-	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
-	printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
-
-	init_topology_matrix();
-	dump_topology();
-
-	gen_region_mask(&region_mask, numnodes);
-	CNODEMASK_CLRALL(hub_init_mask);
-
-	setup_replication_mask(numnodes);
-
-	/*
-	 * Set all nodes' calias sizes to 8k
-	 */
-	for (i = 0; i < numnodes; i++) {
-		nasid_t nasid;
-
-		nasid = COMPACT_TO_NASID_NODEID(i);
-
-		/*
-		 * Always have node 0 in the region mask, otherwise
-		 * CALIAS accesses get exceptions since the hub
-		 * thinks it is a node 0 address.
-		 */
-		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
-#ifdef CONFIG_REPLICATE_EXHANDLERS
-		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
-#else
-		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
-#endif
-
-#ifdef LATER
-		/*
-		 * Set up all hubs to have a big window pointing at
-		 * widget 0. Memory mode, widget 0, offset 0
-		 */
-		REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
-			((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
-			(0 << IIO_ITTE_WIDGET_SHIFT)));
-#endif
-	}
-}
-
-
-void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
-							char *name)
-{
-	volatile hubreg_t bits;
-	int i;
-
-	/* Check pending interrupts */
-	if ((bits = HUB_L(pend)) != 0)
-		for (i = 0; i < N_INTPEND_BITS; i++)
-			if (bits & (1 << i))
-				LOCAL_HUB_CLR_INTR(base_level + i);
-}
-	
-void intr_clear_all(nasid_t nasid)
-{
-	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
-		INT_PEND0_BASELVL, "INT_PEND0");
-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
-		INT_PEND1_BASELVL, "INT_PEND1");
-}
-
-void sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-#if 0
-	cpuid_t		cpu;
-#endif
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-#if 0
-		init_platform_nodepda();
-#endif
-		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-	}
-#if 0
-	for (cpu = 0; cpu < maxcpus; cpu++) {
-		init_platform_pda();
-	}
-#endif
-}
-
-void per_hub_init(cnodeid_t cnode)
-{
-	extern void pcibr_setup(cnodeid_t);
-	cnodemask_t	done;
-	nasid_t		nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	spin_lock(&hub_mask_lock);
-	/* Test our bit. */
-	if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) {
-		/* Turn our bit on in the mask. */
-		CNODEMASK_SETB(hub_init_mask, cnode);
-		/*
-	 	 * Do the actual initialization if it hasn't been done yet.
-	 	 * We don't need to hold a lock for this work.
-	 	 */
-		/*
-		 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
-		 */
-		REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
-		REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-		hub_rtc_init(cnode);
-		pcibr_setup(cnode); 
-#ifdef CONFIG_REPLICATE_EXHANDLERS
-		/*
-		 * If this is not a headless node initialization, 
-		 * copy over the caliased exception handlers.
-		 */
-		if (get_compact_nodeid() == cnode) {
-			extern char except_vec0, except_vec1_r10k;
-			extern char except_vec2_generic, except_vec3_generic;
-
-			memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic,
-								0x80);
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-								0x80);
-			memcpy((void *)KSEG0, &except_vec0, 0x80);
-			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
-			memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-								0x100);
-			flush_cache_l1();
-			flush_cache_l2();
-		}
-#endif
-	}
-	spin_unlock(&hub_mask_lock);
-}
-
-/*
- * This is similar to hard_smp_processor_id().
- */
-cpuid_t getcpuid(void)
-{
-	klcpu_t *klcpu;
-
-	klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
-	return klcpu->cpu_info.virtid;
-}
-
-void per_cpu_init(void)
-{
-	extern void install_cpu_nmi_handler(int slice);
-	extern void load_mmu(void);
-	static int is_slave = 0;
-	int cpu = smp_processor_id();
-	cnodeid_t cnode = get_compact_nodeid();
-
-	TLBMISS_HANDLER_SETUP();
-#if 0
-	intr_init();
-#endif
-	clear_cp0_status(ST0_IM);
-	per_hub_init(cnode);
-	cpu_time_init();
-	if (smp_processor_id())	/* master can't do this early, no kmalloc */
-		install_cpuintr(cpu);
-	/* Install our NMI handler if symmon hasn't installed one. */
-	install_cpu_nmi_handler(cputoslice(cpu));
-#if 0
-	install_tlbintr(cpu);
-#endif
-	set_cp0_status(SRB_DEV0 | SRB_DEV1);
-	if (is_slave) {
-		clear_cp0_status(ST0_BEV);
-		if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
-			set_cp0_status(ST0_XX);
-		set_cp0_status(ST0_KX|ST0_SX|ST0_UX);
-		sti();
-		load_mmu();
-		atomic_inc(&numstarted);
-	} else {
-		is_slave = 1;
-	}
-}
-
-cnodeid_t get_compact_nodeid(void)
-{
-	nasid_t nasid;
-
-	nasid = get_nasid();
-	/*
-	 * Map the physical node id to a virtual node id (virtual node ids
-	 * are contiguous).
-	 */
-	return NASID_TO_COMPACT_NODEID(nasid);
-}
-
-#ifdef CONFIG_SMP
-
-/*
- * Takes as first input the PROM assigned cpu id, and the kernel
- * assigned cpu id as the second.
- */
-static void alloc_cpupda(cpuid_t cpu, int cpunum)
-{
-	cnodeid_t	node;
-	nasid_t		nasid;
-
-	node = get_cpu_cnode(cpu);
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	cputonasid(cpunum) = nasid;
-	cputocnode(cpunum) = node;
-	cputoslice(cpunum) = get_cpu_slice(cpu);
-	cpu_data[cpunum].p_cpuid = cpu;
-}
-
-static volatile cpumask_t boot_barrier;
-
-void __init start_secondary(void)
-{
-	CPUMASK_CLRB(boot_barrier, getcpuid());	/* needs atomicity */
-	per_cpu_init();
-	per_cpu_trap_init();
-#if 0
-	ecc_init();
-	bte_lateinit();
-	init_mfhi_war();
-#endif
-	local_flush_tlb_all();
-	flush_cache_l1();
-	flush_cache_l2();
-	start_secondary();
-}
-
-__init void allowboot(void)
-{
-	int		num_cpus = 0;
-	cpuid_t		cpu, mycpuid = getcpuid();
-	cnodeid_t	cnode;
-	extern void	smp_bootstrap(void);
-
-	sn_mp_setup();
-	/* Master has already done per_cpu_init() */
-	install_cpuintr(smp_processor_id());
-#if 0
-	bte_lateinit();
-	ecc_init();
-#endif
-
-	replicate_kernel_text(numnodes);
-	boot_barrier = boot_cpumask;
-	/* Launch slaves. */
-	for (cpu = 0; cpu < maxcpus; cpu++) {
-		if (cpu == mycpuid) {
-			alloc_cpupda(cpu, num_cpus);
-			num_cpus++;
-			/* We're already started, clear our bit */
-			CPUMASK_CLRB(boot_barrier, cpu);
-			continue;
-		}
-
-		/* Skip holes in CPU space */
-		if (CPUMASK_TSTB(boot_cpumask, cpu)) {
-			struct task_struct *p;
-
-			/*
-			 * The following code is purely to make sure
-			 * Linux can schedule processes on this slave.
-			 */
-			kernel_thread(0, NULL, CLONE_PID);
-			p = init_task.prev_task;
-			sprintf(p->comm, "%s%d", "Idle", num_cpus);
-			init_tasks[num_cpus] = p;
-			alloc_cpupda(cpu, num_cpus);
-			del_from_runqueue(p);
-			p->processor = num_cpus;
-			p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */
-			unhash_process(p);
-			/* Attach to the address space of init_task. */
-			atomic_inc(&init_mm.mm_count);
-			p->active_mm = &init_mm;
-
-			/*
-		 	 * Launch a slave into smp_bootstrap().
-		 	 * It doesn't take an argument, and we
-			 * set sp to the kernel stack of the newly 
-			 * created idle process, gp to the proc struct
-			 * (so that current-> works).
-		 	 */
-			LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), 
-				(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
-				0, (void *)((unsigned long)p + 
-				KERNEL_STACK_SIZE - 32), (void *)p);
-
-			/*
-			 * Now optimistically set the mapping arrays. We
-			 * need to wait here, verify the cpu booted up, then
-			 * fire up the next cpu.
-			 */
-			__cpu_number_map[cpu] = num_cpus;
-			__cpu_logical_map[num_cpus] = cpu;
-			CPUMASK_SETB(cpu_online_map, cpu);
-			num_cpus++;
-			/*
-			 * Wait this cpu to start up and initialize its hub,
-			 * and discover the io devices it will control.
-			 * 
-			 * XXX: We really want to fire up launch all the CPUs
-			 * at once.  We have to preserve the order of the
-			 * devices on the bridges first though.
-			 */
-			while(atomic_read(&numstarted) != num_cpus);
-		}
-	}
-
-
-#ifdef LATER
-	Wait logic goes here.
-#endif
-	for (cnode = 0; cnode < numnodes; cnode++) {
-#if 0
-		if (cnodetocpu(cnode) == -1) {
-			printk("Initializing headless hub,cnode %d", cnode);
-			per_hub_init(cnode);
-		}
-#endif
-	}
-#if 0
-	cpu_io_setup();
-	init_mfhi_war();
-#endif
-	smp_num_cpus = num_cpus;
-}
-
-void __init smp_boot_cpus(void)
-{
-	extern void allowboot(void);
-
-	init_new_context(current, &init_mm);
-	current->processor = 0;
-	init_idle();
-	smp_tune_scheduling();
-	allowboot();
-}
-
-#else /* CONFIG_SMP */
-void __init start_secondary(void)
-{
-	/* XXX Why do we need this empty definition at all?  */
-}
-#endif /* CONFIG_SMP */
-
-
-#define	rou_rflag	rou_flags
-
-void
-router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
-{
-	klrou_t *router;
-	lboard_t *brd;
-	int	port;
-
-	if (router_a->rou_rflag == 1)
-		return;
-
-	if (depth >= router_distance)
-		return;
-
-	router_a->rou_rflag = 1;
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
-			continue;
-
-		brd = (lboard_t *)NODE_OFFSET_TO_K0(
-			router_a->rou_port[port].port_nasid,
-			router_a->rou_port[port].port_offset);
-
-		if (brd->brd_type == KLTYPE_ROUTER) {
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-			if (router == router_b) {
-				if (depth < router_distance)
-					router_distance = depth;
-			}
-			else
-				router_recurse(router, router_b, depth + 1);
-		}
-	}
-
-	router_a->rou_rflag = 0;
-}
-
-int
-node_distance(nasid_t nasid_a, nasid_t nasid_b)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd, *dest_brd;
-	int port;
-	klrou_t *router, *router_a = NULL, *router_b = NULL;
-
-	/* Figure out which routers nodes in question are connected to */
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		if (nasid == -1) continue;
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-					KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-			router->rou_rflag = 0;
-
-			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-				if (router->rou_port[port].port_nasid == INVALID_NASID)
-					continue;
-
-				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-					router->rou_port[port].port_nasid,
-					router->rou_port[port].port_offset);
-
-				if (dest_brd->brd_type == KLTYPE_IP27) {
-					if (dest_brd->brd_nasid == nasid_a)
-						router_a = router;
-					if (dest_brd->brd_nasid == nasid_b)
-						router_b = router;
-				}
-			}
-			
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-
-	if (router_a == NULL) {
-		printk("node_distance: router_a NULL\n");
-		return -1;
-	}
-	if (router_b == NULL) {
-		printk("node_distance: router_b NULL\n");
-		return -1;
-	}
-
-	if (nasid_a == nasid_b)
-		return 0;
-
-	if (router_a == router_b)
-		return 1;
-
-	router_distance = 100;
-	router_recurse(router_a, router_b, 2);
-
-	return router_distance;
-}
-
-void
-init_topology_matrix(void)
-{
-	nasid_t nasid, nasid2;
-	cnodeid_t row, col;
-
-	for (row = 0; row < MAX_COMPACT_NODES; row++)
-		for (col = 0; col < MAX_COMPACT_NODES; col++)
-			node_distances[row][col] = -1;
-
-	for (row = 0; row < numnodes; row++) {
-		nasid = COMPACT_TO_NASID_NODEID(row);
-		for (col = 0; col < numnodes; col++) {
-			nasid2 = COMPACT_TO_NASID_NODEID(col);
-			node_distances[row][col] = node_distance(nasid, nasid2);
-		}
-	}
-}
-
-void
-dump_topology(void)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd, *dest_brd;
-	int port;
-	int router_num = 0;
-	klrou_t *router;
-	cnodeid_t row, col;
-
-	printk("************** Topology ********************\n");
-
-	printk("    ");
-	for (col = 0; col < numnodes; col++)
-		printk("%02d ", col);
-	printk("\n");
-	for (row = 0; row < numnodes; row++) {
-		printk("%02d  ", row);
-		for (col = 0; col < numnodes; col++)
-			printk("%2d ", node_distances[row][col]);
-		printk("\n");
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		if (nasid == -1) continue;
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-					KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-			printk("Router %d:", router_num);
-			router_num++;
-
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-
-			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-				if (router->rou_port[port].port_nasid == INVALID_NASID)
-					continue;
-
-				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-					router->rou_port[port].port_nasid,
-					router->rou_port[port].port_offset);
-
-				if (dest_brd->brd_type == KLTYPE_IP27)
-					printk(" %d", dest_brd->brd_nasid);
-				if (dest_brd->brd_type == KLTYPE_ROUTER)
-					printk(" r");
-			}
-			printk("\n");
-			
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-#if 0
-#define		brd_widgetnum	brd_slot
-#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
-void
-dump_klcfg(void)
-{
-	cnodeid_t       cnode;
-	int i;
-	nasid_t         nasid;
-	lboard_t        *lbptr;
-	gda_t           *gdap;
-	
-	gdap = (gda_t *)GDA_ADDR(get_nasid());
-	if (gdap->g_magic != GDA_MAGIC) {
-		printk("dumpklcfg_cmd: Invalid GDA MAGIC\n");
-		return;
-	}
-
-	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
-		nasid = gdap->g_nasidtable[cnode];
-
-		if (nasid == INVALID_NASID)
-			continue;
-
-		printk("\nDumpping klconfig Nasid %d:\n", nasid);
-	
-		lbptr = KL_CONFIG_INFO(nasid);
-
-		while (lbptr) {
-			printk("    %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx",
-				"board name here", /* BOARD_NAME(lbptr->brd_type), */
-				lbptr->brd_nasid, lbptr->brd_module, 
-				lbptr->brd_widgetnum,
-				lbptr->brd_partition, 
-				(lbptr->brd_nic), lbptr);
-			if (lbptr->brd_flags & DUPLICATE_BOARD)
-				printk(" -D");
-			printk("\n");
-			for (i = 0; i < lbptr->brd_numcompts; i++) {
-				klinfo_t *kli;
-				kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]);                       
-				printk("        type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n", 
-					kli->struct_type, 
-					kli->flags,
-					kli->diagval,
-					kli->physid,
-					kli->virtid,
-					"comp. name here");
-					/* COMPONENT_NAME(kli->struct_type)); */
-			}
-			lbptr = KLCF_NEXT(lbptr);
-		}
-	}
-	printk("\n");
-
-	/* Useful to print router maps also */
-
-	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
-		klrou_t *kr;
-		int i;
-
-        	nasid = gdap->g_nasidtable[cnode];
-        	if (nasid == INVALID_NASID)
-            		continue;
-        	lbptr = KL_CONFIG_INFO(nasid);
-
-        	while (lbptr) {
-			
-			lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER);
-			if(!lbptr)
-				break;
-			if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) {
-				printk("%llx -> \n", lbptr->brd_nic);
-				kr = (klrou_t *)find_first_component(lbptr,
-					KLSTRUCT_ROU);
-				for (i = 1; i <= MAX_ROUTER_PORTS; i++) {
-					printk("[%d, %llx]; ",
-						kr->rou_port[i].port_nasid,
-						kr->rou_port[i].port_offset);
-				}
-				printk("\n");
-			}
-			lbptr = KLCF_NEXT(lbptr);
-        	}
-        	printk("\n");
-    	}
-
-	dump_topology();
-}
-#endif
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-irq-glue.S linux-2.4.20/arch/mips64/sgi-ip27/ip27-irq-glue.S
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-irq-glue.S	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-irq-glue.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,64 +0,0 @@
-/*
- * 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) 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	.text
-	.set	noat
-	.align	5
-NESTED(ip27_irq, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-
-	/* IP27 may signal interrupt which we're not interested in.
-	   Mask them out.  */
-	mfc0	s0, CP0_CAUSE
-	mfc0	t0, CP0_STATUS
-	and	s0, t0
-
-	/* First check for RT interrupt.  */
-	andi	a0, s0, CAUSEF_IP4
-	beqz	a0, 1f
-
-	/* Ok, a timer interrupt. */
-	move	a0, sp
-	jal	rt_timer_interrupt
-
-	j	ret_from_irq
-
-1:	andi	a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
-	beqz	a0, 1f
-
-	/* ... a device interrupt ...  */
-	move	a0, sp
-	jal	ip27_do_irq
-
-	j	ret_from_irq
-
-1:
-#if 1
-	mfc0	a1, CP0_STATUS
-	srl	a1, a1, 8
-	andi	a1, 0xff
-
-	mfc0	a2, CP0_CAUSE
-	srl	a2, a2, 8
-	andi	a2, 0xff
-
-	move	a3, s0
-	PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
-	ld	a1, PT_EPC(sp)
-0:	b	0b
-#endif
-
-	j	ret_from_irq
-	END(ip27_irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-irq.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-irq.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,487 +0,0 @@
-/*
- * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
- *
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- * Copyright (C) 1999 - 2001 Kanoj Sarcar
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp_lock.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/pci/bridge.h>
-#include <asm/sn/sn0/hub.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/agent.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/intr_public.h>
-
-
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* These should die */
-unsigned char bus_to_wid[256];	/* widget id for linux pci bus */
-unsigned char bus_to_nid[256];	/* nasid for linux pci bus */
-unsigned char num_bridges;	/* number of bridges in the system */
-
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
-
-extern asmlinkage void ip27_irq(void);
-extern void do_IRQ(int irq, struct pt_regs *regs);
-
-extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[];
-int intr_connect_level(int cpu, int bit);
-int intr_disconnect_level(int cpu, int bit);
-
-/*
- * There is a single intpend register per node, and we want to have
- * distinct levels for intercpu intrs for both cpus A and B on a node.
- */
-int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
-
-/*
- * use these macros to get the encoded nasid and widget id
- * from the irq value
- */
-#define IRQ_TO_BUS(i)			irq_to_bus[(i)]
-#define IRQ_TO_CPU(i)			bus_to_cpu[IRQ_TO_BUS(i)]
-#define NASID_FROM_PCI_IRQ(i)		bus_to_nid[IRQ_TO_BUS(i)]
-#define WID_FROM_PCI_IRQ(i)		bus_to_wid[IRQ_TO_BUS(i)]
-#define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
-
-static inline int alloc_level(cpuid_t cpunum, int irq)
-{
-	cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum);
-	int j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
-
-	while (++j < PERNODE_LEVELS) {
-		if (node_level_to_irq[nodenum][j] == -1) {
-			node_level_to_irq[nodenum][j] = irq;
-			return j;
-		}
-	}
-	printk("Cpu %ld flooded with devices\n", cpunum);
-	while(1);
-	return -1;
-}
-
-static inline int find_level(cpuid_t *cpunum, int irq)
-{
-	int j;
-	cnodeid_t nodenum = INVALID_CNODEID;
-
-	while (++nodenum < MAX_COMPACT_NODES) {
-		j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
-		while (++j < PERNODE_LEVELS)
-			if (node_level_to_irq[nodenum][j] == irq) {
-				*cpunum = 0;	/* XXX Fixme */
-				return(j);
-			}
-	}
-	printk("Could not identify cpu/level for irq %d\n", irq);
-	while(1);
-	return(-1);
-}
-
-/*
- * Find first bit set
- */
-static int ms1bit(unsigned long x)
-{
-	int b = 0, s;
-
-	s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
-	s =  8; if (x >>  8 == 0) s = 0; b += s; x >>= s;
-	s =  4; if (x >>  4 == 0) s = 0; b += s; x >>= s;
-	s =  2; if (x >>  2 == 0) s = 0; b += s; x >>= s;
-	s =  1; if (x >>  1 == 0) s = 0; b += s;
-
-	return b;
-}
-
-/*
- * This code is unnecessarily complex, because we do SA_INTERRUPT
- * intr enabling. Basically, once we grab the set of intrs we need
- * to service, we must mask _all_ these interrupts; firstly, to make
- * sure the same intr does not intr again, causing recursion that 
- * can lead to stack overflow. Secondly, we can not just mask the
- * one intr we are do_IRQing, because the non-masked intrs in the
- * first set might intr again, causing multiple servicings of the
- * same intr. This effect is mostly seen for intercpu intrs.
- * Kanoj 05.13.00
- */
-void ip27_do_irq(struct pt_regs *regs)
-{
-	int irq, swlevel;
-	hubreg_t pend0, mask0;
-	cpuid_t thiscpu = smp_processor_id();
-	int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ?
-					PI_INT_MASK0_A : PI_INT_MASK0_B);
-
-	/* copied from Irix intpend0() */
-	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & 
-				(mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) {
-		pend0 &= mask0;		/* Pick intrs we should look at */
-		if (pend0) {
-			/* Prevent any of the picked intrs from recursing */
-			LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0));
-			do {
-				swlevel = ms1bit(pend0);
-				LOCAL_HUB_CLR_INTR(swlevel);
-				/* "map" swlevel to irq */
-				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
-				do_IRQ(irq, regs);
-				/* clear bit in pend0 */
-				pend0 ^= 1ULL << swlevel;
-			} while(pend0);
-			/* Now allow the set of serviced intrs again */
-			LOCAL_HUB_S(pi_int_mask0, mask0);
-			LOCAL_HUB_L(PI_INT_PEND0);
-		}
-	}
-}
-
-
-/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(unsigned int irq)
-{
-	bridgereg_t device;
-	bridge_t *bridge;
-	int pin, swlevel;
-	cpuid_t cpu;
-	nasid_t master = NASID_FROM_PCI_IRQ(irq);
-
-	if (irq < BASE_PCI_IRQ)
-		return 0;
-
-        bridge = (bridge_t *) NODE_SWIN_BASE(master, WID_FROM_PCI_IRQ(irq));
-	pin = SLOT_FROM_PCI_IRQ(irq);
-	cpu = IRQ_TO_CPU(irq);
-
-	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
-	/*
-	 * "map" irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = alloc_level(cpu, irq);
-	intr_connect_level(cpu, swlevel);
-
-	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8));
-	bridge->b_int_enable |= (1 << pin);
-	/* more stuff in int_enable reg */
-	bridge->b_int_enable |= 0x7ffffe00;
-
-	/*
-	 * XXX This only works if b_int_device is initialized to 0!
-	 * We program the bridge to have a 1:1 mapping between devices
-	 * (slots) and intr pins.
-	 */
-	device = bridge->b_int_device;
-	device |= (pin << (pin*3));
-	bridge->b_int_device = device;
-
-        bridge->b_widget.w_tflush;                      /* Flush */
-
-        return 0;       /* Never anything pending.  */
-}
-
-/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int shutdown_bridge_irq(unsigned int irq)
-{
-	bridge_t *bridge;
-	int pin, swlevel;
-	cpuid_t cpu;
-
-	if (irq < BASE_PCI_IRQ)
-		return 0;
-
-	bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq), 
-	                                     WID_FROM_PCI_IRQ(irq));
-	DBG("bridge_shutdown: irq 0x%x\n", irq);
-	pin = SLOT_FROM_PCI_IRQ(irq);
-
-	/*
-	 * map irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = find_level(&cpu, irq);
-	intr_disconnect_level(cpu, swlevel);
-	LEVEL_TO_IRQ(cpu, swlevel) = -1;
-
-	bridge->b_int_enable &= ~(1 << pin);
-	bridge->b_widget.w_tflush;                      /* Flush */
-
-	return 0;       /* Never anything pending.  */
-}
-
-static inline void enable_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void disable_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void mask_and_ack_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void end_bridge_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_bridge_irq(irq);
-}
-
-static struct hw_interrupt_type bridge_irq_type = {
-	"bridge",
-	startup_bridge_irq,
-	shutdown_bridge_irq,
-	enable_bridge_irq,
-	disable_bridge_irq,
-	mask_and_ack_bridge_irq,
-	end_bridge_irq
-};
-
-void irq_debug(void)
-{
-	bridge_t *bridge = (bridge_t *) 0x9200000008000000;
-
-	printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
-	printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
-	printk("PI_INT_PEND0   = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0));
-	printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A));
-}
-
-void __init init_IRQ(void)
-{
-	int i;
-
-	set_except_vector(0, ip27_irq);
-
-	/*
-	 * Right now the bridge irq is our kitchen sink interrupt type
-	 */
-	for (i = 0; i <= NR_IRQS; i++) {
-		irq_desc[i].status	= IRQ_DISABLED;
-		irq_desc[i].action	= 0;
-		irq_desc[i].depth	= 1;
-		irq_desc[i].handler	= &bridge_irq_type;
-	}
-}
-
-/*
- * Get values that vary depending on which CPU and bit we're operating on.
- */
-static hub_intmasks_t *intr_get_ptrs(cpuid_t cpu, int bit, int *new_bit,
-				hubreg_t **intpend_masks, int *ip)
-{
-	hub_intmasks_t *hub_intmasks;
-
-	hub_intmasks = &cpu_data[cpu].p_intmasks;
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-	return hub_intmasks;
-}
-
-int intr_connect_level(int cpu, int bit)
-{
-	int ip;
-	int slice = cputoslice(cpu);
-	volatile hubreg_t *mask_reg;
-	hubreg_t *intpend_masks;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
-
-	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS);
-
-	intpend_masks[0] |= (1ULL << (u64)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + 
-				PI_INT_MASK_OFFSET * slice);
-	} else {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + 
-				PI_INT_MASK_OFFSET * slice);
-	}
-	HUB_S(mask_reg, intpend_masks[0]);
-	return(0);
-}
-
-int intr_disconnect_level(int cpu, int bit)
-{
-	int ip;
-	int slice = cputoslice(cpu);
-	volatile hubreg_t *mask_reg;
-	hubreg_t *intpend_masks;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
-
-	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
-	intpend_masks[0] &= ~(1ULL << (u64)bit);
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + 
-				PI_INT_MASK_OFFSET * slice);
-	} else {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + 
-				PI_INT_MASK_OFFSET * slice);
-	}
-	HUB_S(mask_reg, intpend_masks[0]);
-	return(0);
-}
-
-
-void handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* Nothing, the return from intr will work for us */
-}
-
-#ifdef CONFIG_SMP
-
-void core_send_ipi(int destid, unsigned int action)
-{
-	int irq;
-
-#if (CPUS_PER_NODE == 2)
-	switch (action) {
-		case SMP_RESCHEDULE_YOURSELF:
-			irq = CPU_RESCHED_A_IRQ;
-			break;
-		case SMP_CALL_FUNCTION:
-			irq = CPU_CALL_A_IRQ;
-			break;
-		default:
-			panic("sendintr");
-	}
-	irq += cputoslice(destid);
-
-	/*
-	 * Convert the compact hub number to the NASID to get the correct
-	 * part of the address space.  Then set the interrupt bit associated
-	 * with the CPU we want to send the interrupt to.
-	 */
-	REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)),
-			FAST_IRQ_TO_LEVEL(irq));
-#else
-	<< Bomb!  Must redefine this for more than 2 CPUS. >>
-#endif
-}
-
-#endif
-
-extern void smp_call_function_interrupt(void);
-
-void install_cpuintr(int cpu)
-{
-#ifdef CONFIG_SMP
-#if (CPUS_PER_NODE == 2)
-	static int done = 0;
-
-	/*
-	 * This is a hack till we have a pernode irqlist. Currently,
-	 * just have the master cpu set up the handlers for the per
-	 * cpu irqs.
-	 */
-	if (done == 0) {
-		int j;
-
-		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, 
-							0, "resched", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, 
-							0, "resched", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
-							0, "callfunc", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
-							0, "callfunc", 0))
-			panic("intercpu intr unconnectible");
-
-		for (j = 0; j < PERNODE_LEVELS; j++)
-			LEVEL_TO_IRQ(0, j) = -1;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) = 
-							CPU_RESCHED_A_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) = 
-							CPU_RESCHED_B_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) = 
-							CPU_CALL_A_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) = 
-							CPU_CALL_B_IRQ;
-		for (j = 1; j < MAX_COMPACT_NODES; j++)
-			memcpy(&node_level_to_irq[j][0], 
-			&node_level_to_irq[0][0], 
-			sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS);
-
-		done = 1;
-	}
-
-	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ + 
-							cputoslice(cpu)));
-	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ +
-							cputoslice(cpu)));
-#else /* CPUS_PER_NODE */
-#error Must redefine this for more than 2 CPUS.
-#endif /* CPUS_PER_NODE */
-#endif /* CONFIG_SMP */
-}
-
-void install_tlbintr(int cpu)
-{
-#if 0
-	int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
-
-	intr_connect_level(cpu, intr_bit);
-#endif
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-klconfig.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-klconfig.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-klconfig.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-klconfig.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/param.h>
-#include <linux/timex.h>
-#include <linux/mm.h>		
-
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-
-klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			printk("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;		/* next component */
-	}
-
-	for (; index < KLCF_NUM_COMPS(brd); index++) {
-		kli = KLCF_COMP(brd, index);
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-cnodeid_t get_cpu_cnode(cpuid_t cpu)
-{
-	return CPUID_TO_COMPACT_NODEID(cpu);
-}
-
-klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
-{
-	lboard_t *brd;
-	klcpu_t *acpu;
-
-	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
-		return (klcpu_t *)NULL;
-
-	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
-		return (klcpu_t *)NULL;
-
-	do {
-		if ((acpu->cpu_info.physid) == slice)
-			return acpu;
-	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
-								KLSTRUCT_CPU)));
-	return (klcpu_t *)NULL;
-}
-
-klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
-{
-	nasid_t nasid;
-	int slice;
-	klcpu_t *acpu;
-	gda_t *gdap = GDA;
-	cnodeid_t cnode;
-
-	if (!(cpu < MAXCPUS)) {
-		printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
-		return NULL;
-	}
-
-	cnode = get_cpu_cnode(cpu);
-	if (cnode == INVALID_CNODEID)
-		return NULL;
-
-	if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
-		return NULL;
-
-	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
-		acpu = nasid_slice_to_cpuinfo(nasid, slice);
-		if (acpu && acpu->cpu_info.virtid == cpu)
-			return acpu;
-	}
-	return NULL;
-}
-
-int get_cpu_slice(cpuid_t cpu)
-{
-	klcpu_t *acpu;
-
-	if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
-		return -1;
-	return acpu->cpu_info.physid;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-klnuma.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-klnuma.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-klnuma.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-klnuma.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,143 +0,0 @@
-/*
- * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
- * Copyright 2000 - 2001 Silicon Graphics, Inc.
- * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mmzone.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-#include <asm/smp.h>
-#include <asm/sn/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-#include <asm/mmzone.h>
-#include <asm/sn/klkernvars.h>
-#include <asm/sn/mapped_kernel.h>
-#include <asm/sn/sn_private.h>
-
-extern char _end;
-static cpumask_t ktext_repmask;
-
-/*
- * XXX - This needs to be much smarter about where it puts copies of the
- * kernel.  For example, we should never put a copy on a headless node,
- * and we should respect the topology of the machine.
- */
-void __init setup_replication_mask(int maxnodes)
-{
-	static int 	numa_kernel_replication_ratio;
-	cnodeid_t	cnode;
-
-	/* Set only the master cnode's bit.  The master cnode is always 0. */
-	CPUMASK_CLRALL(ktext_repmask);
-	CPUMASK_SETB(ktext_repmask, 0);
-
-	numa_kernel_replication_ratio = 0;
-#ifdef CONFIG_REPLICATE_KTEXT
-#ifndef CONFIG_MAPPED_KERNEL
-#error Kernel replication works with mapped kernel support. No calias support.
-#endif
-	numa_kernel_replication_ratio = 1;
-#endif
-
-	for (cnode = 1; cnode < numnodes; cnode++) {
-		/* See if this node should get a copy of the kernel */
-		if (numa_kernel_replication_ratio &&
-		    !(cnode % numa_kernel_replication_ratio)) {
-
-			/* Advertise that we have a copy of the kernel */
-			CPUMASK_SETB(ktext_repmask, cnode);
-		}
-	}
-
-	/* Set up a GDA pointer to the replication mask. */
-	GDA->g_ktext_repmask = &ktext_repmask;
-}
-
-
-static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
-{
-	kern_vars_t *kvp;
-	cnodeid_t client_cnode;
-
-	client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
-	
-	kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars);
-
-	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
-
-	kvp->kv_magic = KV_MAGIC;
-
-	kvp->kv_ro_nasid = server_nasid;
-	kvp->kv_rw_nasid = master_nasid;
-	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
-	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
-	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
-}
-
-/* XXX - When the BTE works, we should use it instead of this. */
-static __init void copy_kernel(nasid_t dest_nasid)
-{
-	extern char _stext, _etext;
-	unsigned long dest_kern_start, source_start, source_end, kern_size;
-
-	source_start = (unsigned long)&_stext;
-	source_end = (unsigned long)&_etext;
-	kern_size = source_end - source_start;
-
-	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
-					    dest_nasid);
-	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
-}
-
-void __init replicate_kernel_text(int maxnodes)
-{
-	cnodeid_t cnode;
-	nasid_t client_nasid;
-	nasid_t server_nasid;
-
-	server_nasid = master_nasid;
-
-	/* Record where the master node should get its kernel text */
-	set_ktext_source(master_nasid, master_nasid);
-
-	for (cnode = 1; cnode < maxnodes; cnode++) {
-		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		/* Check if this node should get a copy of the kernel */
-		if (CPUMASK_TSTB(ktext_repmask, cnode)) {
-			server_nasid = client_nasid;
-			copy_kernel(server_nasid);
-		}
-
-		/* Record where this node should get its kernel text */
-		set_ktext_source(client_nasid, server_nasid);
-	}
-}
-
-/*
- * Return pfn of first free page of memory on a node. PROM may allocate
- * data structures on the first couple of pages of the first slot of each 
- * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
- */
-pfn_t node_getfirstfree(cnodeid_t cnode)
-{
-	unsigned long loadbase = CKSEG0;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
-	unsigned long offset;
-
-#ifdef CONFIG_MAPPED_KERNEL
-	loadbase = CKSSEG + 16777216;
-#endif
-	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
-	if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode)))
-		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
-	else
-		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> 
-								PAGE_SHIFT);
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-memory.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-memory.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-memory.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-memory.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,344 +0,0 @@
-/*
- * 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) 2000 by Ralf Baechle
- * Copyright (C) 2000 by Silicon Graphics, Inc.
- *
- * On SGI IP27 the ARC memory configuration data is completly bogus but
- * alternate easier to use mechanisms are available.
- */
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/swap.h>
-
-#include <asm/page.h>
-#include <asm/bootinfo.h>
-#include <asm/addrspace.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/mmzone.h>
-
-/* ip27-klnuma.c   */
-extern pfn_t node_getfirstfree(cnodeid_t cnode);
-
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define SLOT_IGNORED	0xffff
-
-short slot_lastfilled_cache[MAX_COMPACT_NODES];
-unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
-static pfn_t numpages;
-
-plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
-bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
-
-int numa_debug(void)
-{
-	printk("NUMA debug\n");
-	*(int *)0 = 0;
-	return(0);
-}
-
-/*
- * Return the number of pages of memory provided by the given slot
- * on the specified node.
- */
-pfn_t slot_getsize(cnodeid_t node, int slot)
-{
-	return (pfn_t) slot_psize_cache[node][slot];
-}
-
-/*
- * Return highest slot filled
- */
-int node_getlastslot(cnodeid_t node)
-{
-	return (int) slot_lastfilled_cache[node];
-}
-
-/*
- * Return the pfn of the last free page of memory on a node.
- */
-pfn_t node_getmaxclick(cnodeid_t node)
-{
-	pfn_t	slot_psize;
-	int	slot;
-
-	/*
-	 * Start at the top slot. When we find a slot with memory in it,
-	 * that's the winner.
-	 */
-	for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) {
-		if ((slot_psize = slot_getsize(node, slot))) {
-			if (slot_psize == SLOT_IGNORED)
-				continue;
-			/* Return the basepfn + the slot size, minus 1. */
-			return slot_getbasepfn(node, slot) + slot_psize - 1;
-		}
-	}
-
-	/*
-	 * If there's no memory on the node, return 0. This is likely
-	 * to cause problems.
-	 */
-	return (pfn_t)0;
-}
-
-static pfn_t slot_psize_compute(cnodeid_t node, int slot)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klmembnk_t *banks;
-	unsigned long size;
-
-	nasid = COMPACT_TO_NASID_NODEID(node);
-	/* Find the node board */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
-	if (!brd)
-		return 0;
-
-	/* Get the memory bank structure */
-	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
-	if (!banks)
-		return 0;
-
-	/* Size in _Megabytes_ */
-	size = (unsigned long)banks->membnk_bnksz[slot/4];
-
-	/* hack for 128 dimm banks */
-	if (size <= 128) {
-		if (slot%4 == 0) {
-			size <<= 20;		/* size in bytes */
-			return(size >> PAGE_SHIFT);
-		} else {
-			return 0;
-		}
-	} else {
-		size /= 4;
-		size <<= 20;
-		return(size >> PAGE_SHIFT);
-	}
-}
-
-pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
-{
-	cnodeid_t node;
-	int slot, numslots;
-	pfn_t num_pages = 0, slot_psize;
-	pfn_t slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
-	int ignore;
-
-	for (node = 0; node < numnodes; node++) {
-		numslots = node_getnumslots(node);
-		ignore = nodebytes = 0;
-		for (slot = 0; slot < numslots; slot++) {
-			slot_psize = slot_psize_compute(node, slot);
-			if (slot == 0) slot0sz = slot_psize;
-			/* 
-			 * We need to refine the hack when we have replicated
-			 * kernel text.
-			 */
-			nodebytes += SLOT_SIZE;
-			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
-						(slot0sz << PAGE_SHIFT))
-				ignore = 1;
-			if (ignore && slot_psize) {
-				printk("Ignoring slot %d onwards on node %d\n",
-								slot, node);
-				slot_psize_cache[node][slot] = SLOT_IGNORED;
-				slot = numslots;
-				continue;
-			}
-			num_pages += slot_psize;
-			slot_psize_cache[node][slot] = 
-					(unsigned short) slot_psize;
-			if (slot_psize)
-				slot_lastfilled_cache[node] = slot;
-		}
-	}
-	if (maxpmem)
-		return((maxpmem > num_pages) ? num_pages : maxpmem);
-	else
-		return num_pages;
-}
-
-/*
- * Currently, the intranode memory hole support assumes that each slot
- * contains at least 32 MBytes of memory. We assume all bootmem data
- * fits on the first slot.
- */
-void __init prom_meminit(void)
-{
-	extern void mlreset(void);
-	cnodeid_t node;
-	pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn;
-	unsigned long bootmap_size;
-	int node_datasz;
-
-	node_datasz = PFN_UP(sizeof(plat_pg_data_t));
-	mlreset();
-	numpages = szmem(0, 0);
-	for (node = (numnodes - 1); node >= 0; node--) {
-		slot_firstpfn = slot_getbasepfn(node, 0);
-		slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
-		slot_freepfn = node_getfirstfree(node);
-		/* Foll line hack for non discontigmem; remove once discontigmem
-		 * becomes the default. */
-		max_low_pfn = (slot_lastpfn - slot_firstpfn);
-
-		/*
-		 * Allocate the node data structure on the node first.
-		 */
-		plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \
-							<< PAGE_SHIFT));
-		NODE_DATA(node)->bdata = plat_node_bdata + node;
-		slot_freepfn += node_datasz;
-	  	bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, 
-						slot_firstpfn, slot_lastpfn);
-		free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, 
-				(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
-		reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
-		  ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
-	}
-	printk("Total memory probed : 0x%lx pages\n", numpages);
-}
-
-int __init page_is_ram(unsigned long pagenr)
-{
-        return 1;
-}
-
-void __init
-prom_free_prom_memory (void)
-{
-	/* We got nothing to free here ...  */
-}
-
-#ifdef CONFIG_DISCONTIGMEM
-
-static pfn_t pagenr = 0;
-
-void __init paging_init(void)
-{
-	pmd_t *pmd = kpmdtbl;
-	pte_t *pte = kptbl;
-
-	cnodeid_t node;
-	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-	int i;
-
-	/* Initialize the entire pgd.  */
-	pgd_init((unsigned long)swapper_pg_dir);
-	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
-	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
-
-	/* This is for vmalloc  */
-	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
-	memset((void *)kpmdtbl, 0, PAGE_SIZE);
-	pgd_set(swapper_pg_dir, kpmdtbl);
-	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
-		pmd_val(*pmd) = (unsigned long)pte;
-
-	for (node = 0; node < numnodes; node++) {
-		pfn_t start_pfn = slot_getbasepfn(node, 0);
-		pfn_t end_pfn = node_getmaxclick(node);
-
-		zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
-		free_area_init_node(node, NODE_DATA(node), 0, zones_size, 
-						start_pfn << PAGE_SHIFT, 0);
-		if ((PLAT_NODE_DATA_STARTNR(node) + 
-					PLAT_NODE_DATA_SIZE(node)) > pagenr)
-			pagenr = PLAT_NODE_DATA_STARTNR(node) +
-					PLAT_NODE_DATA_SIZE(node);
-	}
-}
-
-void __init mem_init(void)
-{
-	extern char _stext, _etext, _fdata, _edata;
-	extern char __init_begin, __init_end;
-	extern unsigned long totalram_pages;
-	extern unsigned long setup_zero_pages(void);
-	cnodeid_t nid;
-	unsigned long tmp;
-	unsigned long codesize, datasize, initsize;
-	int slot, numslots;
-	struct page *pg, *pslot;
-	pfn_t pgnr;
-
-	num_physpages = numpages;	/* memory already sized by szmem */
-	max_mapnr = pagenr;		/* already found during paging_init */
-	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
-
-	for (nid = 0; nid < numnodes; nid++) {
-
-		/*
-		 * Hack till free_area_init_core() zeroes free_pages
-		 */
-		for (tmp = 0; tmp < MAX_NR_ZONES; tmp++)
-			PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0;
-		/*
-	 	 * This will free up the bootmem, ie, slot 0 memory.
-	 	 */
-		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
-
-		/*
-		 * We need to manually do the other slots.
-		 */
-		pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
-		pgnr = PLAT_NODE_DATA_STARTNR(nid) + slot_getsize(nid, 0);
-		numslots = node_getlastslot(nid);
-		for (slot = 1; slot <= numslots; slot++) {
-			pslot = NODE_DATA(nid)->node_mem_map + 
-			   slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
-
-			/*
-			 * Mark holes in previous slot. May also want to
-			 * free up the pages that hold the memmap entries.
-			 */
-			while (pg < pslot) {
-				pg++; pgnr++;
-			}
-
-			/*
-			 * Free valid memory in current slot.
-			 */
-			pslot += slot_getsize(nid, slot);
-			while (pg < pslot) {
-				if (!page_is_ram(pgnr))
-					continue;
-				ClearPageReserved(pg);
-				atomic_set(&pg->count, 1);
-				__free_page(pg);
-				totalram_pages++;
-				pg++; pgnr++;
-			}
-		}
-	}
-
-	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	tmp = (unsigned long) nr_free_pages();
-	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
-		"%ldk data, %ldk init)\n",
-		tmp << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		(num_physpages - tmp) << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10);
-}
-
-#endif /* CONFIG_DISCONTIGMEM */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-nmi.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-nmi.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-nmi.c	2000-11-29 05:42:04.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-nmi.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,168 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/mmzone.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <asm/atomic.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nmi.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn0/hub.h>
-
-#if 0
-#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)
-#else
-#define NODE_NUM_CPUS(n)	CPUS_PER_NODE
-#endif
-
-#define CNODEID_NONE (cnodeid_t)-1
-#define enter_panic_mode()	spin_lock(&nmi_lock)
-
-typedef unsigned long machreg_t;
-
-spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * Lets see what else we need to do here. Set up sp, gp?
- */
-void nmi_dump(void)
-{
-	void cont_nmi_dump(void);
-
-	cont_nmi_dump();
-}
-
-void install_cpu_nmi_handler(int slice)
-{
-	nmi_t *nmi_addr;
-
-	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
-	if (nmi_addr->call_addr)
-		return;
-	nmi_addr->magic = NMI_MAGIC;
-	nmi_addr->call_addr = (void *)nmi_dump;
-	nmi_addr->call_addr_c =
-		(void *)(~((unsigned long)(nmi_addr->call_addr)));
-	nmi_addr->call_parm = 0;
-}
-
-/*
- * Copy the cpu registers which have been saved in the IP27prom format
- * into the eframe format for the node under consideration.
- */
-
-void
-nmi_cpu_eframe_save(nasid_t nasid,
-		    int	    slice)
-{
-	int 		i, numberof_nmi_cpu_regs;
-	machreg_t	*prom_format;
-
-	/* Get the total number of registers being saved by the prom */
-	numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t);
-
-	/* Get the pointer to the current cpu's register set. */
-	prom_format = 
-	    (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
-			  slice * IP27_NMI_KREGS_CPU_SIZE);
-
-	printk("NMI nasid %d: slice %d\n", nasid, slice);
-	for (i = 0; i < numberof_nmi_cpu_regs; i++)
-		printk("0x%lx  ", prom_format[i]);
-	printk("\n\n");
-}	
-
-/*
- * Copy the cpu registers which have been saved in the IP27prom format
- * into the eframe format for the node under consideration.
- */
-void
-nmi_node_eframe_save(cnodeid_t  cnode)
-{
-	int		cpu;
-	nasid_t		nasid;
-
-	/* Make sure that we have a valid node */
-	if (cnode == CNODEID_NONE)
-		return;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	if (nasid == INVALID_NASID)
-		return;
-
-	/* Save the registers into eframe for each cpu */
-	for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++) 
-		nmi_cpu_eframe_save(nasid, cpu);
-}
-
-/*
- * Save the nmi cpu registers for all cpus in the system.
- */
-void
-nmi_eframes_save(void)
-{
-	cnodeid_t	cnode;
-
-	for(cnode = 0 ; cnode < numnodes; cnode++) 
-		nmi_node_eframe_save(cnode);
-}
-
-void
-cont_nmi_dump(void)
-{
-#ifndef REAL_NMI_SIGNAL
-	static atomic_t nmied_cpus = ATOMIC_INIT(0);
-
-	atomic_inc(&nmied_cpus);
-#endif
-	/* 
-	 * Use enter_panic_mode to allow only 1 cpu to proceed
-	 */
-	enter_panic_mode();
-
-#ifdef REAL_NMI_SIGNAL
-	/*
-	 * Wait up to 15 seconds for the other cpus to respond to the NMI.
-	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
-	 * This is for 2 reasons:
-	 *	- sometimes a MMSC fail to NMI all cpus.
-	 *	- on 512p SN0 system, the MMSC will only send NMIs to
-	 *	  half the cpus. Unfortunately, we dont know which cpus may be
-	 *	  NMIed - it depends on how the site chooses to configure.
-	 * 
-	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
-	 * send NMIs to all cpus on a 256p system.
-	 */
-	for (i=0; i < 1500; i++) {
-		for (node=0; node < numnodes; node++)
-			if (NODEPDA(node)->dump_count == 0)
-				break;
-		if (node == numnodes)
-			break;
-		if (i == 1000) {
-			for (node=0; node < numnodes; node++)
-				if (NODEPDA(node)->dump_count == 0) {
-					cpu = CNODE_TO_CPU_BASE(node);
-					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
-						CPUMASK_SETB(nmied_cpus, cpu);
-						/* 
-						 * cputonasid, cputoslice
-						 * needs kernel cpuid
-						 */
-						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
-					}
-				}
-					
-		}
-		udelay(10000);
-	}
-#else
-	while (atomic_read(&nmied_cpus) != smp_num_cpus);
-#endif
-
-	/*
-	 * Save the nmi cpu registers for all cpu in the eframe format.
-	 */
-	nmi_eframes_save();
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-pci-dma.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-pci-dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-pci-dma.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,150 +0,0 @@
-/*
- * Dynamic DMA mapping support.
- *
- * On the Origin there is dynamic DMA address translation for all PCI DMA.
- * However we don't use this facility yet but rely on the 2gb direct
- * mapped DMA window for PCI64.  So consistent alloc/free are merely page
- * allocation/freeing.  The rest of the dynamic DMA mapping interface is
- * implemented in <asm/pci.h>.  So this code will fail with more than
- * 2gb of memory.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-			   dma_addr_t *dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC;
-	int order = get_order(size);
-
-	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
-		gfp |= GFP_DMA;
-	ret = (void *)__get_free_pages(gfp, order);
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = (bus_to_baddr[hwdev->bus->number] | __pa(ret));
-	}
-
-	return ret;
-}
-
-void pci_free_consistent(struct pci_dev *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
-dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
-                          int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	return (bus_to_baddr[hwdev->bus->number] | __pa(ptr));
-}
-
-/*
- * Unmap a single streaming mode DMA translation.  The dma_addr and size
- * must match what was provided for in a previous pci_map_single call.  All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
-void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-                     size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scather-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-               int direction)
-{
-	int i;
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Make sure that gcc doesn't leave the empty loop body.  */
-	for (i = 0; i < nents; i++, sg++) {
-		sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
-	}
-
-	return nents;
-}
-
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-                  int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/*
- * Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, the
- * device again owns the buffer.
- */
-void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
-                         size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-}
-
-/*
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list,
- * same rules and usage.
- */
-void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-                     int nelems, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-pci.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-pci.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,428 +0,0 @@
-/*
- * 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) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/sn/arch.h>
-#include <asm/pci/bridge.h>
-#include <asm/paccess.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-/*
- * Max #PCI busses we can handle; ie, max #PCI bridges.
- */
-#define MAX_PCI_BUSSES		40
-
-/*
- * Max #PCI devices (like scsi controllers) we handle on a bus.
- */
-#define MAX_DEVICES_PER_PCIBUS	8
-
-/*
- * No locking needed until PCI initialization is done parallely.
- */
-int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS];
-int lastirq = BASE_PCI_IRQ;
-
-/*
- * Translate from irq to software PCI bus number and PCI slot.
- */
-int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-
-/*
- * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
- * not really documented, so right now I can't write code which uses it.
- * Therefore we use type 0 accesses for now even though they won't work
- * correcly for PCI-to-PCI bridges.
- */
-#define CF0_READ_PCI_CFG(dev,where,value,bm,mask)			\
-do {									\
-	bridge_t *bridge;                                               \
-	int slot = PCI_SLOT(dev->devfn);				\
-	int fn = PCI_FUNC(dev->devfn);					\
-	volatile u32 *addr;						\
-	u32 cf, __bit;							\
-	unsigned int bus_id = (unsigned) dev->bus->number;              \
-									\
-	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
-                                             bus_to_wid[bus_id]);       \
-                                                                        \
-	if (dev->vendor == PCI_VENDOR_ID_SGI				\
-	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
-	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) {	\
-		*value = 0;						\
-		return PCIBIOS_SUCCESSFUL;				\
-	}								\
-									\
-	__bit = (((where) & (bm)) << 3);				\
-	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
-	if (get_dbe(cf, addr))						\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-	*value = (cf >> __bit) & (mask);				\
-	return PCIBIOS_SUCCESSFUL;					\
-} while (0)
-
-static int
-pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,3,0xff);
-}
-
-static int
-pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,2,0xffff);
-}
-
-static int
-pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff);
-}
-
-#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask)			\
-do {									\
-	bridge_t *bridge;                                               \
-	int slot = PCI_SLOT(dev->devfn);				\
-	int fn = PCI_FUNC(dev->devfn);					\
-	volatile u32 *addr;						\
-	u32 cf, __bit;							\
-	unsigned int bus_id = (unsigned) dev->bus->number;              \
-									\
-	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
-                                             bus_to_wid[bus_id]);       \
-                                                                        \
-	if (dev->vendor == PCI_VENDOR_ID_SGI				\
-	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
-	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48)))	\
-		return PCIBIOS_SUCCESSFUL;				\
-									\
-	__bit = (((where) & (bm)) << 3);				\
-	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
-	if (get_dbe(cf, addr))						\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-	cf &= (~mask);							\
-	cf |= (value);							\
-	put_dbe(cf, addr);						\
-	return PCIBIOS_SUCCESSFUL;					\
-} while (0)
-
-static int
-pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,3,0xff);
-}
-
-static int
-pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff);
-}
-
-static int
-pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff);
-}
-
-
-static struct pci_ops bridge_pci_ops = {
-	pci_conf0_read_config_byte,
-	pci_conf0_read_config_word,
-	pci_conf0_read_config_dword,
-	pci_conf0_write_config_byte,
-	pci_conf0_write_config_word,
-	pci_conf0_write_config_dword
-};
-
-void __init pcibios_init(void)
-{
-	struct pci_ops *ops = &bridge_pci_ops;
-	int	i;
-
-	ioport_resource.end = ~0UL;
-	iomem_resource.end = ~0UL;
-
-	for (i=0; i<num_bridges; i++) {
-		printk("PCI: Probing PCI hardware on host bus %2d.\n", i);
-		pci_scan_bus(i, ops, NULL);
-	}
-}
-
-static inline u8
-bridge_swizzle(u8 pin, u8 slot) 
-{
-	return (((pin-1) + slot) % 4) + 1;
-}
-
-static u8 __init
-pci_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-	u8 pin = *pinp;
-
-	while (dev->bus->self) {	/* Move up the chain of bridges. */
-		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-		dev = dev->bus->self;
-	}
-	*pinp = pin;
-
-	return PCI_SLOT(dev->devfn);
-}
-
-/*
- * All observed requests have pin == 1. We could have a global here, that
- * gets incremented and returned every time - unfortunately, pci_map_irq
- * may be called on the same device over and over, and need to return the
- * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. 
- *
- * A given PCI device, in general, should be able to intr any of the cpus
- * on any one of the hubs connected to its xbow.
- */
-static int __init
-pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	if ((dev->bus->number >= MAX_PCI_BUSSES)
-	    || (pin != 1)
-	    || (slot >= MAX_DEVICES_PER_PCIBUS))
-		panic("Increase supported PCI busses %d,%d,%d",
-		      dev->bus->number, slot, pin);
-
-	/*
-	 * Already assigned? Then return previously assigned value ...
-	 */
-	if (irqstore[dev->bus->number][slot])
-		return irqstore[dev->bus->number][slot];
-
-	irq_to_bus[lastirq] = dev->bus->number;
-	irq_to_slot[lastirq] = slot;
-	irqstore[dev->bus->number][slot] = lastirq;
-	lastirq++;
-	return lastirq - 1;
-}
-
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-void __init
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-                        struct resource *res, int resource)
-{
-	unsigned long where, size;
-	u32 reg;
-
-	where = PCI_BASE_ADDRESS_0 + (resource * 4);
-	size = res->end - res->start;
-	pci_read_config_dword(dev, where, &reg);
-	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
-	pci_write_config_dword(dev, where, reg);
-}
-
-void __init
-pcibios_fixup_bus(struct pci_bus *b)
-{
-	pci_fixup_irqs(pci_swizzle, pci_map_irq);
-}
-
-void __init
-pcibios_fixup_pbus_ranges(struct pci_bus * bus,
-                          struct pbus_set_ranges_data * ranges)
-{
-	ranges->io_start  -= bus->resource[0]->start;
-	ranges->io_end    -= bus->resource[0]->start;
-	ranges->mem_start -= bus->resource[1]->start;
-	ranges->mem_end   -= bus->resource[1]->start;
-}
-
-int __init
-pcibios_enable_device(struct pci_dev *dev)
-{
-	/* Not needed, since we enable all devices at startup.  */
-	return 0;
-}
-
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 0;
-}
-
-char * __init
-pcibios_setup(char *str)
-{
-	/* Nothing to do for now.  */
-
-	return str;
-}
-
-/*
- * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
- * to find the slot number in sense of the bridge device register.
- * XXX This also means multiple devices might rely on conflicting bridge
- * settings.
- */
-
-static void __init
-pci_disable_swapping(struct pci_dev *dev)
-{
-	unsigned int bus_id = (unsigned) dev->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-	                                               bus_to_wid[bus_id]);
-	int		slot = PCI_SLOT(dev->devfn);
-
-	/* Turn off byte swapping */
-	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
-	bridge->b_widget.w_tflush;		/* Flush */
-}
-
-static void __init
-pci_enable_swapping(struct pci_dev *dev)
-{
-	unsigned int bus_id = (unsigned) dev->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-	                                               bus_to_wid[bus_id]);
-	int		slot = PCI_SLOT(dev->devfn);
-
-	/* Turn on byte swapping */
-	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
-	bridge->b_widget.w_tflush;		/* Flush */
-}
-
-static void __init
-pci_fixup_ioc3(struct pci_dev *d)
-{
-	unsigned long bus_id = (unsigned) d->bus->number;
-
-	printk("PCI: Fixing base addresses for IOC3 device %s\n", d->slot_name);
-
-	d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]);
-	d->resource[0].end   |= NODE_OFFSET(bus_to_nid[bus_id]);
-
-	pci_disable_swapping(d);
-}
-
-static void __init
-pci_fixup_isp1020(struct pci_dev *d)
-{
-	unsigned short command;
-
-	d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32);
-	printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name);
-
-	/*
-	 * Configure device to allow bus mastering, i/o and memory mapping. 
-	 * Older qlogicisp driver expects to have the IO space enable 
-	 * bit set. Things stop working if we program the controllers as not 
-	 * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
-	 */
-
-	pci_set_master(d);
-	pci_read_config_word(d, PCI_COMMAND, &command);
-	command |= PCI_COMMAND_MEMORY;
-	command |= PCI_COMMAND_IO;
-	pci_write_config_word(d, PCI_COMMAND, command);
-	d->resource[1].flags |= 1;
-
-	pci_enable_swapping(d);
-}
-
-static void __init
-pci_fixup_isp2x00(struct pci_dev *d)
-{
-	unsigned int bus_id = (unsigned) d->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-				     bus_to_wid[bus_id]);
-	bridgereg_t 	devreg;
-	int		i;
-	int		slot = PCI_SLOT(d->devfn);
-	unsigned int	start;
-	unsigned short command;
-
-	printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name);
-
-	/* set the resource struct for this device */
-	start = (u32) (u64)bridge;	/* yes, we want to lose the upper 32 bits here */
-	start |= BRIDGE_DEVIO(slot);
-
-	d->resource[0].start = start;
-	d->resource[0].end = d->resource[0].start + 0xff;
-	d->resource[0].flags = IORESOURCE_IO;
-
-	d->resource[1].start = start;
-	d->resource[1].end = d->resource[0].start + 0xfff;
-	d->resource[1].flags = IORESOURCE_MEM;
-
-	/*
-	 * set the bridge device(x) reg for this device
-	 */
-	devreg = bridge->b_device[slot].reg;
-	/* point device(x) to it appropriate small window */
-	devreg &= ~BRIDGE_DEV_OFF_MASK;
-	devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK;
-	bridge->b_device[slot].reg = devreg;
-
-	pci_enable_swapping(d);
-
-	/* set card's base addr reg */
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001);
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000);
-	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000);
-
-	/* I got these from booting irix on system...*/
-	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001);
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000);
-	pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS,   0x10200000);
-
-	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, start);
-	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000));
-
-	/* set cache line size */
-	pci_conf0_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080);
-
-	/* set pci bus timeout */
-	bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3);
-	bridge->b_wid_tflush;
-	printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout);
-
-	/* set host error field */
-	bridge->b_int_host_err = 0x44;
-	bridge->b_wid_tflush;
-
-	bridge->b_wid_tflush;   	/* wait until Bridge PIO complete */
-	for (i=0; i<8; i++)
-		printk("PCI: device(%d)= 0x%x\n",i,bridge->b_device[i].reg);
-
-	/* configure device to allow bus mastering, i/o and memory mapping */
-	pci_set_master(d);
-	pci_read_config_word(d, PCI_COMMAND, &command);
-	command |= PCI_COMMAND_MEMORY;
-	command |= PCI_COMMAND_IO;
-	pci_write_config_word(d, PCI_COMMAND, command);
-	/*d->resource[1].flags |= 1;*/
-}
-
-struct pci_fixup pcibios_fixups[] = {
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-	  pci_fixup_ioc3 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
-	  pci_fixup_isp1020 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
-	  pci_fixup_isp2x00 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
-	  pci_fixup_isp2x00 },
-	{ 0 }
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-reset.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-reset.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,80 +0,0 @@
-/*
- * 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.
- *
- * Reset an IP27.
- *
- * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/smp.h>
-#include <linux/mmzone.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <asm/sgialib.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-#include <asm/sn/sn0/hub.h>
-
-void machine_restart(char *command) __attribute__((noreturn));
-void machine_halt(void) __attribute__((noreturn));
-void machine_power_off(void) __attribute__((noreturn));
-
-#define noreturn while(1);				/* Silence gcc.  */
-
-/* XXX How to pass the reboot command to the firmware??? */
-static void ip27_machine_restart(char *command)
-{
-#if 0
-	int i;
-#endif
-
-	printk("Reboot started from CPU %d\n", smp_processor_id());
-#ifdef CONFIG_SMP
-	smp_send_stop();
-#endif
-#if 0
-	for (i = 0; i < numnodes; i++)
-		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, 
-							PROMOP_REBOOT);
-#else
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-#endif
-	noreturn;
-}
-
-static void ip27_machine_halt(void)
-{
-	int i;
-
-#ifdef CONFIG_SMP
-	smp_send_stop();
-#endif
-	for (i = 0; i < numnodes; i++)
-		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, 
-							PROMOP_RESTART);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-	noreturn;
-}
-
-static void ip27_machine_power_off(void)
-{
-	/* To do ...  */
-	noreturn;
-}
-
-void ip27_reboot_setup(void)
-{
-	_machine_restart = ip27_machine_restart;
-	_machine_halt = ip27_machine_halt;
-	_machine_power_off = ip27_machine_power_off;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-rtc.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-rtc.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,334 +0,0 @@
-/*
- *	Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
- *
- *	Real Time Clock interface for Linux	
- *
- *	TODO: Implement periodic interrupts.
- *
- *	Copyright (C) 2000 Silicon Graphics, Inc.
- *	Written by Ulf Carlsson (ulfc@engr.sgi.com)
- *
- *	Based on code written by Paul Gortmaker.
- *
- *	This driver allows use of the real time clock (built into
- *	nearly all computers) from user space. It exports the /dev/rtc
- *	interface supporting various ioctl() and also the /proc/rtc
- *	pseudo-file for status information.
- *
- *	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.
- *
- */
-
-#define RTC_VERSION		"1.09b"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/rtc.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
-
-#include <asm/m48t35.h>
-#include <asm/sn/ioc3.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-static int rtc_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg);
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-
-static void get_rtc_time(struct rtc_time *rtc_tm);
-
-/*
- *	Bits in rtc_status. (6 bits of room for future expansion)
- */
-
-#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
-#define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
-
-static unsigned char rtc_status;	/* bitmapped status byte.	*/
-static spinlock_t rtc_status_lock = SPIN_LOCK_UNLOCKED;
-static unsigned long rtc_freq;	/* Current periodic IRQ rate	*/
-static struct m48t35_rtc *rtc;
-
-/*
- *	If this driver ever becomes modularised, it will be really nice
- *	to make the epoch retain its value across module reload...
- */
-
-static unsigned long epoch = 1970;	/* year corresponding to 0x00	*/
-
-static const unsigned char days_in_mo[] = 
-{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		     unsigned long arg)
-{
-
-	struct rtc_time wtime; 
-
-	switch (cmd) {
-	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
-	{
-		get_rtc_time(&wtime);
-		break;
-	}
-	case RTC_SET_TIME:	/* Set the RTC */
-	{
-		struct rtc_time rtc_tm;
-		unsigned char mon, day, hrs, min, sec, leap_yr;
-		unsigned int yrs;
-		unsigned long flags;
-			
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
-
-		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
-				   sizeof(struct rtc_time)))
-			return -EFAULT;
-
-		yrs = rtc_tm.tm_year + 1900;
-		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
-		day = rtc_tm.tm_mday;
-		hrs = rtc_tm.tm_hour;
-		min = rtc_tm.tm_min;
-		sec = rtc_tm.tm_sec;
-
-		if (yrs < 1970)
-			return -EINVAL;
-
-		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
-		if ((mon > 12) || (day == 0))
-			return -EINVAL;
-
-		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-			return -EINVAL;
-			
-		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-			return -EINVAL;
-
-		if ((yrs -= epoch) > 255)    /* They are unsigned */
-			return -EINVAL;
-
-		save_flags(flags);
-		cli();
-		if (yrs > 169) {
-			restore_flags(flags);
-			return -EINVAL;
-		}
-		if (yrs >= 100)
-			yrs -= 100;
-
-		BIN_TO_BCD(sec);
-		BIN_TO_BCD(min);
-		BIN_TO_BCD(hrs);
-		BIN_TO_BCD(day);
-		BIN_TO_BCD(mon);
-		BIN_TO_BCD(yrs);
-
-		rtc->control &= ~M48T35_RTC_SET;
-		rtc->year = yrs;
-		rtc->month = mon;
-		rtc->date = day;
-		rtc->hour = hrs;
-		rtc->min = min;
-		rtc->sec = sec;
-		rtc->control &= ~M48T35_RTC_SET;
-
-		restore_flags(flags);
-		return 0;
-	}
-	default:
-		return -EINVAL;
-	}
-	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
-}
-
-/*
- *	We enforce only one user at a time here with the open/close.
- *	Also clear the previous interrupt data on an open, and clean
- *	up things on a close.
- */
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-	spin_lock(rtc_status_lock);
-
-	if (rtc_status & RTC_IS_OPEN) {
-		spin_unlock(rtc_status_lock);
-		return -EBUSY;
-	}
-
-	rtc_status |= RTC_IS_OPEN;
-	spin_unlock(rtc_status_lock);
-
-	return 0;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-	/*
-	 * Turn off all interrupts once the device is no longer
-	 * in use, and clear the data.
-	 */
-
-	spin_lock(rtc_status_lock);
-	rtc_status &= ~RTC_IS_OPEN;
-	spin_unlock(rtc_status_lock);
-
-	return 0;
-}
-
-/*
- *	The various file operations we support.
- */
-
-static struct file_operations rtc_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
-};
-
-static struct miscdevice rtc_dev=
-{
-	RTC_MINOR,
-	"rtc",
-	&rtc_fops
-};
-
-static int __init rtc_init(void)
-{
-	unsigned long flags;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)
-	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
-
-	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
-	if (misc_register(&rtc_dev))
-		return -ENODEV;
-	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
-
-	save_flags(flags);
-	cli();
-	restore_flags(flags);
-	rtc_freq = 1024;
-	return 0;
-}
-
-static void __exit rtc_exit (void)
-{
-	/* interrupts and timer disabled at this point by rtc_release */
-
-	remove_proc_entry ("rtc", NULL);
-	misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_init);
-module_exit(rtc_exit);
-EXPORT_NO_SYMBOLS;
-
-/*
- *	Info exported via "/proc/rtc".
- */
-
-static int rtc_get_status(char *buf)
-{
-	char *p;
-	struct rtc_time tm;
-
-	/*
-	 * Just emulate the standard /proc/rtc
-	 */
-
-	p = buf;
-
-	get_rtc_time(&tm);
-
-	/*
-	 * There is no way to tell if the luser has the RTC set for local
-	 * time or for Universal Standard Time (GMT). Probably local though.
-	 */
-	p += sprintf(p,
-		     "rtc_time\t: %02d:%02d:%02d\n"
-		     "rtc_date\t: %04d-%02d-%02d\n"
-	 	     "rtc_epoch\t: %04lu\n"
-		     "24hr\t\t: yes\n",
-		     tm.tm_hour, tm.tm_min, tm.tm_sec,
-		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-
-	return  p - buf;
-}
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
-{
-        int len = rtc_get_status(page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-static void get_rtc_time(struct rtc_time *rtc_tm)
-{
-
-	unsigned long flags;
-
-	/*
-	 * Do we need to wait for the last update to finish?
-	 */
-
-	/*
-	 * Only the values that we read from the RTC are set. We leave
-	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
-	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
-	 * by the RTC when initially set to a non-zero value.
-	 */
-	save_flags(flags);
-	cli();
-        rtc->control |= M48T35_RTC_READ;
-	rtc_tm->tm_sec = rtc->sec;
-	rtc_tm->tm_min = rtc->min;
-	rtc_tm->tm_hour = rtc->hour;
-	rtc_tm->tm_mday = rtc->date;
-	rtc_tm->tm_mon = rtc->month;
-	rtc_tm->tm_year = rtc->year;
-	rtc->control &= ~M48T35_RTC_READ;
-	restore_flags(flags);
-
-	BCD_TO_BIN(rtc_tm->tm_sec);
-	BCD_TO_BIN(rtc_tm->tm_min);
-	BCD_TO_BIN(rtc_tm->tm_hour);
-	BCD_TO_BIN(rtc_tm->tm_mday);
-	BCD_TO_BIN(rtc_tm->tm_mon);
-	BCD_TO_BIN(rtc_tm->tm_year);
-
-	/*
-	 * Account for differences between how the RTC uses the values
-	 * and how they are defined in a struct rtc_time;
-	 */
-	if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
-		rtc_tm->tm_year += 100;
-
-	rtc_tm->tm_mon--;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-setup.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-setup.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,314 +0,0 @@
-/*
- * 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.
- *
- * SGI IP27 specific setup.
- *
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-
-#include <asm/io.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/sn0/hubio.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/time.h>
-#include <asm/mipsregs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_private.h>
-#include <asm/pci/bridge.h>
-#include <asm/paccess.h>
-#include <asm/sn/sn0/ip27.h>
-
-/* Check against user dumbness.  */
-#ifdef CONFIG_VT
-#error CONFIG_VT not allowed for IP27.
-#endif
-
-#undef DEBUG_SETUP
-#ifdef DEBUG_SETUP
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/*
- * get_nasid() returns the physical node id number of the caller.
- */
-nasid_t
-get_nasid(void)
-{
-	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
-	                 >> NSRI_NODEID_SHFT);
-}
-
-/* Extracted from the IOC3 meta driver.  FIXME.  */
-static inline void ioc3_sio_init(void)
-{
-	struct ioc3 *ioc3;
-	nasid_t nid;
-        long loops;
-
-	nid = get_nasid();
-	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
-
-	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
-	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
-	ioc3->sio_iec = ~0;
-	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
-
-	loops=1000000; while(loops--);
-	ioc3->sregs.uarta.iu_fcr = 0;
-	ioc3->sregs.uartb.iu_fcr = 0;
-	loops=1000000; while(loops--);
-}
-
-static inline void ioc3_eth_init(void)
-{
-	struct ioc3 *ioc3;
-	nasid_t nid;
-
-	nid = get_nasid();
-	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
-
-	ioc3->eier = 0;
-}
-
-/* Try to catch kernel missconfigurations and give user an indication what
-   option to select.  */
-static void __init verify_mode(void)
-{
-	int n_mode;
-
-	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
-	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
-#ifdef CONFIG_SGI_SN0_N_MODE
-	if (!n_mode)
-		panic("Kernel compiled for M mode.");
-#else
-	if (n_mode)
-		panic("Kernel compiled for N mode.");
-#endif
-}
-
-#define XBOW_WIDGET_PART_NUM    0x0
-#define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */
-#define BASE_XBOW_PORT  	8     /* Lowest external port */
-
-unsigned int bus_to_cpu[256];
-unsigned long bus_to_baddr[256];
-
-void __init pcibr_setup(cnodeid_t nid)
-{
-	int 			i, start, num;
-	unsigned long		masterwid;
-	bridge_t 		*bridge; 
-	volatile u64 		hubreg;
-	nasid_t	 		nasid, masternasid;
-	xwidget_part_num_t	partnum;
-	widgetreg_t 		widget_id;
-	static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
-
-	/*
-	 * If the master is doing this for headless node, nothing to do.
-	 * This is because currently we require at least one of the hubs
-	 * (master hub) connected to the xbow to have at least one enabled 
-	 * cpu to receive intrs. Else we need an array bus_to_intrnasid[] 
-	 * that bridge_startup() needs to use to target intrs. All dma is
-	 * routed thru the widget of the master hub. The master hub wid
-	 * is selectable by WIDGET_A below.
-	 */
-	if (nid != get_compact_nodeid())
-		return;
-	/*
-	 * find what's on our local node
-	 */
-	spin_lock(&pcibr_setup_lock);
-	start = num_bridges;		/* Remember where we start from */
-	nasid = COMPACT_TO_NASID_NODEID(nid);
-	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	if (hubreg & IIO_LLP_CSR_IS_UP) {
-		/* link is up */
-		widget_id = *(volatile widgetreg_t *)
-                        (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-		partnum = XWIDGET_PART_NUM(widget_id);
-		printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
-					smp_processor_id(), nasid, partnum);
-		if (partnum == BRIDGE_WIDGET_PART_NUM) {
-			/*
-			 * found direct connected bridge so must be Origin200
-			 */
-			printk("...is bridge\n");
-			num_bridges = 1;
-        		bus_to_wid[0] = 0x8;
-			bus_to_nid[0] = 0;
-			masterwid = 0xa;
-			bus_to_baddr[0] = 0xa100000000000000UL;
-		} else if (partnum == XBOW_WIDGET_PART_NUM) {
-			lboard_t *brd;
-			klxbow_t *xbow_p;
-			/*
-			 * found xbow, so may have multiple bridges
-			 * need to probe xbow
-			 */
-			printk("...is xbow\n");
-
-			if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
-                                   KLTYPE_MIDPLANE8)) == NULL)
-				printk("argh\n");
-			else
-				printk("brd = 0x%lx\n", (unsigned long) brd);
-			if ((xbow_p = (klxbow_t *)
-			     find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
-				printk("argh\n");
-			else {
-			   /*
-			    * Okay, here's a xbow. Lets arbitrate and find
-			    * out if we should initialize it. Set enabled 
-			    * hub connected at highest or lowest widget as 
-			    * master.
-			    */
-#ifdef WIDGET_A
-			   i = HUB_WIDGET_ID_MAX + 1;
-			   do {
-				i--;
-			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
-					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
-#else
-			   i = HUB_WIDGET_ID_MIN - 1;
-			   do {
-				i++;
-			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
-					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
-#endif
-			   masterwid = i;
-			   masternasid = XBOW_PORT_NASID(xbow_p, i);
-			   if (nasid == masternasid)
-			   for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
-				if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
-					continue;
-				if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
-				   widget_id = *(volatile widgetreg_t *)
-                        		   (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
-				   partnum = XWIDGET_PART_NUM(widget_id);
-				   if (partnum == BRIDGE_WIDGET_PART_NUM) {
-					printk("widget 0x%x is a bridge\n", i);
-					bus_to_wid[num_bridges] = i;
-					bus_to_nid[num_bridges] = nasid;
-					bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */
-					num_bridges++;
-				   }
-				}
-			   }
-			}
-		} else if (partnum == XXBOW_WIDGET_PART_NUM) {
-			/*
-			 * found xbridge, assume ibrick for now 
-			 */
-			printk("...is xbridge\n");
-        		bus_to_wid[0] = 0xb;
-        		bus_to_wid[1] = 0xe;
-        		bus_to_wid[2] = 0xf;
-
-        		bus_to_nid[0] = 0;
-        		bus_to_nid[1] = 0;
-        		bus_to_nid[2] = 0;
-
-			bus_to_baddr[0] = 0xa100000000000000UL;
-			bus_to_baddr[1] = 0xa100000000000000UL;
-			bus_to_baddr[2] = 0xa100000000000000UL;
-			masterwid = 0xa;
-			num_bridges = 3;
-		}
-	}
-	num = num_bridges - start;
-	spin_unlock(&pcibr_setup_lock);
-	/*
-         * set bridge registers
-         */
-	for (i = start; i < (start + num); i++) {
-
-		DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",
-                        i, i, bus_to_wid[i], i, bus_to_nid[i]);
-
-		bus_to_cpu[i] = smp_processor_id();
-		/*
-		 * point to this bridge
-		 */
-		bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
-		/*
-	 	 * Clear all pending interrupts.
-	 	 */
-		bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-		/*
-	 	 * Until otherwise set up, assume all interrupts are from slot 0
-	 	 */
-		bridge->b_int_device = (u32) 0x0;
-		/*
-	 	 * swap pio's to pci mem and io space (big windows)
-	 	 */
-		bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
-		bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
-
-		/*
-		 * Hmm...  IRIX sets additional bits in the address which 
-		 * are documented as reserved in the bridge docs.
-		 */
-		bridge->b_int_mode = 0x0;		/* Don't clear ints */
-		bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
-		bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
-		bridge->b_dir_map = (masterwid << 20);	/* DMA */
-		bridge->b_int_enable = 0;
-
-		bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
-	}
-}
-
-extern void ip27_setup_console(void);
-extern void ip27_time_init(void);
-
-void __init ip27_setup(void)
-{
-	nasid_t nid;
-	hubreg_t p, e;
-
-	ip27_setup_console();
-
-	num_bridges = 0;
-	/*
-	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
-	 */
-	DBG("ip27_setup(): Entered.\n");
-	nid = get_nasid();
-	printk("IP27: Running on node %d.\n", nid);
-
-	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
-	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
-	printk("Node %d has %s primary CPU%s.\n", nid,
-	       p ? "a" : "no",
-	       e ? ", CPU is running" : "");
-
-	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
-	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
-	printk("Node %d has %s secondary CPU%s.\n", nid,
-	       p ? "a" : "no",
-	       e ? ", CPU is running" : "");
-
-	verify_mode();
-	ioc3_sio_init();
-	ioc3_eth_init();
-	per_cpu_init();
-
-	mips_io_port_base = IO_BASE;
-	board_time_init = ip27_time_init;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip27/ip27-timer.c linux-2.4.20/arch/mips64/sgi-ip27/ip27-timer.c
--- linux-2.4.19/arch/mips64/sgi-ip27/ip27-timer.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip27/ip27-timer.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,239 +0,0 @@
-/*
- * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/param.h>
-#include <linux/timex.h>
-#include <linux/mm.h>		
-
-#include <asm/time.h>
-#include <asm/pgtable.h>
-#include <asm/sgialib.h>
-#include <asm/sn/ioc3.h>
-#include <asm/m48t35.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-/*
- * This is a hack; we really need to figure these values out dynamically
- * 
- * Since 800 ns works very well with various HUB frequencies, such as
- * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
- *
- * Ralf: which clock rate is used to feed the counter?
- */
-#define NSEC_PER_CYCLE		800
-#define NSEC_PER_SEC		1000000000
-#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
-
-static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
-static long last_rtc_update;		/* Last time the rtc clock got updated */
-
-extern rwlock_t xtime_lock;
-extern volatile unsigned long wall_jiffies;
-
-
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	struct m48t35_rtc *rtc;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + 
-							IOC3_BYTEBUS_DEV0);
-
-	rtc->control |= M48T35_RTC_READ;
-	cmos_minutes = rtc->min;
-	BCD_TO_BIN(cmos_minutes);
-	rtc->control &= ~M48T35_RTC_READ;
-
-	/*
-	 * 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) {
-		BIN_TO_BCD(real_seconds);
-		BIN_TO_BCD(real_minutes);
-		rtc->control |= M48T35_RTC_SET;
-		rtc->sec = real_seconds;
-		rtc->min = real_minutes;
-		rtc->control &= ~M48T35_RTC_SET;
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	return retval;
-}
-
-void rt_timer_interrupt(struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int cpuA = ((cputoslice(cpu)) == 0);
-	int irq = 9;				/* XXX Assign number */
-
-	irq_enter(cpu, irq);
-	write_lock(&xtime_lock);
-
-again:
-	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
-	ct_cur[cpu] += CYCLES_PER_JIFFY;
-	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
-
-	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
-		goto again;
-
-	kstat.irqs[cpu][irq]++;		/* kstat only for bootcpu? */
-
-	if (cpu == 0)
-		do_timer(regs);
-
-#ifdef CONFIG_SMP
-	update_process_times(user_mode(regs));
-#endif /* CONFIG_SMP */
-	
-	/*
-	 * If we have an externally synchronized Linux clock, then update
-	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-	 * called as close as possible to when a second starts.
-	 */
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660) {
-		if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
-			if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else    
-				last_rtc_update = xtime.tv_sec - 600;
-		} else if (xtime.tv_usec <= ((unsigned) tick) / 2) {
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else    
-				last_rtc_update = xtime.tv_sec - 600;
-		}
-        }
-
-	write_unlock(&xtime_lock);
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
-}
-
-unsigned long ip27_do_gettimeoffset(void)
-{
-	unsigned long ct_cur1;
-	ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
-	return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
-}
-
-/* Includes for ioc3_init().  */
-#include <asm/sn/types.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/sn0/hubio.h>
-#include <asm/pci/bridge.h>
-
-static __init unsigned long get_m48t35_time(void)
-{
-        unsigned int year, month, date, hour, min, sec;
-	struct m48t35_rtc *rtc;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + 
-							IOC3_BYTEBUS_DEV0);
-
-	rtc->control |= M48T35_RTC_READ;
-	sec = rtc->sec;
-	min = rtc->min;
-	hour = rtc->hour;
-	date = rtc->date;
-	month = rtc->month;
-	year = rtc->year;
-	rtc->control &= ~M48T35_RTC_READ;
-
-        BCD_TO_BIN(sec);
-        BCD_TO_BIN(min);
-        BCD_TO_BIN(hour);
-        BCD_TO_BIN(date);
-        BCD_TO_BIN(month);
-        BCD_TO_BIN(year);
-
-        year += 1970;
-
-        return mktime(year, month, date, hour, min, sec);
-}
-
-void __init ip27_time_init(void)
-{
-	xtime.tv_sec = get_m48t35_time();
-	xtime.tv_usec = 0;
-
-	do_gettimeoffset = ip27_do_gettimeoffset;
-}
-
-void __init cpu_time_init(void)
-{
-	lboard_t *board;
-	klcpu_t *cpu;
-	int cpuid;
-
-	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
-	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
-	if (!board)
-		panic("Can't find board info for myself.");
-
-	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
-	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
-	if (!cpu)
-		panic("No information about myself?");
-
-	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
-
-	set_cp0_status(SRB_TIMOCLK);
-}
-
-void __init hub_rtc_init(cnodeid_t cnode)
-{
-	/*
-	 * We only need to initialize the current node.
-	 * If this is not the current node then it is a cpuless
-	 * node and timeouts will not happen there.
-	 */
-	if (get_compact_nodeid() == cnode) {
-		int cpu = smp_processor_id();
-		LOCAL_HUB_S(PI_RT_EN_A, 1);
-		LOCAL_HUB_S(PI_RT_EN_B, 1);
-		LOCAL_HUB_S(PI_PROF_EN_A, 0);
-		LOCAL_HUB_S(PI_PROF_EN_B, 0);
-		ct_cur[cpu] = CYCLES_PER_JIFFY;
-		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
-		LOCAL_HUB_S(PI_RT_COUNT, 0);
-		LOCAL_HUB_S(PI_RT_PEND_A, 0);
-		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
-		LOCAL_HUB_S(PI_RT_COUNT, 0);
-		LOCAL_HUB_S(PI_RT_PEND_B, 0);
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/Makefile linux-2.4.20/arch/mips64/sgi-ip32/Makefile
--- linux-2.4.19/arch/mips64/sgi-ip32/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-#
-# Makefile for the SGI specific kernel interface routines
-# under Linux.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-USE_STANDARD_AS_RULE := true
-
-O_TARGET := ip32-kern.a
-
-all: ip32-kern.a ip32-irq-glue.o
-
-obj-y	+= ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \
-	   ip32-timer.o crime.o ip32-reset.o
-
-obj-$(CONFIG_PCI)   += ip32-pci.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/crime.c linux-2.4.20/arch/mips64/sgi-ip32/crime.c
--- linux-2.4.19/arch/mips64/sgi-ip32/crime.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/crime.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,49 +0,0 @@
-/*
- * 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) 2001 Keith M Wesolowski
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/ip32/crime.h>
-#include <asm/ptrace.h>
-
-void __init crime_init (void)
-{
-	u64 id = crime_read_64 (CRIME_ID);
-	u64 rev = id & CRIME_ID_REV;
-
-	id = (id & CRIME_ID_IDBITS) >> 4;
-
-	printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev,
-		(unsigned long) CRIME_BASE);
-}
-
-/* XXX Like on Sun, these give us various useful information to printk. */
-void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
-{
-	u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
-	u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
-	memerr &= CRIME_MEM_ERROR_STAT_MASK;
-	
-	printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
-		addr << 2, memerr);
-
-	crime_write_64 (CRIME_MEM_ERROR_STAT, 0);
-}
-
-void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
-{
-	u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT);
-	u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR);
-	cpuerr &= CRIME_CPU_ERROR_MASK;
-	addr <<= 2UL;
-
-	printk ("CRIME CPU interface error detected at %09lx status %08lx\n",
-		addr, cpuerr);
-
-	crime_write_64 (CRIME_CPU_ERROR_STAT, 0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-berr.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-berr.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-berr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-berr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/*
- * 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) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics
- * Copyright (C) 2002  Maciej W. Rozycki
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/traps.h>
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/ptrace.h>
-
-int
-be_ip32_handler(struct pt_regs *regs, int is_fixup)
-{
-	int data = regs->cp0_cause & 4;
-
-	if (is_fixup)
-		return MIPS_BE_FIXUP;
-
-	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_all();
-	while(1);
-	force_sig(SIGBUS, current);
-}
-
-void __init
-bus_error_init(void)
-{
-	be_board_handler = be_ip27_handler;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq-glue.S linux-2.4.20/arch/mips64/sgi-ip32/ip32-irq-glue.S
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq-glue.S	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-irq-glue.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,87 +0,0 @@
-/*
- * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
- *
- * 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) 2000 Harald Koerfgen
- * Copyright (C) 2001 Keith M Wesolowski
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/stackframe.h>
-#include <asm/addrspace.h>
-#include <asm/ip32/ip32_ints.h>
-
-		.text
-		.set    noreorder
-		.set    noat
-		.align  5
-		NESTED(ip32_handle_int, PT_SIZE, ra)
-		.set    noat
-		SAVE_ALL
-		CLI			# TEST: interrupts should be off
-		.set    at
-		.set    noreorder
-
-		mfc0	s0,CP0_CAUSE
-
-		andi	t1, s0, IE_IRQ0
-		bnez	t1, handle_irq0
-		 andi	t1, s0, IE_IRQ1
-		bnez	t1, handle_irq1
-		 andi	t1, s0, IE_IRQ2
-		bnez	t1, handle_irq2
-		 andi	t1, s0, IE_IRQ3
-		bnez	t1, handle_irq3
-		 andi	t1, s0, IE_IRQ4
-		bnez	t1, handle_irq4
-		 andi	t1, s0, IE_IRQ5
-		bnez	t1, handle_irq5
-		 nop
-
-		/* Either someone has triggered the "software interrupts"
-		 * or we lost an interrupt somehow.  Ignore it.
-		 */
-		j	ret_from_irq
-		 nop
-
-handle_irq0:
-		jal	ip32_irq0
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq1:
-		jal	ip32_irq1
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq2:
-		jal	ip32_irq2
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq3:
-		jal	ip32_irq3
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq4:
-		jal	ip32_irq4
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq5:
-		jal	ip32_irq5
-		move	a0, sp
-		j	ret_from_irq
-		 nop
-
-		END(ip32_handle_int)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-irq.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,571 +0,0 @@
-/*
- * Code to handle IP32 IRQs
- *
- * 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) 2000 Harald Koerfgen
- * Copyright (C) 2001 Keith M Wesolowski
- */
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/random.h>
-#include <linux/sched.h>
-
-#include <asm/bitops.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/ip32/ip32_ints.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/mace.h>
-#include <asm/signal.h>
-
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* O2 irq map
- *
- * IP0 -> software (ignored)
- * IP1 -> software (ignored)
- * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
- * IP3 -> (irq1) X unknown
- * IP4 -> (irq2) X unknown
- * IP5 -> (irq3) X unknown
- * IP6 -> (irq4) X unknown
- * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
- *
- * crime: (C)
- *
- * CRIME_INT_STAT 31:0:
- *
- * 0 -> 1 Video in 1
- * 1 -> 2 Video in 2
- * 2 -> 3 Video out
- * 3 -> 4 Mace ethernet
- * 4 -> S  SuperIO sub-interrupt
- * 5 -> M  Miscellaneous sub-interrupt
- * 6 -> A  Audio sub-interrupt
- * 7 -> 8  PCI bridge errors
- * 8 -> 9  PCI SCSI aic7xxx 0
- * 9 -> 10  PCI SCSI aic7xxx 1
- * 10 -> 11 PCI slot 0
- * 11 -> 12 unused (PCI slot 1)
- * 12 -> 13 unused (PCI slot 2)
- * 13 -> 14 unused (PCI shared 0)
- * 14 -> 15 unused (PCI shared 1)
- * 15 -> 16 unused (PCI shared 2)
- * 16 -> 17 GBE0 (E)
- * 17 -> 18 GBE1 (E)
- * 18 -> 19 GBE2 (E)
- * 19 -> 20 GBE3 (E)
- * 20 -> 21 CPU errors
- * 21 -> 22 Memory errors
- * 22 -> 23 RE empty edge (E)
- * 23 -> 24 RE full edge (E)
- * 24 -> 25 RE idle edge (E)
- * 25 -> 26 RE empty level
- * 26 -> 27 RE full level
- * 27 -> 28 RE idle level
- * 28 -> 29  unused (software 0) (E)
- * 29 -> 30  unused (software 1) (E)
- * 30 -> 31  unused (software 2) - crime 1.5 CPU SysCorError (E)
- * 31 -> 32 VICE
- *
- * S, M, A: Use the MACE ISA interrupt register
- * MACE_ISA_INT_STAT 31:0
- *
- * 0-7 -> 33-40 Audio
- * 8 -> 41 RTC
- * 9 -> 42 Keyboard
- * 10 -> X Keyboard polled
- * 11 -> 44 Mouse
- * 12 -> X Mouse polled
- * 13-15 -> 46-48 Count/compare timers
- * 16-19 -> 49-52 Parallel (16 E)
- * 20-25 -> 53-58 Serial 1 (22 E)
- * 26-31 -> 59-64 Serial 2 (28 E)
- *
- * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
- * different IRQ map than IRIX uses, but that's OK as Linux irq handling
- * is quite different anyway.
- */
-
-/* Some initial interrupts to set up */
-extern void crime_memerr_intr (unsigned int irq, void *dev_id,
-			       struct pt_regs *regs);
-extern void crime_cpuerr_intr (unsigned int irq, void *dev_id,
-			       struct pt_regs *regs);
-
-struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
-			       0, "CRIME memory error", NULL,
-			       NULL };
-struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
-			       0, "CRIME CPU error", NULL,
-			       NULL };
-
-extern void ip32_handle_int (void);
-asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
-
-/*
- * For interrupts wired from a single device to the CPU.  Only the clock
- * uses this it seems, which is IRQ 0 and IP7.
- */
-
-static void enable_cpu_irq(unsigned int irq)
-{
-	set_cp0_status(STATUSF_IP7);
-}
-
-static unsigned int startup_cpu_irq(unsigned int irq)
-{
-	enable_cpu_irq(irq);
-	return 0;
-}
-
-static void disable_cpu_irq(unsigned int irq)
-{
-	clear_cp0_status(STATUSF_IP7);
-}
-
-static void end_cpu_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_cpu_irq (irq);
-}
-
-#define shutdown_cpu_irq disable_cpu_irq
-#define mask_and_ack_cpu_irq disable_cpu_irq
-
-static struct hw_interrupt_type ip32_cpu_interrupt = {
-	"IP32 CPU",
-	startup_cpu_irq,
-	shutdown_cpu_irq,
-	enable_cpu_irq,
-	disable_cpu_irq,
-	mask_and_ack_cpu_irq,
-	end_cpu_irq,
-	NULL
-};
-
-/*
- * This is for pure CRIME interrupts - ie not MACE.  The advantage?
- * We get to split the register in half and do faster lookups.
- */
-
-static void enable_crime_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	crime_mask = crime_read_64(CRIME_INT_MASK);
-	crime_mask |= 1 << (irq - 1);
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_crime_irq(unsigned int irq)
-{
-	enable_crime_irq(irq);
-	return 0; /* This is probably not right; we could have pending irqs */
-}
-
-static void disable_crime_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	crime_mask = crime_read_64(CRIME_INT_MASK);
-	crime_mask &= ~(1 << (irq - 1));
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static void mask_and_ack_crime_irq (unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	/* Edge triggered interrupts must be cleared. */
-	if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ)
-	    || (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ)
-	    || (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) {
-		save_and_cli(flags);
-		crime_mask = crime_read_64(CRIME_HARD_INT);
-		crime_mask &= ~(1 << (irq - 1));
-		crime_write_64(CRIME_HARD_INT, crime_mask);
-		restore_flags(flags);
-	}
-	disable_crime_irq(irq);
-}
-
-static void end_crime_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_crime_irq (irq);
-}
-
-#define shutdown_crime_irq disable_crime_irq
-
-static struct hw_interrupt_type ip32_crime_interrupt = {
-	"IP32 CRIME",
-	startup_crime_irq,
-	shutdown_crime_irq,
-	enable_crime_irq,
-	disable_crime_irq,
-	mask_and_ack_crime_irq,
-	end_crime_irq,
-	NULL
-};
-
-/*
- * This is for MACE PCI interrupts.  We can decrease bus traffic by masking
- * as close to the source as possible.  This also means we can take the
- * next chunk of the CRIME register in one piece.
- */
-
-static void enable_macepci_irq(unsigned int irq)
-{
-	u32 mace_mask;
-	u64 crime_mask;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mace_mask = mace_read_32(MACEPCI_CONTROL);
-	mace_mask |= MACEPCI_CONTROL_INT(irq - 9);
-	mace_write_32(MACEPCI_CONTROL, mace_mask);
-	/*
-	 * In case the CRIME interrupt isn't enabled, we must enable it;
-	 * however, we never disable interrupts at that level.
-	 */
-	crime_mask = crime_read_64(CRIME_INT_MASK);
-	crime_mask |= 1 << (irq - 1);
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_macepci_irq(unsigned int irq)
-{
-	enable_macepci_irq (irq);
-
-	return 0; /* XXX */
-}
-
-static void disable_macepci_irq(unsigned int irq)
-{
-	u32 mace_mask;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mace_mask = mace_read_32(MACEPCI_CONTROL);
-	mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
-	mace_write_32(MACEPCI_CONTROL, mace_mask);
-	restore_flags(flags);
-}
-
-static void end_macepci_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_macepci_irq (irq);
-}
-
-#define shutdown_macepci_irq disable_macepci_irq
-#define mask_and_ack_macepci_irq disable_macepci_irq
-
-static struct hw_interrupt_type ip32_macepci_interrupt = {
-	"IP32 MACE PCI",
-	startup_macepci_irq,
-	shutdown_macepci_irq,
-	enable_macepci_irq,
-	disable_macepci_irq,
-	mask_and_ack_macepci_irq,
-	end_macepci_irq,
-	NULL
-};
-
-/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
- * CRIME register.
- */
-
-static void enable_maceisa_irq (unsigned int irq)
-{
-	u64 crime_mask;
-	u32 mace_mask;
-	unsigned int crime_int = 0;
-	unsigned long flags;
-
-	DBG ("maceisa enable: %u\n", irq);
-	
-	switch (irq) {
-	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
-		crime_int = MACE_AUDIO_INT;
-		break;
-	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
-		crime_int = MACE_MISC_INT;
-		break;
-	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
-		crime_int = MACE_SUPERIO_INT;
-		break;
-	}
-	DBG ("crime_int %016lx enabled\n", crime_int);
-	save_and_cli(flags);
-	crime_mask = crime_read_64(CRIME_INT_MASK);
-	crime_mask |= crime_int;
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	mace_mask = mace_read_32(MACEISA_INT_MASK);
-	mace_mask |= 1 << (irq - 33);
-	mace_write_32(MACEISA_INT_MASK, mace_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_maceisa_irq (unsigned int irq)
-{
-	enable_maceisa_irq(irq);
-	return 0;
-}
-
-static void disable_maceisa_irq(unsigned int irq)
-{
-	u32 mace_mask;
-	unsigned long flags;
-
-	save_and_cli (flags);
-	mace_mask = mace_read_32(MACEISA_INT_MASK);
-	mace_mask &= ~(1 << (irq - 33));
-	mace_write_32(MACEISA_INT_MASK, mace_mask);
-	restore_flags(flags);
-}
-
-static void mask_and_ack_maceisa_irq(unsigned int irq)
-{
-	u32 mace_mask;
-	unsigned long flags;
-
-	switch (irq) {
-	case MACEISA_PARALLEL_IRQ:
-	case MACEISA_SERIAL1_TDMAPR_IRQ:
-	case MACEISA_SERIAL2_TDMAPR_IRQ:
-		save_and_cli(flags);
-		mace_mask = mace_read_32(MACEISA_INT_STAT);
-		mace_mask &= ~(1 << (irq - 33));
-		mace_write_32(MACEISA_INT_STAT, mace_mask);
-		restore_flags(flags);
-		break;
-	}
-	disable_maceisa_irq(irq);
-}
-
-static void end_maceisa_irq(unsigned irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_maceisa_irq (irq);
-}
-
-#define shutdown_maceisa_irq disable_maceisa_irq
-
-static struct hw_interrupt_type ip32_maceisa_interrupt = {
-	"IP32 MACE ISA",
-	startup_maceisa_irq,
-	shutdown_maceisa_irq,
-	enable_maceisa_irq,
-	disable_maceisa_irq,
-	mask_and_ack_maceisa_irq,
-	end_maceisa_irq,
-	NULL
-};
-
-/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
- * bits 0-3 and 7 in the CRIME register.
- */
-
-static void enable_mace_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	save_and_cli (flags);
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
-	crime_mask |= 1 << (irq - 1);
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags (flags);
-}
-
-static unsigned int startup_mace_irq(unsigned int irq)
-{
-	enable_mace_irq(irq);
-	return 0;
-}
-
-static void disable_mace_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	save_and_cli (flags);
-	crime_mask = crime_read_64 (CRIME_INT_MASK);
-	crime_mask &= ~(1 << (irq - 1));
-	crime_write_64 (CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static void end_mace_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_mace_irq (irq);
-}
-
-#define shutdown_mace_irq disable_mace_irq
-#define mask_and_ack_mace_irq disable_mace_irq
-
-static struct hw_interrupt_type ip32_mace_interrupt = {
-	"IP32 MACE",
-	startup_mace_irq,
-	shutdown_mace_irq,
-	enable_mace_irq,
-	disable_mace_irq,
-	mask_and_ack_mace_irq,
-	end_mace_irq,
-	NULL
-};
-
-static void ip32_unknown_interrupt (struct pt_regs *regs)
-{
-	u64 crime;
-	u32 mace;
-	
-	printk ("Unknown interrupt occurred!\n");
-	printk ("cp0_status: %08x\tcp0_cause: %08x\n",
-		read_32bit_cp0_register (CP0_STATUS),
-		read_32bit_cp0_register (CP0_CAUSE));
-	crime = crime_read_64 (CRIME_INT_MASK);
-	printk ("CRIME interrupt mask: %016lx\n", crime);
-	crime = crime_read_64 (CRIME_INT_STAT);
-	printk ("CRIME interrupt status: %016lx\n", crime);
-	crime = crime_read_64 (CRIME_HARD_INT);
-	printk ("CRIME hardware interrupt register: %016lx\n", crime);
-	mace = mace_read_32 (MACEISA_INT_MASK);
-	printk ("MACE ISA interrupt mask: %08x\n", mace);
-	mace = mace_read_32 (MACEISA_INT_STAT);
-	printk ("MACE ISA interrupt status: %08x\n", mace);
-	mace = mace_read_32 (MACEPCI_CONTROL);
-	printk ("MACE PCI control register: %08x\n", mace);
-
-	printk("Register dump:\n");
-	show_regs(regs);
-
-	printk("Please mail this report to linux-mips@oss.sgi.com\n");
-	printk("Spinning...");
-	while(1) ;
-}
-
-/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
-void ip32_irq0(struct pt_regs *regs)
-{
-	u64 crime_int = crime_read_64 (CRIME_INT_STAT);
-	int irq = 0;
-	
-	if (crime_int & CRIME_MACE_INT_MASK) {
-		crime_int &= CRIME_MACE_INT_MASK;
-		irq = ffs (crime_int);
-	} else if (crime_int & CRIME_MACEISA_INT_MASK) {
-		u32 mace_int;
-		mace_int = mace_read_32 (MACEISA_INT_STAT);
-		if (mace_int == 0)
-			irq = 0;
-		else
-			irq = ffs (mace_int) + 32;
-	} else if (crime_int & CRIME_MACEPCI_INT_MASK) {
-		crime_int &= CRIME_MACEPCI_INT_MASK;
-		crime_int >>= 8;
-		irq = ffs (crime_int) + 8;
-	} else if (crime_int & 0xffff0000) {
-		crime_int >>= 16;
-		irq = ffs (crime_int) + 16;
-	}
-	if (irq == 0)
-		ip32_unknown_interrupt(regs);
-	DBG("*irq %u*\n", irq);
-	do_IRQ(irq, regs);
-}
-
-void ip32_irq1(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq2(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq3(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq4(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq5(struct pt_regs *regs)
-{
-	do_IRQ (CLOCK_IRQ, regs);
-}
-
-void __init init_IRQ(void)
-{
-	unsigned int irq;
-	int i;
-
-	/* Install our interrupt handler, then clear and disable all
-	 * CRIME and MACE interrupts.
-	 */
-	crime_write_64(CRIME_INT_MASK, 0);
-	crime_write_64(CRIME_HARD_INT, 0);
-	crime_write_64(CRIME_SOFT_INT, 0);
-	mace_write_32(MACEISA_INT_STAT, 0);
-	mace_write_32(MACEISA_INT_MASK, 0);
-	set_except_vector(0, ip32_handle_int);
-
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc[i].status  = IRQ_DISABLED;
-		irq_desc[i].action  = NULL;
-		irq_desc[i].depth   = 1;
-		irq_desc[i].handler = &no_irq_type;
-	}
-
-	for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
-		hw_irq_controller *controller;
-
-		if (irq == CLOCK_IRQ)
-			controller = &ip32_cpu_interrupt;
-		else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
-			controller = &ip32_mace_interrupt;
-		else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
-			controller = &ip32_macepci_interrupt;
-		else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
-			controller = &ip32_crime_interrupt;
-		else
-			controller = &ip32_maceisa_interrupt;
-
-		irq_desc[irq].status = IRQ_DISABLED;
-		irq_desc[irq].action = 0;
-		irq_desc[irq].depth = 0;
-		irq_desc[irq].handler = controller;
-	}
-	setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
-	setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-pci.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-pci.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,460 +0,0 @@
-/*
- * 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) 2000, 2001 Keith M Wesolowski
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <asm/ip32/mace.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/ip32_ints.h>
-#include <linux/delay.h>
-
-#undef DEBUG_MACE_PCI
-
-/*
- * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
- * map looks like this:
- *
- * 0  aic7xxx 0
- * 1  aic7xxx 1
- * 2  expansion slot
- * 3  N/C
- * 4  N/C
- */
-
-#define chkslot(dev)							\
-do {									\
-	if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1	\
-	    || PCI_SLOT ((dev)->devfn) > 3)				\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-} while (0)
-		
-#define mkaddr(dev, where) \
-((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
-
-void macepci_error (int irq, void *dev, struct pt_regs *regs);
-
-static int macepci_read_config_byte (struct pci_dev *dev, int where,
-				     u8 *val)
-{
-	*val = 0xff;
-	chkslot (dev);
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_word (struct pci_dev *dev, int where,
-				     u16 *val)
-{
-	*val = 0xffff;
-	chkslot (dev);
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
- 	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_dword (struct pci_dev *dev, int where,
-				      u32 *val)
-{
-	*val = 0xffffffff;
-	chkslot (dev);
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_32 (MACEPCI_CONFIG_DATA);
-	
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_byte (struct pci_dev *dev, int where,
-				      u8 val)
-{
-	chkslot (dev);
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_word (struct pci_dev *dev, int where,
-				      u16 val)
-{
-	chkslot (dev);
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_dword (struct pci_dev *dev, int where,
-                                          u32 val)
-{
-	chkslot (dev);
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_32 (MACEPCI_CONFIG_DATA, val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macepci_ops = {
-	macepci_read_config_byte,
-	macepci_read_config_word,
-	macepci_read_config_dword,
-	macepci_write_config_byte,
-	macepci_write_config_word,
-	macepci_write_config_dword
-};
-
-struct pci_fixup pcibios_fixups[] = { { 0 } };
-
-void __init pcibios_init (void)
-{
-	struct pci_dev *dev;
-	u32 start, size;
-	u16 cmd;
-	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
-	u32 base_mem = 0x80100000; /* Likewise */
-	u32 rev = mace_read_32 (MACEPCI_REV);
-	int i;
-
-	printk ("MACE: PCI rev %d detected at %016lx\n", rev,
-		(u64) MACE_BASE + MACE_PCI);
-
-	/* These are *bus* addresses */
-	ioport_resource.start = 0;
-	ioport_resource.end = 0xffffffffUL;
-	iomem_resource.start = 0x80000000UL;
-	iomem_resource.end = 0xffffffffUL;
-
-	/* Clear any outstanding errors and enable interrupts */
-	mace_write_32 (MACEPCI_ERROR_ADDR, 0);
-	mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
-	mace_write_32 (MACEPCI_CONTROL, 0xff008500);
-	crime_write_64 (CRIME_HARD_INT, 0UL);
-	crime_write_64 (CRIME_SOFT_INT, 0UL);
-	crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
-
-	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
-			 "MACE PCI error", NULL))
-		panic("PCI bridge can't get interrupt; can't happen.");
-
-	pci_scan_bus (0, &macepci_ops, NULL);
-
-#ifdef DEBUG_MACE_PCI
-	pci_for_each_dev (dev) {
-		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
-			dev->bus->number, PCI_SLOT (dev->devfn),
-			PCI_FUNC (dev->devfn));
-		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			printk ("%d: %016lx - %016lx (flags %04lx)\n",
-				i, dev->resource[i].start,
-				dev->resource[i].end, dev->resource[i].flags);
-		}
-	}
-#endif
-	/*
-	 * Assign sane resources to and enable all devices.  The requirement
-	 * for the SCSI controllers is well-known: a 256-byte I/O region
-	 * which we must assign, and a 1-page memory region which is
-	 * assigned by the system firmware.
-	 */
-	pci_for_each_dev (dev) {
-		switch (PCI_SLOT (dev->devfn)) {
-		case 1: /* SCSI bus 0 */
-			dev->resource[0].start = 0x1000UL;
-			dev->resource[0].end = 0x10ffUL;
-			break;
-		case 2: /* SCSI bus 1 */
-			dev->resource[0].start = 0x2000UL;
-			dev->resource[0].end = 0x20ffUL;
-			break;
-		default: /* Slots - I guess we have only 1 */
-			for (i=0; i < 6; i++) {
-				size = dev->resource[i].end
-					- dev->resource[i].start;
-				if (!size
-				    || !(dev->resource[i].flags
-					 & (IORESOURCE_IO|IORESOURCE_MEM))) {
-					dev->resource[i].start
-						= dev->resource[i].end = 0UL;
-					continue;
-				}
-				if (dev->resource[i].flags & IORESOURCE_IO) {
-					dev->resource[i].start = base_io;
-					base_io += PAGE_ALIGN (size);
-				} else {
-					dev->resource[i].start = base_mem;
-					base_mem += 0x100000UL;
-				}
-				dev->resource[i].end =
-					dev->resource[i].start + size;
-			}
-			break;
-		}
-		for (i=0; i < 6; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			start = dev->resource[i].start;
-			if (dev->resource[i].flags & IORESOURCE_IO)
-				start |= 1;
-			pci_write_config_dword (dev, 
-				PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
-		}
-		pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
-		pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
-		pci_read_config_word (dev, PCI_COMMAND, &cmd);
-		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
-		pci_write_config_word (dev, PCI_COMMAND, cmd);
-		pci_set_master (dev);
-	}
-        /*
-         * Fixup O2 PCI slot. Bad hack.
-         */
-/*        devtag = pci_make_tag(0, 0, 3, 0);
-
-        slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG);
-        slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
-        macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot);
-
-        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START);
-        if (slot == 0xffffffe1)
-                macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000);
-
-        slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2));
-        if ((slot & 0xffff0000) == 0) {
-                slot += 0x00010000;
-                macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2),
-                    0x00000000);
-        }
- */
-#ifdef DEBUG_MACE_PCI
-	printk ("Triggering PCI bridge interrupt...\n");
-	mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
-
-	pci_for_each_dev (dev) {
-		printk ("Device: %d/%d/%d final bus resource map\n",
-			dev->bus->number, PCI_SLOT (dev->devfn),
-			PCI_FUNC (dev->devfn));
-		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			printk ("%d: %016lx - %016lx (flags %04lx)\n",
-				i, dev->resource[i].start,
-				dev->resource[i].end, dev->resource[i].flags);
-		}
-	}
-#endif
-}
-
-/*
- * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
- * the device (1-4 => A-D), tell what irq to use.  Note that we don't
- * in theory have slots 4 and 5, and we never normally use the shared
- * irqs.  I suppose a device without a pin A will thank us for doing it
- * right if there exists such a broken piece of crap.
- */
-static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
-{
-	chkslot (dev);
-	if (pin == 0)
-		pin = 1;
-	switch (slot) {
-	case 1:
-		return MACEPCI_SCSI0_IRQ;
-	case 2:
-		return MACEPCI_SCSI1_IRQ;
-	case 3:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED0_IRQ;
-		case 3:
-			return MACEPCI_SHARED1_IRQ;
-		case 4:
-			return MACEPCI_SHARED2_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT0_IRQ;
-		}
-	case 4:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED2_IRQ;
-		case 3:
-			return MACEPCI_SHARED0_IRQ;
-		case 4:
-			return MACEPCI_SHARED1_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT1_IRQ;
-		}
-		return MACEPCI_SLOT1_IRQ;
-	case 5:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED1_IRQ;
-		case 3:
-			return MACEPCI_SHARED2_IRQ;
-		case 4:
-			return MACEPCI_SHARED0_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT2_IRQ;
-		}
-	default:
-		return 0;
-	}
-}
-
-/*
- * It's not entirely clear what this does in a system with no bridges.
- * In any case, bridges are not supported by Linux in O2.
- */
-static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
-{
-	if (PCI_SLOT (dev->devfn) == 2)
-		*pinp = 2;
-	else
-		*pinp = 1;
-	return PCI_SLOT (dev->devfn);
-}
-
-/* All devices are enabled during initialization. */
-int pcibios_enable_device (struct pci_dev *dev)
-{
-	return PCIBIOS_SUCCESSFUL;
-}
-
-char * __init pcibios_setup (char *str)
-{
-	return str;
-}
-
-void __init pcibios_align_resource (void *data, struct resource *res,
-				    unsigned long size)
-{
-}
-
-void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
-				     struct resource *res, int resource)
-{
-}
-
-void __init pcibios_update_irq (struct pci_dev *dev, int irq)
-{
-	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
-}
-
-void __init pcibios_fixup_bus (struct pci_bus *b)
-{
-	pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
-}
-
-/* XXX anybody know what this is supposed to do? */
-void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
-				      struct pbus_set_ranges_data * ranges)
-{
-	ranges->io_start -= bus->resource[0]->start;
-	ranges->io_end -= bus->resource[0]->start;
-	ranges->mem_start -= bus->resource[1]->start;
-	ranges->mem_end -= bus->resource[1]->start;
-}
-
-/*
- * Handle errors from the bridge.  This includes master and target aborts,
- * various command and address errors, and the interrupt test.  This gets
- * registered on the bridge error irq.  It's conceivable that some of these
- * conditions warrant a panic.  Anybody care to say which ones?
- */
-void macepci_error (int irq, void *dev, struct pt_regs *regs) {
-	u32 flags, error_addr;
-	char space;
-
-	flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
-	error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
-
-	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
-		space = 'M';
-	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
-		space = 'C';
-	else space = 'X';
-	
-	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
-		printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_MASTER_ABORT);
-	}
-	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
-		printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_TARGET_ABORT);
-	}
-	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
-		printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_DATA_PARITY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_RETRY_ERR) {
-		printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_RETRY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
-		printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS,
-			       flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
-	}
-	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
-		printk ("MACEPCI: System error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_SYSTEM_ERR);
-	}
-	if (flags & MACEPCI_ERROR_PARITY_ERR) {
-		printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_PARITY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_OVERRUN) {
-		printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_OVERRUN);
-	}
-	if (flags & MACEPCI_ERROR_SIG_TABORT) {
-		printk ("MACEPCI: Signaled target abort (clearing)\n");
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_SIG_TABORT);
-	}
-	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
-		printk ("MACEPCI: Interrupt test triggered (clearing)\n");
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
-	}
-}
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-reset.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-reset.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-reset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,34 +0,0 @@
-/*
- * 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) 2001 Keith M Wesolowski
- * Copyright (C) 2001 Paul Mundt
- */
-#include <linux/init.h>
-
-#include <asm/reboot.h>
-#include <asm/sgialib.h>
-
-static void ip32_machine_restart(char *cmd)
-{
-	ArcReboot();
-}
-
-static inline void ip32_machine_halt(void)
-{
-	ArcEnterInteractiveMode();
-}
-
-static void ip32_machine_power_off(void)
-{
-	ip32_machine_halt();
-}
-
-void __init ip32_reboot_setup(void)
-{
-	_machine_restart = ip32_machine_restart;
-	_machine_halt = ip32_machine_halt;
-	_machine_power_off = ip32_machine_power_off;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-rtc.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-rtc.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-rtc.c	2001-09-09 17:43:02.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,32 +0,0 @@
-/*
- * RTC routines for IP32 style attached Dallas chip.
- *
- * 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) 2000 Harald Koerfgen
- */
-#include <linux/mc146818rtc.h>
-#include <asm/ip32/mace.h>
-
-static unsigned char ip32_rtc_read_data(unsigned long addr)
-{
-	return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8));
-}
-
-static void ip32_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data);
-}
-
-static int ip32_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops ip32_rtc_ops = {
-	&ip32_rtc_read_data,
-	&ip32_rtc_write_data,
-	&ip32_rtc_bcd_mode
-};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-setup.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-setup.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,102 +0,0 @@
-/*
- * IP32 basic setup
- *
- * 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) 2000 Harald Koerfgen
- */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/param.h>
-#include <linux/init.h>
-
-#include <asm/time.h>
-#include <asm/mipsregs.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu_context.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/mace.h>
-#include <asm/ip32/ip32_ints.h>
-#include <asm/sgialib.h>
-
-extern struct rtc_ops ip32_rtc_ops;
-extern u32 cc_interval;
-
-#ifdef CONFIG_SGI_O2MACE_ETH
-
-/*
- * This is taken care of in here 'cause they say using Arc later on is
- * problematic
- */
-extern char o2meth_eaddr[8];
-static inline unsigned char str2hexnum(unsigned char c)
-{
-	if (c >= '0' && c <= '9')
-		return c - '0';
-	if (c >= 'a' && c <= 'f')
-		return c - 'a' + 10;
-	return 0; /* foo */
-}
-
-static inline void str2eaddr(unsigned char *ea, unsigned char *str)
-{
-	int i;
-
-	for (i = 0; i < 6; i++) {
-		unsigned char num;
-
-		if(*str == ':')
-			str++;
-		num = str2hexnum(*str++) << 4;
-		num |= (str2hexnum(*str++));
-		ea[i] = num;
-	}
-}
-#endif
-
-extern void ip32_time_init(void);
-
-void __init ip32_setup(void)
-{
-#ifdef CONFIG_SERIAL_CONSOLE
-	char *ctype;
-#endif
-	TLBMISS_HANDLER_SETUP ();
-
-	mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	ctype = ArcGetEnvironmentVariable("console");
-	if (*ctype == 'd') {
-		if (ctype[1] == '2')
-			console_setup ("ttyS1");
-		else
-			console_setup ("ttyS0");
-	}
-#endif
-#ifdef CONFIG_SGI_O2MACE_ETH
-	{
-		char *mac=ArcGetEnvironmentVariable("eaddr");
-		str2eaddr(o2meth_eaddr, mac);
-	}
-#endif
-
-#ifdef CONFIG_VT
-	conswitchp = &dummy_con;
-#endif
-
-	rtc_ops = &ip32_rtc_ops;
-	board_time_init = ip32_time_init;
-
-	crime_init ();
-}
-
-int __init page_is_ram (unsigned long pagenr)
-{
-	/* XXX: to do? */
-	return 1;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/sgi-ip32/ip32-timer.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-timer.c
--- linux-2.4.19/arch/mips64/sgi-ip32/ip32-timer.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/sgi-ip32/ip32-timer.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,238 +0,0 @@
-/*
- * IP32 timer calibration
- *
- * 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) 2001 Keith M Wesolowski
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/mc146818rtc.h>
-#include <linux/timex.h>
-
-#include <asm/mipsregs.h>
-#include <asm/param.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/ip32_ints.h>
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
-
-u32 cc_interval;
-
-/* Cycle counter value at the previous timer interrupt.. */
-static unsigned int timerhi, timerlo;
-
-/* An arbitrary time; this can be decreased if reliability looks good */
-#define WAIT_MS 10
-#define PER_MHZ (1000000 / 2 / HZ)
-/*
- * Change this if you have some constant time drift
- */
-#define USECS_PER_JIFFY (1000000/HZ)
-
-
-void __init ip32_timer_setup (struct irqaction *irq)
-{
-	u64 crime_time;
-	u32 cc_tick;
-
-	printk("Calibrating system timer... ");
-
-	crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
-	cc_tick = read_32bit_cp0_register (CP0_COUNT);
-
-	while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time 
-		< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
-		;
-	cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
-	cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
-	/* The round-off seems unnecessary; in testing, the error of the
-	 * above procedure is < 100 ticks, which means it gets filtered
-	 * out by the HZ adjustment. 
-	 */
-	cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
-
-	printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
-
-	setup_irq (CLOCK_IRQ, irq);
-}
-
-struct irqaction irq0  = { NULL, SA_INTERRUPT, 0,
-			   "timer", NULL, NULL};
-
-void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	u32 count;
-
-	/*
-	 * The cycle counter is only 32 bit which is good for about
-	 * a minute at current count rates of upto 150MHz or so.
-	 */
-	count = read_32bit_cp0_register(CP0_COUNT);
-	timerhi += (count < timerlo);	/* Wrap around */
-	timerlo = count;
-
-	write_32bit_cp0_register (CP0_COMPARE, 
-				  (u32) (count + cc_interval));
-	kstat.irqs[0][irq]++;
-	do_timer (regs);
-
-	if (!jiffies)
-	{
-		/*
-		 * If jiffies has overflowed in this timer_interrupt we must
-		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
-		 * quotient calc still valid. -arca
-		 */
-		timerhi = timerlo = 0;
-	}
-}
-
-/*
- * On MIPS only R4000 and better have a cycle counter.
- *
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
-static unsigned long do_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies;
-	u32 quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static u32 cached_quotient;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY)
-			:"$1");
-		cached_quotient = quotient;
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_32bit_cp0_register(CP0_COUNT);
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
-
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
-}
-
-void __init ip32_time_init(void)
-{
-	unsigned int epoch = 0, year, mon, day, hour, min, sec;
-	int i;
-
-	/* 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;
-	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));
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BCD_TO_BIN(sec);
-		BCD_TO_BIN(min);
-		BCD_TO_BIN(hour);
-		BCD_TO_BIN(day);
-		BCD_TO_BIN(mon);
-		BCD_TO_BIN(year);
-	}
-
-	/* Attempt to guess the epoch.  This is the same heuristic as in
-	 * rtc.c so no stupid things will happen to timekeeping.  Who knows,
-	 * maybe Ultrix also uses 1952 as epoch ...
-	 */
-	if (year > 10 && year < 44)
-		epoch = 1980;
-	else if (year < 96)
-		epoch = 1952;
-	year += epoch;
-
-	write_lock_irq (&xtime_lock);
-	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	xtime.tv_usec = 0;
-	write_unlock_irq (&xtime_lock);
-
-	write_32bit_cp0_register(CP0_COUNT, 0);
-	irq0.handler = cc_timer_interrupt;
-
-	ip32_timer_setup (&irq0);
-
-#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-	/* Set ourselves up for future interrupts */
-        write_32bit_cp0_register(CP0_COMPARE,
-				 read_32bit_cp0_register(CP0_COUNT)
-				 + cc_interval);
-        change_cp0_status(ST0_IM, ALLINTS);
-	sti ();
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/tools/Makefile linux-2.4.20/arch/mips64/tools/Makefile
--- linux-2.4.19/arch/mips64/tools/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/mips64/tools/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-#
-# Makefile for MIPS kernel build tools.
-#
-# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
-# Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org)
-# Copyright (C) 1999 Silicon Graphics, Inc.
-#
-TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
-
-USE_STANDARD_AS_RULE := true
-
-$(TARGET): offset.h
-	cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
-
-offset.h: offset.s
-	sed -n '/^@@@/s///p' $^ >$@
-
-offset.s: offset.c $(TOPDIR)/include/linux/autoconf.h
-
-clean:
-	rm -f offset.[hs] $(TARGET).new
-	
-mrproper: clean
-	rm -f $(TARGET)
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips64/tools/offset.c linux-2.4.20/arch/mips64/tools/offset.c
--- linux-2.4.19/arch/mips64/tools/offset.c	2000-07-28 01:36:54.000000000 +0000
+++ linux-2.4.20/arch/mips64/tools/offset.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,150 +0,0 @@
-/*
- * offset.c: Calculate pt_regs and task_struct offsets.
- *
- * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-
-#define text(t) __asm__("\n@@@" t)
-#define _offset(type, member) (&(((type *)NULL)->member))
-
-#define offset(string, ptr, member) \
-	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
-#define size(string, size) \
-	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
-#define linefeed text("")
-
-text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */");
-linefeed;
-text("#ifndef _MIPS_OFFSET_H");
-text("#define _MIPS_OFFSET_H");
-linefeed;
-
-void output_ptreg_defines(void)
-{
-	text("/* MIPS pt_regs offsets. */");
-	offset("#define PT_R0     ", struct pt_regs, regs[0]);
-	offset("#define PT_R1     ", struct pt_regs, regs[1]);
-	offset("#define PT_R2     ", struct pt_regs, regs[2]);
-	offset("#define PT_R3     ", struct pt_regs, regs[3]);
-	offset("#define PT_R4     ", struct pt_regs, regs[4]);
-	offset("#define PT_R5     ", struct pt_regs, regs[5]);
-	offset("#define PT_R6     ", struct pt_regs, regs[6]);
-	offset("#define PT_R7     ", struct pt_regs, regs[7]);
-	offset("#define PT_R8     ", struct pt_regs, regs[8]);
-	offset("#define PT_R9     ", struct pt_regs, regs[9]);
-	offset("#define PT_R10    ", struct pt_regs, regs[10]);
-	offset("#define PT_R11    ", struct pt_regs, regs[11]);
-	offset("#define PT_R12    ", struct pt_regs, regs[12]);
-	offset("#define PT_R13    ", struct pt_regs, regs[13]);
-	offset("#define PT_R14    ", struct pt_regs, regs[14]);
-	offset("#define PT_R15    ", struct pt_regs, regs[15]);
-	offset("#define PT_R16    ", struct pt_regs, regs[16]);
-	offset("#define PT_R17    ", struct pt_regs, regs[17]);
-	offset("#define PT_R18    ", struct pt_regs, regs[18]);
-	offset("#define PT_R19    ", struct pt_regs, regs[19]);
-	offset("#define PT_R20    ", struct pt_regs, regs[20]);
-	offset("#define PT_R21    ", struct pt_regs, regs[21]);
-	offset("#define PT_R22    ", struct pt_regs, regs[22]);
-	offset("#define PT_R23    ", struct pt_regs, regs[23]);
-	offset("#define PT_R24    ", struct pt_regs, regs[24]);
-	offset("#define PT_R25    ", struct pt_regs, regs[25]);
-	offset("#define PT_R26    ", struct pt_regs, regs[26]);
-	offset("#define PT_R27    ", struct pt_regs, regs[27]);
-	offset("#define PT_R28    ", struct pt_regs, regs[28]);
-	offset("#define PT_R29    ", struct pt_regs, regs[29]);
-	offset("#define PT_R30    ", struct pt_regs, regs[30]);
-	offset("#define PT_R31    ", struct pt_regs, regs[31]);
-	offset("#define PT_LO     ", struct pt_regs, lo);
-	offset("#define PT_HI     ", struct pt_regs, hi);
-	offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
-	offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
-	offset("#define PT_STATUS ", struct pt_regs, cp0_status);
-	offset("#define PT_CAUSE  ", struct pt_regs, cp0_cause);
-	size("#define PT_SIZE   ", struct pt_regs);
-	linefeed;
-}
-
-void output_task_defines(void)
-{
-	text("/* MIPS task_struct offsets. */");
-	offset("#define TASK_STATE         ", struct task_struct, state);
-	offset("#define TASK_FLAGS         ", struct task_struct, flags);
-	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
-	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
-	offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
-	offset("#define TASK_COUNTER       ", struct task_struct, counter);
-	offset("#define TASK_NICE          ", struct task_struct, nice);
-	offset("#define TASK_MM            ", struct task_struct, mm);
-	offset("#define TASK_PROCESSOR     ", struct task_struct, processor);
-	size("#define TASK_STRUCT_SIZE   ", struct task_struct);
-	linefeed;
-}
-
-void output_thread_defines(void)
-{
-	text("/* MIPS specific thread_struct offsets. */");
-	offset("#define THREAD_REG16   ", struct task_struct, thread.reg16);
-	offset("#define THREAD_REG17   ", struct task_struct, thread.reg17);
-	offset("#define THREAD_REG18   ", struct task_struct, thread.reg18);
-	offset("#define THREAD_REG19   ", struct task_struct, thread.reg19);
-	offset("#define THREAD_REG20   ", struct task_struct, thread.reg20);
-	offset("#define THREAD_REG21   ", struct task_struct, thread.reg21);
-	offset("#define THREAD_REG22   ", struct task_struct, thread.reg22);
-	offset("#define THREAD_REG23   ", struct task_struct, thread.reg23);
-	offset("#define THREAD_REG29   ", struct task_struct, thread.reg29);
-	offset("#define THREAD_REG30   ", struct task_struct, thread.reg30);
-	offset("#define THREAD_REG31   ", struct task_struct, thread.reg31);
-	offset("#define THREAD_STATUS  ", struct task_struct, \
-	       thread.cp0_status);
-	offset("#define THREAD_FPU     ", struct task_struct, thread.fpu);
-	offset("#define THREAD_BVADDR  ", struct task_struct, \
-	       thread.cp0_badvaddr);
-	offset("#define THREAD_BUADDR  ", struct task_struct, \
-	       thread.cp0_baduaddr);
-	offset("#define THREAD_ECODE   ", struct task_struct, \
-	       thread.error_code);
-	offset("#define THREAD_TRAPNO  ", struct task_struct, thread.trap_no);
-	offset("#define THREAD_MFLAGS  ", struct task_struct, thread.mflags);
-	offset("#define THREAD_CURDS   ", struct task_struct, \
-	       thread.current_ds);
-	offset("#define THREAD_TRAMP   ", struct task_struct, \
-	       thread.irix_trampoline);
-	offset("#define THREAD_OLDCTX  ", struct task_struct, \
-	       thread.irix_oldctx);
-	linefeed;
-}
-
-void output_mm_defines(void)
-{
-	text("/* Linux mm_struct offsets. */");
-	offset("#define MM_USERS      ", struct mm_struct, mm_users);
-	offset("#define MM_PGD        ", struct mm_struct, pgd);
-	offset("#define MM_CONTEXT    ", struct mm_struct, context);
-	linefeed;
-}
-
-void output_sc_defines(void)
-{
-	text("/* Linux sigcontext offsets. */");
-	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
-	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
-	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
-	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
-	offset("#define SC_PC         ", struct sigcontext, sc_pc);
-	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
-	offset("#define SC_OWNEDFP    ", struct sigcontext, sc_ownedfp);
-	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
-	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
-	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
-	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
-	linefeed;
-}
-
-text("#endif /* !(_MIPS_OFFSET_H) */");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/Makefile linux-2.4.20/arch/parisc/Makefile
--- linux-2.4.19/arch/parisc/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/Makefile	2002-10-04 00:41:15.000000000 +0000
@@ -17,12 +17,28 @@
 # Mike Shaver, Helge Deller and Martin K. Petersen
 #
 
+ifdef CONFIG_PARISC64
+LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux64.lds $(LDFLAGS)
+CROSS_COMPILE := hppa64-linux-
+UTS_MACHINE := parisc64
+#CFLAGS += -b hppa64-linux
+
+else
+LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux.lds $(LDFLAGS)
+MACHINE	:= $(subst 64,,$(shell uname -m))
+ifneq (${MACHINE},parisc)
+# cross compilation
+CROSS_COMPILE := hppa-linux-
+endif
+endif
+
+OFFSET_H := $(TOPDIR)/include/asm-parisc/offset.h
 FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align 
 
 CPP=$(CC) -E
 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 LDFLAGS =
-LINKFLAGS =-T $(TOPDIR)/arch/parisc/vmlinux.lds $(LDFLAGS)
+
 
 CFLAGS_PIPE := -pipe
 CFLAGS_NSR  := -fno-strength-reduce
@@ -32,25 +48,48 @@
 # enable them by default.
 CFLAGS += -mno-space-regs -mfast-indirect-calls
 
-# If we become able to compile for specific platforms, this should be
-# conditional on that.
-CFLAGS += -mschedule=7200
-
 # No fixed-point multiply
 CFLAGS += -mdisable-fpregs
 
-HEAD = arch/parisc/kernel/head.o 
+# Without this, "ld -r" results in .text sections that are too big
+# (> 0x40000) for branches to reach stubs.
+CFLAGS += -ffunction-sections
+
+# select which processor to optimise for
+ifdef CONFIG_PA7100
+CFLAGS += -march=1.1 -mschedule=7100
+endif
+
+ifdef CONFIG_PA7200
+CFLAGS += -march=1.1 -mschedule=7200
+endif
+
+ifdef CONFIG_PA7100LC
+CFLAGS += -march=1.1 -mschedule=7100LC
+endif
+
+ifdef CONFIG_PA8X00
+CFLAGS += -march=2.0 -mschedule=8000
+endif
+
+ASFLAGS := -D__ASSEMBLY__ -traditional
+
+HEAD := arch/parisc/kernel/head.o 
 
 SUBDIRS := $(SUBDIRS) $(addprefix arch/parisc/, tools kernel mm lib hpux)
 CORE_FILES :=  $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \
 	lib/lib.a mm/mm.o kernel/kernel.o hpux/hpux.o) \
 	$(CORE_FILES) arch/parisc/kernel/init_task.o
+CLEAN_FILES := $(CLEAN_FILES) arch/parisc/tools/offset.[hs] 
+
+ifdef CONFIG_PARISC64
+HEAD := arch/parisc/kernel/head64.o
+endif
+
 LIBS := `$(CC) -print-libgcc-file-name` $(TOPDIR)/arch/parisc/lib/lib.a $(LIBS) 
 
-ifdef CONFIG_MATH_EMULATION
 SUBDIRS := $(SUBDIRS) arch/parisc/math-emu
-DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.a
-endif
+DRIVERS := $(DRIVERS) arch/parisc/math-emu/math.o
 
 ifdef CONFIG_KWDB
 SUBDIRS := $(SUBDIRS) arch/parisc/kdb
@@ -67,7 +106,7 @@
 	$(MAKE) linuxsubdirs SUBDIRS=arch/parisc/mm
 
 palo: vmlinux
-	export TOPDIR=`pwd`; export CONFIG_STI_CONSOLE=$(CONFIG_STI_CONSOLE); \
+	export TOPDIR=`pwd`; \
 	unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
 
 Image: palo
@@ -84,8 +123,14 @@
 
 install: 
 
+archmrproper:
+	rm -f $(OFFSET_H)
+
 archclean:
 
-archmrproper:
+archdep: $(OFFSET_H)
+
+$(OFFSET_H): include/linux/version.h
+	$(MAKE) -C $(TOPDIR)/arch/$(ARCH)/tools all
 
-archdep:
+.PHONY: $(OFFSET_H)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/config.in linux-2.4.20/arch/parisc/config.in
--- linux-2.4.19/arch/parisc/config.in	2001-04-18 00:19:25.000000000 +0000
+++ linux-2.4.20/arch/parisc/config.in	2002-10-04 00:41:30.000000000 +0000
@@ -16,98 +16,106 @@
 endmenu
 
 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 module symbols' CONFIG_MODVERSIONS
+  bool 'Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Processor type'
+choice 'Processor family' \
+	"PA7000/PA7100		CONFIG_PA7100 \
+	 PA7200			CONFIG_PA7200 \
+	 PA7100LC/PA7300LC	CONFIG_PA7100LC \
+	 PA8x00			CONFIG_PA8X00" PA7000
+
+if [ "$CONFIG_PA8X00" = "y" ] ; then
+   define_bool CONFIG_PA20 y
+   bool '64-bit kernel' CONFIG_PARISC64
+   dep_bool '32-bit PDC' CONFIG_PDC_NARROW $CONFIG_PARISC64
+else
+   define_bool CONFIG_PA11 y
+fi
+endmenu
+
+mainmenu_option next_comment
 comment 'General options'
 
-# bool 'Symmetric multi-processing support' CONFIG_SMP
-define_bool CONFIG_SMP n
+bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Chassis LCD and LED support' CONFIG_CHASSIS_LCD_LED
 
 bool 'Kernel Debugger support' CONFIG_KWDB
 # define_bool CONFIG_KWDB n
 
-# bool 'GSC/Gecko bus support' CONFIG_GSC y
-define_bool CONFIG_GSC y
-
-bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO y
-bool 'LASI I/O support' CONFIG_GSC_LASI y
-
-bool 'PCI bus support' CONFIG_PCI y
+bool 'U2/Uturn I/O MMU' CONFIG_IOMMU_CCIO
+bool 'VSC/GSC/HSC bus support' CONFIG_GSC
+dep_bool '  Lasi I/O support' CONFIG_GSC_LASI $CONFIG_GSC
+dep_bool '  Wax I/O support' CONFIG_GSC_WAX $CONFIG_GSC
+
+dep_bool 'EISA support' CONFIG_EISA $CONFIG_GSC
+define_bool CONFIG_ISA $CONFIG_EISA
+bool 'PCI support' CONFIG_PCI
 
 if [ "$CONFIG_PCI" = "y" ]; then
-	bool 'GSCtoPCI/DINO PCI support' CONFIG_GSC_DINO y
-	bool 'LBA/Elroy PCI support' CONFIG_PCI_LBA n
-fi 
+   dep_bool '  GSCtoPCI/Dino PCI support' CONFIG_GSC_DINO $CONFIG_GSC
+   bool '  LBA/Elroy PCI support' CONFIG_PCI_LBA
+   define_bool CONFIG_IOSAPIC $CONFIG_PCI_LBA
+   define_bool CONFIG_IOMMU_SBA $CONFIG_PCI_LBA
 
-if [ "$CONFIG_PCI_LBA" = "y" ]; then
-	define_bool CONFIG_IOSAPIC y
-	define_bool CONFIG_IOMMU_SBA y
-fi
+#   bool '  EPIC PCI support' CONFIG_PCI_EPIC n
+   bool '  SuperIO support' CONFIG_SUPERIO
+fi 
 
-#
-# if [ "$CONFIG_PCI_EPIC" = "y" ]; then...
-#
+source drivers/pci/Config.in
 
 endmenu
 
 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 module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
 comment 'General setup'
 
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
 bool 'Networking support' CONFIG_NET
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
-tristate 'Kernel support for SOM binaries' CONFIG_BINFMT_SOM
+define_bool CONFIG_KCORE_ELF y
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for SOM binaries' CONFIG_BINFMT_SOM
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'Kernel support for JAVA binaries (obsolete)' CONFIG_BINFMT_JAVA
-fi
+
+# anyone want to get ACPI working on PA/RISC?
+define_bool CONFIG_PM n
 
 endmenu
 
-##source drivers/parport/Config.in
-mainmenu_option next_comment
-comment 'Parallel port support'
+source drivers/parport/Config.in
 
-tristate 'Parallel port support' CONFIG_PARPORT
-if [ "$CONFIG_PARPORT" != "n" ]; then
-   if [ "$CONFIG_PCI" = "y" ]; then
-     dep_tristate '  PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
-     if [ "$CONFIG_PARPORT_PC" != "n" ]; then
-        bool '    Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO
-        if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-           bool '    SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO
-        fi
-     fi
-   fi
-   if [ "$CONFIG_GSC_LASI" = "y" ]; then
-      dep_tristate '  LASI/ASP builtin parallel-port' CONFIG_PARPORT_GSC $CONFIG_PARPORT
-   else
-      define_tristate CONFIG_PARPORT_GSC n
-   fi
+source drivers/block/Config.in
 
-   # If exactly one hardware type is selected then parport will optimise away
-   # support for loading any others.  Defeat this if the user is keen.
-   bool '  Support foreign hardware' CONFIG_PARPORT_OTHER
+source drivers/md/Config.in
 
-   bool '  IEEE 1284 transfer modes' CONFIG_PARPORT_1284
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
 fi
-endmenu
 
+if [ "$CONFIG_SUPERIO" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'ATA/IDE/MFM/RLL support'
 
-source drivers/block/Config.in
+    tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
 
-if [ "$CONFIG_NET" = "y" ]; then
-  source net/Config.in
+    if [ "$CONFIG_IDE" != "n" ]; then
+      source drivers/ide/Config.in
+    else
+      define_bool CONFIG_BLK_DEV_IDE_MODES n
+      define_bool CONFIG_BLK_DEV_HD n
+    fi
+    endmenu
 fi
 
 mainmenu_option next_comment
@@ -116,90 +124,70 @@
 tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
-  comment 'SCSI support type (disk, tape, CDrom)'
-
-  dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
-  if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
-    int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
-  fi
-
-  dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-  dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
-  if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
-    bool '  Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
-    int  'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
-  fi
-  dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $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
-  bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
-
-  mainmenu_option next_comment
-  comment 'SCSI low-level drivers'
-  if [ "$CONFIG_GSC_LASI" = "y" ]; then
-    dep_tristate 'Lasi SCSI support' CONFIG_SCSI_LASI $CONFIG_SCSI
-    dep_tristate 'Zalon SCSI support' CONFIG_SCSI_ZALON $CONFIG_SCSI
-  fi
-  if [ "$CONFIG_PCI" = "y" ]; then
-    dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI
-  fi
-  if [ "$CONFIG_SCSI_ZALON" != "n" -o "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then
-    int  '  default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
-    int  '  maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
-    int  '  synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
-    bool '  enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
-    bool '  use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED
-  fi
-  endmenu
+   source drivers/scsi/Config.in
 fi
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Network device support'
+   mainmenu_option next_comment
+   comment 'Network device support'
 
-  bool 'Network device support' CONFIG_NETDEVICES
+   bool 'Network device support' CONFIG_NETDEVICES
 
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    if [ "$CONFIG_GSC_LASI" = "y" ]; then
-      tristate 'Lasi ethernet' CONFIG_LASI_82596
-    fi
-    source drivers/net/Config.in
-  fi
-  endmenu
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
 fi
 
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
 source drivers/char/Config.in
+source drivers/hil/Config.in
+
+source drivers/media/Config.in
 
 source fs/Config.in
 
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   source drivers/video/Config.in
+
+   bool 'STI console' CONFIG_STI_CONSOLE
+   if [ "$CONFIG_GSC_PS2" = "y" ]; then
+      define_bool CONFIG_DUMMY_CONSOLE y
+   fi
+   if [ "$CONFIG_STI_CONSOLE" = "y" ]; then
+      define_bool CONFIG_DUMMY_CONSOLE y
+      define_bool CONFIG_FBCON y
+      define_bool CONFIG_FBCON_FONT y
+#      define_bool CONFIG_FBCON_FONTWIDTH8_ONLY n
+      define_bool CONFIG_FONT_8x8 y
+      define_bool CONFIG_FONT_8x16 y
+      define_bool CONFIG_FONT_6x11 y
+      define_bool CONFIG_FONT_SUN12x22 y
+   fi
+   endmenu
+fi
+
 mainmenu_option next_comment
-comment 'Sound Drivers'
+comment 'Sound'
+
 tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
    source drivers/sound/Config.in
 fi
 endmenu
 
-if [ "$CONFIG_VT" = "y" ]; then
-  mainmenu_option next_comment
-  comment 'Console drivers'
-  source drivers/video/Config.in
-
-#  bool 'IODC console' CONFIG_IODC_CONSOLE
-  bool 'STI console' CONFIG_STI_CONSOLE
-  if [ "$CONFIG_IODC_CONSOLE" = "n" ]; then
-    if [ "$CONFIG_GSC_PS2" = "y" ]; then
-      define_bool CONFIG_DUMMY_CONSOLE y
-    fi
-  fi
-  if [ "$CONFIG_STI_CONSOLE" = "y" ]; then
-    define_bool CONFIG_DUMMY_CONSOLE y
-  fi
-  endmenu
+if [ "$CONFIG_SUPERIO" = "y" ]; then
+    source drivers/usb/Config.in
 fi
-# endmenu
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
@@ -208,3 +196,4 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/defconfig linux-2.4.20/arch/parisc/defconfig
--- linux-2.4.19/arch/parisc/defconfig	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/defconfig	2002-10-04 00:41:10.000000000 +0000
@@ -1,8 +1,10 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_PARISC=y
 # CONFIG_UID16 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 
 #
 # Code maturity level options
@@ -10,44 +12,70 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Processor type
+#
+# CONFIG_PA7100 is not set
+# CONFIG_PA7200 is not set
+# CONFIG_PA7100LC is not set
+# CONFIG_PA8X00 is not set
+# CONFIG_PA11 is not set
+
+#
 # General options
 #
 # CONFIG_SMP is not set
+CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_KWDB is not set
-CONFIG_GSC=y
 CONFIG_IOMMU_CCIO=y
+CONFIG_GSC=y
 CONFIG_GSC_LASI=y
+CONFIG_GSC_WAX=y
+CONFIG_EISA=y
+CONFIG_ISA=y
 CONFIG_PCI=y
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
 CONFIG_IOMMU_SBA=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_SUPERIO=y
+CONFIG_PCI_NAMES=y
 
 #
 # General setup
 #
+CONFIG_HOTPLUG=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_BINFMT_SOM=y
+CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_SOM=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PM is not set
 
 #
 # Parallel port support
 #
 CONFIG_PARPORT=y
-# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_CML1=y
+# CONFIG_PARPORT_SERIAL is not set
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
 # CONFIG_PARPORT_1284 is not set
 
@@ -60,33 +88,54 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 
 #
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -106,36 +155,181 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+CONFIG_BLK_DEV_NS87415=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
 CONFIG_BLK_DEV_SR=y
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
 
 #
 # SCSI low-level drivers
 #
-CONFIG_SCSI_LASI=y
-CONFIG_SCSI_ZALON=y
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_LASI700=y
+CONFIG_53C700_MEM_MAPPED=y
+CONFIG_53C700_LE_ON_BE=y
+CONFIG_53C700_USE_CONSISTENT=y
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
 CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_SCSI_PCMCIA is not set
 
 #
 # Network device support
 #
 CONFIG_NETDEVICES=y
-CONFIG_LASI_82596=y
 
 #
 # ARCnet devices
@@ -145,12 +339,18 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+CONFIG_LASI_82596=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
@@ -165,23 +365,31 @@
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
 CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -189,6 +397,9 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
@@ -217,12 +428,27 @@
 # CONFIG_WAN is not set
 
 #
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_GSC_PS2=y
-CONFIG_HIL=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_SERIAL_GSC=y
@@ -243,12 +469,45 @@
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+CONFIG_INPUT_SERIO=y
+# CONFIG_INPUT_SERPORT is not set
 
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -271,27 +530,67 @@
 # CONFIG_DRM is not set
 
 #
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+
+#
+# HIL support
+#
+CONFIG_HIL=y
+# CONFIG_HIL_KBD_BASIC is not set
+
+#
+#  HIL driver core support
+#
+CONFIG_HP_SDC=y
+# CONFIG_HP_SDC_RTC is not set
+CONFIG_HIL_MLC=y
+CONFIG_HP_SDC_MLC=y
+
+#
+#  HIL device driver
+#
+CONFIG_HIL_KBD=y
+CONFIG_HIL_PTR=y
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -299,13 +598,12 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
@@ -315,13 +613,15 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -330,22 +630,60 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
 
 #
-# Sound Drivers
+# Native Language Support
 #
-# CONFIG_SOUND is not set
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Console drivers
@@ -354,8 +692,171 @@
 #
 # Frame-buffer support
 #
-# CONFIG_FB is not set
-# CONFIG_STI_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_STI=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_STI=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FBCON=y
+CONFIG_FBCON_FONT=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_SUN12x22=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+CONFIG_SOUND_HARMONY=y
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
 
 #
 # Kernel hacking
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/Makefile linux-2.4.20/arch/parisc/hpux/Makefile
--- linux-2.4.19/arch/parisc/hpux/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/Makefile	2002-10-04 00:41:14.000000000 +0000
@@ -7,10 +7,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-all: hpux.o
 O_TARGET = hpux.o
-O_OBJS = entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
-
-.o.S:	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
+obj-y := entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/entry_hpux.S linux-2.4.20/arch/parisc/hpux/entry_hpux.S
--- linux-2.4.19/arch/parisc/hpux/entry_hpux.S	2001-10-05 19:22:07.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/entry_hpux.S	2002-10-04 00:41:15.000000000 +0000
@@ -1,6 +1,6 @@
-/* -----------------------------------------------------------------------------
+/*
  *
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * modified by Matthew Wilcox <willy@bofh.ai> 1999-07-26
  */
@@ -10,13 +10,13 @@
 #include <linux/linkage.h>
 #include <asm/unistd.h>
 
-
 	.text
 
 #define ENTRY_NAME(_name_) .word _name_
 
 	.align 4
 	.export hpux_call_table
+	.import hpux_unimplemented_wrapper
 hpux_call_table:
 	ENTRY_NAME(sys_ni_syscall)	/* 0 */
 	ENTRY_NAME(sys_exit)
@@ -36,7 +36,7 @@
 	ENTRY_NAME(sys_chmod)	/* 15 */
 	ENTRY_NAME(sys_chown)
 	ENTRY_NAME(hpux_brk)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_lseek)
 	ENTRY_NAME(sys_getpid)	/* 20 */
 	ENTRY_NAME(hpux_mount)
@@ -46,34 +46,34 @@
 	ENTRY_NAME(sys_stime)	/* 25 */
 	ENTRY_NAME(hpux_ptrace)
 	ENTRY_NAME(sys_alarm)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_pause)
 	ENTRY_NAME(sys_utime)	/* 30 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_access)
 	ENTRY_NAME(hpux_nice)
-	ENTRY_NAME(sys_ni_syscall)	/* 35 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 35 */
 	ENTRY_NAME(sys_sync)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_newstat)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_setpgrp3)
 	ENTRY_NAME(sys_newlstat)	/* 40 */
 	ENTRY_NAME(sys_dup)
 	ENTRY_NAME(hpux_pipe_wrapper)
 	ENTRY_NAME(sys_times)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 45 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 45 */
 	ENTRY_NAME(sys_setgid)
 	ENTRY_NAME(sys_getgid)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 50 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 50 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_ioctl)
-	ENTRY_NAME(sys_ni_syscall)	/* 55 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 55 */
 	ENTRY_NAME(sys_symlink)
 	ENTRY_NAME(hpux_utssys)
 	ENTRY_NAME(sys_readlink)
@@ -81,218 +81,218 @@
 	ENTRY_NAME(sys_umask)	/* 60 */
 	ENTRY_NAME(sys_chroot)
 	ENTRY_NAME(sys_fcntl)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 65 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 65 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_sbrk)
-	ENTRY_NAME(sys_ni_syscall)	/* 70 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 70 */
 	ENTRY_NAME(sys_mmap)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 75 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 80 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 75 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 80 */
 	ENTRY_NAME(sys_getpgid)
 	ENTRY_NAME(sys_setpgid)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 85 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(sys_setitimer)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 85 */
+	ENTRY_NAME(sys_getitimer)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_dup2)		/* 90 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_newfstat)
 	ENTRY_NAME(sys_select)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 95 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 100 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 105 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 110 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 115 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 95 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 100 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 105 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 110 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 115 */
 	ENTRY_NAME(sys_gettimeofday)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 120 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 120 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_fchown)
 	ENTRY_NAME(sys_fchmod)
-	ENTRY_NAME(sys_ni_syscall)	/* 125 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 125 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_rename)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 130 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 130 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_sysconf)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 135 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 135 */
 	ENTRY_NAME(sys_mkdir)
 	ENTRY_NAME(sys_rmdir)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 140 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 145 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 150 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 155 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 160 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 165 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 170 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 175 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 180 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 185 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 190 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 140 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(sys_getrlimit)
+	ENTRY_NAME(sys_setrlimit)      /* 145 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 150 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_lockf)      /* 155 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 160 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 165 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 170 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 175 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 180 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(sys_sigprocmask)      /* 185 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 190 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_getdomainname)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 195 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 195 */
+	ENTRY_NAME(hpux_statfs)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_waitpid)	/* 200 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 205 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 210 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 215 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 220 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 225 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 230 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 235 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 240 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 245 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 250 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 255 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 260 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 265 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 270 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 205 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 210 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 215 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 220 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 225 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 230 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 235 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 240 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 245 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 250 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 255 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 260 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 265 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 270 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_fchdir)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_accept)		/* 275 */
 	ENTRY_NAME(sys_bind)
 	ENTRY_NAME(sys_connect)
@@ -309,227 +309,227 @@
 	ENTRY_NAME(sys_setsockopt)
 	ENTRY_NAME(sys_shutdown)
 	ENTRY_NAME(sys_socket)		/* 290 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 295 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 300 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 305 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 310 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 315 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 320 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 325 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 330 */
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 295 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 300 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 305 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 310 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 315 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 320 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 325 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 330 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_lchown)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 335 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 340 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 345 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 350 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_sysfs)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 335 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 340 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 345 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 350 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_nanosleep)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 355 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 355 */
 	ENTRY_NAME(hpux_getdents)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 360 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 360 */
 	ENTRY_NAME(hpux_fstat64)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 365 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 365 */
 	ENTRY_NAME(hpux_lstat64)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_stat64)
-	ENTRY_NAME(sys_ni_syscall)	/* 370 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 375 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 380 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 385 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 390 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 395 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 400 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 405 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 410 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 415 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 420 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 425 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 430 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 435 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 440 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 445 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 450 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 455 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 460 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 465 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 470 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 475 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 480 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 485 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 490 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 495 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 500 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 505 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)	/* 510 */
-	ENTRY_NAME(sys_ni_syscall)
-	ENTRY_NAME(sys_ni_syscall)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 370 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 375 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 380 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_setpgrp)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 385 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 390 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 395 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 400 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 405 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 410 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 415 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 420 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 425 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 430 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 435 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 440 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 445 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 450 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 455 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 460 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 465 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 470 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 475 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 480 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 485 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 490 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 495 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 500 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 505 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 510 */
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
 .end
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/fs.c linux-2.4.20/arch/parisc/hpux/fs.c
--- linux-2.4.19/arch/parisc/hpux/fs.c	2001-08-12 22:07:55.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/fs.c	2002-10-04 00:41:13.000000000 +0000
@@ -52,7 +52,8 @@
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
-static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino)
+static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
+		ino_t ino, unsigned int d_type)
 {
 	struct hpux_dirent * dirent;
 	struct getdents_callback * buf = (struct getdents_callback *) __buf;
@@ -83,42 +84,21 @@
 int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
 {
 	struct file * file;
-	struct dentry * dentry;
-	struct inode * inode;
 	struct hpux_dirent * lastdirent;
 	struct getdents_callback buf;
 	int error;
 
-	lock_kernel();
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
 		goto out;
 
-	dentry = file->f_dentry;
-	if (!dentry)
-		goto out_putf;
-
-	inode = dentry->d_inode;
-	if (!inode)
-		goto out_putf;
-
 	buf.current_dir = dirent;
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
 
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
-		goto out_putf;
-
-	/*
-	 * Get the inode's semaphore to prevent changes
-	 * to the directory while we read it.
-	 */
-	down(&inode->i_sem);
-	error = file->f_op->readdir(file, &buf, filldir);
-	up(&inode->i_sem);
+	error = vfs_readdir(file, filldir, &buf);
 	if (error < 0)
 		goto out_putf;
 	error = buf.error;
@@ -131,7 +111,6 @@
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/gate.S linux-2.4.20/arch/parisc/hpux/gate.S
--- linux-2.4.19/arch/parisc/hpux/gate.S	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/gate.S	2002-10-04 00:41:11.000000000 +0000
@@ -1,6 +1,6 @@
-/* ------------------------------------------------------------------------------
+/*
  *
- * Linux/PARISC Project (http://www.thepuffingroup.com/parisc)
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
  * Licensed under the GNU GPL.
@@ -8,14 +8,23 @@
  * sorry about the wall, puffin..
  */
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/offset.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
 
+#ifdef __LP64__
+	.level          2.0w
+#else
+	.level		1.1
+#endif
 	.text
 
+#ifdef __LP64__
+#define FRAME_SIZE	128
+#else
+#define FRAME_SIZE	64
+#endif
 	.import hpux_call_table
 	.import hpux_syscall_exit,code
 	.export hpux_gateway_page
@@ -23,35 +32,70 @@
 	.align 4096
 hpux_gateway_page:
 	nop
-	mfsp	%sr7,%r1			;! we must set sr3 to the space
-	mtsp	%r1,%sr3			;! of the user before the gate
 #ifdef __LP64__
 #warning NEEDS WORK for 64-bit
 #endif
-	ldw	-64(%r30), %r28			;! 8th argument
+	ldw     -64(%r30), %r29                 ;! 8th argument
 	ldw	-60(%r30), %r19			;! 7th argument
 	ldw	-56(%r30), %r20			;! 6th argument
 	ldw	-52(%r30), %r21			;! 5th argument
-	gate	.+8, %r0			;! become privileged
-	mtsp	%r0,%sr4			;! get kernel space into sr4
-	mtsp	%r0,%sr5			;! get kernel space into sr5
-	mtsp	%r0,%sr6			;! get kernel space into sr6
-	mtsp	%r0,%sr7			;! get kernel space into sr7
-	mfctl	%cr30,%r1			;! get the kernel task ptr
-	mtctl	%r0,%cr30			;! zero it (flag)
-	STREG	%r30,TASK_PT_GR30(%r1)		;! preserve userspace sp
-	STREG	%r2,TASK_PT_GR2(%r1)		;! preserve rp
-	STREG	%r27,TASK_PT_GR27(%r1)		;! user dp
-	STREG	%r31,TASK_PT_GR31(%r1)		;! preserve syscall return ptr
+	gate	.+8, %r0			/* become privileged */
+	mtsp	%r0,%sr4			/* get kernel space into sr4 */
+	mtsp	%r0,%sr5			/* get kernel space into sr5 */
+	mtsp	%r0,%sr6			/* get kernel space into sr6 */
+	mfsp    %sr7,%r1                        /* save user sr7 */
+	mtsp    %r1,%sr3                        /* and store it in sr3 */
+
+	mtctl   %r30,%cr28
+	mfctl   %cr30,%r1
+	xor     %r1,%r30,%r30                   /* ye olde xor trick */
+	xor     %r1,%r30,%r1
+	xor     %r1,%r30,%r30
+	ldo     TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30  /* set up kernel stack */
+
+	/* N.B.: It is critical that we don't set sr7 to 0 until r30
+	 *       contains a valid kernel stack pointer. It is also
+	 *       critical that we don't start using the kernel stack
+	 *       until after sr7 has been set to 0.
+	 */
+
+	mtsp	%r0,%sr7			/* get kernel space into sr7 */
+	STREG   %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */
+	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1   /* get task ptr in %r1 */
+
+	/* Save some registers for sigcontext and potential task
+	   switch (see entry.S for the details of which ones are
+	   saved/restored).  TASK_PT_PSW is zeroed so we can see whether
+	   a process is on a syscall or not.  For an interrupt the real
+	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
+	STREG	%r0,  TASK_PT_PSW(%r1)
+	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
+	STREG   %r19, TASK_PT_GR19(%r1)         /* 7th argument */
+	STREG   %r20, TASK_PT_GR20(%r1)         /* 6th argument */
+	STREG   %r21, TASK_PT_GR21(%r1)         /* 5th argument */
+	STREG   %r22, TASK_PT_GR22(%r1)         /* syscall # */
+	STREG	%r23, TASK_PT_GR23(%r1)		/* 4th argument */
+	STREG	%r24, TASK_PT_GR24(%r1)		/* 3rd argument */
+	STREG	%r25, TASK_PT_GR25(%r1)		/* 2nd argument */
+	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
+	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
+	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
+	STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+	STREG   %r29, TASK_PT_GR29(%r1)         /* 8th argument */
+	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
+	
+	ldo	TASK_PT_FR0(%r1), %r27		/* save fpregs from the kernel */
+	save_fp	%r27				/* or potential task switch  */
 
-	loadgp					;! setup kernel dp
+	mfctl	%cr11, %r27			/* i.e. SAR */
+	STREG	%r27, TASK_PT_SAR(%r1)
 
-	ldo	TASK_SZ_ALGN+64(%r1),%r30	;! set up kernel stack
+	loadgp
 
 	stw	%r21, -52(%r30)			;! 5th argument
 	stw	%r20, -56(%r30)			;! 6th argument
 	stw	%r19, -60(%r30)			;! 7th argument
-	stw	%r28, -64(%r30)			;! 8th argument
+	stw     %r29, -64(%r30)                 ;! 8th argument
 
 	ldil	L%hpux_call_table, %r21
 	ldo	R%hpux_call_table(%r21), %r21
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/ioctl.c linux-2.4.20/arch/parisc/hpux/ioctl.c
--- linux-2.4.19/arch/parisc/hpux/ioctl.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/ioctl.c	2002-10-04 00:41:13.000000000 +0000
@@ -19,6 +19,7 @@
  *   TIOCSPGRP
  */
 
+#include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <asm/errno.h>
 #include <asm/ioctl.h>
@@ -54,10 +55,6 @@
 	case 't':
 		result = hpux_ioctl_t(fd, cmd, arg);
 		break;
-	default:
-		/* If my mother ever sees this, I hope she disowns me.
-		 * Take this out after NYLWE. */
-		result = sys_ioctl(fd, cmd, arg);
 	}
 	return result;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/sys_hpux.c linux-2.4.20/arch/parisc/hpux/sys_hpux.c
--- linux-2.4.19/arch/parisc/hpux/sys_hpux.c	2001-08-09 23:41:36.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/sys_hpux.c	2002-10-04 00:41:21.000000000 +0000
@@ -9,6 +9,9 @@
 #include <linux/utsname.h>
 #include <asm/errno.h>
 #include <asm/uaccess.h>
+#include <linux/vmalloc.h>
+#include <asm/pgalloc.h>
+#include <linux/slab.h>
 
 unsigned long sys_brk(unsigned long addr);
  
@@ -41,6 +44,17 @@
 	return sys_waitpid(-1, stat_loc, 0);
 }
 
+int hpux_setpgrp(void)
+{
+	extern int sys_setpgid(int, int);
+	return sys_setpgid(0,0);
+}
+
+int hpux_setpgrp3(void)
+{
+	return hpux_setpgrp();
+}
+
 #define _SC_CPU_VERSION	10001
 #define _SC_OPEN_MAX	4
 #define CPU_PA_RISC1_1	0x210
@@ -129,6 +143,66 @@
 	return err;
 }
 
+/*
+ * Wrapper for hpux statfs call. At the moment, just calls the linux native one
+ * and ignores the extra fields at the end of the hpux statfs struct.
+ *
+ */
+
+typedef int32_t hpux_fsid_t[2];              /* file system ID type */
+typedef uint16_t hpux_site_t;
+
+struct hpux_statfs {
+     int32_t f_type;                    /* type of info, zero for now */
+     int32_t f_bsize;                   /* fundamental file system block size */
+     int32_t f_blocks;                  /* total blocks in file system */
+     int32_t f_bfree;                   /* free block in fs */
+     int32_t f_bavail;                  /* free blocks avail to non-superuser */
+     int32_t f_files;                   /* total file nodes in file system */
+     int32_t f_ffree;                   /* free file nodes in fs */
+     hpux_fsid_t  f_fsid;                    /* file system ID */
+     int32_t f_magic;                   /* file system magic number */
+     int32_t f_featurebits;             /* file system features */
+     int32_t f_spare[4];                /* spare for later */
+     hpux_site_t  f_cnode;                   /* cluster node where mounted */
+     int16_t f_pad;
+};
+
+/* hpux statfs */
+int hpux_statfs(const char *path, struct hpux_statfs *buf)
+{
+	int error;
+	int len;
+	char *kpath;
+
+	len = strlen_user((char *)path); 
+
+	kpath = (char *) kmalloc(len+1, GFP_KERNEL);
+	if ( !kpath ) {
+	printk(KERN_DEBUG "failed to kmalloc kpath\n");
+	return 0;
+	}
+
+	if ( copy_from_user(kpath, (char *)path, len+1) ) {
+	printk(KERN_DEBUG "failed to copy_from_user kpath\n");
+	kfree(kpath);
+	return 0;
+	}
+
+	printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);
+
+	kfree(kpath);
+
+	/* just fake it, beginning of structures match */
+	extern int sys_statfs(const char *, struct statfs *);
+	error = sys_statfs(path, (struct statfs *) buf);
+
+	/* ignoring rest of statfs struct, but it should be zeros. Need to do 
+		something with f_fsid[1], which is the fstype for sysfs */
+
+	return error;
+}
+
 
 /*  This function is called from hpux_utssys(); HP-UX implements
  *  uname() as an option to utssys().
@@ -333,3 +407,541 @@
 	unlock_kernel();
 	return error;
 }
+
+/* lies - says it works, but it really didn't lock anything */
+int hpux_lockf(int fildes, int function, off_t size)
+{
+	return 0;
+}
+
+int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
+{
+	char *fsname = NULL;
+	int len = 0;
+	int fstype;
+
+/*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
+  Args: 1 80057bf4 0 400179f0 0 0 0 */
+	printk(KERN_DEBUG "in hpux_sysfs\n");
+	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
+	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
+
+	if ( opcode == 1 ) { /* GETFSIND */	
+		len = strlen_user((char *)arg1);
+		printk(KERN_DEBUG "len of arg1 = %d\n", len);
+
+		fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+		if ( !fsname ) {
+			printk(KERN_DEBUG "failed to kmalloc fsname\n");
+			return 0;
+		}
+
+		if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
+			kfree(fsname);
+			return 0;
+		}
+
+		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
+		if ( !strcmp(fsname, "hfs") ) {
+			fstype = 0;
+		} else {
+			fstype = 0;
+		};
+
+		kfree(fsname);
+
+		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
+		return fstype; /* something other than default */
+	}
+
+
+	return 0;
+}
+
+
+/* Table of syscall names and handle for unimplemented routines */
+static const char *syscall_names[] = {
+	"nosys",                  /* 0 */
+	"exit",                  
+	"fork",                  
+	"read",                  
+	"write",                 
+	"open",                   /* 5 */
+	"close",                 
+	"wait",                  
+	"creat",                 
+	"link",                  
+	"unlink",                 /* 10 */
+	"execv",                 
+	"chdir",                 
+	"time",                  
+	"mknod",                 
+	"chmod",                  /* 15 */
+	"chown",                 
+	"brk",                   
+	"lchmod",                
+	"lseek",                 
+	"getpid",                 /* 20 */
+	"mount",                 
+	"umount",                
+	"setuid",                
+	"getuid",                
+	"stime",                  /* 25 */
+	"ptrace",                
+	"alarm",                 
+	NULL,                    
+	"pause",                 
+	"utime",                  /* 30 */
+	"stty",                  
+	"gtty",                  
+	"access",                
+	"nice",                  
+	"ftime",                  /* 35 */
+	"sync",                  
+	"kill",                  
+	"stat",                  
+	"setpgrp3",              
+	"lstat",                  /* 40 */
+	"dup",                   
+	"pipe",                  
+	"times",                 
+	"profil",                
+	"ki_call",                /* 45 */
+	"setgid",                
+	"getgid",                
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 50 */
+	"acct",                  
+	"set_userthreadid",      
+	NULL,                    
+	"ioctl",                 
+	"reboot",                 /* 55 */
+	"symlink",               
+	"utssys",                
+	"readlink",              
+	"execve",                
+	"umask",                  /* 60 */
+	"chroot",                
+	"fcntl",                 
+	"ulimit",                
+	NULL,                    
+	NULL,                     /* 65 */
+	"vfork",                 
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 70 */
+	"mmap",                  
+	NULL,                    
+	"munmap",                
+	"mprotect",              
+	"madvise",                /* 75 */
+	"vhangup",               
+	"swapoff",               
+	NULL,                    
+	"getgroups",             
+	"setgroups",              /* 80 */
+	"getpgrp2",              
+	"setpgid/setpgrp2",      
+	"setitimer",             
+	"wait3",                 
+	"swapon",                 /* 85 */
+	"getitimer",             
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"dup2",                   /* 90 */
+	NULL,                    
+	"fstat",                 
+	"select",                
+	NULL,                    
+	"fsync",                  /* 95 */
+	"setpriority",           
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"getpriority",            /* 100 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 105 */
+	NULL,                    
+	NULL,                    
+	"sigvector",             
+	"sigblock",              
+	"sigsetmask",             /* 110 */
+	"sigpause",              
+	"sigstack",              
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 115 */
+	"gettimeofday",          
+	"getrusage",             
+	NULL,                    
+	NULL,                    
+	"readv",                  /* 120 */
+	"writev",                
+	"settimeofday",          
+	"fchown",                
+	"fchmod",                
+	NULL,                     /* 125 */
+	"setresuid",             
+	"setresgid",             
+	"rename",                
+	"truncate",              
+	"ftruncate",              /* 130 */
+	NULL,                    
+	"sysconf",               
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 135 */
+	"mkdir",                 
+	"rmdir",                 
+	NULL,                    
+	"sigcleanup",            
+	"setcore",                /* 140 */
+	NULL,                    
+	"gethostid",             
+	"sethostid",             
+	"getrlimit",             
+	"setrlimit",              /* 145 */
+	NULL,                    
+	NULL,                    
+	"quotactl",              
+	"get_sysinfo",           
+	NULL,                     /* 150 */
+	"privgrp",               
+	"rtprio",                
+	"plock",                 
+	NULL,                    
+	"lockf",                  /* 155 */
+	"semget",                
+	NULL,                    
+	"semop",                 
+	"msgget",                
+	NULL,                     /* 160 */
+	"msgsnd",                
+	"msgrcv",                
+	"shmget",                
+	NULL,                    
+	"shmat",                  /* 165 */
+	"shmdt",                 
+	NULL,                    
+	"csp/nsp_init",          
+	"cluster",               
+	"mkrnod",                 /* 170 */
+	"test",                  
+	"unsp_open",             
+	NULL,                    
+	"getcontext",            
+	"osetcontext",            /* 175 */
+	"bigio",                 
+	"pipenode",              
+	"lsync",                 
+	"getmachineid",          
+	"cnodeid/mysite",         /* 180 */
+	"cnodes/sitels",         
+	"swapclients",           
+	"rmtprocess",            
+	"dskless_stats",         
+	"sigprocmask",            /* 185 */
+	"sigpending",            
+	"sigsuspend",            
+	"sigaction",             
+	NULL,                    
+	"nfssvc",                 /* 190 */
+	"getfh",                 
+	"getdomainname",         
+	"setdomainname",         
+	"async_daemon",          
+	"getdirentries",          /* 195 */
+	"statfs",                
+	"fstatfs",               
+	"vfsmount",              
+	NULL,                    
+	"waitpid",                /* 200 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 205 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 210 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 215 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 220 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"sigsetreturn",          
+	"sigsetstatemask",        /* 225 */
+	"bfactl",                
+	"cs",                    
+	"cds",                   
+	NULL,                    
+	"pathconf",               /* 230 */
+	"fpathconf",             
+	NULL,                    
+	NULL,                    
+	"nfs_fcntl",             
+	"ogetacl",                /* 235 */
+	"ofgetacl",              
+	"osetacl",               
+	"ofsetacl",              
+	"pstat",                 
+	"getaudid",               /* 240 */
+	"setaudid",              
+	"getaudproc",            
+	"setaudproc",            
+	"getevent",              
+	"setevent",               /* 245 */
+	"audwrite",              
+	"audswitch",             
+	"audctl",                
+	"ogetaccess",            
+	"fsctl",                  /* 250 */
+	"ulconnect",             
+	"ulcontrol",             
+	"ulcreate",              
+	"uldest",                
+	"ulrecv",                 /* 255 */
+	"ulrecvcn",              
+	"ulsend",                
+	"ulshutdown",            
+	"swapfs",                
+	"fss",                    /* 260 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 265 */
+	NULL,                    
+	"tsync",                 
+	"getnumfds",             
+	"poll",                  
+	"getmsg",                 /* 270 */
+	"putmsg",                
+	"fchdir",                
+	"getmount_cnt",          
+	"getmount_entry",        
+	"accept",                 /* 275 */
+	"bind",                  
+	"connect",               
+	"getpeername",           
+	"getsockname",           
+	"getsockopt",             /* 280 */
+	"listen",                
+	"recv",                  
+	"recvfrom",              
+	"recvmsg",               
+	"send",                   /* 285 */
+	"sendmsg",               
+	"sendto",                
+	"setsockopt",            
+	"shutdown",              
+	"socket",                 /* 290 */
+	"socketpair",            
+	"proc_open",             
+	"proc_close",            
+	"proc_send",             
+	"proc_recv",              /* 295 */
+	"proc_sendrecv",         
+	"proc_syscall",          
+	"ipccreate",             
+	"ipcname",               
+	"ipcnamerase",            /* 300 */
+	"ipclookup",             
+	"ipcselect",             
+	"ipcconnect",            
+	"ipcrecvcn",             
+	"ipcsend",                /* 305 */
+	"ipcrecv",               
+	"ipcgetnodename",        
+	"ipcsetnodename",        
+	"ipccontrol",            
+	"ipcshutdown",            /* 310 */
+	"ipcdest",               
+	"semctl",                
+	"msgctl",                
+	"shmctl",                
+	"mpctl",                  /* 315 */
+	"exportfs",              
+	"getpmsg",               
+	"putpmsg",               
+	"strioctl",              
+	"msync",                  /* 320 */
+	"msleep",                
+	"mwakeup",               
+	"msem_init",             
+	"msem_remove",           
+	"adjtime",                /* 325 */
+	"kload",                 
+	"fattach",               
+	"fdetach",               
+	"serialize",             
+	"statvfs",                /* 330 */
+	"fstatvfs",              
+	"lchown",                
+	"getsid",                
+	"sysfs",                 
+	NULL,                     /* 335 */
+	NULL,                    
+	"sched_setparam",        
+	"sched_getparam",        
+	"sched_setscheduler",    
+	"sched_getscheduler",     /* 340 */
+	"sched_yield",           
+	"sched_get_priority_max",
+	"sched_get_priority_min",
+	"sched_rr_get_interval", 
+	"clock_settime",          /* 345 */
+	"clock_gettime",         
+	"clock_getres",          
+	"timer_create",          
+	"timer_delete",          
+	"timer_settime",          /* 350 */
+	"timer_gettime",         
+	"timer_getoverrun",      
+	"nanosleep",             
+	"toolbox",               
+	NULL,                     /* 355 */
+	"getdents",              
+	"getcontext",            
+	"sysinfo",               
+	"fcntl64",               
+	"ftruncate64",            /* 360 */
+	"fstat64",               
+	"getdirentries64",       
+	"getrlimit64",           
+	"lockf64",               
+	"lseek64",                /* 365 */
+	"lstat64",               
+	"mmap64",                
+	"setrlimit64",           
+	"stat64",                
+	"truncate64",             /* 370 */
+	"ulimit64",              
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                     /* 375 */
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	NULL,                    
+	"setcontext",             /* 380 */
+	"sigaltstack",           
+	"waitid",                
+	"setpgrp",               
+	"recvmsg2",              
+	"sendmsg2",               /* 385 */
+	"socket2",               
+	"socketpair2",           
+	"setregid",              
+	"lwp_create",            
+	"lwp_terminate",          /* 390 */
+	"lwp_wait",              
+	"lwp_suspend",           
+	"lwp_resume",            
+	"lwp_self",              
+	"lwp_abort_syscall",      /* 395 */
+	"lwp_info",              
+	"lwp_kill",              
+	"ksleep",                
+	"kwakeup",               
+	"ksleep_abort",           /* 400 */
+	"lwp_proc_info",         
+	"lwp_exit",              
+	"lwp_continue",          
+	"getacl",                
+	"fgetacl",                /* 405 */
+	"setacl",                
+	"fsetacl",               
+	"getaccess",             
+	"lwp_mutex_init",        
+	"lwp_mutex_lock_sys",     /* 410 */
+	"lwp_mutex_unlock",      
+	"lwp_cond_init",         
+	"lwp_cond_signal",       
+	"lwp_cond_broadcast",    
+	"lwp_cond_wait_sys",      /* 415 */
+	"lwp_getscheduler",      
+	"lwp_setscheduler",      
+	"lwp_getprivate",        
+	"lwp_setprivate",        
+	"lwp_detach",             /* 420 */
+	"mlock",                 
+	"munlock",               
+	"mlockall",              
+	"munlockall",            
+	"shm_open",               /* 425 */
+	"shm_unlink",            
+	"sigqueue",              
+	"sigwaitinfo",           
+	"sigtimedwait",          
+	"sigwait",                /* 430 */
+	"aio_read",              
+	"aio_write",             
+	"lio_listio",            
+	"aio_error",             
+	"aio_return",             /* 435 */
+	"aio_cancel",            
+	"aio_suspend",           
+	"aio_fsync",             
+	"mq_open",               
+	"mq_unlink",              /* 440 */
+	"mq_send",               
+	"mq_receive",            
+	"mq_notify",             
+	"mq_setattr",            
+	"mq_getattr",             /* 445 */
+	"ksem_open",             
+	"ksem_unlink",           
+	"ksem_close",            
+	"ksem_destroy",          
+	"lw_sem_incr",            /* 450 */
+	"lw_sem_decr",           
+	"lw_sem_read",           
+	"mq_close",              
+};
+static const int syscall_names_max = 453;
+
+int
+hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,
+		   unsigned long arg4,unsigned long arg5,unsigned long arg6,
+		   unsigned long arg7,unsigned long sc_num)
+{
+	/* NOTE: sc_num trashes arg8 for the few syscalls that actually
+	 * have a valid 8th argument.
+	 */
+	const char *name = NULL;
+	if ( sc_num <= syscall_names_max && sc_num >= 0 ) {
+		name = syscall_names[sc_num];
+	}
+
+	if ( name ) {
+		printk(KERN_DEBUG "Unimplemented HP-UX syscall emulation. Syscall #%lu (%s)\n",
+		sc_num, name);
+	} else {
+		printk(KERN_DEBUG "Unimplemented unknown HP-UX syscall emulation. Syscall #%lu\n",
+		sc_num);
+	}
+	
+	printk(KERN_DEBUG "  Args: %lx %lx %lx %lx %lx %lx %lx\n",
+		arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+
+	return -ENOSYS;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/hpux/wrappers.S linux-2.4.20/arch/parisc/hpux/wrappers.S
--- linux-2.4.19/arch/parisc/hpux/wrappers.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/hpux/wrappers.S	2002-10-04 00:41:15.000000000 +0000
@@ -1,5 +1,5 @@
-/*------------------------------------------------------------------------------
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+/*
+ * Linux/PARISC Project (http://www.parisc-linux.org/)
  *
  * HP-UX System Call Wrapper routines and System Call Return Path
  *
@@ -29,7 +29,6 @@
 	.level		1.1
 	.text
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/signal.h>
 
@@ -81,6 +80,7 @@
 
 
 	.export hpux_fork_wrapper
+	.export hpux_child_return
 	.import sys_fork
 
 hpux_fork_wrapper:
@@ -91,12 +91,10 @@
 	stw	%r2,-20(%r30)
 	ldo	64(%r30),%r30
 	stw	%r2,PT_GR19(%r1)	;! save for child
-	stw	%r30,PT_GR20(%r1)	;! save for child
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	stw	%r3,PT_GR21(%r1)	;! save for child
+	stw	%r30,PT_GR21(%r1)	;! save for child
 
-	ldw	TASK_PT_GR30(%r1),%r25
+	ldw     PT_GR30(%r1),%r25
+	mtctl   %r25,%cr29
 	copy	%r1,%r24
 	bl	sys_clone,%r2
 	ldi	SIGCHLD,%r26
@@ -130,7 +128,10 @@
 
 	/* Set the return value for the child */
 
-child_return:
+hpux_child_return:
+	bl	schedule_tail, %r2
+	nop
+
 	ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
 	b fork_return
 	copy %r0,%r28
@@ -242,3 +243,10 @@
 no_error:
 	b syscall_exit
 	nop
+
+	.export hpux_unimplemented_wrapper
+	.import hpux_unimplemented
+
+hpux_unimplemented_wrapper:
+	b hpux_unimplemented
+	stw %r22,-64(%r30)  /* overwrite arg8 with syscall number */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/Makefile linux-2.4.20/arch/parisc/kernel/Makefile
--- linux-2.4.19/arch/parisc/kernel/Makefile	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/Makefile	2002-10-04 00:41:15.000000000 +0000
@@ -7,26 +7,30 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-all: kernel.o init_task.o pdc_cons.o process.o head.o
-O_TARGET = kernel.o
-O_OBJS = 
+ifdef CONFIG_PARISC64
+all: kernel.o init_task.o pdc_cons.o process.o head64.o unaligned.o perf.o perf_asm.o
+else
+all: kernel.o init_task.o pdc_cons.o process.o head.o unaligned.o
+endif
 
-# Object file lists.
+O_TARGET = kernel.o
 
 obj-y		:=
 obj-m		:=
 obj-n		:=
 obj-		:=
 
-obj-y		+= cache.o setup.o traps.o time.o irq.o \
-		syscall.o entry.o sys_parisc.o pdc.o ptrace.o hardware.o \
-		inventory.o drivers.o semaphore.o pa7300lc.o pci-dma.o \
-		signal.o hpmc.o \
-		real1.o real2.o led.o parisc_ksyms.o
+obj-y           += cache.o pacache.o setup.o traps.o time.o irq.o \
+		pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
+		ptrace.o hardware.o inventory.o drivers.o semaphore.o \
+		signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
+		processor.o power.o
 
-export-objs	:= parisc_ksyms.o
+export-objs	:= parisc_ksyms.o superio.o keyboard.o
 
 
+obj-$(CONFIG_SMP) += smp.o irq_smp.o
+obj-$(CONFIG_PA11) += pci-dma.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_VT) += keyboard.o
 obj-$(CONFIG_PCI_LBA) += lba_pci.o
@@ -37,16 +41,11 @@
 # Only use one of them: ccio-rm-dma is for PCX-W systems *only*
 # obj-$(CONFIG_IOMMU_CCIO) += ccio-rm-dma.o
 obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o
-
-.o.S:	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
-
-# Translate to Rules.make lists.
-
-O_OBJS          := $(filter-out $(export-objs), $(obj-y))
-OX_OBJS         := $(filter     $(export-objs), $(obj-y))
-M_OBJS          := $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS         := $(sort $(filter     $(export-objs), $(obj-m)))
-MI_OBJS		:= $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS	:= $(sort $(filter     $(export-objs), $(int-m)))
+obj-$(CONFIG_CHASSIS_LCD_LED) += led.o 
+obj-$(CONFIG_SUPERIO) += superio.o
+obj-$(CONFIG_PARISC64) += binfmt_elf32.o sys_parisc32.o \
+		ioctl32.o signal32.o
+# only supported for PCX-W/U in 64-bit mode at the moment
+obj-$(CONFIG_PARISC64) += perf.o perf_asm.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/binfmt_elf32.c linux-2.4.20/arch/parisc/kernel/binfmt_elf32.c
--- linux-2.4.19/arch/parisc/kernel/binfmt_elf32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/binfmt_elf32.c	2002-10-04 00:41:21.000000000 +0000
@@ -0,0 +1,93 @@
+/*
+ * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
+ *
+ * Copyright (C) 2000 John Marvin
+ * Copyright (C) 2000 Hewlett Packard Co.
+ *
+ * Heavily inspired from various other efforts to do the same thing
+ * (ia64,sparc64/mips64)
+ */
+
+/* Make sure include/asm-parisc/elf.h does the right thing */
+
+#define ELF_CLASS	ELFCLASS32
+
+typedef unsigned int elf_greg_t;
+
+#include <linux/spinlock.h>
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/elfcore.h>
+#include "sys32.h"		/* struct timeval32 */
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+	struct elf_siginfo pr_info;	/* Info associated with signal */
+	short	pr_cursig;		/* Current signal */
+	unsigned int pr_sigpend;	/* Set of pending signals */
+	unsigned int pr_sighold;	/* Set of held signals */
+	pid_t	pr_pid;
+	pid_t	pr_ppid;
+	pid_t	pr_pgrp;
+	pid_t	pr_sid;
+	struct timeval32 pr_utime;	/* User time */
+	struct timeval32 pr_stime;	/* System time */
+	struct timeval32 pr_cutime;	/* Cumulative user time */
+	struct timeval32 pr_cstime;	/* Cumulative system time */
+	elf_gregset_t pr_reg;	/* GP registers */
+	int pr_fpvalid;		/* True if math co-processor being used.  */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+	char	pr_state;	/* numeric process state */
+	char	pr_sname;	/* char for pr_state */
+	char	pr_zomb;	/* zombie */
+	char	pr_nice;	/* nice val */
+	unsigned int pr_flag;	/* flags */
+	u16	pr_uid;
+	u16	pr_gid;
+	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	/* Lots missing */
+	char	pr_fname[16];	/* filename of executable */
+	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
+};
+
+#define elf_addr_t	unsigned int
+typedef unsigned int elf_caddr_t;
+#define init_elf_binfmt init_elf32_binfmt
+
+#define ELF_PLATFORM  ("PARISC32\0")
+
+#define ELF_CORE_COPY_REGS(dst, pt)	\
+	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */ \
+	{	int i; \
+		for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
+		for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
+	} \
+	dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
+	dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
+	dst[44] = (elf_greg_t) pt->sar;   dst[45] = (elf_greg_t) pt->iir; \
+	dst[46] = (elf_greg_t) pt->isr;   dst[47] = (elf_greg_t) pt->ior; \
+	dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
+	dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
+	dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
+	dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
+	dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
+	dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
+	dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
+	dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
+
+/*
+ * We should probably use this macro to set a flag somewhere to indicate
+ * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
+ * could set a processor dependent flag in the thread_struct.
+ */
+
+#define SET_PERSONALITY(ex, ibcs2) \
+	current->personality = PER_LINUX_32BIT
+
+#include "../../../fs/binfmt_elf.c"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/cache.c linux-2.4.20/arch/parisc/kernel/cache.c
--- linux-2.4.19/arch/parisc/kernel/cache.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/cache.c	2002-10-04 00:41:17.000000000 +0000
@@ -15,202 +15,85 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 
 #include <asm/pdc.h>
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
+#include <asm/processor.h>
+
+int split_tlb;
+int dcache_stride;
+int icache_stride;
 
 struct pdc_cache_info cache_info;
-#ifndef __LP64__
+#ifndef CONFIG_PA20
 static struct pdc_btlb_info btlb_info;
 #endif
 
-
-void __flush_page_to_ram(unsigned long address)
-{
-	__flush_dcache_range(address, PAGE_SIZE);
-	__flush_icache_range(address, PAGE_SIZE);
-}
-
-
-
-void flush_data_cache(void)
+#ifdef CONFIG_SMP
+void
+flush_data_cache(void)
 {
-	register unsigned long base   = cache_info.dc_base;
-	register unsigned long count  = cache_info.dc_count;
-	register unsigned long loop   = cache_info.dc_loop;
-	register unsigned long stride = cache_info.dc_stride;
-	register unsigned long addr;
-	register long i, j;
-
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			fdce(addr);
-}
-		
-static inline void flush_data_tlb_space(void)
-{
-	unsigned long base   = cache_info.dt_off_base;
-	unsigned long count  = cache_info.dt_off_count;
-	unsigned long stride = cache_info.dt_off_stride;
-	unsigned long loop   = cache_info.dt_loop;
-
-	unsigned long addr;
-	long i,j;
-	
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			pdtlbe(addr);
-}
-
-
-
-void flush_data_tlb(void)
-{
-	unsigned long base   = cache_info.dt_sp_base;
-	unsigned long count  = cache_info.dt_sp_count;
-	unsigned long stride = cache_info.dt_sp_stride;
-	unsigned long space;
-	unsigned long old_sr1;
-	long i;
-	
-	old_sr1 = mfsp(1);
-	
-	for(i=0,space=base; i<count; i++, space+=stride) {
-		mtsp(space,1);
-		flush_data_tlb_space();
-	}
-
-	mtsp(old_sr1, 1);
+	smp_call_function((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
+	flush_data_cache_local();
 }
+#endif
 
-static inline void flush_instruction_tlb_space(void)
+void
+flush_cache_all_local(void)
 {
-	unsigned long base   = cache_info.it_off_base;
-	unsigned long count  = cache_info.it_off_count;
-	unsigned long stride = cache_info.it_off_stride;
-	unsigned long loop   = cache_info.it_loop;
-
-	unsigned long addr;
-	long i,j;
-	
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			pitlbe(addr);
-}
-
-void flush_instruction_tlb(void)
-{
-	unsigned long base   = cache_info.it_sp_base;
-	unsigned long count  = cache_info.it_sp_count;
-	unsigned long stride = cache_info.it_sp_stride;
-	unsigned long space;
-	unsigned long old_sr1;
-	unsigned int i;
-	
-	old_sr1 = mfsp(1);
-	
-	for(i=0,space=base; i<count; i++, space+=stride) {
-		mtsp(space,1);
-		flush_instruction_tlb_space();
-	}
-
-	mtsp(old_sr1, 1);
+	flush_instruction_cache_local();
+	flush_data_cache_local();
 }
 
+/* flushes EVERYTHING (tlb & cache) */
 
-void __flush_tlb_space(unsigned long space)
+void
+flush_all_caches(void)
 {
-	unsigned long old_sr1;
-
-	old_sr1 = mfsp(1);
-	mtsp(space, 1);
-	
-	flush_data_tlb_space();
-	flush_instruction_tlb_space();
-
-	mtsp(old_sr1, 1);
+	flush_cache_all();
+	flush_tlb_all();
 }
 
-
-void flush_instruction_cache(void)
+void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	register unsigned long base   = cache_info.ic_base;
-	register unsigned long count  = cache_info.ic_count;
-	register unsigned long loop   = cache_info.ic_loop;
-	register unsigned long stride = cache_info.ic_stride;
-	register unsigned long addr;
-	register long i, j;
-	unsigned long old_sr1;
-	
-	old_sr1 = mfsp(1);
-	mtsp(0,1);
+	struct page *page = pte_page(pte);
 
-	/*
-	 * Note: fice instruction has 3 bit space field, so one must
-	 *       be specified (otherwise you are justing using whatever
-	 *       happens to be in sr0).
-	 */
+	if (VALID_PAGE(page) && page->mapping &&
+	    test_bit(PG_dcache_dirty, &page->flags)) {
 
-	for(i=0,addr=base; i<count; i++,addr+=stride)
-		for(j=0; j<loop; j++)
-			fice(addr);
-
-	mtsp(old_sr1, 1);
-}
-
-/* not yet ... fdc() needs to be implemented in cache.h !
-void flush_datacache_range( unsigned int base, unsigned int end )
-{
-    register long offset,offset_add;
-    offset_add = ( (1<<(cache_info.dc_conf.cc_block-1)) * 
-		    cache_info.dc_conf.cc_line ) << 4;
-    for (offset=base; offset<=end; offset+=offset_add)
-	fdc(space,offset);
-    fdc(space,end);
-}
-*/
-
-/* flushes code and data-cache */
-void flush_all_caches(void)
-{
-	flush_instruction_cache();
-	flush_data_cache();
-
-	flush_instruction_tlb();
-	flush_data_tlb();
-
-	asm volatile("sync");
-	asm volatile("syncdma");
-	asm volatile("sync");
+		flush_kernel_dcache_page(page_address(page));
+		clear_bit(PG_dcache_dirty, &page->flags);
+	}
 }
 
-int get_cache_info(char *buffer)
+void
+show_cache_info(struct seq_file *m)
 {
-	char *p = buffer;
-
-	p += sprintf(p, "I-cache\t\t: %ld KB\n", 
+	seq_printf(m, "I-cache\t\t: %ld KB\n", 
 		cache_info.ic_size/1024 );
-	p += sprintf(p, "D-cache\t\t: %ld KB (%s)%s\n", 
+	seq_printf(m, "D-cache\t\t: %ld KB (%s)%s\n", 
 		cache_info.dc_size/1024,
 		(cache_info.dc_conf.cc_wt ? "WT":"WB"),
 		(cache_info.dc_conf.cc_sh ? " - shared I/D":"")
 	);
 
-	p += sprintf(p, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
+	seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
 		cache_info.it_size,
 		cache_info.dt_size,
 		cache_info.dt_conf.tc_sh ? " - shared with ITLB":""
 	);
 		
-#ifndef __LP64__
+#ifndef CONFIG_PA20
 	/* BTLB - Block TLB */
 	if (btlb_info.max_size==0) {
-		p += sprintf(p, "BTLB\t\t: not supported\n" );
+		seq_printf(m, "BTLB\t\t: not supported\n" );
 	} else {
-		p += sprintf(p, 
+		seq_printf(m, 
 		"BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
 		"BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
 		"BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
@@ -225,11 +108,8 @@
 		);
 	}
 #endif
-
-	return p - buffer;
 }
 
-
 void __init 
 cache_init(void)
 {
@@ -237,17 +117,108 @@
 		panic("cache_init: pdc_cache_info failed");
 
 #if 0
-	printk("ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
+	printk(KERN_DEBUG "ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
 	    cache_info.ic_size,
 	    cache_info.dc_size,
 	    cache_info.it_size,
 	    sizeof (struct pdc_cache_info) / sizeof (long),
 	    sizeof (struct pdc_cache_cf)
 	);
+
+	printk(KERN_DEBUG "dc base %x dc stride %x dc count %x dc loop %d\n",
+	    cache_info.dc_base,
+	    cache_info.dc_stride,
+	    cache_info.dc_count,
+	    cache_info.dc_loop);
+
+	printk(KERN_DEBUG "dc conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
+	    cache_info.dc_conf.cc_alias,
+	    cache_info.dc_conf.cc_block,
+	    cache_info.dc_conf.cc_line,
+	    cache_info.dc_conf.cc_wt,
+	    cache_info.dc_conf.cc_sh,
+	    cache_info.dc_conf.cc_cst,
+	    cache_info.dc_conf.cc_assoc);
+
+	printk(KERN_DEBUG "ic conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
+	    cache_info.ic_conf.cc_alias,
+	    cache_info.ic_conf.cc_block,
+	    cache_info.ic_conf.cc_line,
+	    cache_info.ic_conf.cc_wt,
+	    cache_info.ic_conf.cc_sh,
+	    cache_info.ic_conf.cc_cst,
+	    cache_info.ic_conf.cc_assoc);
+
+	printk(KERN_DEBUG "dt conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	    cache_info.dt_conf.tc_sh,
+	    cache_info.dt_conf.tc_page,
+	    cache_info.dt_conf.tc_cst,
+	    cache_info.dt_conf.tc_aid,
+	    cache_info.dt_conf.tc_pad1);
+
+	printk(KERN_DEBUG "it conf: sh %d page %d cst %d aid %d pad1 %d \n",
+	    cache_info.it_conf.tc_sh,
+	    cache_info.it_conf.tc_page,
+	    cache_info.it_conf.tc_cst,
+	    cache_info.it_conf.tc_aid,
+	    cache_info.it_conf.tc_pad1);
 #endif
-#ifndef __LP64__
+
+	split_tlb = 0;
+	if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
+
+	    if (cache_info.dt_conf.tc_sh == 2)
+		printk(KERN_WARNING "Unexpected TLB configuration. "
+			"Will flush I/D separately (could be optimized).\n");
+
+	    split_tlb = 1;
+	}
+
+	dcache_stride = ( (1<<(cache_info.dc_conf.cc_block+3)) *
+			 cache_info.dc_conf.cc_line );
+	icache_stride = ( (1<<(cache_info.ic_conf.cc_block+3)) *
+			 cache_info.ic_conf.cc_line );
+#ifndef CONFIG_PA20
 	if(pdc_btlb_info(&btlb_info)<0) {
 		memset(&btlb_info, 0, sizeof btlb_info);
 	}
 #endif
+
+	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == PDC_MODEL_NVA_UNSUPPORTED) {
+		printk(KERN_WARNING "Only equivalent aliasing supported\n");
+#ifndef CONFIG_SMP
+		panic("SMP kernel required to avoid non-equivalent aliasing");
+#endif
+	}
+}
+
+void disable_sr_hashing(void)
+{
+    int srhash_type;
+
+    if (boot_cpu_data.cpu_type == pcxl2)
+	return; /* pcxl2 doesn't support space register hashing */
+
+    switch (boot_cpu_data.cpu_type) {
+
+    case pcx:
+	BUG(); /* We shouldn't get here. code in setup.c should prevent it */
+	return;
+
+    case pcxs:
+    case pcxt:
+    case pcxt_:
+	srhash_type = SRHASH_PCXST;
+	break;
+
+    case pcxl:
+	srhash_type = SRHASH_PCXL;
+	break;
+
+    default: /* Currently all PA2.0 machines use the same ins. sequence */
+	srhash_type = SRHASH_PA20;
+	break;
+    }
+
+    disable_sr_hashing_asm(srhash_type);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ccio-dma.c linux-2.4.20/arch/parisc/kernel/ccio-dma.c
--- linux-2.4.19/arch/parisc/kernel/ccio-dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/ccio-dma.c	2002-10-04 00:41:12.000000000 +0000
@@ -38,16 +38,19 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#define PCI_DEBUG
 #include <linux/pci.h>
+#undef PCI_DEBUG
 
 #include <asm/byteorder.h>
 #include <asm/cache.h>		/* for L1_CACHE_BYTES */
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
-
+#include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/gsc.h>		/* for gsc_writeN()... */
+#include <asm/hardware.h>       /* for register_module() */
 
 /* 
 ** Choose "ccio" since that's what HP-UX calls it.
@@ -55,12 +58,10 @@
 */
 #define MODULE_NAME "ccio"
 
-/*
-#define DEBUG_CCIO_RES
-#define DEBUG_CCIO_RUN
-#define DEBUG_CCIO_INIT
-#define DUMP_RESMAP
-*/
+#undef DEBUG_CCIO_RES
+#undef DEBUG_CCIO_RUN
+#undef DEBUG_CCIO_INIT
+#undef DEBUG_CCIO_RUN_SG
 
 #include <linux/proc_fs.h>
 #include <asm/runway.h>		/* for proc_runway_root */
@@ -83,68 +84,20 @@
 #define DBG_RES(x...)
 #endif
 
+#ifdef DEBUG_CCIO_RUN_SG
+#define DBG_RUN_SG(x...) printk(x)
+#else
+#define DBG_RUN_SG(x...)
+#endif
+
 #define CCIO_INLINE	/* inline */
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
+#define WRITE_U32(value, addr) gsc_writel(value, (u32 *)(addr))
+#define READ_U32(addr) gsc_readl((u32 *)(addr))
 
 #define U2_IOA_RUNWAY 0x580
 #define U2_BC_GSC     0x501
 #define UTURN_IOA_RUNWAY 0x581
 #define UTURN_BC_GSC     0x502
-/* We *can't* support JAVA (T600). Venture there at your own risk. */
-
-static void dump_resmap(void);
-
-static int ccio_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver ccio_drivers_for[] = {
-
-   {HPHW_IOA, U2_IOA_RUNWAY, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 I/O MMU", (void *) ccio_driver_callback},
-
-   {HPHW_IOA, UTURN_IOA_RUNWAY, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn I/O MMU", (void *) ccio_driver_callback},
-
-/*
-** FIXME: The following claims the GSC bus port, not the IOA.
-**        And there are two busses below a single I/O TLB.
-**
-** These should go away once we have a real PA bus walk.
-** Firmware wants to tell the PA bus walk code about the GSC ports
-** since they are not "architected" PA I/O devices. Ie a PA bus walk
-** wouldn't discover them. But the PA bus walk code could check
-** the "fixed module table" to add such devices to an I/O Tree
-** and proceed with the recursive, depth first bus walk.
-*/
-   {HPHW_BCPORT, U2_BC_GSC, 0x0, 0xc, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 GSC+ BC", (void *) ccio_driver_callback},
-
-   {HPHW_BCPORT, UTURN_BC_GSC, 0x0, 0xc, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn GSC+ BC", (void *) ccio_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
-
-
-#define IS_U2(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC))  \
-)
-
-#define IS_UTURN(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == UTURN_IOA_RUNWAY)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC))  \
-)
-
 
 #define IOA_NORMAL_MODE      0x00020080 /* IO_CONTROL to turn on CCIO        */
 #define CMD_TLB_DIRECT_WRITE 35         /* IO_COMMAND for I/O TLB Writes     */
@@ -176,41 +129,46 @@
         volatile uint32_t   io_io_high;             /* Offset 15 */
 };
 
+struct ioc {
+	struct ioa_registers *ioc_hpa;  /* I/O MMU base address */
+	u8  *res_map;	                /* resource map, bit == pdir entry */
+	u64 *pdir_base;	                /* physical base address */
+	u32 res_hint;	                /* next available IOVP - 
+					   circular search */
+	u32 res_size;		    	/* size of resource map in bytes */
+	spinlock_t res_lock;
+
+#ifdef CONFIG_PROC_FS
+#define CCIO_SEARCH_SAMPLE 0x100
+	unsigned long avg_search[CCIO_SEARCH_SAMPLE];
+	unsigned long avg_idx;		  /* current index into avg_search */
+	unsigned long used_pages;
+	unsigned long msingle_calls;
+	unsigned long msingle_pages;
+	unsigned long msg_calls;
+	unsigned long msg_pages;
+	unsigned long usingle_calls;
+	unsigned long usingle_pages;
+	unsigned long usg_calls;
+	unsigned long usg_pages;
 
-struct ccio_device {
-	struct ccio_device    *next;  /* list of LBA's in system */
-	struct hp_device      *iodc;  /* data about dev from firmware */
-	spinlock_t            ccio_lock;
-
-	struct ioa_registers   *ccio_hpa; /* base address */
-	u64   *pdir_base;   /* physical base address */
-	char  *res_map;     /* resource map, bit == pdir entry */
-
-	int   res_hint;	/* next available IOVP - circular search */
-	int   res_size;	/* size of resource map in bytes */
-	int   chainid_shift; /* specify bit location of chain_id */
-	int   flags;         /* state/functionality enabled */
-#ifdef DELAYED_RESOURCE_CNT
-	dma_addr_t res_delay[DELAYED_RESOURCE_CNT];
+	unsigned short cujo20_bug;
 #endif
 
 	/* STUFF We don't need in performance path */
-	int  pdir_size;     /* in bytes, determined by IOV Space size */
-	int  hw_rev;        /* HW revision of chip */
+	u32 pdir_size; 			/* in bytes, determined by IOV Space size */
+	u32 chainid_shift; 		/* specify bit location of chain_id */
+	struct ioc *next;		/* Linked list of discovered iocs */
+	const char *name;		/* device name from firmware */
+	unsigned int hw_path;           /* the hardware path this ioc is associatd with */
+	struct pci_dev *fake_pci_dev;   /* the fake pci_dev for non-pci devs */
+	struct resource mmio_region[2]; /* The "routed" MMIO regions */
 };
 
-
 /* Ratio of Host MEM to IOV Space size */
 static unsigned long ccio_mem_ratio = 4;
-static struct ccio_device *ccio_list = NULL;
-
-static int ccio_proc_info(char *buffer, char **start, off_t offset, int length);
-static unsigned long ccio_used_bytes = 0;
-static unsigned long ccio_used_pages = 0;
-static int ccio_cujo_bug = 0;
-
-static unsigned long ccio_alloc_size = 0;
-static unsigned long ccio_free_size = 0;
+static struct ioc *ioc_list;
+static int ioc_count;
 
 /**************************************************************
 *
@@ -227,55 +185,41 @@
 *   match the I/O TLB replacement policy.
 *
 ***************************************************************/
-#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
 #define IOVP_SIZE PAGE_SIZE
 #define IOVP_SHIFT PAGE_SHIFT
 #define IOVP_MASK PAGE_MASK
 
 /* Convert from IOVP to IOVA and vice versa. */
 #define CCIO_IOVA(iovp,offset) ((iovp) | (offset))
-#define CCIO_IOVP(iova) ((iova) & ~(IOVP_SIZE-1) )
+#define CCIO_IOVP(iova) ((iova) & IOVP_MASK)
 
 #define PDIR_INDEX(iovp)    ((iovp)>>IOVP_SHIFT)
 #define MKIOVP(pdir_idx)    ((long)(pdir_idx) << IOVP_SHIFT)
 #define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
-
-/* CUJO20 KLUDGE start */
-#define CUJO_20_BITMASK    0x0ffff000	/* upper nibble is a don't care   */
-#define CUJO_20_STEP       0x10000000	/* inc upper nibble */
-#define CUJO_20_BADPAGE1   0x01003000	/* pages that hpmc on raven U+    */
-#define CUJO_20_BADPAGE2   0x01607000	/* pages that hpmc on firehawk U+ */
-#define CUJO_20_BADHVERS   0x6821	/* low nibble 1 is cujo rev 2.0 */
-#define CUJO_RAVEN_LOC     0xf1000000UL	/* cujo location on raven U+ */
-#define CUJO_FIREHAWK_LOC  0xf1604000UL	/* cujo location on firehawk U+ */
-/* CUJO20 KLUDGE end */
+#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
 
 /*
 ** Don't worry about the 150% average search length on a miss.
 ** If the search wraps around, and passes the res_hint, it will
 ** cause the kernel to panic anyhow.
 */
-
-/* ioa->res_hint = idx + (size >> 3); \ */
-
-#define CCIO_SEARCH_LOOP(ioa, idx, mask, size)  \
-       for(; res_ptr < res_end; ++res_ptr) \
-       { \
-               if(0 == ((*res_ptr) & mask)) { \
-                       *res_ptr |= mask; \
-                       idx = (int)((unsigned long)res_ptr - (unsigned long)ioa->res_map); \
-                       ioa->res_hint = 0;\
+#define CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size)  \
+       for(; res_ptr < res_end; ++res_ptr) { \
+               if(0 == (*res_ptr & *mask_ptr)) { \
+                       *res_ptr |= *mask_ptr; \
+                       res_idx = (int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
+                       ioc->res_hint = res_idx + (size >> 3); \
                        goto resource_found; \
                } \
        }
 
-#define CCIO_FIND_FREE_MAPPING(ioa, idx, mask, size)  { \
-       u##size *res_ptr = (u##size *)&((ioa)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
-       u##size *res_end = (u##size *)&(ioa)->res_map[ioa->res_size]; \
-       CCIO_SEARCH_LOOP(ioa, idx, mask, size); \
-       res_ptr = (u##size *)&(ioa)->res_map[0]; \
-       CCIO_SEARCH_LOOP(ioa, idx, mask, size); \
-}
+#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
+       u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
+       u##size *res_end = (u##size *)&(ioc)->res_map[ioa->res_size]; \
+       u##size *mask_ptr = (u##size *)&mask; \
+       CCIO_SEARCH_LOOP(ioc, res_idx, mask_ptr, size); \
+       res_ptr = (u##size *)&(ioc)->res_map[0]; \
+       CCIO_SEARCH_LOOP(ioa, res_idx, mask_ptr, size);
 
 /*
 ** Find available bit in this ioa's resource map.
@@ -290,123 +234,132 @@
 ** o use different search for "large" (eg > 4 pages) or "very large"
 **   (eg > 16 pages) mappings.
 */
+
+/**
+ * ccio_alloc_range - Allocate pages in the ioc's resource map.
+ * @ioc: The I/O Controller.
+ * @pages_needed: The requested number of pages to be mapped into the
+ * I/O Pdir...
+ *
+ * This function searches the resource map of the ioc to locate a range
+ * of available pages for the requested size.
+ */
 static int
-ccio_alloc_range(struct ccio_device *ioa, size_t size)
+ccio_alloc_range(struct ioc *ioc, unsigned long pages_needed)
 {
 	int res_idx;
-	unsigned long mask, flags;
-	unsigned int pages_needed = size >> PAGE_SHIFT;
-
+	unsigned long mask;
+#ifdef CONFIG_PROC_FS
+	unsigned long cr_start = mfctl(16);
+#endif
+	
 	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
 
-	mask = (unsigned long) -1L;
- 	mask >>= BITS_PER_LONG - pages_needed;
-
-	DBG_RES(__FUNCTION__ " size: %d pages_needed %d pages_mask 0x%08lx\n", 
-		size, pages_needed, mask);
-
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
+	mask = ~(~0UL >> pages_needed);
+     
+	DBG_RES("%s() size: %d pages_needed %d mask 0x%08lx\n", 
+		__FUNCTION__, size, pages_needed, mask);
 
 	/*
 	** "seek and ye shall find"...praying never hurts either...
-	** ggg sacrafices another 710 to the computer gods.
+	** ggg sacrifices another 710 to the computer gods.
 	*/
 
 	if(pages_needed <= 8) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 8);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 8);
 	} else if(pages_needed <= 16) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 16);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 16);
 	} else if(pages_needed <= 32) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 32);
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 32);
 #ifdef __LP64__
 	} else if(pages_needed <= 64) {
-		CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, 64)
+		CCIO_FIND_FREE_MAPPING(ioc, res_idx, mask, 64);
 #endif
 	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to map.\n");
+		panic(__FILE__ ": %s() Too many pages to map. pages_needed: %ld\n", 
+		      __FUNCTION__, pages_needed);
 	}
 
-#ifdef DUMP_RESMAP
-	dump_resmap();
-#endif
-	panic(__FILE__ ":" __FUNCTION__ "() I/O MMU is out of mapping resources\n");
+	panic(__FILE__ ": %s() I/O MMU is out of mapping resources.\n", 
+	      __FUNCTION__);
 	
 resource_found:
 	
-	DBG_RES(__FUNCTION__ " res_idx %d mask 0x%08lx res_hint: %d\n",
-		res_idx, mask, ioa->res_hint);
+	DBG_RES("%s() res_idx %d mask 0x%08lx res_hint: %d\n",
+		__FUNCTION__, res_idx, mask, ioc->res_hint);
 
-	ccio_used_pages += pages_needed;
-	ccio_used_bytes += ((pages_needed >> 3) ? (pages_needed >> 3) : 1);
-
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
+#ifdef CONFIG_PROC_FS
+	{
+		unsigned long cr_end = mfctl(16);
+		unsigned long tmp = cr_end - cr_start;
+		/* check for roll over */
+		cr_start = (cr_end < cr_start) ?  -(tmp) : (tmp);
+	}
+	ioc->avg_search[ioc->avg_idx++] = cr_start;
+	ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
 
-#ifdef DUMP_RESMAP
-	dump_resmap();
+	ioc->used_pages += pages_needed;
 #endif
 
 	/* 
-	** return the bit address (convert from byte to bit).
+	** return the bit address.
 	*/
-	return (res_idx << 3);
+	return res_idx << 3;
 }
 
-
-#define CCIO_FREE_MAPPINGS(ioa, idx, mask, size) \
-        u##size *res_ptr = (u##size *)&((ioa)->res_map[idx + (((size >> 3) - 1) & ~((size >> 3) - 1))]); \
-        ASSERT((*res_ptr & mask) == mask); \
-        *res_ptr &= ~mask;
-
-/*
-** clear bits in the ioa's resource map
-*/
+#define CCIO_FREE_MAPPINGS(ioc, res_idx, mask, size) \
+        u##size *res_ptr = (u##size *)&((ioc)->res_map[res_idx]); \
+	u##size *mask_ptr = (u##size *)&mask; \
+        ASSERT((*res_ptr & *mask_ptr) == *mask_ptr); \
+        *res_ptr &= ~(*mask_ptr);
+
+/**
+ * ccio_free_range - Free pages from the ioc's resource map.
+ * @ioc: The I/O Controller.
+ * @iova: The I/O Virtual Address.
+ * @pages_mapped: The requested number of pages to be freed from the
+ * I/O Pdir.
+ *
+ * This function frees the resouces allocated for the iova.
+ */
 static void
-ccio_free_range(struct ccio_device *ioa, dma_addr_t iova, size_t size)
+ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
 {
-	unsigned long mask, flags;
+	unsigned long mask;
 	unsigned long iovp = CCIO_IOVP(iova);
-	unsigned int res_idx = PDIR_INDEX(iovp)>>3;
-	unsigned int pages_mapped = (size >> IOVP_SHIFT) + !!(size & ~IOVP_MASK);
+	unsigned int res_idx = PDIR_INDEX(iovp) >> 3;
 
-	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < (BITS_PER_LONG - IOVP_SHIFT));
+	ASSERT(pages_mapped);
+	ASSERT((pages_mapped * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_mapped <= BITS_PER_LONG);
 
-	mask = (unsigned long) -1L;
- 	mask >>= BITS_PER_LONG - pages_mapped;
+	mask = ~(~0UL >> pages_mapped);
 
-	DBG_RES(__FUNCTION__ " res_idx: %d size: %d pages_mapped %d mask 0x%08lx\n", 
-		res_idx, size, pages_mapped, mask);
+	DBG_RES("%s():  res_idx: %d pages_mapped %d mask 0x%08lx\n", 
+		__FUNCTION__, res_idx, pages_mapped, mask);
 
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= pages_mapped;
+#endif
 
 	if(pages_mapped <= 8) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 8);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
 	} else if(pages_mapped <= 16) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 16);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 16);
 	} else if(pages_mapped <= 32) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 32);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 32);
 #ifdef __LP64__
 	} else if(pages_mapped <= 64) {
-		CCIO_FREE_MAPPINGS(ioa, res_idx, mask, 64);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 64);
 #endif
 	} else {
-		panic(__FILE__ ":" __FUNCTION__ "() Too many pages to unmap.\n");
+		panic(__FILE__ ":%s() Too many pages to unmap.\n", 
+		      __FUNCTION__);
 	}
-	
-	ccio_used_pages -= (pages_mapped ? pages_mapped : 1);
-	ccio_used_bytes -= ((pages_mapped >> 3) ? (pages_mapped >> 3) : 1);
-
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
-
-#ifdef DUMP_RESMAP
-	dump_resmap();
-#endif
 }
 
-
 /****************************************************************
 **
 **          CCIO dma_ops support routines
@@ -416,7 +369,6 @@
 typedef unsigned long space_t;
 #define KERNEL_SPACE 0
 
-
 /*
 ** DMA "Page Type" and Hints 
 ** o if SAFE_DMA isn't set, mapping is for FAST_DMA. SAFE_DMA should be
@@ -466,32 +418,35 @@
 	[PCI_DMA_NONE]           0,            /* not valid */
 };
 
-/*
-** Initialize an I/O Pdir entry
-**
-** Given a virtual address (vba, arg2) and space id, (sid, arg1),
-** load the I/O PDIR entry pointed to by pdir_ptr (arg0). Each IO Pdir
-** entry consists of 8 bytes as shown below (MSB == bit 0):
-**
-**
-** WORD 0:
-** +------+----------------+-----------------------------------------------+
-** | Phys | Virtual Index  |               Phys                            |
-** | 0:3  |     0:11       |               4:19                            |
-** |4 bits|   12 bits      |              16 bits                          |
-** +------+----------------+-----------------------------------------------+
-** WORD 1:
-** +-----------------------+-----------------------------------------------+
-** |      Phys    |  Rsvd  | Prefetch |Update |Rsvd  |Lock  |Safe  |Valid  |
-** |     20:39    |        | Enable   |Enable |      |Enable|DMA   |       |
-** |    20 bits   | 5 bits | 1 bit    |1 bit  |2 bits|1 bit |1 bit |1 bit  |
-** +-----------------------+-----------------------------------------------+
-**
-** The virtual index field is filled with the results of the LCI
-** (Load Coherence Index) instruction.  The 8 bits used for the virtual
-** index are bits 12:19 of the value returned by LCI.
-*/
-
+/**
+ * ccio_io_pdir_entry - Initialize an I/O Pdir.
+ * @pdir_ptr: A pointer into I/O Pdir.
+ * @sid: The Space Identifier.
+ * @vba: The virtual address.
+ * @hints: The DMA Hint.
+ *
+ * Given a virtual address (vba, arg2) and space id, (sid, arg1),
+ * load the I/O PDIR entry pointed to by pdir_ptr (arg0). Each IO Pdir
+ * entry consists of 8 bytes as shown below (MSB == bit 0):
+ *
+ *
+ * WORD 0:
+ * +------+----------------+-----------------------------------------------+
+ * | Phys | Virtual Index  |               Phys                            |
+ * | 0:3  |     0:11       |               4:19                            |
+ * |4 bits|   12 bits      |              16 bits                          |
+ * +------+----------------+-----------------------------------------------+
+ * WORD 1:
+ * +-----------------------+-----------------------------------------------+
+ * |      Phys    |  Rsvd  | Prefetch |Update |Rsvd  |Lock  |Safe  |Valid  |
+ * |     20:39    |        | Enable   |Enable |      |Enable|DMA   |       |
+ * |    20 bits   | 5 bits | 1 bit    |1 bit  |2 bits|1 bit |1 bit |1 bit  |
+ * +-----------------------+-----------------------------------------------+
+ *
+ * The virtual index field is filled with the results of the LCI
+ * (Load Coherence Index) instruction.  The 8 bits used for the virtual
+ * index are bits 12:19 of the value returned by LCI.
+ */ 
 void CCIO_INLINE
 ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, void * vba, unsigned long hints)
 {
@@ -499,8 +454,7 @@
 	register unsigned long ci; /* coherent index */
 
 	/* We currently only support kernel addresses */
-	ASSERT(sid == 0);
-	ASSERT(((unsigned long) vba & 0xf0000000UL) == 0xc0000000UL);
+	ASSERT(sid == KERNEL_SPACE);
 
 	mtsp(sid,1);
 
@@ -524,7 +478,7 @@
 	** and deposit them
 	*/
 	asm volatile ("extrd,u %1,15,4,%0" : "=r" (ci) : "r" (pa));
-	asm volatile ("extrd,u %1,31,16,%0" : "+r" (ci) : "r" (ci));
+	asm volatile ("extrd,u %1,31,16,%0" : "+r" (pa) : "r" (pa));
 	asm volatile ("depd  %1,35,4,%0" : "+r" (pa) : "r" (ci));
 #else
 	pa = 0;
@@ -556,31 +510,39 @@
 	asm volatile("sync");
 }
 
-
-/*
-** Remove stale entries from the I/O TLB.
-** Need to do this whenever an entry in the PDIR is marked invalid.
-*/
+/**
+ * ccio_clear_io_tlb - Remove stale entries from the I/O TLB.
+ * @ioc: The I/O Controller.
+ * @iovp: The I/O Virtual Page.
+ * @byte_cnt: The requested number of bytes to be freed from the I/O Pdir.
+ *
+ * Purge invalid I/O PDIR entries from the I/O TLB.
+ *
+ * FIXME: Can we change the byte_cnt to pages_mapped?
+ */
 static CCIO_INLINE void
-ccio_clear_io_tlb( struct ccio_device *d, dma_addr_t iovp, size_t byte_cnt)
+ccio_clear_io_tlb(struct ioc *ioc, dma_addr_t iovp, size_t byte_cnt)
 {
-	u32 chain_size = 1 << d->chainid_shift;
+	u32 chain_size = 1 << ioc->chainid_shift;
 
-	iovp &= ~(IOVP_SIZE-1);	/* clear offset bits, just want pagenum */
+	iovp &= IOVP_MASK;	/* clear offset bits, just want pagenum */
 	byte_cnt += chain_size;
 
-        while (byte_cnt > chain_size) {
-		WRITE_U32(CMD_TLB_PURGE | iovp, &d->ccio_hpa->io_command);
-                iovp += chain_size;
+	while(byte_cnt > chain_size) {
+		WRITE_U32(CMD_TLB_PURGE | iovp, &ioc->ioc_hpa->io_command);
+		iovp += chain_size;
 		byte_cnt -= chain_size;
-        }
+      }
 }
 
-
-/***********************************************************
+/**
+ * ccio_mark_invalid - Mark the I/O Pdir entries invalid.
+ * @ioc: The I/O Controller.
+ * @iova: The I/O Virtual Address.
+ * @byte_cnt: The requested number of bytes to be freed from the I/O Pdir.
  *
- * Mark the I/O Pdir entries invalid and blow away the
- * corresponding I/O TLB entries.
+ * Mark the I/O Pdir entries invalid and blow away the corresponding I/O
+ * TLB entries.
  *
  * FIXME: at some threshhold it might be "cheaper" to just blow
  *        away the entire I/O TLB instead of individual entries.
@@ -588,25 +550,25 @@
  * FIXME: Uturn has 256 TLB entries. We don't need to purge every
  *        PDIR entry - just once for each possible TLB entry.
  *        (We do need to maker I/O PDIR entries invalid regardless).
- ***********************************************************/
+ *
+ * FIXME: Can we change byte_cnt to pages_mapped?
+ */ 
 static CCIO_INLINE void
-ccio_mark_invalid(struct ccio_device *d, dma_addr_t iova, size_t byte_cnt)
+ccio_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
 {
-	u32 iovp = (u32) CCIO_IOVP(iova);
+	u32 iovp = (u32)CCIO_IOVP(iova);
 	size_t saved_byte_cnt;
 
 	/* round up to nearest page size */
-	saved_byte_cnt = byte_cnt = (byte_cnt + IOVP_SIZE - 1) & IOVP_MASK;
+	saved_byte_cnt = byte_cnt = ROUNDUP(byte_cnt, IOVP_SIZE);
 
-	while (byte_cnt > 0) {
+	while(byte_cnt > 0) {
 		/* invalidate one page at a time */
 		unsigned int idx = PDIR_INDEX(iovp);
-		char *pdir_ptr = (char *) &(d->pdir_base[idx]);
-
-		ASSERT( idx < (d->pdir_size/sizeof(u64)));
-
-		pdir_ptr[7] = 0;	/* clear only VALID bit */
+		char *pdir_ptr = (char *) &(ioc->pdir_base[idx]);
 
+		ASSERT(idx < (ioc->pdir_size / sizeof(u64)));
+		pdir_ptr[7] = 0;	/* clear only VALID bit */ 
 		/*
 		** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360)
 		**   PCX-U/U+ do. (eg C200/C240)
@@ -622,232 +584,485 @@
 	}
 
 	asm volatile("sync");
-	ccio_clear_io_tlb(d, CCIO_IOVP(iova), saved_byte_cnt);
+	ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt);
 }
 
-
 /****************************************************************
 **
 **          CCIO dma_ops
 **
 *****************************************************************/
 
-void __init ccio_init(void)
-{
-	register_driver(ccio_drivers_for);
-}
-
-
-static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
+/**
+ * ccio_dma_supported - Verify the IOMMU supports the DMA address range.
+ * @dev: The PCI device.
+ * @mask: A bit mask describing the DMA address range of the device.
+ *
+ * This function implements the pci_dma_supported function.
+ */
+static int 
+ccio_dma_supported(struct pci_dev *dev, u64 mask)
 {
-	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
+	if(dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
 		BUG();
-		return(0);
+		return 0;
 	}
 
 	dev->dma_mask = mask;   /* save it */
 
 	/* only support 32-bit devices (ie PCI/GSC) */
-	return((int) (mask >= 0xffffffffUL));
+	return (int)(mask == 0xffffffffUL);
 }
 
-/*
-** Dump a hex representation of the resource map.
-*/
-
-#ifdef DUMP_RESMAP
-static 
-void dump_resmap()
-{
-	struct ccio_device *ioa = ccio_list;
-	unsigned long *res_ptr = (unsigned long *)ioa->res_map;
-	unsigned long i = 0;
-
-	printk("res_map: ");
-	for(; i < (ioa->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
-		printk("%08lx ", *res_ptr);
-
-	printk("\n");
-}
-#endif
-
-/*
-** map_single returns a fully formed IOVA
-*/
-static dma_addr_t ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+/**
+ * ccio_map_single - Map an address range into the IOMMU.
+ * @dev: The PCI device.
+ * @addr: The start address of the DMA region.
+ * @size: The length of the DMA region.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_map_single function.
+ */
+static dma_addr_t 
+ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
-	struct ccio_device *ioa = ccio_list;  /* FIXME : see Multi-IOC below */
+	int idx;
+	struct ioc *ioc;
+	unsigned long flags;
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
 	unsigned long hint = hint_lookup[direction];
-	int idx;
+
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
 
 	ASSERT(size > 0);
 
 	/* save offset bits */
-	offset = ((dma_addr_t) addr) & ~IOVP_MASK;
+	offset = ((unsigned long) addr) & ~IOVP_MASK;
 
 	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
+	size = ROUNDUP(size + offset, IOVP_SIZE);
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->msingle_calls++;
+	ioc->msingle_pages += size >> IOVP_SHIFT;
+#endif
 
-	idx = ccio_alloc_range(ioa, size);
-	iovp = (dma_addr_t) MKIOVP(idx);
+	idx = ccio_alloc_range(ioc, (size >> IOVP_SHIFT));
+	iovp = (dma_addr_t)MKIOVP(idx);
 
-	DBG_RUN(__FUNCTION__ " 0x%p -> 0x%lx", addr, (long) iovp | offset);
+	pdir_start = &(ioc->pdir_base[idx]);
 
-	pdir_start = &(ioa->pdir_base[idx]);
+	DBG_RUN("%s() 0x%p -> 0x%lx size: %0x%x\n",
+		__FUNCTION__, addr, (long)iovp | offset, size);
 
 	/* If not cacheline aligned, force SAFE_DMA on the whole mess */
-	if ((size % L1_CACHE_BYTES) || ((unsigned long) addr % L1_CACHE_BYTES))
+	if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES))
 		hint |= HINT_SAFE_DMA;
 
-	/* round up to nearest IOVP_SIZE */
-	size = (size + IOVP_SIZE - 1) & IOVP_MASK;
-
-	while (size > 0) {
-
+	while(size > 0) {
 		ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, addr, hint);
 
 		DBG_RUN(" pdir %p %08x%08x\n",
 			pdir_start,
 			(u32) (((u32 *) pdir_start)[0]),
-			(u32) (((u32 *) pdir_start)[1])
-			);
+			(u32) (((u32 *) pdir_start)[1]));
+		++pdir_start;
 		addr += IOVP_SIZE;
 		size -= IOVP_SIZE;
-		pdir_start++;
 	}
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
 	/* form complete address */
 	return CCIO_IOVA(iovp, offset);
 }
 
-
-static void ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
-{
-#ifdef FIXME
-/* Multi-IOC (ie N-class) :  need to lookup IOC from dev
-** o If we can't know about lba PCI data structs, that eliminates ->sysdata.
-** o walking up pcidev->parent dead ends at elroy too
-** o leaves hashing dev->bus->number into some lookup.
-**   (may only work for N-class)
-*/
-	struct ccio_device *ioa = dev->sysdata
-#else
-	struct ccio_device *ioa = ccio_list;
-#endif
-	dma_addr_t offset;
+/**
+ * ccio_unmap_single - Unmap an address range from the IOMMU.
+ * @dev: The PCI device.
+ * @addr: The start address of the DMA region.
+ * @size: The length of the DMA region.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_unmap_single function.
+ */
+static void 
+ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, 
+		  int direction)
+{
+	struct ioc *ioc;
+	unsigned long flags; 
+	dma_addr_t offset = iova & ~IOVP_MASK;
 	
-	offset = iova & ~IOVP_MASK;
-
-	/* round up to nearest IOVP_SIZE */
-	size = (size + offset + IOVP_SIZE - 1) & IOVP_MASK;
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long)iova, size);
+
+	iova ^= offset;        /* clear offset bits */
+	size += offset;
+	size = ROUNDUP(size, IOVP_SIZE);
 
-	/* Mask off offset */
-	iova &= IOVP_MASK;
+	spin_lock_irqsave(&ioc->res_lock, flags);
 
-	DBG_RUN(__FUNCTION__ " iovp 0x%lx\n", (long) iova);
-
-#ifdef DELAYED_RESOURCE_CNT
-	if (ioa->saved_cnt < DELAYED_RESOURCE_CNT) {
-		ioa->saved_iova[ioa->saved_cnt] = iova;
-		ioa->saved_size[ioa->saved_cnt] = size;
-		ccio_saved_cnt++;
-	} else {
-		do {
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
-			ccio_mark_invalid(ioa, iova, size);
-			ccio_free_range(ioa, iova, size);
 
-#ifdef DELAYED_RESOURCE_CNT
-			d->saved_cnt--;
-			iova = ioa->saved_iova[ioa->saved_cnt];
-			size = ioa->saved_size[ioa->saved_cnt];
-		} while (ioa->saved_cnt)
-	}
-#endif
+	ccio_mark_invalid(ioc, iova, size);
+	ccio_free_range(ioc, iova, (size >> IOVP_SHIFT));
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
 }
 
-
-static void * ccio_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+/**
+ * ccio_alloc_consistent - Allocate a consistent DMA mapping.
+ * @dev: The PCI device.
+ * @size: The length of the DMA region.
+ * @dma_handle: The DMA address handed back to the device (not the cpu).
+ *
+ * This function implements the pci_alloc_consistent function.
+ */
+static void * 
+ccio_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle)
 {
-	void *ret;
-	unsigned long flags;
-	struct ccio_device *ioa = ccio_list;
-
-	DBG_RUN(__FUNCTION__ " size 0x%x\n",  size);
-
+      void *ret;
 #if 0
 /* GRANT Need to establish hierarchy for non-PCI devs as well
 ** and then provide matching gsc_map_xxx() functions for them as well.
 */
-	if (!hwdev) {
+	if(!hwdev) {
 		/* only support PCI */
 		*dma_handle = 0;
 		return 0;
 	}
 #endif
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-	ccio_alloc_size += get_order(size);
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
-
         ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
 
 	if (ret) {
 		memset(ret, 0, size);
-		*dma_handle = ccio_map_single(hwdev, ret, size, PCI_DMA_BIDIRECTIONAL);
+		*dma_handle = ccio_map_single(dev, ret, size, PCI_DMA_BIDIRECTIONAL);
 	}
-	DBG_RUN(__FUNCTION__ " ret %p\n",  ret);
 
 	return ret;
 }
 
-
-static void ccio_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+/**
+ * ccio_free_consistent - Free a consistent DMA mapping.
+ * @dev: The PCI device.
+ * @size: The length of the DMA region.
+ * @cpu_addr: The cpu address returned from the ccio_alloc_consistent.
+ * @dma_handle: The device address returned from the ccio_alloc_consistent.
+ *
+ * This function implements the pci_free_consistent function.
+ */
+static void 
+ccio_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, 
+		     dma_addr_t dma_handle)
 {
-	unsigned long flags;
-	struct ccio_device *ioa = ccio_list;
+	ccio_unmap_single(dev, dma_handle, size, 0);
+	free_pages((unsigned long)cpu_addr, get_order(size));
+}
 
-	spin_lock_irqsave(&ioa->ccio_lock, flags);
-	ccio_free_size += get_order(size);
-	spin_unlock_irqrestore(&ioa->ccio_lock, flags);
+/*
+** Since 0 is a valid pdir_base index value, can't use that
+** to determine if a value is valid or not. Use a flag to indicate
+** the SG list entry contains a valid pdir index.
+*/
+#define PIDE_FLAG 0x80000000UL
 
-	ccio_unmap_single(hwdev, dma_handle, size, 0);
-	free_pages((unsigned long) vaddr, get_order(size));
+/**
+ * ccio_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir.
+ * @ioc: The I/O Controller.
+ * @startsg: The scatter/gather list of coalesced chunks.
+ * @nents: The number of entries in the scatter/gather list.
+ * @hint: The DMA Hint.
+ *
+ * This function inserts the coalesced scatter/gather list chunks into the
+ * I/O Controller's I/O Pdir.
+ */ 
+static CCIO_INLINE int
+ccio_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, 
+	       unsigned long hint)
+{
+	struct scatterlist *dma_sg = startsg;	/* pointer to current DMA */
+	int n_mappings = 0;
+	u64 *pdirp = 0;
+	unsigned long dma_offset = 0;
+
+	dma_sg--;
+	while (nents-- > 0) {
+		int cnt = sg_dma_len(startsg);
+		sg_dma_len(startsg) = 0;
+
+		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents,
+			   (unsigned long)sg_dma_address(startsg), cnt,
+			   startsg->address, startsg->length
+		);
+
+		/*
+		** Look for the start of a new DMA stream
+		*/
+		if(sg_dma_address(startsg) & PIDE_FLAG) {
+			u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG;
+			dma_offset = (unsigned long) pide & ~IOVP_MASK;
+			sg_dma_address(startsg) = 0;
+			dma_sg++;
+			sg_dma_address(dma_sg) = pide;
+			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
+			n_mappings++;
+		}
+
+		/*
+		** Look for a VCONTIG chunk
+		*/
+		if (cnt) {
+			unsigned long vaddr = (unsigned long)startsg->address;
+			ASSERT(pdirp);
+
+			/* Since multiple Vcontig blocks could make up
+			** one DMA stream, *add* cnt to dma_len.
+			*/
+			sg_dma_len(dma_sg) += cnt;
+			cnt += dma_offset;
+			dma_offset=0;	/* only want offset on first chunk */
+			cnt = ROUNDUP(cnt, IOVP_SIZE);
+#ifdef CONFIG_PROC_FS
+			ioc->msg_pages += cnt >> IOVP_SHIFT;
+#endif
+			do {
+				ccio_io_pdir_entry(pdirp, KERNEL_SPACE, 
+						   (void *)vaddr, hint);
+				vaddr += IOVP_SIZE;
+				cnt -= IOVP_SIZE;
+				pdirp++;
+			} while (cnt > 0);
+		}
+		startsg++;
+	}
+	return(n_mappings);
 }
 
+/*
+** First pass is to walk the SG list and determine where the breaks are
+** in the DMA stream. Allocates PDIR entries but does not fill them.
+** Returns the number of DMA chunks.
+**
+** Doing the fill seperate from the coalescing/allocation keeps the
+** code simpler. Future enhancement could make one pass through
+** the sglist do both.
+*/
 
-static int ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static CCIO_INLINE int
+ccio_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
-	int tmp = nents;
+	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */
+	unsigned long vcontig_len;         /* len of VCONTIG chunk */
+	unsigned long vcontig_end;
+	struct scatterlist *dma_sg;        /* next DMA stream head */
+	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
+	int n_mappings = 0;
+
+	while (nents > 0) {
+
+		/*
+		** Prepare for first/next DMA stream
+		*/
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = startsg->length;
+		vcontig_end += (unsigned long) startsg->address;
+		dma_offset = (unsigned long) startsg->address & ~IOVP_MASK;
+
+		/* PARANOID: clear entries */
+		sg_dma_address(startsg) = 0;
+		sg_dma_len(startsg) = 0;
+
+		/*
+		** This loop terminates one iteration "early" since
+		** it's always looking one "ahead".
+		*/
+		while(--nents > 0) {
+			unsigned long startsg_end;
 
-	DBG_RUN(KERN_WARNING __FUNCTION__ " START\n");
+			startsg++;
+			startsg_end = (unsigned long)startsg->address + 
+				startsg->length;
+
+			/* PARANOID: clear entries */
+			sg_dma_address(startsg) = 0;
+			sg_dma_len(startsg) = 0;
+
+			/*
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
+			*/   
+			if(ROUNDUP(dma_len + dma_offset + startsg->length,
+				   IOVP_SIZE) > DMA_CHUNK_SIZE)
+				break;
+
+			/*
+			** Append the next transaction?
+			*/
+			if(vcontig_end == (unsigned long) startsg->address) {
+				vcontig_len += startsg->length;
+				vcontig_end += startsg->length;
+				dma_len     += startsg->length;
+				continue;
+			}
+
+			/*
+			** Not virtually contigous.
+			** Terminate prev chunk.
+			** Start a new chunk.
+			**
+			** Once we start a new VCONTIG chunk, dma_offset
+			** can't change. And we need the offset from the first
+			** chunk - not the last one. Ergo Successive chunks
+			** must start on page boundaries and dove tail
+			** with it's predecessor.
+			*/
+			sg_dma_len(vcontig_sg) = vcontig_len;
+
+			vcontig_sg = startsg;
+			vcontig_len = startsg->length;
+			break;
+		}
 
-        /* KISS: map each buffer seperately. */
-	while (nents) {
-		sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
-		sg_dma_len(sglist) = sglist->length;
-		nents--;
-		sglist++;
+		/*
+		** End of DMA Stream
+		** Terminate last VCONTIG block.
+		** Allocate space for DMA stream.
+		*/
+		sg_dma_len(vcontig_sg) = vcontig_len;
+		dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE);
+		sg_dma_address(dma_sg) =
+			PIDE_FLAG 
+			| (ccio_alloc_range(ioc, (dma_len >> IOVP_SHIFT)) << IOVP_SHIFT)
+			| dma_offset;
+		n_mappings++;
 	}
 
-	DBG_RUN(KERN_WARNING __FUNCTION__ " DONE\n");
-	return tmp;
+	return n_mappings;
 }
 
-
-static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+/**
+ * ccio_map_sg - Map the scatter/gather list into the IOMMU.
+ * @dev: The PCI device.
+ * @sglist: The scatter/gather list to be mapped in the IOMMU.
+ * @nents: The number of entries in the scatter/gather list.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_map_sg function.
+ */
+static int
+ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
+	    int direction)
 {
-	DBG_RUN(KERN_WARNING __FUNCTION__ " : unmapping %d entries\n", nents);
-	while (nents) {
-		ccio_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
-		nents--;
-		sglist++;
+	struct ioc *ioc;
+	int coalesced, filled = 0;
+	unsigned long flags;
+	unsigned long hint = hint_lookup[direction];
+	
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+	
+	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+
+	/* Fast path single entry scatterlists. */
+	if(nents == 1) {
+		sg_dma_address(sglist)= ccio_map_single(dev, sglist->address,
+							sglist->length, 
+							direction);
+		sg_dma_len(sglist)= sglist->length;
+		return 1;
 	}
-	return;
+	
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef CONFIG_PROC_FS
+	ioc->msg_calls++;
+#endif
+
+	/*
+	** First coalesce the chunks and allocate I/O pdir space
+	**
+	** If this is one DMA stream, we can properly map using the
+	** correct virtual address associated with each DMA page.
+	** w/o this association, we wouldn't have coherent DMA!
+	** Access to the virtual address is what forces a two pass algorithm.
+	*/
+	coalesced = ccio_coalesce_chunks(ioc, sglist, nents);
+
+	/*
+	** Program the I/O Pdir
+	**
+	** map the virtual addresses to the I/O Pdir
+	** o dma_address will contain the pdir index
+	** o dma_len will contain the number of bytes to map 
+	** o address contains the virtual address.
+	*/
+	filled = ccio_fill_pdir(ioc, sglist, nents, hint);
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	ASSERT(coalesced == filled);
+	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+	return filled;
 }
 
+/**
+ * ccio_unmap_sg - Unmap the scatter/gather list from the IOMMU.
+ * @dev: The PCI device.
+ * @sglist: The scatter/gather list to be unmapped from the IOMMU.
+ * @nents: The number of entries in the scatter/gather list.
+ * @direction: The direction of the DMA transaction (to/from device).
+ *
+ * This function implements the pci_unmap_sg function.
+ */
+static void 
+ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
+	      int direction)
+{
+	struct ioc *ioc;
+
+	ASSERT(dev);
+	ASSERT(dev->sysdata);
+	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	ioc = GET_IOC(dev);
+
+	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
+		__FUNCTION__, nents, sglist->address, sglist->length);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usg_calls++;
+#endif
+
+	while(sg_dma_len(sglist) && nents--) {
+
+#ifdef CONFIG_PROC_FS
+		ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
+#endif
+		ccio_unmap_single(dev, sg_dma_address(sglist),
+				  sg_dma_len(sglist), direction);
+		++sglist;
+	}
+
+	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
+}
 
 static struct pci_dma_ops ccio_ops = {
 	ccio_dma_supported,
@@ -861,6 +1076,201 @@
 	NULL,                   /* dma_sync_sg     : ditto */
 };
 
+#ifdef CONFIG_PROC_FS
+static int proc_append(char *src, int len, char **dst, off_t *offset, int *max)
+{
+	if (len < *offset) {
+		*offset -= len;
+		return 0;
+	}
+	if (*offset > 0) {
+		src += *offset;
+		len -= *offset;
+		*offset = 0;
+	}
+	if (len > *max) {
+		len = *max;
+	}
+	memcpy(*dst, src, len);
+	*dst += len;
+	*max -= len;
+	return (*max == 0);
+}
+
+static int ccio_proc_info(char *buf, char **start, off_t offset, int count,
+			  int *eof, void *data)
+{
+	int max = count;
+	char tmp[80]; /* width of an ANSI-standard terminal */
+	struct ioc *ioc = ioc_list;
+
+	while (ioc != NULL) {
+		unsigned int total_pages = ioc->res_size << 3;
+		unsigned long avg = 0, min, max;
+		int j, len;
+
+		len = sprintf(tmp, "%s\n", ioc->name);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "Cujo 2.0 bug    : %s\n",
+			      (ioc->cujo20_bug ? "yes" : "no"));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "IO PDIR size    : %d bytes (%d entries)\n",
+			      total_pages * 8, total_pages);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "IO PDIR entries : %ld free  %ld used (%d%%)\n",
+			      total_pages - ioc->used_pages, ioc->used_pages,
+			      (int)(ioc->used_pages * 100 / total_pages));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", 
+			ioc->res_size, total_pages);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+		min = max = ioc->avg_search[0];
+		for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
+			avg += ioc->avg_search[j];
+			if(ioc->avg_search[j] > max) 
+				max = ioc->avg_search[j];
+			if(ioc->avg_search[j] < min) 
+				min = ioc->avg_search[j];
+		}
+		avg /= CCIO_SEARCH_SAMPLE;
+		len = sprintf(tmp, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+			      min, avg, max);
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+
+		len = sprintf(tmp, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
+			      ioc->msingle_calls, ioc->msingle_pages,
+			      (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		
+
+		/* KLUGE - unmap_sg calls unmap_single for each mapped page */
+		min = ioc->usingle_calls - ioc->usg_calls;
+		max = ioc->usingle_pages - ioc->usg_pages;
+		len = sprintf(tmp, "pci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
+			      min, max, (int)((max * 1000)/min));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+ 
+		len = sprintf(tmp, "pci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
+			      ioc->msg_calls, ioc->msg_pages,
+			      (int)((ioc->msg_pages * 1000)/ioc->msg_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+		len = sprintf(tmp, "pci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",
+			      ioc->usg_calls, ioc->usg_pages,
+			      (int)((ioc->usg_pages * 1000)/ioc->usg_calls));
+		if (proc_append(tmp, len, &buf, &offset, &count))
+			break;
+
+		ioc = ioc->next;
+	}
+
+	if (count == 0) {
+		*eof = 1;
+	}
+	return (max - count);
+}
+
+static int ccio_resource_map(char *buf, char **start, off_t offset, int len,
+			     int *eof, void *data)
+{
+	struct ioc *ioc = ioc_list;
+
+	buf[0] = '\0';
+	while (ioc != NULL) {
+		u32 *res_ptr = (u32 *)ioc->res_map;
+		int j;
+
+		for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {
+			if ((j & 7) == 0)
+				strcat(buf,"\n   ");
+			sprintf(buf, "%s %08x", buf, *res_ptr);
+			res_ptr++;
+		}
+		strcat(buf, "\n\n");
+		ioc = ioc->next;
+		break; /* XXX - remove me */
+	}
+
+	return strlen(buf);
+}
+#endif
+
+/**
+ * ccio_find_ioc - Find the ioc in the ioc_list
+ * @hw_path: The hardware path of the ioc.
+ *
+ * This function searches the ioc_list for an ioc that matches
+ * the provide hardware path.
+ */
+static struct ioc * ccio_find_ioc(int hw_path)
+{
+	int i;
+	struct ioc *ioc;
+
+	ioc = ioc_list;
+	for (i = 0; i < ioc_count; i++) {
+		if (ioc->hw_path == hw_path)
+			return ioc;
+
+		ioc = ioc->next;
+	}
+
+	return NULL;
+}
+
+/**
+ * ccio_get_iommu - Find the iommu which controls this device
+ * @dev: The parisc device.
+ *
+ * This function searches through the registerd IOMMU's and returns the
+ * appropriate IOMMU for the device based upon the devices hardware path.
+ */
+void * ccio_get_iommu(const struct parisc_device *dev)
+{
+	dev = find_pa_parent_type(dev, HPHW_IOA);
+	if (!dev)
+		return NULL;
+
+	return ccio_find_ioc(dev->hw_path);
+}
+
+#define CUJO_20_STEP       0x10000000	/* inc upper nibble */
+
+/* Cujo 2.0 has a bug which will silently corrupt data being transferred
+ * to/from certain pages.  To avoid this happening, we mark these pages
+ * as `used', and ensure that nothing will try to allocate from them.
+ */
+void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp)
+{
+	unsigned int idx;
+	struct ioc *ioc = ccio_get_iommu(dev);
+	u8 *res_ptr;
+
+#ifdef CONFIG_PROC_FS
+	ioc->cujo20_bug = 1;
+#endif
+	res_ptr = ioc->res_map;
+	idx = PDIR_INDEX(iovp) >> 3;
+
+	while (idx < ioc->res_size) {
+ 		res_ptr[idx] |= 0xff;
+		idx += PDIR_INDEX(CUJO_20_STEP) >> 3;
+	}
+}
+
 #if 0
 /* GRANT -  is this needed for U2 or not? */
 
@@ -875,38 +1285,37 @@
 ** I think only Java (K/D/R-class too?) systems don't do this.
 */
 static int
-ccio_get_iotlb_size(struct hp_device *d)
+ccio_get_iotlb_size(struct parisc_device *dev)
 {
-	if(d->spa_shift == 0) {
-		panic(__FUNCTION__ ": Can't determine I/O TLB size.\n");
+	if (dev->spa_shift == 0) {
+		panic("%s() : Can't determine I/O TLB size.\n", __FUNCTION__);
 	}
-	return(1 << d->spa_shift);
+	return (1 << dev->spa_shift);
 }
 #else
 
 /* Uturn supports 256 TLB entries */
 #define CCIO_CHAINID_SHIFT	8
 #define CCIO_CHAINID_MASK	0xff
-
 #endif /* 0 */
 
-
-/*
-** Figure out how big the I/O PDIR should be and alloc it.
-** Also sets variables which depend on pdir size.
-*/
+/**
+ * ccio_ioc_init - Initalize the I/O Controller
+ * @ioc: The I/O Controller.
+ *
+ * Initalize the I/O Controller which includes setting up the
+ * I/O Page Directory, the resource map, and initalizing the
+ * U2/Uturn chip into virtual mode.
+ */
 static void
-ccio_alloc_pdir(struct ccio_device *ioa)
+ccio_ioc_init(struct ioc *ioc)
 {
-	extern unsigned long mem_max;          /* arch.../setup.c */
-
-	u32 iova_space_size = 0;
-	void * pdir_base;
-	int pdir_size, iov_order;
+	int i, iov_order;
+	u32 iova_space_size;
+	unsigned long physmem;
 
 	/*
 	** Determine IOVA Space size from memory size.
-	** Using "mem_max" is a kluge.
 	**
 	** Ideally, PCI drivers would register the maximum number
 	** of DMA they can have outstanding for each device they
@@ -915,15 +1324,18 @@
 	** methods still require some "extra" to support PCI
 	** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
 	*/
+
 	/* limit IOVA space size to 1MB-1GB */
-	if (mem_max < (ccio_mem_ratio*1024*1024)) {
-		iova_space_size = 1024*1024;
+
+	physmem = num_physpages << PAGE_SHIFT;
+	if(physmem < (ccio_mem_ratio * 1024 * 1024)) {
+		iova_space_size = 1024 * 1024;
 #ifdef __LP64__
-	} else if (mem_max > (ccio_mem_ratio*512*1024*1024)) {
-		iova_space_size = 512*1024*1024;
+	} else if(physmem > (ccio_mem_ratio * 512 * 1024 * 1024)) {
+		iova_space_size = 512 * 1024 * 1024;
 #endif
 	} else {
-		iova_space_size = (u32) (mem_max/ccio_mem_ratio);
+		iova_space_size = (u32)(physmem / ccio_mem_ratio);
 	}
 
 	/*
@@ -933,277 +1345,271 @@
 
 	/* We could use larger page sizes in order to *decrease* the number
 	** of mappings needed.  (ie 8k pages means 1/2 the mappings).
-        **
+	**
 	** Note: Grant Grunder says "Using 8k I/O pages isn't trivial either
 	**   since the pages must also be physically contiguous - typically
 	**   this is the case under linux."
 	*/
 
-	iov_order = get_order(iova_space_size);
+	iov_order = get_order(iova_space_size) >> (IOVP_SHIFT - PAGE_SHIFT);
 	ASSERT(iov_order <= (30 - IOVP_SHIFT));   /* iova_space_size <= 1GB */
 	ASSERT(iov_order >= (20 - IOVP_SHIFT));   /* iova_space_size >= 1MB */
 	iova_space_size = 1 << (iov_order + IOVP_SHIFT);
 
-	ioa->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
+	ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
 
-	ASSERT(pdir_size < 4*1024*1024);   /* max pdir size < 4MB */
+	ASSERT(ioc->pdir_size < 4 * 1024 * 1024);   /* max pdir size < 4MB */
 
 	/* Verify it's a power of two */
-	ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
+	ASSERT((1 << get_order(ioc->pdir_size)) == (ioc->pdir_size >> PAGE_SHIFT));
 
-	DBG_INIT(__FUNCTION__ " hpa 0x%p mem %dMB IOV %dMB (%d bits)\n    PDIR size 0x%0x",
-		ioa->ccio_hpa, (int) (mem_max>>20), iova_space_size>>20,
-		iov_order + PAGE_SHIFT, pdir_size);
-
-	ioa->pdir_base =
-	pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(pdir_size));
-	if (NULL == pdir_base)
-	{
-		panic(__FILE__ ":" __FUNCTION__ "() could not allocate I/O Page Table\n");
+	DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits) PDIR size 0x%0x",
+		__FUNCTION__, ioc->ioc_hpa, physmem>>20, iova_space_size>>20,
+		 iov_order + PAGE_SHIFT, ioc->pdir_size);
+
+	ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, 
+						 get_order(ioc->pdir_size));
+	if(NULL == ioc->pdir_base) {
+		panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
 	}
-	memset(pdir_base, 0, pdir_size);
+	memset(ioc->pdir_base, 0, ioc->pdir_size);
 
-	ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base);
+	ASSERT((((unsigned long)ioc->pdir_base) & PAGE_MASK) == (unsigned long)ioc->pdir_base);
+	DBG_INIT(" base %p", ioc->pdir_base);
 
-	DBG_INIT(" base %p", pdir_base);
+	/* resource map size dictated by pdir_size */
+ 	ioc->res_size = (ioc->pdir_size / sizeof(u64)) >> 3;
+	DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+	
+	ioc->res_map = (u8 *)__get_free_pages(GFP_KERNEL, 
+					      get_order(ioc->res_size));
+	if(NULL == ioc->res_map) {
+		panic(__FILE__ ":%s() could not allocate resource map\n", __FUNCTION__);
+	}
+	memset(ioc->res_map, 0, ioc->res_size);
+
+	/* Initialize the res_hint to 16 */
+	ioc->res_hint = 16;
+
+	/* Initialize the spinlock */
+	spin_lock_init(&ioc->res_lock);
 
 	/*
 	** Chainid is the upper most bits of an IOVP used to determine
 	** which TLB entry an IOVP will use.
 	*/
-	ioa->chainid_shift = get_order(iova_space_size)+PAGE_SHIFT-CCIO_CHAINID_SHIFT;
-
-	DBG_INIT(" chainid_shift 0x%x\n", ioa->chainid_shift);
-}
-
-
-static void
-ccio_hw_init(struct ccio_device *ioa)
-{
-	int i;
+	ioc->chainid_shift = get_order(iova_space_size) + PAGE_SHIFT - CCIO_CHAINID_SHIFT;
+	DBG_INIT(" chainid_shift 0x%x\n", ioc->chainid_shift);
 
 	/*
 	** Initialize IOA hardware
 	*/
-	WRITE_U32(CCIO_CHAINID_MASK << ioa->chainid_shift, &ioa->ccio_hpa->io_chain_id_mask);
-	WRITE_U32(virt_to_phys(ioa->pdir_base), &ioa->ccio_hpa->io_pdir_base);
+	WRITE_U32(CCIO_CHAINID_MASK << ioc->chainid_shift, 
+		  &ioc->ioc_hpa->io_chain_id_mask);
 
+	WRITE_U32(virt_to_phys(ioc->pdir_base), 
+		  &ioc->ioc_hpa->io_pdir_base);
 
 	/*
 	** Go to "Virtual Mode"
 	*/
-	WRITE_U32(IOA_NORMAL_MODE, &ioa->ccio_hpa->io_control);
+	WRITE_U32(IOA_NORMAL_MODE, &ioc->ioc_hpa->io_control);
 
 	/*
 	** Initialize all I/O TLB entries to 0 (Valid bit off).
 	*/
-	WRITE_U32(0, &ioa->ccio_hpa->io_tlb_entry_m);
-	WRITE_U32(0, &ioa->ccio_hpa->io_tlb_entry_l);
+	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_m);
+	WRITE_U32(0, &ioc->ioc_hpa->io_tlb_entry_l);
 
-	for (i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
-		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioa->chainid_shift)),
-					&ioa->ccio_hpa->io_command);
+	for(i = 1 << CCIO_CHAINID_SHIFT; i ; i--) {
+		WRITE_U32((CMD_TLB_DIRECT_WRITE | (i << ioc->chainid_shift)),
+			  &ioc->ioc_hpa->io_command);
 	}
-
 }
 
-
 static void
-ccio_resmap_init(struct ccio_device *ioa)
+ccio_init_resource(struct resource *res, char *name, unsigned long ioaddr)
 {
-	u32 res_size;
-
-	/*
-	** Ok...we do more than just init resource map
-	*/
-	ioa->ccio_lock = SPIN_LOCK_UNLOCKED;
+	int result;
 
-	ioa->res_hint = 16;    /* next available IOVP - circular search */
-
-	/* resource map size dictated by pdir_size */
-	res_size = ioa->pdir_size/sizeof(u64); /* entries */
-	res_size >>= 3;	/* convert bit count to byte count */
-	DBG_INIT(__FUNCTION__ "() res_size 0x%x\n", res_size);
-
-	ioa->res_size = res_size;
-	ioa->res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
-	if (NULL == ioa->res_map)
-	{
-		panic(__FILE__ ":" __FUNCTION__ "() could not allocate resource map\n");
+	res->flags = IORESOURCE_MEM;
+	res->start = (unsigned long)(signed) __raw_readl(ioaddr) << 16;
+	res->end = (unsigned long)(signed) (__raw_readl(ioaddr + 4) << 16) - 1;
+	if (res->end + 1 == res->start)
+		return;
+	res->name = name;
+	result = request_resource(&iomem_resource, res);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim CCIO bus address space (%p,%p)\n", 
+		       __FILE__, res->start, res->end);
 	}
-	memset(ioa->res_map, 0, res_size);
 }
 
-/* CUJO20 KLUDGE start */
-static struct {
-		u16 hversion;
-		u8  spa;
-		u8  type;
-		u32     foo[3];	/* 16 bytes total */
-} cujo_iodc __attribute__ ((aligned (64)));
-static unsigned long cujo_result[32] __attribute__ ((aligned (16))) = {0,0,0,0};
+static void __init ccio_init_resources(struct ioc *ioc)
+{
+	struct resource *res = ioc->mmio_region;
+	char *name = kmalloc(14, GFP_KERNEL);
 
-/*
-** CUJO 2.0 incorrectly decodes a memory access for specific
-** pages (every page at specific iotlb locations dependent
-** upon where the cujo is flexed - diff on raven/firehawk.
-** resulting in an hpmc and/or silent data corruption.
-** Workaround is to prevent use of those I/O TLB entries
-** by marking the suspect bitmap range entries as busy.
-*/
-static void
-ccio_cujo20_hack(struct ccio_device *ioa)
+	sprintf(name, "GSC Bus [%d/]", ioc->hw_path);
+
+	ccio_init_resource(res, name, (unsigned long)&ioc->ioc_hpa->io_io_low);
+	ccio_init_resource(res + 1, name,
+			(unsigned long)&ioc->ioc_hpa->io_io_low_hv);
+}
+
+static void expand_ioc_area(struct ioc *ioc, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align)
 {
-	unsigned long status;
-	unsigned int idx;
-	u8 *res_ptr = ioa->res_map;
-	u32 iovp=0x0;
-	unsigned long mask;
+#ifdef NASTY_HACK_FOR_K_CLASS
+	__raw_writel(0xfffff600, (unsigned long)&(ioc->ioc_hpa->io_io_high));
+	ioc->mmio_region[0].end = 0xf5ffffff;
+#endif
+}
 
-	status = pdc_iodc_read( &cujo_result, (void *) CUJO_RAVEN_LOC, 0, &cujo_iodc, 16);
-	if (status == 0) {
-		if (cujo_iodc.hversion==CUJO_20_BADHVERS)
-			iovp = CUJO_20_BADPAGE1;
+static struct resource *ccio_get_resource(struct ioc* ioc,
+		const struct parisc_device *dev)
+{
+	if (!ioc) {
+		return &iomem_resource;
+	} else if ((ioc->mmio_region->start <= dev->hpa) &&
+			(dev->hpa < ioc->mmio_region->end)) {
+		return ioc->mmio_region;
+	} else if (((ioc->mmio_region + 1)->start <= dev->hpa) &&
+			(dev->hpa < (ioc->mmio_region + 1)->end)) {
+		return ioc->mmio_region + 1;
 	} else {
-		status = pdc_iodc_read( &cujo_result, (void *) CUJO_FIREHAWK_LOC, 0, &cujo_iodc, 16);
-		if (status == 0) {
-			if (cujo_iodc.hversion==CUJO_20_BADHVERS)
-				iovp = CUJO_20_BADPAGE2;
-		} else {
-			/* not a defective system */
-			return;
-		}
+		return NULL;
 	}
+}
 
-	printk(MODULE_NAME ": Cujo 2.0 bug needs a work around\n");
-	ccio_cujo_bug = 1;
+int ccio_allocate_resource(const struct parisc_device *dev,
+		struct resource *res, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align,
+		void (*alignf)(void *, struct resource *, unsigned long),
+		void *alignf_data)
+{
+	struct ioc *ioc = ccio_get_iommu(dev);
+	struct resource *parent = ccio_get_resource(ioc, dev);
+	if (!parent)
+		return -EBUSY;
 
-	/*
-	** mark bit entries that match "bad page"
-	*/
-	idx = PDIR_INDEX(iovp)>>3;
-	mask = 0xff;
-	
-	while(idx * sizeof(u8) < ioa->res_size) {
-		res_ptr[idx] |= mask;
-		idx += (PDIR_INDEX(CUJO_20_STEP)>>3);
-		ccio_used_pages += 8;
-		ccio_used_bytes += 1;
-	}
+	if (!allocate_resource(parent, res, size, min, max, align, alignf,
+			alignf_data))
+		return 0;
+
+	expand_ioc_area(ioc, size, min, max, align);
+	return allocate_resource(parent, res, size, min, max, align, alignf,
+			alignf_data);
 }
-/* CUJO20 KLUDGE end */
 
-#ifdef CONFIG_PROC_FS
-static int ccio_proc_info(char *buf, char **start, off_t offset, int len)
+int ccio_request_resource(const struct parisc_device *dev,
+		struct resource *res)
 {
-	unsigned long i = 0;
-	struct ccio_device *ioa = ccio_list;
-	unsigned long *res_ptr = (unsigned long *)ioa->res_map;
-	unsigned long total_pages = ioa->res_size << 3;            /* 8 bits per byte */
-
-	sprintf(buf, "%s\nCujo 2.0 bug    : %s\n",
-		parisc_getHWdescription(ioa->iodc->hw_type, ioa->iodc->hversion,
-					ioa->iodc->sversion),
-		(ccio_cujo_bug ? "yes" : "no"));
-
-	sprintf(buf, "%sIO pdir size    : %d bytes (%d entries)\n",
-		buf, ((ioa->res_size << 3) * sizeof(u64)), /* 8 bits per byte */
-		ioa->res_size << 3);                       /* 8 bits per byte */
+	struct ioc *ioc = ccio_get_iommu(dev);
+	struct resource *parent = ccio_get_resource(ioc, dev);
+
+	return request_resource(parent, res);
+}
+/**
+ * ccio_probe - Determine if ccio should claim this device.
+ * @dev: The device which has been found
+ *
+ * Determine if ccio should claim this chip (return 0) or not (return 1).
+ * If so, initialize the chip and tell other partners in crime they
+ * have work to do.
+ */
+static int ccio_probe(struct parisc_device *dev)
+{
+	int i;
+	struct ioc *ioc, **ioc_p = &ioc_list;
 	
-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-		buf, ioa->res_size, ioa->res_size << 3);   /* 8 bits per byte */
+	ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL);
+	if (ioc == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return 1;
+	}
+	memset(ioc, 0, sizeof(struct ioc));
 
-	strcat(buf,  "     	  total:    free:    used:   % used:\n");
-	sprintf(buf, "%sblocks  %8d %8ld %8ld %8ld%%\n", buf, ioa->res_size,
-		ioa->res_size - ccio_used_bytes, ccio_used_bytes,
-		(ccio_used_bytes * 100) / ioa->res_size);
-
-	sprintf(buf, "%spages   %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
-		total_pages - ccio_used_pages, ccio_used_pages,
-		(ccio_used_pages * 100 / total_pages));
+	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
-	sprintf(buf, "%sconsistent       %8ld %8ld\n", buf,
-		ccio_alloc_size, ccio_free_size);
- 
-	strcat(buf, "\nResource bitmap:\n");
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
 
-	for(; i < (ioa->res_size / sizeof(unsigned long)); ++i, ++res_ptr)
-		len += sprintf(buf, "%s%08lx ", buf, *res_ptr);
+	for (i = 0; i < ioc_count; i++) {
+		ioc_p = &(*ioc_p)->next;
+	}
+	*ioc_p = ioc;
 
-	strcat(buf, "\n");
-	return strlen(buf);
+	ioc->hw_path = dev->hw_path;
+	ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
+	ccio_ioc_init(ioc);
+	ccio_init_resources(ioc);
+	hppa_dma_ops = &ccio_ops;
+
+	if (ioc_count == 0) {
+		/* XXX: Create separate entries for each ioc */
+		create_proc_read_entry(MODULE_NAME, S_IRWXU, proc_runway_root,
+				       ccio_proc_info, NULL);
+		create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU,
+				       proc_runway_root, ccio_resource_map, NULL);
+	}
+
+	ioc_count++;
+	return 0;
 }
-#endif
 
-/*
-** Determine if ccio should claim this chip (return 0) or not (return 1).
-** If so, initialize the chip and tell other partners in crime they
-** have work to do.
-*/
-static int
-ccio_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+struct pci_dev * ccio_get_fake(const struct parisc_device *dev)
 {
-	struct ccio_device *ioa;
+	struct ioc *ioc;
 
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
+	dev = find_pa_parent_type(dev, HPHW_IOA);
+	if(!dev)
+		return NULL;
 
-	if (ccio_list) {
-		printk(MODULE_NAME ": already initialized one device\n");
-		return(0);
-	}
+	ioc = ccio_find_ioc(dev->hw_path);
+	if(!ioc)
+		return NULL;
 
-	ioa = kmalloc(sizeof(struct ccio_device), GFP_KERNEL);
-	if (NULL == ioa)
-	{
-		printk(MODULE_NAME " - couldn't alloc ccio_device\n");
-		return(1);
-	}
-	memset(ioa, 0, sizeof(struct ccio_device));
+	if(ioc->fake_pci_dev)
+		return ioc->fake_pci_dev;
 
-	/*
-	** ccio list is used mainly as a kluge to support a single instance. 
-	** Eventually, with core dumps, it'll be useful for debugging.
-	*/
-	ccio_list = ioa;
-	ioa->iodc = d;
+	ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if(ioc->fake_pci_dev == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return NULL;
+	}
+	memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
 
-#if 1
-/* KLUGE: determine IOA hpa based on GSC port value.
-** Needed until we have a PA bus walk. Can only discover IOA via
-** walking the architected PA MMIO space as described by the I/O ACD.
-** "Legacy" PA Firmware only tells us about unarchitected devices
-** that can't be detected by PA/EISA/PCI bus walks.
-*/
-	switch((long) d->hpa) {
-	case 0xf3fbf000L:       /* C110 IOA0 LBC (aka GSC port) */
-		/* ccio_hpa same as C200 IOA0 */
-	case 0xf203f000L:       /* C180/C200/240/C360 IOA0 LBC (aka GSC port) */
-		ioa->ccio_hpa = (struct ioa_registers *) 0xfff88000L;
-		break;
-	case 0xf103f000L:       /* C180/C200/240/C360 IOA1 LBC (aka GSC port) */
-		ioa->ccio_hpa = (struct ioa_registers *) 0xfff8A000L;
-		break;
-	default:
-		panic("ccio-dma.c doesn't know this GSC port Address!\n");
-		break;
-	};
-#else
-	ioa->ccio_hpa = d->hpa;
-#endif
+	ioc->fake_pci_dev->sysdata = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+	if(ioc->fake_pci_dev->sysdata == NULL) {
+		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
+		return NULL;
+	}
 
-	ccio_alloc_pdir(ioa);
-	ccio_hw_init(ioa);
-	ccio_resmap_init(ioa);
+	HBA_DATA(ioc->fake_pci_dev->sysdata)->iommu = ioc;
+	return ioc->fake_pci_dev;
+}
 
-	/* CUJO20 KLUDGE start */
-	ccio_cujo20_hack(ioa);
-	/* CUJO20 KLUDGE end */
+/* We *can't* support JAVA (T600). Venture there at your own risk. */
+static struct parisc_device_id ccio_tbl[] = {
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
+	{ 0, }
+};
 
-	hppa_dma_ops = &ccio_ops;
+static struct parisc_driver ccio_driver = {
+	name:		"U2/Uturn",
+	id_table:	ccio_tbl,
+	probe:		ccio_probe,
+};
 
-	create_proc_info_entry(MODULE_NAME, 0, proc_runway_root, ccio_proc_info);
-	return(0);
+/**
+ * ccio_init - ccio initalization procedure.
+ *
+ * Register this driver.
+ */
+void __init ccio_init(void)
+{
+	register_parisc_driver(&ccio_driver);
 }
 
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ccio-rm-dma.c linux-2.4.20/arch/parisc/kernel/ccio-rm-dma.c
--- linux-2.4.19/arch/parisc/kernel/ccio-rm-dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/ccio-rm-dma.c	2002-10-04 00:41:13.000000000 +0000
@@ -56,26 +56,6 @@
 #define UTURN_IOA_RUNWAY 0x581
 #define UTURN_BC_GSC     0x502
 
-static int ccio_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver ccio_drivers_for[] = {
-
-   {HPHW_BCPORT, U2_BC_GSC, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "U2 I/O MMU", (void *) ccio_driver_callback},
-
-   {HPHW_BCPORT, UTURN_BC_GSC, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "Uturn I/O MMU", (void *) ccio_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
-
-
 #define IS_U2(id) ( \
     (((id)->hw_type == HPHW_IOA) && ((id)->hversion == U2_IOA_RUNWAY)) || \
     (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == U2_BC_GSC))  \
@@ -86,17 +66,10 @@
     (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == UTURN_BC_GSC))  \
 )
 
-
-void __init ccio_init(void)
-{
-	register_driver(ccio_drivers_for);
-}
-
-
 static int ccio_dma_supported( struct pci_dev *dev, u64 mask)
 {
 	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
 		BUG();
 		return(0);
 	}
@@ -182,8 +155,6 @@
 	ccio_unmap_sg,
 	NULL,                   /* dma_sync_single : NOP for U2 */
 	NULL,                   /* dma_sync_sg     : ditto */
-
-
 };
 
 
@@ -193,9 +164,11 @@
 ** have work to do.
 */
 static int
-ccio_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+ccio_probe(struct parisc_device *dev)
 {
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
+	printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
+			dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
+			dev->hpa);
 
 /*
 ** FIXME - should check U2 registers to verify it's really running
@@ -210,3 +183,20 @@
 	hppa_dma_ops = &ccio_ops;
 	return 0;
 }
+
+static struct parisc_device_id ccio_tbl[] = {
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc },
+	{ 0, }
+};
+
+static struct parisc_driver ccio_driver = {
+        name:           "U2/Uturn",
+        id_table:       ccio_tbl,
+        probe:          ccio_probe,
+};
+
+void __init ccio_init(void)
+{
+	register_parisc_driver(&ccio_driver);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/drivers.c linux-2.4.20/arch/parisc/kernel/drivers.c
--- linux-2.4.19/arch/parisc/kernel/drivers.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/drivers.c	2002-10-04 00:41:15.000000000 +0000
@@ -1,134 +1,591 @@
 /*
-
-drivers.c
-
-Copyright (c) 1999 The Puffin Group 
-
-This is a collection of routines intended to register all the devices
-in a system, and register device drivers.
-
-*/
+ * drivers.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1999 The Puffin Group
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
+ * Copyright (c) 2001 Helge Deller <deller@gmx.de>
+ * 
+ * The file handles registering devices and drivers, then matching them.
+ * It's the closest we get to a dating agency.
+ */
 
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/gsc.h>
 
+/* See comments in include/asm-parisc/pci.h */
+struct pci_dma_ops *hppa_dma_ops;
 
-extern struct hp_hardware *parisc_get_reference(
-	unsigned short hw_type, unsigned long hversion, 
-	unsigned long sversion );
+static struct parisc_driver *pa_drivers;
+static struct parisc_device root;
 
+/* This lock protects the pa_drivers list _only_ since all parisc_devices
+ * are registered before smp_init() is called.  If you wish to add devices
+ * after that, this muct be serialised somehow.  I recommend a semaphore
+ * rather than a spinlock since driver ->probe functions are allowed to
+ * sleep (for example when allocating memory).
+ */
+static spinlock_t pa_lock = SPIN_LOCK_UNLOCKED;
 
-/* I'm assuming there'll never be 64 devices.  We should probably make 
-   this more flexible.  */
+#define for_each_padev(dev) \
+	for (dev = root.child; dev != NULL; dev = next_dev(dev))
 
-#define MAX_DEVICES 64
+#define check_dev(dev) \
+	(dev->id.hw_type != HPHW_FAULTY) ? dev : next_dev(dev)
 
-unsigned int num_devices = 0;
+/**
+ * next_dev - enumerates registered devices
+ * @dev: the previous device returned from next_dev
+ *
+ * next_dev does a depth-first search of the tree, returning parents
+ * before children.  Returns NULL when there are no more devices.
+ */
+struct parisc_device *next_dev(struct parisc_device *dev)
+{
+	if (dev->child) {
+		return check_dev(dev->child);
+	} else if (dev->sibling) {
+		return dev->sibling;
+	}
 
-struct hp_device devices[MAX_DEVICES];
+	/* Exhausted tree at this level, time to go up. */
+	do {
+		dev = dev->parent;
+		if (dev && dev->sibling)
+			return dev->sibling;
+	} while (dev != &root);
 
-static unsigned long pdc_result[32] __attribute__ ((aligned (16))) = {0,0,0,0};
-static  u8 iodc_data[32] __attribute__ ((aligned (64)));
+	return NULL;
+}
 
-/*
- *	XXX should we be using a locked array ?
+/**
+ * match_device - Report whether this driver can handle this device
+ * @driver: the PA-RISC driver to try
+ * @dev: the PA-RISC device to try
  */
- 
-int register_driver(struct pa_iodc_driver *driver)
+static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
 {
-	unsigned int i;
-	struct hp_device * device;
+	const struct parisc_device_id *ids;
 
-	for (;driver->check;driver++)  {
+	for (ids = driver->id_table; ids->sversion; ids++) {
+		if ((ids->sversion != SVERSION_ANY_ID) &&
+		    (ids->sversion != dev->id.sversion))
+			continue;
+
+		if ((ids->hw_type != HWTYPE_ANY_ID) &&
+		    (ids->hw_type != dev->id.hw_type))
+			continue;
+
+		if ((ids->hversion != HVERSION_ANY_ID) &&
+		    (ids->hversion != dev->id.hversion))
+			continue;
 
-		for (i=0;i<num_devices;i++) {
-			device = &devices[i];
+		return 1;
+	}
+	return 0;
+}
 
-			if (device->managed) continue;
+static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
+{
+	dev->driver = driver;
+	request_mem_region(dev->hpa, 0x1000, driver->name);
+}
 
-			if ((driver->check & DRIVER_CHECK_HWTYPE) &&
-			    (driver->hw_type != device->hw_type))
-				continue;
-			if ((driver->check & DRIVER_CHECK_HVERSION) &&
-			    (driver->hversion != device->hversion))
-				continue;
-			if ((driver->check & DRIVER_CHECK_HVERSION_REV) &&
-			    (driver->hversion_rev != device->hversion_rev))
-				continue;
-			if ((driver->check & DRIVER_CHECK_SVERSION) &&
-			    (driver->sversion != device->sversion))
-				continue;
-			if ((driver->check & DRIVER_CHECK_SVERSION_REV) &&
-			    (driver->sversion_rev != device->sversion_rev))
-				continue;
-			if ((driver->check & DRIVER_CHECK_OPT) &&
-			    (driver->opt != device->opt))
-				continue;
-			if ( (*driver->callback)(device,driver) ==0) {
-				device->managed=1;
-			} else {
-				printk("Warning : device (%d, 0x%x, 0x%x, 0x%x, 0x%x) NOT claimed by %s %s\n",
-					device->hw_type,
-					device->hversion, device->hversion_rev,
-					device->sversion, device->sversion_rev,
-					driver->name, driver->version);
-			}
+/**
+ * register_parisc_driver - Register this driver if it can handle a device
+ * @driver: the PA-RISC driver to try
+ */
+int register_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *device;
+
+	if (driver->next) {
+		printk(KERN_WARNING 
+		       "BUG: Skipping previously registered driver: %s\n",
+		       driver->name);
+		return 1;
+	}
+
+	for_each_padev(device) {
+		if (device->driver)
+			continue;
+		if (!match_device(driver, device))
+			continue;
+
+		if (driver->probe(device) < 0)
+			continue;
+		claim_device(driver, device);
+	}
+
+	/* Note that the list is in reverse order of registration.  This
+	 * may be significant if we ever actually support hotplug and have
+	 * multiple drivers capable of claiming the same chip.
+	 */
+
+	spin_lock(&pa_lock);
+	driver->next = pa_drivers;
+	pa_drivers = driver;
+	spin_unlock(&pa_lock);
+
+	return 0;
+}
+
+/**
+ * count_parisc_driver - count # of devices this driver would match
+ * @driver: the PA-RISC driver to try
+ *
+ * Use by IOMMU support to "guess" the right size IOPdir.
+ * Formula is something like memsize/(num_iommu * entry_size).
+ */
+int count_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *device;
+	int cnt = 0;
+
+	for_each_padev(device) {
+		if (match_device(driver, device))
+			cnt++;
+	}
+
+	return cnt;
+}
+
+
+
+/**
+ * unregister_parisc_driver - Unregister this driver from the list of drivers
+ * @driver: the PA-RISC driver to unregister
+ */
+int unregister_parisc_driver(struct parisc_driver *driver)
+{
+	struct parisc_device *dev;
+
+	spin_lock(&pa_lock);
+
+	if (pa_drivers == driver) {
+		/* was head of list - update head */
+		pa_drivers = driver->next;
+	} else {
+		struct parisc_driver *prev = pa_drivers;
+
+		while (prev && driver != prev->next) {
+			prev = prev->next;
+		}
+
+		if (!prev) {
+			printk(KERN_WARNING "unregister_parisc_driver: %s wasn't registered\n", driver->name);
+		} else {
+			/* Drop driver from list */
+			prev->next = driver->next;
+			driver->next = NULL;
 		}
+
 	}
+
+	spin_unlock(&pa_lock);
+
+	for_each_padev(dev) {
+		if (dev->driver != driver)
+			continue;
+		dev->driver = NULL;
+		release_mem_region(dev->hpa, 0x1000);
+	}
+
 	return 0;
 }
 
+static struct parisc_device *find_device_by_addr(unsigned long hpa)
+{
+	struct parisc_device *dev;
+	for_each_padev(dev) {
+		if (dev->hpa == hpa)
+			return dev;
+	}
+	return NULL;
+}
 
-struct hp_device * register_module(void *hpa)
+/**
+ * find_pa_parent_type - Find a parent of a specific type
+ * @dev: The device to start searching from
+ * @type: The device type to search for.
+ *
+ * Walks up the device tree looking for a device of the specified type.
+ * If it finds it, it returns it.  If not, it returns NULL.
+ */
+const struct parisc_device *find_pa_parent_type(const struct parisc_device *dev, int type)
 {
+	while (dev != &root) {
+		if (dev->id.hw_type == type)
+			return dev;
+		dev = dev->parent;
+	}
 
-	struct hp_device * d;
+	return NULL;
+}
+
+static void
+get_node_path(struct parisc_device *dev, struct hardware_path *path)
+{
+	int i = 5;
+	memset(&path->bc, -1, 6);
+	while (dev != &root) {
+		path->bc[i--] = dev->hw_path;
+		dev = dev->parent;
+	}
+}
+
+static char *print_hwpath(struct hardware_path *path, char *output)
+{
+	int i;
+	for (i = 0; i < 6; i++) {
+		if (path->bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u/", (unsigned char) path->bc[i]);
+	}
+	output += sprintf(output, "%u", (unsigned char) path->mod);
+	return output;
+}
+
+/**
+ * print_pa_hwpath - Returns hardware path for PA devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PA device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pa_hwpath(struct parisc_device *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_node_path(dev->parent, &path);
+	path.mod = dev->hw_path;
+	return print_hwpath(&path, output);
+}
+
+
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+/**
+ * get_pci_node_path - Returns hardware path for PCI devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the hardware_path structure with the route to
+ * the specified PCI device.  This structure is suitable for passing to
+ * PDC calls.
+ */
+void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
+{
+	struct pci_bus *bus;
+	const struct parisc_device *padev;
+	int i = 5;
+
+	memset(&path->bc, -1, 6);
+	path->mod = PCI_FUNC(dev->devfn);
+	path->bc[i--] = PCI_SLOT(dev->devfn);
+	for (bus = dev->bus; bus->parent; bus = bus->parent) {
+		unsigned int devfn = bus->self->devfn;
+		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
+	}
+
+	padev = HBA_DATA(bus->sysdata)->dev;
+	while (padev != &root) {
+		path->bc[i--] = padev->hw_path;
+		padev = padev->parent;
+	}
+}
+
+/**
+ * print_pci_hwpath - Returns hardware path for PCI devices
+ * dev: The device to return the path for
+ * output: Pointer to a previously-allocated array to place the path in.
+ *
+ * This function fills in the output array with a human-readable path
+ * to a PCI device.  This string is compatible with that used by PDC, and
+ * may be printed on the outside of the box.
+ */
+char *print_pci_hwpath(struct pci_dev *dev, char *output)
+{
+	struct hardware_path path;
+
+	get_pci_node_path(dev, &path);
+	return print_hwpath(&path, output);
+}
+#endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
+
+
+struct parisc_device * create_tree_node(char id, struct parisc_device *parent,
+		struct parisc_device **insert)
+{
+	struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+	dev->hw_path = id;
+	dev->id.hw_type = HPHW_FAULTY;
+	dev->parent = parent;
+	dev->sibling = *insert;
+	*insert = dev;
+	return dev;
+}
+
+/**
+ * alloc_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @id: the element of the module path for this entry
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it allocates a new device and returns it.
+ */
+struct parisc_device *
+alloc_tree_node(struct parisc_device *parent, char id)
+{
+	struct parisc_device *prev;
+	if ((!parent->child) || (parent->child->hw_path > id)) {
+		return create_tree_node(id, parent, &parent->child);
+	}
+
+	prev = parent->child;
+	if (prev->hw_path == id)
+		return prev;
+
+	while (prev->sibling && prev->sibling->hw_path < id) {
+		prev = prev->sibling;
+	}
+
+	if ((prev->sibling) && (prev->sibling->hw_path == id))
+		return prev->sibling;
+
+	return create_tree_node(id, parent, &prev->sibling);
+}
+
+static struct parisc_device *find_parisc_device(struct hardware_path *modpath)
+{
+	int i;
+	struct parisc_device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = alloc_tree_node(parent, modpath->bc[i]);
+	}
+	return alloc_tree_node(parent, modpath->mod);
+}
+
+struct parisc_device *
+alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
+{
 	int status;
+	unsigned long bytecnt;
+	u8 iodc_data[32];
+	struct parisc_device *dev;
+	const char *name;
+
+	/* Check to make sure this device has not already been added - Ryan */
+	if (find_device_by_addr(hpa) != NULL)
+		return NULL;
+
+	status = pdc_iodc_read(&bytecnt, hpa, 0, &iodc_data, 32);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = find_parisc_device(mod_path);
+	if (dev->id.hw_type != HPHW_FAULTY) {
+		char p[64];
+		print_pa_hwpath(dev, p);
+		printk("Two devices have hardware path %s.  Please file a bug with HP.\n"
+			"In the meantime, you could try rearranging your cards.\n", p);
+		return NULL;
+	}
+
+	dev->id.hw_type = iodc_data[3] & 0x1f;
+	dev->id.hversion = (iodc_data[0] << 4) | ((iodc_data[1] & 0xf0) >> 4);
+	dev->id.hversion_rev = iodc_data[1] & 0x0f;
+	dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
+			(iodc_data[5] << 8) | iodc_data[6];
+	dev->hpa = hpa;
+	name = parisc_hardware_description(&dev->id);
+	if (name) {
+		strncpy(dev->name, name, sizeof(dev->name)-1);
+	}
+
+	return dev;
+}
 
-	d = &devices[num_devices];
-	status = pdc_iodc_read(&pdc_result,hpa,0,&iodc_data,32 );
-	if (status !=PDC_RET_OK) {
-		/* There is no device here, so we'll skip it */
+/**
+ * register_parisc_device - Locate a driver to manage this device.
+ * @dev: The parisc device.
+ *
+ * Search the driver list for a driver that is willing to manage
+ * this device.
+ */
+int register_parisc_device(struct parisc_device *dev)
+{
+	struct parisc_driver *driver;
+
+	if (!dev)
 		return 0;
+
+	if (dev->driver)
+		return 1;
+	
+	spin_lock(&pa_lock);
+
+	/* Locate a driver which agrees to manage this device.  */
+	for (driver = pa_drivers; driver; driver = driver->next) {
+		if (!match_device(driver,dev))
+			continue;
+		if (driver->probe(dev) == 0)
+			break;
 	}
 
-	d->hw_type = iodc_data[3]&0x1f;
-	d->hversion = (iodc_data[0]<<4)|((iodc_data[1]&0xf0)>>4);
-	d->sversion = 
-		((iodc_data[4]&0x0f)<<16)|(iodc_data[5]<<8)|(iodc_data[6]);
-	d->hversion_rev = iodc_data[1]&0x0f;
-	d->sversion_rev = iodc_data[4]>>4;
-	d->opt = iodc_data[7];
-	d->hpa = hpa;
-	d->managed=0;
-	d->reference = parisc_get_reference(d->hw_type, d->hversion, 
-								d->sversion);
-		
-	num_devices++;	
+	if (driver != NULL) {
+		claim_device(driver, dev);
+	}
+	spin_unlock(&pa_lock);
+	return driver != NULL;
+}
+
+#define BC_PORT_MASK 0x8
+#define BC_LOWER_PORT 0x8
+
+#define BUS_CONVERTER(dev) \
+        ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
+
+#define IS_LOWER_PORT(dev) \
+        ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
+                & BC_PORT_MASK) == BC_LOWER_PORT)
+
+#define READ_IO_IO_LOW(dev) \
+	(dev->id.hw_type == HPHW_IOA ? \
+	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \
+	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low))
 
-	return d;
-}	
+static void walk_native_bus(unsigned long addr, struct parisc_device *parent);
+void walk_lower_bus(struct parisc_device *dev)
+{
+
+	if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
+		return;
 
-void print_devices(char * buf) {
+	walk_native_bus((unsigned long)(signed int)READ_IO_IO_LOW(dev), dev);
+}
 
+#define MAX_NATIVE_DEVICES 64
+#define NATIVE_DEVICE_OFFSET 0x1000
+
+/**
+ * walk_native_bus -- Probe a bus for devices
+ * @addr: Base address of this bus.
+ * 
+ * A native bus (eg Runway or GSC) may have up to 64 devices on it,
+ * spaced at intervals of 0x1000 bytes.  PDC may not inform us of these
+ * devices, so we have to probe for them.  Unfortunately, we may find
+ * devices which are not physically connected (such as extra serial &
+ * keyboard ports).  This problem is not yet solved.
+ */
+static void walk_native_bus(unsigned long addr, struct parisc_device *parent)
+{
 	int i;
-	struct hp_device *d;
-	printk("Found devices:\n");
-	for (i=0;i<num_devices;i++) {	
-		d = &devices[i];
-		printk(KERN_INFO 
-		"%d. %s (%d) at 0x%p, versions 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", 
-		i+1,
-		(d->reference) ? d->reference->name : "Unknown device",
-		d->hw_type,d->hpa, d->hversion, d->hversion_rev,
-		d->sversion, d->sversion_rev, d->opt);
+	struct hardware_path path;
+
+	get_node_path(parent, &path);
+	for (i = 0; i < MAX_NATIVE_DEVICES; i++) {
+		unsigned long hpa = (addr + i * NATIVE_DEVICE_OFFSET);
+		struct parisc_device *dev;
+
+		/* Was the device already added by Firmware? */
+		dev = find_device_by_addr(hpa);
+		if (!dev) {
+			path.mod = i;
+			dev = alloc_pa_dev(hpa, &path);
+			if (!dev)
+				continue;
+
+			register_parisc_device(dev);
+		}
+		walk_lower_bus(dev);
+	}
+}
+
+#define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
+
+/**
+ * walk_central_bus - Find devices attached to the central bus
+ *
+ * PDC doesn't tell us about all devices in the system.  This routine
+ * finds devices connected to the central bus.
+ */
+void walk_central_bus(void)
+{
+	walk_native_bus(CENTRAL_BUS_ADDR, &root);
+}
+
+void fixup_child_irqs(struct parisc_device *parent, int base,
+			int (*choose_irq)(struct parisc_device *))
+{
+	struct parisc_device *dev;
 
+	if (!parent->child)
+		return;
+
+	for (dev = check_dev(parent->child); dev; dev = dev->sibling) {
+		int irq = choose_irq(dev);
+		if (irq > 0) {
+#ifdef __LP64__
+			irq += 32;
+#endif
+			dev->irq = base + irq;
+		}
 	}
-	printk("That's a total of %d devices.\n",num_devices);
 }
 
+static void print_parisc_device(struct parisc_device *dev)
+{
+	char hw_path[64];
+	static int count;
 
+	print_pa_hwpath(dev, hw_path);
+	printk(KERN_INFO "%d. %s (%d) at 0x%lx [%s], versions 0x%x, 0x%x, 0x%x",
+		++count, dev->name, dev->id.hw_type, dev->hpa, hw_path,
+		dev->id.hversion, dev->id.hversion_rev, dev->id.sversion);
+
+	if (dev->num_addrs) {
+		int k;
+		printk(",  additional addresses: ");
+		for (k = 0; k < dev->num_addrs; k++)
+			printk("0x%lx ", dev->addr[k]);
+	}
+	printk("\n");
+}
+
+void print_subdevices(struct parisc_device *parent)
+{
+	struct parisc_device *dev;
+	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
+		print_parisc_device(dev);
+	}
+}
+
+/**
+ * print_parisc_devices - Print out a list of devices found in this system
+ */
+void print_parisc_devices(void)
+{
+	struct parisc_device *dev;
+	for_each_padev(dev) {
+		print_parisc_device(dev);
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/entry.S linux-2.4.20/arch/parisc/kernel/entry.S
--- linux-2.4.19/arch/parisc/kernel/entry.S	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/entry.S	2002-10-04 00:41:13.000000000 +0000
@@ -1,5 +1,5 @@
-/*------------------------------------------------------------------------------
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+/*
+ * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  *
  * kernel entry points (interruptions, system call wrappers)
  *  Copyright (C) 1999,2000 Philipp Rumpf 
@@ -25,39 +25,51 @@
 #include <linux/config.h>
 #include <asm/offset.h>
 
-/* the following is the setup i think we should follow:
- * whenever the CPU is interruptible, the following has to be true:
- *  CR30 is the kernel sp or 0 if we currently use the kernel stack
- *  CR31 is the kernel gp */ 
-
 /* we have the following possibilities to act on an interruption:
  *  - handle in assembly and use shadowed registers only
  *  - save registers to kernel stack and handle in assembly or C */
 
-	.text
-
-#ifdef __LP64__
-	.level 2.0w
-#endif
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>	/* for LDREG/STREG defines */
 #include <asm/pgtable.h>
 #include <asm/psw.h>
 #include <asm/signal.h>
+#include <asm/unistd.h>
 
 #ifdef __LP64__
-#define FRAME_SIZE	64
+#define FRAME_SIZE	128
+#define CMPIB           cmpib,*
+#define CMPB            cmpb,*
+
+	.level 2.0w
 #else
 #define FRAME_SIZE	64
+#define CMPIB           cmpib,
+#define CMPB            cmpb,
+
+	.level 2.0
+#endif
+
+	.import         pa_dbit_lock,data
+
+	/* space_to_prot macro creates a prot id from a space id */
+
+#if (SPACEID_SHIFT) == 0
+	.macro  space_to_prot spc prot
+	depd,z  \spc,62,31,\prot
+	.endm
+#else
+	.macro  space_to_prot spc prot
+	extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
+	.endm
 #endif
 
 	/* Switch to virtual mapping, trashing only %r1 */
-	.macro	virt_map rfi_type
-	mtsm	%r0
-	tovirt	%r29
-	tovirt	%r30
+	.macro  virt_map
+	rsm     PSW_SM_Q,%r0
+	tovirt_r1 %r29
 	mfsp	%sr7, %r1
+	or,=    %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
 	mtsp	%r1, %sr3
 	mtsp	%r0, %sr4
 	mtsp	%r0, %sr5
@@ -65,95 +77,114 @@
 	mtsp	%r0, %sr7
 	ldil	L%KERNEL_PSW, %r1
 	ldo	R%KERNEL_PSW(%r1), %r1
-	LDIL_FIXUP(%r1)
 	mtctl	%r1, %cr22
 	mtctl	%r0, %cr17
 	mtctl	%r0, %cr17
-	ldil	L%.+28, %r1
-	ldo	R%.+24(%r1), %r1
-	LDIL_FIXUP(%r1)
+	ldil	L%4f, %r1
+	ldo	R%4f(%r1), %r1
 	mtctl	%r1, %cr18
 	ldo	4(%r1), %r1
 	mtctl	%r1, %cr18
-	\rfi_type
+	rfir
 	nop
+4:
 	.endm
 
-	.macro	get_stack
-	mfctl	%cr30, %r1 
-	comib,=,n 0, %r1, 0f   /* forward so predicted not taken */
+	/*
+	 * The "get_stack" macros are responsible for determining the
+	 * kernel stack value.
+	 *
+	 * For Faults:
+	 *      If sr7 == 0
+	 *          Already using a kernel stack, so call the
+	 *          get_stack_use_r30 macro to push a pt_regs structure
+	 *          on the stack, and store registers there.
+	 *      else
+	 *          Need to set up a kernel stack, so call the
+	 *          get_stack_use_cr30 macro to set up a pointer
+	 *          to the pt_regs structure contained within the
+	 *          task pointer pointed to by cr30. Set the stack
+	 *          pointer to point to the end of the task structure.
+	 *
+	 * For Interrupts:
+	 *      If sr7 == 0
+	 *          Already using a kernel stack, check to see if r30
+	 *          is already pointing to the per processor interrupt
+	 *          stack. If it is, call the get_stack_use_r30 macro
+	 *          to push a pt_regs structure on the stack, and store
+	 *          registers there. Otherwise, call get_stack_use_cr31
+	 *          to get a pointer to the base of the interrupt stack
+	 *          and push a pt_regs structure on that stack.
+	 *      else
+	 *          Need to set up a kernel stack, so call the
+	 *          get_stack_use_cr30 macro to set up a pointer
+	 *          to the pt_regs structure contained within the
+	 *          task pointer pointed to by cr30. Set the stack
+	 *          pointer to point to the end of the task structure.
+	 *          N.B: We don't use the interrupt stack for the
+	 *          first interrupt from userland, because signals/
+	 *          resched's are processed when returning to userland,
+	 *          and we can sleep in those cases.
+	 *
+	 * Note that we use shadowed registers for temps until
+	 * we can save %r26 and %r29. %r26 is used to preserve
+	 * %r8 (a shadowed register) which temporarily contained
+	 * either the fault type ("code") or the eirr. We need
+	 * to use a non-shadowed register to carry the value over
+	 * the rfir in virt_map. We use %r26 since this value winds
+	 * up being passed as the argument to either do_cpu_irq_mask
+	 * or handle_interruption. %r29 is used to hold a pointer
+	 * the register save area, and once again, it needs to
+	 * be a non-shadowed register so that it survives the rfir.
+	 *
+	 * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
+	 */
+
+	.macro  get_stack_use_cr30
 
 	/* we save the registers in the task struct */
-	ldo	TASK_REGS(%r1), %r29
-	tophys	%r29
-	STREG	%r30, PT_GR30(%r29)
-	STREG	%r1,  PT_CR30(%r29)
+
+	mfctl   %cr30, %r1
+	tophys  %r1,%r9
+	ldo     TASK_REGS(%r9),%r9
+	STREG   %r30, PT_GR30(%r9)
 	ldo	TASK_SZ_ALGN(%r1), %r30
-	b	1f		    /* unconditional so predicted taken */	
-	mtctl	%r0,%cr30
-0:
-	/* we put a struct pt_regs on the stack and save the registers there */
-	copy	%r30,%r29
-	ldo	PT_SZ_ALGN(%r30),%r30
-	tophys	%r29
-	STREG	%r30,PT_GR30(%r29)
-	STREG	%r0,PT_CR30(%r29)
-1:
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	copy    %r9,%r29
 	.endm
 
-	.macro	rest_stack regs
-	LDREG	PT_CR30(\regs), %r1
-	comib,=,n 0, %r1, 2f/* forward so predicted not taken */
-
-	/* we restore the registers out of the task struct */
-	mtctl	%r1, %cr30
-	LDREG	PT_GR1(\regs), %r1
-	LDREG	PT_GR30(\regs),%r30
-	b	3f
-	LDREG	PT_GR29(\regs),%r29
-2:
-	/* we take a struct pt_regs off the stack */
-	LDREG	PT_GR1(\regs),  %r1
-	LDREG	PT_GR29(\regs), %r29
-	ldo	-PT_SZ_ALGN(%r30), %r30
-3:
-	.endm
+	.macro  get_stack_use_r30
 
-#ifdef OLD
-	/* fixme interruption handler */
-	.macro	def code
-	/* WARNING!!! THIS IS DEBUG CODE ONLY!!! */
-	b	unimplemented_64bitirq
-	ldi	\code, %r1
-	.align	32
+	/* we put a struct pt_regs on the stack and save the registers there */
+
+	tophys  %r30,%r9
+	STREG   %r30,PT_GR30(%r9)
+	ldo	PT_SZ_ALGN(%r30),%r30
+	STREG   %r29,PT_GR29(%r9)
+	STREG   %r26,PT_GR26(%r9)
+	copy    %r9,%r29
 	.endm
 
-	/* Use def to enable break - KWDB wants em
-	 * (calls traps.c:handle_interruption) */
-	.macro	pass_break code
+	.macro  rest_stack
+	LDREG   PT_GR1(%r29), %r1
+	LDREG   PT_GR30(%r29),%r30
+	LDREG   PT_GR29(%r29),%r29
+	.endm
 
-#else
 	/* default interruption handler
 	 * (calls traps.c:handle_interruption) */
 	.macro	def code
-#endif
-	mtctl	%r29, %cr31
-	mtctl	%r1,  %cr28
-	ldi	\code, %r1
 	b	intr_save
-	mtctl   %r1, %cr29
+	ldi     \code, %r8
 	.align	32
 	.endm
 
 	/* Interrupt interruption handler
-	 * (calls irq.c:do_irq_mask) */
+	 * (calls irq.c:do_cpu_irq_mask) */
 	.macro	extint code
-	mtctl	%r29, %cr31
-	mtctl	%r1,  %cr28
-	mfctl	%cr23, %r1
-	mtctl	%r1, %cr23
 	b	intr_extint
-	mtctl	%r1, %cr29
+	mfsp    %sr7,%r16
 	.align	32
 	.endm	
 
@@ -203,7 +234,6 @@
 	 */
 
 	.macro	itlb_20 code
-
 	mfctl	%pcsq, spc
 #ifdef __LP64__
 	b       itlb_miss_20w
@@ -298,37 +328,27 @@
 	.endm
 	
 #ifndef __LP64__
-	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit)
-	 *
-	 * Note: nadtlb misses will be treated
-	 * as an ordinary dtlb miss for now.
-	 *
-	 */
+	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
 
 	.macro	nadtlb_11 code
 
 	mfctl	%isr,spc
-	b	dtlb_miss_11
+	b       nadtlb_miss_11
 	mfctl	%ior,va
 
 	.align		32
 	.endm
 #endif
 	
-	/* nadtlb miss interruption handler (parisc 2.0)
-	 *
-	 * Note: nadtlb misses will be treated
-	 * as an ordinary dtlb miss for now.
-	 *
-	 */
+	/* nadtlb miss interruption handler (parisc 2.0) */
 
 	.macro	nadtlb_20 code
 
 	mfctl	%isr,spc
 #ifdef __LP64__
-	b       dtlb_miss_20w
+	b       nadtlb_miss_20w
 #else
-	b	dtlb_miss_20
+	b       nadtlb_miss_20
 #endif
 	mfctl	%ior,va
 
@@ -372,13 +392,14 @@
 	 * fault_vector_11 and fault_vector_20 are on the
 	 * same page. This is only necessary as long as we
 	 * write protect the kernel text, which we may stop
-	 * doing once we use large parge translations to cover
+	 * doing once we use large page translations to cover
 	 * the static part of the kernel address space.
 	 */
 
-
 	.export fault_vector_20
 
+	.text
+
 	.align 4096
 
 fault_vector_20:
@@ -402,7 +423,11 @@
 	def		13
 	def		14
 	dtlb_20		15
+#if 0
 	naitlb_20	16
+#else
+	def             16
+#endif
 	nadtlb_20	17
 	def		18
 	def		19
@@ -446,7 +471,11 @@
 	def		13
 	def		14
 	dtlb_11		15
+#if 0
 	naitlb_11	16
+#else
+	def             16
+#endif
 	nadtlb_11	17
 	def		18
 	def		19
@@ -467,7 +496,7 @@
 
 	.import		handle_interruption,code
 	.import		handle_real_interruption,code
-	.import		do_irq_mask,code
+	.import		do_cpu_irq_mask,code
 	.import		parisc_stopkernel,code
 	.import		cpu_irq_region,data
 
@@ -492,7 +521,8 @@
 	ldo	PT_SZ_ALGN(%r30),%r30
 #ifdef __LP64__
 	/* Yo, function pointers in wide mode are little structs... -PB */
-	/* XXX FIXME do we need to honor the fptr's %dp value too? */
+	ldd	24(%r26), %r2
+	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
 	ldd	16(%r26), %r26
 #endif
 	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */
@@ -500,15 +530,17 @@
 	ldo	CLONE_VM(%r0), %r26   /* Force CLONE_VM since only init_mm */
 	or	%r26, %r24, %r26      /* will have kernel mappings.	 */
 	copy	%r0, %r25
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl	do_fork, %r2
 	copy	%r1, %r24
 
 	/* Parent Returns here */
 
-	ldo	-PT_SZ_ALGN(%r30), %r30
-	LDREG	-RP_OFFSET(%r30), %r2
+	LDREG	-PT_SZ_ALGN-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
-	nop
+	ldo	-PT_SZ_ALGN(%r30), %r30
 
 	/*
 	 * Child Returns here
@@ -520,11 +552,22 @@
 	.export	ret_from_kernel_thread
 ret_from_kernel_thread:
 
+	/* Call schedule_tail first though */
+	bl	schedule_tail, %r2
+	nop
+
 	LDREG	TASK_PT_GR26-TASK_SZ_ALGN(%r30), %r1
 	LDREG	TASK_PT_GR25-TASK_SZ_ALGN(%r30), %r26
+#ifdef __LP64__
+	LDREG	TASK_PT_GR27-TASK_SZ_ALGN(%r30), %r27
+#endif
 	ble	0(%sr7, %r1)
 	copy	%r31, %r2
 
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+	loadgp				/* Thread could have been in a module */
+#endif
 	b	sys_exit
 	ldi	0, %r26
 
@@ -532,23 +575,22 @@
 	.export	__execve, code
 __execve:
 	copy	%r2, %r15
-	copy	%r23, %r17
 	copy	%r30, %r16
 	ldo	PT_SZ_ALGN(%r30), %r30
 	STREG	%r26, PT_GR26(%r16)
 	STREG	%r25, PT_GR25(%r16)
 	STREG	%r24, PT_GR24(%r16)
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl	sys_execve, %r2
 	copy	%r16, %r26
 
-	comib,<>,n 0,%r28,__execve_failed
-
-	b	intr_return
-	STREG	%r17, PT_CR30(%r16)
+	cmpib,=,n 0,%r28,intr_return    /* forward */
 
-__execve_failed:
 	/* yes, this will trap and die. */
 	copy	%r15, %r2
+	copy	%r16, %r30
 	bv	%r0(%r2)
 	nop
 
@@ -567,16 +609,14 @@
 
 	ldil	L%_switch_to_ret, %r2
 	ldo	R%_switch_to_ret(%r2), %r2
-	LDIL_FIXUP(%r2)
 
 	STREG	%r2, TASK_PT_KPC(%r26)
 	LDREG	TASK_PT_KPC(%r25), %r2
 
 	STREG	%r30, TASK_PT_KSP(%r26)
 	LDREG	TASK_PT_KSP(%r25), %r30
-
 	bv	%r0(%r2)
-	nop
+	mtctl   %r25,%cr30
 
 _switch_to_ret:
 	mtctl	%r0, %cr0		/* Needed for single stepping */
@@ -587,27 +627,30 @@
 	copy	%r26, %r28
 
 	/*
-	 * Common rfi return path for interruptions, kernel execve, and some
-	 * syscalls.  The sys_rt_sigreturn syscall will return via this path
-	 * if the signal was received when the process was running; if the
-	 * process was blocked on a syscall then the normal syscall_exit
-	 * path is used.  All syscalls for traced proceses exit via
-	 * intr_restore.
-	 * Note that the following code uses a "relied upon translation". See
-	 * the parisc ACD for details. The ssm is necessary due to a PCXT bug.
+	 * Common rfi return path for interruptions, kernel execve, and
+	 * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
+	 * return via this path if the signal was received when the process
+	 * was running; if the process was blocked on a syscall then the
+	 * normal syscall_exit path is used.  All syscalls for traced
+	 * proceses exit via intr_restore.
+	 *
+	 * XXX If any syscalls that change a processes space id ever exit
+	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
+	 * adjust IASQ[0..1].
+	 *
+	 * Note that the following code uses a "relied upon translation".
+	 * See the parisc ACD for details. The ssm is necessary due to a
+	 * PCXT bug.
 	 */
 
 	.align 4096
 
 	.export	syscall_exit_rfi
 syscall_exit_rfi:
-	copy    %r30,%r16
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r16 /* get task pointer */
+	mfctl   %cr30,%r16
 	ldo	TASK_REGS(%r16),%r16
 	/* Force iaoq to userspace, as the user has had access to our current
-	 * context via sigcontext.
-	 * XXX do we need any other protection here?
+	 * context via sigcontext. Also Filter the PSW for the same reason.
 	 */
 	LDREG	PT_IAOQ0(%r16),%r19
 	depi	3,31,2,%r19
@@ -615,57 +658,84 @@
 	LDREG	PT_IAOQ1(%r16),%r19
 	depi	3,31,2,%r19
 	STREG	%r19,PT_IAOQ1(%r16)
-	
+	LDREG   PT_PSW(%r16),%r19
+	ldil    L%USER_PSW_MASK,%r1
+	ldo     R%USER_PSW_MASK(%r1),%r1
+#ifdef __LP64__
+	ldil    L%USER_PSW_HI_MASK,%r20
+	ldo     R%USER_PSW_HI_MASK(%r20),%r20
+	depd    %r20,31,32,%r1
+#endif
+	and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
+	ldil    L%USER_PSW,%r1
+	ldo     R%USER_PSW(%r1),%r1
+	or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
+	STREG   %r19,PT_PSW(%r16)
+
+	/*
+	 * If we aren't being traced, we never saved space registers
+	 * (we don't store them in the sigcontext), so set them
+	 * to "proper" values now (otherwise we'll wind up restoring
+	 * whatever was last stored in the task structure, which might
+	 * be inconsistant if an interrupt occured while on the gateway
+	 * page) Note that we may be "trashing" values the user put in
+	 * them, but we don't support the the user changing them.
+	 */
+
+	STREG   %r0,PT_SR2(%r16)
+	mfsp    %sr3,%r19
+	STREG   %r19,PT_SR0(%r16)
+	STREG   %r19,PT_SR1(%r16)
+	STREG   %r19,PT_SR3(%r16)
+	STREG   %r19,PT_SR4(%r16)
+	STREG   %r19,PT_SR5(%r16)
+	STREG   %r19,PT_SR6(%r16)
+	STREG   %r19,PT_SR7(%r16)
+
 intr_return:
+	ssm     PSW_SM_I, %r0
 
 	/* Check for software interrupts */
 
 	.import irq_stat,data
 
-	ldil    L%irq_stat,%r19
-	ldo     R%irq_stat(%r19),%r19
-	LDIL_FIXUP(%r19)
-
+	ldil	L%irq_stat,%r19
+	ldo	R%irq_stat(%r19),%r19
 #ifdef CONFIG_SMP
-	copy    %r30,%r1
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r1 /* get task pointer */
-	ldw     TASK_PROCESSOR(%r1),%r20 /* get cpu # - int */
-#if (IRQSTAT_SZ == 32)
-	dep     %r20,26,27,%r20 /* shift left 5 bits */
-#else
-#error IRQSTAT_SZ changed, fix dep
-#endif /* IRQSTAT_SZ */
-	add     %r19,%r20,%r19
+	mfctl   %cr30,%r1
+	ldw	TASK_PROCESSOR(%r1),%r1 /* get cpu # - int */
+	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
+	** irq_stat[] is defined using ____cacheline_aligned.
+	*/
+#ifdef __LP64__
+	shld	%r1, 6, %r20
+#else
+	shlw	%r1, 5, %r20
+#endif
+	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
 #endif /* CONFIG_SMP */
 
-	ldw     IRQSTAT_SI_ACTIVE(%r19),%r20	/* hardirq.h: unsigned int */
-	ldw     IRQSTAT_SI_MASK(%r19),%r19	/* hardirq.h: unsigned int */
-	and     %r19,%r20,%r20
-	comib,<>,n 0,%r20,intr_do_softirq /* forward */
+	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+	cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
 
 intr_check_resched:
 
 	/* check for reschedule */
-	copy    %r30,%r1
-	/* FIXME! depi below has hardcoded dependency on kernel stack size */
-	depi    0,31,14,%r1 /* get task pointer */
+	mfctl   %cr30,%r1
 	LDREG     TASK_NEED_RESCHED(%r1),%r19	/* sched.h: long need_resched */
-	comib,<>,n 0,%r19,intr_do_resched /* forward */
+	CMPIB<>,n 0,%r19,intr_do_resched /* forward */
 
 intr_check_sig:
 	/* As above */
-	copy    %r30,%r1
-	depi    0,31,14,%r1 /* get task pointer */
+	mfctl   %cr30,%r1
 	ldw	TASK_SIGPENDING(%r1),%r19	/* sched.h: int sigpending */
-	comib,<>,n 0,%r19,intr_do_signal /* forward */
+	cmpib,<>,n 0,%r19,intr_do_signal /* forward */
 
 intr_restore:
-	copy	    	%r16, %r29
-	ldo		PT_FR31(%r29), %r29
-	rest_fp		%r29
-	copy    	%r16, %r29
-	rest_general 	%r29
+	copy            %r16,%r29
+	ldo             PT_FR31(%r29),%r1
+	rest_fp         %r1
+	rest_general    %r29
 	ssm		0,%r0
 	nop
 	nop
@@ -674,10 +744,10 @@
 	nop
 	nop
 	nop
-	tophys		%r29
-	mtsm		%r0
+	tophys_r1       %r29
+	rsm             (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
 	rest_specials	%r29
-	rest_stack	%r29
+	rest_stack
 	rfi
 	nop
 	nop
@@ -691,88 +761,175 @@
 	.import do_softirq,code
 intr_do_softirq:
 	bl      do_softirq,%r2
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	nop
+#endif
 	b       intr_check_resched
 	nop
 
 	.import schedule,code
 intr_do_resched:
 	/* Only do reschedule if we are returning to user space */
-	LDREG     PT_SR7(%r16), %r20
-	comib,= 0,%r20,intr_restore /* backward */
+	LDREG   PT_IASQ0(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
+	nop
+	LDREG   PT_IASQ1(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
 
-	bl      schedule,%r2
-	ssm     PSW_SM_I, %r0
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
+
+	ldil	L%intr_return, %r2
+	b	schedule
+	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
 
-	/* It's OK to leave I bit on */
-	b       intr_return /* start over if we got a resched */
-	nop
 
 	.import do_signal,code
 intr_do_signal:
 	/* Only do signals if we are returning to user space */
-	LDREG   PT_SR7(%r16), %r20
-	comib,= 0,%r20,intr_restore /* backward */
+	LDREG   PT_IASQ0(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
+	nop
+	LDREG   PT_IASQ1(%r16), %r20
+	CMPIB= 0,%r20,intr_restore /* backward */
 	nop
 
 	copy	%r0, %r24			/* unsigned long in_syscall */
 	copy	%r16, %r25			/* struct pt_regs *regs */
 	ssm     PSW_SM_I, %r0
+#ifdef __LP64__
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
 	b	intr_restore
 	nop
 
-	/* CR28 - saved GR1
-	 * CR29 - argument for do_irq_mask */
+	/*
+	 * External interrupts.
+	 */
 
-	/* External interrupts */
 intr_extint:
-	get_stack
+	CMPIB=,n 0,%r16,1f
+	get_stack_use_cr30
+	b,n 3f
+
+1:
+#if 0  /* Interrupt Stack support not working yet! */
+	mfctl	%cr31,%r1
+	copy	%r30,%r17
+	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
+#ifdef __LP64__
+	depdi	0,63,15,%r17
+#else
+	depi	0,31,15,%r17
+#endif
+	CMPB=,n	%r1,%r17,2f
+	get_stack_use_cr31
+	b,n 3f
+#endif
+2:
+	get_stack_use_r30
+
+3:
 	save_specials	%r29
-	virt_map	rfi
+	virt_map
 	save_general	%r29
 
-	ldo		PT_FR0(%r29), %r24
-	save_fp		%r24
+	ldo	PT_FR0(%r29), %r24
+	save_fp	%r24
 	
 	loadgp
 
-	copy		%r29, %r24	/* arg2 is pt_regs */
-	copy		%r29, %r16	/* save pt_regs */
+	copy	%r29, %r25	/* arg1 is pt_regs */
+	copy	%r29, %r16	/* save pt_regs */
 #ifdef CONFIG_KWDB
-	copy		%r29, %r3	/* KWDB - update frame pointer (gr3) */
+	copy	%r29, %r3	/* KWDB - update frame pointer (gr3) */
 #endif
 
-	/* sorry to put this cruft in the interrupt path */
-	ldil		L%cpu_irq_region, %r25
-	ldo		R%cpu_irq_region(%r25), %r25
-	bl		do_irq_mask,%r2
 #ifdef __LP64__
-	LDIL_FIXUP(%r25)
+	ldo	-16(%r30),%r29	/* Reference param save area */
 #else
 	nop
 #endif
-
-	b		intr_return
-	nop
+	
+	/*
+	 * We need to either load the CPU's ID or IRQ region.
+	 * Until we have "per CPU" IRQ regions, this is easy.
+	 */
+	ldil	L%cpu_irq_region, %r26
+	ldil	L%intr_return, %r2
+	ldo	R%cpu_irq_region(%r26), %r26
+	
+	b	do_cpu_irq_mask
+	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
 
 	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
 
 	.export         intr_save, code /* for os_hpmc */
 
 intr_save:
-	get_stack
+	mfsp    %sr7,%r16
+	CMPIB=,n 0,%r16,1f
+	get_stack_use_cr30
+	b	2f
+	copy    %r8,%r26
+
+1:
+	get_stack_use_r30
+	copy    %r8,%r26
+
+2:
 	save_specials	%r29
 
-	mfctl		%cr20, %r1
-	STREG		%r1, PT_ISR(%r29)
-	mfctl		%cr21, %r1
-	STREG		%r1, PT_IOR(%r29)
+	/* If this trap is a itlb miss, skip saving/adjusting isr/ior */
+
+	/*
+	 * FIXME: 1) Use a #define for the hardwired "6" below (and in
+	 *           traps.c.
+	 *        2) Once we start executing code above 4 Gb, we need
+	 *           to adjust iasq/iaoq here in the same way we
+	 *           adjust isr/ior below.
+	 */
+
+	CMPIB=,n        6,%r26,skip_save_ior
+
+	/* save_specials left ipsw value in r8 for us to test */
+
+	mfctl           %cr20, %r16 /* isr */
+	mfctl           %cr21, %r17 /* ior */
+
+#ifdef __LP64__
+	/*
+	 * If the interrupted code was running with W bit off (32 bit),
+	 * clear the b bits (bits 0 & 1) in the ior.
+	 */
+	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
+	depdi           0,1,2,%r17
+
+	/*
+	 * FIXME: This code has hardwired assumptions about the split
+	 *        between space bits and offset bits. This will change
+	 *        when we allow alternate page sizes.
+	 */
+
+	/* adjust isr/ior. */
+
+	extrd,u         %r16,63,7,%r1    /* get high bits from isr for ior */
+	depd            %r1,31,7,%r17    /* deposit them into ior */
+	depdi           0,63,7,%r16      /* clear them from isr */
+#endif
+	STREG           %r16, PT_ISR(%r29)
+	STREG           %r17, PT_IOR(%r29)
+
 
-	virt_map	rfi
+skip_save_ior:
+	virt_map
 	save_general	%r29
 
 	ldo		PT_FR0(%r29), %r25
@@ -785,11 +942,16 @@
 	copy		%r29, %r3	/* KWDB - update frame pointer (gr3) */
 #endif
 
-	bl		handle_interruption,%r2
-	copy		%r29, %r16	/* save pt_regs */
+#ifdef __LP64__
+	ldo		-16(%r30),%r29	/* Reference param save area */
+#endif
+
+	ldil		L%intr_return, %r2
+	copy		%r25, %r16	/* save pt_regs */
+
+	b		handle_interruption
+	ldo		R%intr_return(%r2), %r2	/* return to intr_return */
 
-	b		intr_return
-	nop
 
 	/*
 	 * Note for all tlb miss handlers:
@@ -821,10 +983,9 @@
 #ifdef __LP64__
 
 dtlb_miss_20w:
-
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -832,20 +993,20 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,*<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldd,s           t1(ptp),ptp
 	extrd,u         va,42,9,t0     /* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 	depdi           0,63,12,ptp     /* clear prot bits */
 
 	/* Second level page table lookup */
 
 	ldd,s           t0(ptp),ptp
 	extrd,u         va,51,9,t0     /* get third-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 	depdi           0,63,12,ptp     /* clear prot bits */
 
 	/* Third level page table lookup */
@@ -853,7 +1014,7 @@
 	shladd           t0,3,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldd              0(ptp),pte
-	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -861,11 +1022,9 @@
 	and,*<>         t1,pte,%r0      /* test and nullify if already set */
 	std             t0,0(ptp)       /* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -874,11 +1033,106 @@
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
 	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
-	idtlbt		%r16,%r17
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
 
 	rfir
 	nop
+
+dtlb_check_alias_20w:
+
+	/* Check to see if fault is in the temporary alias region */
+
+	cmpib,*<>,n     0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depdi           0,63,23,t1
+	cmpb,*<>,n      t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depd,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrd,u,*=      va,41,1,r0
+	or,*tr          %r23,%r0,pte    /* If "from" use "from" page */
+	or,*            %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20w:
+	extrd,u         spc,63,7,t1     /* adjust va */
+	depd            t1,31,7,va      /* adjust va */
+	depdi           0,63,7,spc      /* adjust space */
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extrd,u         va,33,9,t1      /* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
+	cmpb,*<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldd,s           t1(ptp),ptp
+	extrd,u         va,42,9,t0     /* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depdi           0,63,12,ptp     /* clear prot bits */
+
+	/* Second level page table lookup */
+
+	ldd,s           t0(ptp),ptp
+	extrd,u         va,51,9,t0     /* get third-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depdi           0,63,12,ptp     /* clear prot bits */
+
+	/* Third level page table lookup */
+
+	shladd           t0,3,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldd              0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20w
+
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
+	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
+	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
+	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_check_flush_20w:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	depdi,z         7,7,3,prot
+	depdi           1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
 #else
 
 dtlb_miss_11:
@@ -889,13 +1143,13 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldwx,s		t1(ptp),ptp
 	extru		va,19,10,t0	/* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_11
 	depi		0,31,12,ptp	/* clear prot bits */
 
 	/* Second level page table lookup */
@@ -903,7 +1157,7 @@
 	sh2addl 	 t0,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldw		 0(ptp),pte
-	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_11
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -911,8 +1165,8 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -937,9 +1191,108 @@
 	rfir
 	nop
 
-dtlb_miss_20:
-	.level 2.0
+dtlb_check_alias_11:
+
+	/* Check to see if fault is in the temporary alias region */
+
+	cmpib,<>,n      0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depwi           0,31,23,t1
+	cmpb,<>,n       t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depw,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrw,u,=       va,9,1,r0
+	or,tr           %r23,%r0,pte    /* If "from" use "from" page */
+	or              %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlba          pte,(va)
+	idtlbp          prot,(va)
+
+	rfir
+	nop
+
+nadtlb_miss_11:
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extru		va,9,10,t1	/* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
+	cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldwx,s		t1(ptp),ptp
+	extru		va,19,10,t0	/* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depi		0,31,12,ptp	/* clear prot bits */
+
+	/* Second level page table lookup */
+
+	sh2addl 	 t0,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldw		 0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_11
+
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
+
+	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
+	depi		1,12,1,prot
+	extru,=         pte,_PAGE_USER_BIT,1,r0
+	depi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extru,= 	pte,_PAGE_GATEWAY_BIT,1,r0
+	depi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlba */
+
+	depi		0,31,12,pte
+	extru		pte,24,25,pte
+
+	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t0, %sr1	/* Restore sr1 */
+
+	rfir
+	nop
+
+nadtlb_check_flush_11:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	zdepi           7,7,3,prot
+	depi            1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlba */
+
+	depi		0,31,12,pte
+	extru		pte,24,25,pte
 
+	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mtsp		spc,%sr1
+
+	idtlba		pte,(%sr1,va)
+	idtlbp		prot,(%sr1,va)
+
+	mtsp		t0, %sr1	/* Restore sr1 */
+
+	rfir
+	nop
+
+dtlb_miss_20:
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -947,13 +1300,13 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dtlb_fault /* forward */
+	cmpb,<>,n       t0,spc,dtlb_fault /* forward */
 
 	/* First level page table lookup */
 
 	ldwx,s		t1(ptp),ptp
 	extru		va,19,10,t0	/* get second-level index */
-	bb,>=,n 	ptp,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20
 	depi		0,31,12,ptp	/* clear prot bits */
 
 	/* Second level page table lookup */
@@ -961,7 +1314,7 @@
 	sh2addl 	 t0,ptp,ptp
 	ldi		_PAGE_ACCESSED,t1
 	ldw		 0(ptp),pte
-	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dtlb_fault
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20
 
 	/* Check whether the "accessed" bit was set, otherwise do so */
 
@@ -969,11 +1322,9 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -981,16 +1332,145 @@
 
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	idtlbt		%r16,%r17
+	extrd,s         pte,35,4,t0
+	depdi		0,63,12,pte	/* clear lower 12 bits */
+        addi,=          1,t0,0 
+        extrd,u,*tr     pte,56,25,pte 
+	extrd,s		pte,56,25,pte	/* bit 31:8 >> 8  */ 
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+dtlb_check_alias_20:
+
+	/* Check to see if fault is in the temporary alias region */
 
-	.level		1.1
+	cmpib,<>,n      0,spc,dtlb_fault /* forward */
+	ldil            L%(TMPALIAS_MAP_START),t0
+	copy            va,t1
+	depwi           0,31,23,t1
+	cmpb,<>,n       t0,t1,dtlb_fault /* forward */
+	ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
+	depd,z          prot,8,7,prot
+
+	/*
+	 * OK, it is in the temp alias region, check whether "from" or "to".
+	 * Check "subtle" note in pacache.S re: r23/r26.
+	 */
+
+	extrw,u,=       va,9,1,r0
+	or,tr           %r23,%r0,pte    /* If "from" use "from" page */
+	or              %r26,%r0,pte    /* else "to", use "to" page  */
+
+	idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_miss_20:
+	mfctl           %cr25,ptp	/* Assume user space miss */
+	or,<>           %r0,spc,%r0	/* If it is user space, nullify */
+	mfctl           %cr24,ptp	/* Load kernel pgd instead */
+	extru		va,9,10,t1	/* Get pgd index */
+
+	mfsp            %sr7,t0		/* Get current space */
+	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
+	cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
+
+	/* First level page table lookup */
+
+	ldwx,s		t1(ptp),ptp
+	extru		va,19,10,t0	/* get second-level index */
+	bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
+	depi		0,31,12,ptp	/* clear prot bits */
+
+	/* Second level page table lookup */
+
+	sh2addl 	 t0,ptp,ptp
+	ldi		_PAGE_ACCESSED,t1
+	ldw		 0(ptp),pte
+	bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20
+
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
+	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
+	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
+	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
+	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+        extrd,s         pte,35,4,t0
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+        idtlbt          pte,prot
+
+	rfir
+	nop
+
+nadtlb_check_flush_20:
+	bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
+
+	/* Insert a "flush only" translation */
+
+	depdi,z         7,7,3,prot
+	depdi           1,10,1,prot
+
+	/* Get rid of prot bits and convert to page addr for idtlbt */
+
+	depdi		0,63,12,pte
+	extrd,u         pte,56,32,pte
+	idtlbt          pte,prot
 
 	rfir
 	nop
 #endif
 
+nadtlb_emulate:
+
+	/*
+	 * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
+	 * probei instructions. We don't want to fault for these
+	 * instructions (not only does it not make sense, it can cause
+	 * deadlocks, since some flushes are done with the mmap
+	 * semaphore held). If the translation doesn't exist, we can't
+	 * insert a translation, so have to emulate the side effects
+	 * of the instruction. Since we don't insert a translation
+	 * we can get a lot of faults during a flush loop, so it makes
+	 * sense to try to do it here with minimum overhead. We only
+	 * emulate fdc,fic & pdc instructions whose base and index
+	 * registers are not shadowed. We defer everything else to the
+	 * "slow" path.
+	 */
+
+	mfctl           %cr19,%r9 /* Get iir */
+	ldi             0x280,%r16
+	and             %r9,%r16,%r17
+	cmpb,<>,n       %r16,%r17,nadtlb_fault /* Not fdc,fic,pdc */
+	bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
+	b,l             get_register,%r25
+	extrw,u         %r9,15,5,%r8           /* Get index register # */
+	CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	copy            %r1,%r24
+	b,l             get_register,%r25
+	extrw,u         %r9,10,5,%r8           /* Get base register # */
+	CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+	b,l             set_register,%r25
+	add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
+
+nadtlb_nullify:
+	mfctl           %cr22,%r8              /* Get ipsw */
+	ldil            L%PSW_N,%r9
+	or              %r8,%r9,%r8            /* Set PSW_N */
+	mtctl           %r8,%cr22
+
+	rfir
+	nop
+
 #ifdef __LP64__
 itlb_miss_20w:
 
@@ -999,9 +1479,9 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	cmpib,*=        0,spc,itlb_miss_kernel_20w
 	extrd,u         va,33,9,t1      /* Get pgd index */
 
@@ -1039,11 +1519,9 @@
 	and,*<>         t1,pte,%r0      /* test and nullify if already set */
 	std             t0,0(ptp)       /* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1053,7 +1531,7 @@
 
 	depdi		0,63,12,pte
 	extrd,u         pte,56,32,pte
-	iitlbt          %r16,%r17
+	iitlbt          pte,prot
 
 	rfir
 	nop
@@ -1070,14 +1548,14 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	comib,=         0,spc,itlb_miss_kernel_11
+	cmpib,=         0,spc,itlb_miss_kernel_11
 	extru		va,9,10,t1	/* Get pgd index */
 
 	mfctl           %cr25,ptp	/* load user pgd */
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,itlb_fault /* forward */
+	cmpb,<>,n       t0,spc,itlb_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1100,8 +1578,8 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -1137,14 +1615,14 @@
 	 * on the gateway page which is in the kernel address space.
 	 */
 
-	comib,=         0,spc,itlb_miss_kernel_20
+	cmpib,=         0,spc,itlb_miss_kernel_20
 	extru		va,9,10,t1	/* Get pgd index */
 
 	mfctl           %cr25,ptp	/* load user pgd */
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,itlb_fault /* forward */
+	cmpb,<>,n       t0,spc,itlb_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1167,13 +1645,9 @@
 	and,<>		t1,pte,%r0	/* test and nullify if already set */
 	stw		t0,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	.level 2.0
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
 
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1181,10 +1655,12 @@
 
 	/* Get rid of prot bits and convert to page addr for iitlbt */
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	iitlbt          %r16,%r17
-	.level		1.1
+        extrd,s         pte,35,4,t0 
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte 
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+	iitlbt          pte,prot
 
 	rfir
 	nop
@@ -1198,11 +1674,10 @@
 #ifdef __LP64__
 
 dbit_trap_20w:
-
-	extrd,u         spc,31,7,t1     /* adjust va */
+	extrd,u         spc,63,7,t1     /* adjust va */
 	depd            t1,31,7,va      /* adjust va */
 	depdi           0,1,2,va        /* adjust va */
-	depdi           0,31,7,spc      /* adjust space */
+	depdi           0,63,7,spc      /* adjust space */
 	mfctl           %cr25,ptp	/* Assume user space miss */
 	or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
 	mfctl           %cr24,ptp	/* Load kernel pgd instead */
@@ -1210,7 +1685,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,*<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1229,6 +1704,18 @@
 	/* Third level page table lookup */
 
 	shladd           t0,3,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_20w
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_20w:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_20w
+	nop
+
+dbit_nolock_20w:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldd              0(ptp),pte
 	bb,>=,n          pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1238,11 +1725,9 @@
 	or		t1,pte,pte
 	std             pte,0(ptp)      /* write back pte */
 
-	copy            spc,prot	/* init prot with faulting space */
-	
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
+
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
@@ -1251,8 +1736,15 @@
 	/* Get rid of prot bits and convert to page addr for idtlbt */
 
 	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
-	idtlbt		%r16,%r17
+	extrd,u         pte,56,52,pte
+	idtlbt          pte,prot
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_20w
+	ldi             1,t1
+	stw             t1,0(t0)
+
+dbit_nounlock_20w:
+#endif
 
 	rfir
 	nop
@@ -1266,7 +1758,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1278,6 +1770,18 @@
 	/* Second level page table lookup */
 
 	sh2addl 	 t0,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_11
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_11:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_11
+	nop
+
+dbit_nolock_11:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldw		 0(ptp),pte
 	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1287,8 +1791,8 @@
 	or		t1,pte,pte
 	stw		pte,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	dep		pte,8,7,prot
+	zdep            spc,30,15,prot  /* create prot id from space */
+	dep             pte,8,7,prot    /* add in prot bits from pte */
 
 	extru,=		pte,_PAGE_NO_CACHE_BIT,1,r0
 	depi		1,12,1,prot
@@ -1302,13 +1806,20 @@
 	depi		0,31,12,pte
 	extru		pte,24,25,pte
 
-	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+	mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
 
 	idtlba		pte,(%sr1,va)
 	idtlbp		prot,(%sr1,va)
 
-	mtsp		t0, %sr1     /* Restore sr1 */
+	mtsp            t1, %sr1     /* Restore sr1 */
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_11
+	ldi             1,t1
+	stw             t1,0(t0)
+
+dbit_nounlock_11:
+#endif
 
 	rfir
 	nop
@@ -1321,7 +1832,7 @@
 
 	mfsp            %sr7,t0		/* Get current space */
 	or,=            %r0,t0,%r0	/* If kernel, nullify following test */
-	comb,<>,n       t0,spc,dbit_fault /* forward */
+	cmpb,<>,n       t0,spc,dbit_fault /* forward */
 
 	/* First level page table lookup */
 
@@ -1333,6 +1844,18 @@
 	/* Second level page table lookup */
 
 	sh2addl 	 t0,ptp,ptp
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nolock_20
+	ldil            L%PA(pa_dbit_lock),t0
+	ldo             R%PA(pa_dbit_lock)(t0),t0
+
+dbit_spin_20:
+	ldcw            0(t0),t1
+	cmpib,=         0,t1,dbit_spin_20
+	nop
+
+dbit_nolock_20:
+#endif
 	ldi		(_PAGE_ACCESSED|_PAGE_DIRTY),t1
 	ldw		 0(ptp),pte
 	bb,>=,n 	 pte,_PAGE_PRESENT_BIT,dbit_fault
@@ -1342,25 +1865,28 @@
 	or		t1,pte,pte
 	stw		pte,0(ptp)	/* write back pte */
 
-	copy            spc,prot        /* init prot with faulting space */
-	
-	.level 2.0
+	space_to_prot   spc prot        /* create prot id from space */
+	depd            pte,8,7,prot    /* add in prot bits from pte */
 
-	depd		pte,8,7,prot
-	extrd,u,*=	pte,_PAGE_NO_CACHE_BIT+32,1,r0
-	depdi		1,12,1,prot
 	extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
 	depdi		7,11,3,prot   /* Set for user space (1 rsvd for read) */
 	extrd,u,*= 	pte,_PAGE_GATEWAY_BIT+32,1,r0
 	depdi		0,11,2,prot	/* If Gateway, Set PL2 to 0 */
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+        extrd,s         pte,35,4,t0 
+        depdi           0,63,12,pte     /* clear lower 12 bits */
+        addi,=          1,t0,0
+        extrd,u,*tr     pte,56,25,pte 
+        extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
+        idtlbt          pte,prot
 
-	depdi		0,63,12,pte
-	extrd,u		pte,56,25,pte
-	idtlbt		%r16,%r17
+#ifdef CONFIG_SMP
+	CMPIB=,n        0,spc,dbit_nounlock_20
+	ldi             1,t1
+	stw             t1,0(t0)
 
-	.level		1.1
+dbit_nounlock_20:
+#endif
 
 	rfir
 	nop
@@ -1369,50 +1895,24 @@
 	.import handle_interruption,code
 
 kernel_bad_space:
-	b		tlb_fault
-	ldi		31,%r1	/* Use an unused code */
+	b               intr_save
+	ldi             31,%r8  /* Use an unused code */
 
 dbit_fault:
-	b		tlb_fault
-	ldi		20,%r1
+	b               intr_save
+	ldi             20,%r8
 
 itlb_fault:
-	b		tlb_fault
-	ldi		6,%r1
-
-dtlb_fault:
-	ldi		15,%r1
+	b               intr_save
+	ldi             6,%r8
 
-	/* Fall Through */
+nadtlb_fault:
+	b               intr_save
+	ldi             17,%r8
 
-tlb_fault:
-	mtctl		%r1,%cr29
-	mtctl		%r29,%cr31
-
-	get_stack
-	save_specials	%r29		/* Note this saves a trashed r1 */
-
-	SAVE_CR		(%cr20, PT_ISR(%r29))
-	SAVE_CR		(%cr21, PT_IOR(%r29))
-
-	virt_map	rfir
-
-	STREG		%r1,PT_GR1(%r29)	/* save good value after rfir */
-
-	save_general	%r29
-
-	ldo	PT_FR0(%r29), %r25
-	save_fp		%r25
-	
-	loadgp
-
-	copy		%r29, %r25
-
-	bl		handle_interruption, %r2
-	copy		%r29, %r16
-
-	b		intr_return
-	nop
+dtlb_fault:
+	b               intr_save
+	ldi             15,%r8
 
 	/* Register saving semantics for system calls:
 
@@ -1475,21 +1975,23 @@
 	.endm
 
 	.export sys_fork_wrapper
+	.export child_return
 sys_fork_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
 	/* These are call-clobbered registers and therefore
 	   also syscall-clobbered (we hope). */
 	STREG	%r2,PT_GR19(%r1)	/* save for child */
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return, %r3
-	ldo	R%child_return(%r3), %r3
-	LDIL_FIXUP(%r3)
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 
 	LDREG	PT_GR30(%r1),%r25
 	copy	%r1,%r24
@@ -1501,14 +2003,21 @@
 	ldo	-FRAME_SIZE(%r30),%r30		/* get the stackframe */
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1    /* get pt regs */
 
+	LDREG	PT_CR27(%r1), %r3
+	mtctl	%r3, %cr27
 	reg_restore %r1
 
+	/* strace expects syscall # to be preserved in r20 */
+	ldi	__NR_fork,%r20
 	bv %r0(%r2)
-	nop
+	STREG	%r20,PT_GR20(%r1)
 
 	/* Set the return value for the child */
 child_return:
-	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
+	bl	schedule_tail, %r2
+	nop
+
+	LDREG	TASK_PT_GR19-TASK_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30),%r2
 	b	wrapper_exit
 	copy	%r0,%r28
 
@@ -1517,35 +2026,38 @@
 sys_clone_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	LDIL_FIXUP(%r3)
-
+	STREG	%r2,PT_GR19(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 	bl	sys_clone,%r2
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	copy	%r1,%r24
 
 	b	wrapper_exit
 	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2
 
-
 	.export sys_vfork_wrapper
 sys_vfork_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* get pt regs */
 	reg_save %r1
+	mfctl	%cr27, %r3
+	STREG	%r3, PT_CR27(%r1)
 
 	STREG	%r2,-RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 
-	STREG	%r30,PT_GR20(%r1)
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	LDIL_FIXUP(%r3)
-	STREG	%r3,PT_GR21(%r1)	/* save for child */
+	STREG	%r2,PT_GR19(%r1)	/* save for child */
+	STREG	%r30,PT_GR21(%r1)
 
 	bl	sys_vfork,%r2
 	copy	%r1,%r26
@@ -1567,6 +2079,9 @@
 
 	STREG %r2,-RP_OFFSET(%r30)
 	ldo FRAME_SIZE(%r30),%r30
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#endif
 	bl \execve,%r2
 	copy %r1,%arg0
 
@@ -1576,7 +2091,7 @@
 	/* If exec succeeded we need to load the args */
 
 	ldo -1024(%r0),%r1
-	comb,>>= %r28,%r1,error_\execve
+	cmpb,>>= %r28,%r1,error_\execve
 	copy %r2,%r19
 
 error_\execve:
@@ -1603,8 +2118,14 @@
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r26
 	/* Don't save regs, we are going to restore them from sigcontext. */
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	sys_rt_sigreturn,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	sys_rt_sigreturn,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
@@ -1625,22 +2146,50 @@
 	/* Get the user stack pointer */
 	LDREG	-TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	do_sigaltstack,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	do_sigaltstack,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
 	bv	%r0(%r2)
 	nop
 
+#ifdef __LP64__
+	.export sys32_sigaltstack_wrapper
+sys32_sigaltstack_wrapper:
+	/* Get the user stack pointer */
+	LDREG	-TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
+	STREG	%r2, -RP_OFFSET(%r30)
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	do_sigaltstack32,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+
+	ldo	-FRAME_SIZE(%r30), %r30
+	LDREG	-RP_OFFSET(%r30), %r2
+	bv	%r0(%r2)
+	nop
+#endif
+
 	.export sys_rt_sigsuspend_wrapper
 sys_rt_sigsuspend_wrapper:
 	ldo	TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r24
 	reg_save %r24
 
 	STREG	%r2, -RP_OFFSET(%r30)
+#ifdef __LP64__
+	ldo	FRAME_SIZE(%r30), %r30
+	bl	sys_rt_sigsuspend,%r2
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	bl	sys_rt_sigsuspend,%r2
 	ldo	FRAME_SIZE(%r30), %r30
+#endif
 
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
@@ -1658,66 +2207,80 @@
 	   values. */
 	/* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
 	 * via syscall_exit_rfi if the signal was received while the process
-	 * was running.  All traced processes will probably exit via
-	 * syscall_exit_rfi in the future.
+	 * was running.
 	 */
 
 	/* save return value now */
 
 	STREG     %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)
 
+	/* Save other hpux returns if personality is PER_HPUX */
+
+#define PER_HPUX 0xe /* <linux/personality.h> cannot be easily included */
+
+	LDREG     TASK_PERSONALITY-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19
+	CMPIB<>,n PER_HPUX,%r19,1f
+	STREG     %r22,TASK_PT_GR22-TASK_SZ_ALGN-FRAME_SIZE(%r30)
+	STREG     %r29,TASK_PT_GR29-TASK_SZ_ALGN-FRAME_SIZE(%r30)
+1:
+
+	/* Seems to me that dp could be wrong here, if the syscall involved
+	 * calling a module, and nothing got round to restoring dp on return.
+	 */
+	loadgp
+
 syscall_check_bh:
 
-/* #ifdef NOTNOW */
 	/* Check for software interrupts */
 
 	.import irq_stat,data
 
 	ldil    L%irq_stat,%r19
 	ldo     R%irq_stat(%r19),%r19
-	LDIL_FIXUP(%r19)
 
 #ifdef CONFIG_SMP
 	/* sched.h: int processor */
-	ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r20 /* get cpu # */
-#if (IRQSTAT_SZ == 32)
-	dep     %r20,26,27,%r20 /* shift left 5 bits */
-#else
-#error IRQSTAT_SZ changed, fix dep
-#endif /* IRQSTAT_SZ */
-	add     %r19,%r20,%r19
-#endif /* CONFIG_SMP */
+	/* %r26 is used as scratch register to index into irq_stat[] */
+	ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
 
-	ldw     IRQSTAT_SI_ACTIVE(%r19),%r20	/* hardirq.h: unsigned int */
-	ldw     IRQSTAT_SI_MASK(%r19),%r19	/* hardirq.h: unsigned int */
-	and     %r19,%r20,%r20
-	comib,<>,n 0,%r20,syscall_do_softirq /* forward */
-/* #endif */
+	/* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
+#ifdef __LP64__
+	shld	%r26, 6, %r20
+#else
+	shlw	%r26, 5, %r20
+#endif
+	add     %r19,%r20,%r19	/* now have &irq_stat[smp_processor_id()] */
+#endif /* CONFIG_SMP */
 
+	LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
+	cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
 
 syscall_check_resched:
 
 	/* check for reschedule */
 
 	LDREG  TASK_NEED_RESCHED-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
-	comib,<>,n 0,%r19,syscall_do_resched /* forward */
+	CMPIB<>,n 0,%r19,syscall_do_resched /* forward */
 
 syscall_check_sig:
 	ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1         /* get task ptr */
 	/* check for pending signals */
 	ldw     TASK_SIGPENDING(%r1),%r19
-	comib,<>,n 0,%r19,syscall_do_signal  /* forward */
+	cmpib,<>,n 0,%r19,syscall_do_signal  /* forward */
 
 syscall_restore:
-	/* disable interrupts while dicking with the kernel stack, */
-	/* or life can become unpleasant */
-	rsm	PSW_SM_I, %r20
 	LDREG	TASK_PTRACE(%r1), %r19		/* Are we being ptraced? */
 	bb,<,n	%r19,31,syscall_restore_rfi
-	LDREG	TASK_PT_GR20(%r1),%r19
-	mtctl	%r19, %cr27
+
+	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
+	rest_fp	%r19
+
+	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
+	mtsar	%r19
 
 	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */
+	LDREG	TASK_PT_GR19(%r1),%r19
+	LDREG   TASK_PT_GR20(%r1),%r20
 	LDREG	TASK_PT_GR21(%r1),%r21
 	LDREG	TASK_PT_GR22(%r1),%r22
 	LDREG	TASK_PT_GR23(%r1),%r23
@@ -1727,43 +2290,31 @@
 	LDREG	TASK_PT_GR27(%r1),%r27	   /* restore user dp */
 	LDREG	TASK_PT_GR28(%r1),%r28	   /* syscall return value */
 	LDREG	TASK_PT_GR29(%r1),%r29
-	LDREG	TASK_PT_GR30(%r1),%r30	   /* restore user sp */
 	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */
-	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
-	rest_fp	%r19
-	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
-	mtsar	%r19
-	LDREG	TASK_PT_GR19(%r1),%r19
 
-	mtctl	%r1,%cr30			   /* intrhandler okay. */
+	rsm     PSW_SM_I, %r0
+	LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
 	mfsp	%sr3,%r1			   /* Get users space id */
+	mtsp    %r1,%sr7                           /* Restore sr7 */
+	ssm     PSW_SM_I, %r0
 	mtsp	%r1,%sr4			   /* Restore sr4 */
 	mtsp	%r1,%sr5			   /* Restore sr5 */
 	mtsp	%r1,%sr6			   /* Restore sr6 */
 
 	depi	3,31,2,%r31			   /* ensure return to user mode. */
 
-	mtsm	%r20				   /* restore irq state  */
-	mfctl	%cr27,%r20
-	
-	/*
-	 * Due to a dependency in the tlb miss handlers on sr7, it
-	 * is essential that sr7 get set in the delay slot.
-	 */
-
 #ifdef __LP64__
-
-	/* Note the be (and mtsp) is executed in narrow mode. This is OK
-	 * for 32 bit processes, but won't work once we support 64 bit
-	 * processes.
+	/* Since we are returning to a 32 bit user process, we always
+	 * clear the W bit. This means that the be (and mtsp) gets
+	 * executed in narrow mode, but that is OK, since we are
+	 * returning to a 32 bit process. When we support 64 bit processes
+	 * we won't clear the W bit, so the be will run in wide mode.
 	 */
 
-	rsm	PSW_SM_W, %r0
 	be	0(%sr3,%r31)			   /* return to user space */
-	mtsp	%r1,%sr7			   /* Restore sr7 */
+	rsm	PSW_SM_W, %r0
 #else
-	be	0(%sr3,%r31)			   /* return to user space */
-	mtsp	%r1,%sr7			   /* Restore sr7 */
+	be,n    0(%sr3,%r31)                       /* return to user space */
 #endif
 
 	/* We have to return via an RFI, so that PSW T and R bits can be set
@@ -1774,43 +2325,52 @@
 syscall_restore_rfi:
 	ldo	-1(%r0),%r2			   /* Set recovery cntr to -1 */
 	mtctl	%r2,%cr0			   /*   for immediate trap */
-	copy	%r0,%r2				   /* Create a reasonable PSW */
+	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */
+	ldi	0x0b,%r20			   /* Create new PSW */
+	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */
+	bb,>=,n	%r19,15,try_tbit		   /* PT_SINGLESTEP */
+	depi	-1,27,1,%r20			   /* R bit */
+try_tbit:
+	bb,>=,n	%r19,14,psw_setup		   /* PT_BLOCKSTEP, see ptrace.c */
+	depi	-1,7,1,%r20			   /* T bit */
+psw_setup:
+	STREG	%r20,TASK_PT_PSW(%r1)
+
+	/* Always store space registers, since sr3 can be changed (e.g. fork) */
+
+	mfsp    %sr3,%r25
+	STREG   %r25,TASK_PT_SR3(%r1)
+	STREG   %r25,TASK_PT_SR4(%r1)
+	STREG   %r25,TASK_PT_SR5(%r1)
+	STREG   %r25,TASK_PT_SR6(%r1)
+	STREG   %r25,TASK_PT_SR7(%r1)
+	STREG   %r25,TASK_PT_IASQ0(%r1)
+	STREG   %r25,TASK_PT_IASQ1(%r1)
+
 	/* XXX W bit??? */
-	depi	-1,13,1,%r2
-	depi	-1,28,1,%r2
-	depi	-1,30,1,%r2
-	depi	-1,31,1,%r2
-	bb,<,n	%r19,15,set_rbit		   /* PT_SINGLESTEP */
-	bb,>=,n	%r19,14,set_nobit		   /* PT_BLOCKSTEP, see ptrace.c */
-set_tbit:
-	depi	-1,7,1,%r2
-	b,n	set_nobit
-set_rbit:
-	depi	-1,27,1,%r2
-set_nobit:
-	STREG	%r2,TASK_PT_PSW(%r1)
-	STREG	%r1,TASK_PT_CR30(%r1)
+	/* Now if old D bit is clear, it means we didn't save all registers
+	 * on syscall entry, so do that now.  This only happens on TRACEME
+	 * calls, or if someone attached to us while we were on a syscall.
+	 * We could make this more efficient by not saving r3-r18, but
+	 * then we wouldn't be able to use the common intr_restore path.
+	 * It is only for traced processes anyway, so performance is not
+	 * an issue.
+	 */
+	bb,<	%r2,30,pt_regs_ok		   /* Branch if D set */
+	ldo	TASK_REGS(%r1),%r25
+	reg_save %r25				   /* Save r3 to r18 */
 	mfsp	%sr0,%r2
 	STREG	%r2,TASK_PT_SR0(%r1)
 	mfsp	%sr1,%r2
 	STREG	%r2,TASK_PT_SR1(%r1)
 	mfsp	%sr2,%r2
 	STREG	%r2,TASK_PT_SR2(%r1)
-	mfsp	%sr3,%r2
-	STREG	%r2,TASK_PT_SR3(%r1)
-	STREG	%r2,TASK_PT_SR4(%r1)
-	STREG	%r2,TASK_PT_SR5(%r1)
-	STREG	%r2,TASK_PT_SR6(%r1)
-	STREG	%r2,TASK_PT_SR7(%r1)
-	STREG	%r2,TASK_PT_IASQ0(%r1)
-	STREG	%r2,TASK_PT_IASQ1(%r1)
+pt_regs_ok:
 	LDREG	TASK_PT_GR31(%r1),%r2
 	depi	3,31,2,%r2			   /* ensure return to user mode. */
 	STREG	%r2,TASK_PT_IAOQ0(%r1)
 	ldo	4(%r2),%r2
 	STREG	%r2,TASK_PT_IAOQ1(%r1)
-	ldo	TASK_REGS(%r1),%r25
-	reg_save %r25				   /* Save r3 to r18 */
 	copy	%r25,%r16
 	b	intr_restore
 	nop
@@ -1825,7 +2385,11 @@
 	.import schedule,code
 syscall_do_resched:
 	bl	schedule,%r2
+#ifdef __LP64__
+	ldo	-16(%r30),%r29		/* Reference param save area */
+#else
 	nop
+#endif
 	b       syscall_check_bh  /* if resched, we start over again */
 	nop
 
@@ -1840,6 +2404,9 @@
 
 	ldi	1, %r24				/* unsigned long in_syscall */
 
+#ifdef __LP64__
+	ldo	-16(%r30),%r29			/* Reference param save area */
+#endif
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
@@ -1849,19 +2416,155 @@
 
 	b,n     syscall_restore
 
-#ifdef __LP64__
-unimplemented_64bitirq:
-	ssm PSW_SM_Q+PSW_SM_I, %r0
-	/* indicate that we had an interrupt */
-	ldi	0x77, %r28
-	ldi	0x77, %r29
-	/* save interrupt registers in GRs for diagnosis */
-	mfctl %cr17, %r17
-	mfctl %cr18, %r18
-	mfctl %cr19, %r19
-	mfctl %cr20, %r20
-	mfctl %cr21, %r21
-	mfctl %cr22, %r22
-	b,n .
-	nop
-#endif
+	/*
+	 * get_register is used by the non access tlb miss handlers to
+	 * copy the value of the general register specified in r8 into
+	 * r1. This routine can't be used for shadowed registers, since
+	 * the rfir will restore the original value. So, for the shadowed
+	 * registers we put a -1 into r1 to indicate that the register
+	 * should not be used (the register being copied could also have
+	 * a -1 in it, but that is OK, it just means that we will have
+	 * to use the slow path instead).
+	 */
+
+get_register:
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 */
+	copy    %r0,%r1
+	bv      %r0(%r25)    /* r1 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r2,%r1
+	bv      %r0(%r25)    /* r3 */
+	copy    %r3,%r1
+	bv      %r0(%r25)    /* r4 */
+	copy    %r4,%r1
+	bv      %r0(%r25)    /* r5 */
+	copy    %r5,%r1
+	bv      %r0(%r25)    /* r6 */
+	copy    %r6,%r1
+	bv      %r0(%r25)    /* r7 */
+	copy    %r7,%r1
+	bv      %r0(%r25)    /* r8 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r9 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r10 */
+	copy    %r10,%r1
+	bv      %r0(%r25)    /* r11 */
+	copy    %r11,%r1
+	bv      %r0(%r25)    /* r12 */
+	copy    %r12,%r1
+	bv      %r0(%r25)    /* r13 */
+	copy    %r13,%r1
+	bv      %r0(%r25)    /* r14 */
+	copy    %r14,%r1
+	bv      %r0(%r25)    /* r15 */
+	copy    %r15,%r1
+	bv      %r0(%r25)    /* r16 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r17 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r18 */
+	copy    %r18,%r1
+	bv      %r0(%r25)    /* r19 */
+	copy    %r19,%r1
+	bv      %r0(%r25)    /* r20 */
+	copy    %r20,%r1
+	bv      %r0(%r25)    /* r21 */
+	copy    %r21,%r1
+	bv      %r0(%r25)    /* r22 */
+	copy    %r22,%r1
+	bv      %r0(%r25)    /* r23 */
+	copy    %r23,%r1
+	bv      %r0(%r25)    /* r24 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r25 - shadowed */
+	ldi     -1,%r1
+	bv      %r0(%r25)    /* r26 */
+	copy    %r26,%r1
+	bv      %r0(%r25)    /* r27 */
+	copy    %r27,%r1
+	bv      %r0(%r25)    /* r28 */
+	copy    %r28,%r1
+	bv      %r0(%r25)    /* r29 */
+	copy    %r29,%r1
+	bv      %r0(%r25)    /* r30 */
+	copy    %r30,%r1
+	bv      %r0(%r25)    /* r31 */
+	copy    %r31,%r1
+
+	/*
+	 * set_register is used by the non access tlb miss handlers to
+	 * copy the value of r1 into the general register specified in
+	 * r8.
+	 */
+
+set_register:
+	blr     %r8,%r0
+	nop
+	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
+	copy    %r1,%r0
+	bv      %r0(%r25)    /* r1 */
+	copy    %r1,%r1
+	bv      %r0(%r25)    /* r2 */
+	copy    %r1,%r2
+	bv      %r0(%r25)    /* r3 */
+	copy    %r1,%r3
+	bv      %r0(%r25)    /* r4 */
+	copy    %r1,%r4
+	bv      %r0(%r25)    /* r5 */
+	copy    %r1,%r5
+	bv      %r0(%r25)    /* r6 */
+	copy    %r1,%r6
+	bv      %r0(%r25)    /* r7 */
+	copy    %r1,%r7
+	bv      %r0(%r25)    /* r8 */
+	copy    %r1,%r8
+	bv      %r0(%r25)    /* r9 */
+	copy    %r1,%r9
+	bv      %r0(%r25)    /* r10 */
+	copy    %r1,%r10
+	bv      %r0(%r25)    /* r11 */
+	copy    %r1,%r11
+	bv      %r0(%r25)    /* r12 */
+	copy    %r1,%r12
+	bv      %r0(%r25)    /* r13 */
+	copy    %r1,%r13
+	bv      %r0(%r25)    /* r14 */
+	copy    %r1,%r14
+	bv      %r0(%r25)    /* r15 */
+	copy    %r1,%r15
+	bv      %r0(%r25)    /* r16 */
+	copy    %r1,%r16
+	bv      %r0(%r25)    /* r17 */
+	copy    %r1,%r17
+	bv      %r0(%r25)    /* r18 */
+	copy    %r1,%r18
+	bv      %r0(%r25)    /* r19 */
+	copy    %r1,%r19
+	bv      %r0(%r25)    /* r20 */
+	copy    %r1,%r20
+	bv      %r0(%r25)    /* r21 */
+	copy    %r1,%r21
+	bv      %r0(%r25)    /* r22 */
+	copy    %r1,%r22
+	bv      %r0(%r25)    /* r23 */
+	copy    %r1,%r23
+	bv      %r0(%r25)    /* r24 */
+	copy    %r1,%r24
+	bv      %r0(%r25)    /* r25 */
+	copy    %r1,%r25
+	bv      %r0(%r25)    /* r26 */
+	copy    %r1,%r26
+	bv      %r0(%r25)    /* r27 */
+	copy    %r1,%r27
+	bv      %r0(%r25)    /* r28 */
+	copy    %r1,%r28
+	bv      %r0(%r25)    /* r29 */
+	copy    %r1,%r29
+	bv      %r0(%r25)    /* r30 */
+	copy    %r1,%r30
+	bv      %r0(%r25)    /* r31 */
+	copy    %r1,%r31
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/firmware.c linux-2.4.20/arch/parisc/kernel/firmware.c
--- linux-2.4.19/arch/parisc/kernel/firmware.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/firmware.c	2002-10-04 00:41:15.000000000 +0000
@@ -0,0 +1,1111 @@
+/* arch/parisc/kernel/pdc.c  - safe pdc access routines
+ *
+ * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
+ * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
+ *
+ * only these routines should be used out of the real kernel (i.e. everything
+ * using virtual addresses) for obvious reasons */
+
+/*	I think it would be in everyone's best interest to follow this
+ *	guidelines when writing PDC wrappers:
+ *
+ *	 - the name of the pdc wrapper should match one of the macros
+ *	   used for the first two arguments
+ *	 - don't use caps for random parts of the name
+ *	 - use the static PDC result buffers and "copyout" to structs
+ *	   supplied by the caller to encapsulate alignment restrictions
+ *	 - hold pdc_lock while in PDC or using static result buffers
+ *	 - use __pa() to convert virtual (kernel) pointers to physical
+ *	   ones.
+ *	 - the name of the struct used for pdc return values should equal
+ *	   one of the macros used for the first two arguments to the
+ *	   corresponding PDC call
+ *	 - keep the order of arguments
+ *	 - don't be smart (setting trailing NUL bytes for strings, return
+ *	   something useful even if the call failed) unless you are sure
+ *	   it's not going to affect functionality or performance
+ *
+ *	Example:
+ *	int pdc_cache_info(struct pdc_cache_info *cache_info )
+ *	{
+ *		int retval;
+ *
+ *		spin_lock_irq(&pdc_lock);
+ *		retval = mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
+ *		convert_to_wide(pdc_result);
+ *		memcpy(cache_info, pdc_result, sizeof(*cache_info));
+ *		spin_unlock_irq(&pdc_lock);
+ *
+ *		return retval;
+ *	}
+ *					prumpf	991016	
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/page.h>
+#include <asm/pdc.h>
+#include <asm/system.h>
+#include <asm/processor.h>	/* for boot_cpu_data */
+
+#include <stdarg.h>
+
+static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
+static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
+
+/* on all currently-supported platforms, IODC I/O calls are always
+ * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
+ * This means Cxxx boxes can't run wide kernels right now. -PB
+ *
+ * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
+ * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
+ * run on Cxxx boxes now. -RB
+ *
+ * Note that some PAT boxes may have 64-bit IODC I/O...
+ */
+
+#ifdef __LP64__
+static long real64_call(unsigned long function, ...);
+#endif
+static long real32_call(unsigned long function, ...);
+
+#if defined(__LP64__) && ! defined(CONFIG_PDC_NARROW)
+#define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real64_call(MEM_PDC, args)
+#else
+#define MEM_PDC (unsigned long)PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real32_call(MEM_PDC, args)
+#endif
+
+
+/**
+ * f_extend - Convert PDC addresses to kernel addresses.
+ * @address: Address returned from PDC.
+ *
+ * This function is used to convert PDC addresses into kernel addresses
+ * when the PDC address size and kernel address size are different.
+ */
+static unsigned long f_extend(unsigned long address)
+{
+#ifdef CONFIG_PDC_NARROW
+	if((address & 0xff000000) == 0xf0000000)
+		return 0xf0f0f0f000000000 | (u32)address;
+
+	if((address & 0xf0000000) == 0xf0000000)
+		return 0xffffffff00000000 | (u32)address;
+#endif
+	return address;
+}
+
+/**
+ * convert_to_wide - Convert the return buffer addresses into kernel addresses.
+ * @address: The return buffer from PDC.
+ *
+ * This function is used to convert the return buffer addresses retrieved from PDC
+ * into kernel addresses when the PDC address size and kernel address size are
+ * different.
+ */
+static void convert_to_wide(unsigned long *addr)
+{
+#ifdef CONFIG_PDC_NARROW
+	int i;
+	unsigned *p = (unsigned int *)addr;
+	for(i = 31; i >= 0; --i)
+		addr[i] = p[i];
+#endif
+}
+
+/**
+ * pdc_emergency_unlock - Unlock the linux pdc lock
+ *
+ * This call unlocks the linux pdc lock in case we need some PDC functions
+ * (like pdc_add_valid) during kernel stack dump.
+ */
+void pdc_emergency_unlock(void)
+{
+        spin_unlock(&pdc_lock);
+}
+
+
+/**
+ * pdc_add_valid - Verify address can be accessed without causing a HPMC.
+ * @address: Address to be verified.
+ *
+ * This PDC call attempts to read from the specified address and verifies
+ * if the address is valid.
+ * 
+ * The return value is PDC_OK (0) in case accessing this address is valid.
+ */
+int pdc_add_valid(unsigned long address)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_chassis_info - Return chassis information.
+ * @result: The return buffer.
+ * @chassis_info: The memory buffer address.
+ * @len: The size of the memory buffer address.
+ *
+ * An HVERSION dependent call for returning the chassis information.
+ */
+int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
+        memcpy(&pdc_result2, led_info, len);
+        retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+                              __pa(pdc_result), __pa(pdc_result2), len);
+        memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
+        memcpy(led_info, pdc_result2, len);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_coproc_cfg - To identify coprocessors attached to the processor.
+ * @pdc_coproc_info: Return buffer address.
+ *
+ * This PDC call returns the presence and status of all the coprocessors
+ * attached to the processor.
+ */
+int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+        convert_to_wide(pdc_result);
+        pdc_coproc_info->ccr_functional = pdc_result[0];
+        pdc_coproc_info->ccr_present = pdc_result[1];
+        pdc_coproc_info->revision = pdc_result[17];
+        pdc_coproc_info->model = pdc_result[18];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_iodc_read - Read data from the modules IODC.
+ * @actcnt: The actual number of bytes.
+ * @hpa: The HPA of the module for the iodc read.
+ * @index: The iodc entry point.
+ * @iodc_data: A buffer memory for the iodc options.
+ * @iodc_data_size: Size of the memory buffer.
+ *
+ * This PDC call reads from the IODC of the module specified by the hpa
+ * argument.
+ */
+int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
+		  void *iodc_data, unsigned int iodc_data_size)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, 
+			      index, __pa(pdc_result2), iodc_data_size);
+	convert_to_wide(pdc_result);
+	*actcnt = pdc_result[0];
+	memcpy(iodc_data, pdc_result2, iodc_data_size);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_system_map_find_mods - Locate unarchitected modules.
+ * @pdc_mod_info: Return buffer address.
+ * @mod_path: pointer to dev path structure.
+ * @mod_index: fixed address module index.
+ *
+ * To locate and identify modules which reside at fixed I/O addresses, which
+ * do not self-identify via architected bus walks.
+ */
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+			     struct pdc_module_path *mod_path, long mod_index)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), 
+			      __pa(pdc_result2), mod_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
+	memcpy(mod_path, pdc_result2, sizeof(*mod_path));
+	spin_unlock_irq(&pdc_lock);
+
+	pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_system_map_find_addrs - Retrieve additional address ranges.
+ * @pdc_addr_info: Return buffer address.
+ * @mod_index: Fixed address module index.
+ * @addr_index: Address range index.
+ * 
+ * Retrieve additional information about subsequent address ranges for modules
+ * with multiple address ranges.  
+ */
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+			      long mod_index, long addr_index)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
+			      mod_index, addr_index);
+	convert_to_wide(pdc_result);
+	memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
+	spin_unlock_irq(&pdc_lock);
+
+	pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
+	return retval;
+}
+
+/**
+ * pdc_model_info - Return model information about the processor.
+ * @model: The return buffer.
+ *
+ * Returns the version numbers, identifiers, and capabilities from the processor module.
+ */
+int pdc_model_info(struct pdc_model *model) 
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
+	convert_to_wide(pdc_result);
+	memcpy(model, pdc_result, sizeof(*model));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_model_sysmodel - Get the system model name.
+ * @name: A char array of at least 81 characters.
+ *
+ * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L)
+ */
+int pdc_model_sysmodel(char *name)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
+                              OS_ID_HPUX, __pa(name));
+        convert_to_wide(pdc_result);
+
+        if (retval == PDC_OK) {
+                name[pdc_result[0]] = '\0'; /* add trailing '\0' */
+        } else {
+                name[0] = 0;
+        }
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_versions - Identify the version number of each processor.
+ * @cpu_id: The return buffer.
+ * @id: The id of the processor to check.
+ *
+ * Returns the version number for each processor component.
+ *
+ * This comment was here before, but I do not know what it means :( -RB
+ * id: 0 = cpu revision, 1 = boot-rom-version
+ */
+int pdc_model_versions(unsigned long *versions, int id)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
+        convert_to_wide(pdc_result);
+        *versions = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_cpuid - Returns the CPU_ID.
+ * @cpu_id: The return buffer.
+ *
+ * Returns the CPU_ID value which uniquely identifies the cpu portion of
+ * the processor module.
+ */
+int pdc_model_cpuid(unsigned long *cpu_id)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        *cpu_id = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_model_capabilities - Returns the platform capabilities.
+ * @capabilities: The return buffer.
+ *
+ * Returns information about platform support for 32- and/or 64-bit
+ * OSes, IO-PDIR coherency, and virtual aliasing.
+ */
+int pdc_model_capabilities(unsigned long *capabilities)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
+        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        *capabilities = pdc_result[0];
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_cache_info - Return cache and TLB information.
+ * @cache_info: The return buffer.
+ *
+ * Returns information about the processor's cache and TLB.
+ */
+int pdc_cache_info(struct pdc_cache_info *cache_info)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(cache_info, pdc_result, sizeof(*cache_info));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifndef CONFIG_PA20
+/**
+ * pdc_btlb_info - Return block TLB information.
+ * @btlb: The return buffer.
+ *
+ * Returns information about the hardware Block TLB.
+ */
+int pdc_btlb_info(struct pdc_btlb_info *btlb) 
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
+        memcpy(btlb, pdc_result, sizeof(*btlb));
+        spin_unlock_irq(&pdc_lock);
+
+        if(retval < 0) {
+                btlb->max_size = 0;
+        }
+        return retval;
+}
+
+/**
+ * pdc_mem_map_hpa - Find fixed module information.  
+ * @address: The return buffer
+ * @mod_path: pointer to dev path structure.
+ *
+ * This call was developed for S700 workstations to allow the kernel to find
+ * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this
+ * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP
+ * call.
+ *
+ * This call is supported by all existing S700 workstations (up to  Gecko).
+ */
+int pdc_mem_map_hpa(struct pdc_memory_map *address,
+		struct pdc_module_path *mod_path)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        memcpy(pdc_result2, mod_path, sizeof(*mod_path));
+        retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
+				__pa(pdc_result2));
+        memcpy(address, pdc_result, sizeof(*address));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+#endif	/* !CONFIG_PA20 */
+
+/**
+ * pdc_lan_station_id - Get the LAN address.
+ * @lan_addr: The return buffer.
+ * @hpa: The network device HPA.
+ *
+ * Get the LAN station address when it is not directly available from the LAN hardware.
+ */
+int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
+			__pa(pdc_result), hpa);
+	if (retval < 0) {
+		/* FIXME: else read MAC from NVRAM */
+		memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
+	} else {
+		memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+
+/**
+ * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
+ * @hwpath: fully bc.mod style path to the device.
+ * @scsi_id: what someone told firmware the ID should be.
+ * @period: time in cycles 
+ * @width: 8 or 16-bit wide bus
+ * @mode: 0,1,2 -> SE,HVD,LVD signalling mode
+ *
+ * Get the SCSI operational parameters from PDC.
+ * Needed since HPUX never used BIOS or symbios card NVRAM.
+ * Most ncr/sym cards won't have an entry and just use whatever
+ * capabilities of the card are (eg Ultra, LVD). But there are
+ * several cases where it's useful:
+ *    o set SCSI id for Multi-initiator clusters,
+ *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
+ *    o bus width exported is less than what the interface chip supports.
+ */
+int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id,
+	unsigned long *period, char *width, char *mode)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+
+/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
+#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
+	strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 9) == 0)
+
+	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
+			      __pa(pdc_result), __pa(hwpath));
+
+
+	if (retval >= PDC_OK) {
+		*scsi_id = (unsigned char) pdc_result[0];
+
+		/* convert Bus speed in Mhz to period (in 1/10 ns) */
+		switch(pdc_result[1]) {
+		/*
+		** case  0:   driver determines rate
+		** case -1:   Settings are uninitialized.
+		*/
+		case  5:  *period = 2000; break;
+		case 10:  *period = 1000; break;
+		case 20:  *period = 500; break;
+		case 40:  *period = 250; break;
+		default: /* Do nothing */ break;
+		}
+
+		/* 
+		** pdc_result[2]	PDC suggested SCSI id
+		** pdc_result[3]	PDC suggested SCSI rate
+		*/
+
+		if (IS_SPROCKETS()) {
+			/*
+			** Revisit: PAT PDC do the same thing?
+			** A500 also exports 50-pin SE SCSI.
+			**	0 == 8-bit
+			**	1 == 16-bit
+			*/
+			*width = (char) pdc_result[4];
+
+			/* ...in case someone needs it in the future.
+			** sym53c8xx.c comments say it can't autodetect
+			** for 825/825A/875 chips.
+			**	0 == SE, 1 == HVD, 2 == LVD
+			*/
+			*mode = (char) pdc_result[5]; 
+		}
+	}
+
+	spin_unlock_irq(&pdc_lock);
+	return retval >= PDC_OK;
+}
+
+
+/**
+ * pdc_pci_irt_size - Get the number of entries in the interrupt routing table.
+ * @num_entries: The return value.
+ * @hpa: The HPA for the device.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */ 
+int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, 
+			      __pa(pdc_result), hpa);
+	convert_to_wide(pdc_result);
+	*num_entries = pdc_result[0];
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/** 
+ * pdc_pci_irt - Get the PCI interrupt routing table.
+ * @num_entries: The number of entries in the table.
+ * @hpa: The Hard Physical Address of the device.
+ * @tbl: 
+ *
+ * Get the PCI interrupt routing table for the device at the given HPA.
+ * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
+ */
+int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	pdc_result[0] = num_entries;
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 
+			      __pa(pdc_result), hpa, __pa(tbl));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+
+/**
+ * pdc_tod_read - Read the Time-Of-Day clock.
+ * @tod: The return buffer:
+ *
+ * Read the Time-Of-Day clock
+ */
+int pdc_tod_read(struct pdc_tod *tod)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(tod, pdc_result, sizeof(*tod));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/**
+ * pdc_tod_set - Set the Time-Of-Day clock.
+ * @sec: The number of seconds since epoch.
+ * @usec: The number of micro seconds.
+ *
+ * Set the Time-Of-Day clock.
+ */ 
+int pdc_tod_set(unsigned long sec, unsigned long usec)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifdef __LP64__
+int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+		struct pdc_memory_table *tbl, unsigned long entries)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
+	convert_to_wide(pdc_result);
+	memcpy(r_addr, pdc_result, sizeof(*r_addr));
+	memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+#endif /* __LP64__ */
+
+/* FIXME: Is this pdc used?  I could not find type reference to ftc_bitmap
+ * so I guessed at unsigned long.  Someone who knows what this does, can fix
+ * it later. :)
+ */
+int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
+                              PDC_FIRM_TEST_MAGIC, ftc_bitmap);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/*
+ * pdc_do_reset - Reset the system.
+ *
+ * Reset the system.
+ */
+int pdc_do_reset()
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+/*
+ * pdc_soft_power_info - Enable soft power switch.
+ * @power_reg: address of soft power register
+ *
+ * Return the absolute address of the soft power switch register
+ */
+int __init pdc_soft_power_info(unsigned long *power_reg)
+{
+	int retval;
+
+	*power_reg = (unsigned long) (-1);
+	
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
+	if (retval == PDC_OK) {
+                convert_to_wide(pdc_result);
+                *power_reg = f_extend(pdc_result[0]);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/*
+ * pdc_soft_power_button - Control the soft power button behaviour
+ * @sw_control: 0 for hardware control, 1 for software control 
+ *
+ *
+ * This PDC function places the soft power button under software or
+ * hardware control.
+ * Under software control the OS may control to when to allow to shut 
+ * down the system. Under hardware control pressing the power button 
+ * powers off the system immediately.
+ */
+int pdc_soft_power_button(int sw_control)
+{
+	int retval;
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
+	spin_unlock_irq(&pdc_lock);
+	return retval;
+}
+
+/*
+ * pdc_suspend_usb - Stop USB controller
+ *
+ * If PDC used the usb controller, the usb controller
+ * is still running and will crash the machines during iommu 
+ * setup, because of still running DMA. This PDC call
+ * stops the USB controller
+ */
+void pdc_suspend_usb(void)
+{
+	spin_lock_irq(&pdc_lock);  
+	mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
+	spin_unlock_irq(&pdc_lock);
+}
+
+/**
+ * pdc_iodc_putc - Console character print using IODC.
+ * @c: the character to output.
+ *
+ * Note that only these special chars are architected for console IODC io:
+ * BEL, BS, CR, and LF. Others are passed through.
+ * Since the HP console requires CR+LF to perform a 'newline', we translate
+ * "\n" to "\r\n".
+ */
+void pdc_iodc_putc(unsigned char c)
+{
+        /* XXX Should we spinlock posx usage */
+        static int posx;        /* for simple TAB-Simulation... */
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+        unsigned int n;
+	unsigned int flags;
+
+        switch (c) {
+        case '\n':
+                iodc_dbuf[0] = '\r';
+                iodc_dbuf[1] = '\n';
+                n = 2;
+                posx = 0;
+                break;
+        case '\t':
+                pdc_iodc_putc(' ');
+                while (posx & 7)        /* expand TAB */
+                        pdc_iodc_putc(' ');
+                return;         /* return since IODC can't handle this */
+        case '\b':
+                posx-=2;                /* BS */
+        default:
+                iodc_dbuf[0] = c;
+                n = 1;
+                posx++;
+                break;
+        }
+
+        spin_lock_irqsave(&pdc_lock, flags);
+        real32_call(PAGE0->mem_cons.iodc_io,
+                    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+                    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+                    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
+        spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+/**
+ * pdc_iodc_outc - Console character print using IODC (without conversions).
+ * @c: the character to output.
+ *
+ * Write the character directly to the IODC console.
+ */
+void pdc_iodc_outc(unsigned char c)
+{
+	unsigned int n, flags;
+
+	/* fill buffer with one caracter and print it */
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+
+	n = 1;
+	iodc_dbuf[0] = c;
+
+	spin_lock_irqsave(&pdc_lock, flags);
+	real32_call(PAGE0->mem_cons.iodc_io,
+		    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+		    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+}
+
+/**
+ * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
+ *
+ * Read a character (non-blocking) from the PDC console, returns -1 if
+ * key is not present.
+ */
+int pdc_iodc_getc(void)
+{
+	unsigned int flags;
+        static int __attribute__((aligned(8)))   iodc_retbuf[32];
+        static char __attribute__((aligned(64))) iodc_dbuf[4096];
+	int ch;
+	int status;
+
+	/* Bail if no console input device. */
+	if (!PAGE0->mem_kbd.iodc_io)
+		return 0;
+	
+	/* wait for a keyboard (rs232)-input */
+	spin_lock_irqsave(&pdc_lock, flags);
+	real32_call(PAGE0->mem_kbd.iodc_io,
+		    (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+		    PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
+		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+
+	ch = *iodc_dbuf;
+	status = *iodc_retbuf;
+	spin_unlock_irqrestore(&pdc_lock, flags);
+
+	if (status == 0)
+	    return -1;
+	
+	return ch;
+}
+
+int pdc_sti_call(unsigned long func, unsigned long flags,
+                 unsigned long inptr, unsigned long outputr,
+                 unsigned long glob_cfg)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);  
+        retval = real32_call(func, flags, inptr, outputr, glob_cfg);
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+
+#ifdef __LP64__
+/**
+ * pdc_pat_cell_get_number - Returns the cell number.
+ * @cell_info: The return buffer.
+ *
+ * This PDC call returns the cell number of the cell from which the call
+ * is made.
+ */
+int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
+	memcpy(cell_info, pdc_result, sizeof(*cell_info));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cell_module - Retrieve the cell's module information.
+ * @actcnt: The number of bytes written to mem_addr.
+ * @ploc: The physical location.
+ * @mod: The module index.
+ * @view_type: The view of the address type.
+ * @mem_addr: The return buffer.
+ *
+ * This PDC call returns information about each module attached to the cell
+ * at the specified location.
+ */
+int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
+			unsigned long view_type, void *mem_addr)
+{
+	int retval;
+	static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), 
+			      ploc, mod, view_type, __pa(&result));
+	if(!retval) {
+		*actcnt = pdc_result[0];
+		memcpy(mem_addr, &result, *actcnt);
+	}
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_cpu_get_number - Retrieve the cpu number.
+ * @cpu_info: The return buffer.
+ * @hpa: The Hard Physical Address of the CPU.
+ *
+ * Retrieve the cpu number for the cpu at the specified HPA.
+ */
+int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
+			      __pa(&pdc_result), hpa);
+	memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table.
+ * @num_entries: The return value.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the number of entries in the specified cell's
+ * interrupt table.
+ */
+int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
+			      __pa(pdc_result), cell_num);
+	*num_entries = pdc_result[0];
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_get_irt - Retrieve the cell's interrupt table.
+ * @r_addr: The return buffer.
+ * @cell_num: The target cell.
+ *
+ * This PDC function returns the actual interrupt table for the specified cell.
+ */
+int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
+			      __pa(r_addr), cell_num);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+
+/**
+ * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges.
+ * @actlen: The return buffer.
+ * @mem_addr: Pointer to the memory buffer.
+ * @count: The number of bytes to read from the buffer.
+ * @offset: The offset with respect to the beginning of the buffer.
+ *
+ */
+int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, 
+			    unsigned long count, unsigned long offset)
+{
+	int retval;
+
+	spin_lock_irq(&pdc_lock);
+	retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), 
+			      __pa(pdc_result2), count, offset);
+	*actual_len = pdc_result[0];
+	memcpy(mem_addr, pdc_result2, *actual_len);
+	spin_unlock_irq(&pdc_lock);
+
+	return retval;
+}
+#endif /* __LP64__ */
+
+
+/***************** 32-bit real-mode calls ***********/
+/* The struct below is used
+ * to overlay real_stack (real2.S), preparing a 32-bit call frame.
+ * real32_call_asm() then uses this stack in narrow real mode
+ */
+
+struct narrow_stack {
+	/* use int, not long which is 64 bits */
+	unsigned int arg13;
+	unsigned int arg12;
+	unsigned int arg11;
+	unsigned int arg10;
+	unsigned int arg9;
+	unsigned int arg8;
+	unsigned int arg7;
+	unsigned int arg6;
+	unsigned int arg5;
+	unsigned int arg4;
+	unsigned int arg3;
+	unsigned int arg2;
+	unsigned int arg1;
+	unsigned int arg0;
+	unsigned int frame_marker[8];
+	unsigned int sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+static long real32_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct narrow_stack real_stack;
+	extern unsigned long real32_call_asm(unsigned int *,
+					     unsigned int *, 
+					     unsigned int);
+	
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned int);
+	real_stack.arg1 = va_arg(args, unsigned int);
+	real_stack.arg2 = va_arg(args, unsigned int);
+	real_stack.arg3 = va_arg(args, unsigned int);
+	real_stack.arg4 = va_arg(args, unsigned int);
+	real_stack.arg5 = va_arg(args, unsigned int);
+	real_stack.arg6 = va_arg(args, unsigned int);
+	real_stack.arg7 = va_arg(args, unsigned int);
+	real_stack.arg8 = va_arg(args, unsigned int);
+	real_stack.arg9 = va_arg(args, unsigned int);
+	real_stack.arg10 = va_arg(args, unsigned int);
+	real_stack.arg11 = va_arg(args, unsigned int);
+	real_stack.arg12 = va_arg(args, unsigned int);
+	real_stack.arg13 = va_arg(args, unsigned int);
+	va_end(args);
+	
+	return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+}
+
+#ifdef __LP64__
+/***************** 64-bit real-mode calls ***********/
+
+struct wide_stack {
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long arg6;
+	unsigned long arg7;
+	unsigned long arg8;
+	unsigned long arg9;
+	unsigned long arg10;
+	unsigned long arg11;
+	unsigned long arg12;
+	unsigned long arg13;
+	unsigned long frame_marker[2];	/* rp, previous sp */
+	unsigned long sp;
+	/* in reality, there's nearly 8k of stack after this */
+};
+
+static long real64_call(unsigned long fn, ...)
+{
+	va_list args;
+	extern struct wide_stack real_stack;
+	extern unsigned long real64_call_asm(unsigned long *,
+					     unsigned long *, 
+					     unsigned long);
+    
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned long);
+	real_stack.arg1 = va_arg(args, unsigned long);
+	real_stack.arg2 = va_arg(args, unsigned long);
+	real_stack.arg3 = va_arg(args, unsigned long);
+	real_stack.arg4 = va_arg(args, unsigned long);
+	real_stack.arg5 = va_arg(args, unsigned long);
+	real_stack.arg6 = va_arg(args, unsigned long);
+	real_stack.arg7 = va_arg(args, unsigned long);
+	real_stack.arg8 = va_arg(args, unsigned long);
+	real_stack.arg9 = va_arg(args, unsigned long);
+	real_stack.arg10 = va_arg(args, unsigned long);
+	real_stack.arg11 = va_arg(args, unsigned long);
+	real_stack.arg12 = va_arg(args, unsigned long);
+	real_stack.arg13 = va_arg(args, unsigned long);
+	va_end(args);
+	
+	return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+}
+
+#endif /* __LP64__ */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/hardware.c linux-2.4.20/arch/parisc/kernel/hardware.c
--- linux-2.4.19/arch/parisc/kernel/hardware.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/hardware.c	2002-10-04 00:41:17.000000000 +0000
@@ -5,7 +5,7 @@
  * 
  *    Based on the document "PA-RISC 1.1 I/O Firmware Architecture 
  *    Reference Specification", March 7, 1999, version 0.96.  This
- *    is available at ?.
+ *    is available at http://parisc-linux.org/documentation/
  *
  *    Copyright 1999 by Alex deVries <adevries@thepuffingroup.com>
  *    and copyright 1999 The Puffin Group Inc.
@@ -30,32 +30,15 @@
 #include <asm/hardware.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
-
-#define HPHW_NUM_TYPES 3431
-
-static char * hw_type_name[16] = {
-	"Processor",
-	"Memory",
-	"B DMA",
-	"Obsolete",
-	"A DMA",
-	"A Direct",
-	"Obsolete",
-	"Bus Converter Port",
-	"HP CIO Adapter",
-	"Console",
-	"Foreign I/O Module",
-	"Bus Adapter",
-	"IOA (?)",
-	"Bus Bridge to Foreign Bus",
-	"HP Clothing: Fabric Component"
-};
+#include <linux/init.h>
 
 /*
- *	XXX	Could this be __init ??
+ *	HP PARISC Hardware Database
+ *	Access to this database is only possible during bootup
+ *	so don't reference this table after starting the init process
  */
  
-static struct hp_hardware hp_hardware_list[] = {
+static struct hp_hardware hp_hardware_list[] __initdata = {
 	{HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"},
 	{HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"},
 	{HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"},
@@ -169,9 +152,10 @@
 	{HPHW_NPROC,0x59A,0x4,0x91,"Unlisted but reserved"},
 	{HPHW_NPROC,0x59A,0x4,0x81,"Unlisted but reserved"},
 	{HPHW_NPROC,0x59B,0x4,0x81,"Raven U 160 (9000/780/C160)"},
+	{HPHW_NPROC,0x59C,0x4,0x81,"Raven U 180 (9000/780/C180)"},
 	{HPHW_NPROC,0x59D,0x4,0x81,"Raven U 200 (9000/780/C200)"},
 	{HPHW_NPROC,0x59E,0x4,0x91,"ThunderHawk T' 120"},
-	{HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780/\?\?\?\?)"},
+	{HPHW_NPROC,0x59F,0x4,0x91,"Raven U 180+ (9000/780)"},
 	{HPHW_NPROC,0x5A0,0x4,0x81,"UL 1w T120 1MB/1MB (841/D260,D360)"},
 	{HPHW_NPROC,0x5A1,0x4,0x91,"UL 2w T120 1MB/1MB (851/D260,D360)"},
 	{HPHW_NPROC,0x5A2,0x4,0x81,"UL 1w U160 512K/512K (861/D270,D370)"},
@@ -201,7 +185,7 @@
 	{HPHW_NPROC,0x5B8,0x4,0x91,"SPP2250 240 MHz"},
 	{HPHW_NPROC,0x5B9,0x4,0x81,"UL 1w U+/240 (350/550)"},
 	{HPHW_NPROC,0x5BA,0x4,0x91,"UL 2w U+/240 (350/550)"},
-	{HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W "},
+	{HPHW_NPROC,0x5BB,0x4,0x81,"AllegroHigh W"},
 	{HPHW_NPROC,0x5BC,0x4,0x91,"AllegroLow W"},
 	{HPHW_NPROC,0x5BD,0x4,0x91,"Forte W 2-way"},
 	{HPHW_NPROC,0x5BE,0x4,0x91,"Prelude W"},
@@ -212,12 +196,41 @@
 	{HPHW_NPROC,0x5C3,0x4,0x91,"Sonata 360"},
 	{HPHW_NPROC,0x5C4,0x4,0x91,"Rhapsody 440"},
 	{HPHW_NPROC,0x5C5,0x4,0x91,"Rhapsody 360"},
-	{HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780/\?\?\?\?)"},
+	{HPHW_NPROC,0x5C6,0x4,0x91,"Raven W 360 (9000/780)"},
 	{HPHW_NPROC,0x5C7,0x4,0x91,"Halfdome W 440"},
 	{HPHW_NPROC,0x5C8,0x4,0x81,"Lego 360 processor"},
 	{HPHW_NPROC,0x5C9,0x4,0x91,"Rhapsody DC- 440"},
 	{HPHW_NPROC,0x5CA,0x4,0x91,"Rhapsody DC- 360"},
 	{HPHW_NPROC,0x5CB,0x4,0x91,"Crescendo 440"},
+	{HPHW_NPROC,0x5CC,0x4,0x91,"Prelude W 440"},
+	{HPHW_NPROC,0x5CD,0x4,0x91,"SPP2600"},
+	{HPHW_NPROC,0x5CE,0x4,0x91,"M2600"},
+	{HPHW_NPROC,0x5CF,0x4,0x81,"Allegro W+"},
+	{HPHW_NPROC,0x5D0,0x4,0x81,"Kazoo W+"},
+	{HPHW_NPROC,0x5D1,0x4,0x91,"Forte W+ 2w"},
+	{HPHW_NPROC,0x5D2,0x4,0x91,"Forte W+ 4w"},
+	{HPHW_NPROC,0x5D3,0x4,0x91,"Prelude W+ 540"},
+	{HPHW_NPROC,0x5D4,0x4,0x91,"Duet W+"},
+	{HPHW_NPROC,0x5D5,0x4,0x91,"Crescendo 550"},
+	{HPHW_NPROC,0x5D6,0x4,0x81,"Crescendo DC- 440"},
+	{HPHW_NPROC,0x5D7,0x4,0x91,"Keystone W+"},
+	{HPHW_NPROC,0x5D8,0x4,0x91,"Rhapsody wave 2 W+ DC-"},
+	{HPHW_NPROC,0x5D9,0x4,0x91,"Rhapsody wave 2 W+"},
+	{HPHW_NPROC,0x5DA,0x4,0x91,"Marcato W+ DC-"},
+	{HPHW_NPROC,0x5DB,0x4,0x91,"Marcato W+"},
+	{HPHW_NPROC,0x5DC,0x4,0x91,"Allegro W2"},
+	{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
+	{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
+	{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
+	{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
+	{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
+	{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
+	{HPHW_NPROC,0x5E3,0x4,0x91,"Crescendo 750 W2"},
+	{HPHW_NPROC,0x5E4,0x4,0x91,"Keystone/Matterhorn W2 750"},
+	{HPHW_NPROC,0x5E5,0x4,0x91,"PowerBar W+"},
+	{HPHW_NPROC,0x5E6,0x4,0x91,"Keystone/Matterhorn W2 650"},
+	{HPHW_NPROC,0x5E7,0x4,0x91,"Caribe W2 800"},
+	{HPHW_NPROC,0x5E8,0x4,0x91,"Pikes Peak W2"},
 	{HPHW_NPROC,0x5FF,0x4,0x91,"Hitachi W"},
 	{HPHW_NPROC,0x600,0x4,0x81,"Gecko (712/60)"},
 	{HPHW_NPROC,0x601,0x4,0x81,"Gecko 80 (712/80)"},
@@ -243,7 +256,7 @@
 	{HPHW_NPROC,0x616,0x4,0x81,"Piranha 120"},
 	{HPHW_NPROC,0x617,0x4,0x81,"Jason 50"},
 	{HPHW_NPROC,0x618,0x4,0x81,"Jason 100"},
-	{HPHW_NPROC,0x619,0x4,0x81,"Mirage 80 "},
+	{HPHW_NPROC,0x619,0x4,0x81,"Mirage 80"},
 	{HPHW_NPROC,0x61A,0x4,0x81,"SAIC L-80"},
 	{HPHW_NPROC,0x61B,0x4,0x81,"Rocky1 L-60"},
 	{HPHW_NPROC,0x61C,0x4,0x81,"Anole T (743/T)"},
@@ -311,6 +324,7 @@
 	{HPHW_A_DMA, 0x004, 0x00050, 0x80, "Lanbrusca 802.3 (36967A)"}, 
 	{HPHW_A_DMA, 0x004, 0x00056, 0x80, "HP-PB LoQuix FDDI"}, 
 	{HPHW_A_DMA, 0x004, 0x00057, 0x80, "HP-PB LoQuix FDDI (28670A)"}, 
+	{HPHW_A_DMA, 0x004, 0x0005E, 0x00, "Gecko Add-on Token Ring"}, 
 	{HPHW_A_DMA, 0x012, 0x00089, 0x80, "Barracuda Add-on FW-SCSI"}, 
 	{HPHW_A_DMA, 0x013, 0x00089, 0x80, "Bluefish Add-on FW-SCSI"}, 
 	{HPHW_A_DMA, 0x014, 0x00089, 0x80, "Shrike Add-on FW-SCSI"}, 
@@ -319,6 +333,7 @@
 	{HPHW_A_DMA, 0x01F, 0x00089, 0x80, "SkyHawk 100/120 FW-SCSI"}, 
 	{HPHW_A_DMA, 0x027, 0x00089, 0x80, "Piranha 100 FW-SCSI"}, 
 	{HPHW_A_DMA, 0x032, 0x00089, 0x80, "Raven T' Core FW-SCSI"}, 
+	{HPHW_A_DMA, 0x03b, 0x00089, 0x80, "Raven U/L2 Core FW-SCSI"}, 
 	{HPHW_A_DMA, 0x03d, 0x00089, 0x80, "Merlin 160 Core FW-SCSI"},
 	{HPHW_A_DMA, 0x044, 0x00089, 0x80, "Mohawk Core FW-SCSI"}, 
 	{HPHW_A_DMA, 0x051, 0x00089, 0x80, "Firehawk FW-SCSI"}, 
@@ -440,6 +455,8 @@
 	{HPHW_BA, 0x801, 0x00081, 0x0, "Hitachi Tiny 80 Core BA"}, 
 	{HPHW_BA, 0x004, 0x0008B, 0x0, "Anole Optional PCMCIA BA"}, 
 	{HPHW_BA, 0x004, 0x0008E, 0x0, "GSC ITR Wax BA"}, 
+	{HPHW_BA, 0x00C, 0x0008E, 0x0, "Gecko Optional Wax BA"}, 
+	{HPHW_BA, 0x010, 0x0008E, 0x0, "Pace Wax BA"}, 
 	{HPHW_BA, 0x011, 0x0008E, 0x0, "SuperPace Wax BA"}, 
 	{HPHW_BA, 0x012, 0x0008E, 0x0, "Mirage Jr Wax BA"}, 
 	{HPHW_BA, 0x013, 0x0008E, 0x0, "Mirage Wax BA"}, 
@@ -489,7 +506,7 @@
 	{HPHW_BA, 0x800, 0x00090, 0x0, "Hitachi Tiny 64 Wax EISA BA"}, 
 	{HPHW_BA, 0x801, 0x00090, 0x0, "Hitachi Tiny 80 Wax EISA BA"}, 
 	{HPHW_BA, 0x01A, 0x00093, 0x0, "Anole 64 TIMI BA"}, 
-	{HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 64 TIMI BA"}, 
+	{HPHW_BA, 0x01B, 0x00093, 0x0, "Anole 100 TIMI BA"}, 
 	{HPHW_BA, 0x034, 0x00093, 0x0, "Anole T TIMI BA"}, 
 	{HPHW_BA, 0x04A, 0x00093, 0x0, "Anole L2 132 TIMI BA"}, 
 	{HPHW_BA, 0x04C, 0x00093, 0x0, "Anole L2 165 TIMI BA"}, 
@@ -551,6 +568,7 @@
 	{HPHW_CONSOLE, 0x01A, 0x0001F, 0x00, "Jason/Anole 64 Null Console"}, 
 	{HPHW_CONSOLE, 0x01B, 0x0001F, 0x00, "Jason/Anole 100 Null Console"}, 
 	{HPHW_FABRIC, 0x004, 0x000AA, 0x80, "Halfdome DNA Central Agent"}, 
+	{HPHW_FABRIC, 0x007, 0x000AA, 0x80, "Caribe DNA Central Agent"}, 
 	{HPHW_FABRIC, 0x004, 0x000AB, 0x00, "Halfdome TOGO Fabric Crossbar"}, 
 	{HPHW_FABRIC, 0x004, 0x000AC, 0x00, "Halfdome Sakura Fabric Router"}, 
 	{HPHW_FIO, 0x025, 0x0002E, 0x80, "Armyknife Optional X.25"}, 
@@ -588,14 +606,14 @@
 	{HPHW_FIO, 0x00D, 0x00072, 0x0, "Strider-33 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x00E, 0x00072, 0x0, "Trailways-50 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x00F, 0x00072, 0x0, "Trailways-33 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x010, 0x00072, 0x0, "Pace Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x011, 0x00072, 0x0, "Sidewinder Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x019, 0x00072, 0x0, "Scorpio Sr. Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x020, 0x00072, 0x0, "Scorpio 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x021, 0x00072, 0x0, "Spectra 50 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x022, 0x00072, 0x0, "Spectra 75 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x023, 0x00072, 0x0, "Spectra 100 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x024, 0x00072, 0x0, "Fast Pace Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x026, 0x00072, 0x0, "CoralII Jaguar Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x004, 0x00073, 0x0, "Cobra Core HIL"}, 
 	{HPHW_FIO, 0x005, 0x00073, 0x0, "Coral Core HIL"}, 
@@ -694,8 +712,8 @@
 	{HPHW_FIO, 0x04D, 0x00074, 0x0, "Anole L2 165 Core Centronics"}, 
 	{HPHW_FIO, 0x050, 0x00074, 0x0, "Merlin Jr 132 Core Centronics"}, 
 	{HPHW_FIO, 0x051, 0x00074, 0x0, "Firehawk Core Centronics"}, 
-	{HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ wSE FWSCSI Core Centronics"}, 
-	{HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ wDiff FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x056, 0x00074, 0x0, "Raven+ w SE FWSCSI Core Centronics"}, 
+	{HPHW_FIO, 0x057, 0x00074, 0x0, "Raven+ w Diff FWSCSI Core Centronics"}, 
 	{HPHW_FIO, 0x058, 0x00074, 0x0, "FireHawk 200 Core Centronics"}, 
 	{HPHW_FIO, 0x05C, 0x00074, 0x0, "SummitHawk 230 Core Centronics"}, 
 	{HPHW_FIO, 0x800, 0x00074, 0x0, "Hitachi Tiny 64 Core Centronics"}, 
@@ -861,66 +879,66 @@
 	{HPHW_FIO, 0x02E, 0x00083, 0x0, "UL 350 Core PC Floppy"}, 
 	{HPHW_FIO, 0x02F, 0x00083, 0x0, "UL 550 Core PC Floppy"}, 
 	{HPHW_FIO, 0x032, 0x00083, 0x0, "Raven T' Core PC Floppy"}, 
-	{HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floopy"}, 
-	{HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floopy"}, 
-	{HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floopy"}, 
-	{HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floopy"}, 
-	{HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floopy"}, 
-	{HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floopy"}, 
-	{HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floopy"}, 
-	{HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floopy"}, 
-	{HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floopy"}, 
-	{HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floopy"}, 
-	{HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floopy"}, 
-	{HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floopy"}, 
-	{HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PC Keyboard"}, 
-	{HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PC Keyboard"}, 
-	{HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PC Keyboard"}, 
-	{HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PC Keyboard"}, 
-	{HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PC Keyboard"}, 
-	{HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PC Keyboard"}, 
-	{HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core Keyboard"}, 
-	{HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core Keyboard"}, 
-	{HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PC Keyboard"}, 
-	{HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PC Keyboard"}, 
-	{HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PC Keyboard"}, 
-	{HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PC Keyboard"}, 
-	{HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PC Keyboard"}, 
-	{HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PC Keyboard"}, 
-	{HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PC Keyboard"}, 
-	{HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PC Keyboard"}, 
+	{HPHW_FIO, 0x034, 0x00083, 0x0, "SAIC L-80 Core PC Floppy"}, 
+	{HPHW_FIO, 0x035, 0x00083, 0x0, "PCX-L2 712/132 Core Floppy"}, 
+	{HPHW_FIO, 0x036, 0x00083, 0x0, "PCX-L2 712/160 Core Floppy"}, 
+	{HPHW_FIO, 0x03B, 0x00083, 0x0, "Raven U/L2 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03C, 0x00083, 0x0, "Merlin 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03D, 0x00083, 0x0, "Merlin 160 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03E, 0x00083, 0x0, "Merlin+ 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x03F, 0x00083, 0x0, "Merlin+ 180 Core PC Floppy"}, 
+	{HPHW_FIO, 0x045, 0x00083, 0x0, "Rocky1 Core PC Floppy"}, 
+	{HPHW_FIO, 0x046, 0x00083, 0x0, "Rocky2 120 Core PC Floppy"}, 
+	{HPHW_FIO, 0x047, 0x00083, 0x0, "Rocky2 150 Core PC Floppy"}, 
+	{HPHW_FIO, 0x04E, 0x00083, 0x0, "Kiji L2 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x050, 0x00083, 0x0, "Merlin Jr 132 Core PC Floppy"}, 
+	{HPHW_FIO, 0x056, 0x00083, 0x0, "Raven+ w SE FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x057, 0x00083, 0x0, "Raven+ w Diff FWSCSI Core PC Floppy"}, 
+	{HPHW_FIO, 0x800, 0x00083, 0x0, "Hitachi Tiny 64 Core PC Floppy"}, 
+	{HPHW_FIO, 0x801, 0x00083, 0x0, "Hitachi Tiny 80 Core PC Floppy"},
+	{HPHW_FIO, 0x015, 0x00084, 0x0, "KittyHawk GSY Core PS/2 Port"}, 
+	{HPHW_FIO, 0x016, 0x00084, 0x0, "Gecko Core PS/2 Port"}, 
+	{HPHW_FIO, 0x018, 0x00084, 0x0, "Gecko Optional PS/2 Port"}, 
+	{HPHW_FIO, 0x01A, 0x00084, 0x0, "Anole 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01B, 0x00084, 0x0, "Anole 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01C, 0x00084, 0x0, "Gecko 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01D, 0x00084, 0x0, "Gecko 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x01F, 0x00084, 0x0, "SkyHawk 100/120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x027, 0x00084, 0x0, "Piranha 100 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x028, 0x00084, 0x0, "Mirage Jr Core PS/2 Port"}, 
+	{HPHW_FIO, 0x029, 0x00084, 0x0, "Mirage Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02A, 0x00084, 0x0, "Electra Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02B, 0x00084, 0x0, "Mirage 80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02C, 0x00084, 0x0, "Mirage 100+ Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02E, 0x00084, 0x0, "UL 350 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x02F, 0x00084, 0x0, "UL 550 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x032, 0x00084, 0x0, "Raven T' Core PS/2 Port"}, 
+	{HPHW_FIO, 0x033, 0x00084, 0x0, "Anole T Core PS/2 Port"}, 
+	{HPHW_FIO, 0x034, 0x00084, 0x0, "SAIC L-80 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x035, 0x00084, 0x0, "PCX-L2 712/132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x036, 0x00084, 0x0, "PCX-L2 712/160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03B, 0x00084, 0x0, "Raven U/L2 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03C, 0x00084, 0x0, "Merlin 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03D, 0x00084, 0x0, "Merlin 160 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03E, 0x00084, 0x0, "Merlin+ 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x03F, 0x00084, 0x0, "Merlin+ 180 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x044, 0x00084, 0x0, "Mohawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x045, 0x00084, 0x0, "Rocky1 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x046, 0x00084, 0x0, "Rocky2 120 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x047, 0x00084, 0x0, "Rocky2 150 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x048, 0x00084, 0x0, "Rocky2 120 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x049, 0x00084, 0x0, "Rocky2 150 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x04B, 0x00084, 0x0, "Anole L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04D, 0x00084, 0x0, "Anole L2 165 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x04E, 0x00084, 0x0, "Kiji L2 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x050, 0x00084, 0x0, "Merlin Jr 132 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x051, 0x00084, 0x0, "Firehawk Core PS/2 Port"}, 
+	{HPHW_FIO, 0x056, 0x00084, 0x0, "Raven+ w SE FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x057, 0x00084, 0x0, "Raven+ w Diff FWSCSI Core PS/2 Port"}, 
+	{HPHW_FIO, 0x058, 0x00084, 0x0, "FireHawk 200 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x05C, 0x00084, 0x0, "SummitHawk 230 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x800, 0x00084, 0x0, "Hitachi Tiny 64 Core PS/2 Port"}, 
+	{HPHW_FIO, 0x801, 0x00084, 0x0, "Hitachi Tiny 80 Core PS/2 Port"}, 
 	{HPHW_FIO, 0x004, 0x00085, 0x0, "Solo GSC Optional Graphics"}, 
 	{HPHW_FIO, 0x005, 0x00085, 0x0, "Duet GSC Optional Graphics"}, 
 	{HPHW_FIO, 0x008, 0x00085, 0x0, "Anole Artist Optional Graphics"}, 
@@ -969,18 +987,17 @@
 	{HPHW_FIO, 0x034, 0x00088, 0x0, "Anole T VME Networking"}, 
 	{HPHW_FIO, 0x04A, 0x00088, 0x0, "Anole L2 132 VME Networking"}, 
 	{HPHW_FIO, 0x04C, 0x00088, 0x0, "Anole L2 165 VME Networking"}, 
-	{HPHW_FIO, 0x03B, 0x00089, 0x0, "Raven U/L2 Core FW-SCSI"}, 
-	{HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional Lan (802.3)"}, 
-	{HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x011, 0x0008A, 0x0, "WB-96 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x012, 0x0008A, 0x0, "Orville Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x013, 0x0008A, 0x0, "Wilbur Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x014, 0x0008A, 0x0, "WB-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x015, 0x0008A, 0x0, "KittyHawk GSY Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x016, 0x0008A, 0x0, "Gecko Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x018, 0x0008A, 0x0, "Gecko Optional LAN (802.3)"}, 
+	{HPHW_FIO, 0x01A, 0x0008A, 0x0, "Anole 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01B, 0x0008A, 0x0, "Anole 100 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01C, 0x0008A, 0x0, "Gecko 80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x01D, 0x0008A, 0x0, "Gecko 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x01F, 0x0008A, 0x0, "SkyHawk 100/120 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x027, 0x0008A, 0x0, "Piranha 100 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x028, 0x0008A, 0x0, "Mirage Jr Core LAN (802.3)"}, 
@@ -991,24 +1008,24 @@
 	{HPHW_FIO, 0x02E, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x02F, 0x0008A, 0x0, "UL 350 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x032, 0x0008A, 0x0, "Raven T' Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x033, 0x0008A, 0x0, "Anole T Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x034, 0x0008A, 0x0, "SAIC L-80 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x035, 0x0008A, 0x0, "PCX-L2 712/132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x036, 0x0008A, 0x0, "PCX-L2 712/160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03B, 0x0008A, 0x0, "Raven U/L2 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03C, 0x0008A, 0x0, "Merlin 132 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x03D, 0x0008A, 0x0, "Merlin 160 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x044, 0x0008A, 0x0, "Mohawk Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x045, 0x0008A, 0x0, "Rocky1 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x046, 0x0008A, 0x0, "Rocky2 120 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x047, 0x0008A, 0x0, "Rocky2 150 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04B, 0x0008A, 0x0, "Anole L2 132 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04D, 0x0008A, 0x0, "Anole L2 165 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x04E, 0x0008A, 0x0, "Kiji L2 132 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x050, 0x0008A, 0x0, "Merlin Jr 132 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x058, 0x0008A, 0x0, "FireHawk 200 Core LAN (802.3)"}, 
-	{HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core Lan (802.3)"}, 
-	{HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core Lan (802.3)"}, 
+	{HPHW_FIO, 0x800, 0x0008A, 0x0, "Hitachi Tiny 64 Core LAN (802.3)"}, 
+	{HPHW_FIO, 0x801, 0x0008A, 0x0, "Hitachi Tiny 80 Core LAN (802.3)"}, 
 	{HPHW_FIO, 0x004, 0x0008C, 0x0, "SkyHawk 100/120 Wax RS-232"}, 
 	{HPHW_FIO, 0x005, 0x0008C, 0x0, "SAIC L-80 Wax RS-232"}, 
 	{HPHW_FIO, 0x006, 0x0008C, 0x0, "Raven U/L2 Dino RS-232"}, 
@@ -1099,14 +1116,15 @@
 	{HPHW_FIO, 0x005, 0x0008F, 0x0, "Rocky1 Boot Rom"}, 
 	{HPHW_FIO, 0x006, 0x0008F, 0x0, "Rocky2 120 Boot Rom"}, 
 	{HPHW_FIO, 0x007, 0x0008F, 0x0, "Rocky2 150 Boot Rom"}, 
-	{HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS2 Keyboard"}, 
-	{HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG lan"}, 
+	{HPHW_FIO, 0x01B, 0x0008F, 0x0, "Anole 100 Boot Rom"}, 
+	{HPHW_FIO, 0x006, 0x00096, 0x0, "Raven U/L2 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x007, 0x00096, 0x0, "Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x008, 0x00096, 0x0, "Merlin 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x009, 0x00096, 0x0, "Merlin 160 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x00A, 0x00096, 0x0, "Merlin Jr 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x019, 0x00096, 0x0, "Merlin+ 180 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x022, 0x00096, 0x0, "Merlin+ 132 Dino PS/2 Port"}, 
+	{HPHW_FIO, 0x004, 0x00097, 0x0, "Cascade EISA 100VG LAN"}, 
 	{HPHW_FIO, 0x023, 0x00099, 0x0, "Rocky1 Wax HPIB"}, 
 	{HPHW_FIO, 0x048, 0x00099, 0x0, "Rocky2 120 Clark/Dino HPIB"}, 
 	{HPHW_FIO, 0x049, 0x00099, 0x0, "Rocky2 150 Clark/Dino HPIB"}, 
@@ -1114,14 +1132,14 @@
 	{HPHW_FIO, 0x004, 0x000A2, 0x0, "Forte Core PCI 10/100BT LAN"}, 
 	{HPHW_FIO, 0x005, 0x000A2, 0x0, "AllegroLow PCI 10/100BT LAN"}, 
 	{HPHW_FIO, 0x006, 0x000A2, 0x0, "AllegroHIgh Core PCI 10/100BT LAN"}, 
-	{HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in Lan"}, 
-	{HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT Lan"}, 
-	{HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI Lan"}, 
-	{HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI Lan"}, 
-	{HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI Lan"}, 
-	{HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI Lan"}, 
-	{HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI Lan"}, 
-	{HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI Lan"}, 
+	{HPHW_FIO, 0x007, 0x000A2, 0x0, "PCI Plug-in LAN"}, 
+	{HPHW_FIO, 0x00A, 0x000A2, 0x0, "Lego 360 Core PCI 10/100BT LAN"}, 
+	{HPHW_FIO, 0x03E, 0x000A2, 0x0, "Merlin+ 132 Core PCI LAN"}, 
+	{HPHW_FIO, 0x03F, 0x000A2, 0x0, "Merlin+ 180 Core PCI LAN"}, 
+	{HPHW_FIO, 0x056, 0x000A2, 0x0, "Raven+ w SE FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x057, 0x000A2, 0x0, "Raven+ w Diff FWSCSI Core PCI LAN"}, 
+	{HPHW_FIO, 0x05E, 0x000A2, 0x0, "Staccato 132 PCI LAN"}, 
+	{HPHW_FIO, 0x05F, 0x000A2, 0x0, "Staccato 180 PCI LAN"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI LVD Ultra2 SCSI"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI SE UltraSCSI"}, 
 	{HPHW_FIO, 0x004, 0x000A3, 0x0, "Forte Core PCI IDE/ATAPI CD-ROM"}, 
@@ -1157,160 +1175,19 @@
 	{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, 
 	{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, 
 	{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, 
-	{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"}, 
-	{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"}, 
-	{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"}, 
+	{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"},
+	{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"},
+	{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"},
 	{HPHW_MEMORY, 0x002, 0x00008, 0x00, "MID_BUS"}, 
-	{HPHW_MEMORY, 0x00C, 0x00008, 0x08, "Kahlua 8MB"}, 
-	{HPHW_MEMORY, 0x00D, 0x00008, 0x08, "Kahlua 4MB"}, 
-	{HPHW_MEMORY, 0x00E, 0x00008, 0x08, "Tequila 16MB"}, 
-	{HPHW_MEMORY, 0x00F, 0x00008, 0x08, "Tequila 32MB"}, 
-	{HPHW_MEMORY, 0x040, 0x00008, 0x00, "Hitachi"}, 
-	{HPHW_MEMORY, 0x004, 0x00009, 0x00, "Cheetah"}, 
-	{HPHW_MEMORY, 0x005, 0x00009, 0x00, "Emerald"}, 
-	{HPHW_MEMORY, 0x008, 0x00009, 0x00, "Indigo 3MB/5MB"}, 
-	{HPHW_MEMORY, 0x00C, 0x00009, 0x00, "Indigo 8MB"}, 
-	{HPHW_MEMORY, 0x00D, 0x00009, 0x00, "Paradise 4MB"}, 
-	{HPHW_MEMORY, 0x00E, 0x00009, 0x00, "Burgundy Onboard"}, 
-	{HPHW_MEMORY, 0x012, 0x00009, 0x00, "Indigo 12MB/20MB"}, 
-	{HPHW_MEMORY, 0x013, 0x00009, 0x00, "Cobra"}, 
-	{HPHW_MEMORY, 0x014, 0x00009, 0x00, "Nova"}, 
-	{HPHW_MEMORY, 0x015, 0x00009, 0x00, "Coral"}, 
-	{HPHW_MEMORY, 0x016, 0x00009, 0x00, "Bushmaster"}, 
-	{HPHW_MEMORY, 0x017, 0x00009, 0x00, "Scorpio"}, 
-	{HPHW_MEMORY, 0x018, 0x00009, 0x00, "Flounder"}, 
-	{HPHW_MEMORY, 0x019, 0x00009, 0x00, "Hardball"}, 
-	{HPHW_MEMORY, 0x01A, 0x00009, 0x00, "CoralII 99"}, 
-	{HPHW_MEMORY, 0x01B, 0x00009, 0x00, "Scorpio Jr."}, 
-	{HPHW_MEMORY, 0x01C, 0x00009, 0x00, "Strider-50 (715T)"}, 
-	{HPHW_MEMORY, 0x01D, 0x00009, 0x00, "Strider-33 (707T)"}, 
-	{HPHW_MEMORY, 0x01E, 0x00009, 0x00, "Trailways-50 (715S)"}, 
-	{HPHW_MEMORY, 0x01F, 0x00009, 0x00, "Trailways-33 (707S)"}, 
-	{HPHW_MEMORY, 0x020, 0x00009, 0x00, "Pace"}, 
-	{HPHW_MEMORY, 0x021, 0x00009, 0x00, "Sidewinder"}, 
-	{HPHW_MEMORY, 0x022, 0x00009, 0x00, "Orville"}, 
-	{HPHW_MEMORY, 0x023, 0x00009, 0x00, "Wilbur"}, 
-	{HPHW_MEMORY, 0x026, 0x00009, 0x00, "Gecko"}, 
-	{HPHW_MEMORY, 0x027, 0x00009, 0x00, "Scorpio Sr."}, 
-	{HPHW_MEMORY, 0x028, 0x00009, 0x00, "Scorpio 100"}, 
-	{HPHW_MEMORY, 0x029, 0x00009, 0x00, "Spectra 50"}, 
-	{HPHW_MEMORY, 0x02A, 0x00009, 0x00, "CoralII 132"}, 
-	{HPHW_MEMORY, 0x02F, 0x00009, 0x00, "KittyHawk DC2-"}, 
-	{HPHW_MEMORY, 0x030, 0x00009, 0x00, "Spectra 75"}, 
-	{HPHW_MEMORY, 0x031, 0x00009, 0x00, "Spectra 100"}, 
-	{HPHW_MEMORY, 0x032, 0x00009, 0x00, "KittyHawk DC3"}, 
-	{HPHW_MEMORY, 0x033, 0x00009, 0x00, "Fast Pace"}, 
-	{HPHW_MEMORY, 0x034, 0x00009, 0x00, "Snake Eagle"}, 
-	{HPHW_MEMORY, 0x035, 0x00009, 0x00, "Anole 64"}, 
-	{HPHW_MEMORY, 0x036, 0x00009, 0x00, "Anole 100"}, 
-	{HPHW_MEMORY, 0x037, 0x00009, 0x00, "Snake Cheetah"}, 
-	{HPHW_MEMORY, 0x038, 0x00009, 0x00, "Gecko 80"}, 
-	{HPHW_MEMORY, 0x039, 0x00009, 0x00, "Gecko 100"}, 
-	{HPHW_MEMORY, 0x03A, 0x00009, 0x00, "Gecko 120"}, 
-	{HPHW_MEMORY, 0x03B, 0x00009, 0x00, "Gila 80"}, 
-	{HPHW_MEMORY, 0x03C, 0x00009, 0x00, "Gila 100"}, 
-	{HPHW_MEMORY, 0x03D, 0x00009, 0x00, "Gila 120"}, 
-	{HPHW_MEMORY, 0x03E, 0x00009, 0x00, "Scorpio-L 80"}, 
-	{HPHW_MEMORY, 0x03F, 0x00009, 0x00, "Scorpio-L 100"}, 
-	{HPHW_MEMORY, 0x040, 0x00009, 0x00, "Scorpio-L 120"}, 
-	{HPHW_MEMORY, 0x041, 0x00009, 0x00, "Spectra-L 80"}, 
-	{HPHW_MEMORY, 0x042, 0x00009, 0x00, "Spectra-L 100"}, 
-	{HPHW_MEMORY, 0x043, 0x00009, 0x00, "Spectra-L 120"}, 
-	{HPHW_MEMORY, 0x044, 0x00009, 0x00, "Piranha 100"}, 
-	{HPHW_MEMORY, 0x045, 0x00009, 0x00, "Piranha 120"}, 
-	{HPHW_MEMORY, 0x046, 0x00009, 0x00, "Jason 50"}, 
-	{HPHW_MEMORY, 0x047, 0x00009, 0x00, "Jason 100"}, 
-	{HPHW_MEMORY, 0x049, 0x00009, 0x00, "SkyHawk 100/120"}, 
-	{HPHW_MEMORY, 0x04A, 0x00009, 0x00, "Mirage Jr"}, 
-	{HPHW_MEMORY, 0x04B, 0x00009, 0x00, "Mirage 100"}, 
-	{HPHW_MEMORY, 0x04C, 0x00009, 0x00, "Mirage 100+"}, 
-	{HPHW_MEMORY, 0x04D, 0x00009, 0x00, "Electra 100"}, 
-	{HPHW_MEMORY, 0x04E, 0x00009, 0x00, "Electra 120"}, 
-	{HPHW_MEMORY, 0x04F, 0x00009, 0x00, "Mirage 80"}, 
-	{HPHW_MEMORY, 0x050, 0x00009, 0x00, "UL Proc 1 way T'100"}, 
-	{HPHW_MEMORY, 0x051, 0x00009, 0x00, "UL Proc 1 way T'120"}, 
-	{HPHW_MEMORY, 0x052, 0x00009, 0x00, "UL Proc 2 way T'100"}, 
-	{HPHW_MEMORY, 0x053, 0x00009, 0x00, "KittyHawk DC3-"}, 
-	{HPHW_MEMORY, 0x054, 0x00009, 0x00, "UL Proc 2 way T'120"}, 
-	{HPHW_MEMORY, 0x055, 0x00009, 0x00, "Raven 120 mem"}, 
-	{HPHW_MEMORY, 0x056, 0x00009, 0x00, "UL Proc L 75"}, 
-	{HPHW_MEMORY, 0x057, 0x00009, 0x00, "UL Proc L 100"}, 
-	{HPHW_MEMORY, 0x058, 0x00009, 0x00, "Anole T"}, 
-	{HPHW_MEMORY, 0x059, 0x00009, 0x00, "SAIC L-80"}, 
-	{HPHW_MEMORY, 0x05A, 0x00009, 0x00, "Merlin+ L2 180"}, 
-	{HPHW_MEMORY, 0x05B, 0x00009, 0x00, "Raven U 200 2-way"}, 
-	{HPHW_MEMORY, 0x05C, 0x00009, 0x00, "Raven U 180+"}, 
-	{HPHW_MEMORY, 0x05D, 0x00009, 0x00, "Raven U 200"}, 
-	{HPHW_MEMORY, 0x05E, 0x00009, 0x00, "Rocky2 150 Memory"}, 
-	{HPHW_MEMORY, 0x08A, 0x00009, 0x00, "Staccato L2 132 Memory"}, 
-	{HPHW_MEMORY, 0x08B, 0x00009, 0x00, "Staccato L2 180 Memory"}, 
-	{HPHW_MEMORY, 0x05F, 0x00009, 0x00, "SPP2000 Memory"}, 
-	{HPHW_MEMORY, 0x060, 0x00009, 0x00, "Merlin L2 132"}, 
-	{HPHW_MEMORY, 0x061, 0x00009, 0x00, "Merlin+ L2 132"}, 
 	{HPHW_MEMORY, 0x063, 0x00009, 0x00, "712/132 L2 Upgrade"}, 
 	{HPHW_MEMORY, 0x064, 0x00009, 0x00, "712/160 L2 Upgrade"}, 
 	{HPHW_MEMORY, 0x065, 0x00009, 0x00, "715/132 L2 Upgrade"}, 
-	{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"}, 
-	{HPHW_MEMORY, 0x067, 0x00009, 0x00, "Merlin 160/ThunderHawk Memory"}, 
-	{HPHW_MEMORY, 0x068, 0x00009, 0x00, "LightningHawk Memory"}, 
-	{HPHW_MEMORY, 0x069, 0x00009, 0x00, "Rocky1 Memory"}, 
-	{HPHW_MEMORY, 0x06A, 0x00009, 0x00, "Raven L2 132"}, 
-	{HPHW_MEMORY, 0x06B, 0x00009, 0x00, "Raven L2 160"}, 
-	{HPHW_MEMORY, 0x06C, 0x00009, 0x00, "Raven L2 187"}, 
-	{HPHW_MEMORY, 0x06D, 0x00009, 0x00, "Raven L2 200"}, 
-	{HPHW_MEMORY, 0x06E, 0x00009, 0x00, "Raven U 230"}, 
-	{HPHW_MEMORY, 0x06F, 0x00009, 0x00, "Raven U 240"}, 
-	{HPHW_MEMORY, 0x070, 0x00009, 0x00, "Rocky2 120 Memory"}, 
-	{HPHW_MEMORY, 0x071, 0x00009, 0x00, "Raven U 160"}, 
-	{HPHW_MEMORY, 0x072, 0x00009, 0x00, "Raven U 180"}, 
-	{HPHW_MEMORY, 0x072, 0x00009, 0x00, "UL Proc 1 way T'120 1MB/1MB"}, 
-	{HPHW_MEMORY, 0x073, 0x00009, 0x00, "UL Proc 2 way T'120 1MB/1MB"}, 
-	{HPHW_MEMORY, 0x074, 0x00009, 0x00, "Anole L2 132 memory"}, 
-	{HPHW_MEMORY, 0x075, 0x00009, 0x00, "Anole L2 165 memory"}, 
-	{HPHW_MEMORY, 0x076, 0x00009, 0x00, "UL 1 way U160 512K/512K memory"}, 
-	{HPHW_MEMORY, 0x077, 0x00009, 0x00, "UL 2 way U160 512K/512K memory"}, 
-	{HPHW_MEMORY, 0x078, 0x00009, 0x00, "Kiji L2 132 memory"}, 
-	{HPHW_MEMORY, 0x079, 0x00009, 0x00, "UL 1 way U160 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07A, 0x00009, 0x00, "UL 2 way U160 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07B, 0x00009, 0x00, "UL 1 way U180 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07C, 0x00009, 0x00, "UL 2 way U180 1M/1M memory"}, 
-	{HPHW_MEMORY, 0x07D, 0x00009, 0x00, "UL 1 way U240 U+ 2M/2M memory"}, 
-	{HPHW_MEMORY, 0x07E, 0x00009, 0x00, "UL 2 way U240 U+ 2M/2M memory"}, 
-	{HPHW_MEMORY, 0x07F, 0x00009, 0x00, "UL L2 132 memory"}, 
-	{HPHW_MEMORY, 0x080, 0x00009, 0x00, "UL L2 160 memory"}, 
-	{HPHW_MEMORY, 0x081, 0x00009, 0x00, "Merlin Jr 132 memory"}, 
-	{HPHW_MEMORY, 0x082, 0x00009, 0x00, "FireHawk 200 Memory"}, 
-	{HPHW_MEMORY, 0x083, 0x00009, 0x00, "SummitHawk Memory"}, 
-	{HPHW_MEMORY, 0x084, 0x00009, 0x00, "Jade Upgrade Memory"}, 
-	{HPHW_MEMORY, 0x085, 0x00009, 0x00, "SPP2500 Memory"}, 
-	{HPHW_MEMORY, 0x086, 0x00009, 0x00, "AllegroHigh Memory"}, 
-	{HPHW_MEMORY, 0x087, 0x00009, 0x00, "AllegroLow Memory"}, 
-	{HPHW_MEMORY, 0x088, 0x00009, 0x00, "Forte 2w Memory"}, 
-	{HPHW_MEMORY, 0x089, 0x00009, 0x00, "Forte 4w Memory"}, 
-	{HPHW_MEMORY, 0x08A, 0x00009, 0x00, "Staccato L2 132 Memory"}, 
-	{HPHW_MEMORY, 0x08B, 0x00009, 0x00, "Staccato L2 180 Memory"}, 
-	{HPHW_MEMORY, 0x090, 0x00009, 0x00, "Prelude SMC Memory"}, 
-	{HPHW_MEMORY, 0x091, 0x00009, 0x00, "Lego 360 Memory"}, 
-	{HPHW_MEMORY, 0x7FF, 0x00009, 0x00, "NEC Aska memory"}, 
-	{HPHW_MEMORY, 0x800, 0x00009, 0x00, "Hitachi Tiny 64"}, 
-	{HPHW_MEMORY, 0x801, 0x00009, 0x00, "Hitachi Tiny 80"}, 
-	{HPHW_MEMORY, 0x8FF, 0x00009, 0x00, "Hitachi X memory"}, 
-	{HPHW_MEMORY, 0x091, 0x00009, 0x00, "M2250 Memory"}, 
-	{HPHW_MEMORY, 0x092, 0x00009, 0x00, "M2500 Memory"}, 
-	{HPHW_MEMORY, 0x093, 0x00009, 0x00, "Sonata 440 Memory"}, 
-	{HPHW_MEMORY, 0x094, 0x00009, 0x00, "Sonata 360 Memory"}, 
-	{HPHW_MEMORY, 0x095, 0x00009, 0x00, "Rhapsody 440 Memory"}, 
-	{HPHW_MEMORY, 0x096, 0x00009, 0x00, "Rhapsody 360 Memory"}, 
-	{HPHW_MEMORY, 0x097, 0x00009, 0x00, "Raven W 360 Memory"}, 
-	{HPHW_MEMORY, 0x098, 0x00009, 0x00, "Halfdome W 440 Memory"}, 
-	{HPHW_MEMORY, 0x099, 0x00009, 0x00, "Rhapsody DC- 440 Memory"}, 
-	{HPHW_MEMORY, 0x09A, 0x00009, 0x00, "Rhapsody DC- 360 Memory"}, 
-	{HPHW_MEMORY, 0x09B, 0x00009, 0x00, "Crescendo Memory"}, 
+	{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"},
 	{HPHW_OTHER, 0x004, 0x00030, 0x00, "Master"}, 
 	{HPHW_OTHER, 0x004, 0x00034, 0x00, "Slave"}, 
 	{HPHW_OTHER, 0x004, 0x00038, 0x00, "EDU"}, 
 	{HPHW_OTHER, 0x004, 0x00049, 0x00, "LGB Control"}, 
-        {0, }			/* leave the last entry empty ! */
+	{HPHW_FAULTY, 0, }  /* Special Marker for last entry */
 };
 
 
@@ -1318,7 +1195,7 @@
 	unsigned short model;
 	unsigned short mask;
 	enum cpu_type cpu;
-} hp_cpu_type_mask_list[] = {
+} hp_cpu_type_mask_list[] __initdata = {
 
 	{ 0x0000, 0x0ff0, pcx    },  /* 0x0000 - 0x000f */
 	{ 0x0048, 0x0ff0, pcxl   },  /* 0x0040 - 0x004f */
@@ -1350,8 +1227,10 @@
 	{ 0x0592, 0x0fff, pcxt_  },  /* 0x0592 - 0x0592 */
 	{ 0x0593, 0x0fff, pcxu   },  /* 0x0593 - 0x0593 */
 	{ 0x0594, 0x0ffc, pcxu   },  /* 0x0594 - 0x0597 */
-	{ 0x0598, 0x0ffc, pcxu   },  /* 0x0598 - 0x059b */
-	{ 0x059c, 0x0ffe, pcxu_  },  /* 0x059c - 0x059d */
+	{ 0x0598, 0x0ffe, pcxu_  },  /* 0x0598 - 0x0599 */
+	{ 0x059a, 0x0ffe, pcxu   },  /* 0x059a - 0x059b */
+	{ 0x059c, 0x0fff, pcxu   },  /* 0x059c - 0x059c */
+	{ 0x059d, 0x0fff, pcxu_  },  /* 0x059d - 0x059d */
 	{ 0x059e, 0x0fff, pcxt_  },  /* 0x059e - 0x059e */
 	{ 0x059f, 0x0fff, pcxu   },  /* 0x059f - 0x059f */
 	{ 0x05a0, 0x0ffe, pcxt_  },  /* 0x05a0 - 0x05a1 */
@@ -1370,7 +1249,27 @@
 	{ 0x05ba, 0x0fff, pcxu_  },  /* 0x05ba - 0x05ba */
 	{ 0x05bb, 0x0fff, pcxw   },  /* 0x05bb - 0x05bb */
 	{ 0x05bc, 0x0ffc, pcxw   },  /* 0x05bc - 0x05bf */
-	{ 0x05c0, 0x0fc0, pcxw   },  /* 0x05c0 - 0x05ff */
+	{ 0x05c0, 0x0ffc, pcxw 	 },  /* 0x05c0 - 0x05c3 */
+	{ 0x05c4, 0x0ffe, pcxw 	 },  /* 0x05c4 - 0x05c5 */
+	{ 0x05c6, 0x0fff, pcxw 	 },  /* 0x05c6 - 0x05c6 */
+	{ 0x05c7, 0x0fff, pcxw_  },  /* 0x05c7 - 0x05c7 */
+	{ 0x05c8, 0x0ffc, pcxw 	 },  /* 0x05c8 - 0x05cb */
+	{ 0x05cc, 0x0ffe, pcxw 	 },  /* 0x05cc - 0x05cd */
+	{ 0x05ce, 0x0ffe, pcxw_  },  /* 0x05ce - 0x05cf */
+	{ 0x05d0, 0x0ffc, pcxw_  },  /* 0x05d0 - 0x05d3 */
+	{ 0x05d4, 0x0ffe, pcxw_  },  /* 0x05d4 - 0x05d5 */
+	{ 0x05d6, 0x0fff, pcxw 	 },  /* 0x05d6 - 0x05d6 */
+	{ 0x05d7, 0x0fff, pcxw_  },  /* 0x05d7 - 0x05d7 */
+	{ 0x05d8, 0x0ffc, pcxw_  },  /* 0x05d8 - 0x05db */
+	{ 0x05dc, 0x0ffe, pcxw2  },  /* 0x05dc - 0x05dd */
+	{ 0x05de, 0x0fff, pcxw_  },  /* 0x05de - 0x05de */
+	{ 0x05df, 0x0fff, pcxw2  },  /* 0x05df - 0x05df */
+	{ 0x05e0, 0x0ffc, pcxw2  },  /* 0x05e0 - 0x05e3 */
+	{ 0x05e4, 0x0fff, pcxw2  },  /* 0x05e4 - 0x05e4 */
+	{ 0x05e5, 0x0fff, pcxw_  },  /* 0x05e5 - 0x05e5 */
+	{ 0x05e6, 0x0ffe, pcxw2  },  /* 0x05e6 - 0x05e7 */
+	{ 0x05e8, 0x0ff8, pcxw2  },  /* 0x05e8 - 0x05ef */
+	{ 0x05f0, 0x0ff0, pcxw2  },  /* 0x05f0 - 0x05ff */
 	{ 0x0600, 0x0ff0, pcxl   },  /* 0x0600 - 0x060f */
 	{ 0x0610, 0x0ff0, pcxl   },  /* 0x0610 - 0x061f */
 	{ 0x0000, 0x0000, pcx    }	/* terminate table */
@@ -1386,36 +1285,51 @@
 	[pcxu]	{ "PA8000 (PCX-U)",	"2.0" },
 	[pcxu_]	{ "PA8200 (PCX-U+)",	"2.0" },
 	[pcxw]	{ "PA8500 (PCX-W)",	"2.0" },
-	[pcxw_]	{ "PA8600 (PCX-W+)",	"2.0" }
+	[pcxw_]	{ "PA8600 (PCX-W+)",	"2.0" },
+	[pcxw2]	{ "PA8700 (PCX-W2)",	"2.0" }
 };
 
-char *parisc_getHWtype(unsigned short hw_type)
-{
-	if (hw_type <= HPHW_CIO) {
-		return hw_type_name[hw_type];
-	} else {
-		return "Unknown Type";
-	}
-}
-
-char *parisc_getHWdescription(unsigned short hw_type, unsigned long hversion,
-		unsigned long sversion)
+const char * __init
+parisc_hardware_description(struct parisc_device_id *id)
 {
 	struct hp_hardware *listptr;
 	
-	for (listptr = hp_hardware_list; listptr->name; listptr++) {
-		if ((listptr->hw_type==hw_type) &&
-				(listptr->hversion==hversion) &&
-				(listptr->sversion==sversion)){
+	for (listptr = hp_hardware_list; listptr->hw_type != HPHW_FAULTY; listptr++) {
+		if ((listptr->hw_type == id->hw_type) &&
+				(listptr->hversion == id->hversion) &&
+				(listptr->sversion == id->sversion)){
 			return listptr->name;
 		}
 	}
+
+	/*
+	 * ok, the above hardware table isn't complete, and we haven't found
+	 * our device in this table. So let's now try to find a generic name
+	 * to describe the given hardware...
+	 */
+	switch (id->hw_type) {
+		case HPHW_NPROC:
+			return "Unknown machine";
+
+		case HPHW_A_DIRECT:
+			switch (id->sversion) {
+				case 0x0D: return "MUX port";
+				case 0x0E: return "RS-232 port";
+			}
+			break;
+			
+		case HPHW_MEMORY:
+			return "Memory";
+			
+	}
+	
 	return "unknown device";
 }
 
 
 /* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */
-enum cpu_type parisc_get_cpu_type(unsigned long hversion)
+enum cpu_type __init
+parisc_get_cpu_type(unsigned long hversion)
 {
 	struct hp_cpu_type_mask *ptr;
 	unsigned short model = ((unsigned short) (hversion)) >> 4;
@@ -1424,23 +1338,8 @@
 		if (ptr->model == (model & ptr->mask))
 			return ptr->cpu;
 	}
-	panic("parisc_get_cpu_type() could not identify CPU type\n");
+	panic("could not identify CPU type\n");
 
 	return pcx;	/* not reached: */
 }
 
-
-struct hp_hardware *parisc_get_reference(unsigned short hw_type,
-		unsigned long hversion, unsigned long sversion)
-{
-	struct hp_hardware *listptr = hp_hardware_list;
-
-	for (listptr = hp_hardware_list; listptr->name; listptr++) {
-		if ((listptr->hw_type == hw_type) &&
-				(listptr->hversion == hversion) &&
-				(listptr->sversion == sversion)) {
-			return listptr;
-		}
-	}
-	return NULL;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/head.S linux-2.4.20/arch/parisc/kernel/head.S
--- linux-2.4.19/arch/parisc/kernel/head.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/head.S	2002-10-04 00:41:29.000000000 +0000
@@ -8,17 +8,14 @@
  * Copyright 1999 SuSE GmbH (Philipp Rumpf)
  * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  *
- * Initial Version 04-23-1999 by Helge Deller (helge.deller@ruhr-uni-bochum.de)
+ * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
  */
 
+#include <linux/autoconf.h>	/* for CONFIG_SMP */
 
 #include <asm/offset.h>
 #include <asm/psw.h>
 
-#define __ASSEMBLY__
-/*********
-#include <asm/pdc.h>
-*********/
 #include <asm/assembly.h>
 #include <asm/pgtable.h>
 
@@ -36,6 +33,15 @@
 	.export __setup_end
 __setup_end:
 
+	.data
+
+	.export boot_args
+boot_args:
+	.word 0 /* arg0 */
+	.word 0 /* arg1 */
+	.word 0 /* arg2 */
+	.word 0 /* arg3 */
+
 	.text
 	.align	4	
 	.import init_task_union,data
@@ -52,43 +58,129 @@
 	.callinfo
 
 	/* Make sure sr4-sr7 are set to zero for the kernel address space */
-
-	mtsp		%r0,%sr4
-	mtsp		%r0,%sr5
-	mtsp		%r0,%sr6
-	mtsp		%r0,%sr7
+	mtsp	%r0,%sr4
+	mtsp	%r0,%sr5
+	mtsp	%r0,%sr6
+	mtsp	%r0,%sr7
+
+	/* Clear BSS (shouldn't the boot loader do this?) */
+
+	.import _edata,data
+	.import _end,data
+
+	ldil            L%PA(_edata),%r3
+	ldo             R%PA(_edata)(%r3),%r3
+	ldil            L%PA(_end),%r4
+	ldo             R%PA(_end)(%r4),%r4
+$bss_loop:
+	cmpb,<<,n       %r3,%r4,$bss_loop
+	stb,ma          %r0,1(%r3)
+
+	/* Save away the arguments the boot loader passed in (32 bit args) */
+
+	ldil            L%PA(boot_args),%r1
+	ldo             R%PA(boot_args)(%r1),%r1
+	stw,ma          %arg0,4(%r1)
+	stw,ma          %arg1,4(%r1)
+	stw,ma          %arg2,4(%r1)
+	stw,ma          %arg3,4(%r1)
 
 	/* Initialize startup VM. Just map first 8 MB of memory */
-
 	ldil		L%PA(pg0),%r1
 	ldo		R%PA(pg0)(%r1),%r1
 	ldo		_PAGE_TABLE(%r1),%r3
+
 	ldil		L%PA(swapper_pg_dir),%r4
 	ldo		R%PA(swapper_pg_dir)(%r4),%r4
 	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
 	mtctl		%r4,%cr25	/* Initialize user root pointer */
-	stw		%r3,0xc00(%r4)	/* Hardwired 0xc0000000 kernel vaddr start */
+
+#if (__PAGE_OFFSET != 0x10000000UL)
+Error! Code below (the next two stw's) needs to be changed
+#endif
+
+	stw             %r3,0x100(%r4)  /* Hardwired 0x1... kernel Vaddr start*/
 	ldo		0x1000(%r3),%r3
-	stw		%r3,0xc04(%r4)
-	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0x0 phys addr start */
+	stw             %r3,0x104(%r4)
+	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
 $pgt_fill_loop:
 	stwm		%r3,4(%r1)
 	ldo		0x1000(%r3),%r3
 	bb,>=		%r3,8,$pgt_fill_loop
 	nop
 
+
+	/* Load the return address...er...crash 'n burn */
+	copy		%r0,%r2
+
+	/* And the RFI Target address too */
+	ldil            L%start_kernel,%r11
+	ldo             R%start_kernel(%r11),%r11
+
+	/* And the initial task pointer */
+
+	ldil            L%init_task_union,%r6
+	ldo             R%init_task_union(%r6),%r6
+	mtctl           %r6,%cr30
+
+	/* And the stack pointer too */
+
+	ldo             TASK_SZ_ALGN(%r6),%sp
+
+	/* And the interrupt stack */
+
+	ldil            L%interrupt_stack,%r6
+	ldo             R%interrupt_stack(%r6),%r6
+	mtctl           %r6,%cr31
+
+#ifdef CONFIG_SMP
+	/* Set the smp rendevous address into page zero.
+	** It would be safer to do this in init_smp_config() but
+	** it's just way easier to deal with here because
+	** of 64-bit function ptrs and the address is local to this file.
+	*/
+	ldil		L%PA(smp_slave_stext),%r10
+	ldo		R%PA(smp_slave_stext)(%r10),%r10
+	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
+
+	/* FALLTHROUGH */
+	.procend
+
+	/*
+	** Code Common to both Monarch and Slave processors.
+	** Entry:
+	**    %r11 must contain RFI target address.
+	**    %r25/%r26 args to pass to target function
+	**    %r2  in case rfi target decides it didn't like something
+	**
+	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
+	*/
+common_stext:
+	.proc
+	.callinfo
+#else
+	/* Clear PDC entry point - we won't use it */
+	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+#endif
+
+	/* PARANOID: clear user scratch/user space SR's */
+	mtsp	%r0,%sr0
+	mtsp	%r0,%sr1
+	mtsp	%r0,%sr2
+	mtsp	%r0,%sr3
+
+	/* Initialize Protection Registers */
+	mtctl	%r0,%cr8
+	mtctl	%r0,%cr9
+	mtctl	%r0,%cr12
+	mtctl	%r0,%cr13
+
 	/* Initialize the global data pointer */
 	ldil		L%$global$,%dp
 	ldo		R%$global$(%dp),%dp
-	
-	/* And the stack pointer, physical too */
-	ldil		L%init_task_union+TASK_SZ_ALGN,%sp
-	ldo		R%init_task_union+TASK_SZ_ALGN(%sp),%sp
-
-	/* we need this to take interruptions directly after the rfi below */
-	/* (which we need for PA2.0 boxes) */
-	mtctl		%r0, %cr30
-	
+
 	/*
 	 * Set up our interrupt table.  HPMCs might not work after this! 
 	 *
@@ -96,7 +188,6 @@
 	 * following short sequence of instructions can determine this
 	 * (without being illegal on a PA1.1 machine).
 	 */
-	
 	ldi		32,%r10
 	mtctl		%r10,%cr11
 	.level 2.0
@@ -114,30 +205,30 @@
 $install_iva:
 	mtctl		%r10,%cr14
 
-	/* Disable (most) interruptions */
-	mtsm		%r0			
-	
+	/* Disable Q bit so we can load the iia queue */
+	rsm            PSW_SM_Q,%r0
+
 	/* kernel PSW:
-	 *  - no interruptions except for HPMC and TOC (which are handled by PDC)
+	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
 	 *  - Q bit set (IODC / PDC interruptions)
 	 *  - big-endian
 	 *  - virtually mapped
 	 */
-
 	ldil		L%KERNEL_PSW,%r10
 	ldo		R%KERNEL_PSW(%r10),%r10
 	mtctl		%r10,%ipsw
-	
-	/* Set the space pointers for the post-RFI world */
-	mtctl		%r0,%cr17		/* Clear two-level IIA Space Queue */
-	mtctl		%r0,%cr17		/*    effectively setting kernel space. */
-
-	/* And the return address(es) too */
-	ldil		L%start_parisc,%r10
-	ldo		R%start_parisc(%r10),%r10
-	mtctl		%r10,%cr18
-	ldo		4(%r10),%r10
-	mtctl		%r10,%cr18
+
+	/* Set the space pointers for the post-RFI world
+	** Clear the two-level IIA Space Queue, effectively setting
+	** Kernel space.
+	*/
+	mtctl		%r0,%cr17
+	mtctl		%r0,%cr17
+
+	/* Load RFI target into PC queue */
+	mtctl		%r11,%cr18
+	ldo		4(%r11),%r11
+	mtctl		%r11,%cr18
 
 	/* Jump to hyperspace */
 	rfi
@@ -145,6 +236,71 @@
 
 	.procend
 
+#ifdef CONFIG_SMP
+
+	.import smp_init_current_idle_task,data
+	.import	smp_callin,code
+
+smp_callin_rtn:
+        .proc
+	.callinfo
+	break	1,1		/*  Break if returned from start_secondary */
+	nop
+	nop
+        .procend
+
+/***************************************************************************
+*
+* smp_slave_stext is executed by all non-monarch Processors when the Monarch
+* pokes the slave CPUs in smp.c:smp_boot_cpus().
+*
+* Once here, registers values are initialized in order to branch to virtual
+* mode. Once all available/eligible CPUs are in virtual mode, all are
+* released and start out by executing their own idle task.
+*****************************************************************************/
+
+
+smp_slave_stext:
+        .proc
+	.callinfo
+
+	/*
+	** Initialize Space registers
+	*/
+	mtsp	   %r0,%sr4
+	mtsp	   %r0,%sr5
+	mtsp	   %r0,%sr6
+	mtsp	   %r0,%sr7
+
+	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
+	ldil		L%PA(smp_init_current_idle_task),%sp
+	ldo		R%PA(smp_init_current_idle_task)(%sp),%sp
+	ldw		0(%sp),%sp	/* load task address */
+	mtctl           %sp,%cr30       /* store in cr30 */
+	addil		L%TASK_SZ_ALGN,%sp	/* stack is above task */
+	ldo		R%TASK_SZ_ALGN(%r1),%sp
+
+	/* point CPU to kernel page tables */
+	ldil		L%PA(swapper_pg_dir),%r4
+	ldo		R%PA(swapper_pg_dir)(%r4),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+	/* Load RFI *return* address in case smp_callin bails */
+	ldil		L%smp_callin_rtn,%r2
+	ldo		R%smp_callin_rtn(%r2),%r2
+
+	/* Load RFI target address.  */
+	ldil		L%smp_callin,%r11
+	ldo		R%smp_callin(%r11),%r11
+	
+	/* ok...common code can handle the rest */
+	b		common_stext
+	nop
+
+	.procend
+#endif /* CONFIG_SMP */
+
 	.data
 
 	.align	4
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/head64.S linux-2.4.20/arch/parisc/kernel/head64.S
--- linux-2.4.19/arch/parisc/kernel/head64.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/head64.S	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,333 @@
+/*
+ *
+ * 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) 1999 by Helge Deller
+ * Copyright 1999 SuSE GmbH (Philipp Rumpf)
+ * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
+ * Copyright 2000 Hewlett Packard (Paul Bame, bame@puffin.external.hp.com)
+ * Copyright (C) 2001 Grant Grundler (Hewlett Packard)
+ *
+ * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
+ */
+
+
+#include <linux/autoconf.h>	/* for CONFIG_SMP */
+
+#include <asm/offset.h>
+#include <asm/psw.h>
+
+#include <asm/assembly.h>
+#include <asm/pgtable.h>
+#include <asm/pdc.h>		/* for PDC_PSW defines */
+
+
+	.level 2.0
+
+	.section	.initcall.init
+	.align		4
+	.export __initcall_start
+__initcall_start:
+	.export __initcall_end
+__initcall_end:
+	.export __setup_start
+__setup_start:
+	.export __setup_end
+__setup_end:
+
+	.data
+
+	.export boot_args
+boot_args:
+	.word 0 /* arg0 */
+	.word 0 /* arg1 */
+	.word 0 /* arg2 */
+	.word 0 /* arg3 */
+
+	.text
+	.align	4	
+
+	.export stext
+	.export _stext,data		/* Kernel want it this way! */
+_stext:
+stext:
+	.proc
+	.callinfo
+
+	/* Make sure sr4-sr7 are set to zero for the kernel address space */
+	mtsp	%r0,%sr4
+	mtsp	%r0,%sr5
+	mtsp	%r0,%sr6
+	mtsp	%r0,%sr7
+
+	/* Clear BSS (shouldn't the boot loader do this?) */
+
+	.import _edata,data
+	.import _end,data
+
+	ldil            L%PA(_edata),%r3
+	ldo             R%PA(_edata)(%r3),%r3
+	ldil            L%PA(_end),%r4
+	ldo             R%PA(_end)(%r4),%r4
+$bss_loop:
+	cmpb,<<,n       %r3,%r4,$bss_loop
+	stb,ma          %r0,1(%r3)
+
+	/* Save away the arguments the boot loader passed in (32 bit args) */
+
+	ldil            L%PA(boot_args),%r1
+	ldo             R%PA(boot_args)(%r1),%r1
+	stw,ma          %arg0,4(%r1)
+	stw,ma          %arg1,4(%r1)
+	stw,ma          %arg2,4(%r1)
+	stw,ma          %arg3,4(%r1)
+
+	/* Initialize startup VM. Just map first 8 MB of memory */
+
+	ldil		L%PA(pg0),%r1
+	ldo		R%PA(pg0)(%r1),%r1
+
+	ldil		L%PA(pmd0),%r5
+	ldo		R%PA(pmd0)(%r5),%r5
+	ldo		_PAGE_TABLE(%r5),%r3
+
+	ldil		L%PA(swapper_pg_dir),%r4
+	ldo		R%PA(swapper_pg_dir)(%r4),%r4
+
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+#if (__PAGE_OFFSET != 0x10000000UL)
+Error! Code below (the next five std's) needs to be changed
+#endif
+
+	std             %r3,0x00(%r4)   /* Hardwired 0x1... kernel Vaddr start*/
+
+	ldo		_PAGE_TABLE(%r1),%r3
+	std             %r3,0x400(%r5)  /* Hardwired 0x1... kernel Vaddr start*/
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x408(%r5)
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x410(%r5)
+	ldo		0x1000(%r3),%r3
+	std             %r3,0x418(%r5)
+
+	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
+$pgt_fill_loop:
+	std,ma		%r3,8(%r1)
+	ldo		0x1000(%r3),%r3
+	bb,>=		%r3,8,$pgt_fill_loop
+	nop
+
+	/* And the RFI Target address too */
+	load32          start_kernel, %r11
+
+	/* And the stack pointer too */
+	load32		PA(init_task_union+TASK_SZ_ALGN),%sp
+
+	/* And the initial task pointer */
+
+	load32          init_task_union,%r6
+	mtctl           %r6,%cr30
+
+	/* And the interrupt stack */
+
+	load32          interrupt_stack,%r6
+	mtctl           %r6,%cr31
+
+	/* Act like PDC just called us - that's how slave CPUs enter */
+#define MEM_PDC_LO 0x388
+#define MEM_PDC_HI 0x35C
+	ldw		MEM_PDC_LO(%r0),%r3
+	ldw		MEM_PDC_HI(%r0),%r6
+	depd		%r6, 31, 32, %r3	/* move to upper word */
+
+#ifdef CONFIG_SMP
+	/* Set the smp rendevous address into page zero.
+	** It would be safer to do this in init_smp_config() but
+	** it's just way easier to deal with here because
+	** of 64-bit function ptrs and the address is local to this file.
+	*/
+	ldil		L%PA(smp_slave_stext),%r10
+	ldo		R%PA(smp_slave_stext)(%r10),%r10
+	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
+
+	/* FALLTHROUGH */
+	.procend
+
+	/*
+	** Code Common to both Monarch and Slave processors.
+	** Entry:
+	**    %r3	PDCE_PROC address
+	**    %r11	RFI target address.
+	**
+	** Caller must init: SR4-7, %sp, %r10, %cr24/25, 
+	*/
+common_stext:
+	.proc
+	.callinfo
+#else /* CONFIG_SMP */
+	/* Clear PDC's CPU handoff address - we won't use it */
+	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
+	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
+#endif /* CONFIG_SMP */
+
+	/* Save the rfi target address */
+	std		%r11,  TASK_PT_GR11-TASK_SZ_ALGN(%sp)
+
+#ifndef CONFIG_PDC_NARROW
+	/* Switch to wide mode; Superdome doesn't support narrow PDC
+	** calls.
+	*/
+1:	mfia		%rp		/* clear upper part of pcoq */
+	ldo		2f-1b(%rp),%rp
+	depdi		0,31,32,%rp
+	bv		(%rp)
+	ssm		PSW_SM_W,%r0
+2:
+#endif /* CONFIG_PDC_NARROW */
+
+	/* Set Wide mode as the "Default" (eg for traps)
+	** First trap occurs *right* after (or part of) rfi for slave CPUs.
+	** Someday, palo might not do this for the Monarch either.
+	*/
+
+	ldo		PDC_PSW(%r0),%arg0		/* 21 */
+	ldo		PDC_PSW_SET_DEFAULTS(%r0),%arg1	/* 2 */
+	ldo		PDC_PSW_WIDE_BIT(%r0),%arg2	/* 2 */
+
+	load32		PA(stext_pdc_ret), %rp
+
+	bv		(%r3)
+	copy		%r0,%arg3
+
+stext_pdc_ret:
+	/* restore rfi target address*/
+	ldd		TASK_PT_GR11-TASK_SZ_ALGN(%sp), %r11
+
+	/* PARANOID: clear user scratch/user space SR's */
+	mtsp	%r0,%sr0
+	mtsp	%r0,%sr1
+	mtsp	%r0,%sr2
+	mtsp	%r0,%sr3
+
+	/* Initialize Protection Registers */
+	mtctl	%r0,%cr8
+	mtctl	%r0,%cr9
+	mtctl	%r0,%cr12
+	mtctl	%r0,%cr13
+
+	/* Prepare to RFI! Man all the cannons! */
+	tovirt_r1       %sp
+
+	/* Initialize the global data pointer */
+	load32		__gp,%dp
+
+	/* Set up our interrupt table.  HPMCs might not work after this! */
+	ldil		L%PA(fault_vector_20),%r10
+	ldo		R%PA(fault_vector_20)(%r10),%r10
+	mtctl		%r10,%cr14
+
+	b		aligned_rfi
+	nop
+
+	/* the magic spell */
+	.align          256
+aligned_rfi:
+	ssm		0,0
+	nop		/* 1 */
+	nop		/* 2 */
+	nop		/* 3 */
+	nop		/* 4 */
+	nop		/* 5 */
+	nop		/* 6 */
+	nop		/* 7 */
+	nop		/* 8 */
+
+	/* turn off troublesome PSW bits */
+	rsm		PSW_Q+PSW_I+PSW_D+PSW_P+PSW_R, %r0
+
+	/* kernel PSW:
+	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
+	 *  - Q bit set (IODC / PDC interruptions)
+	 *  - big-endian
+	 *  - virtually mapped
+	 */
+	load32		KERNEL_PSW,%r10
+	mtctl		%r10,%ipsw
+
+	/* Set the space pointers for the post-RFI world
+	** Clear the two-level IIA Space Queue, effectively setting
+	** Kernel space.
+	*/
+	mtctl		%r0,%cr17
+	mtctl		%r0,%cr17
+
+	/* Load RFI target into PC queue */
+	mtctl		%r11,%cr18
+	ldo		4(%r11),%r11
+	mtctl		%r11,%cr18
+
+	/* Jump to hyperspace */
+	rfi
+	nop
+
+	.procend
+
+
+#ifdef CONFIG_SMP
+
+	.import smp_init_current_idle_task,data
+	.import	smp_callin,code
+
+/***************************************************************************
+*
+* smp_slave_stext is executed by all non-monarch Processors when the Monarch
+* pokes the slave CPUs in smp.c:smp_boot_cpus().
+*
+* Once here, registers values are initialized in order to branch to virtual
+* mode. Once all available/eligible CPUs are in virtual mode, all are
+* released and start out by executing their own idle task.
+*****************************************************************************/
+
+
+smp_slave_stext:
+        .proc
+	.callinfo
+
+	/*
+	** Initialize Space registers
+	*/
+	mtsp	   %r0,%sr4
+	mtsp	   %r0,%sr5
+	mtsp	   %r0,%sr6
+	mtsp	   %r0,%sr7
+
+	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
+	load32		PA(smp_init_current_idle_task),%sp
+	ldd		0(%sp),%sp	/* load task address */
+	mtctl           %sp,%cr30       /* store in cr30 */
+	ldo             TASK_SZ_ALGN(%sp),%sp
+	tophys_r1       %sp
+
+	/* point CPU to kernel page tables */
+	load32		PA(swapper_pg_dir),%r4
+	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
+	mtctl		%r4,%cr25	/* Initialize user root pointer */
+
+	/* Setup PDCE_PROC entry */
+	copy		%arg0,%r3
+
+	/* Load RFI target address.  */
+	load32		smp_callin, %r11
+	
+	/* ok...common code can handle the rest */
+	b		common_stext
+	nop
+
+	.procend
+#endif /* CONFIG_SMP */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/hpmc.S linux-2.4.20/arch/parisc/kernel/hpmc.S
--- linux-2.4.19/arch/parisc/kernel/hpmc.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/hpmc.S	2002-10-04 00:41:15.000000000 +0000
@@ -43,7 +43,6 @@
 	.level		1.1
 	.data
 
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/pdc.h>
 
@@ -262,12 +261,10 @@
 	mtsp	%r0, %sr6
 	mtsp	%r0, %sr7
 
-	tovirt  %r30        /* make sp virtual */
+	tovirt_r1 %r30      /* make sp virtual */
 
 	rsm 8,%r0           /* Clear Q bit */
-	ldi     1,%r1
-	mtctl   %r1,%cr29   /* Set trap code to "1" for HPMC */
-	mtctl   %r0,%cr30   /* Force interruptions to use hpmc stack */
+	ldi     1,%r8       /* Set trap code to "1" for HPMC */
 	ldil    L%PA(intr_save), %r1
 	ldo     R%PA(intr_save)(%r1), %r1
 	be      0(%sr7,%r1)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/init_task.c linux-2.4.20/arch/parisc/kernel/init_task.c
--- linux-2.4.19/arch/parisc/kernel/init_task.c	2001-09-17 22:29:09.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/init_task.c	2002-10-04 00:41:09.000000000 +0000
@@ -18,10 +18,11 @@
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
+unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
 union task_union init_task_union 
 	__attribute__((section("init_task"), aligned(4096))) = { INIT_TASK(init_task_union.task) };
 
-unsigned long swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(4096))) = { 0, };
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(4096))) = { {0}, };
 #ifdef __LP64__
 unsigned long pmd0[PTRS_PER_PMD] __attribute__ ((aligned(4096))) = { 0, };
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/inventory.c linux-2.4.20/arch/parisc/kernel/inventory.c
--- linux-2.4.19/arch/parisc/kernel/inventory.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/inventory.c	2002-10-04 00:41:11.000000000 +0000
@@ -1,40 +1,157 @@
-
-/* Copyright (c) 1999 The Puffin Group */
-/* Written by David Kennedy and Alex deVries */
+/*
+ * inventory.c
+ *
+ * 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.
+ *
+ * Copyright (c) 1999 The Puffin Group (David Kennedy and Alex deVries)
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett-Packard
+ *
+ * These are the routines to discover what hardware exists in this box.
+ * This task is complicated by there being 3 different ways of
+ * performing an inventory, depending largely on the age of the box.
+ * The recommended way to do this is to check to see whether the machine
+ * is a `Snake' first, then try System Map, then try PAT.  We try System
+ * Map before checking for a Snake -- this probably doesn't cause any
+ * problems, but...
+ */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/processor.h>
+#include <asm/page.h>
 
 /*
 ** Debug options
-**    DEBUG_PAT	Dump details which PDC PAT provides about ranges/devices.
+** DEBUG_PAT Dump details which PDC PAT provides about ranges/devices.
 */
 #undef DEBUG_PAT
 
-extern char *parisc_getHWtype(unsigned short hw_type);
+int pdc_type = PDC_TYPE_ILLEGAL;
+
+void __init setup_pdc(void)
+{
+	long status;
+	unsigned int bus_id;
+	struct pdc_system_map_mod_info module_result;
+	struct pdc_module_path module_path;
+	struct pdc_model model;
+#ifdef __LP64__
+	struct pdc_pat_cell_num cell_info;
+#endif
 
-extern struct hp_device * register_module(void *hpa);
-extern void print_devices(char * buf);
+	/* Determine the pdc "type" used on this machine */
 
+	printk(KERN_INFO "Determining PDC firmware type: ");
 
-int pdc_hpa_processor(void *address);
+	status = pdc_system_map_find_mods(&module_result, &module_path, 0);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_SYSTEM_MAP;
+		printk("System Map.\n");
+		return;
+	}
 
-#ifndef __LP64__ 
-static	u8 iodc_data[32] __attribute__ ((aligned (64)));
-static	struct pdc_model model __attribute__ ((aligned (8)));
+	/*
+	 * If the machine doesn't support PDC_SYSTEM_MAP then either it
+	 * is a pdc pat box, or it is an older box. All 64 bit capable
+	 * machines are either pdc pat boxes or they support PDC_SYSTEM_MAP.
+	 */
+
+	/*
+	 * TODO: We should test for 64 bit capability and give a
+	 * clearer message.
+	 */
+
+#ifdef __LP64__
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status == PDC_OK) {
+		pdc_type = PDC_TYPE_PAT;
+		printk("64 bit PAT.\n");
+		return;
+	}
 #endif
-static	unsigned long pdc_result[32] __attribute__ ((aligned (8))) = {0,0,0,0};
-static	struct pdc_hpa processor_hpa __attribute__ ((aligned (8)));
-static	struct pdc_system_map module_result __attribute__ ((aligned (8)));
-static	struct pdc_module_path module_path __attribute__ ((aligned (8)));
+
+	/* Check the CPU's bus ID.  There's probably a better test.  */
+
+	status = pdc_model_info(&model);
+
+	bus_id = (model.hversion >> (4 + 7)) & 0x1f;
+
+	switch (bus_id) {
+	case 0x4:		/* 720, 730, 750, 735, 755 */
+	case 0x6:		/* 705, 710 */
+	case 0x7:		/* 715, 725 */
+	case 0x8:		/* 745, 747, 742 */
+	case 0xA:		/* 712 and similiar */
+	case 0xC:		/* 715/64, at least */
+
+		pdc_type = PDC_TYPE_SNAKE;
+		printk("Snake.\n");
+		return;
+
+	default:		/* Everything else */
+
+		printk("Unsupported.\n");
+		panic("If this is a 64-bit machine, please try a 64-bit kernel.\n");
+	}
+}
+
+#define PDC_PAGE_ADJ_SHIFT (PAGE_SHIFT - 12) /* pdc pages are always 4k */
+
+static void __init
+set_pmem_entry(physmem_range_t *pmem_ptr, unsigned long start,
+	       unsigned long pages4k)
+{
+	/* Rather than aligning and potentially throwing away
+	 * memory, we'll assume that any ranges are already
+	 * nicely aligned with any reasonable page size, and
+	 * panic if they are not (it's more likely that the
+	 * pdc info is bad in this case).
+	 */
+
+	if (   ((start & (PAGE_SIZE - 1)) != 0)
+	    || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) ) {
+
+		panic("Memory range doesn't align with page size!\n");
+	}
+
+	pmem_ptr->start_pfn = (start >> PAGE_SHIFT);
+	pmem_ptr->pages = (pages4k >> PDC_PAGE_ADJ_SHIFT);
+}
+
+static void __init pagezero_memconfig(void)
+{
+	unsigned long npages;
+
+	/* Use the 32 bit information from page zero to create a single
+	 * entry in the pmem_ranges[] table.
+	 *
+	 * We currently don't support machines with contiguous memory
+	 * >= 4 Gb, who report that memory using 64 bit only fields
+	 * on page zero. It's not worth doing until it can be tested,
+	 * and it is not clear we can support those machines for other
+	 * reasons.
+	 *
+	 * If that support is done in the future, this is where it
+	 * should be done.
+	 */
+
+	npages = (PAGE_ALIGN(PAGE0->imm_max_mem) >> PAGE_SHIFT);
+	set_pmem_entry(pmem_ranges,0UL,npages);
+	npmem_ranges = 1;
+}
 
 #ifdef __LP64__
-#include <asm/pdcpat.h>
 
-int pdc_pat = 0;
+/* All of the PDC PAT specific code is 64-bit only */
 
 /*
 **  The module object is filled via PDC_PAT_CELL[Return Cell Module].
@@ -47,30 +164,37 @@
 **
 */
 
-static int
-pat_query_module( ulong pcell_loc, ulong mod_index)
+static int __init 
+pat_query_module(ulong pcell_loc, ulong mod_index)
 {
-	extern int num_devices;
-	extern struct hp_device devices[];
-
 	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
-        struct hp_device * dev = &devices[num_devices];
-	uint64_t temp;             /* 64-bit scratch value */
-	long status;               /* PDC return value status */
+	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;
+	unsigned long bytecnt;
+	unsigned long temp;	/* 64-bit scratch value */
+	long status;		/* PDC return value status */
+	struct parisc_device *dev;
 
 	/* return cell module (PA or Processor view) */
-	status = pdc_pat_cell_module(& pdc_result, pcell_loc, mod_index,
-		PA_VIEW, & pa_pdc_cell);
+	status = pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				     PA_VIEW, &pa_pdc_cell);
 
-	if (status != PDC_RET_OK) {
+	if (status != PDC_OK) {
 		/* no more cell modules or error */
 		return status;
 	}
 
+	temp = pa_pdc_cell.cba;
+	dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
+	if (!dev) {
+		return PDC_NE_MOD;
+	}
+
+	/* alloc_pa_dev sets dev->hpa */
+
 	/*
-	** save parameters in the hp_device
+	** save parameters in the parisc_device
 	** (The idea being the device driver will call pdc_pat_cell_module()
-	** and store the results in it's own data structure.)
+	** and store the results in its own data structure.)
 	*/
 	dev->pcell_loc = pcell_loc;
 	dev->mod_index = mod_index;
@@ -79,319 +203,410 @@
 	/* REVISIT: who is the consumer of this? not sure yet... */
 	dev->mod_info = pa_pdc_cell.mod_info;	/* pass to PAT_GET_ENTITY() */
 	dev->pmod_loc = pa_pdc_cell.mod_location;
-	dev->mod_path = pa_pdc_cell.mod_path;
 
-	temp = pa_pdc_cell.cba;
-	register_module((void *) PAT_GET_CBA(temp));	/* fills in dev->hpa */
+	register_parisc_device(dev);	/* advertise device */
 
 #ifdef DEBUG_PAT
 	/* dump what we see so far... */
 	switch (PAT_GET_ENTITY(dev->mod_info)) {
-		ulong i;
+		unsigned long i;
 
 	case PAT_ENTITY_PROC:
-		printk ("PAT_ENTITY_PROC: id_eid 0x%lx\n", pa_pdc_cell.mod[0]);
+		printk(KERN_DEBUG "PAT_ENTITY_PROC: id_eid 0x%lx\n",
+			pa_pdc_cell.mod[0]);
 		break;
 
 	case PAT_ENTITY_MEM:
-		printk ("PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
-			pa_pdc_cell.mod[0],
-			pa_pdc_cell.mod[1],
+		printk(KERN_DEBUG 
+			"PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n",
+			pa_pdc_cell.mod[0], pa_pdc_cell.mod[1], 
 			pa_pdc_cell.mod[2]);
 		break;
 	case PAT_ENTITY_CA:
-		printk ("PAT_ENTITY_CA: %ld\n",pcell_loc);
+		printk(KERN_DEBUG "PAT_ENTITY_CA: %ld\n", pcell_loc);
 		break;
 
 	case PAT_ENTITY_PBC:
-		printk ("PAT_ENTITY_PBC: ");
+		printk(KERN_DEBUG "PAT_ENTITY_PBC: ");
 		goto print_ranges;
 
 	case PAT_ENTITY_SBA:
-		printk ("PAT_ENTITY_SBA: ");
+		printk(KERN_DEBUG "PAT_ENTITY_SBA: ");
 		goto print_ranges;
 
 	case PAT_ENTITY_LBA:
-		printk ("PAT_ENTITY_LBA: ");
+		printk(KERN_DEBUG "PAT_ENTITY_LBA: ");
 
-print_ranges:
-		printk ("ranges %ld\n", pa_pdc_cell.mod[1]);
+ print_ranges:
+		pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index,
+				    IO_VIEW, &io_pdc_cell);
+		printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell.mod[1]);
 		for (i = 0; i < pa_pdc_cell.mod[1]; i++) {
-			printk ("	%ld: 0x%016lx 0x%016lx 0x%016lx\n", i,
-				pa_pdc_cell.mod[2+i*3],	/* type */
-				pa_pdc_cell.mod[3+i*3],	/* start */
-				pa_pdc_cell.mod[4+i*3]);	/* finish (ie end) */
+			printk(KERN_DEBUG 
+				"  PA_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, pa_pdc_cell.mod[2 + i * 3],	/* type */
+				pa_pdc_cell.mod[3 + i * 3],	/* start */
+				pa_pdc_cell.mod[4 + i * 3]);	/* finish (ie end) */
+			printk(KERN_DEBUG 
+				"  IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", 
+				i, io_pdc_cell.mod[2 + i * 3],	/* type */
+				io_pdc_cell.mod[3 + i * 3],	/* start */
+				io_pdc_cell.mod[4 + i * 3]);	/* finish (ie end) */
 		}
-		printk("\n");
+		printk(KERN_DEBUG "\n");
 		break;
 	}
 #endif /* DEBUG_PAT */
-	return PDC_RET_OK;
+	return PDC_OK;
 }
 
 
-static int do_pat_inventory(void)
-{
-	ulong mod_index=0;
-	int status;
-	ulong cell_num;
-	ulong pcell_loc;
+/* pat pdc can return information about a variety of different
+ * types of memory (e.g. firmware,i/o, etc) but we only care about
+ * the usable physical ram right now. Since the firmware specific
+ * information is allocated on the stack, we'll be generous, in
+ * case there is a lot of other information we don't care about.
+ */
 
-	pdc_pat = (pdc_pat_cell_get_number(&pdc_result) == PDC_OK);
-	if (!pdc_pat)
-	{
-		return 0;
-	}
-
-	cell_num = pdc_result[0];	/* Cell number call was made */
-
-	/* As of PDC PAT ARS 2.5, ret[1] is NOT architected! */
-	pcell_loc = pdc_result[1];	/* Physical location of the cell */
-
-#ifdef DEBUG_PAT
-	printk("CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_num, pcell_loc);
-#endif
-
-        status = pdc_pat_cell_num_to_loc(&pdc_result, cell_num);
-        if (status == PDC_BAD_OPTION)
-	{
-		/* Prelude (and it's successors: Lclass, A400/500) only
-		** implement PDC_PAT_CELL sub-options 0 and 2.
-		** "Home cook'n is best anyhow!"
-		*/
-	} else if (PDC_OK == status) {
-		/* so far only Halfdome supports this */
-		pcell_loc = pdc_result[0];
-	} else {
-		panic("WTF? CELL_GET_NUMBER give me invalid cell number?");
-	}
-
-	while (PDC_RET_OK == pat_query_module(pcell_loc, mod_index))
-	{
-		mod_index++;
-	}
-
-	return mod_index;
-}
-#endif /* __LP64__ */
+#define PAT_MAX_RANGES (4 * MAX_PHYSMEM_RANGES)
 
-static int do_newer_workstation_inventory(void)
+static void __init pat_memconfig(void)
 {
+	unsigned long actual_len;
+	struct pdc_pat_pd_addr_map_entry mem_table[PAT_MAX_RANGES+1];
+	struct pdc_pat_pd_addr_map_entry *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
 	long status;
-	int i, num = 0;
+	int entries;
+	unsigned long length;
+	int i;
+
+	length = (PAT_MAX_RANGES + 1) * sizeof(struct pdc_pat_pd_addr_map_entry);
+
+	status = pdc_pat_pd_get_addr_map(&actual_len, mem_table, length, 0L);
+
+	if ((status != PDC_OK)
+	    || ((actual_len % sizeof(struct pdc_pat_pd_addr_map_entry)) != 0)) {
+
+		/* The above pdc call shouldn't fail, but, just in
+		 * case, just use the PAGE0 info.
+		 */
+
+		printk("\n\n\n");
+		printk(KERN_WARNING "WARNING! Could not get full memory configuration. "
+			"All memory may not be used!\n\n\n");
+		pagezero_memconfig();
+		return;
+	}
 
-	/* So the idea here is to simply try one SYSTEM_MAP call.  If 
-	   that one works, great, otherwise do it another way */
+	entries = actual_len / sizeof(struct pdc_pat_pd_addr_map_entry);
 
-	status = pdc_system_map_find_mods(&module_result,&module_path,0);
+	if (entries > PAT_MAX_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+	}
 
-	if (status == PDC_RET_OK) {
-		/* This is for newer non-PDC-PAT boxes */
+	/* Copy information into the firmware independent pmem_ranges
+	 * array, skipping types we don't care about. Notice we said
+	 * "may" above. We'll use all the entries that were returned.
+	 */
+
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		if (   (mtbl_ptr->entry_type != PAT_MEMORY_DESCRIPTOR)
+		    || (mtbl_ptr->memory_type != PAT_MEMTYPE_MEMORY)
+		    || (mtbl_ptr->pages == 0)
+		    || (   (mtbl_ptr->memory_usage != PAT_MEMUSE_GENERAL)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GI)
+			&& (mtbl_ptr->memory_usage != PAT_MEMUSE_GNI) ) ) {
 
-		printk("a newer box...\n");
-		for(i=0, status=PDC_RET_OK; status != PDC_RET_NE_PROC && 
-			status != PDC_RET_NE_MOD ;i++) {
+			continue;
+		}
 
-			status = pdc_system_map_find_mods(&module_result,&module_path,i);
-			if (status == PDC_RET_OK) {
-				num++;
-				register_module(module_result.mod_addr);
-			}
+		if (npmem_ranges == MAX_PHYSMEM_RANGES) {
+			printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+			printk(KERN_WARNING "Some memory will not be used!\n");
+			break;
 		}
-	}
 
-	return (num > 0);
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
 }
 
-#ifndef __LP64__
-static	struct  pdc_memory_map r_addr __attribute__ ((aligned (8)));
-
-static int really_do_oldhw_inventory(void)
+static int __init pat_inventory(void)
 {
-	int i, mod, num = 0;
 	int status;
-	unsigned int hw_type;
-	unsigned int func;
+	ulong mod_index = 0;
+	struct pdc_pat_cell_num cell_info;
 
-	/* This is undocumented at the time of writing, but basically 
-	   we're setting up mod_path so that bc[0..4]=0xff, and step
-	   through mod to get the "Path Structure for GSC Modules".  If
-	   it works, use the returned HPA and determine the hardware type.  */
+	/*
+	** Note:  Prelude (and it's successors: Lclass, A400/500) only
+	**        implement PDC_PAT_CELL sub-options 0 and 2.
+	*/
+	status = pdc_pat_cell_get_number(&cell_info);
+	if (status != PDC_OK) {
+		return 0;
+	}
 
-	for (i=0;i<6;i++) module_path.bc[i]=0xff;
+#ifdef DEBUG_PAT
+	printk(KERN_DEBUG "CELL_GET_NUMBER: 0x%lx 0x%lx\n", cell_info.cell_num, 
+	       cell_info.cell_loc);
+#endif
 
-	for (mod=0;mod<16;mod++) {
-		char *stype = NULL;
+	while (PDC_OK == pat_query_module(cell_info.cell_loc, mod_index)) {
+		mod_index++;
+	}
 
-		module_path.mod=mod;
-		status = pdc_mem_map_hpa(&r_addr, &module_path);
-		if (status!=PDC_RET_OK) continue;
-	
-		status = pdc_iodc_read(&pdc_result,(void *) r_addr.hpa,
-			0, &iodc_data,32 );
-		if (status!=PDC_RET_OK) continue;
-		hw_type = iodc_data[3]&0x1f;
+	return mod_index;
+}
 
-		switch (hw_type)
-		{
-		case HPHW_NPROC:	/* 0 */
-			stype="Processor"; break;
+/* We only look for extended memory ranges on a 64 bit capable box */
+static void __init sprockets_memconfig(void)
+{
+	struct pdc_memory_table_raddr r_addr;
+	struct pdc_memory_table mem_table[MAX_PHYSMEM_RANGES];
+	struct pdc_memory_table *mtbl_ptr;
+	physmem_range_t *pmem_ptr;
+	long status;
+	int entries;
+	int i;
 
-		case HPHW_MEMORY:	/* 1 */
-			stype="Memory"; break;
+	status = pdc_mem_mem_table(&r_addr,mem_table,
+				(unsigned long)MAX_PHYSMEM_RANGES);
 
-		case HPHW_B_DMA:	/* 2 */
-			stype="Type B DMA"; break;
+	if (status != PDC_OK) {
 
-		case HPHW_A_DMA:	/* 4 */
-			stype="Type A DMA"; break;
+		/* The above pdc call only works on boxes with sprockets
+		 * firmware (newer B,C,J class). Other non PAT PDC machines
+		 * do support more than 3.75 Gb of memory, but we don't
+		 * support them yet.
+		 */
 
-		case HPHW_A_DIRECT:	/* 5 */
-			stype="Type A Direct"; break;
+		pagezero_memconfig();
+		return;
+	}
+
+	if (r_addr.entries_total > MAX_PHYSMEM_RANGES) {
+		printk(KERN_WARNING "This Machine has more memory ranges than we support!\n");
+		printk(KERN_WARNING "Some memory will not be used!\n");
+	}
 
-		case HPHW_BCPORT:	/* 7 */
-			stype="Bus Converter Port"; break;
+	entries = (int)r_addr.entries_returned;
 
-		case HPHW_CONSOLE:	/* 9 */
-			stype="Console"; break;
+	npmem_ranges = 0;
+	mtbl_ptr = mem_table;
+	pmem_ptr = pmem_ranges; /* Global firmware independent table */
+	for (i = 0; i < entries; i++,mtbl_ptr++) {
+		set_pmem_entry(pmem_ptr++,mtbl_ptr->paddr,mtbl_ptr->pages);
+		npmem_ranges++;
+	}
+}
 
-		case HPHW_FIO:		/* 10 - Graphics */
-			stype="Foreign I/O (Graphics)"; break;
+#else   /* !__LP64__ */
 
-		case HPHW_BA:		/* 11 - Bus Adapter */
-			stype="Bus Adapter"; break;
+#define pat_inventory() do { } while (0)
+#define pat_memconfig() do { } while (0)
+#define sprockets_memconfig() pagezero_memconfig()
 
-		case HPHW_IOA:		/* 12 */
-			stype="I/O Adapter"; break;
+#endif	/* !__LP64__ */
 
-		case HPHW_BRIDGE:	/* 13 */
-			stype="Bridge"; break;
 
-		case HPHW_FABRIC:	/* 14 */
-			stype="Fabric"; break;
+#ifndef CONFIG_PA20
 
-		case HPHW_FAULTY:	/* 31 */
-			stype="Faulty HW"; break;
+/* Code to support Snake machines (7[2350], 7[235]5, 715/Scorpio) */
 
-		case HPHW_OTHER:	/* 42 */
-		default:	
-			printk("Don't know this hw_type: %d\n", hw_type);
-			break;
-		}
+static struct parisc_device * __init
+legacy_create_device(struct pdc_memory_map *r_addr,
+		struct pdc_module_path *module_path)
+{
+	struct parisc_device *dev;
+	int status = pdc_mem_map_hpa(r_addr, module_path);
+	if (status != PDC_OK)
+		return NULL;
+
+	dev = alloc_pa_dev(r_addr->hpa, &module_path->path);
+	if (dev == NULL)
+		return NULL;
 
-		// This is kluged. But don't want to replicate code for
-		// most of the above cases.
-		if (stype) {
-#ifdef DBG_PDC_QUERY
-			// parisc/kernel/drivers.c
-			extern int num_devices; 
-			extern struct hp_device devices[];
-			struct hp_hardware *h;
-#endif
+	register_parisc_device(dev);
+	return dev;
+}
 
-			status = pdc_mem_map_hpa(&r_addr, &module_path);
-			if (status==PDC_RET_OK && register_module((void *) r_addr.hpa) != NULL)
-					num++;
-
-
-		    if (hw_type == HPHW_BA) {
-			/* Now, we're checking for devices for each
-			   module.  I seem to think that the
-			   modules in question are Lasi (2), 2nd Lasi (6)
-			   Wax (5).  To do this, set bc[5]=0, and set
-			   bc[4] to the module, and step through the
-			   functions. */
-
-			for (i=0;i<4;i++) module_path.bc[i]=0xff;
-			module_path.bc[4]=mod;
-			for (func=0;func<16;func++) {
-				module_path.mod = func;
-				module_path.bc[5]=0;
-				status = pdc_mem_map_hpa(&r_addr, &module_path);
-				if (status!=PDC_RET_OK) continue;
-				if (register_module((void *) r_addr.hpa) != NULL) 
-					num++;
-			}
+/**
+ * snake_inventory
+ *
+ * Before PDC_SYSTEM_MAP was invented, the PDC_MEM_MAP call was used.
+ * To use it, we initialise the mod_path.bc to 0xff and try all values of
+ * mod to get the HPA for the top-level devices.  Bus adapters may have
+ * sub-devices which are discovered by setting bc[5] to 0 and bc[4] to the
+ * module, then trying all possible functions.
+ */
+static void __init snake_inventory(void)
+{
+	int mod;
+	for (mod = 0; mod < 16; mod++) {
+		struct parisc_device *dev;
+		struct pdc_module_path module_path;
+		struct pdc_memory_map r_addr;
+		unsigned int func;
+
+		memset(module_path.path.bc, 0xff, 6);
+		module_path.path.mod = mod;
+		dev = legacy_create_device(&r_addr, &module_path);
+		if ((!dev) || (dev->id.hw_type != HPHW_BA))
+			continue;
+
+		memset(module_path.path.bc, 0xff, 4);
+		module_path.path.bc[4] = mod;
+
+		for (func = 0; func < 16; func++) {
+			module_path.path.bc[5] = 0;
+			module_path.path.mod = func;
+			legacy_create_device(&r_addr, &module_path);
 		}
-		// reset module_path.bc[]
-		for (i=0;i<6;i++) module_path.bc[i]=0xff;
+	}
+}
 
+#else /* CONFIG_PA20 */
+#define snake_inventory() do { } while (0)
+#endif  /* CONFIG_PA20 */
+
+/* Common 32/64 bit based code goes here */
+
+/**
+ * add_system_map_addresses - Add additional addresses to the parisc device.
+ * @dev: The parisc device.
+ * @num_addrs: Then number of addresses to add;
+ * @module_instance: The system_map module instance.
+ *
+ * This function adds any additional addresses reported by the system_map
+ * firmware to the parisc device.
+ */
+static void __init
+add_system_map_addresses(struct parisc_device *dev, int num_addrs, 
+			 int module_instance)
+{
+	int i;
+	long status;
+	struct pdc_system_map_addr_info addr_result;
 
-#ifdef DBG_PDC_QUERY
-//
-// Let print_devices() dump everything which is registered.
-//
-			h = devices[num_devices-1].reference;
+	dev->addr = kmalloc(num_addrs * sizeof(unsigned long), GFP_KERNEL);
+	if(!dev->addr) {
+		printk(KERN_ERR "%s %s(): memory allocation failure\n",
+		       __FILE__, __FUNCTION__);
+		return;
+	}
 
-			if (h) stype = h->name;
-			printk("Found %s at %d\n", stype, module_path.mod);
-#endif
+	for(i = 1; i <= num_addrs; ++i) {
+		status = pdc_system_map_find_addrs(&addr_result, 
+						   module_instance, i);
+		if(PDC_OK == status) {
+			dev->addr[dev->num_addrs] = (unsigned long)addr_result.mod_addr;
+			dev->num_addrs++;
+		} else {
+			printk(KERN_WARNING 
+			       "Bad PDC_FIND_ADDRESS status return (%ld) for index %d\n",
+			       status, i);
 		}
 	}
-	return num;
 }
 
-static int
-do_old_inventory(void)
+/**
+ * do_system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ *
+ * This function attempts to retrieve and register all the devices firmware
+ * knows about via the SYSTEM_MAP PDC call.
+ */
+static void __init system_map_inventory(void)
 {
-        unsigned int bus_id;
-	long status;
-	int ok = 0;
-
-	printk(" an older box...\n");
+	int i;
+	long status = PDC_OK;
+    
+	/*
+	 * first stop the usb controller, otherwise the machine
+	 * might crash during iommu setup
+	 */
+	pdc_suspend_usb();
+
+	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
+		struct parisc_device *dev;
+		struct pdc_system_map_mod_info module_result;
+		struct pdc_module_path module_path;
+
+		status = pdc_system_map_find_mods(&module_result,
+				&module_path, i);
+		if (status != PDC_OK)
+			continue;
+		
+		dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
+		if (!dev)
+			continue;
+		
+		register_parisc_device(dev);
+
+		/* if available, get the additional addresses for a module */
+		if (!module_result.add_addrs)
+			continue;
 
-	/* Here, we're going to check the model, and decide
-	   if we should even bother trying. */
+		add_system_map_addresses(dev, module_result.add_addrs, i);
+	}
 
-	status = pdc_model_info(&model);
+	walk_central_bus();
+	return;
+}
 
-	bus_id = (model.hversion >> (4+7) ) &0x1f;
+void __init do_memory_inventory(void)
+{
+	switch (pdc_type) {
 
-	/* Here, we're checking the HVERSION of the CPU.
-	   We're only checking the 0th CPU, since it'll
-	   be the same on an SMP box. */
+	case PDC_TYPE_PAT:
+		pat_memconfig();
+		break;
 
-	switch (bus_id) {
-		case 0x4: 	/* 720, 730, 750, 735, 755 */
-		case 0x6: 	/* 705, 710 */
-		case 0x7: 	/* 715, 725 */
-		case 0x8: 	/* 745, 747, 742 */
-		case 0xA: 	/* 712 and similiar */
-		case 0xC: 	/* 715/64, at least */
-
-		/* Do inventory using MEM_MAP */
-		really_do_oldhw_inventory();
-		ok = 1;
+	case PDC_TYPE_SYSTEM_MAP:
+		sprockets_memconfig();
 		break;
-	default: 	/* Everything else */
-		printk("This is a very very old machine, with a bus_id of 0x%x.\n",bus_id);
-		panic("This will probably never run Linux.\n");
+
+	case PDC_TYPE_SNAKE:
+		pagezero_memconfig();
+		return;
+
+	default:
+		panic("Unknown PDC type!\n");
 	}
 
-	return ok;
+	if (npmem_ranges == 0 || pmem_ranges[0].start_pfn != 0) {
+		printk(KERN_WARNING "Bad memory configuration returned!\n");
+		printk(KERN_WARNING "Some memory may not be used!\n");
+		pagezero_memconfig();
+	}
 }
 
-#endif /* !__LP64__ */
+void __init do_device_inventory(void)
+{
+	printk(KERN_INFO "Searching for devices...\n");
 
-void do_inventory(void){
-	if((pdc_hpa_processor(&processor_hpa))<0){
-		printk(KERN_INFO "Couldn't get the HPA of the processor.\n" );
-	}
+	switch (pdc_type) {
+
+	case PDC_TYPE_PAT:
+		pat_inventory();
+		break;
 
-	printk("Searching for devices in PDC firmware... ");
-	printk("processor hpa 0x%lx\n", processor_hpa.hpa);
+	case PDC_TYPE_SYSTEM_MAP:
+		system_map_inventory();
+		break;
 
-	if (!(
-		do_newer_workstation_inventory()
-#ifdef __LP64__
-		|| do_pat_inventory()
-#else /* __LP64__ */
-		|| do_old_inventory()
-#endif /* __LP64__ */
-	    ))
-	{
-	    panic("I can't get the hardware inventory on this machine");
+	case PDC_TYPE_SNAKE:
+		snake_inventory();
+		break;
+
+	default:
+		panic("Unknown PDC type!\n");
 	}
-	print_devices(NULL);
-}
 
+	printk(KERN_INFO "Found devices:\n");
+	print_parisc_devices();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ioctl32.c linux-2.4.20/arch/parisc/kernel/ioctl32.c
--- linux-2.4.19/arch/parisc/kernel/ioctl32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/ioctl32.c	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,3758 @@
+/* $Id: ioctl32.c,v 1.12 2002/07/08 20:52:15 grundler Exp $
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ *
+ * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * ioctls.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include "sys32.h"
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ioctl.h>
+#include <linux/if.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/raid/md.h>
+#include <linux/kd.h>
+#include <linux/route.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/vt.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/fd.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+#include <linux/mtio.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
+#include <linux/auto_fs.h>
+#include <linux/devfs_fs.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/fb.h>
+#include <linux/ext2_fs.h>
+#include <linux/videodev.h>
+#include <linux/netdevice.h>
+#include <linux/raw.h>
+#include <linux/smb_fs.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/rtc.h>
+#include <linux/serial.h>
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh. This header really is not clean */
+/* #define min min
+#define max max */
+#include <linux/lvm.h>
+#endif /* LVM */
+
+#include <scsi/scsi.h>
+/* Ugly hack. */
+#undef __KERNEL__
+#include <scsi/scsi_ioctl.h>
+#define __KERNEL__
+#include <scsi/sg.h>
+
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <asm/perf.h>
+#include <linux/ethtool.h>
+#include <linux/soundcard.h>
+
+#include <linux/atm.h>
+#include <linux/atmarp.h>
+#include <linux/atmclip.h>
+#include <linux/atmdev.h>
+#include <linux/atmioc.h>
+#include <linux/atmlec.h>
+#include <linux/atmmpc.h>
+#include <linux/atmsvc.h>
+#include <linux/atm_tcp.h>
+#include <linux/sonet.h>
+#include <linux/atm_suni.h>
+
+#include <asm/module.h>	/* get #define module_map() */
+
+/* Use this to get at 32-bit user passed pointers. 
+   See sys_sparc32.c for description about these. */
+#define A(__x) ((unsigned long)(__x))
+
+/* Aiee. Someone does not find a difference between int and long */
+#define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
+#define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
+#define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
+#define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
+
+extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+ 
+static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	if(get_user(val, (u32 *)arg))
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+
+static int siocprivate(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	int err = sys_ioctl(fd, cmd, arg);
+	if ((unsigned) err > -4095)
+		printk(KERN_WARNING 
+			"ioctl(%d, 0x%x, %p) -- SIOCDEVPRIVATE-based ioctls aren't really\n"
+			"supported, though some will work by accident.\n",
+		    fd, cmd, (void *)arg);
+	return err;
+}
+
+static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* These are just misnamed, they actually get/put from/to user an int */
+	switch (cmd) {
+	case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
+	case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
+	case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
+	case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
+	}
+	return sys_ioctl(fd, cmd, arg);
+}
+ 
+static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct timeval32 *up = (struct timeval32 *)arg;
+	struct timeval ktv;
+	mm_segment_t old_fs = get_fs();
+	int err;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
+	set_fs(old_fs);
+	if(!err) {
+		err = put_user(ktv.tv_sec, &up->tv_sec);
+		err |= __put_user(ktv.tv_usec, &up->tv_usec);
+	}
+	return err;
+}
+
+struct ifmap32 {
+	u32 mem_start;
+	u32 mem_end;
+	unsigned short base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+struct ifreq32 {
+#define IFHWADDRLEN     6
+#define IFNAMSIZ        16
+        union {
+                char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
+        } ifr_ifrn;
+        union {
+                struct  sockaddr ifru_addr;
+                struct  sockaddr ifru_dstaddr;
+                struct  sockaddr ifru_broadaddr;
+                struct  sockaddr ifru_netmask;
+                struct  sockaddr ifru_hwaddr;
+                short   ifru_flags;
+                int     ifru_ivalue;
+                int     ifru_mtu;
+                struct  ifmap32 ifru_map;
+                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
+		char	ifru_newname[IFNAMSIZ];
+                __kernel_caddr_t32 ifru_data;
+        } ifr_ifru;
+};
+
+struct ifconf32 {
+        int     ifc_len;                        /* size of buffer       */
+        __kernel_caddr_t32  ifcbuf;
+};
+
+static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct net_device *dev;
+	struct ifreq32 ifr32;
+	int err;
+
+	if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+		return -EFAULT;
+
+	dev = dev_get_by_index(ifr32.ifr_ifindex);
+	if (!dev)
+		return -ENODEV;
+
+	strcpy(ifr32.ifr_name, dev->name);
+
+	err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
+	return (err ? -EFAULT : 0);
+}
+
+static inline int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifconf32 ifc32;
+	struct ifconf ifc;
+	struct ifreq32 *ifr32;
+	struct ifreq *ifr;
+	mm_segment_t old_fs;
+	unsigned int i, j;
+	int err;
+
+	if (copy_from_user(&ifc32, (struct ifconf32 *)arg, sizeof(struct ifconf32)))
+		return -EFAULT;
+
+	if(ifc32.ifcbuf == 0) {
+		ifc32.ifc_len = 0;
+		ifc.ifc_len = 0;
+		ifc.ifc_buf = NULL;
+	} else {
+		ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
+			sizeof (struct ifreq);
+		ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
+		if (!ifc.ifc_buf)
+			return -ENOMEM;
+	}
+	ifr = ifc.ifc_req;
+	ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
+		if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
+			kfree (ifc.ifc_buf);
+			return -EFAULT;
+		}
+	}
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);	
+	set_fs (old_fs);
+	if (!err) {
+		ifr = ifc.ifc_req;
+		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
+		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
+			if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
+				err = -EFAULT;
+				break;
+			}
+		}
+		if (!err) {
+			if (i <= ifc32.ifc_len)
+				ifc32.ifc_len = i;
+			else
+				ifc32.ifc_len = i - sizeof (struct ifreq32);
+			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
+				err = -EFAULT;
+		}
+	}
+	if(ifc.ifc_buf != NULL)
+		kfree (ifc.ifc_buf);
+	return err;
+}
+
+static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	mm_segment_t old_fs;
+	int err;
+	
+	switch (cmd) {
+	case SIOCSIFMAP:
+		err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
+		err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+		err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+		err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+		err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+		err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+		err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+		if (err)
+			return -EFAULT;
+		break;
+	case SIOCGPPPSTATS:
+	case SIOCGPPPCSTATS:
+	case SIOCGPPPVER:
+	case SIOCETHTOOL:
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+			return -EFAULT;
+		ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
+		if (!ifr.ifr_data)
+			return -EAGAIN;
+		if(cmd == SIOCETHTOOL) {
+			u32 data;
+
+			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+			if(copy_from_user(ifr.ifr_data,
+					  (char *)A(data),
+					  sizeof(struct ethtool_cmd))) {
+				free_page((unsigned long)ifr.ifr_data);
+				return -EFAULT;
+			}
+		}
+		break;
+	default:
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+			return -EFAULT;
+		break;
+	}
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+	set_fs (old_fs);
+	if (!err) {
+		switch (cmd) {
+		case SIOCGIFFLAGS:
+		case SIOCGIFMETRIC:
+		case SIOCGIFMTU:
+		case SIOCGIFMEM:
+		case SIOCGIFHWADDR:
+		case SIOCGIFINDEX:
+		case SIOCGIFADDR:
+		case SIOCGIFBRDADDR:
+		case SIOCGIFDSTADDR:
+		case SIOCGIFNETMASK:
+		case SIOCGIFTXQLEN:
+			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
+				return -EFAULT;
+			break;
+		case SIOCGPPPSTATS:
+		case SIOCGPPPCSTATS:
+		case SIOCGPPPVER:
+		case SIOCETHTOOL:
+		{
+			u32 data;
+			int len;
+
+			__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+			if(cmd == SIOCETHTOOL)
+				len = sizeof(struct ethtool_cmd);
+			if(cmd == SIOCGPPPVER)
+				len = strlen((char *)ifr.ifr_data) + 1;
+			else if(cmd == SIOCGPPPCSTATS)
+				len = sizeof(struct ppp_comp_stats);
+			else
+				len = sizeof(struct ppp_stats);
+
+			len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+			free_page((unsigned long)ifr.ifr_data);
+			if(len)
+				return -EFAULT;
+			break;
+		}
+		case SIOCGIFMAP:
+			err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
+			err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
+			err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
+			err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
+			err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
+			err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
+			err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+			if (err)
+				err = -EFAULT;
+			break;
+		}
+	}
+	return err;
+}
+
+struct rtentry32 {
+        u32   		rt_pad1;
+        struct sockaddr rt_dst;         /* target address               */
+        struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
+        struct sockaddr rt_genmask;     /* target network mask (IP)     */
+        unsigned short  rt_flags;
+        short           rt_pad2;
+        u32   		rt_pad3;
+        unsigned char   rt_tos;
+        unsigned char   rt_class;
+        short           rt_pad4;
+        short           rt_metric;      /* +1 for binary compatibility! */
+        /* char * */ u32 rt_dev;        /* forcing the device at add    */
+        u32   		rt_mtu;         /* per route MTU/Window         */
+        u32   		rt_window;      /* Window clamping              */
+        unsigned short  rt_irtt;        /* Initial RTT                  */
+
+};
+
+static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct rtentry r;
+	char devname[16];
+	u32 rtdev;
+	int ret;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = copy_from_user (&r.rt_dst, &(((struct rtentry32 *)arg)->rt_dst), 3 * sizeof(struct sockaddr));
+	ret |= __get_user (r.rt_flags, &(((struct rtentry32 *)arg)->rt_flags));
+	ret |= __get_user (r.rt_metric, &(((struct rtentry32 *)arg)->rt_metric));
+	ret |= __get_user (r.rt_mtu, &(((struct rtentry32 *)arg)->rt_mtu));
+	ret |= __get_user (r.rt_window, &(((struct rtentry32 *)arg)->rt_window));
+	ret |= __get_user (r.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
+	ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
+	if (rtdev) {
+		ret |= copy_from_user (devname, (char *)A(rtdev), 15);
+		r.rt_dev = devname; devname[15] = 0;
+	} else
+		r.rt_dev = 0;
+	if (ret)
+		return -EFAULT;
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, cmd, (long)&r);
+	set_fs (old_fs);
+	return ret;
+}
+
+struct hd_geometry32 {
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned short cylinders;
+	u32 start;
+};
+                        
+static inline int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct hd_geometry geo;
+	int err;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
+	set_fs (old_fs);
+	if (!err) {
+		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
+		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
+	}
+	return err ? -EFAULT : 0;
+}
+
+
+#if 0
+/* looks like SPARC only - eg sbus video */
+struct  fbcmap32 {
+	int             index;          /* first element (0 origin) */
+	int             count;
+	u32		red;
+	u32		green;
+	u32		blue;
+};
+
+
+static inline int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct fbcmap f;
+	int ret;
+	char red[256], green[256], blue[256];
+	u32 r, g, b;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index));
+	ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count));
+	ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red));
+	ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green));
+	ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue));
+	if (ret)
+		return -EFAULT;
+	if ((f.index < 0) || (f.index > 255)) return -EINVAL;
+	if (f.index + f.count > 256)
+		f.count = 256 - f.index;
+	if (cmd == FBIOPUTCMAP32) {
+		ret = copy_from_user (red, (char *)A(r), f.count);
+		ret |= copy_from_user (green, (char *)A(g), f.count);
+		ret |= copy_from_user (blue, (char *)A(b), f.count);
+		if (ret)
+			return -EFAULT;
+	}
+	f.red = red; f.green = green; f.blue = blue;
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f);
+	set_fs (old_fs);
+	if (!ret && cmd == FBIOGETCMAP32) {
+		ret = copy_to_user ((char *)A(r), red, f.count);
+		ret |= copy_to_user ((char *)A(g), green, f.count);
+		ret |= copy_to_user ((char *)A(b), blue, f.count);
+	}
+	return ret ? -EFAULT : 0;
+}
+
+struct fbcursor32 {
+	short set;		/* what to set, choose from the list above */
+	short enable;		/* cursor on/off */
+	struct fbcurpos pos;	/* cursor position */
+	struct fbcurpos hot;	/* cursor hot spot */
+	struct fbcmap32 cmap;	/* color map info */
+	struct fbcurpos size;	/* cursor bit map size */
+	u32	image;		/* cursor image bits */
+	u32	mask;		/* cursor mask bits */
+};
+	
+static inline int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct fbcursor f;
+	int ret;
+	char red[2], green[2], blue[2];
+	char image[128], mask[128];
+	u32 r, g, b;
+	u32 m, i;
+	mm_segment_t old_fs = get_fs();
+	
+	ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
+	ret |= __get_user(f.size.fbx, &(((struct fbcursor32 *)arg)->size.fbx));
+	ret |= __get_user(f.size.fby, &(((struct fbcursor32 *)arg)->size.fby));
+	ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index));
+	ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count));
+	ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red));
+	ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green));
+	ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue));
+	ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask));
+	ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image));
+	if (ret)
+		return -EFAULT;
+	if (f.set & FB_CUR_SETCMAP) {
+		if ((uint) f.size.fby > 32)
+			return -EINVAL;
+		ret = copy_from_user (mask, (char *)A(m), f.size.fby * 4);
+		ret |= copy_from_user (image, (char *)A(i), f.size.fby * 4);
+		if (ret)
+			return -EFAULT;
+		f.image = image; f.mask = mask;
+	}
+	if (f.set & FB_CUR_SETCMAP) {
+		ret = copy_from_user (red, (char *)A(r), 2);
+		ret |= copy_from_user (green, (char *)A(g), 2);
+		ret |= copy_from_user (blue, (char *)A(b), 2);
+		if (ret)
+			return -EFAULT;
+		f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue;
+	}
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f);
+	set_fs (old_fs);
+	return ret;
+}
+#endif /* 0 */
+
+struct fb_fix_screeninfo32 {
+	char			id[16];
+        __kernel_caddr_t32	smem_start;
+	__u32			smem_len;
+	__u32			type;
+	__u32			type_aux;
+	__u32			visual;
+	__u16			xpanstep;
+	__u16			ypanstep;
+	__u16			ywrapstep;
+	__u32			line_length;
+        __kernel_caddr_t32	mmio_start;
+	__u32			mmio_len;
+	__u32			accel;
+	__u16			reserved[3];
+};
+
+struct fb_cmap32 {
+	__u32			start;
+	__u32			len;
+	__kernel_caddr_t32	red;
+	__kernel_caddr_t32	green;
+	__kernel_caddr_t32	blue;
+	__kernel_caddr_t32	transp;
+};
+
+static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	u32 red = 0, green = 0, blue = 0, transp = 0;
+	struct fb_fix_screeninfo fix;
+	struct fb_cmap cmap;
+	void *karg;
+	int err = 0;
+
+	memset(&cmap, 0, sizeof(cmap));
+	switch (cmd) {
+	case FBIOGET_FSCREENINFO:
+		karg = &fix;
+		break;
+	case FBIOGETCMAP:
+	case FBIOPUTCMAP:
+		karg = &cmap;
+		err = __get_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
+		err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
+		err |= __get_user(red, &((struct fb_cmap32 *)arg)->red);
+		err |= __get_user(green, &((struct fb_cmap32 *)arg)->green);
+		err |= __get_user(blue, &((struct fb_cmap32 *)arg)->blue);
+		err |= __get_user(transp, &((struct fb_cmap32 *)arg)->transp);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+		err = -ENOMEM;
+		cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.red)
+			goto out;
+		cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.green)
+			goto out;
+		cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+		if (!cmap.blue)
+			goto out;
+		if (transp) {
+			cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
+			if (!cmap.transp)
+				goto out;
+		}
+			
+		if (cmd == FBIOGETCMAP)
+			break;
+
+		err = __copy_from_user(cmap.red, (char *)A(red), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16));
+		if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16));
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"%s: Unknown fb ioctl cmd fd(%d) "
+					"cmd(%08x) arg(%08lx)\n",
+					__FUNCTION__, fd, cmd, arg);
+		} while(0);
+		return -ENOSYS;
+	}
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)karg);
+	set_fs(old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+		struct fb_fix_screeninfo32 fix32;
+	case FBIOGET_FSCREENINFO:
+		memset(&fix32, 0, sizeof(fix32));
+		memcpy(fix32.id, fix.id, sizeof(fix32.id));
+		fix32.smem_start = (__u32)(unsigned long)fix.smem_start;
+		fix32.smem_len	= fix.smem_len;
+		fix32.type	= fix.type;
+		fix32.type_aux	= fix.type_aux;
+		fix32.visual	= fix.visual;
+		fix32.xpanstep	= fix.xpanstep;
+		fix32.ypanstep	= fix.ypanstep;
+		fix32.ywrapstep = fix.ywrapstep;
+		fix32.line_length = fix.line_length;
+		fix32.mmio_start = (__u32)(unsigned long)fix.mmio_start;
+		fix32.mmio_len	= fix.mmio_len;
+		fix32.accel	= fix.accel;
+		memcpy(fix32.reserved, fix.reserved, sizeof(fix32.reserved));
+		err = __copy_to_user((void *) arg, (const void *) &fix32, sizeof(fix32));
+
+printk("fix  : %lx %x  %x %x %x  %x %x %x %x  %lx %x %x\n",
+	fix.smem_start, fix.smem_len,
+	fix.type, fix.type_aux, fix.visual,
+	fix.xpanstep, fix.ypanstep, fix.ywrapstep, fix.line_length,
+	fix.mmio_start, fix.mmio_len, fix.accel);
+printk("fix32: %x %x  %x %x %x  %x %x %x %x  %x %x %x\n",
+	fix32.smem_start, fix32.smem_len,
+	fix32.type, fix32.type_aux, fix32.visual,
+	fix32.xpanstep, fix32.ypanstep, fix32.ywrapstep, fix32.line_length,
+	fix32.mmio_start, fix32.mmio_len, fix32.accel);
+
+		break;
+	case FBIOGETCMAP:
+		err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16));
+		err |= __copy_to_user((char *)A(green), cmap.blue, cmap.len * sizeof(__u16));
+		err |= __copy_to_user((char *)A(blue), cmap.blue, cmap.len * sizeof(__u16));
+		if (cmap.transp)
+			err |= __copy_to_user((char *)A(transp), cmap.transp, cmap.len * sizeof(__u16));
+		break;
+	case FBIOPUTCMAP:
+		break;
+	}
+	if (err)
+		err = -EFAULT;
+
+out:	if (cmap.red) kfree(cmap.red);
+	if (cmap.green) kfree(cmap.green);
+	if (cmap.blue) kfree(cmap.blue);
+	if (cmap.transp) kfree(cmap.transp);
+	return err;
+}
+
+static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	unsigned long kval;
+	unsigned int *uvp;
+	int error;
+
+	set_fs(KERNEL_DS);
+	error = sys_ioctl(fd, cmd, (long)&kval);
+	set_fs(old_fs);
+
+	if(error == 0) {
+		uvp = (unsigned int *)arg;
+		if(put_user(kval, uvp))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+struct floppy_struct32 {
+	unsigned int	size;
+	unsigned int	sect;
+	unsigned int	head;
+	unsigned int	track;
+	unsigned int	stretch;
+	unsigned char	gap;
+	unsigned char	rate;
+	unsigned char	spec1;
+	unsigned char	fmt_gap;
+	const __kernel_caddr_t32 name;
+};
+
+struct floppy_drive_params32 {
+	char		cmos;
+	u32		max_dtr;
+	u32		hlt;
+	u32		hut;
+	u32		srt;
+	u32		spinup;
+	u32		spindown;
+	unsigned char	spindown_offset;
+	unsigned char	select_delay;
+	unsigned char	rps;
+	unsigned char	tracks;
+	u32		timeout;
+	unsigned char	interleave_sect;
+	struct floppy_max_errors max_errors;
+	char		flags;
+	char		read_track;
+	short		autodetect[8];
+	int		checkfreq;
+	int		native_format;
+};
+
+struct floppy_drive_struct32 {
+	signed char	flags;
+	u32		spinup_date;
+	u32		select_date;
+	u32		first_read_date;
+	short		probed_format;
+	short		track;
+	short		maxblock;
+	short		maxtrack;
+	int		generation;
+	int		keep_data;
+	int		fd_ref;
+	int		fd_device;
+	int		last_checked;
+	__kernel_caddr_t32 dmabuf;
+	int		bufblocks;
+};
+
+struct floppy_fdc_state32 {
+	int		spec1;
+	int		spec2;
+	int		dtr;
+	unsigned char	version;
+	unsigned char	dor;
+	u32		address;
+	unsigned int	rawcmd:2;
+	unsigned int	reset:1;
+	unsigned int	need_configure:1;
+	unsigned int	perp_mode:2;
+	unsigned int	has_fifo:1;
+	unsigned int	driver_version;
+	unsigned char	track[4];
+};
+
+struct floppy_write_errors32 {
+	unsigned int	write_errors;
+	u32		first_error_sector;
+	int		first_error_generation;
+	u32		last_error_sector;
+	int		last_error_generation;
+	unsigned int	badness;
+};
+
+#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
+#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)
+#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)
+#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)
+#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)
+#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)
+#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)
+#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)
+#define FDWERRORGET32  _IOR(2, 0x17, struct floppy_write_errors32)
+
+static struct {
+	unsigned int	cmd32;
+	unsigned int	cmd;
+} fd_ioctl_trans_table[] = {
+	{ FDSETPRM32, FDSETPRM },
+	{ FDDEFPRM32, FDDEFPRM },
+	{ FDGETPRM32, FDGETPRM },
+	{ FDSETDRVPRM32, FDSETDRVPRM },
+	{ FDGETDRVPRM32, FDGETDRVPRM },
+	{ FDGETDRVSTAT32, FDGETDRVSTAT },
+	{ FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
+	{ FDGETFDCSTAT32, FDGETFDCSTAT },
+	{ FDWERRORGET32, FDWERRORGET }
+};
+
+#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))
+
+static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	void *karg = NULL;
+	unsigned int kcmd = 0;
+	int i, err;
+
+	for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
+		if (cmd == fd_ioctl_trans_table[i].cmd32) {
+			kcmd = fd_ioctl_trans_table[i].cmd;
+			break;
+		}
+	if (!kcmd)
+		return -EINVAL;
+
+	switch (cmd) {
+		case FDSETPRM32:
+		case FDDEFPRM32:
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETPRM32)
+				break;
+			err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDSETDRVPRM32:
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f;
+
+			f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			if (cmd == FDGETDRVPRM32)
+				break;
+			err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors));
+			err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
+			err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			if (err) {
+				err = -EFAULT;
+				goto out;
+			}
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+			karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDGETFDCSTAT32:
+			karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		case FDWERRORGET32:
+			karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
+			if (!karg)
+				return -ENOMEM;
+			break;
+		default:
+			return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+		case FDGETPRM32:
+		{
+			struct floppy_struct *f = karg;
+
+			err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
+			err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
+			err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
+			err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
+			err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
+			err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
+			err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
+			err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
+			err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
+			err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
+			break;
+		}
+		case FDGETDRVPRM32:
+		{
+			struct floppy_drive_params *f = karg;
+
+			err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos);
+			err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr);
+			err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt);
+			err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut);
+			err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt);
+			err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup);
+			err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown);
+			err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset);
+			err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay);
+			err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps);
+			err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks);
+			err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout);
+			err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect);
+			err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors));
+			err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags);
+			err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track);
+			err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect));
+			err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
+			err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
+			break;
+		}
+		case FDGETDRVSTAT32:
+		case FDPOLLDRVSTAT32:
+		{
+			struct floppy_drive_struct *f = karg;
+
+			err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags);
+			err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date);
+			err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date);
+			err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date);
+			err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format);
+			err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track);
+			err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock);
+			err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack);
+			err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation);
+			err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data);
+			err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref);
+			err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device);
+			err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked);
+			err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf);
+			err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks);
+			break;
+		}
+		case FDGETFDCSTAT32:
+		{
+			struct floppy_fdc_state *f = karg;
+
+			err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1);
+			err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2);
+			err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr);
+			err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version);
+			err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor);
+			err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address);
+			err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address
+			    		   + sizeof(((struct floppy_fdc_state32 *)arg)->address),
+					   (char *)&f->address + sizeof(f->address), sizeof(int));
+			err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version);
+			err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track));
+			break;
+		}
+		case FDWERRORGET32:
+		{
+			struct floppy_write_errors *f = karg;
+
+			err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors);
+			err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector);
+			err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation);
+			err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector);
+			err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation);
+			err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness);
+			break;
+		}
+		default:
+			break;
+	}
+	if (err)
+		err = -EFAULT;
+
+out:	if (karg) kfree(karg);
+	return err;
+}
+
+struct ppp_option_data32 {
+	__kernel_caddr_t32	ptr;
+	__u32			length;
+	int			transmit;
+};
+#define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
+
+struct ppp_idle32 {
+	__kernel_time_t32 xmit_idle;
+	__kernel_time_t32 recv_idle;
+};
+#define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
+
+static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct ppp_option_data32 data32;
+	struct ppp_option_data data;
+	struct ppp_idle32 idle32;
+	struct ppp_idle idle;
+	unsigned int kcmd;
+	void *karg;
+	int err = 0;
+
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		kcmd = PPPIOCGIDLE;
+		karg = &idle;
+		break;
+	case PPPIOCSCOMPRESS32:
+		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
+			return -EFAULT;
+		data.ptr = kmalloc (data32.length, GFP_KERNEL);
+		if (!data.ptr)
+			return -ENOMEM;
+		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
+			kfree(data.ptr);
+			return -EFAULT;
+		}
+		data.length = data32.length;
+		data.transmit = data32.transmit;
+		kcmd = PPPIOCSCOMPRESS;
+		karg = &data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"ppp_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	switch (cmd) {
+	case PPPIOCGIDLE32:
+		if (err)
+			return err;
+		idle32.xmit_idle = idle.xmit_idle;
+		idle32.recv_idle = idle.recv_idle;
+		if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))
+			return -EFAULT;
+		break;
+	case PPPIOCSCOMPRESS32:
+		kfree(data.ptr);
+		break;
+	default:
+		break;
+	}
+	return err;
+}
+
+
+struct mtget32 {
+	__u32	mt_type;
+	__u32	mt_resid;
+	__u32	mt_dsreg;
+	__u32	mt_gstat;
+	__u32	mt_erreg;
+	__kernel_daddr_t32	mt_fileno;
+	__kernel_daddr_t32	mt_blkno;
+};
+#define MTIOCGET32	_IOR('m', 2, struct mtget32)
+
+struct mtpos32 {
+	__u32	mt_blkno;
+};
+#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
+
+struct mtconfiginfo32 {
+	__u32	mt_type;
+	__u32	ifc_type;
+	__u16	irqnr;
+	__u16	dmanr;
+	__u16	port;
+	__u32	debug;
+	__u32	have_dens:1;
+	__u32	have_bsf:1;
+	__u32	have_fsr:1;
+	__u32	have_bsr:1;
+	__u32	have_eod:1;
+	__u32	have_seek:1;
+	__u32	have_tell:1;
+	__u32	have_ras1:1;
+	__u32	have_ras2:1;
+	__u32	have_ras3:1;
+	__u32	have_qfa:1;
+	__u32	pad1:5;
+	char	reserved[10];
+};
+#define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)
+#define	MTIOCSETCONFIG32	_IOW('m', 5, struct mtconfiginfo32)
+
+static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct mtconfiginfo info;
+	struct mtget get;
+	struct mtpos pos;
+	unsigned long kcmd;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case MTIOCPOS32:
+		kcmd = MTIOCPOS;
+		karg = &pos;
+		break;
+	case MTIOCGET32:
+		kcmd = MTIOCGET;
+		karg = &get;
+		break;
+	case MTIOCGETCONFIG32:
+		kcmd = MTIOCGETCONFIG;
+		karg = &info;
+		break;
+	case MTIOCSETCONFIG32:
+		kcmd = MTIOCSETCONFIG;
+		karg = &info;
+		err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
+				     (char *)&((struct mtconfiginfo32 *)arg)->debug
+				     + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
+		if (err)
+			return -EFAULT;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"mt_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		return err;
+	switch (cmd) {
+	case MTIOCPOS32:
+		err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGET32:
+		err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
+		err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
+		err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
+		err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
+		err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
+		err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
+		err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGETCONFIG32:
+		err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
+			    		   + sizeof(((struct mtconfiginfo32 *)arg)->debug),
+					   (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
+		break;
+	case MTIOCSETCONFIG32:
+		break;
+	}
+	return err ? -EFAULT: 0;
+}
+
+struct cdrom_read32 {
+	int			cdread_lba;
+	__kernel_caddr_t32	cdread_bufaddr;
+	int			cdread_buflen;
+};
+
+struct cdrom_read_audio32 {
+	union cdrom_addr	addr;
+	u_char			addr_format;
+	int			nframes;
+	__kernel_caddr_t32	buf;
+};
+
+struct cdrom_generic_command32 {
+	unsigned char		cmd[CDROM_PACKET_SIZE];
+	__kernel_caddr_t32	buffer;
+	unsigned int		buflen;
+	int			stat;
+	__kernel_caddr_t32	sense;
+	__kernel_caddr_t32	reserved[3];
+};
+
+static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct cdrom_read cdread;
+	struct cdrom_read_audio cdreadaudio;
+	struct cdrom_generic_command cgc;
+	__kernel_caddr_t32 addr;
+	char *data = 0;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case CDROMREADMODE2:
+	case CDROMREADMODE1:
+	case CDROMREADRAW:
+	case CDROMREADCOOKED:
+		karg = &cdread;
+		err = __get_user(cdread.cdread_lba, &((struct cdrom_read32 *)arg)->cdread_lba);
+		err |= __get_user(addr, &((struct cdrom_read32 *)arg)->cdread_bufaddr);
+		err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
+		if (err)
+			return -EFAULT;
+		data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		cdread.cdread_bufaddr = data;
+		break;
+	case CDROMREADAUDIO:
+		karg = &cdreadaudio;
+		err = copy_from_user(&cdreadaudio.addr, &((struct cdrom_read_audio32 *)arg)->addr, sizeof(cdreadaudio.addr));
+		err |= __get_user(cdreadaudio.addr_format, &((struct cdrom_read_audio32 *)arg)->addr_format);
+		err |= __get_user(cdreadaudio.nframes, &((struct cdrom_read_audio32 *)arg)->nframes); 
+		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
+		if (err)
+			return -EFAULT;
+		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+		cdreadaudio.buf = data;
+		break;
+	case CDROM_SEND_PACKET:
+		karg = &cgc;
+		err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
+		err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
+		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
+		if (err)
+			return -EFAULT;
+		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		cgc.buffer = data;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk(KERN_WARNING
+					"cdrom_ioctl: Unknown cmd fd(%d) "
+					"cmd(%08x) arg(%08x)\n",
+					(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		goto out;
+	switch (cmd) {
+	case CDROMREADMODE2:
+	case CDROMREADMODE1:
+	case CDROMREADRAW:
+	case CDROMREADCOOKED:
+		err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
+		break;
+	case CDROMREADAUDIO:
+		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
+		break;
+	case CDROM_SEND_PACKET:
+		err = copy_to_user((char *)A(addr), data, cgc.buflen);
+		break;
+	default:
+		break;
+	}
+out:	if (data)
+		kfree(data);
+	return err ? -EFAULT : 0;
+}
+
+struct loop_info32 {
+	int			lo_number;      /* ioctl r/o */
+	__kernel_dev_t32	lo_device;      /* ioctl r/o */
+	unsigned int		lo_inode;       /* ioctl r/o */
+	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
+	int			lo_offset;
+	int			lo_encrypt_type;
+	int			lo_encrypt_key_size;    /* ioctl w/o */
+	int			lo_flags;       /* ioctl r/o */
+	char			lo_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int		lo_init[2];
+	char			reserved[4];
+};
+
+static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct loop_info l;
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case LOOP_SET_STATUS:
+		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
+					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+		if (err) {
+			err = -EFAULT;
+		} else {
+			set_fs (KERNEL_DS);
+			err = sys_ioctl (fd, cmd, (unsigned long)&l);
+			set_fs (old_fs);
+		}
+		break;
+	case LOOP_GET_STATUS:
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&l);
+		set_fs (old_fs);
+		if (!err) {
+			err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+			err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+			err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+			err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+			err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
+					   (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+			if (err)
+				err = -EFAULT;
+		}
+		break;
+	default: {
+		static int count = 0;
+		if (++count <= 20)
+			printk(KERN_WARNING
+				"%s: Unknown loop ioctl cmd, fd(%d) "
+				"cmd(%08x) arg(%08lx)\n",
+				__FUNCTION__, fd, cmd, arg);
+	}
+	}
+	return err;
+}
+
+#ifdef CONFIG_VT
+extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
+
+static int vt_check(struct file *file)
+{
+	struct tty_struct *tty;
+	struct inode *inode = file->f_dentry->d_inode;
+	
+	if (file->f_op->ioctl != tty_ioctl)
+		return -EINVAL;
+	                
+	tty = (struct tty_struct *)file->private_data;
+	if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
+		return -EINVAL;
+	                                                
+	if (tty->driver.ioctl != vt_ioctl)
+		return -EINVAL;
+	
+	/*
+	 * To have permissions to do most of the vt ioctls, we either have
+	 * to be the owner of the tty, or super-user.
+	 */
+	if (current->tty == tty || suser())
+		return 1;
+	return 0;                                                    
+}
+
+struct consolefontdesc32 {
+	unsigned short charcount;       /* characters in font (256 or 512) */
+	unsigned short charheight;      /* scan lines per character (1-32) */
+	u32 chardata;			/* font data in expanded form */
+};
+
+static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
+{
+	struct consolefontdesc cfdarg;
+	struct console_font_op op;
+	int i, perm;
+
+	perm = vt_check(file);
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
+		return -EFAULT;
+	
+	cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
+ 	
+	switch (cmd) {
+	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+		op.op = KD_FONT_OP_SET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		return con_font_op(fg_console, &op);
+	case GIO_FONTX:
+		if (!cfdarg.chardata)
+			return 0;
+		op.op = KD_FONT_OP_GET;
+		op.flags = 0;
+		op.width = 8;
+		op.height = cfdarg.charheight;
+		op.charcount = cfdarg.charcount;
+		op.data = cfdarg.chardata;
+		i = con_font_op(fg_console, &op);
+		if (i)
+			return i;
+		cfdarg.charheight = op.height;
+		cfdarg.charcount = op.charcount;
+		((struct consolefontdesc32 *)&cfdarg)->chardata	= (unsigned long)cfdarg.chardata;
+		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+struct console_font_op32 {
+	unsigned int op;        /* operation code KD_FONT_OP_* */
+	unsigned int flags;     /* KD_FONT_FLAG_* */
+	unsigned int width, height;     /* font size */
+	unsigned int charcount;
+	u32 data;    /* font data with height fixed to 32 */
+};
+                                        
+static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
+{
+	struct console_font_op op;
+	int perm = vt_check(file), i;
+	struct vt_struct *vt;
+	
+	if (perm < 0) return perm;
+	
+	if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	if (!perm && op.op != KD_FONT_OP_GET)
+		return -EPERM;
+	op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
+	op.flags |= KD_FONT_FLAG_OLD;
+	vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
+	i = con_font_op(vt->vc_num, &op);
+	if (i) return i;
+	((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
+	if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
+		return -EFAULT;
+	return 0;
+}
+
+struct unimapdesc32 {
+	unsigned short entry_ct;
+	u32 entries;
+};
+
+static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
+{
+	struct unimapdesc32 tmp;
+	int perm = vt_check(file);
+	
+	if (perm < 0) return perm;
+	if (copy_from_user(&tmp, user_ud, sizeof tmp))
+		return -EFAULT;
+	switch (cmd) {
+	case PIO_UNIMAP:
+		if (!perm) return -EPERM;
+		return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
+	case GIO_UNIMAP:
+		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
+	}
+	return 0;
+}
+#endif
+
+#if 0
+static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	__kernel_uid_t kuid;
+	int err;
+
+	cmd = SMB_IOC_GETMOUNTUID;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+	set_fs(old_fs);
+
+	if (err >= 0)
+		err = put_user(kuid, (__kernel_uid_t32 *)arg);
+
+	return err;
+}
+#endif
+
+struct atmif_sioc32 {
+        int                number;
+        int                length;
+        __kernel_caddr_t32 arg;
+};
+
+struct atm_iobuf32 {
+	int                length;
+	__kernel_caddr_t32 buffer;
+};
+
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
+#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
+#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
+#define ATM_GETESI32	  _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
+#define ATM_GETADDR32	  _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
+#define ATM_RSTADDR32	  _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
+#define ATM_ADDADDR32	  _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
+#define ATM_DELADDR32	  _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
+#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
+#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
+#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
+#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
+#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
+#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
+#define ATM_GETLOOP32	  _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
+#define ATM_SETLOOP32	  _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32	  _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
+
+static struct {
+        unsigned int cmd32;
+        unsigned int cmd;
+} atm_ioctl_map[] = {
+        { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+	{ ATM_GETNAMES32,    ATM_GETNAMES },
+        { ATM_GETTYPE32,     ATM_GETTYPE },
+        { ATM_GETESI32,      ATM_GETESI },
+        { ATM_GETADDR32,     ATM_GETADDR },
+        { ATM_RSTADDR32,     ATM_RSTADDR },
+        { ATM_ADDADDR32,     ATM_ADDADDR },
+        { ATM_DELADDR32,     ATM_DELADDR },
+        { ATM_GETCIRANGE32,  ATM_GETCIRANGE },
+	{ ATM_SETCIRANGE32,  ATM_SETCIRANGE },
+	{ ATM_SETESI32,      ATM_SETESI },
+	{ ATM_SETESIF32,     ATM_SETESIF },
+	{ ATM_GETSTAT32,     ATM_GETSTAT },
+	{ ATM_GETSTATZ32,    ATM_GETSTATZ },
+	{ ATM_GETLOOP32,     ATM_GETLOOP },
+	{ ATM_SETLOOP32,     ATM_SETLOOP },
+	{ ATM_QUERYLOOP32,   ATM_QUERYLOOP }
+};
+
+#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
+
+
+static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct atm_iobuf32 iobuf32;
+	struct atm_iobuf   iobuf = { 0, NULL };
+	mm_segment_t old_fs;
+	int err;
+
+	err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg,
+	    sizeof(struct atm_iobuf32));
+	if (err)
+		return -EFAULT;
+
+	iobuf.length = iobuf32.length;
+
+	if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
+		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
+	} else {
+		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
+		if (iobuf.buffer == NULL) {
+			err = -ENOMEM;
+			goto out;
+		}
+
+		err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);      
+	set_fs (old_fs);
+        if(err)
+		goto out;
+
+        if(iobuf.buffer && iobuf.length > 0) {
+		err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length);
+		if (err) {
+			err = -EFAULT;
+			goto out;
+		}
+	}
+	err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
+
+ out:
+        if(iobuf32.buffer && iobuf32.length > 0)
+		kfree(iobuf.buffer);
+
+	return err;
+}
+
+
+static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+        struct atmif_sioc32 sioc32;
+        struct atmif_sioc   sioc = { 0, 0, NULL };
+        mm_segment_t old_fs;
+        int err;
+        
+        err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg,
+			     sizeof(struct atmif_sioc32));
+        if (err)
+                return -EFAULT;
+
+        sioc.number = sioc32.number;
+        sioc.length = sioc32.length;
+        
+	if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
+		sioc.arg = (void*)(unsigned long)sioc32.arg;
+        } else {
+                sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
+                if (sioc.arg == NULL) {
+                        err = -ENOMEM;
+			goto out;
+		}
+                
+                err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)&sioc);	
+        set_fs (old_fs);
+        if(err) {
+                goto out;
+	}
+        
+        if(sioc.arg && sioc.length > 0) {
+                err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length);
+                if (err) {
+                        err = -EFAULT;
+                        goto out;
+                }
+        }
+        err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
+        
+ out:
+        if(sioc32.arg && sioc32.length > 0)
+		kfree(sioc.arg);
+        
+	return err;
+}
+
+
+static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+{
+        int i;
+        unsigned int cmd = 0;
+        
+	switch (cmd32) {
+	case SONET_GETSTAT:
+	case SONET_GETSTATZ:
+	case SONET_GETDIAG:
+	case SONET_SETDIAG:
+	case SONET_CLRDIAG:
+	case SONET_SETFRAMING:
+	case SONET_GETFRAMING:
+	case SONET_GETFRSENSE:
+		return do_atmif_sioc(fd, cmd32, arg);
+	}
+
+		for (i = 0; i < NR_ATM_IOCTL; i++) {
+			if (cmd32 == atm_ioctl_map[i].cmd32) {
+				cmd = atm_ioctl_map[i].cmd;
+				break;
+			}
+		}
+	        if (i == NR_ATM_IOCTL) {
+	        return -EINVAL;
+	        }
+        
+        switch (cmd) {
+	case ATM_GETNAMES:
+		return do_atm_iobuf(fd, cmd, arg);
+	    
+	case ATM_GETLINKRATE:
+        case ATM_GETTYPE:
+        case ATM_GETESI:
+        case ATM_GETADDR:
+        case ATM_RSTADDR:
+        case ATM_ADDADDR:
+        case ATM_DELADDR:
+        case ATM_GETCIRANGE:
+	case ATM_SETCIRANGE:
+	case ATM_SETESI:
+	case ATM_SETESIF:
+	case ATM_GETSTAT:
+	case ATM_GETSTATZ:
+	case ATM_GETLOOP:
+	case ATM_SETLOOP:
+	case ATM_QUERYLOOP:
+                return do_atmif_sioc(fd, cmd, arg);
+        }
+
+        return -EINVAL;
+}
+
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
+typedef struct {
+	uint8_t vg_name[NAME_LEN];
+	uint32_t vg_number;
+	uint32_t vg_access;
+	uint32_t vg_status;
+	uint32_t lv_max;
+	uint32_t lv_cur;
+	uint32_t lv_open;
+	uint32_t pv_max;
+	uint32_t pv_cur;
+	uint32_t pv_act;
+	uint32_t dummy;
+	uint32_t vgda;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pvg_total;
+	u32 proc;
+	u32 pv[ABS_MAX_PV + 1];
+	u32 lv[ABS_MAX_LV + 1];
+    	uint8_t vg_uuid[UUID_LEN+1];	/* volume group UUID */
+	uint8_t dummy1[200];
+} vg32_t;
+
+typedef struct {
+	uint8_t id[2];
+	uint16_t version;
+	lvm_disk_data_t pv_on_disk;
+	lvm_disk_data_t vg_on_disk;
+	lvm_disk_data_t pv_namelist_on_disk;
+	lvm_disk_data_t lv_on_disk;
+	lvm_disk_data_t pe_on_disk;
+	uint8_t pv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint8_t system_id[NAME_LEN];
+	kdev_t pv_dev;
+	uint32_t pv_number;
+	uint32_t pv_status;
+	uint32_t pv_allocatable;
+	uint32_t pv_size;
+	uint32_t lv_cur;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pe_stale;
+	u32 pe;
+	u32 inode;
+	uint8_t pv_uuid[UUID_LEN+1];
+} pv32_t;
+
+typedef struct {
+	char lv_name[NAME_LEN];
+	u32 lv;
+} lv_req32_t;
+
+typedef struct {
+	u32 lv_index;
+	u32 lv;
+	/* Transfer size because user space and kernel space differ */
+	uint16_t size;
+} lv_status_byindex_req32_t;
+
+typedef struct {
+	__kernel_dev_t32 dev;
+	u32   lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	kdev_t old_dev;
+	kdev_t new_dev;
+	u32 old_pe;
+	u32 new_pe;
+} le_remap_req32_t;
+
+typedef struct {
+	char pv_name[NAME_LEN];
+	u32 pv;
+} pv_status_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint32_t lv_access;
+	uint32_t lv_status;
+	uint32_t lv_open;
+	kdev_t lv_dev;
+	uint32_t lv_number;
+	uint32_t lv_mirror_copies;
+	uint32_t lv_recovery;
+	uint32_t lv_schedule;
+	uint32_t lv_size;
+	u32 lv_current_pe;
+	uint32_t lv_current_le;
+	uint32_t lv_allocated_le;
+	uint32_t lv_stripes;
+	uint32_t lv_stripesize;
+	uint32_t lv_badblock;
+	uint32_t lv_allocation;
+	uint32_t lv_io_timeout;
+	uint32_t lv_read_ahead;
+	/* delta to version 1 starts here */
+	u32 lv_snapshot_org;
+	u32 lv_snapshot_prev;
+	u32 lv_snapshot_next;
+	u32 lv_block_exception;
+	uint32_t lv_remap_ptr;
+	uint32_t lv_remap_end;
+	uint32_t lv_chunk_size;
+	uint32_t lv_snapshot_minor;
+	char dummy[200];
+} lv32_t;
+
+typedef struct {
+	u32 hash[2];
+	u32 rsector_org;
+	kdev_t rdev_org;
+	u32 rsector_new;
+	kdev_t rdev_new;
+} lv_block_exception32_t;
+
+static void put_lv_t(lv_t *l)
+{
+	if (l->lv_current_pe) vfree(l->lv_current_pe);
+	if (l->lv_block_exception) vfree(l->lv_block_exception);
+	kfree(l);
+}
+
+static lv_t *get_lv_t(u32 p, int *errp)
+{
+	int err, i;
+	u32 ptr1, ptr2;
+	size_t size;
+	lv_block_exception32_t *lbe32;
+	lv_block_exception_t *lbe;
+	lv32_t *ul = (lv32_t *)A(p);
+	lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
+	if (!l) {
+		*errp = -ENOMEM;
+		return NULL;
+	}
+	memset(l, 0, sizeof(lv_t));
+	err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	err |= __get_user(ptr1, &ul->lv_current_pe);
+	err |= __get_user(ptr2, &ul->lv_block_exception);
+	if (err) {
+		kfree(l);
+		*errp = -EFAULT;
+		return NULL;
+	}
+	if (ptr1) {
+		size = l->lv_allocated_le * sizeof(pe_t);
+		l->lv_current_pe = vmalloc(size);
+		if (l->lv_current_pe)
+			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
+	}
+	if (!err && ptr2) {
+		size = l->lv_remap_end * sizeof(lv_block_exception_t);
+		l->lv_block_exception = lbe = vmalloc(size);
+		if (l->lv_block_exception) {
+			lbe32 = (lv_block_exception32_t *)A(ptr2);
+			memset(lbe, 0, size);
+			for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
+				err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
+				err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
+				err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
+				err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+			}
+		}
+	}
+	if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
+		if (!err)
+			*errp = -ENOMEM;
+		else
+			*errp = -EFAULT;
+		put_lv_t(l);
+		return NULL;
+	}
+	return l;
+}
+
+static int copy_lv_t(u32 ptr, lv_t *l)
+{
+	int err;
+	lv32_t *ul = (lv32_t *)A(ptr);
+	u32 ptr1;
+	size_t size;
+
+	err = get_user(ptr1, &ul->lv_current_pe);
+	if (err)
+		return -EFAULT;
+	err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	size = l->lv_allocated_le * sizeof(pe_t);
+	if (ptr1)
+		err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+	return err ? -EFAULT : 0;
+}
+
+static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	vg_t *v = NULL;
+	union {
+		lv_req_t lv_req;
+		le_remap_req_t le_remap;
+		lv_status_byindex_req_t lv_byindex;
+	        lv_status_bydev_req_t lv_bydev;
+		pv_status_req_t pv_status;
+	} u;
+	pv_t p;
+	int err;
+	u32 ptr = 0;
+	int i;
+	mm_segment_t old_fs;
+	void *karg = &u;
+
+	switch (cmd) {
+	case VG_STATUS:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		karg = v;
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		/* 'proc' field is unused, just NULL it out. */
+		v->proc = NULL;
+		if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		    
+		karg = v;
+		memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
+		if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
+			return -EPERM;
+		for (i = 0; i < v->pv_max; i++) {
+			err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
+			if (err)
+				break;
+			if (ptr) {
+				v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
+				if (!v->pv[i]) {
+					err = -ENOMEM;
+					break;
+				}
+				err = copy_from_user(v->pv[i], (void *)A(ptr),
+						     sizeof(pv32_t) - 8 - UUID_LEN+1);
+				if (err) {
+					err = -EFAULT;
+					break;
+				}
+				err = copy_from_user(v->pv[i]->pv_uuid,
+						     ((pv32_t *)A(ptr))->pv_uuid,
+						     UUID_LEN+1);
+				if (err) {
+				        err = -EFAULT;
+					break;
+				}
+
+				v->pv[i]->pe = NULL;
+				v->pv[i]->bd = NULL;
+			}
+		}
+		if (!err) {
+			for (i = 0; i < v->lv_max; i++) {
+				err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
+				if (err)
+					break;
+				if (ptr) {
+					v->lv[i] = get_lv_t(ptr, &err);
+					if (err)
+						break;
+				}
+			}
+		}
+		break;
+
+	case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+	case LV_REMOVE:
+	case LV_RENAME:
+	case LV_STATUS_BYNAME:
+	        err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+		if (err)
+			return -EFAULT;
+		if (cmd != LV_REMOVE) {
+			err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
+			if (err)
+				return err;
+			u.lv_req.lv = get_lv_t(ptr, &err);
+		} else
+			u.lv_req.lv = NULL;
+		break;
+
+	case LV_STATUS_BYINDEX:
+		err = get_user(u.lv_byindex.lv_index,
+			       &((lv_status_byindex_req32_t *)arg)->lv_index);
+		err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_byindex.lv = get_lv_t(ptr, &err);
+		break;
+
+	case LV_STATUS_BYDEV:
+	        err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+		err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_bydev.lv = get_lv_t(ptr, &err);
+		break;
+
+	case VG_EXTEND:
+		err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		p.pe = NULL;
+		p.bd = NULL;
+		karg = &p;
+		break;
+
+	case PV_CHANGE:
+	case PV_STATUS:
+		err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
+		if (err)
+			return -EFAULT;
+		err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
+		if (err)
+			return err;
+		u.pv_status.pv = &p;
+		if (cmd == PV_CHANGE) {
+			err = copy_from_user(&p, (void *)A(ptr),
+					     sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			p.pe = NULL;
+			p.bd = NULL;
+		}
+		break;
+	};
+
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)karg);
+        set_fs (old_fs);
+
+	switch (cmd) {
+	case VG_STATUS:
+		if (!err) {
+			if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
+			    clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
+				err = -EFAULT;
+		}
+		if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+		        err = -EFAULT;
+		}
+		kfree(v);
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		for (i = 0; i < v->pv_max; i++) {
+			if (v->pv[i])
+				kfree(v->pv[i]);
+		}
+		for (i = 0; i < v->lv_max; i++) {
+			if (v->lv[i])
+				put_lv_t(v->lv[i]);
+		}
+		kfree(v);
+		break;
+
+	case LV_STATUS_BYNAME:
+		if (!err && u.lv_req.lv)
+			err = copy_lv_t(ptr, u.lv_req.lv);
+		/* Fall through */
+
+        case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+		if (u.lv_req.lv)
+			put_lv_t(u.lv_req.lv);
+		break;
+
+	case LV_STATUS_BYINDEX:
+		if (u.lv_byindex.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_byindex.lv);
+			put_lv_t(u.lv_byindex.lv);
+		}
+		break;
+
+	case LV_STATUS_BYDEV:
+	        if (u.lv_bydev.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_bydev.lv);
+			put_lv_t(u.lv_byindex.lv);
+	        }
+	        break;
+
+	case PV_STATUS:
+		if (!err) {
+			err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+			if (err)
+				return -EFAULT;
+		}
+		break;
+	};
+
+	return err;
+}
+#endif
+
+#ifdef CONFIG_GENRTC
+#endif
+
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+/* This really belongs in include/linux/drm.h -DaveM */
+#include "../../../drivers/char/drm/drm.h"
+
+typedef struct drm32_version {
+	int    version_major;	  /* Major version			    */
+	int    version_minor;	  /* Minor version			    */
+	int    version_patchlevel;/* Patch level			    */
+	int    name_len;	  /* Length of name buffer		    */
+	u32    name;		  /* Name of driver			    */
+	int    date_len;	  /* Length of date buffer		    */
+	u32    date;		  /* User-space buffer to hold date	    */
+	int    desc_len;	  /* Length of desc buffer		    */
+	u32    desc;		  /* User-space buffer to hold desc	    */
+} drm32_version_t;
+#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
+
+static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_version_t *uversion = (drm32_version_t *)arg;
+	char *name_ptr, *date_ptr, *desc_ptr;
+	u32 tmp1, tmp2, tmp3;
+	drm_version_t kversion;
+	mm_segment_t old_fs;
+	int ret;
+
+	memset(&kversion, 0, sizeof(kversion));
+	if (get_user(kversion.name_len, &uversion->name_len) ||
+	    get_user(kversion.date_len, &uversion->date_len) ||
+	    get_user(kversion.desc_len, &uversion->desc_len) ||
+	    get_user(tmp1, &uversion->name) ||
+	    get_user(tmp2, &uversion->date) ||
+	    get_user(tmp3, &uversion->desc))
+		return -EFAULT;
+
+	name_ptr = (char *) A(tmp1);
+	date_ptr = (char *) A(tmp2);
+	desc_ptr = (char *) A(tmp3);
+
+	ret = -ENOMEM;
+	if (kversion.name_len && name_ptr) {
+		kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
+		if (!kversion.name)
+			goto out;
+	}
+	if (kversion.date_len && date_ptr) {
+		kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
+		if (!kversion.date)
+			goto out;
+	}
+	if (kversion.desc_len && desc_ptr) {
+		kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
+		if (!kversion.desc)
+			goto out;
+	}
+
+        old_fs = get_fs();
+	set_fs(KERNEL_DS);
+        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if ((kversion.name &&
+		     copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
+		    (kversion.date &&
+		     copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
+		    (kversion.desc &&
+		     copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
+			ret = -EFAULT;
+		if (put_user(kversion.version_major, &uversion->version_major) ||
+		    put_user(kversion.version_minor, &uversion->version_minor) ||
+		    put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
+		    put_user(kversion.name_len, &uversion->name_len) ||
+		    put_user(kversion.date_len, &uversion->date_len) ||
+		    put_user(kversion.desc_len, &uversion->desc_len))
+			ret = -EFAULT;
+	}
+
+out:
+	if (kversion.name)
+		kfree(kversion.name);
+	if (kversion.date)
+		kfree(kversion.date);
+	if (kversion.desc)
+		kfree(kversion.desc);
+	return ret;
+}
+
+typedef struct drm32_unique {
+	int	unique_len;	  /* Length of unique			    */
+	u32	unique;		  /* Unique name for driver instantiation   */
+} drm32_unique_t;
+#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
+#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
+
+static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_unique_t *uarg = (drm32_unique_t *)arg;
+	drm_unique_t karg;
+	mm_segment_t old_fs;
+	char *uptr;
+	u32 tmp;
+	int ret;
+
+	if (get_user(karg.unique_len, &uarg->unique_len))
+		return -EFAULT;
+	karg.unique = NULL;
+
+	if (get_user(tmp, &uarg->unique))
+		return -EFAULT;
+
+	uptr = (char *) A(tmp);
+
+	if (uptr) {
+		karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
+		if (!karg.unique)
+			return -ENOMEM;
+		if (cmd == DRM32_IOCTL_SET_UNIQUE &&
+		    copy_from_user(karg.unique, uptr, karg.unique_len)) {
+			kfree(karg.unique);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	if (cmd == DRM32_IOCTL_GET_UNIQUE)
+		ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
+	else
+		ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
+        set_fs(old_fs);
+
+	if (!ret) {
+		if (cmd == DRM32_IOCTL_GET_UNIQUE &&
+		    uptr != NULL &&
+		    copy_to_user(uptr, karg.unique, karg.unique_len))
+			ret = -EFAULT;
+		if (put_user(karg.unique_len, &uarg->unique_len))
+			ret = -EFAULT;
+	}
+
+	if (karg.unique != NULL)
+		kfree(karg.unique);
+
+	return ret;
+}
+
+typedef struct drm32_map {
+	u32		offset;	 /* Requested physical address (0 for SAREA)*/
+	u32		size;	 /* Requested physical size (bytes)	    */
+	drm_map_type_t	type;	 /* Type of memory to map		    */
+	drm_map_flags_t flags;	 /* Flags				    */
+	u32		handle;  /* User-space: "Handle" to pass to mmap    */
+				 /* Kernel-space: kernel-virtual address    */
+	int		mtrr;	 /* MTRR slot used			    */
+				 /* Private data			    */
+} drm32_map_t;
+#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
+
+static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_map_t *uarg = (drm32_map_t *) arg;
+	drm_map_t karg;
+	mm_segment_t old_fs;
+	u32 tmp;
+	int ret;
+
+	ret  = get_user(karg.offset, &uarg->offset);
+	ret |= get_user(karg.size, &uarg->size);
+	ret |= get_user(karg.type, &uarg->type);
+	ret |= get_user(karg.flags, &uarg->flags);
+	ret |= get_user(tmp, &uarg->handle);
+	ret |= get_user(karg.mtrr, &uarg->mtrr);
+	if (ret)
+		return -EFAULT;
+
+	karg.handle = (void *) A(tmp);
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		ret  = put_user(karg.offset, &uarg->offset);
+		ret |= put_user(karg.size, &uarg->size);
+		ret |= put_user(karg.type, &uarg->type);
+		ret |= put_user(karg.flags, &uarg->flags);
+		tmp = (u32) (long)karg.handle;
+		ret |= put_user(tmp, &uarg->handle);
+		ret |= put_user(karg.mtrr, &uarg->mtrr);
+		if (ret)
+			ret = -EFAULT;
+	}
+
+	return ret;
+}
+
+typedef struct drm32_buf_info {
+	int	       count;	/* Entries in list			     */
+	u32	       list;    /* (drm_buf_desc_t *) */ 
+} drm32_buf_info_t;
+#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
+
+static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
+	drm_buf_desc_t *ulist;
+	drm_buf_info_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (drm_buf_desc_t *) A(tmp);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
+	if (!karg.list)
+		return -EFAULT;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (karg.count <= orig_count &&
+		    (copy_to_user(ulist, karg.list,
+				  karg.count * sizeof(drm_buf_desc_t))))
+			ret = -EFAULT;
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_free {
+	int	       count;
+	u32	       list;	/* (int *) */
+} drm32_buf_free_t;
+#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
+
+static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
+	drm_buf_free_t karg;
+	mm_segment_t old_fs;
+	int *ulist;
+	int ret;
+	u32 tmp;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->list))
+		return -EFAULT;
+
+	ulist = (int *) A(tmp);
+
+	karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
+		goto out;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+out:
+	kfree(karg.list);
+
+	return ret;
+}
+
+typedef struct drm32_buf_pub {
+	int		  idx;	       /* Index into master buflist	     */
+	int		  total;       /* Buffer size			     */
+	int		  used;	       /* Amount of buffer in use (for DMA)  */
+	u32		  address;     /* Address of buffer (void *)	     */
+} drm32_buf_pub_t;
+
+typedef struct drm32_buf_map {
+	int	      count;	/* Length of buflist			    */
+	u32	      virtual;	/* Mmaped area in user-virtual (void *)	    */
+	u32 	      list;	/* Buffer information (drm_buf_pub_t *)	    */
+} drm32_buf_map_t;
+#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
+
+static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
+	drm32_buf_pub_t *ulist;
+	drm_buf_map_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret, i;
+	u32 tmp1, tmp2;
+
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp1, &uarg->virtual) ||
+	    get_user(tmp2, &uarg->list))
+		return -EFAULT;
+
+	karg.virtual = (void *) A(tmp1);
+	ulist = (drm32_buf_pub_t *) A(tmp2);
+
+	orig_count = karg.count;
+
+	karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
+	if (!karg.list)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	for (i = 0; i < karg.count; i++) {
+		if (get_user(karg.list[i].idx, &ulist[i].idx) ||
+		    get_user(karg.list[i].total, &ulist[i].total) ||
+		    get_user(karg.list[i].used, &ulist[i].used) ||
+		    get_user(tmp1, &ulist[i].address))
+			goto out;
+
+		karg.list[i].address = (void *) A(tmp1);
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		for (i = 0; i < orig_count; i++) {
+			tmp1 = (u32) (long) karg.list[i].address;
+			if (put_user(karg.list[i].idx, &ulist[i].idx) ||
+			    put_user(karg.list[i].total, &ulist[i].total) ||
+			    put_user(karg.list[i].used, &ulist[i].used) ||
+			    put_user(tmp1, &ulist[i].address)) {
+				ret = -EFAULT;
+				goto out;
+			}
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+out:
+	kfree(karg.list);
+	return ret;
+}
+
+typedef struct drm32_dma {
+				/* Indices here refer to the offset into
+				   buflist in drm_buf_get_t.  */
+	int		context;	  /* Context handle		    */
+	int		send_count;	  /* Number of buffers to send	    */
+	u32		send_indices;	  /* List of handles to buffers (int *) */
+	u32		send_sizes;	  /* Lengths of data to send (int *) */
+	drm_dma_flags_t flags;		  /* Flags			    */
+	int		request_count;	  /* Number of buffers requested    */
+	int		request_size;	  /* Desired size for buffers	    */
+	u32		request_indices;  /* Buffer information (int *)	    */
+	u32		request_sizes;    /* (int *) */
+	int		granted_count;	  /* Number of buffers granted	    */
+} drm32_dma_t;
+#define DRM32_IOCTL_DMA	     DRM_IOWR(0x29, drm32_dma_t)
+
+/* RED PEN	The DRM layer blindly dereferences the send/request
+ * 		indice/size arrays even though they are userland
+ * 		pointers.  -DaveM
+ */
+static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_dma_t *uarg = (drm32_dma_t *) arg;
+	int *u_si, *u_ss, *u_ri, *u_rs;
+	drm_dma_t karg;
+	mm_segment_t old_fs;
+	int ret;
+	u32 tmp1, tmp2, tmp3, tmp4;
+
+	karg.send_indices = karg.send_sizes = NULL;
+	karg.request_indices = karg.request_sizes = NULL;
+
+	if (get_user(karg.context, &uarg->context) ||
+	    get_user(karg.send_count, &uarg->send_count) ||
+	    get_user(tmp1, &uarg->send_indices) ||
+	    get_user(tmp2, &uarg->send_sizes) ||
+	    get_user(karg.flags, &uarg->flags) ||
+	    get_user(karg.request_count, &uarg->request_count) ||
+	    get_user(karg.request_size, &uarg->request_size) ||
+	    get_user(tmp3, &uarg->request_indices) ||
+	    get_user(tmp4, &uarg->request_sizes) ||
+	    get_user(karg.granted_count, &uarg->granted_count))
+		return -EFAULT;
+
+	u_si = (int *) A(tmp1);
+	u_ss = (int *) A(tmp2);
+	u_ri = (int *) A(tmp3);
+	u_rs = (int *) A(tmp4);
+
+	if (karg.send_count) {
+		karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+		karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.send_indices || !karg.send_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.send_indices, u_si,
+				   (karg.send_count * sizeof(int))) ||
+		    copy_from_user(karg.send_sizes, u_ss,
+				   (karg.send_count * sizeof(int))))
+			goto out;
+	}
+
+	if (karg.request_count) {
+		karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+		karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
+
+		ret = -ENOMEM;
+		if (!karg.request_indices || !karg.request_sizes)
+			goto out;
+
+		ret = -EFAULT;
+		if (copy_from_user(karg.request_indices, u_ri,
+				   (karg.request_count * sizeof(int))) ||
+		    copy_from_user(karg.request_sizes, u_rs,
+				   (karg.request_count * sizeof(int))))
+			goto out;
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (put_user(karg.context, &uarg->context) ||
+		    put_user(karg.send_count, &uarg->send_count) ||
+		    put_user(karg.flags, &uarg->flags) ||
+		    put_user(karg.request_count, &uarg->request_count) ||
+		    put_user(karg.request_size, &uarg->request_size) ||
+		    put_user(karg.granted_count, &uarg->granted_count))
+			ret = -EFAULT;
+
+		if (karg.send_count) {
+			if (copy_to_user(u_si, karg.send_indices,
+					 (karg.send_count * sizeof(int))) ||
+			    copy_to_user(u_ss, karg.send_sizes,
+					 (karg.send_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+		if (karg.request_count) {
+			if (copy_to_user(u_ri, karg.request_indices,
+					 (karg.request_count * sizeof(int))) ||
+			    copy_to_user(u_rs, karg.request_sizes,
+					 (karg.request_count * sizeof(int))))
+				ret = -EFAULT;
+		}
+	}
+
+out:
+	if (karg.send_indices)
+		kfree(karg.send_indices);
+	if (karg.send_sizes)
+		kfree(karg.send_sizes);
+	if (karg.request_indices)
+		kfree(karg.request_indices);
+	if (karg.request_sizes)
+		kfree(karg.request_sizes);
+
+	return ret;
+}
+
+typedef struct drm32_ctx_res {
+	int		count;
+	u32		contexts; /* (drm_ctx_t *) */
+} drm32_ctx_res_t;
+#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
+
+static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
+	drm_ctx_t *ulist;
+	drm_ctx_res_t karg;
+	mm_segment_t old_fs;
+	int orig_count, ret;
+	u32 tmp;
+
+	karg.contexts = NULL;
+	if (get_user(karg.count, &uarg->count) ||
+	    get_user(tmp, &uarg->contexts))
+		return -EFAULT;
+
+	ulist = (drm_ctx_t *) A(tmp);
+
+	orig_count = karg.count;
+	if (karg.count && ulist) {
+		karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
+		if (!karg.contexts)
+			return -ENOMEM;
+		if (copy_from_user(karg.contexts, ulist,
+				   (karg.count * sizeof(drm_ctx_t)))) {
+			kfree(karg.contexts);
+			return -EFAULT;
+		}
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
+	set_fs(old_fs);
+
+	if (!ret) {
+		if (orig_count) {
+			if (copy_to_user(ulist, karg.contexts,
+					 (orig_count * sizeof(drm_ctx_t))))
+				ret = -EFAULT;
+		}
+		if (put_user(karg.count, &uarg->count))
+			ret = -EFAULT;
+	}
+
+	if (karg.contexts)
+		kfree(karg.contexts);
+
+	return ret;
+}
+
+#endif
+
+static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* The mkswap binary hard codes it to Intel value :-((( */
+	return w_long(fd, BLKGETSIZE, arg);
+}
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+                                
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
+	return err;
+}
+
+static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
+}
+
+
+struct serial_struct32 {
+	int	type;
+	int	line;
+	unsigned int	port;
+	int	irq;
+	int	flags;
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	baud_base;
+	unsigned short	close_delay;
+	char	io_type;
+	char	reserved_char[1];
+	int	hub6;
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned short	closing_wait2; /* no longer used... */
+	unsigned int	iomem_base;	/* char * really */
+	unsigned short	iomem_reg_shift;
+	unsigned int	port_high;
+	int	reserved[1];
+};
+
+static int do_tiocgserial(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct serial_struct ss;
+	int ret;
+	struct serial_struct32 * uptr = (struct serial_struct32 *)arg;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs (KERNEL_DS);
+	ret = sys_ioctl(fd, cmd, (unsigned long) &ss);
+	set_fs(old_fs);
+
+	if (!ret) {
+		/* structs match up to iomem_base */
+		ret = copy_to_user(uptr, &ss, sizeof(struct serial_struct32));
+		ret |= put_user(ss.iomem_base, &uptr->iomem_base);
+		ret |= put_user(ss.iomem_reg_shift, &uptr->iomem_reg_shift);
+		ret |= put_user(ss.port_high, &uptr->port_high);
+		if (ret)
+			ret = -EFAULT;
+	}
+	return ret;
+}
+
+
+struct ioctl_trans {
+	unsigned long handler;
+	unsigned int cmd;
+	unsigned int next;
+};
+#define HANDLE_IOCTL(cmd, handler) asm volatile(".dword %1\n.word %0, 0" : : "i" (cmd), "i" (handler));
+
+#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
+
+
+#define IOCTL_TABLE_START void ioctl32_foo(void) { asm volatile(".data\nioctl_translations:");
+#define IOCTL_TABLE_END asm volatile("\nioctl_translations_end:\n\t.previous"); }
+
+IOCTL_TABLE_START
+/* List here exlicitly which ioctl's are known to have
+ * compatable types passed or none at all...
+ */
+/* Big T */
+COMPATIBLE_IOCTL(TCGETA)
+COMPATIBLE_IOCTL(TCSETA)
+COMPATIBLE_IOCTL(TCSETAW)
+COMPATIBLE_IOCTL(TCSETAF)
+COMPATIBLE_IOCTL(TCSBRK)
+COMPATIBLE_IOCTL(TCXONC)
+COMPATIBLE_IOCTL(TCFLSH)
+COMPATIBLE_IOCTL(TCGETS)
+COMPATIBLE_IOCTL(TCSETS)
+COMPATIBLE_IOCTL(TCSETSW)
+COMPATIBLE_IOCTL(TCSETSF)
+COMPATIBLE_IOCTL(TIOCLINUX)
+/* Little t */
+COMPATIBLE_IOCTL(TIOCGETD)
+COMPATIBLE_IOCTL(TIOCSETD)
+COMPATIBLE_IOCTL(TIOCEXCL)
+COMPATIBLE_IOCTL(TIOCNXCL)
+COMPATIBLE_IOCTL(TIOCCONS)
+COMPATIBLE_IOCTL(TIOCGSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSWINSZ)
+COMPATIBLE_IOCTL(TIOCGWINSZ)
+COMPATIBLE_IOCTL(TIOCMGET)
+COMPATIBLE_IOCTL(TIOCMBIC)
+COMPATIBLE_IOCTL(TIOCMBIS)
+COMPATIBLE_IOCTL(TIOCMSET)
+COMPATIBLE_IOCTL(TIOCPKT)
+COMPATIBLE_IOCTL(TIOCNOTTY)
+COMPATIBLE_IOCTL(TIOCSTI)
+COMPATIBLE_IOCTL(TIOCOUTQ)
+COMPATIBLE_IOCTL(TIOCSPGRP)
+COMPATIBLE_IOCTL(TIOCGPGRP)
+COMPATIBLE_IOCTL(TIOCSCTTY)
+COMPATIBLE_IOCTL(TIOCGPTN)
+COMPATIBLE_IOCTL(TIOCSPTLCK)
+COMPATIBLE_IOCTL(TIOCSSERIAL)
+COMPATIBLE_IOCTL(TIOCSERGETLSR)
+/* Big F */
+#if 0
+COMPATIBLE_IOCTL(FBIOGTYPE)
+COMPATIBLE_IOCTL(FBIOSATTR)
+COMPATIBLE_IOCTL(FBIOGATTR)
+COMPATIBLE_IOCTL(FBIOSVIDEO)
+COMPATIBLE_IOCTL(FBIOGVIDEO)
+COMPATIBLE_IOCTL(FBIOGCURSOR32)  /* This is not implemented yet. Later it should be converted... */
+COMPATIBLE_IOCTL(FBIOSCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURMAX)
+#endif
+COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
+COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
+
+COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
+COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO)
+COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO)
+COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO)
+COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE)
+COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE)
+COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
+COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
+/* Little f */
+COMPATIBLE_IOCTL(FIOCLEX)
+COMPATIBLE_IOCTL(FIONCLEX)
+COMPATIBLE_IOCTL(FIOASYNC)
+COMPATIBLE_IOCTL(FIONBIO)
+COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
+/* 0x00 */
+COMPATIBLE_IOCTL(FIBMAP)
+COMPATIBLE_IOCTL(FIGETBSZ)
+/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
+ *         Some need translations, these do not.
+ */
+COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
+COMPATIBLE_IOCTL(HDIO_SET_DMA)
+COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
+COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
+COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
+COMPATIBLE_IOCTL(HDIO_SET_32BIT)
+COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
+COMPATIBLE_IOCTL(HDIO_SET_NICE)
+/* 0x02 -- Floppy ioctls */
+COMPATIBLE_IOCTL(FDMSGON)
+COMPATIBLE_IOCTL(FDMSGOFF)
+COMPATIBLE_IOCTL(FDSETEMSGTRESH)
+COMPATIBLE_IOCTL(FDFLUSH)
+COMPATIBLE_IOCTL(FDWERRORCLR)
+COMPATIBLE_IOCTL(FDSETMAXERRS)
+COMPATIBLE_IOCTL(FDGETMAXERRS)
+COMPATIBLE_IOCTL(FDGETDRVTYP)
+COMPATIBLE_IOCTL(FDEJECT)
+COMPATIBLE_IOCTL(FDCLRPRM)
+COMPATIBLE_IOCTL(FDFMTBEG)
+COMPATIBLE_IOCTL(FDFMTEND)
+COMPATIBLE_IOCTL(FDRESET)
+COMPATIBLE_IOCTL(FDTWADDLE)
+COMPATIBLE_IOCTL(FDFMTTRK)
+COMPATIBLE_IOCTL(FDRAWCMD)
+/* 0x12 */
+COMPATIBLE_IOCTL(BLKROSET)
+COMPATIBLE_IOCTL(BLKROGET)
+COMPATIBLE_IOCTL(BLKRRPART)
+COMPATIBLE_IOCTL(BLKFLSBUF)
+COMPATIBLE_IOCTL(BLKRASET)
+COMPATIBLE_IOCTL(BLKFRASET)
+COMPATIBLE_IOCTL(BLKSECTSET)
+COMPATIBLE_IOCTL(BLKSSZGET)
+
+/* RAID */
+COMPATIBLE_IOCTL(RAID_VERSION)
+COMPATIBLE_IOCTL(GET_ARRAY_INFO)
+COMPATIBLE_IOCTL(GET_DISK_INFO)
+COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
+COMPATIBLE_IOCTL(CLEAR_ARRAY)
+COMPATIBLE_IOCTL(ADD_NEW_DISK)
+COMPATIBLE_IOCTL(HOT_REMOVE_DISK)
+COMPATIBLE_IOCTL(SET_ARRAY_INFO)
+COMPATIBLE_IOCTL(SET_DISK_INFO)
+COMPATIBLE_IOCTL(WRITE_RAID_INFO)
+COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
+COMPATIBLE_IOCTL(PROTECT_ARRAY)
+COMPATIBLE_IOCTL(HOT_ADD_DISK)
+COMPATIBLE_IOCTL(SET_DISK_FAULTY)
+COMPATIBLE_IOCTL(RUN_ARRAY)
+COMPATIBLE_IOCTL(START_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY_RO)
+COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+
+/* Big K */
+COMPATIBLE_IOCTL(PIO_FONT)
+COMPATIBLE_IOCTL(GIO_FONT)
+COMPATIBLE_IOCTL(KDSIGACCEPT)
+COMPATIBLE_IOCTL(KDGETKEYCODE)
+COMPATIBLE_IOCTL(KDSETKEYCODE)
+COMPATIBLE_IOCTL(KIOCSOUND)
+COMPATIBLE_IOCTL(KDMKTONE)
+COMPATIBLE_IOCTL(KDGKBTYPE)
+COMPATIBLE_IOCTL(KDSETMODE)
+COMPATIBLE_IOCTL(KDGETMODE)
+COMPATIBLE_IOCTL(KDSKBMODE)
+COMPATIBLE_IOCTL(KDGKBMODE)
+COMPATIBLE_IOCTL(KDSKBMETA)
+COMPATIBLE_IOCTL(KDGKBMETA)
+COMPATIBLE_IOCTL(KDGKBENT)
+COMPATIBLE_IOCTL(KDSKBENT)
+COMPATIBLE_IOCTL(KDGKBSENT)
+COMPATIBLE_IOCTL(KDSKBSENT)
+COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDSKBDIACR)
+COMPATIBLE_IOCTL(KDGKBLED)
+COMPATIBLE_IOCTL(KDSKBLED)
+COMPATIBLE_IOCTL(KDGETLED)
+COMPATIBLE_IOCTL(KDSETLED)
+COMPATIBLE_IOCTL(GIO_SCRNMAP)
+COMPATIBLE_IOCTL(PIO_SCRNMAP)
+COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_FONTRESET)
+COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
+/* Little k */
+#if 0
+COMPATIBLE_IOCTL(KIOCTYPE)
+COMPATIBLE_IOCTL(KIOCLAYOUT)
+COMPATIBLE_IOCTL(KIOCGTRANS)
+COMPATIBLE_IOCTL(KIOCTRANS)
+COMPATIBLE_IOCTL(KIOCCMD)
+COMPATIBLE_IOCTL(KIOCSDIRECT)
+COMPATIBLE_IOCTL(KIOCSLED)
+COMPATIBLE_IOCTL(KIOCGLED)
+COMPATIBLE_IOCTL(KIOCSRATE)
+COMPATIBLE_IOCTL(KIOCGRATE)
+#endif
+/* Big S */
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
+COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+/* Big V */
+COMPATIBLE_IOCTL(VT_SETMODE)
+COMPATIBLE_IOCTL(VT_GETMODE)
+COMPATIBLE_IOCTL(VT_GETSTATE)
+COMPATIBLE_IOCTL(VT_OPENQRY)
+COMPATIBLE_IOCTL(VT_ACTIVATE)
+COMPATIBLE_IOCTL(VT_WAITACTIVE)
+COMPATIBLE_IOCTL(VT_RELDISP)
+COMPATIBLE_IOCTL(VT_DISALLOCATE)
+COMPATIBLE_IOCTL(VT_RESIZE)
+COMPATIBLE_IOCTL(VT_RESIZEX)
+COMPATIBLE_IOCTL(VT_LOCKSWITCH)
+COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
+/* Little v, the video4linux ioctls */
+COMPATIBLE_IOCTL(VIDIOCGCAP)
+COMPATIBLE_IOCTL(VIDIOCGCHAN)
+COMPATIBLE_IOCTL(VIDIOCSCHAN)
+COMPATIBLE_IOCTL(VIDIOCGPICT)
+COMPATIBLE_IOCTL(VIDIOCSPICT)
+COMPATIBLE_IOCTL(VIDIOCCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCKEY)
+COMPATIBLE_IOCTL(VIDIOCGAUDIO)
+COMPATIBLE_IOCTL(VIDIOCSAUDIO)
+COMPATIBLE_IOCTL(VIDIOCSYNC)
+COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCGMBUF)
+COMPATIBLE_IOCTL(VIDIOCGUNIT)
+COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
+COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
+/* BTTV specific... */
+COMPATIBLE_IOCTL(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]))
+COMPATIBLE_IOCTL(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
+COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
+COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
+/* Little m */
+COMPATIBLE_IOCTL(MTIOCTOP)
+/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOSETOWN)
+COMPATIBLE_IOCTL(SIOCSPGRP)
+COMPATIBLE_IOCTL(FIOGETOWN)
+COMPATIBLE_IOCTL(SIOCGPGRP)
+COMPATIBLE_IOCTL(SIOCATMARK)
+COMPATIBLE_IOCTL(SIOCSIFLINK)
+COMPATIBLE_IOCTL(SIOCSIFENCAP)
+COMPATIBLE_IOCTL(SIOCGIFENCAP)
+COMPATIBLE_IOCTL(SIOCSIFBR)
+COMPATIBLE_IOCTL(SIOCGIFBR)
+COMPATIBLE_IOCTL(SIOCSARP)
+COMPATIBLE_IOCTL(SIOCGARP)
+COMPATIBLE_IOCTL(SIOCDARP)
+COMPATIBLE_IOCTL(SIOCSRARP)
+COMPATIBLE_IOCTL(SIOCGRARP)
+COMPATIBLE_IOCTL(SIOCDRARP)
+COMPATIBLE_IOCTL(SIOCADDDLCI)
+COMPATIBLE_IOCTL(SIOCDELDLCI)
+/* SG stuff */
+COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_EMULATED_HOST)
+COMPATIBLE_IOCTL(SG_SET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
+COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
+COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
+COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
+COMPATIBLE_IOCTL(SG_SET_DEBUG)
+COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
+COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
+COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
+COMPATIBLE_IOCTL(SG_SCSI_RESET)
+COMPATIBLE_IOCTL(SG_IO)
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
+COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
+COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
+/* PPP stuff */
+COMPATIBLE_IOCTL(PPPIOCGFLAGS)
+COMPATIBLE_IOCTL(PPPIOCSFLAGS)
+COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGUNIT)
+COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGMRU)
+COMPATIBLE_IOCTL(PPPIOCSMRU)
+COMPATIBLE_IOCTL(PPPIOCSMAXCID)
+COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
+COMPATIBLE_IOCTL(PPPIOCGNPMODE)
+COMPATIBLE_IOCTL(PPPIOCSNPMODE)
+COMPATIBLE_IOCTL(PPPIOCGDEBUG)
+COMPATIBLE_IOCTL(PPPIOCSDEBUG)
+COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
+COMPATIBLE_IOCTL(PPPIOCATTACH)
+COMPATIBLE_IOCTL(PPPIOCDETACH)
+COMPATIBLE_IOCTL(PPPIOCSMRRU)
+COMPATIBLE_IOCTL(PPPIOCCONNECT)
+COMPATIBLE_IOCTL(PPPIOCDISCONN)
+COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+/* PPPOX */
+COMPATIBLE_IOCTL(PPPOEIOCSFWD);
+COMPATIBLE_IOCTL(PPPOEIOCDFWD);
+/* CDROM stuff */
+COMPATIBLE_IOCTL(CDROMPAUSE)
+COMPATIBLE_IOCTL(CDROMRESUME)
+COMPATIBLE_IOCTL(CDROMPLAYMSF)
+COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
+COMPATIBLE_IOCTL(CDROMREADTOCHDR)
+COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
+COMPATIBLE_IOCTL(CDROMSTOP)
+COMPATIBLE_IOCTL(CDROMSTART)
+COMPATIBLE_IOCTL(CDROMEJECT)
+COMPATIBLE_IOCTL(CDROMVOLCTRL)
+COMPATIBLE_IOCTL(CDROMSUBCHNL)
+COMPATIBLE_IOCTL(CDROMEJECT_SW)
+COMPATIBLE_IOCTL(CDROMMULTISESSION)
+COMPATIBLE_IOCTL(CDROM_GET_MCN)
+COMPATIBLE_IOCTL(CDROMRESET)
+COMPATIBLE_IOCTL(CDROMVOLREAD)
+COMPATIBLE_IOCTL(CDROMSEEK)
+COMPATIBLE_IOCTL(CDROMPLAYBLK)
+COMPATIBLE_IOCTL(CDROMCLOSETRAY)
+COMPATIBLE_IOCTL(CDROM_SET_OPTIONS)
+COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS)
+COMPATIBLE_IOCTL(CDROM_SELECT_SPEED)
+COMPATIBLE_IOCTL(CDROM_SELECT_DISC)
+COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED)
+COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS)
+COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
+COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
+COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
+COMPATIBLE_IOCTL(CDROM_DEBUG)
+COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* Big L */
+COMPATIBLE_IOCTL(LOOP_SET_FD)
+COMPATIBLE_IOCTL(LOOP_CLR_FD)
+/* Big Q for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
+COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
+COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
+/* Big T for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_START)
+COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
+COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
+/* Little m for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
+/* Big P for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
+COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
+/* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
+/* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
+COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
+/* Big C for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
+COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
+COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
+COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
+/* Big M for sound/OSS */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_MUTE)
+/* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
+/* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
+/* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
+/* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
+COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
+COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
+COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
+COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
+COMPATIBLE_IOCTL(OSS_GETVERSION)
+/* AUTOFS */
+COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
+COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+/* DEVFS */
+COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
+COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
+COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
+/* Raw devices */
+COMPATIBLE_IOCTL(RAW_SETBIND)
+COMPATIBLE_IOCTL(RAW_GETBIND)
+/* SMB ioctls which do not need any translations */
+COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+/* Little a */
+COMPATIBLE_IOCTL(ATMSIGD_CTRL)
+COMPATIBLE_IOCTL(ATMARPD_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_MCAST)
+COMPATIBLE_IOCTL(ATMLEC_DATA)
+COMPATIBLE_IOCTL(ATM_SETSC)
+COMPATIBLE_IOCTL(SIOCSIFATMTCP)
+COMPATIBLE_IOCTL(SIOCMKCLIP)
+COMPATIBLE_IOCTL(ATMARP_MKIP)
+COMPATIBLE_IOCTL(ATMARP_SETENTRY)
+COMPATIBLE_IOCTL(ATMARP_ENCAP)
+COMPATIBLE_IOCTL(ATMTCP_CREATE)
+COMPATIBLE_IOCTL(ATMTCP_REMOVE)
+COMPATIBLE_IOCTL(ATMMPC_CTRL)
+COMPATIBLE_IOCTL(ATMMPC_DATA)
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* 0xfe - lvm */
+COMPATIBLE_IOCTL(VG_SET_EXTENDABLE)
+COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT)
+COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST)
+COMPATIBLE_IOCTL(VG_REMOVE)
+COMPATIBLE_IOCTL(VG_RENAME)
+COMPATIBLE_IOCTL(VG_REDUCE)
+COMPATIBLE_IOCTL(PE_LOCK_UNLOCK)
+COMPATIBLE_IOCTL(PV_FLUSH)
+COMPATIBLE_IOCTL(LVM_LOCK_LVM)
+COMPATIBLE_IOCTL(LVM_GET_IOP_VERSION)
+#ifdef LVM_TOTAL_RESET
+COMPATIBLE_IOCTL(LVM_RESET)
+#endif
+COMPATIBLE_IOCTL(LV_SET_ACCESS)
+COMPATIBLE_IOCTL(LV_SET_STATUS)
+COMPATIBLE_IOCTL(LV_SET_ALLOCATION)
+COMPATIBLE_IOCTL(LE_REMAP)
+COMPATIBLE_IOCTL(LV_BMAP)
+COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
+#endif /* LVM */
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
+COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
+COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
+COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
+COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
+COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
+#endif /* DRM */
+/* elevator */
+COMPATIBLE_IOCTL(BLKELVGET)
+COMPATIBLE_IOCTL(BLKELVSET)
+/* And these ioctls need translation */
+HANDLE_IOCTL(TIOCGSERIAL, do_tiocgserial)
+HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
+HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
+HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc)
+HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
+HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
+HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
+HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
+HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
+HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
+/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
+HANDLE_IOCTL(SIOCRTMSG, ret_einval)
+HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
+HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
+HANDLE_IOCTL(BLKRAGET, w_long)
+HANDLE_IOCTL(BLKGETSIZE, w_long)
+HANDLE_IOCTL(0x1260, broken_blkgetsize)
+HANDLE_IOCTL(BLKFRAGET, w_long)
+HANDLE_IOCTL(BLKSECTGET, w_long)
+HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
+
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
+HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
+HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
+
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans)
+HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
+HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
+HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
+HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
+HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
+HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans)
+HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
+HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
+HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
+HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
+#ifdef CONFIG_VT
+HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
+HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
+HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
+HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
+HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
+#endif
+HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
+#if 0
+/* One SMB ioctl needs translations. */
+#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
+HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+#endif
+HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
+HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
+HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl)
+HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl)
+HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl)
+HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
+HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
+HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
+#endif /* LVM */
+#if defined(CONFIG_GENRTC)
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
+COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
+HANDLE_IOCTL(RTC_IRQP_READ, w_long)
+COMPATIBLE_IOCTL(RTC_IRQP_SET)
+HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
+COMPATIBLE_IOCTL(RTC_EPOCH_SET)
+#endif
+#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+#endif /* DRM */
+COMPATIBLE_IOCTL(PA_PERF_ON)
+COMPATIBLE_IOCTL(PA_PERF_OFF)
+COMPATIBLE_IOCTL(PA_PERF_VERSION)
+IOCTL_TABLE_END
+
+unsigned int ioctl32_hash_table[1024];
+
+extern inline unsigned long ioctl32_hash(unsigned long cmd)
+{
+	return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
+}
+
+static void ioctl32_insert_translation(struct ioctl_trans *trans)
+{
+	unsigned long hash;
+	struct ioctl_trans *t;
+
+	hash = ioctl32_hash (trans->cmd);
+	if (!ioctl32_hash_table[hash])
+		ioctl32_hash_table[hash] = (u32)(long)trans;
+	else {
+		t = (struct ioctl_trans *)(long)ioctl32_hash_table[hash];
+		while (t->next)
+			t = (struct ioctl_trans *)(long)t->next;
+		trans->next = 0;
+		t->next = (u32)(long)trans;
+	}
+}
+
+static int __init init_sys32_ioctl(void)
+{
+	int i;
+	extern struct ioctl_trans ioctl_translations[], ioctl_translations_end[];
+
+	for (i = 0; &ioctl_translations[i] < &ioctl_translations_end[0]; i++)
+		ioctl32_insert_translation(&ioctl_translations[i]);
+	return 0;
+}
+
+__initcall(init_sys32_ioctl);
+
+static struct ioctl_trans *additional_ioctls;
+
+/* Always call these with kernel lock held! */
+
+int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
+{
+	int i;
+
+panic("register_ioctl32_conversion() is B0RKEN! Called by %p\n", __builtin_return_address(0));
+
+	if (!additional_ioctls) {
+		additional_ioctls = module_map(PAGE_SIZE);
+		if (!additional_ioctls)
+			return -ENOMEM;
+		memset(additional_ioctls, 0, PAGE_SIZE);
+	}
+	for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
+		if (!additional_ioctls[i].cmd)
+			break;
+	if (i == PAGE_SIZE/sizeof(struct ioctl_trans))
+		return -ENOMEM;
+	additional_ioctls[i].cmd = cmd;
+	if (!handler)
+		additional_ioctls[i].handler = (u32)(long)sys_ioctl;
+	else
+		additional_ioctls[i].handler = (u32)(long)handler;
+	ioctl32_insert_translation(&additional_ioctls[i]);
+	return 0;
+}
+
+int unregister_ioctl32_conversion(unsigned int cmd)
+{
+	unsigned long hash = ioctl32_hash(cmd);
+	struct ioctl_trans *t, *t1;
+
+	t = (struct ioctl_trans *)(long)ioctl32_hash_table[hash];
+	if (!t) return -EINVAL;
+	if (t->cmd == cmd && t >= additional_ioctls &&
+	    (unsigned long)t < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+		ioctl32_hash_table[hash] = t->next;
+		t->cmd = 0;
+		return 0;
+	} else while (t->next) {
+		t1 = (struct ioctl_trans *)(long)t->next;
+		if (t1->cmd == cmd && t1 >= additional_ioctls &&
+		    (unsigned long)t1 < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
+			t1->cmd = 0;
+			t->next = t1->next;
+			return 0;
+		}
+		t = t1;
+	}
+	return -EINVAL;
+}
+
+asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct file * filp;
+	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+	unsigned long pafnptr[4];
+	extern char __gp;
+	struct ioctl_trans *t;
+	int error = -EBADF;
+
+	filp = fget(fd);
+	if(!filp)
+		goto out2;
+
+	if (!filp->f_op || !filp->f_op->ioctl) {
+		error = sys_ioctl (fd, cmd, arg);
+		goto out;
+	}
+
+	/* intercept private networking ioctl() calls here since it is
+	 * an onerous task to figure out which ones of the HANDLE_IOCTL
+	 * list map to these values.
+	 */
+	if (cmd >= SIOCDEVPRIVATE && cmd <= SIOCDEVPRIVATE + 0xf) {
+		error = siocprivate(fd, cmd, arg);
+		goto out;
+	}
+
+	t = (struct ioctl_trans *)(long)ioctl32_hash_table [ioctl32_hash (cmd)];
+
+	while (t && t->cmd != cmd)
+		t = (struct ioctl_trans *)(long)t->next;
+	if (t) {
+		handler = (void *) pafnptr;
+		pafnptr[0] = pafnptr[1] = 0UL;
+		pafnptr[2] = (unsigned long) t->handler;
+		pafnptr[3] = A(&__gp);
+		error = handler(fd, cmd, arg, filp);
+	} else {
+		static int count = 0;
+		if (++count <= 20)
+			printk(KERN_WARNING
+				"sys32_ioctl: Unknown cmd fd(%d) "
+				"cmd(%08x) arg(%08x)\n",
+				(int)fd, (unsigned int)cmd, (unsigned int)arg);
+		error = -EINVAL;
+	}
+out:
+	fput(filp);
+out2:
+	return error;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/iosapic.c linux-2.4.20/arch/parisc/kernel/iosapic.c
--- linux-2.4.19/arch/parisc/kernel/iosapic.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/iosapic.c	2002-10-04 00:41:13.000000000 +0000
@@ -169,11 +169,13 @@
 
 #include <asm/byteorder.h>	/* get in-line asm for swab */
 #include <asm/pdc.h>
-#include <asm/pdcpat.h>
 #include <asm/page.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/gsc.h>		/* gsc_read/write functions */
+#ifdef CONFIG_SUPERIO
+#include <asm/superio.h>
+#endif
 
 #include <asm/iosapic.h>
 #include "./iosapic_private.h"
@@ -181,7 +183,6 @@
 #define MODULE_NAME "iosapic"
 
 /* "local" compile flags */
-#undef IOSAPIC_CALLBACK
 #undef PCI_BRIDGE_FUNCS
 #undef DEBUG_IOSAPIC
 #undef DEBUG_IOSAPIC_IRT
@@ -282,28 +283,6 @@
 
 #define	IOSAPIC_EOI(eoi_addr, eoi_data) gsc_writel(eoi_data, eoi_addr)
 
-#if IOSAPIC_CALLBACK
-/*
-** Shouldn't use callback since SAPIC doesn't have an officially assigned
-** H or S version numbers. Slight long term risk the number chosen would
-** collide with something else.
-** But benefit is cleaner lba/sapic interface.
-** Might be worth it but for just use direct calls for now.
-**
-** Entry below is copied from lba driver.
-** Only thing different is hw_type.
-*/
-static struct pa_iodc_driver iosapic_driver_for[] = {
-	{HPHW_OTHER, 0x782, 0, 0x0000A, 0, 0x00,
-	DRIVER_CHECK_HWTYPE + DRIVER_CHECK_HVERSION + DRIVER_CHECK_SVERSION,
-	"I/O Sapic", "",(void *) iosapic_callback},     
-	{0,0,0,0,0,0,
-	0,
-	(char *) NULL,(char *) NULL,(void *) NULL}                     
-};
-#endif /* IOSAPIO_CALLBACK */
-
-
 static struct iosapic_info *iosapic_list;
 static spinlock_t iosapic_lock;
 static int iosapic_count;
@@ -350,25 +329,22 @@
 static int __init /* return number of entries as success/fail flag */
 iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
 {
-	struct pdc_pat_io_num pdc_io_num; /* PAT PDC return block */
 	long status;              /* PDC return value status */
-	struct irt_entry *table = NULL;  /* start of interrupt routing tbl */
+	struct irt_entry *table;  /* start of interrupt routing tbl */
 	unsigned long num_entries = 0UL;
 
 	ASSERT(NULL != irt);
-	/* FIXME ASSERT(((&pdc_io_num) & (0x3f)) == 0);  enforce 32-byte alignment */
 
-	/* Try PAT_PDC to get interrupt routing table size */
-	DBG(KERN_DEBUG "calling get_irt_size\n");
-	status = pdc_pat_get_irt_size( &pdc_io_num, cell_num);
-	DBG(KERN_DEBUG "get_irt_size: %ld\n", status);
+	if (is_pdc_pat()) {
 
-	switch(status) {
+		/* Use pat pdc routine to get interrupt routing table size */
+		DBG("calling get_irt_size (cell %ld)\n", cell_num);
+		status = pdc_pat_get_irt_size(&num_entries, cell_num);
+		DBG("get_irt_size: %ld\n", status);
 
-	case PDC_RET_OK:	/* PAT box. Proceed to get the IRT */
+		ASSERT(status == PDC_OK);
 
 		/* save the number of entries in the table */
-		num_entries = pdc_io_num.num;
 		ASSERT(0UL != num_entries);
 
 		/*
@@ -384,30 +360,27 @@
 		}
 
 		/* get PCI INT routing table */
-		status = pdc_pat_get_irt( (void *) table, cell_num);
-		DBG(KERN_DEBUG "pdc_pat_get_irt: %ld\n", status);
-		ASSERT(status == PDC_RET_OK);
-		break;
-
-	case PDC_RET_NE_PROC: /* Not a PAT platform. Try PDC_PCI extensions */
+		status = pdc_pat_get_irt(table, cell_num);
+		DBG("pdc_pat_get_irt: %ld\n", status);
+		ASSERT(status == PDC_OK);
+	} else {
 		/*
-		** C3000/J5000 (and similar) platforms with "legacy" PDC
-		** will return exactly one IRT.
+		** C3000/J5000 (and similar) platforms with Sprockets PDC
+		** will return exactly one IRT for all iosapics.
 		** So if we have one, don't need to get it again.
 		*/
 		if (NULL != irt_cell)
-			break;
+			return 0;
 
-		status = pdc_pci_irt_size( (void *)&pdc_io_num,
-				/* elroy HPA (really a NOP) */ 0);
-		DBG(KERN_WARNING "pdc_pci_irt_size: %ld\n", status);
+		/* Should be using the Elroy's HPA, but it's ignored anyway */
+		status = pdc_pci_irt_size(&num_entries, 0);
+		DBG("pdc_pci_irt_size: %ld\n", status);
 
-		if (PDC_RET_OK != status) {
+		if (PDC_OK != status) {
 			/* Not a "legacy" system with I/O SAPIC either */
 			return 0;
 		}
 
-		num_entries = pdc_io_num.num;
 		ASSERT(0UL != num_entries);
 
 		table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
@@ -416,36 +389,27 @@
 			return 0;
 		}
 
-		status = pdc_pci_irt( (void *) &pdc_io_num,
-				(void *) NULL, /* Elroy HPA - not used */
-				(void *) table);
-
-		ASSERT(PDC_RET_OK == status);
-		break;
-
-	default:
-		printk(KERN_WARNING MODULE_NAME ": PDC_PAT_IO call failed with %ld\n", status);
-		break;
+		/* HPA ignored by this call too. */
+		status = pdc_pci_irt(num_entries, 0, table);
+		ASSERT(PDC_OK == status);
 	}
 
 	/* return interrupt table address */
 	*irt = table;
 
-
 #ifdef DEBUG_IOSAPIC_IRT
-	{
+{
 	struct irt_entry *p = table;
 	int i;
 
-	printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
-	printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
+	printk(KERN_DEBUG MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
+	printk(KERN_DEBUG MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
 		table,
 		num_entries,
 		(int) sizeof(struct irt_entry));
 
-	for (i = 0 ; i < num_entries ; i++, p++)
-	{
-		printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
+	for (i = 0 ; i < num_entries ; i++, p++) {
+		printk(KERN_DEBUG MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
 		p->entry_type, p->entry_length, p->interrupt_type,
 		p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
 		p->src_seg_id, p->dest_iosapic_intin,
@@ -453,7 +417,7 @@
 		((u32 *) p)[3]
 		);
 	}
-	}
+}
 #endif /* DEBUG_IOSAPIC_IRT */
 
 	return num_entries;
@@ -464,6 +428,8 @@
 void __init
 iosapic_init(void)
 {
+	unsigned long cell = 0;
+
 	/* init global data */
 	iosapic_lock = SPIN_LOCK_UNLOCKED;
         iosapic_list = (struct iosapic_info *) NULL;
@@ -471,22 +437,24 @@
 
 	DBG("iosapic_init()\n");
 
+#ifdef __LP64__
+	if (is_pdc_pat()) {
+		int status;
+		struct pdc_pat_cell_num cell_info;
+
+		status = pdc_pat_cell_get_number(&cell_info);
+		if (status == PDC_OK) {
+			cell = cell_info.cell_num;
+		}
+	}
+#endif
+
 	/*
 	**  get IRT for this cell.
 	*/
-	irt_num_entry =  iosapic_load_irt(0L, &irt_cell);
+	irt_num_entry =  iosapic_load_irt(cell, &irt_cell);
 	if (0 == irt_num_entry)
 		irt_cell = NULL;	/* old PDC w/o iosapic */
-
-#ifdef IOSAPIC_CALLBACK
-	/*
-	** When new I/O SAPICs are discovered, this callback
-	** will get invoked. Implies lba driver will register
-	** I/O Sapic as a device it "discovered" with faked
-	** IODC data.
-	*/
-	register_driver(iosapic_driver_for);
-#endif /* IOSAPIC_CALLBACK */
 }
 
 
@@ -546,7 +514,7 @@
 		return i;
 	}
 
-	printk(KERN_WARNING MODULE_NAME ": 0x%p : no IRT entry for slot %d, pin %d\n",
+	printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
 			isi->isi_hpa, slot, intr_pin);
 	return NULL;
 }
@@ -571,21 +539,18 @@
 {
 	u8 intr_pin, intr_slot;
 
-	(void) pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
+	pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
 
-	DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n", PCI_SLOT(pcidev->devfn), intr_pin);
+	DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n",
+		PCI_SLOT(pcidev->devfn), intr_pin);
 
-	if (0 == intr_pin)
-	{
-		/*
-		** The device does NOT support/use IRQ lines.
-		*/
+	if (0 == intr_pin) {
+		/* The device does NOT support/use IRQ lines.  */
 		return NULL;
 	}
 
 	/* Check if pcidev behind a PPB */
-	if (NULL != pcidev->bus->self)
-	{
+	if (NULL != pcidev->bus->self) {
 		/* Convert pcidev INTR_PIN into something we
 		** can lookup in the IRT.
 		*/
@@ -600,7 +565,7 @@
 		** or by some ambitous soul who wants to watch TV.
 		*/
 		if (pci_bridge_funcs->xlate_intr_line) {
-			intr_pin = (*pci_bridge_funcs->xlate_intr_line)(pcidev);
+			intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
 		}
 #else	/* PCI_BRIDGE_FUNCS */
 		struct pci_bus *p = pcidev->bus;
@@ -646,8 +611,8 @@
 	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
 	int irq_num = vi->vi_ios->isi_region->data.irqbase + vi->vi_irqline;
 
-	DBG("iosapic_interrupt(): irq %d line %d eoi %p\n", irq, vi->vi_irqline,
-				vi->vi_eoi_addr);
+	DBG("iosapic_interrupt(): irq %d line %d eoi %p\n",
+		irq, vi->vi_irqline, vi->vi_eoi_addr);
 
 /* FIXME: Need to mask/unmask? processor IRQ is already masked... */
 	do_irq(&vi->vi_ios->isi_region->action[vi->vi_irqline], irq_num, regs);
@@ -668,12 +633,39 @@
 	struct vector_info *vi;
 	int isi_line;	/* line used by device */
 	int tmp;
+	int return_irq;
+#ifdef CONFIG_SUPERIO
+	int superio_irq = -1;
+#endif
 
 	if (NULL == isi) {
-		printk(KERN_WARNING MODULE_NAME ": 0x%p hpa not registered\n", isi->isi_hpa);
+		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+			pcidev->name);
 		return(-1);
 	}
 
+#ifdef CONFIG_SUPERIO
+	if (is_superio_device(pcidev)) {
+		superio_irq = superio_fixup_irq(pcidev);
+		if (superio_irq == -1)
+		    return(-1);
+
+		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN) {
+
+			/*
+			 * SuperIO USB controller has an irt entry.
+			 * Only let the USB controller hookup the rest
+			 * of the interrupt routing when it comes through.
+			 * Note that interrupts for all three functions
+			 * actually come through the PIC's on function 1!
+			 */
+
+			pcidev->irq = superio_irq;
+			return superio_irq;
+		}
+	}
+#endif /* CONFIG_SUPERIO */
+
 	/* lookup IRT entry for isi/slot/pin set */
 	irte = iosapic_xlate_pin(isi, pcidev);
 	if (NULL == irte) {
@@ -714,22 +706,31 @@
 	vi->vi_txn_data = txn_alloc_data(vi->vi_txn_irq, 8);
         ASSERT(vi->vi_txn_data < 256);  /* matches 8 above */
 
-	tmp = request_irq(vi->vi_txn_irq, iosapic_interrupt, 0, "iosapic", vi);
+	tmp = request_irq(vi->vi_txn_irq, iosapic_interrupt, 0,
+						vi->vi_name, vi);
 	ASSERT(tmp == 0);
 
-	vi->vi_eoi_addr = ((void *) isi->isi_hpa) + IOSAPIC_REG_EOI;
+	vi->vi_eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
 	vi->vi_eoi_data = cpu_to_le32(vi->vi_irqline);
 
 	ASSERT(NULL != isi->isi_region);
-	/*
-	** pcidev->irq still needs to be virtualized.
-	*/
-	pcidev->irq = isi->isi_region->data.irqbase + isi_line;
+	/* pcidev->irq still needs to be virtualized.  */
+
+	return_irq = isi->isi_region->data.irqbase + isi_line;
 
-	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n", PCI_SLOT(pcidev->devfn),
-	PCI_FUNC(pcidev->devfn), pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
+#ifdef CONFIG_SUPERIO
+	if (superio_irq != -1) {
+		superio_inform_irq(return_irq);
+		return_irq = superio_irq;
+	}
+#endif
+	pcidev->irq = return_irq;
+
+	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
+		PCI_SLOT(pcidev->devfn),
+	PCI_FUNC(pcidev->devfn), pcidev->vendor, pcidev->device, isi_line, return_irq);
 
-	return(pcidev->irq);
+	return return_irq;
 }
 
 
@@ -755,7 +756,7 @@
 	struct iosapic_info *isp = vi->vi_ios;
 
 	ASSERT(NULL != isp);
-	ASSERT(NULL != isp->isi_hpa);
+	ASSERT(0 != isp->isi_hpa);
 	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p WINDOW %p  0x%x 0x%x\n",
 		vi->vi_irqline,
 		isp->isi_hpa, isp->isi_hpa+IOSAPIC_REG_WINDOW,
@@ -807,16 +808,13 @@
 	** Extracting id_eid isn't a real clean way of getting it.
 	** But the encoding is the same for both PA and IA64 platforms.
 	*/
-#ifdef __LP64__
-	if (pdc_pat) {
+	if (is_pdc_pat()) {
 		/*
 		** PAT PDC just hands it to us "right".
 		** vi_txn_addr comes from cpu_data[x].txn_addr.
 		*/
 		*dp1 = (u32) (vi->vi_txn_addr);
-	} else
-#endif
-	{
+	} else {
 		/* 
 		** eg if base_addr == 0xfffa0000),
 		**    we want to get 0xa0ff0000.
@@ -886,7 +884,6 @@
 
 	/* data is initialized by fixup_irq */
 	ASSERT(0 < vi->vi_txn_irq);
-	ASSERT(0UL != vi->vi_txn_addr);
 	ASSERT(0UL != vi->vi_txn_data);
 
 	iosapic_set_irt_data(vi, &d0, &d1);
@@ -895,10 +892,10 @@
 
 #ifdef DEBUG_IOSAPIC_IRT
 {
-u32 *t = (u32 *) ((ulong) vi->vi_eoi_addr & ~0xffUL);
-printk("iosapic_enable_irq(): regs %p", vi->vi_eoi_addr);
-while (t < vi->vi_eoi_addr) printk(" %x", READ_U32(t++));
-printk("\n");
+	u32 *t = (u32 *) ((ulong) vi->vi_eoi_addr & ~0xffUL);
+	printk("iosapic_enable_irq(): regs %p", vi->vi_eoi_addr);
+	while (t < vi->vi_eoi_addr) printk(" %x", READ_U32(t++));
+	printk("\n");
 }
 
 printk("iosapic_enable_irq(): sel ");
@@ -943,10 +940,10 @@
 
 
 static struct irq_region_ops iosapic_irq_ops = {
-	iosapic_disable_irq,
-	iosapic_enable_irq,
-	iosapic_mask_irq,
-	iosapic_unmask_irq
+	disable_irq:	iosapic_disable_irq,
+	enable_irq:	iosapic_enable_irq,
+	mask_irq:	iosapic_mask_irq,
+	unmask_irq:	iosapic_unmask_irq
 };
 
 
@@ -967,15 +964,9 @@
 }
 
 
-#ifndef IOSAPIC_CALLBACK
-/*
-** iosapic_register() is the alternative to iosapic_driver_for().
-** (Only one or the other should be implemented.)
-*/
-
 /*
 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
-** Caller must be certain they have an I/O SAPIC and know it's MMIO address.
+** Caller must be certain they have an I/O SAPIC and know its MMIO address.
 **
 **	o allocate iosapic_info and add it to the list
 **	o read iosapic version and squirrel that away
@@ -984,7 +975,7 @@
 **	o allocate isi_region (registers region handlers)
 */
 void *
-iosapic_register(void *hpa)
+iosapic_register(unsigned long hpa)
 {
 	struct iosapic_info *isi = NULL;
 	struct irt_entry *irte = irt_cell;
@@ -1021,7 +1012,7 @@
 
 	memset(isi, 0, sizeof(struct iosapic_info));
 
-	isi->isi_hpa         = (unsigned char *) hpa;
+	isi->isi_hpa         = hpa;
 	isi->isi_version     = iosapic_rd_version(isi);
 	isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
 
@@ -1034,6 +1025,7 @@
 	}
 
 	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
+	sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
 
 	/*
 	** Initialize vector array
@@ -1041,17 +1033,16 @@
 	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
 		vip->vi_irqline = (unsigned char) cnt;
 		vip->vi_ios = isi;
+		sprintf(vip->vi_name, "%s-L%d", isi->isi_name, cnt);
 	}
 
 	isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
-				&iosapic_irq_ops, IRQ_REG_DIS|IRQ_REG_MASK,
-				"I/O Sapic", (void *) isi->isi_vector);
+				&iosapic_irq_ops, isi->isi_name,
+				(void *) isi->isi_vector);
 
 	ASSERT(NULL != isi->isi_region);
 	return ((void *) isi);
 }
-#endif /* !IOSAPIC_CALLBACK */
-
 
 
 #ifdef DEBUG_IOSAPIC
@@ -1092,8 +1083,8 @@
 {
 	ASSERT(NULL != isi);
 	printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
-	printk(KERN_DEBUG "\t\tisi_hpa: %p\n", isi->isi_hpa);
-	printk(KERN_DEBUG "\t\tisi_satus:     %x\n", isi->isi_status);
+	printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
+	printk(KERN_DEBUG "\t\tisi_status:     %x\n", isi->isi_status);
 	printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
 	printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/iosapic_private.h linux-2.4.20/arch/parisc/kernel/iosapic_private.h
--- linux-2.4.19/arch/parisc/kernel/iosapic_private.h	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/iosapic_private.h	2002-10-04 00:41:15.000000000 +0000
@@ -111,22 +111,25 @@
 	struct irt_entry *vi_irte;      /* IRT entry */
 	u32	*vi_eoi_addr;	/* precalculate EOI reg address */
 	u32	vi_eoi_data;	/* IA64: ?       PA: swapped txn_data */
-	u8	vi_status;	/* status/flags */
-	u8	vi_irqline;	/* INTINn(IRQ) */
 	int	vi_txn_irq;	/* virtual IRQ number for processor */
 	ulong	vi_txn_addr;    /* IA64: id_eid  PA: partial HPA */
 	ulong	vi_txn_data;    /* IA64: vector  PA: EIR bit */
+	u8	vi_status;	/* status/flags */
+	u8	vi_irqline;	/* INTINn(IRQ) */
+	char	vi_name[32];    /* user visible identity */
 };
 
 
 struct iosapic_info {
 	struct iosapic_info  *isi_next;      /* list of I/O SAPIC          */
-	volatile void        *isi_hpa;       /* physical base address      */
+	unsigned long	     isi_hpa;	     /* physical base address */
 	struct irq_region    *isi_region;    /* each I/O SAPIC is one region */
 	struct vector_info   *isi_vector;    /* IRdT (IRQ line) array  */
 	int                  isi_num_vectors; /* size of IRdT array */
 	int                  isi_status;     /* status/flags               */
 	unsigned int         isi_version;    /* DEBUG: data fr version reg */
+	/* round up to next cacheline */
+	char                 isi_name[20]; /* identify region for users */
 };
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/irq.c linux-2.4.20/arch/parisc/kernel/irq.c
--- linux-2.4.19/arch/parisc/kernel/irq.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/irq.c	2002-10-04 00:41:16.000000000 +0000
@@ -1,13 +1,10 @@
-/* $Id: irq.c,v 1.8 2000/02/08 02:01:17 grundler Exp $
- *
+/* 
  * Code to handle x86 style IRQs plus some generic interrupt stuff.
  *
- * This is not in any way SMP-clean.
- *
  * Copyright (C) 1992 Linus Torvalds
  * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
- * Copyright (C) 1999 SuSE GmbH (Author: Philipp Rumpf, prumpf@tux.org)
- * Copyright (C) 2000 Hewlett Packard Corp (Co-Author: Grant Grundler, grundler@cup.hp.com)
+ * Copyright (C) 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
+ * Copyright (C) 1999-2000 Grant Grundler
  *
  *    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
@@ -23,138 +20,167 @@
  *    along with this program; if not, write to the Free Software
  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/config.h>
 #include <linux/bitops.h>
 #include <asm/bitops.h>
+#include <linux/config.h>
 #include <asm/pdc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/kernel_stat.h>
 #include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
 #include <linux/irq.h>
+#include <linux/spinlock.h>
 
 #include <asm/cache.h>
 
 #undef DEBUG_IRQ
+#undef PARISC_IRQ_CR16_COUNTS
 
 extern void timer_interrupt(int, void *, struct pt_regs *);
 extern void ipi_interrupt(int, void *, struct pt_regs *);
 
 #ifdef DEBUG_IRQ
-#define DBG_IRQ(x...)   printk(x)
+#define DBG_IRQ(irq, x)	if ((irq) != TIMER_IRQ) printk x
 #else /* DEBUG_IRQ */
-#define DBG_IRQ(x...)
+#define DBG_IRQ(irq, x)	do { } while (0)
 #endif /* DEBUG_IRQ */
 
-#define EIEM_MASK(irq) (1L<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
-#define CLEAR_EIEM_BIT(irq) set_eiem(get_eiem() & ~EIEM_MASK(irq))
-#define SET_EIEM_BIT(irq) set_eiem(get_eiem() | EIEM_MASK(irq))
+#define EIEM_MASK(irq)       (1UL<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
+
+/* Bits in EIEM correlate with cpu_irq_action[].
+** Numbered *Big Endian*! (ie bit 0 is MSB)
+*/
+static unsigned long cpu_eiem = 0;
+
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
+
+#ifdef CONFIG_SMP
+static void cpu_set_eiem(void *info)
+{
+	set_eiem((unsigned long) info);
+}
+#endif
 
-static void disable_cpu_irq(void *unused, int irq)
+static inline void disable_cpu_irq(void *unused, int irq)
 {
-	CLEAR_EIEM_BIT(irq);
+	unsigned long eirr_bit = EIEM_MASK(irq);
+
+	cpu_eiem &= ~eirr_bit;
+	set_eiem(cpu_eiem);
+        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 static void enable_cpu_irq(void *unused, int irq)
 {
-	unsigned long mask = EIEM_MASK(irq);
+	unsigned long eirr_bit = EIEM_MASK(irq);
+
+	mtctl(eirr_bit, 23);	/* clear EIRR bit before unmasking */
+	cpu_eiem |= eirr_bit;
+        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+	set_eiem(cpu_eiem);
+}
+
+/* mask and disable are the same at the CPU level
+** Difference is enable clears pending interrupts
+*/
+#define mask_cpu_irq	disable_cpu_irq
 
-	mtctl(mask, 23);
-	SET_EIEM_BIT(irq);
+static inline void unmask_cpu_irq(void *unused, int irq)
+{
+	unsigned long eirr_bit = EIEM_MASK(irq);
+	cpu_eiem |= eirr_bit;
+	/* NOTE: sending an IPI will cause do_cpu_irq_mask() to
+	** handle *any* unmasked pending interrupts.
+	** ie We don't need to check for pending interrupts here.
+	*/
+        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+	set_eiem(cpu_eiem);
 }
 
 static struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
-	[IRQ_OFFSET(TIMER_IRQ)] { timer_interrupt, 0, 0, "timer", NULL, NULL },
-	[IRQ_OFFSET(IPI_IRQ)]	{ ipi_interrupt, 0, 0, "IPI", NULL, NULL },
+	[IRQ_OFFSET(TIMER_IRQ)] { handler: timer_interrupt, name: "timer", },
+#ifdef CONFIG_SMP
+	[IRQ_OFFSET(IPI_IRQ)]	{ handler: ipi_interrupt,   name: "IPI", },
+#endif
 };
 
 struct irq_region cpu_irq_region = {
-	{ disable_cpu_irq, enable_cpu_irq, NULL, NULL },
-	{ &cpu_data[0], "PA-PIC", IRQ_REG_MASK|IRQ_REG_DIS, IRQ_FROM_REGION(CPU_IRQ_REGION)},
-	cpu_irq_actions
+	ops:	{ disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq },
+	data:	{ dev: &cpu_data[0],
+		  name: "PA-CPU-00",
+		  irqbase: IRQ_FROM_REGION(CPU_IRQ_REGION), },
+	action:	cpu_irq_actions,
 };
 
 struct irq_region *irq_region[NR_IRQ_REGS] = {
-	[ 0 ] NULL,		/* abuse will data page fault (aka code 15) */
+	[ 0 ]              NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
 	[ CPU_IRQ_REGION ] &cpu_irq_region,
 };
 
 
+/*
+** Generic interfaces that device drivers can use:
+**    mask_irq()	block IRQ
+**    unmask_irq()	re-enable IRQ and trigger if IRQ is pending
+**    disable_irq()	block IRQ
+**    enable_irq()	clear pending and re-enable IRQ
+*/
 
-/* we special-case the real IRQs here, which feels right given the relatively
- * high cost of indirect calls.  If anyone is bored enough to benchmark this
- * and find out whether I am right, feel free to.   prumpf */
-
-static inline void mask_irq(int irq)
+void mask_irq(int irq)
 {
 	struct irq_region *region;
-	
-#ifdef DEBUG_IRQ
-	if (irq != TIMER_IRQ)
-#endif
-	DBG_IRQ("mask_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq));
 
-	if(IRQ_REGION(irq) != CPU_IRQ_REGION) {
-		region = irq_region[IRQ_REGION(irq)];
-		if(region->data.flags & IRQ_REG_MASK)
-			region->ops.mask_irq(region->data.dev, IRQ_OFFSET(irq));
-	} else {
-		CLEAR_EIEM_BIT(irq);
-	}
+	DBG_IRQ(irq, ("mask_irq(%d) %d+%d eiem 0x%lx\n", irq,
+				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
+	irq = irq_cannonicalize(irq);
+	region = irq_region[IRQ_REGION(irq)];
+	if (region->ops.mask_irq)
+		region->ops.mask_irq(region->data.dev, IRQ_OFFSET(irq));
 }
 
-static inline void unmask_irq(int irq)
+void unmask_irq(int irq)
 {
 	struct irq_region *region;
 
-#ifdef DEBUG_IRQ
-	if (irq != TIMER_IRQ)
-#endif
-	DBG_IRQ("unmask_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq));
-
-	if(IRQ_REGION(irq) != CPU_IRQ_REGION) {
-		region = irq_region[IRQ_REGION(irq)];
-		if(region->data.flags & IRQ_REG_MASK)
-			region->ops.unmask_irq(region->data.dev, IRQ_OFFSET(irq));
-	} else {
-		SET_EIEM_BIT(irq);
-	}
+	DBG_IRQ(irq, ("unmask_irq(%d) %d+%d eiem 0x%lx\n", irq,
+				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
+	irq = irq_cannonicalize(irq);
+	region = irq_region[IRQ_REGION(irq)];
+	if (region->ops.unmask_irq)
+		region->ops.unmask_irq(region->data.dev, IRQ_OFFSET(irq));
 }
 
 void disable_irq(int irq)
 {
 	struct irq_region *region;
 
-#ifdef DEBUG_IRQ
-	if (irq != TIMER_IRQ)
-#endif
-	DBG_IRQ("disable_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq));
+	DBG_IRQ(irq, ("disable_irq(%d) %d+%d eiem 0x%lx\n", irq,
+				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
+	irq = irq_cannonicalize(irq);
 	region = irq_region[IRQ_REGION(irq)];
-
-	if(region->data.flags & IRQ_REG_DIS)
+	if (region->ops.disable_irq)
 		region->ops.disable_irq(region->data.dev, IRQ_OFFSET(irq));
 	else
 		BUG();
 }
 
-void enable_irq(int irq) 
+void enable_irq(int irq)
 {
 	struct irq_region *region;
 
-#ifdef DEBUG_IRQ
-	if (irq != TIMER_IRQ)
-#endif
-	DBG_IRQ("enable_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq));
+	DBG_IRQ(irq, ("enable_irq(%d) %d+%d eiem 0x%lx\n", irq,
+				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
+	irq = irq_cannonicalize(irq);
 	region = irq_region[IRQ_REGION(irq)];
 
-	if(region->data.flags & IRQ_REG_DIS)
+	if (region->ops.enable_irq)
 		region->ops.enable_irq(region->data.dev, IRQ_OFFSET(irq));
 	else
 		BUG();
@@ -164,30 +190,40 @@
 {
 #ifdef CONFIG_PROC_FS
 	char *p = buf;
-	int i, j;
-	int regnr, irq_no;
-	struct irq_region *region;
-	struct irqaction *action, *mainaction;
+	unsigned int regnr = 0;
 
-	p += sprintf(p, "           ");
-	for (j=0; j<smp_num_cpus; j++)
-		p += sprintf(p, "CPU%d       ",j);
+	p += sprintf(p, "     ");
+#ifdef CONFIG_SMP
+	for (; regnr < smp_num_cpus; regnr++)
+#endif
+		p += sprintf(p, "      CPU%d ", regnr);
+
+#ifdef PARISC_IRQ_CR16_COUNTS
+	p += sprintf(p, "[min/avg/max] (CPU cycle counts)");
+#endif
 	*p++ = '\n';
 
+	/* We don't need *irqsave lock variants since this is
+	** only allowed to change while in the base context.
+	*/
+	spin_lock(&irq_lock);
 	for (regnr = 0; regnr < NR_IRQ_REGS; regnr++) {
-	    region = irq_region[regnr];
-	    if (!region || !region->action)
+	    unsigned int i;
+	    struct irq_region *region = irq_region[regnr];
+
+            if (!region || !region->action)
 		continue;
-	    
-	    mainaction = region->action;
 
 	    for (i = 0; i <= MAX_CPU_IRQ; i++) {
-		action = mainaction++;
-		if (!action || !action->name)
-		    continue;
-		
-		irq_no = IRQ_FROM_REGION(regnr) + i;
-		
+		struct irqaction *action = &region->action[i];
+		unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
+#ifdef CONFIG_SMP
+		unsigned int j;
+#endif
+
+		if (!action->handler)
+			continue;
+
 		p += sprintf(p, "%3d: ", irq_no);
 #ifndef CONFIG_SMP
 		p += sprintf(p, "%10u ", kstat_irqs(irq_no));
@@ -196,30 +232,48 @@
 		    p += sprintf(p, "%10u ",
 			    kstat.irqs[cpu_logical_map(j)][irq_no]);
 #endif
-		p += sprintf(p, " %14s", 
+		p += sprintf(p, " %14s",
 			    region->data.name ? region->data.name : "N/A");
+#ifndef PARISC_IRQ_CR16_COUNTS
 		p += sprintf(p, "  %s", action->name);
 
-		for (action=action->next; action; action = action->next)
-		    p += sprintf(p, ", %s", action->name);
-		*p++ = '\n';
-	    }	    	     
-	}  
+		while ((action = action->next))
+			p += sprintf(p, ", %s", action->name);
+#else
+		for ( ;action; action = action->next) {
+			unsigned int i, avg, min, max;
 
-	p += sprintf(p, "\n");
-#if CONFIG_SMP
-	p += sprintf(p, "LOC: ");
-	for (j = 0; j < smp_num_cpus; j++)
-		p += sprintf(p, "%10u ",
-			apic_timer_irqs[cpu_logical_map(j)]);
-	p += sprintf(p, "\n");
+			min = max = action->cr16_hist[0];
+
+			for (avg = i = 0; i < PARISC_CR16_HIST_SIZE; i++) {
+				int hist = action->cr16_hist[i];
+
+				if (hist) {
+					avg += hist;
+				} else
+					break;
+
+				if (hist > max) max = hist;
+				if (hist < min) min = hist;
+			}
+
+			avg /= i;
+			p += sprintf(p, " %s[%d/%d/%d]", action->name,
+					min,avg,max);
+		}
 #endif
 
+		*p++ = '\n';
+	    }
+	}
+	spin_unlock(&irq_lock);
+
+	p += sprintf(p, "\n");
 	return p - buf;
 
 #else	/* CONFIG_PROC_FS */
 
-	return 0;	
+	return 0;
 
 #endif	/* CONFIG_PROC_FS */
 }
@@ -240,8 +294,8 @@
 	int irq;
 
 	/* never return irq 0 cause that's the interval timer */
-	for(irq=1; irq<=MAX_CPU_IRQ; irq++) {
-		if(cpu_irq_region.action[irq].handler == NULL) {
+	for (irq = 1; irq <= MAX_CPU_IRQ; irq++) {
+		if (cpu_irq_region.action[irq].handler == NULL) {
 			return (IRQ_FROM_REGION(CPU_IRQ_REGION) + irq);
 		}
 	}
@@ -254,9 +308,7 @@
 txn_claim_irq(int irq)
 {
 	if (irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)].handler ==NULL)
-	{
 		return irq;
-	}
 
 	/* unlikely, but be prepared */
 	return -1;
@@ -267,10 +319,10 @@
 {
 	struct cpuinfo_parisc *dev = (struct cpuinfo_parisc *) (irq_region[IRQ_REGION(virt_irq)]->data.dev);
 
-	if (0==dev) {
+	if (!dev) {
 		printk(KERN_ERR "txn_alloc_addr(0x%x): CPU IRQ region? dev %p\n",
 			virt_irq,dev);
-		return(0UL);
+		return 0;
 	}
 	return (dev->txn_addr);
 }
@@ -283,7 +335,7 @@
 ** V-class (EPIC):          6 bits
 ** N/L-class/A500:          8 bits (iosapic)
 ** PCI 2.2 MSI:             16 bits (I think)
-** Existing PCI devices:    32-bits (NCR c720/ATM/GigE/HyperFabric)
+** Existing PCI devices:    32-bits (all Symbios SCSI/ATM/HyperFabric)
 **
 ** On the service provider side:
 ** o PA 1.1 (and PA2.0 narrow mode)     5-bits (width of EIR register)
@@ -308,117 +360,204 @@
 		panic("Sorry -- didn't allocate valid IRQ for this device\n");
 	}
 
-	return(IRQ_OFFSET(virt_irq));
+	return (IRQ_OFFSET(virt_irq));
 }
 
-
-/* FIXME: SMP, flags, bottom halves, rest */
 void do_irq(struct irqaction *action, int irq, struct pt_regs * regs)
 {
 	int cpu = smp_processor_id();
 
 	irq_enter(cpu, irq);
+	++kstat.irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)];
 
-#ifdef DEBUG_IRQ
-	if (irq != TIMER_IRQ)
+	DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)));
+
+	for (; action; action = action->next) {
+#ifdef PARISC_IRQ_CR16_COUNTS
+		unsigned long cr_start = mfctl(16);
 #endif
-	DBG_IRQ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq));
-	if (action->handler == NULL)
-		printk(KERN_ERR "No handler for interrupt %d !\n", irq);
 
-	for(; action && action->handler; action = action->next) {
+		if (action->handler == NULL) {
+			if (IRQ_REGION(irq) == EISA_IRQ_REGION && irq_region[EISA_IRQ_REGION]) {
+				/* were we called due to autodetecting (E)ISA irqs ? */
+				unsigned int *status;
+				status = &irq_region[EISA_IRQ_REGION]->data.status[IRQ_OFFSET(irq)];
+				if (*status & IRQ_AUTODETECT) {
+					*status &= ~IRQ_WAITING;
+					continue; 
+				}
+			}
+			printk(KERN_ERR "IRQ:  CPU:%d No handler for IRQ %d !\n", cpu, irq);
+			continue;
+		}
+
 		action->handler(irq, action->dev_id, regs);
+
+#ifdef PARISC_IRQ_CR16_COUNTS
+		{
+			unsigned long cr_end = mfctl(16);
+			unsigned long tmp = cr_end - cr_start;
+			/* check for roll over */
+			cr_start = (cr_end < cr_start) ?  -(tmp) : (tmp);
+		}
+		action->cr16_hist[action->cr16_idx++] = (int) cr_start;
+		action->cr16_idx &= PARISC_CR16_HIST_SIZE - 1;
+#endif
 	}
-	
+
 	irq_exit(cpu, irq);
+}
+
+
+/* ONLY called from entry.S:intr_extint() */
+void do_cpu_irq_mask(struct irq_region *region, struct pt_regs *regs)
+{
+	unsigned long eirr_val;
+	unsigned int i=3;	/* limit time in interrupt context */
+
+	/*
+	 * PSW_I or EIEM bits cannot be enabled until after the
+	 * interrupts are processed.
+	 * timer_interrupt() assumes it won't get interrupted when it
+	 * holds the xtime_lock...an unmasked interrupt source could
+	 * interrupt and deadlock by trying to grab xtime_lock too.
+	 * Keeping PSW_I and EIEM disabled avoids this.
+	 */
+	set_eiem(0UL);	/* disable all extr interrupt for now */
+
+	/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
+	 * 2) We loop here on EIRR contents in order to avoid
+	 *    nested interrupts or having to take another interupt
+	 *    when we could have just handled it right away.
+	 * 3) Limit the number of times we loop to make sure other
+	 *    processing can occur.
+	 */
+	while ((eirr_val = (mfctl(23) & cpu_eiem)) && --i) {
+		unsigned long bit = (1UL<<MAX_CPU_IRQ);
+		unsigned int irq = 0;
+
+		mtctl(eirr_val, 23); /* reset bits we are going to process */
+
+#ifdef DEBUG_IRQ
+		if (eirr_val != (1UL << MAX_CPU_IRQ))
+			printk(KERN_DEBUG "do_cpu_irq_mask  %x\n", eirr_val);
+#endif
+
+		for (; eirr_val && bit; bit>>=1, irq++)
+		{
+			unsigned int irq_num;
+			if (!(bit&eirr_val))
+				continue;
 
-	/* don't need to care about unmasking and stuff */
-	do_softirq();
+			/* clear bit in mask - can exit loop sooner */
+			eirr_val &= ~bit;
+
+			irq_num = region->data.irqbase + irq;
+			do_irq(&region->action[irq], irq_num, regs);
+		}
+	}
+	set_eiem(cpu_eiem);
 }
 
+
+/* Called from second level IRQ regions: eg dino or iosapic. */
 void do_irq_mask(unsigned long mask, struct irq_region *region, struct pt_regs *regs)
 {
 	unsigned long bit;
-	int irq;
-	int cpu = smp_processor_id();
+	unsigned int irq;
 
 #ifdef DEBUG_IRQ
-	if (mask != (1L << MAX_CPU_IRQ))
-	    printk("do_irq_mask %08lx %p %p\n", mask, region, regs);
+	if (mask != (1L<<MAX_CPU_IRQ))
+	    printk(KERN_DEBUG "do_irq_mask %08lx %p %p\n", mask, region, regs);
 #endif
 
-	for(bit=(1L<<MAX_CPU_IRQ), irq = 0; mask && bit; bit>>=1, irq++) {
-		int irq_num;
-		if(!(bit&mask))
+	for (bit = (1L<<MAX_CPU_IRQ), irq = 0; mask && bit; bit>>=1, irq++) {
+		unsigned int irq_num;
+		if (!(bit&mask))
 			continue;
 
+		mask &= ~bit;	/* clear bit in mask - can exit loop sooner */
 		irq_num = region->data.irqbase + irq;
 
-		++kstat.irqs[cpu][IRQ_FROM_REGION(CPU_IRQ_REGION) | irq];
-		if (IRQ_REGION(irq_num) != CPU_IRQ_REGION)
-		    ++kstat.irqs[cpu][irq_num];
-
 		mask_irq(irq_num);
 		do_irq(&region->action[irq], irq_num, regs);
 		unmask_irq(irq_num);
 	}
 }
 
-static inline int alloc_irqregion(void)
+
+static inline int find_free_region(void)
 {
 	int irqreg;
 
-	for(irqreg=1; irqreg<=(NR_IRQ_REGS); irqreg++) {
-		if(irq_region[irqreg] == NULL)
+	for (irqreg=1; irqreg <= (NR_IRQ_REGS); irqreg++) {
+		if (irq_region[irqreg] == NULL)
 			return irqreg;
 	}
 
 	return 0;
 }
 
-struct irq_region *alloc_irq_region(
-	int count, struct irq_region_ops *ops, unsigned long flags,
-	const char *name, void *dev)
+
+/*****
+ * alloc_irq_region - allocate/init a new IRQ region
+ * @count: number of IRQs in this region.
+ * @ops: function table with request/release/mask/unmask/etc.. entries.
+ * @name: name of region owner for /proc/interrupts output.
+ * @dev: private data to associate with the new IRQ region.
+ *
+ * Every IRQ must become a MMIO write to the CPU's EIRR in
+ * order to get CPU service. The IRQ region represents the
+ * number of unique events the region handler can (or must)
+ * identify. For PARISC CPU, that's the width of the EIR Register.
+ * IRQ regions virtualize IRQs (eg EISA or PCI host bus controllers)
+ * for line based devices.
+ */
+struct irq_region *alloc_irq_region( int count, struct irq_region_ops *ops,
+					const char *name, void *dev)
 {
 	struct irq_region *region;
 	int index;
 
-	index = alloc_irqregion();
+	index = find_free_region();
+	if (index == 0) {
+		printk(KERN_ERR "Maximum number of irq regions exceeded. Increase NR_IRQ_REGS!\n");
+		return NULL;
+	}
 
-	if((IRQ_REGION(count-1)))
+	if ((IRQ_REGION(count-1)))
 		return NULL;
-	
+
 	if (count < IRQ_PER_REGION) {
-	    DBG_IRQ("alloc_irq_region() using minimum of %d irq lines for %s (%d)\n", 
-			IRQ_PER_REGION, name, count);
+	    DBG_IRQ(0, ("alloc_irq_region() using minimum of %d irq lines for %s (%d)\n",
+			IRQ_PER_REGION, name, count));
 	    count = IRQ_PER_REGION;
 	}
 
-	if(flags & IRQ_REG_MASK)
-		if(!(ops->mask_irq && ops->unmask_irq))
-			return NULL;
-			
-	if(flags & IRQ_REG_DIS)
-		if(!(ops->disable_irq && ops->enable_irq))
+	/* if either mask *or* unmask is set, both have to be set. */
+	if((ops->mask_irq || ops->unmask_irq) &&
+		!(ops->mask_irq && ops->unmask_irq))
 			return NULL;
 
-	if((irq_region[index]))
-		return NULL;
+	/* ditto for enable/disable */
+	if( (ops->disable_irq || ops->enable_irq) &&
+		!(ops->disable_irq && ops->enable_irq) )
+			return NULL;
 
-	region = kmalloc(sizeof *region, GFP_ATOMIC);
-	if(!region)
+	region = kmalloc(sizeof(*region), GFP_ATOMIC);
+	if (!region)
 		return NULL;
+	memset(region, 0, sizeof(*region));
 
-	region->action = kmalloc(sizeof *region->action * count, GFP_ATOMIC);
-	if(!region->action) {
+	region->action = kmalloc(count * sizeof(*region->action), GFP_ATOMIC);
+	if (!region->action) {
 		kfree(region);
 		return NULL;
 	}
-	memset(region->action, 0, sizeof *region->action * count);
+	memset(region->action, 0, count * sizeof(*region->action));
 
 	region->ops = *ops;
 	region->data.irqbase = IRQ_FROM_REGION(index);
-	region->data.flags = flags;
 	region->data.name = name;
 	region->data.dev = dev;
 
@@ -426,14 +565,12 @@
 
 	return irq_region[index];
 }
-	
 
-	
 /* FIXME: SMP, flags, bottom halves, rest */
 
-int request_irq(unsigned int irq, 
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -442,13 +579,19 @@
 #if 0
 	printk(KERN_INFO "request_irq(%d, %p, 0x%lx, %s, %p)\n",irq, handler, irqflags, devname, dev_id);
 #endif
-	if(!handler) {
+
+	irq = irq_cannonicalize(irq);
+	/* request_irq()/free_irq() may not be called from interrupt context. */
+	if (in_interrupt())
+		BUG();
+
+	if (!handler) {
 		printk(KERN_ERR "request_irq(%d,...): Augh! No handler for irq!\n",
 			irq);
 		return -EINVAL;
 	}
 
-	if ((IRQ_REGION(irq) == 0) || irq_region[IRQ_REGION(irq)] == NULL) {
+	if (irq_region[IRQ_REGION(irq)] == NULL) {
 		/*
 		** Bug catcher for drivers which use "char" or u8 for
 		** the IRQ number. They lose the region number which
@@ -459,19 +602,24 @@
 		return -EINVAL;
 	}
 
-	action = &irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)];
+	spin_lock(&irq_lock);
+	action = &(irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)]);
 
-	if(action->handler) {
-		while(action->next)
+	/* First one is preallocated. */
+	if (action->handler) {
+		/* But it's in use...find the tail and allocate a new one */
+		while (action->next)
 			action = action->next;
 
-		action->next = kmalloc(sizeof *action, GFP_ATOMIC);
+		action->next = kmalloc(sizeof(*action), GFP_ATOMIC);
+		memset(action->next, 0, sizeof(*action));
 
 		action = action->next;
-	}			
+	}
 
-	if(!action) {
-		printk(KERN_ERR "request_irq():Augh! No action!\n") ;
+	if (!action) {
+		spin_unlock(&irq_lock);
+		printk(KERN_ERR "request_irq(): Augh! No action!\n") ;
 		return -ENOMEM;
 	}
 
@@ -481,6 +629,7 @@
 	action->name = devname;
 	action->next = NULL;
 	action->dev_id = dev_id;
+	spin_unlock(&irq_lock);
 
 	enable_irq(irq);
 	return 0;
@@ -490,14 +639,22 @@
 {
 	struct irqaction *action, **p;
 
+	/* See comments in request_irq() about interrupt context */
+	irq = irq_cannonicalize(irq);
+	
+	if (in_interrupt()) BUG();
+
+	spin_lock(&irq_lock);
 	action = &irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)];
 
-	if(action->dev_id == dev_id) {
-		if(action->next == NULL)
+	if (action->dev_id == dev_id) {
+		if (action->next == NULL) {
 			action->handler = NULL;
-		else
-			memcpy(action, action->next, sizeof *action);
+		} else {
+			memcpy(action, action->next, sizeof(*action));
+		}
 
+		spin_unlock(&irq_lock);
 		return;
 	}
 
@@ -512,27 +669,175 @@
 		*p = action->next;
 		kfree(action);
 
+		spin_unlock(&irq_lock);
 		return;
 	}
 
+	spin_unlock(&irq_lock);
 	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
 }
 
-unsigned long probe_irq_on (void)
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+static DECLARE_MUTEX(probe_sem);
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+
+/* TODO: spin_lock_irq(desc->lock -> irq_lock) */
+
+unsigned long probe_irq_on(void)
 {
-	return 0;
+	unsigned int i;
+	unsigned long val;
+	unsigned long delay;
+	struct irq_region *region;
+
+	/* support for irq autoprobing is limited to EISA (irq region 0) */
+	region = irq_region[EISA_IRQ_REGION];
+	if (!EISA_bus || !region)
+		return 0;
+
+	down(&probe_sem);
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = EISA_MAX_IRQS-1; i > 0; i--) {
+		struct irqaction *action;
+		
+		spin_lock_irq(&irq_lock);
+		action = region->action + i;
+		if (!action->handler) {
+			region->data.status[i] |= IRQ_AUTODETECT | IRQ_WAITING;
+			region->ops.enable_irq(region->data.dev,i);
+		}
+		spin_unlock_irq(&irq_lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < EISA_MAX_IRQS; i++) {
+		unsigned int status;
+
+		spin_lock_irq(&irq_lock);
+		status = region->data.status[i];
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				region->data.status[i] = status & ~IRQ_AUTODETECT;
+				region->ops.disable_irq(region->data.dev,i);
+			} else
+				if (i < BITS_PER_LONG)
+					val |= (1 << i);
+		}
+		spin_unlock_irq(&irq_lock);
+	}
+
+	return val;
 }
 
-int probe_irq_off (unsigned long irqs)
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off	- end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+ 
+int probe_irq_off(unsigned long val)
 {
-	return 0;
+        struct irq_region *region;
+	int i, irq_found, nr_irqs;
+
+        /* support for irq autoprobing is limited to EISA (irq region 0) */
+        region = irq_region[EISA_IRQ_REGION];
+        if (!EISA_bus || !region)
+		return 0;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i = 0; i < EISA_MAX_IRQS; i++) {
+		unsigned int status;
+		
+		spin_lock_irq(&irq_lock);
+		status = region->data.status[i];
+
+                if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+			region->ops.disable_irq(region->data.dev,i);
+			region->data.status[i] = status & ~IRQ_AUTODETECT;
+		}
+		spin_unlock_irq(&irq_lock);
+	}
+	up(&probe_sem);
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
 }
 
 
 void __init init_IRQ(void)
 {
+	local_irq_disable();	/* PARANOID - should already be disabled */
+	mtctl(-1L, 23);		/* EIRR : clear all pending external intr */
+#ifdef CONFIG_SMP
+	if (!cpu_eiem)
+		cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
+#else
+	cpu_eiem = EIEM_MASK(TIMER_IRQ);
+#endif
+        set_eiem(cpu_eiem);	/* EIEM : enable all external intr */
+
 }
 
-void init_irq_proc(void)
+#ifdef CONFIG_PROC_FS
+/* called from kernel/sysctl.c:sysctl_init() */
+void __init init_irq_proc(void)
 {
 }
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/irq_smp.c linux-2.4.20/arch/parisc/kernel/irq_smp.c
--- linux-2.4.19/arch/parisc/kernel/irq_smp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/irq_smp.c	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,232 @@
+/*
+ *  linux/arch/parisc/kernel/irq_smp.c
+ *  (90% stolen from alpha port, 9% from ia64, rest is mine -ggg)
+ *  
+ *  Copyright (C) 2001 Hewlett-Packard Co
+ *  Copyright (C) 2001 Grant Grundler <grundler@puffin.external.hp.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+
+int global_irq_holder = NO_PROC_ID;	/* Who has global_irq_lock. */
+spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; /* protects IRQ's. */
+
+
+/* Global IRQ locking depth. */
+static void *previous_irqholder = NULL;
+
+#define MAXCOUNT 100000000
+
+
+static void
+show(char * str, void *where)
+{
+	int cpu = smp_processor_id();
+
+	printk("\n%s, CPU %d: %p\n", str, cpu, where);
+	printk("irq:  %d [%d %d]\n",
+		irqs_running(),
+		local_irq_count(0),
+		local_irq_count(1));
+
+	printk("bh:   %d [%d %d]\n",
+		spin_is_locked(&global_bh_lock) ? 1 : 0,
+		local_bh_count(0),
+		local_bh_count(1));
+}
+
+static inline void
+wait_on_irq(int cpu, void *where)
+{
+	int count = MAXCOUNT;
+
+	for (;;) {
+
+		/*
+		 * Wait until all interrupts are gone. Wait
+		 * for bottom half handlers unless we're
+		 * already executing in one..
+		 */
+		if (!irqs_running()) {
+			if (local_bh_count(cpu)
+			    || !spin_is_locked(&global_bh_lock))
+				break;
+		}
+
+		/* Duh, we have to loop. Release the lock to avoid deadlocks */
+		spin_unlock(&global_irq_lock);
+
+		for (;;) {
+			if (!--count) {
+				show("wait_on_irq", where);
+				count = MAXCOUNT;
+			}
+			__sti();
+			udelay(1); /* make sure to run pending irqs */
+			__cli();
+
+			if (irqs_running())
+				continue;
+			if (spin_is_locked(&global_irq_lock))
+				continue;
+			if (!local_bh_count(cpu)
+			    && spin_is_locked(&global_bh_lock))
+				continue;
+			if (spin_trylock(&global_irq_lock))
+				break;
+		}
+	}
+}
+
+static inline void
+get_irqlock(int cpu, void* where)
+{
+	if (!spin_trylock(&global_irq_lock)) {
+		/* Do we already hold the lock?  */
+		if (cpu == global_irq_holder)
+			return;
+		/* Uhhuh.. Somebody else got it.  Wait.  */
+		spin_lock(&global_irq_lock);
+	}
+
+	/*
+	 * Ok, we got the lock bit.
+	 * But that's actually just the easy part.. Now
+	 * we need to make sure that nobody else is running
+	 * in an interrupt context. 
+	 */
+	wait_on_irq(cpu, where);
+
+	/*
+	 * Finally.
+	 */
+#if DEBUG_SPINLOCK
+	global_irq_lock.task = current;
+	global_irq_lock.previous = where;
+#endif
+	global_irq_holder = cpu;
+	previous_irqholder = where;
+}
+
+
+/*
+** A global "cli()" while in an interrupt context
+** turns into just a local cli(). Interrupts
+** should use spinlocks for the (very unlikely)
+** case that they ever want to protect against
+** each other.
+** 
+** If we already have local interrupts disabled,
+** this will not turn a local disable into a
+** global one (problems with spinlocks: this makes
+** save_flags+cli+sti usable inside a spinlock).
+*/
+void
+__global_cli(void)
+{
+	unsigned int flags;
+	__save_flags(flags);
+	if (flags & PSW_I) {
+		int cpu = smp_processor_id();
+		__cli(); 
+		if (!local_irq_count(cpu)) {
+			void *where = __builtin_return_address(0);
+			get_irqlock(cpu, where);
+		}
+	}
+}
+
+void
+__global_sti(void)
+{
+	int cpu = smp_processor_id();
+
+	if (!local_irq_count(cpu))
+		release_irqlock(cpu);
+	__sti();
+}
+
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
+unsigned long
+__global_save_flags(void)
+{
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+	int cpu = smp_processor_id();
+
+	__save_flags(flags);
+	local_enabled = (flags & PSW_I) != 0;
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	/* Check for global flags if we're not in an interrupt.  */
+	if (!local_irq_count(cpu)) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == cpu)
+			retval = 0;
+	}
+	return retval;
+}
+
+void
+__global_restore_flags(unsigned long flags)
+{
+	switch (flags) {
+	case 0:
+		__global_cli();
+		break;
+	case 1:
+		__global_sti();
+		break;
+	case 2:
+		__cli();
+		break;
+	case 3:
+		__sti();
+		break;
+	default:
+		printk(KERN_ERR "global_restore_flags: %08lx (%p)\n",
+			flags, __builtin_return_address(0));
+	}
+}
+
+/*
+ * From its use, I infer that synchronize_irq() stalls a thread until
+ * the effects of a command to an external device are known to have
+ * taken hold.  Typically, the command is to stop sending interrupts.
+ * The strategy here is wait until there is at most one processor
+ * (this one) in an irq.  The memory barrier serializes the write to
+ * the device and the subsequent accesses of global_irq_count.
+ * --jmartin
+ */
+#define DEBUG_SYNCHRONIZE_IRQ 0
+
+void
+synchronize_irq(void)
+{
+	/* Jay's version.  */
+	if (irqs_running()) {
+		cli();
+		sti();
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/keyboard.c linux-2.4.20/arch/parisc/kernel/keyboard.c
--- linux-2.4.19/arch/parisc/kernel/keyboard.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/keyboard.c	2002-10-04 00:41:13.000000000 +0000
@@ -1,4 +1,12 @@
 /*
+ *  WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *  ---------------------------------------------------------------
+ *  This source file will be removed as soon as we have converted
+ *  hp_psaux.c and hp_keyb.c to the input layer !
+ *  
+ */
+
+/*
  *  linux/arch/parisc/kernel/keyboard.c
  *
  *  Alex deVries <adevries@thepuffingroup.com>
@@ -7,8 +15,10 @@
  *  Copyright 2000 Philipp Rumpf
  */
 
+#include <linux/errno.h>
 #include <linux/keyboard.h>
 #include <asm/keyboard.h>
+#include <linux/module.h>
 
 static int def_setkeycode(unsigned int x, unsigned int y)
 {
@@ -43,20 +53,29 @@
 
 static char def_sysrq_xlate[NR_KEYS];
 
-static struct kbd_ops def_kbd_ops = {
-	setkeycode:	def_setkeycode,
-	getkeycode:	def_getkeycode,
-	translate:	def_translate,
-	unexpected_up:	def_unexpected_up,
-	leds:		def_leds,
-	init_hw:	def_init_hw,
-
-	sysrq_key:	0xff,
+#define DEFAULT_KEYB_OPS \
+	setkeycode:	def_setkeycode,	\
+	getkeycode:	def_getkeycode, \
+	translate:	def_translate, \
+	unexpected_up:	def_unexpected_up, \
+	leds:		def_leds, \
+	init_hw:	def_init_hw, \
+	sysrq_key:	0xff, \
 	sysrq_xlate:	def_sysrq_xlate,
+
+static struct kbd_ops def_kbd_ops = {
+	DEFAULT_KEYB_OPS
 };
 
 struct kbd_ops *kbd_ops = &def_kbd_ops;
 
+void unregister_kbd_ops(void)
+{
+	struct kbd_ops new_kbd_ops = { DEFAULT_KEYB_OPS };
+	register_kbd_ops(&new_kbd_ops);
+}
+EXPORT_SYMBOL(unregister_kbd_ops);
+
 void register_kbd_ops(struct kbd_ops *ops)
 {
 	if(ops->setkeycode)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/lba_pci.c linux-2.4.20/arch/parisc/kernel/lba_pci.c
--- linux-2.4.19/arch/parisc/kernel/lba_pci.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/lba_pci.c	2002-10-04 00:41:23.000000000 +0000
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>		/* for __init and __devinit */
+/* #define PCI_DEBUG	enable ASSERT */
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
@@ -42,15 +43,13 @@
 #include <asm/byteorder.h>
 #include <asm/irq.h>		/* for struct irq_region support */
 #include <asm/pdc.h>
-#include <asm/pdcpat.h>
 #include <asm/page.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 
-#include <asm/hardware.h>	/* for register_driver() stuff */
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
 #include <asm/iosapic.h>	/* for iosapic_register() */
-#include <asm/gsc.h>		/* gsc_read/write stuff */
-
+#include <asm/io.h>		/* read/write stuff */
 
 #ifndef TRUE
 #define TRUE (1 == 1)
@@ -62,6 +61,9 @@
 #undef DEBUG_LBA_CFG	/* debug Config Space Access (ie PCI Bus walk) */
 #undef DEBUG_LBA_PAT	/* debug PCI Resource Mgt code - PDC PAT only */
 
+#undef FBB_SUPPORT	/* Fast Back-Back xfers - NOT READY YET */
+
+
 #ifdef DEBUG_LBA
 #define DBG(x...)	printk(x)
 #else
@@ -102,22 +104,6 @@
 
 #define MODULE_NAME "lba"
 
-static int lba_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-
-static struct pa_iodc_driver lba_drivers_for[]= {
-
-   {HPHW_BRIDGE, 0x782, 0x0, 0xa, 0,0,
-		DRIVER_CHECK_HVERSION + 
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "tbd", (void *) lba_driver_callback},
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL}
-};
-
-
 #define LBA_FUNC_ID	0x0000	/* function id */
 #define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
 #define LBA_CAPABLE	0x0030	/* capabilities register */
@@ -137,6 +123,9 @@
 #define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */
 
 #define LBA_STAT_CTL	0x0108	/* Status & Control */
+#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
+#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
+#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
 #define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */
 
 #define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
@@ -162,15 +151,18 @@
 
 #define LBA_DMA_CTL	0x0278	/* firmware sets this */
 
-/* RESET: ignore DMA stuff until we can measure performance */
-#define LBA_IBASE	0x0300	/* DMA support */
+#define LBA_IBASE	0x0300	/* SBA DMA support */
 #define LBA_IMASK	0x0308
+
+/* FIXME: ignore DMA Hint stuff until we can measure performance */
 #define LBA_HINT_CFG	0x0310
 #define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */
 
 /* ERROR regs are needed for config cycle kluges */
 #define LBA_ERROR_CONFIG 0x0680
+#define     LBA_SMART_MODE 0x20
 #define LBA_ERROR_STATUS 0x0688
+#define LBA_ROPE_CTL     0x06A0
 
 #define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */
 
@@ -232,19 +224,20 @@
  * BE WARNED: register writes are posted.
  *  (ie follow writes which must reach HW with a read)
  */
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr)  gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
+#define READ_U8(addr)  __raw_readb(addr)
+#define READ_U16(addr) __raw_readw(addr)
+#define READ_U32(addr) __raw_readl(addr)
+#define WRITE_U8(value, addr)  __raw_writeb(value, addr)
+#define WRITE_U16(value, addr) __raw_writew(value, addr)
+#define WRITE_U32(value, addr) __raw_writel(value, addr)
+
+#define READ_REG8(addr)  readb(addr)
+#define READ_REG16(addr) readw(addr)
+#define READ_REG32(addr) readl(addr)
+#define READ_REG64(addr) readq(addr)
+#define WRITE_REG8(value, addr)  writeb(value, addr)
+#define WRITE_REG16(value, addr) writew(value, addr)
+#define WRITE_REG32(value, addr) writel(value, addr)
 
 
 #define LBA_CFG_TOK(bus,dfn) ((u32) ((bus)<<16 | (dfn)<<8))
@@ -253,25 +246,12 @@
 #define LBA_CFG_FUNC(tok) ((u8) ((tok)>>8 ) & 0x7)
 
 
-#ifdef DEBUG_LBA
-/* Extract LBA (Rope) number from HPA */
-#define LBA_NUM(x)    ((((uintptr_t) x) >> 13) & 0xf)
-#endif /* DEBUG_LBA */
-
-#ifdef __LP64__
-/* PDC_PAT */
-static  unsigned long pdc_result[32] __attribute__ ((aligned (8))) = {0,0,0,0};
-#endif
-
 /*
-** One time initialization to let the world know the LBA was found.
-** This is the only routine which is NOT static.
-** Must be called exactly once before pci_init().
+** Extract LBA (Rope) number from HPA
+** REVISIT: 16 ropes for Stretch/Ike?
 */
-void __init lba_init(void)
-{
-	register_driver(lba_drivers_for);
-}
+#define ROPES_PER_SBA	8
+#define LBA_NUM(x)    ((((unsigned long) x) >> 13) & (ROPES_PER_SBA-1))
 
 
 static void
@@ -282,9 +262,9 @@
 	if (NULL == r)
 		return;
 
-	printk("(%p)", r->parent);
+	printk(KERN_DEBUG "(%p)", r->parent);
 	for (i = d; i ; --i) printk(" ");
-	printk("%p [%lx,%lx]/%x\n", r, r->start, r->end, (int) r->flags);
+	printk(KERN_DEBUG "%p [%lx,%lx]/%x\n", r, r->start, r->end, (int) r->flags);
 	lba_dump_res(r->child, d+2);
 	lba_dump_res(r->sibling, d);
 }
@@ -369,7 +349,7 @@
      * Set the smart mode bit so that master aborts don't cause		\
      * LBA to go into PCI fatal mode (required).			\
      */									\
-    WRITE_REG32(error_config | 0x20, d->hba.base_addr + LBA_ERROR_CONFIG);	\
+    WRITE_REG32(error_config | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG);	\
 }
 
 
@@ -414,9 +394,9 @@
  *
  *		Actually, there is still a race in which
  *		we could be clearing a fatal error.  We will
- *		live with this during our real mode bus walk
+ *		live with this during our initial bus walk
  *		until rev 4.0 (no driver activity during
- *		real mode bus walk).  The real mode bus walk
+ *		initial bus walk).  The initial bus walk
  *		has race conditions concerning the use of
  *		smart mode as well.
  */
@@ -430,7 +410,7 @@
      * Set clear enable (CE) bit. Unset by HW when new			\
      * errors are logged -- LBA HW ERS section 14.3.3).		\
      */									\
-    WRITE_REG32(status_control | 0x20, base + LBA_STAT_CTL);	\
+    WRITE_REG32(status_control | CLEAR_ERRLOG_ENABLE, base + LBA_STAT_CTL); \
     error_status = READ_REG32(base + LBA_ERROR_STATUS);		\
     if ((error_status & 0x1f) != 0) {					\
 	/*								\
@@ -442,7 +422,7 @@
 	     * Clear error status (if fatal bit not set) by setting	\
 	     * clear error log bit (CL).				\
 	     */								\
-	    WRITE_REG32(status_control | 0x10, base + LBA_STAT_CTL);	\
+	    WRITE_REG32(status_control | CLEAR_ERRLOG, base + LBA_STAT_CTL); \
 	}								\
     }									\
 }
@@ -483,7 +463,7 @@
 
 
 static unsigned int
-lba_rd_cfg( struct lba_device *d, u32 tok, u8 reg, u32 size)
+lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
 {
 	u32 data = ~0;
 	int error = 0;
@@ -525,7 +505,6 @@
 }
 
 
-
 #define LBA_CFG_RD(size, mask) \
 static int lba_cfg_read##size (struct pci_dev *dev, int pos, u##size *data) \
 { \
@@ -533,17 +512,18 @@
 	u32 local_bus = (dev->bus->parent == NULL) ? 0 : dev->bus->secondary; \
 	u32 tok = LBA_CFG_TOK(local_bus,dev->devfn); \
  \
-	if ((!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
+/* FIXME: B2K/C3600 workaround is always use old method... */ \
+	/* if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) */ { \
 		/* original - Generate config cycle on broken elroy \
 		  with risk we will miss PCI bus errors. */ \
 		*data = (u##size) lba_rd_cfg(d, tok, pos, sizeof(u##size)); \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, *data); \
+		DBG_CFG("%s(%s+%2x) -> 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, *data); \
 		return(*data == (u##size) -1); \
 	} \
  \
 	if (LBA_SKIP_PROBE(d) && (!lba_device_present(dev->bus->secondary, dev->devfn, d))) \
 	{ \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> -1 (b)\n", __FUNCTION__, dev->slot_name, pos, *data); \
+		DBG_CFG("%s(%s+%2x) -> -1 (b)\n", __FUNCTION__, dev->slot_name, pos); \
 		/* either don't want to look or know device isn't present. */ \
 		*data = (u##size) -1; \
 		return(0); \
@@ -555,7 +535,7 @@
 	*/ \
 	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); \
 	*data = READ_REG##size(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & mask));\
-	DBG_CFG(KERN_DEBUG "%s(%s+%2x) -> 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, *data);\
+	DBG_CFG("%s(%s+%2x) -> 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, *data);\
 	return(*data == (u##size) -1); \
 }
 
@@ -618,19 +598,19 @@
  	ASSERT((tok & 0xff) == 0); \
 	ASSERT(pos < 0x100); \
  \
-	if ((!LBA_TR4PLUS(d)) && (!LBA_SKIP_PROBE(d))) { \
+	if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) { \
 		/* Original Workaround */ \
 		lba_wr_cfg(d, tok, pos, (u32) data, sizeof(u##size)); \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, data); \
+		DBG_CFG("%s(%s+%2x) = 0x%x (a)\n", __FUNCTION__, dev->slot_name, pos, data); \
 		return 0; \
 	} \
  \
 	if (LBA_SKIP_PROBE(d) && (!lba_device_present(dev->bus->secondary, dev->devfn, d))) { \
-		DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (b)\n", __FUNCTION__, dev->slot_name, pos, data); \
+		DBG_CFG("%s(%s+%2x) = 0x%x (b)\n", __FUNCTION__, dev->slot_name, pos, data); \
 		return 1; /* New Workaround */ \
 	} \
  \
-	DBG_CFG(KERN_DEBUG "%s(%s+%2x) = 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, data); \
+	DBG_CFG("%s(%s+%2x) = 0x%x (c)\n", __FUNCTION__, dev->slot_name, pos, data); \
 	/* Basic Algorithm */ \
 	LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); \
 	WRITE_REG##size(data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & mask)); \
@@ -644,9 +624,12 @@
 LBA_CFG_WR(32, 0) 
 
 static struct pci_ops lba_cfg_ops = {
-        lba_cfg_read8, lba_cfg_read16, lba_cfg_read32,
-	lba_cfg_write8, lba_cfg_write16, lba_cfg_write32
-
+	read_byte:	lba_cfg_read8,
+	read_word:	lba_cfg_read16,
+	read_dword:	lba_cfg_read32,
+	write_byte:	lba_cfg_write8,
+	write_word:	lba_cfg_write16,
+	write_dword:	lba_cfg_write32
 };
 
 
@@ -654,7 +637,7 @@
 static void
 lba_bios_init(void)
 {
-	DBG(KERN_DEBUG MODULE_NAME ": lba_bios_init\n");
+	DBG(MODULE_NAME ": lba_bios_init\n");
 }
 
 
@@ -712,15 +695,15 @@
 lba_fixup_bus(struct pci_bus *bus)
 {
 	struct list_head *ln;
-        struct pci_dev *dev;
+#ifdef FBB_SUPPORT
 	u16 fbb_enable = PCI_STATUS_FAST_BACK;
 	u16 status;
-	struct lba_device *ldev = LBA_DEV(bus->sysdata);
-#ifdef __LP64__
-	int i;
 #endif
+	struct lba_device *ldev = LBA_DEV(bus->sysdata);
+	int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
+
 	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
-				bus, bus->secondary, bus->sysdata);
+		bus, bus->secondary, bus->sysdata);
 
 	/*
 	** Properly Setup MMIO resources for this bus.
@@ -731,63 +714,119 @@
 
 		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
 			ldev->hba.io_space.name,
-			ldev->hba.io_space.start,
-			ldev->hba.io_space.end,
+			ldev->hba.io_space.start, ldev->hba.io_space.end,
 			(int) ldev->hba.io_space.flags);
 		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
-			ldev->hba.mem_space.name,
-			ldev->hba.mem_space.start,
-			ldev->hba.mem_space.end,
-			(int) ldev->hba.mem_space.flags);
+			ldev->hba.lmmio_space.name,
+			ldev->hba.lmmio_space.start, ldev->hba.lmmio_space.end,
+			(int) ldev->hba.lmmio_space.flags);
 
 		err = request_resource(&ioport_resource, &(ldev->hba.io_space));
 		if (err < 0) {
 			BUG();
 			lba_dump_res(&ioport_resource, 2);
 		}
-		err = request_resource(&iomem_resource, &(ldev->hba.mem_space));
+		err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
 		if (err < 0) {
 			BUG();
 			lba_dump_res(&iomem_resource, 2);
 		}
 
 		bus->resource[0] = &(ldev->hba.io_space);
-		bus->resource[1] = &(ldev->hba.mem_space);
+		bus->resource[1] = &(ldev->hba.lmmio_space);
+	} else {
+		/* KLUGE ALERT!
+		** PCI-PCI Bridge resource munging.
+		** This hack should go away in the near future.
+		** It's based on the Alpha port.
+		*/
+		int i;
+		u16 cmd;
+
+		for (i = 0; i < 4; i++) {
+			bus->resource[i] =
+				&bus->self->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+#if 0
+		bus->resource[0]->flags |= pci_bridge_check_io(bus->self);
+#else
+		bus->resource[0]->flags |= IORESOURCE_IO;
+#endif
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+		bus->resource[2]->flags = 0;	/* Don't support prefetchable */
+		bus->resource[3]->flags = 0;	/* not used */
+
+		/* 
+		** If the PPB is enabled (ie already configured) then
+		** just read those values.
+		*/
+		(void) lba_cfg_read16(bus->self, PCI_COMMAND, &cmd);
+		if (cmd & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) {
+			pci_read_bridge_bases(bus);
+		} else {
+			/* Not configured.
+			** For now, propogate HBA limits to the bus;
+			**	PCI will adjust them later.
+			*/
+			bus->resource[0]->end = ldev->hba.io_space.end;
+			bus->resource[1]->end = ldev->hba.lmmio_space.end;
+		}
+
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
 	}
 
-	list_for_each(ln, &bus->devices) {
 
-		dev = pci_dev_b(ln);
+	list_for_each(ln, &bus->devices) {
+		int i;
+		struct pci_dev *dev = pci_dev_b(ln);
 
-#ifdef __LP64__
-		/*
-		** 0-5 are the "standard PCI regions"
-		** (see comments near PCI_NUM_RESOURCES in include/linux/pci.h)
-		*/
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *res = &(dev->resource[i]);
+		DBG("lba_fixup_bus() %s\n", dev->name);
 
-			if (res->flags & IORESOURCE_MEM) {
-				/* "Globalize" PCI address */
-				res->start |= ldev->lmmio_base;
-				res->end   |= ldev->lmmio_base;
+		/* Virtualize Device/Bridge Resources. */
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *res = &dev->resource[i];
+
+			/* If resource not allocated - skip it */
+			if (!res->start)
+				continue;
+
+			if (res->flags & IORESOURCE_IO) {
+				DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
+					res->start, res->end);
+				res->start |= lba_portbase;
+				res->end   |= lba_portbase;
+				DBG("[%lx/%lx]\n", res->start, res->end);
+			} else if (res->flags & IORESOURCE_MEM) {
+				/*
+				** Convert PCI (IO_VIEW) addresses to
+				** processor (PA_VIEW) addresses
+				 */
+				DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
+					res->start, res->end);
+				res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
+				res->end   = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
+				DBG("[%lx/%lx]\n", res->start, res->end);
 			}
 		}
-#endif
 
+#ifdef FBB_SUPPORT
 		/*
 		** If one device does not support FBB transfers,
 		** No one on the bus can be allowed to use them.
 		*/
 		(void) lba_cfg_read16(dev, PCI_STATUS, &status);
 		fbb_enable &= status;
+#endif
 
 #ifdef __LP64__
-		if (pdc_pat) {
+		if (is_pdc_pat()) {
 			/* Claim resources for PDC's devices */
 			lba_claim_dev_resources(dev);
 		}
-#endif	/* __LP64__ */
+#endif
 
                 /*
 		** P2PB's have no IRQs. ignore them.
@@ -796,12 +835,12 @@
 			continue;
 
 		/* Adjust INTERRUPT_LINE for this dev */
-		iosapic_fixup_irq(LBA_DEV(bus->sysdata)->iosapic_obj, dev);
+		iosapic_fixup_irq(ldev->iosapic_obj, dev);
 	}
 
-#if 0
+#ifdef FBB_SUPPORT
 /* FIXME/REVISIT - finish figuring out to set FBB on both
-** pbus_set_ranges() clobbers PCI_BRIDGE_CONTROL.
+** pci_setup_bridge() clobbers PCI_BRIDGE_CONTROL.
 ** Can't fixup here anyway....garr...
 */
 	if (fbb_enable) {
@@ -828,8 +867,8 @@
 
 
 struct pci_bios_ops lba_bios_ops = {
-	lba_bios_init,
-	lba_fixup_bus  /* void lba_fixup_bus(struct pci_bus *bus) */
+	init:		lba_bios_init,
+	fixup_bus:	lba_fixup_bus,
 };
 
 
@@ -853,8 +892,6 @@
 static u##size lba_astro_in##size (struct pci_hba_data *d, u16 addr) \
 { \
 	u##size t; \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x) ->", __FUNCTION__, bus, addr); \
 	t = READ_REG##size(LBA_ASTRO_PORT_BASE + addr); \
 	DBG_PORT(" 0x%x\n", t); \
 	return (t); \
@@ -895,8 +932,8 @@
 #define LBA_PORT_OUT(size, mask) \
 static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
 { \
-	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
+	ASSERT(d != NULL); \
+	DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
 	WRITE_REG##size(val, LBA_ASTRO_PORT_BASE + addr); \
 	if (LBA_DEV(d)->hw_rev < 3) \
 		lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
@@ -908,13 +945,16 @@
 
 
 static struct pci_port_ops lba_astro_port_ops = {
-	lba_astro_in8, lba_astro_in16, lba_astro_in32,
-	lba_astro_out8, lba_astro_out16, lba_astro_out32
+	inb:	lba_astro_in8,
+	inw:	lba_astro_in16,
+	inl:	lba_astro_in32,
+	outb:	lba_astro_out8,
+	outw:	lba_astro_out16,
+	outl:	lba_astro_out32
 };
 
 
 #ifdef __LP64__
-
 #define PIOP_TO_GMMIO(lba, addr) \
 	((lba)->iop_base + (((addr)&0xFFFC)<<10) + ((addr)&3))
 
@@ -936,7 +976,7 @@
 { \
 	u##size t; \
 	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
+	DBG_PORT("%s(0x%p, 0x%x) ->", __FUNCTION__, l, addr); \
 	t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
 	DBG_PORT(" 0x%x\n", t); \
 	return (t); \
@@ -953,7 +993,7 @@
 { \
 	void *where = (void *) PIOP_TO_GMMIO(LBA_DEV(l), addr); \
 	ASSERT(bus != NULL); \
-	DBG_PORT(KERN_DEBUG "%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
+	DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, l, addr, val); \
 	WRITE_REG##size(val, where); \
 	/* flush the I/O down to the elroy at least */ \
 	lba_t32 = READ_U32(l->base_addr + LBA_FUNC_ID); \
@@ -965,8 +1005,12 @@
 
 
 static struct pci_port_ops lba_pat_port_ops = {
-	lba_pat_in8, lba_pat_in16, lba_pat_in32,
-	lba_pat_out8, lba_pat_out16, lba_pat_out32
+	inb:	lba_pat_in8,
+	inw:	lba_pat_in16,
+	inl:	lba_pat_in32,
+	outb:	lba_pat_out8,
+	outw:	lba_pat_out16,
+	outl:	lba_pat_out32
 };
 
 
@@ -978,30 +1022,27 @@
 ** We don't have a struct pci_bus assigned to us yet.
 */
 static void
-lba_pat_resources( struct hp_device *d, struct lba_device *lba_dev)
+lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 {
+	unsigned long bytecnt;
 	pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;	/* PA_VIEW */
-#ifdef DONT_NEED_THIS_FOR_ASTRO
 	pdc_pat_cell_mod_maddr_block_t io_pdc_cell;	/* IO_VIEW */
 	long io_count;
-#endif
 	long status;	/* PDC return status */
 	long pa_count;
 	int i;
 
 	/* return cell module (IO view) */
-	status = pdc_pat_cell_module(& pdc_result, d->pcell_loc, d->mod_index,
+	status = pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
 				PA_VIEW, & pa_pdc_cell);
 	pa_count = pa_pdc_cell.mod[1];
 
-#ifdef DONT_NEED_THIS_FOR_ASTRO
-	status |= pdc_pat_cell_module(& pdc_result, d->pcell_loc, d->mod_index,
-				IO_VIEW, & io_pdc_cell);
+	status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
+				IO_VIEW, &io_pdc_cell);
 	io_count = io_pdc_cell.mod[1];
-#endif
 
 	/* We've already done this once for device discovery...*/
-	if (status != PDC_RET_OK) {
+	if (status != PDC_OK) {
 		panic("pdc_pat_cell_module() call failed for LBA!\n");
 	}
 
@@ -1017,10 +1058,11 @@
 			unsigned long type;
 			unsigned long start;
 			unsigned long end;	/* aka finish */
-		} *p;
+		} *p, *io;
 		struct resource *r;
 
 		p = (void *) &(pa_pdc_cell.mod[2+i*3]);
+		io = (void *) &(io_pdc_cell.mod[2+i*3]);
 
 		/* Convert the PAT range data to PCI "struct resource" */
 		switch(p->type & 0xff) {
@@ -1030,9 +1072,9 @@
 			break;
 		case PAT_LMMIO:
 			/* used to fix up pre-initialized MEM BARs */
-			lba_dev->lmmio_base = p->start;
+			lba_dev->hba.lmmio_space_offset = p->start - io->start;
 
-			r = &(lba_dev->hba.mem_space);
+			r = &(lba_dev->hba.lmmio_space);
 			r->name   = "LBA LMMIO";
 			r->start  = p->start;
 			r->end    = p->end;
@@ -1060,8 +1102,8 @@
 
 			r = &(lba_dev->hba.io_space);
 			r->name   = "LBA I/O Port";
-			r->start = lba_dev->hba.hba_num << 16;
-			r->end   = r->start + 0xffffUL;
+			r->start  = HBA_PORT_BASE(lba_dev->hba.hba_num);
+			r->end    = r->start + HBA_PORT_SPACE_SIZE - 1;
 			r->flags  = IORESOURCE_IO;
 			r->parent = r->sibling = r->child = NULL;
 			break;
@@ -1077,17 +1119,22 @@
 
 
 static void
-lba_legacy_resources( struct hp_device *d, struct lba_device *lba_dev)
+lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 {
-	int lba_num;
 	struct resource *r;
+	unsigned long rsize;
+	int lba_num;
+
 #ifdef __LP64__
 	/*
-	** Used to sign extend instead BAR values are only 32-bit.
-	** 64-bit BARs have the upper 32-bit's zero'd by firmware.
-	** "Sprockets" PDC initializes for 32-bit OS.
+	** Sign extend all BAR values on "legacy" platforms.
+	** "Sprockets" PDC (Forte/Allegro) initializes everything
+	** for "legacy" 32-bit OS (HPUX 10.20).
+	** Upper 32-bits of 64-bit BAR will be zero too.
 	*/
-	lba_dev->lmmio_base = 0xffffffff00000000UL;
+	lba_dev->hba.lmmio_space_offset = 0xffffffff00000000UL;
+#else
+	lba_dev->hba.lmmio_space_offset = 0UL;
 #endif
 
 	/*
@@ -1097,7 +1144,7 @@
 	** PCI bus walk *should* end up with the same result.
 	** FIXME: But we don't have sanity checks in PCI or LBA.
 	*/
-	lba_num = READ_REG32(d->hpa + LBA_FW_SCRATCH);
+	lba_num = READ_REG32(pa_dev->hpa + LBA_FW_SCRATCH);
 	r = &(lba_dev->hba.bus_num);
 	r->name = "LBA PCI Busses";
 	r->start = lba_num & 0xff;
@@ -1106,19 +1153,67 @@
 	/* Set up local PCI Bus resources - we don't really need
 	** them for Legacy boxes but it's nice to see in /proc.
 	*/
-	r = &(lba_dev->hba.mem_space);
+	r = &(lba_dev->hba.lmmio_space);
 	r->name  = "LBA PCI LMMIO";
 	r->flags = IORESOURCE_MEM;
-	r->start = READ_REG32(d->hpa + LBA_LMMIO_BASE);
-	r->end   = r->start + ~ (READ_REG32(d->hpa + LBA_LMMIO_MASK));
+	/* Ignore "Range Enable" bit in the BASE register */
+	r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev),
+		((long) READ_REG32(pa_dev->hpa + LBA_LMMIO_BASE)) & ~1UL);
+	rsize =  ~READ_REG32(pa_dev->hpa + LBA_LMMIO_MASK) + 1;
+
+	/*
+	** Each rope only gets part of the distributed range.
+	** Adjust "window" for this rope
+	*/
+	rsize /= ROPES_PER_SBA;
+	r->start += rsize * LBA_NUM(pa_dev->hpa);
+	r->end = r->start + rsize - 1 ;
+
+	/*
+	** XXX FIXME - ignore LBA_ELMMIO_BASE for now
+	** "Directed" ranges are used when the "distributed range" isn't
+	** sufficient for all devices below a given LBA.  Typically devices
+	** like graphics cards or X25 may need a directed range when the
+	** bus has multiple slots (ie multiple devices) or the device
+	** needs more than the typical 4 or 8MB a distributed range offers.
+	**
+	** The main reason for ignoring it now frigging complications.
+	** Directed ranges may overlap (and have precedence) over
+	** distributed ranges. Ie a distributed range assigned to a unused
+	** rope may be used by a directed range on a different rope.
+	** Support for graphics devices may require fixing this
+	** since they may be assigned a directed range which overlaps
+	** an existing (but unused portion of) distributed range.
+	*/
+	r = &(lba_dev->hba.elmmio_space);
+	r->name  = "extra LBA PCI LMMIO";
+	r->flags = IORESOURCE_MEM;
+	r->start = READ_REG32(pa_dev->hpa + LBA_ELMMIO_BASE);
+	r->end   = 0;
+
+	/* check Range Enable bit */
+	if (r->start & 1) {
+		/* First baby step to getting Direct Ranges listed in /proc.
+		** AFAIK, only Sprockets PDC will setup a directed Range.
+		*/
+
+		r->start &= ~1;
+		r->end    = r->start;
+		r->end   += ~READ_REG32(pa_dev->hpa + LBA_ELMMIO_MASK);
+		printk(KERN_DEBUG "WARNING: Ignoring enabled ELMMIO BASE 0x%0lx  SIZE 0x%lx\n",
+			r->start,
+			r->end + 1);
+
+	}
 
 	r = &(lba_dev->hba.io_space);
 	r->name  = "LBA PCI I/O Ports";
 	r->flags = IORESOURCE_IO;
-	r->start = READ_REG32(d->hpa + LBA_IOS_BASE);
-	r->end   = r->start + (READ_REG32(d->hpa + LBA_IOS_MASK) ^ 0xffff);
+	r->start = READ_REG32(pa_dev->hpa + LBA_IOS_BASE) & ~1L;
+	r->end   = r->start + (READ_REG32(pa_dev->hpa + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
 
-	lba_num = lba_dev->hba.hba_num << 16;
+	/* Virtualize the I/O Port space ranges */
+	lba_num = HBA_PORT_BASE(lba_dev->hba.hba_num);
 	r->start |= lba_num;
 	r->end   |= lba_num;
 }
@@ -1136,29 +1231,92 @@
 **
 **************************************************************************/
 
-static void
+static int __init
 lba_hw_init(struct lba_device *d)
 {
 	u32 stat;
+	u32 bus_reset;	/* PDC_PAT_BUG */
+
+#if 0
+	printk(KERN_DEBUG "LBA %lx  STAT_CTL %Lx  ERROR_CFG %Lx  STATUS %Lx DMA_CTL %Lx\n",
+		d->hba.base_addr,
+		READ_REG64(d->hba.base_addr + LBA_STAT_CTL),
+		READ_REG64(d->hba.base_addr + LBA_ERROR_CONFIG),
+		READ_REG64(d->hba.base_addr + LBA_ERROR_STATUS),
+		READ_REG64(d->hba.base_addr + LBA_DMA_CTL) );
+	printk(KERN_DEBUG "	ARB mask %Lx  pri %Lx  mode %Lx  mtlt %Lx\n",
+		READ_REG64(d->hba.base_addr + LBA_ARB_MASK),
+		READ_REG64(d->hba.base_addr + LBA_ARB_PRI),
+		READ_REG64(d->hba.base_addr + LBA_ARB_MODE),
+		READ_REG64(d->hba.base_addr + LBA_ARB_MTLT) );
+	printk(KERN_DEBUG "	HINT cfg 0x%Lx\n",
+		READ_REG64(d->hba.base_addr + LBA_HINT_CFG));
+	printk(KERN_DEBUG "	HINT reg ");
+	{ int i;
+	for (i=LBA_HINT_BASE; i< (14*8 + LBA_HINT_BASE); i+=8)
+		printk(" %Lx", READ_REG64(d->hba.base_addr + i));
+	}
+	printk("\n");
+#endif	/* DEBUG_LBA_PAT */
+
+#ifdef __LP64__
+#warning FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
+#endif
+
+	/* PDC_PAT_BUG: exhibited in rev 40.48  on L2000 */
+	bus_reset = READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1;
+	if (bus_reset) {
+		printk(KERN_DEBUG "NOTICE: PCI bus reset still asserted! (clearing)\n");
+	}
+
+	stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG);
+	if (stat & LBA_SMART_MODE) {
+		printk(KERN_DEBUG "NOTICE: LBA in SMART mode! (cleared)\n");
+		stat &= ~LBA_SMART_MODE;
+		WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
+	}
 
 	/* Set HF mode as the default (vs. -1 mode). */
         stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL);
 	WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL);
 
 	/*
+	** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal
+	** if it's not already set. If we just cleared the PCI Bus Reset
+	** signal, wait a bit for the PCI devices to recover and setup.
+	*/
+	if (bus_reset)
+		mdelay(pci_post_reset_delay);
+
+	if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) {
+		/*
+		** PDC_PAT_BUG: PDC rev 40.48 on L2000.
+		** B2000/C3600/J6000 also have this problem?
+		** 
+		** Elroys with hot pluggable slots don't get configured
+		** correctly if the slot is empty.  ARB_MASK is set to 0
+		** and we can't master transactions on the bus if it's
+		** not at least one. 0x3 enables elroy and first slot.
+		*/
+		printk(KERN_DEBUG "NOTICE: Enabling PCI Arbitration\n");
+		WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
+	}
+
+	/*
 	** FIXME: Hint registers are programmed with default hint
 	** values by firmware. Hints should be sane even if we
 	** can't reprogram them the way drivers want.
 	*/
+	return 0;
 }
 
 
 
-static void
+static void __init
 lba_common_init(struct lba_device *lba_dev)
 {
 	pci_bios = &lba_bios_ops;
-	pcibios_register_hba((struct pci_hba_data *)lba_dev);
+	pcibios_register_hba(HBA_DATA(lba_dev));
 	lba_dev->lba_lock = SPIN_LOCK_UNLOCKED;	
 
 	/*
@@ -1176,32 +1334,31 @@
 ** If so, initialize the chip and tell other partners in crime they
 ** have work to do.
 */
-static __init int
-lba_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+static int __init
+lba_driver_callback(struct parisc_device *dev)
 {
 	struct lba_device *lba_dev;
 	struct pci_bus *lba_bus;
 	u32 func_class;
 	void *tmp_obj;
-
-	/* from drivers/pci/setup-bus.c */
-	extern void __init pbus_set_ranges(struct pci_bus *, struct pbus_set_ranges_data *);
+	char *version;
 
 	/* Read HW Rev First */
-	func_class = READ_REG32(d->hpa + LBA_FCLASS);
+	func_class = READ_REG32(dev->hpa + LBA_FCLASS);
 	func_class &= 0xf;
 
 	switch (func_class) {
-	case 0:	dri->version = "TR1.0"; break;
-	case 1:	dri->version = "TR2.0"; break;
-	case 2:	dri->version = "TR2.1"; break;
-	case 3:	dri->version = "TR2.2"; break;
-	case 4:	dri->version = "TR3.0"; break;
-	case 5:	dri->version = "TR4.0"; break;
-	default: dri->version = "TR4+";
+	case 0:	version = "TR1.0"; break;
+	case 1:	version = "TR2.0"; break;
+	case 2:	version = "TR2.1"; break;
+	case 3:	version = "TR2.2"; break;
+	case 4:	version = "TR3.0"; break;
+	case 5:	version = "TR4.0"; break;
+	default: version = "TR4+";
 	}
 
-	printk("%s version %s (0x%x) found at 0x%p\n", dri->name, dri->version, func_class & 0xf, d->hpa);
+	printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+		MODULE_NAME, version, func_class & 0xf, dev->hpa);
 
 	/* Just in case we find some prototypes... */
 	if (func_class < 2) {
@@ -1212,22 +1369,16 @@
 	/*
 	** Tell I/O SAPIC driver we have a IRQ handler/region.
 	*/
-	tmp_obj = iosapic_register(d->hpa+LBA_IOSAPIC_BASE);
-	if (NULL == tmp_obj) {
-		/* iosapic may have failed. But more likely the
-		** slot isn't occupied and thus has no IRT entries.
-		** iosapic_register looks for this iosapic in the IRT
-		** before bothering to allocating data structures
-		** we don't need.
-		*/
-		DBG(KERN_WARNING MODULE_NAME ": iosapic_register says not used\n");
-		return (1);
-	}
+	tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE);
 
+	/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
+	**	have an IRT entry will get NULL back from iosapic code.
+	*/
+	
 	lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL);
 	if (NULL == lba_dev)
 	{
-		printk("lba_init_chip - couldn't alloc lba_device\n");
+		printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n");
 		return(1);
 	}
 
@@ -1242,48 +1393,45 @@
 	*/
 	lba_dev->hw_rev = func_class;
 
-	lba_dev->hba.base_addr = d->hpa;  /* faster access */
+	lba_dev->hba.base_addr = dev->hpa;  /* faster access */
+	lba_dev->hba.dev = dev;
 	lba_dev->iosapic_obj = tmp_obj;  /* save interrupt handle */
+	lba_dev->hba.iommu = sba_get_iommu(dev);  /* get iommu data */
 
 	/* ------------ Second : initialize common stuff ---------- */
 	lba_common_init(lba_dev);
-	lba_hw_init(lba_dev);
+
+	if (lba_hw_init(lba_dev))
+		return(1);
 
 	/* ---------- Third : setup I/O Port and MMIO resources  --------- */
-#ifdef __LP64__
 
-	if (pdc_pat) {
+#ifdef __LP64__
+	if (is_pdc_pat()) {
 		/* PDC PAT firmware uses PIOP region of GMMIO space. */
 		pci_port = &lba_pat_port_ops;
 
 		/* Go ask PDC PAT what resources this LBA has */
-		lba_pat_resources(d, lba_dev);
-
-	} else {
+		lba_pat_resources(dev, lba_dev);
+	} else
 #endif
+	{
 		/* Sprockets PDC uses NPIOP region */
 		pci_port = &lba_astro_port_ops;
 
 		/* Poke the chip a bit for /proc output */
-		lba_legacy_resources(d, lba_dev);
-#ifdef __LP64__
+		lba_legacy_resources(dev, lba_dev);
 	}
-#endif
 
 	/* 
 	** Tell PCI support another PCI bus was found.
 	** Walks PCI bus for us too.
 	*/
 	lba_bus = lba_dev->hba.hba_bus =
-		pci_scan_bus( lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
+		pci_scan_bus(lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
 
 #ifdef __LP64__
-	if (pdc_pat) {
-
-		/* determine window sizes needed by PCI-PCI bridges */
-		DBG_PAT("LBA pcibios_size_bridge()\n");
-		pcibios_size_bridge(lba_bus, NULL);
-
+	if (is_pdc_pat()) {
 		/* assign resources to un-initialized devices */
 		DBG_PAT("LBA pcibios_assign_unassigned_resources()\n");
 		pcibios_assign_unassigned_resources(lba_bus);
@@ -1292,14 +1440,10 @@
 		DBG_PAT("\nLBA PIOP resource tree\n");
 		lba_dump_res(&lba_dev->hba.io_space, 2);
 		DBG_PAT("\nLBA LMMIO resource tree\n");
-		lba_dump_res(&lba_dev->hba.mem_space, 2);
+		lba_dump_res(&lba_dev->hba.lmmio_space, 2);
 #endif
-
-		/* program *all* PCI-PCI bridge range registers */
-		DBG_PAT("LBA pbus_set_ranges()\n");
-		pbus_set_ranges(lba_bus, NULL);
 	}
-#endif /* __LP64__ */
+#endif
 
 	/*
 	** Once PCI register ops has walked the bus, access to config
@@ -1314,33 +1458,43 @@
 	return 0;
 }
 
+static struct parisc_device_id lba_tbl[] = {
+	{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x782, 0xa },
+	{ 0, }
+};
+
+static struct parisc_driver lba_driver = {
+	name:		MODULE_NAME,
+	id_table:	lba_tbl,
+	probe:		lba_driver_callback
+};
+
+/*
+** One time initialization to let the world know the LBA was found.
+** Must be called exactly once before pci_init().
+*/
+void __init lba_init(void)
+{
+	register_parisc_driver(&lba_driver);
+}
 
 /*
 ** Initialize the IBASE/IMASK registers for LBA (Elroy).
-** Only called from sba_iommu.c initialization sequence.
+** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA).
+** sba_iommu is responsible for locking (none needed at init time).
 */
-void lba_init_iregs(void *sba_hpa, u32 ibase, u32 imask)
+void
+lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
 {
-	extern struct pci_hba_data *hba_list;	/* arch/parisc/kernel/pci.c */
-	struct pci_hba_data *lba;
+	unsigned long base_addr = lba->hpa;
 
 	imask <<= 2;	/* adjust for hints - 2 more bits */
 
 	ASSERT((ibase & 0x003fffff) == 0);
 	ASSERT((imask & 0x003fffff) == 0);
 	
-	/* FIXME: sba_hpa is intended to search some table to
-	**      determine which LBA's belong to the caller's SBA.
-	** IS_ASTRO: just assume only one SBA for now.
-	*/
-	ASSERT(NULL != hba_list);
-	DBG(KERN_DEBUG "%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
-
-	for (lba = hba_list; NULL != lba; lba = lba->next) {
-		DBG(KERN_DEBUG "%s() base_addr %p\n", __FUNCTION__, lba->base_addr);
-		WRITE_REG32( imask, lba->base_addr + LBA_IMASK);
-		WRITE_REG32( ibase, lba->base_addr + LBA_IBASE);
-	}
-	DBG(KERN_DEBUG "%s() done\n", __FUNCTION__);
+	DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
+	WRITE_REG32( imask, base_addr + LBA_IMASK);
+	WRITE_REG32( ibase, base_addr + LBA_IBASE);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/led.c linux-2.4.20/arch/parisc/kernel/led.c
--- linux-2.4.19/arch/parisc/kernel/led.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/led.c	2002-10-04 00:41:15.000000000 +0000
@@ -3,34 +3,64 @@
  *
  *      (c) Copyright 2000 Red Hat Software
  *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
+ *      (c) Copyright 2001-2002 Helge Deller <deller@gmx.de>
+ *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
  *
  *      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.
  *
+ * TODO:
+ *	- speed-up calculations with inlined assembler
+ *	- interface to write to second row of LCD from /proc
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
+#include <linux/stddef.h>	/* for offsetof() */
 #include <linux/init.h>
-#include <linux/kernel_stat.h>
 #include <linux/types.h>
-#include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/bitops.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
 #include <asm/io.h>
 #include <asm/gsc.h>
 #include <asm/processor.h>
 #include <asm/hardware.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/led.h>
+#include <asm/pdc.h>
+#include <asm/uaccess.h>
 
+/* The control of the LEDs and LCDs on PARISC-machines have to be done 
+   completely in software. The necessary calculations are done in a tasklet
+   which is scheduled at every timer interrupt and since the calculations 
+   may consume relatively much CPU-time some of the calculations can be 
+   turned off with the following variables (controlled via procfs) */
+
+static int led_type = -1;
+static int led_heartbeat = 1;
+static int led_diskio = 1;
+static int led_lanrxtx = 1;
+static char lcd_text[32];
 
-/* define to disable all LED functions */
-#undef  DISABLE_LEDS
+#if 0
+#define DPRINTK(x)	printk x
+#else
+#define DPRINTK(x)
+#endif
 
 
-#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
+#define CALC_ADD(val, comp, add) \
+ (val<=(comp/8) ? add/16 : val<=(comp/4) ? add/8 : val<=(comp/2) ? add/4 : add)
 
 
 struct lcd_block {
@@ -40,8 +70,10 @@
 };
 
 /* Structure returned by PDC_RETURN_CHASSIS_INFO */
+/* NOTE: we use unsigned long:16 two times, since the following member 
+   lcd_cmd_reg_addr needs to be 64bit aligned on 64bit PA2.0-machines */
 struct pdc_chassis_lcd_info_ret_block {
-	unsigned long model:16;		/* DISPLAY_MODEL_XXXX (see below)  */
+	unsigned long model:16;		/* DISPLAY_MODEL_XXXX */
 	unsigned long lcd_width:16;	/* width of the LCD in chars (DISPLAY_MODEL_LCD only) */
 	char *lcd_cmd_reg_addr;		/* ptr to LCD cmd-register & data ptr for LED */
 	char *lcd_data_reg_addr;	/* ptr to LCD data-register (LCD only) */
@@ -56,33 +88,23 @@
 	char _pad;
 };
 
-/* values for pdc_chassis_lcd_info_ret_block.model: */
-#define DISPLAY_MODEL_LCD  0	/* KittyHawk LED or LCD */
-#define DISPLAY_MODEL_NONE 1	/* no LED or LCD */
-#define DISPLAY_MODEL_LASI 2	/* LASI style 8 bit LED */
-#define DISPLAY_MODEL_OLD_ASP 0x7F /* faked: ASP style 8 x 1 bit LED (only very old ASP versions) */
-
 
 /* LCD_CMD and LCD_DATA for KittyHawk machines */
-#ifdef __LP64__
-#define KITTYHAWK_LCD_CMD 0xfffffffff0190000L
-#else
-#define KITTYHAWK_LCD_CMD 0xf0190000
-#endif
-#define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD + 1)
+#define KITTYHAWK_LCD_CMD  (0xfffffffff0190000UL) /* 64bit-ready */
+#define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
 
-
-/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's */
+/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 
+ * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */
 static struct pdc_chassis_lcd_info_ret_block
 lcd_info __attribute__((aligned(8))) =
 {
-      model:DISPLAY_MODEL_LCD,
-      lcd_width:16,
-      lcd_cmd_reg_addr:(char *) KITTYHAWK_LCD_CMD,
+      model:		DISPLAY_MODEL_LCD,
+      lcd_width:	16,
+      lcd_cmd_reg_addr:	(char *) KITTYHAWK_LCD_CMD,
       lcd_data_reg_addr:(char *) KITTYHAWK_LCD_DATA,
-      min_cmd_delay:40,
-      reset_cmd1:0x80,
-      reset_cmd2:0xc0,
+      min_cmd_delay:	40,
+      reset_cmd1:	0x80,
+      reset_cmd2:	0xc0,
 };
 
 
@@ -92,7 +114,143 @@
 #define LED_DATA_REG	lcd_info.lcd_cmd_reg_addr	/* LASI & ASP only */
 
 
+/* ptr to LCD/LED-specific function */
+static void (*led_func_ptr) (unsigned char);
+
+#define LED_HASLCD 1
+#define LED_NOLCD  0
+#ifdef CONFIG_PROC_FS
+static int led_proc_read(char *page, char **start, off_t off, int count, 
+	int *eof, void *data)
+{
+	char *out = page;
+	int len;
+
+	switch ((long)data)
+	{
+	case LED_NOLCD:
+		out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
+		out += sprintf(out, "Disk IO: %d\n", led_diskio);
+		out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
+		break;
+	case LED_HASLCD:
+		out += sprintf(out, "%s\n", lcd_text);
+		break;
+	default:
+		*eof = 1;
+		return 0;
+	}
+
+	len = out - page - off;
+	if (len < count) {
+		*eof = 1;
+		if (len <= 0) return 0;
+	} else {
+		len = count;
+	}
+	*start = page + off;
+	return len;
+}
+
+static int led_proc_write(struct file *file, const char *buf, 
+	unsigned long count, void *data)
+{
+	char *cur, lbuf[count];
+	int d;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	memset(lbuf, 0, count);
+
+	copy_from_user(lbuf, buf, count);
+	cur = lbuf;
+
+	/* skip initial spaces */
+	while (*cur && isspace(*cur))
+	{
+		cur++;
+	}
+
+	switch ((long)data)
+	{
+	case LED_NOLCD:
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_heartbeat = d;
+
+		if (*cur++ != ' ') goto parse_error;
+
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_diskio = d;
+
+		if (*cur++ != ' ') goto parse_error;
+
+		d = *cur++ - '0';
+		if (d != 0 && d != 1) goto parse_error;
+		led_lanrxtx = d;
+
+		break;
+	case LED_HASLCD:
+		if (*cur == 0) 
+		{
+			/* reset to default */
+			lcd_print("Linux " UTS_RELEASE);
+		}
+		else
+		{
+			/* chop off trailing \n.. if the user gives multiple
+			 * \n then it's all their fault.. */
+			if (*cur && cur[strlen(cur)-1] == '\n')
+				cur[strlen(cur)-1] = 0;
+			lcd_print(cur);
+		}
+		break;
+	default:
+		return 0;
+	}
+	
+	return count;
+
+parse_error:
+	if ((long)data == LED_NOLCD)
+		printk(KERN_CRIT "Parse error: expect \"n n n\" (n == 0 or 1) for heartbeat,\ndisk io and lan tx/rx indicators\n");
+	return -EINVAL;
+}
+
+static int __init led_create_procfs(void)
+{
+	struct proc_dir_entry *proc_pdc_root = NULL;
+	struct proc_dir_entry *ent;
+
+	if (led_type == -1) return -1;
+
+	proc_pdc_root = proc_mkdir("pdc", 0);
+	if (!proc_pdc_root) return -1;
+	proc_pdc_root->owner = THIS_MODULE;
+	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+	if (!ent) return -1;
+	ent->nlink = 1;
+	ent->data = (void *)LED_NOLCD; /* LED */
+	ent->read_proc = led_proc_read;
+	ent->write_proc = led_proc_write;
+	ent->owner = THIS_MODULE;
+
+	if (led_type == LED_HASLCD)
+	{
+		ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
+		if (!ent) return -1;
+		ent->nlink = 1;
+		ent->data = (void *)LED_HASLCD; /* LCD */
+		ent->read_proc = led_proc_read;
+		ent->write_proc = led_proc_write;
+		ent->owner = THIS_MODULE;
+	}
 
+	return 0;
+}
+#endif
 
 /*
    ** 
@@ -132,24 +290,20 @@
    ** 
    ** led_LCD_driver()
    ** 
-   ** The logic of the LCD driver is, that we write at every interrupt
+   ** The logic of the LCD driver is, that we write at every scheduled call
    ** only to one of LCD_CMD_REG _or_ LCD_DATA_REG - registers.
-   ** That way we don't need to let this interrupt routine busywait
-   ** the "min_cmd_delay", since idlewaiting in an interrupt-routine is
-   ** allways a BAD IDEA !
+   ** That way we don't need to let this tasklet busywait for min_cmd_delay
+   ** milliseconds.
    **
    ** TODO: check the value of "min_cmd_delay" against the value of HZ.
    **   
  */
-
 static void led_LCD_driver(unsigned char leds)
 {
 	static int last_index;	/* 0:heartbeat, 1:disk, 2:lan_in, 3:lan_out */
 	static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
 	struct lcd_block *block_ptr;
 	int value;
-	
- 	// leds = ~leds;	/* needed ? */ 
 
 	switch (last_index) {
 	    case 0:	block_ptr = &lcd_info.heartbeat;
@@ -165,7 +319,6 @@
 			value = leds & LED_LAN_TX;
 			break;
 	    default:	/* should never happen: */
-			BUG();
 			return;
 	}
 
@@ -178,179 +331,293 @@
 	}    
 	
 	/* now update the vars for the next interrupt iteration */ 
-	if (++last_was_cmd == 2) {
+	if (++last_was_cmd == 2) { /* switch between cmd & data */
 	    last_was_cmd = 0;
-	    if (++last_index == 4)
-		last_index = 0;
+	    if (++last_index == 4) 
+		last_index = 0;	 /* switch back to heartbeat index */
 	}
 }
 
 
+/*
+   ** 
+   ** led_get_net_stats()
+   ** 
+   ** calculate the TX- & RX-troughput on the network interfaces in
+   ** the system for usage in the LED code
+   **
+   ** (analog to dev_get_info() from net/core/dev.c)
+   **   
+ */
+static unsigned long led_net_rx_counter, led_net_tx_counter;
+
+static void led_get_net_stats(int addvalue)
+{
+	static unsigned long rx_total_last, tx_total_last;
+	unsigned long rx_total, tx_total;
+	struct net_device *dev;
+	struct net_device_stats *stats;
+
+	rx_total = tx_total = 0;
+	
+	/* we are running as a tasklet, so locking dev_base 
+	 * for reading should be OK */
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+	    if (dev->get_stats) { 
+	        stats = dev->get_stats(dev);
+		rx_total += stats->rx_packets;
+		tx_total += stats->tx_packets;
+	    }
+	}
+	read_unlock(&dev_base_lock);
 
-static char currentleds;	/* stores current value of the LEDs */
+	rx_total -= rx_total_last;
+	tx_total -= tx_total_last;
+	
+	if (rx_total)
+	    led_net_rx_counter += CALC_ADD(rx_total, tx_total, addvalue);
+
+	if (tx_total)
+	    led_net_tx_counter += CALC_ADD(tx_total, rx_total, addvalue);
+        
+	rx_total_last += rx_total;
+        tx_total_last += tx_total;
+}
 
-static void (*led_func_ptr) (unsigned char); /* ptr to LCD/LED-specific function */
 
 /*
-   ** led_interrupt_func()
    ** 
-   ** is called at every timer interrupt from time.c,
+   ** led_get_diskio_stats()
+   ** 
+   ** calculate the disk-io througput in the system
+   ** (analog to linux/fs/proc/proc_misc.c)
+   **   
+ */
+static unsigned long led_diskio_counter;
+
+static void led_get_diskio_stats(int addvalue)
+{	
+	static unsigned int diskio_total_last, diskio_max;
+	int major, disk, total;
+	
+	total = 0;
+	for (major = 0; major < DK_MAX_MAJOR; major++) {
+	    for (disk = 0; disk < DK_MAX_DISK; disk++)
+		total += kstat.dk_drive[major][disk];
+	}
+	total -= diskio_total_last;
+	
+	if (total) {
+	    if (total >= diskio_max) {
+		led_diskio_counter += addvalue;
+	        diskio_max = total; /* new maximum value found */ 
+	    } else
+		led_diskio_counter += CALC_ADD(total, diskio_max, addvalue);
+	}
+	
+	diskio_total_last += total; 
+}
+
+
+
+/*
+   ** led_tasklet_func()
+   ** 
+   ** is scheduled at every timer interrupt from time.c and
    ** updates the chassis LCD/LED 
+
+    TODO:
+    - display load average (older machines like 715/64 have 4 "free" LED's for that)
+    - optimizations
  */
 
-#define HEARTBEAT_LEN	(HZ/16)
+static unsigned char currentleds;	/* stores current value of the LEDs */
+
+#define HEARTBEAT_LEN (HZ*6/100)
+#define HEARTBEAT_2ND_RANGE_START (HZ*22/100)
+#define HEARTBEAT_2ND_RANGE_END   (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
 
-void led_interrupt_func(void)
+static void led_tasklet_func(unsigned long unused)
 {
-#ifndef DISABLE_LEDS
-	static int count;
-	static int lastleds = -1;
-	static int nr;
+	static unsigned int count, count_HZ;
+	static unsigned char lastleds;
 
-	/* exit, if not initialized */
+	/* exit if not initialized */
 	if (!led_func_ptr)
 	    return;
-	
-	/* increment the local counter */
-	if (count == (HZ-1))
-	    count = 0;
-	else
-	    count++;
 
-	/* calculate the Heartbeat */
-	if ((count % (HZ/2)) < HEARTBEAT_LEN) 
-	    currentleds |= LED_HEARTBEAT;
-	else
-	    currentleds &= ~LED_HEARTBEAT;
+	/* increment the local counters */
+	++count;
+	if (++count_HZ == HZ)
+	    count_HZ = 0;
+
+	if (led_heartbeat)
+	{
+		/* flash heartbeat-LED like a real heart (2 x short then a long delay) */
+		if (count_HZ<HEARTBEAT_LEN || 
+		    (count_HZ>=HEARTBEAT_2ND_RANGE_START && count_HZ<HEARTBEAT_2ND_RANGE_END)) 
+		    currentleds |= LED_HEARTBEAT;
+		else
+		    currentleds &= ~LED_HEARTBEAT;
+	}
+
+	/* gather network and diskio statistics and flash LEDs respectively */
+
+	if (led_lanrxtx)
+	{
+		if ((count & 31) == 0)
+			led_get_net_stats(30);
+
+		if (led_net_rx_counter) {
+			led_net_rx_counter--;
+			currentleds |= LED_LAN_RCV;
+		}
+		else    
+			currentleds &= ~LED_LAN_RCV;
+
+		if (led_net_tx_counter) {
+			led_net_tx_counter--;
+			currentleds |= LED_LAN_TX;
+		}
+		else    
+			currentleds &= ~LED_LAN_TX;
+	}
 
-	/* roll LEDs 0..2 */
-	if (count == 0) {
-	    if (nr++ >= 2) 
-		nr = 0;
-	    currentleds &= ~7;
-	    currentleds |= (1 << nr);
+	if (led_diskio)
+	{
+		/* avoid to calculate diskio-stats at same irq as netio-stats ! */
+		if ((count & 31) == 15) 
+			led_get_diskio_stats(30);
+
+		if (led_diskio_counter) {
+			led_diskio_counter--;
+			currentleds |= LED_DISK_IO;
+		}
+		else    
+			currentleds &= ~LED_DISK_IO;
 	}
 
-	/* now update the LEDs */
+	/* update the LCD/LEDs */
 	if (currentleds != lastleds) {
 	    led_func_ptr(currentleds);
 	    lastleds = currentleds;
 	}
-#endif
 }
 
+/* main led tasklet struct (scheduled from time.c) */
+DECLARE_TASKLET_DISABLED(led_tasklet, led_tasklet_func, 0);
+
+
+/*
+   ** led_halt()
+   ** 
+   ** called by the reboot notifier chain at shutdown and stops all
+   ** LED/LCD activities.
+   ** 
+ */
+
+static int led_halt(struct notifier_block *, unsigned long, void *);
+
+static struct notifier_block led_notifier = {
+	notifier_call: led_halt,
+};
+
+static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 
+{
+	char *txt;
+	
+	switch (event) {
+	case SYS_RESTART:	txt = "SYSTEM RESTART";
+				break;
+	case SYS_HALT:		txt = "SYSTEM HALT";
+				break;
+	case SYS_POWER_OFF:	txt = "SYSTEM POWER OFF";
+				break;
+	default:		return NOTIFY_DONE;
+	}
+	
+	/* completely stop the LED/LCD tasklet */
+	tasklet_disable(&led_tasklet);
+
+	if (lcd_info.model == DISPLAY_MODEL_LCD)
+		lcd_print(txt);
+	else
+		if (led_func_ptr)
+			led_func_ptr(0xff); /* turn all LEDs ON */
+	
+	unregister_reboot_notifier(&led_notifier);
+	return NOTIFY_OK;
+}
 
 /*
    ** register_led_driver()
    ** 
-   ** All information in lcd_info needs to be set up prior
-   ** calling this function. 
+   ** registers an external LED or LCD for usage by this driver.
+   ** currently only LCD-, LASI- and ASP-style LCD/LED's are supported.
+   ** 
  */
 
-static void __init register_led_driver(void)
+int __init register_led_driver(int model, char *cmd_reg, char *data_reg)
 {
-#ifndef DISABLE_LEDS
+	static int initialized;
+	
+	if (initialized || !data_reg)
+	    return 1;
+	
+	lcd_info.model = model;		/* store the values */
+	LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? NULL : cmd_reg;
+
 	switch (lcd_info.model) {
 	case DISPLAY_MODEL_LCD:
-		printk(KERN_INFO "LCD display at (%p,%p)\n",
-		  LCD_CMD_REG , LCD_DATA_REG);
+		LCD_DATA_REG = data_reg;
+		printk(KERN_INFO "LCD display at %p,%p registered\n", 
+			LCD_CMD_REG , LCD_DATA_REG);
 		led_func_ptr = led_LCD_driver;
+		lcd_print( "Linux " UTS_RELEASE );
+		led_type = LED_HASLCD;
 		break;
 
 	case DISPLAY_MODEL_LASI:
-		printk(KERN_INFO "LED display at %p\n",
-		       LED_DATA_REG);
+		LED_DATA_REG = data_reg;
 		led_func_ptr = led_LASI_driver;
+		printk(KERN_INFO "LED display at %p registered\n", LED_DATA_REG);
+		led_type = LED_NOLCD;
 		break;
 
 	case DISPLAY_MODEL_OLD_ASP:
-		printk(KERN_INFO "LED (ASP-style) display at %p\n",
-		       LED_DATA_REG);
+		LED_DATA_REG = data_reg;
 		led_func_ptr = led_ASP_driver;
+		printk(KERN_INFO "LED (ASP-style) display at %p registered\n", 
+		    LED_DATA_REG);
+		led_type = LED_NOLCD;
 		break;
 
 	default:
 		printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n",
 		       __FUNCTION__, lcd_info.model);
-		return;
+		return 1;
 	}
-#endif
-}
-
-/*
- * XXX - could this move to lasi.c ??
- */
-
-/*
-   ** lasi_led_init()
-   ** 
-   ** lasi_led_init() is called from lasi.c with the base hpa  
-   ** of the lasi controller chip. 
-   ** Since Mirage and Electra machines use a different LED
-   ** address register, we need to check for these machines 
-   ** explicitly.
- */
-
-#ifdef CONFIG_GSC_LASI
-void __init lasi_led_init(unsigned long lasi_hpa)
-{
-	if (lcd_info.model != DISPLAY_MODEL_NONE ||
-	    lasi_hpa == 0)
-		return;
-
-	printk("%s: CPU_HVERSION %x\n", __FUNCTION__, CPU_HVERSION);
-
-	/* Mirage and Electra machines need special offsets */
-	switch (CPU_HVERSION) {
-	case 0x60A:		/* Mirage Jr (715/64) */
-	case 0x60B:		/* Mirage 100 */
-	case 0x60C:		/* Mirage 100+ */
-	case 0x60D:		/* Electra 100 */
-	case 0x60E:		/* Electra 120 */
-		LED_DATA_REG = (char *) (lasi_hpa - 0x00020000);
-		break;
-	default:
-		LED_DATA_REG = (char *) (lasi_hpa + 0x0000C000);
-		break;
-	}			/* switch() */
-
-	lcd_info.model = DISPLAY_MODEL_LASI;
-	register_led_driver();
-}
-#endif
-
-
-/*
-   ** asp_led_init()
-   ** 
-   ** asp_led_init() is called from asp.c with the ptr 
-   ** to the LED display.
- */
-
-#ifdef CONFIG_GSC_LASI
-void __init asp_led_init(unsigned long led_ptr)
-{
-	if (lcd_info.model != DISPLAY_MODEL_NONE ||
-	    led_ptr == 0)
-		return;
-
-	lcd_info.model = DISPLAY_MODEL_OLD_ASP;
-	LED_DATA_REG = (char *) led_ptr;
+	
+	/* mark the LCD/LED driver now as initialized and 
+	 * register to the reboot notifier chain */
+	initialized++;
+	register_reboot_notifier(&led_notifier);
 
-	register_led_driver();
+	/* start the led tasklet for the first time */
+	tasklet_enable(&led_tasklet);
+	
+	return 0;
 }
 
-#endif
-
-
-
 /*
    ** register_led_regions()
    ** 
-   ** Simple function, which registers the LCD/LED regions for /procfs.
+   ** register_led_regions() registers the LCD/LED regions for /procfs.
    ** At bootup - where the initialisation of the LCD/LED normally happens - 
    ** not all internal structures of request_region() are properly set up,
-   ** so that we delay the registration until busdevice.c is executed.
+   ** so that we delay the led-registration until after busdevices_init() 
+   ** has been executed.
    **
  */
 
@@ -358,17 +625,57 @@
 {
 	switch (lcd_info.model) {
 	case DISPLAY_MODEL_LCD:
-		request_region((unsigned long)LCD_CMD_REG,  1, "lcd_cmd");
-		request_region((unsigned long)LCD_DATA_REG, 1, "lcd_data");
+		request_mem_region((unsigned long)LCD_CMD_REG,  1, "lcd_cmd");
+		request_mem_region((unsigned long)LCD_DATA_REG, 1, "lcd_data");
 		break;
 	case DISPLAY_MODEL_LASI:
 	case DISPLAY_MODEL_OLD_ASP:
-		request_region((unsigned long)LED_DATA_REG, 1, "led_data");
+		request_mem_region((unsigned long)LED_DATA_REG, 1, "led_data");
 		break;
 	}
 }
 
 
+/*
+   ** 
+   ** lcd_print()
+   ** 
+   ** Displays the given string on the LCD-Display of newer machines.
+   ** lcd_print() disables the timer-based led tasklet during its 
+   ** execution and enables it afterwards again.
+   **
+ */
+int lcd_print( char *str )
+{
+	int i;
+
+	if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
+	    return 0;
+	
+	/* temporarily disable the led tasklet */
+	tasklet_disable(&led_tasklet);
+
+	/* copy display string to buffer for procfs */
+	strncpy(lcd_text, str, sizeof(lcd_text)-1);
+	
+	/* Set LCD Cursor to 1st character */
+	gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
+	udelay(lcd_info.min_cmd_delay);
+
+	/* Print the string */
+	for (i=0; i < lcd_info.lcd_width; i++) {
+	    if (str && *str)
+		gsc_writeb(*str++, LCD_DATA_REG);
+	    else
+		gsc_writeb(' ', LCD_DATA_REG);
+	    udelay(lcd_info.min_cmd_delay);
+	}
+	
+	/* re-enable the led tasklet */
+	tasklet_enable(&led_tasklet);
+
+	return lcd_info.lcd_width;
+}
 
 /*
    ** led_init()
@@ -384,10 +691,8 @@
 
 int __init led_init(void)
 {
-#ifndef DISABLE_LEDS
-	long pdc_result[32];
-
-	printk("%s: CPU_HVERSION %x\n", __FUNCTION__, CPU_HVERSION);
+	struct pdc_chassis_info chassis_info;
+	int ret;
 
 	/* Work around the buggy PDC of KittyHawk-machines */
 	switch (CPU_HVERSION) {
@@ -396,56 +701,74 @@
 	case 0x582:		/* KittyHawk DC3 100 (K400) */
 	case 0x583:		/* KittyHawk DC3 120 (K410) */
 	case 0x58B:		/* KittyHawk DC2 100 (K200) */
-		printk("%s: KittyHawk-Machine found !!\n", __FUNCTION__);
+		printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
+				"LED detection skipped.\n", __FILE__, CPU_HVERSION);
 		goto found;	/* use the preinitialized values of lcd_info */
-
-	default:
-		break;
 	}
 
-	/* initialize pdc_result, so we can check the return values of pdc_chassis_info() */
-	pdc_result[0] = pdc_result[1] = 0;
-
-	if (pdc_chassis_info(&pdc_result, &lcd_info, sizeof(lcd_info)) == PDC_OK) {
-		printk("%s: chassis info: model %d, ret0=%d, ret1=%d\n",
-		 __FUNCTION__, lcd_info.model, pdc_result[0], pdc_result[1]);
+	/* initialize the struct, so that we can check for valid return values */
+	lcd_info.model = DISPLAY_MODEL_NONE;
+	chassis_info.actcnt = chassis_info.maxcnt = 0;
 
+	if ((ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info))) == PDC_OK) {
+		DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), "
+			 "lcd_width=%d, cmd_delay=%u,\n"
+			 "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
+		         __FILE__, lcd_info.model,
+			 (lcd_info.model==DISPLAY_MODEL_LCD) ? "LCD" :
+			  (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown",
+			 lcd_info.lcd_width, lcd_info.min_cmd_delay,
+			 __FILE__, sizeof(lcd_info), 
+			 chassis_info.actcnt, chassis_info.maxcnt));
+		DPRINTK((KERN_INFO "%s: cmd=%p, data=%p, reset1=%x, reset2=%x, act_enable=%d\n",
+			__FILE__, lcd_info.lcd_cmd_reg_addr, 
+			lcd_info.lcd_data_reg_addr, lcd_info.reset_cmd1,  
+			lcd_info.reset_cmd2, lcd_info.act_enable ));
+	
 		/* check the results. Some machines have a buggy PDC */
-		if (pdc_result[0] <= 0 || pdc_result[0] != pdc_result[1])
+		if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt)
 			goto not_found;
 
 		switch (lcd_info.model) {
-		case DISPLAY_MODEL_LCD:	/* LCD display */
-			if (pdc_result[0] != sizeof(struct pdc_chassis_lcd_info_ret_block)
-			    && pdc_result[0] != sizeof(struct pdc_chassis_lcd_info_ret_block) - 1)
-				 goto not_found;
-			printk("%s: min_cmd_delay = %d uS\n",
-		             __FUNCTION__, lcd_info.min_cmd_delay);
+		case DISPLAY_MODEL_LCD:		/* LCD display */
+			if (chassis_info.actcnt < 
+				offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1)
+				goto not_found;
+			if (!lcd_info.act_enable) {
+				DPRINTK((KERN_INFO "PDC prohibited usage of the LCD.\n"));
+				goto not_found;
+			}
 			break;
 
 		case DISPLAY_MODEL_NONE:	/* no LED or LCD available */
+			printk(KERN_INFO "PDC reported no LCD or LED.\n");
 			goto not_found;
 
 		case DISPLAY_MODEL_LASI:	/* Lasi style 8 bit LED display */
-			if (pdc_result[0] != 8 && pdc_result[0] != 32)
+			if (chassis_info.actcnt != 8 && chassis_info.actcnt != 32)
 				goto not_found;
 			break;
 
 		default:
-			printk(KERN_WARNING "Unknown LCD/LED model %d\n",
+			printk(KERN_WARNING "PDC reported unknown LCD/LED model %d\n",
 			       lcd_info.model);
 			goto not_found;
-		}		/* switch() */
+		} /* switch() */
 
 found:
 		/* register the LCD/LED driver */
-		register_led_driver();
+		register_led_driver(lcd_info.model, LCD_CMD_REG, LCD_DATA_REG);
 		return 0;
 
-	}			/* if() */
+	} else { /* if() */
+		DPRINTK((KERN_INFO "pdc_chassis_info call failed with retval = %d\n", ret));
+	}
 
 not_found:
 	lcd_info.model = DISPLAY_MODEL_NONE;
 	return 1;
-#endif
 }
+
+#ifdef CONFIG_PROC_FS
+module_init(led_create_procfs)
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pa7300lc.c linux-2.4.20/arch/parisc/kernel/pa7300lc.c
--- linux-2.4.19/arch/parisc/kernel/pa7300lc.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pa7300lc.c	2002-10-04 00:41:20.000000000 +0000
@@ -4,11 +4,12 @@
  *
  *   Copyright (C) 2000 Philipp Rumpf */
 
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
 #include <asm/gsc.h>
 #include <asm/ptrace.h>
 #include <asm/machdep.h>
-#include <linux/smp.h>
-#include <linux/kernel.h>
 
 /* CPU register indices */
 
@@ -19,12 +20,6 @@
 #define DIOERR		0xf0ec
 #define HIDMAMEM	0xf0f4
 
-/* read CPU Diagnose register index */
-static u32 diag_read(int index)
-{
-	return 0;
-}
-
 /* this returns the HPA of the CPU it was called on */
 static u32 cpu_hpa(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pacache.S linux-2.4.20/arch/parisc/kernel/pacache.S
--- linux-2.4.19/arch/parisc/kernel/pacache.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pacache.S	2002-10-04 00:41:20.000000000 +0000
@@ -0,0 +1,908 @@
+/*
+ *  Parisc tlb and cache flushing support
+ *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
+ *
+ *    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, 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.
+ */
+
+/*
+ * NOTE: fdc,fic, and pdc instructions that use base register modification
+ *       should only use index and base registers that are not shadowed,
+ *       so that the fast path emulation in the non access miss handler
+ *       can be used.
+ */
+
+#ifdef __LP64__
+#define ADDIB   addib,*
+#define CMPB    cmpb,*
+#define ANDCM   andcm,*
+
+	.level 2.0w
+#else
+#define ADDIB   addib,
+#define CMPB    cmpb,
+#define ANDCM   andcm
+
+	.level 2.0
+#endif
+
+#include <asm/assembly.h>
+#include <asm/psw.h>
+#include <asm/pgtable.h>
+#include <asm/cache.h>
+
+	.text
+	.align 128
+
+	.export flush_tlb_all_local,code
+
+flush_tlb_all_local:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	/*
+	 * The pitlbe and pdtlbe instructions should only be used to
+	 * flush the entire tlb. Also, there needs to be no intervening
+	 * tlb operations, e.g. tlb misses, so the operation needs
+	 * to happen in real mode with all interruptions disabled.
+	 */
+
+	/*
+	 * Once again, we do the rfi dance ... some day we need examine
+	 * all of our uses of this type of code and see what can be
+	 * consolidated.
+	 */
+
+	rsm     PSW_SM_I,%r19      /* relied upon translation! */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	
+	rsm     PSW_SM_Q,%r0       /* Turn off Q bit to load iia queue */
+	ldil    L%REAL_MODE_PSW, %r1
+	ldo     R%REAL_MODE_PSW(%r1), %r1
+	mtctl	%r1, %cr22
+	mtctl	%r0, %cr17
+	mtctl	%r0, %cr17
+	ldil    L%PA(1f),%r1
+	ldo     R%PA(1f)(%r1),%r1
+	mtctl	%r1, %cr18
+	ldo	4(%r1), %r1
+	mtctl	%r1, %cr18
+	rfi
+	nop
+
+1:      ldil            L%PA(cache_info),%r1
+	ldo             R%PA(cache_info)(%r1),%r1
+
+	/* Flush Instruction Tlb */
+
+	LDREG           ITLB_SID_BASE(%r1),%r20
+	LDREG           ITLB_SID_STRIDE(%r1),%r21
+	LDREG           ITLB_SID_COUNT(%r1),%r22
+	LDREG           ITLB_OFF_BASE(%r1),%arg0
+	LDREG           ITLB_OFF_STRIDE(%r1),%arg1
+	LDREG           ITLB_OFF_COUNT(%r1),%arg2
+	LDREG           ITLB_LOOP(%r1),%arg3
+
+	ADDIB=          -1,%arg3,fitoneloop     /* Preadjust and test */
+	movb,<,n        %arg3,%r31,fitdone      /* If loop < 0, skip */
+	copy            %arg0,%r28              /* Init base addr */
+
+fitmanyloop:                                    /* Loop if LOOP >= 2 */
+	mtsp            %r20,%sr1
+	add             %r21,%r20,%r20          /* increment space */
+	copy            %arg2,%r29              /* Init middle loop count */
+
+fitmanymiddle:                                  /* Loop if LOOP >= 2 */
+	ADDIB>          -1,%r31,fitmanymiddle   /* Adjusted inner loop decr */
+	pitlbe          0(%sr1,%r28)
+	pitlbe,m        %arg1(%sr1,%r28)        /* Last pitlbe and addr adjust */
+	ADDIB>          -1,%r29,fitmanymiddle   /* Middle loop decr */
+	copy            %arg3,%r31              /* Re-init inner loop count */
+
+	movb,tr         %arg0,%r28,fitmanyloop  /* Re-init base addr */
+	ADDIB<=,n       -1,%r22,fitdone         /* Outer loop count decr */
+
+fitoneloop:                                     /* Loop if LOOP = 1 */
+	mtsp            %r20,%sr1
+	copy            %arg0,%r28              /* init base addr */
+	copy            %arg2,%r29              /* init middle loop count */
+
+fitonemiddle:                                   /* Loop if LOOP = 1 */
+	ADDIB>          -1,%r29,fitonemiddle    /* Middle loop count decr */
+	pitlbe,m        %arg1(%sr1,%r28)        /* pitlbe for one loop */
+
+	ADDIB>          -1,%r22,fitoneloop      /* Outer loop count decr */
+	add             %r21,%r20,%r20          /* increment space */
+
+fitdone:
+
+	/* Flush Data Tlb */
+
+	LDREG           DTLB_SID_BASE(%r1),%r20
+	LDREG           DTLB_SID_STRIDE(%r1),%r21
+	LDREG           DTLB_SID_COUNT(%r1),%r22
+	LDREG           DTLB_OFF_BASE(%r1),%arg0
+	LDREG           DTLB_OFF_STRIDE(%r1),%arg1
+	LDREG           DTLB_OFF_COUNT(%r1),%arg2
+	LDREG           DTLB_LOOP(%r1),%arg3
+
+	ADDIB=          -1,%arg3,fdtoneloop     /* Preadjust and test */
+	movb,<,n        %arg3,%r31,fdtdone      /* If loop < 0, skip */
+	copy            %arg0,%r28              /* Init base addr */
+
+fdtmanyloop:                                    /* Loop if LOOP >= 2 */
+	mtsp            %r20,%sr1
+	add             %r21,%r20,%r20          /* increment space */
+	copy            %arg2,%r29              /* Init middle loop count */
+
+fdtmanymiddle:                                  /* Loop if LOOP >= 2 */
+	ADDIB>          -1,%r31,fdtmanymiddle   /* Adjusted inner loop decr */
+	pdtlbe          0(%sr1,%r28)
+	pdtlbe,m        %arg1(%sr1,%r28)        /* Last pdtlbe and addr adjust */
+	ADDIB>          -1,%r29,fdtmanymiddle   /* Middle loop decr */
+	copy            %arg3,%r31              /* Re-init inner loop count */
+
+	movb,tr         %arg0,%r28,fdtmanyloop  /* Re-init base addr */
+	ADDIB<=,n       -1,%r22,fdtdone         /* Outer loop count decr */
+
+fdtoneloop:                                     /* Loop if LOOP = 1 */
+	mtsp            %r20,%sr1
+	copy            %arg0,%r28              /* init base addr */
+	copy            %arg2,%r29              /* init middle loop count */
+
+fdtonemiddle:                                   /* Loop if LOOP = 1 */
+	ADDIB>          -1,%r29,fdtonemiddle    /* Middle loop count decr */
+	pdtlbe,m        %arg1(%sr1,%r28)        /* pdtlbe for one loop */
+
+	ADDIB>          -1,%r22,fdtoneloop      /* Outer loop count decr */
+	add             %r21,%r20,%r20          /* increment space */
+
+fdtdone:
+
+	/* Switch back to virtual mode */
+
+	rsm     PSW_SM_Q,%r0       /* clear Q bit to load iia queue */
+	ldil	L%KERNEL_PSW, %r1
+	ldo	R%KERNEL_PSW(%r1), %r1
+	or      %r1,%r19,%r1    /* Set I bit if set on entry */
+	mtctl	%r1, %cr22
+	mtctl	%r0, %cr17
+	mtctl	%r0, %cr17
+	ldil    L%(2f), %r1
+	ldo     R%(2f)(%r1), %r1
+	mtctl	%r1, %cr18
+	ldo	4(%r1), %r1
+	mtctl	%r1, %cr18
+	rfi
+	nop
+
+2:      bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_instruction_cache_local,code
+	.import cache_info,data
+
+flush_instruction_cache_local:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	mtsp            %r0,%sr1
+	ldil            L%cache_info,%r1
+	ldo             R%cache_info(%r1),%r1
+
+	/* Flush Instruction Cache */
+
+	LDREG           ICACHE_BASE(%r1),%arg0
+	LDREG           ICACHE_STRIDE(%r1),%arg1
+	LDREG           ICACHE_COUNT(%r1),%arg2
+	LDREG           ICACHE_LOOP(%r1),%arg3
+	ADDIB=          -1,%arg3,fioneloop      /* Preadjust and test */
+	movb,<,n        %arg3,%r31,fisync       /* If loop < 0, do sync */
+
+fimanyloop:                                     /* Loop if LOOP >= 2 */
+	ADDIB>          -1,%r31,fimanyloop      /* Adjusted inner loop decr */
+	fice            0(%sr1,%arg0)
+	fice,m          %arg1(%sr1,%arg0)       /* Last fice and addr adjust */
+	movb,tr         %arg3,%r31,fimanyloop   /* Re-init inner loop count */
+	ADDIB<=,n       -1,%arg2,fisync         /* Outer loop decr */
+
+fioneloop:                                      /* Loop if LOOP = 1 */
+	ADDIB>          -1,%arg2,fioneloop      /* Outer loop count decr */
+	fice,m          %arg1(%sr1,%arg0)       /* Fice for one loop */
+
+fisync:
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_data_cache_local,code
+	.import cache_info,data
+
+flush_data_cache_local:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	mtsp            %r0,%sr1
+	ldil            L%cache_info,%r1
+	ldo             R%cache_info(%r1),%r1
+
+	/* Flush Data Cache */
+
+	LDREG           DCACHE_BASE(%r1),%arg0
+	LDREG           DCACHE_STRIDE(%r1),%arg1
+	LDREG           DCACHE_COUNT(%r1),%arg2
+	LDREG           DCACHE_LOOP(%r1),%arg3
+	rsm             PSW_SM_I,%r22
+	ADDIB=          -1,%arg3,fdoneloop      /* Preadjust and test */
+	movb,<,n        %arg3,%r31,fdsync       /* If loop < 0, do sync */
+
+fdmanyloop:                                     /* Loop if LOOP >= 2 */
+	ADDIB>          -1,%r31,fdmanyloop      /* Adjusted inner loop decr */
+	fdce            0(%sr1,%arg0)
+	fdce,m          %arg1(%sr1,%arg0)       /* Last fdce and addr adjust */
+	movb,tr         %arg3,%r31,fdmanyloop   /* Re-init inner loop count */
+	ADDIB<=,n       -1,%arg2,fdsync         /* Outer loop decr */
+
+fdoneloop:                                      /* Loop if LOOP = 1 */
+	ADDIB>          -1,%arg2,fdoneloop      /* Outer loop count decr */
+	fdce,m          %arg1(%sr1,%arg0)       /* Fdce for one loop */
+
+fdsync:
+	syncdma
+	sync
+	mtsm    %r22
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export copy_user_page_asm,code
+
+copy_user_page_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldi 64,%r1
+
+	/*
+	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+	 * bundles (very restricted rules for bundling). It probably
+	 * does OK on PCXU and better, but we could do better with
+	 * ldd/std instructions. Note that until (if) we start saving
+	 * the full 64 bit register values on interrupt, we can't
+	 * use ldd/std on a 32 bit kernel.
+	 */
+
+
+1:
+	ldw 0(%r25),%r19
+	ldw 4(%r25),%r20
+	ldw 8(%r25),%r21
+	ldw 12(%r25),%r22
+	stw %r19,0(%r26)
+	stw %r20,4(%r26)
+	stw %r21,8(%r26)
+	stw %r22,12(%r26)
+	ldw 16(%r25),%r19
+	ldw 20(%r25),%r20
+	ldw 24(%r25),%r21
+	ldw 28(%r25),%r22
+	stw %r19,16(%r26)
+	stw %r20,20(%r26)
+	stw %r21,24(%r26)
+	stw %r22,28(%r26)
+	ldw 32(%r25),%r19
+	ldw 36(%r25),%r20
+	ldw 40(%r25),%r21
+	ldw 44(%r25),%r22
+	stw %r19,32(%r26)
+	stw %r20,36(%r26)
+	stw %r21,40(%r26)
+	stw %r22,44(%r26)
+	ldw 48(%r25),%r19
+	ldw 52(%r25),%r20
+	ldw 56(%r25),%r21
+	ldw 60(%r25),%r22
+	stw %r19,48(%r26)
+	stw %r20,52(%r26)
+	stw %r21,56(%r26)
+	stw %r22,60(%r26)
+	ldo 64(%r26),%r26
+	ADDIB>  -1,%r1,1b
+	ldo 64(%r25),%r25
+
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+#if (TMPALIAS_MAP_START >= 0x80000000UL)
+Warning TMPALIAS_MAP_START changed. If > 2 Gb, code in pacache.S is bogus
+#endif
+
+/*
+ * NOTE: Code in clear_user_page has a hard coded dependency on the
+ *       maximum alias boundary being 4 Mb. We've been assured by the
+ *       parisc chip designers that there will not ever be a parisc
+ *       chip with a larger alias boundary (Never say never :-) ).
+ *
+ *       Subtle: the dtlb miss handlers support the temp alias region by
+ *       "knowing" that if a dtlb miss happens within the temp alias
+ *       region it must have occurred while in clear_user_page. Since
+ *       this routine makes use of processor local translations, we
+ *       don't want to insert them into the kernel page table. Instead,
+ *       we load up some general registers (they need to be registers
+ *       which aren't shadowed) with the physical page numbers (preshifted
+ *       for tlb insertion) needed to insert the translations. When we
+ *       miss on the translation, the dtlb miss handler inserts the
+ *       translation into the tlb using these values:
+ *
+ *          %r26 physical page (shifted for tlb insert) of "to" translation
+ *          %r23 physical page (shifted for tlb insert) of "from" translation
+ */
+
+#if 0
+
+	/*
+	 * We can't do this since copy_user_page is used to bring in
+	 * file data that might have instructions. Since the data would
+	 * then need to be flushed out so the i-fetch can see it, it
+	 * makes more sense to just copy through the kernel translation
+	 * and flush it.
+	 *
+	 * I'm still keeping this around because it may be possible to
+	 * use it if more information is passed into copy_user_page().
+	 * Have to do some measurements to see if it is worthwhile to
+	 * lobby for such a change.
+	 */
+
+	.export copy_user_page_asm,code
+
+copy_user_page_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%(__PAGE_OFFSET),%r1
+	sub     %r26,%r1,%r26
+	sub     %r25,%r1,%r23  /* move physical addr into non shadowed reg */
+
+	ldil    L%(TMPALIAS_MAP_START),%r28
+#ifdef __LP64__
+	extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+	extrd,u %r23,56,32,%r23 /* convert phys addr to tlb insert format */
+	depd    %r24,63,22,%r28 /* Form aliased virtual address 'to' */
+	depdi   0,63,12,%r28    /* Clear any offset bits */
+	copy    %r28,%r29
+	depdi   1,41,1,%r29     /* Form aliased virtual address 'from' */
+#else
+	extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+	extrw,u %r23,24,25,%r23 /* convert phys addr to tlb insert format */
+	depw    %r24,31,22,%r28 /* Form aliased virtual address 'to' */
+	depwi   0,31,12,%r28    /* Clear any offset bits */
+	copy    %r28,%r29
+	depwi   1,9,1,%r29      /* Form aliased virtual address 'from' */
+#endif
+
+	/* Purge any old translations */
+
+	pdtlb   0(%r28)
+	pdtlb   0(%r29)
+
+	ldi 64,%r1
+
+	/*
+	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+	 * bundles (very restricted rules for bundling). It probably
+	 * does OK on PCXU and better, but we could do better with
+	 * ldd/std instructions. Note that until (if) we start saving
+	 * the full 64 bit register values on interrupt, we can't
+	 * use ldd/std on a 32 bit kernel.
+	 */
+
+
+1:
+	ldw 0(%r29),%r19
+	ldw 4(%r29),%r20
+	ldw 8(%r29),%r21
+	ldw 12(%r29),%r22
+	stw %r19,0(%r28)
+	stw %r20,4(%r28)
+	stw %r21,8(%r28)
+	stw %r22,12(%r28)
+	ldw 16(%r29),%r19
+	ldw 20(%r29),%r20
+	ldw 24(%r29),%r21
+	ldw 28(%r29),%r22
+	stw %r19,16(%r28)
+	stw %r20,20(%r28)
+	stw %r21,24(%r28)
+	stw %r22,28(%r28)
+	ldw 32(%r29),%r19
+	ldw 36(%r29),%r20
+	ldw 40(%r29),%r21
+	ldw 44(%r29),%r22
+	stw %r19,32(%r28)
+	stw %r20,36(%r28)
+	stw %r21,40(%r28)
+	stw %r22,44(%r28)
+	ldw 48(%r29),%r19
+	ldw 52(%r29),%r20
+	ldw 56(%r29),%r21
+	ldw 60(%r29),%r22
+	stw %r19,48(%r28)
+	stw %r20,52(%r28)
+	stw %r21,56(%r28)
+	stw %r22,60(%r28)
+	ldo 64(%r28),%r28
+	ADDIB>  -1,%r1,1b
+	ldo 64(%r29),%r29
+
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+#endif
+
+	.export clear_user_page_asm,code
+
+clear_user_page_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	tophys_r1 %r26
+
+	ldil    L%(TMPALIAS_MAP_START),%r28
+#ifdef __LP64__
+	extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+	depd    %r25,63,22,%r28 /* Form aliased virtual address 'to' */
+	depdi   0,63,12,%r28    /* Clear any offset bits */
+#else
+	extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+	depw    %r25,31,22,%r28 /* Form aliased virtual address 'to' */
+	depwi   0,31,12,%r28    /* Clear any offset bits */
+#endif
+
+	/* Purge any old translation */
+
+	pdtlb   0(%r28)
+
+	ldi 64,%r1
+
+1:
+	stw %r0,0(%r28)
+	stw %r0,4(%r28)
+	stw %r0,8(%r28)
+	stw %r0,12(%r28)
+	stw %r0,16(%r28)
+	stw %r0,20(%r28)
+	stw %r0,24(%r28)
+	stw %r0,28(%r28)
+	stw %r0,32(%r28)
+	stw %r0,36(%r28)
+	stw %r0,40(%r28)
+	stw %r0,44(%r28)
+	stw %r0,48(%r28)
+	stw %r0,52(%r28)
+	stw %r0,56(%r28)
+	stw %r0,60(%r28)
+	ADDIB>  -1,%r1,1b
+	ldo 64(%r28),%r28
+
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_kernel_dcache_page
+
+flush_kernel_dcache_page:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%dcache_stride,%r1
+	ldw     R%dcache_stride(%r1),%r23
+
+#ifdef __LP64__
+	depdi,z 1,63-PAGE_SHIFT,1,%r25
+#else
+	depwi,z 1,31-PAGE_SHIFT,1,%r25
+#endif
+	add     %r26,%r25,%r25
+	sub     %r25,%r23,%r25
+
+
+1:      fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	fdc,m   %r23(%r26)
+	CMPB<<  %r26,%r25,1b
+	fdc,m   %r23(%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export purge_kernel_dcache_page
+
+purge_kernel_dcache_page:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%dcache_stride,%r1
+	ldw     R%dcache_stride(%r1),%r23
+
+#ifdef __LP64__
+	depdi,z 1,63-PAGE_SHIFT,1,%r25
+#else
+	depwi,z 1,31-PAGE_SHIFT,1,%r25
+#endif
+	add      %r26,%r25,%r25
+	sub      %r25,%r23,%r25
+
+1:      pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	pdc,m   %r23(%r26)
+	CMPB<<  %r26,%r25,1b
+	pdc,m   %r23(%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+#if 0
+	/* Currently not used, but it still is a possible alternate
+	 * solution.
+	 */
+
+	.export flush_alias_page
+
+flush_alias_page:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	tophys_r1 %r26
+
+	ldil    L%(TMPALIAS_MAP_START),%r28
+#ifdef __LP64__
+	extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+	depd    %r25,63,22,%r28 /* Form aliased virtual address 'to' */
+	depdi   0,63,12,%r28    /* Clear any offset bits */
+#else
+	extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+	depw    %r25,31,22,%r28 /* Form aliased virtual address 'to' */
+	depwi   0,31,12,%r28    /* Clear any offset bits */
+#endif
+
+	/* Purge any old translation */
+
+	pdtlb   0(%r28)
+
+	ldil    L%dcache_stride,%r1
+	ldw     R%dcache_stride(%r1),%r23
+
+#ifdef __LP64__
+	depdi,z 1,63-PAGE_SHIFT,1,%r29
+#else
+	depwi,z 1,31-PAGE_SHIFT,1,%r29
+#endif
+	add      %r28,%r29,%r29
+	sub      %r29,%r23,%r29
+
+1:      fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	fdc,m   %r23(%r28)
+	CMPB<<  %r28,%r29,1b
+	fdc,m   %r23(%r28)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+#endif
+
+	.export flush_user_dcache_range_asm
+
+flush_user_dcache_range_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%dcache_stride,%r1
+	ldw     R%dcache_stride(%r1),%r23
+	ldo     -1(%r23),%r21
+	ANDCM   %r26,%r21,%r26
+
+1:      CMPB<<,n %r26,%r25,1b
+	fdc,m   %r23(%sr3,%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_kernel_dcache_range_asm
+
+flush_kernel_dcache_range_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%dcache_stride,%r1
+	ldw     R%dcache_stride(%r1),%r23
+	ldo     -1(%r23),%r21
+	ANDCM   %r26,%r21,%r26
+
+1:      CMPB<<,n %r26,%r25,1b
+	fdc,m   %r23(%r26)
+
+	sync
+	syncdma
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_user_icache_range_asm
+
+flush_user_icache_range_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%icache_stride,%r1
+	ldw     R%icache_stride(%r1),%r23
+	ldo     -1(%r23),%r21
+	ANDCM   %r26,%r21,%r26
+
+1:      CMPB<<,n %r26,%r25,1b
+	fic,m   %r23(%sr3,%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_kernel_icache_page
+
+flush_kernel_icache_page:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%icache_stride,%r1
+	ldw     R%icache_stride(%r1),%r23
+
+#ifdef __LP64__
+	depdi,z 1,63-PAGE_SHIFT,1,%r25
+#else
+	depwi,z 1,31-PAGE_SHIFT,1,%r25
+#endif
+	add     %r26,%r25,%r25
+	sub     %r25,%r23,%r25
+
+
+1:      fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	CMPB<<  %r26,%r25,1b
+	fic,m   %r23(%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.export flush_kernel_icache_range_asm
+
+flush_kernel_icache_range_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%icache_stride,%r1
+	ldw     R%icache_stride(%r1),%r23
+	ldo     -1(%r23),%r21
+	ANDCM   %r26,%r21,%r26
+
+1:      CMPB<<,n %r26,%r25,1b
+	fic,m   %r23(%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.align 128
+
+	.export disable_sr_hashing_asm,code
+
+disable_sr_hashing_asm:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	/* Switch to real mode */
+
+	ssm     0,%r0           /* relied upon translation! */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	
+	rsm     (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q&I to load the iia queue */
+	ldil    L%REAL_MODE_PSW, %r1
+	ldo     R%REAL_MODE_PSW(%r1), %r1
+	mtctl	%r1, %cr22
+	mtctl	%r0, %cr17
+	mtctl	%r0, %cr17
+	ldil    L%PA(1f),%r1
+	ldo     R%PA(1f)(%r1),%r1
+	mtctl	%r1, %cr18
+	ldo	4(%r1), %r1
+	mtctl	%r1, %cr18
+	rfi
+	nop
+
+1:      cmpib,=,n SRHASH_PCXST,%r26,srdis_pcxs
+	cmpib,=,n SRHASH_PCXL,%r26,srdis_pcxl
+	cmpib,=,n SRHASH_PA20,%r26,srdis_pa20
+	b,n       srdis_done
+
+srdis_pcxs:
+
+	/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
+
+	.word           0x141c1a00  /* mfdiag %dr0,%r28 */
+	.word           0x141c1a00  /* must issue twice */
+	depwi           0,18,1,%r28 /* Clear DHE (dcache hash enable) */
+	depwi           0,20,1,%r28 /* Clear IHE (icache hash enable) */
+	.word           0x141c1600  /* mtdiag %r28,%dr0 */
+	.word           0x141c1600  /* must issue twice */
+	b,n             srdis_done
+
+srdis_pcxl:
+
+	/* Disable Space Register Hashing for PCXL */
+
+	.word           0x141c0600  /* mfdiag %dr0,%r28 */
+	depwi           0,28,2,%r28 /* Clear DHASH_EN & IHASH_EN */
+	.word           0x141c0240  /* mtdiag %r28,%dr0 */
+	b,n             srdis_done
+
+srdis_pa20:
+
+	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */
+
+	.word           0x144008bc  /* mfdiag %dr2,%r28 */
+	depdi           0,54,1,%r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
+	.word           0x145c1840  /* mtdiag %r28,%dr2 */
+
+srdis_done:
+
+	/* Switch back to virtual mode */
+
+	rsm     PSW_SM_Q,%r0           /* clear Q bit to load iia queue */
+	ldil	L%KERNEL_PSW, %r1
+	ldo	R%KERNEL_PSW(%r1), %r1
+	mtctl	%r1, %cr22
+	mtctl	%r0, %cr17
+	mtctl	%r0, %cr17
+	ldil    L%(2f), %r1
+	ldo     R%(2f)(%r1), %r1
+	mtctl	%r1, %cr18
+	ldo	4(%r1), %r1
+	mtctl	%r1, %cr18
+	rfi
+	nop
+
+2:      bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
+	.end
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/parisc_ksyms.c linux-2.4.20/arch/parisc/kernel/parisc_ksyms.c
--- linux-2.4.19/arch/parisc/kernel/parisc_ksyms.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/parisc_ksyms.c	2002-10-04 00:41:30.000000000 +0000
@@ -14,17 +14,29 @@
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strncat);
 EXPORT_SYMBOL(strncmp);
 EXPORT_SYMBOL(strncpy);
 EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strstr);
 
+#include <asm/hardware.h>	/* struct parisc_device for asm/pci.h */
 #include <linux/pci.h>
 EXPORT_SYMBOL(hppa_dma_ops);
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+EXPORT_SYMBOL(get_pci_node_path);
+#endif
+
+#ifdef CONFIG_IOMMU_CCIO
+EXPORT_SYMBOL(ccio_get_fake);
+#endif
 
+#include <linux/sched.h>
 #include <asm/irq.h>
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
@@ -32,6 +44,13 @@
 #include <asm/processor.h>
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(boot_cpu_data);
+EXPORT_SYMBOL(map_hpux_gateway_page);
+#ifdef CONFIG_EISA
+EXPORT_SYMBOL(EISA_bus);
+#endif
+
+#include <linux/pm.h>
+EXPORT_SYMBOL(pm_power_off);
 
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(synchronize_irq);
@@ -39,35 +58,100 @@
 #include <asm/smplock.h>
 EXPORT_SYMBOL(kernel_flag);
 
+/* from asm/system.h */
 #include <asm/system.h>
 EXPORT_SYMBOL(__global_sti);
 EXPORT_SYMBOL(__global_cli);
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
 
+#include <linux/smp.h>
+EXPORT_SYMBOL(smp_num_cpus);
+#endif /* CONFIG_SMP */
+
+#include <asm/atomic.h>
+EXPORT_SYMBOL(__xchg8);
+EXPORT_SYMBOL(__xchg32);
+EXPORT_SYMBOL(__cmpxchg_u32);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(__atomic_hash);
+#endif
+#ifdef __LP64__
+EXPORT_SYMBOL(__xchg64);
+EXPORT_SYMBOL(__cmpxchg_u64);
 #endif
 
 #include <asm/uaccess.h>
 EXPORT_SYMBOL(lcopy_to_user);
 EXPORT_SYMBOL(lcopy_from_user);
+EXPORT_SYMBOL(lstrnlen_user);
+EXPORT_SYMBOL(lclear_user);
 
+#ifndef __LP64__
 /* Needed so insmod can set dp value */
-
-extern int data_start;
-
-EXPORT_SYMBOL_NOVERS(data_start);
+extern int $global$;
+EXPORT_SYMBOL_NOVERS($global$);
+#endif
 
 #include <asm/gsc.h>
-EXPORT_SYMBOL(_gsc_writeb);
-EXPORT_SYMBOL(_gsc_writew);
-EXPORT_SYMBOL(_gsc_writel);
-EXPORT_SYMBOL(_gsc_readb);
-EXPORT_SYMBOL(_gsc_readw);
-EXPORT_SYMBOL(_gsc_readl);
-EXPORT_SYMBOL(busdevice_alloc_irq);
-EXPORT_SYMBOL(register_driver);
-EXPORT_SYMBOL(gsc_alloc_irq);
+EXPORT_SYMBOL(register_parisc_driver);
+EXPORT_SYMBOL(unregister_parisc_driver);
 EXPORT_SYMBOL(pdc_iodc_read);
+#ifdef CONFIG_GSC
+EXPORT_SYMBOL(gsc_alloc_irq);
+#endif
+
+#include <asm/io.h>
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memset_io);
+
+#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+EXPORT_SYMBOL(inb);
+EXPORT_SYMBOL(inw);
+EXPORT_SYMBOL(inl);
+EXPORT_SYMBOL(outb);
+EXPORT_SYMBOL(outw);
+EXPORT_SYMBOL(outl);
+
+EXPORT_SYMBOL(insb);
+EXPORT_SYMBOL(insw);
+EXPORT_SYMBOL(insl);
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(outsl);
+#endif
+
+#include <asm/cache.h>
+EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
+EXPORT_SYMBOL(flush_kernel_dcache_page);
+EXPORT_SYMBOL(flush_all_caches);
+
+#include <asm/unistd.h>
+extern long sys_open(const char *, int, int);
+extern off_t sys_lseek(int, off_t, int);
+extern int sys_read(int, char *, int);
+extern int sys_write(int, const char *, int);
+EXPORT_SYMBOL(sys_open);
+EXPORT_SYMBOL(sys_lseek);
+EXPORT_SYMBOL(sys_read);
+EXPORT_SYMBOL(sys_write);
+
+#include <asm/semaphore.h>
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down);
+
+#include <linux/in6.h>
+#include <asm/checksum.h>
+EXPORT_SYMBOL(csum_partial_copy);
+
+#include <asm/pdc.h>
+EXPORT_SYMBOL(pdc_add_valid);
+EXPORT_SYMBOL(pdc_lan_station_id);
+EXPORT_SYMBOL(pdc_get_initiator);
 
 extern void $$divI(void);
 extern void $$divU(void);
@@ -99,7 +183,9 @@
 EXPORT_SYMBOL_NOVERS($$remI);
 EXPORT_SYMBOL_NOVERS($$remU);
 EXPORT_SYMBOL_NOVERS($$mulI);
+#ifndef __LP64__
 EXPORT_SYMBOL_NOVERS($$mulU);
+#endif
 EXPORT_SYMBOL_NOVERS($$divU_3);
 EXPORT_SYMBOL_NOVERS($$divU_5);
 EXPORT_SYMBOL_NOVERS($$divU_6);
@@ -120,15 +206,25 @@
 EXPORT_SYMBOL_NOVERS($$divI_15);
 
 extern void __ashrdi3(void);
+extern void __ashldi3(void);
+extern void __lshrdi3(void);
+extern void __muldi3(void);
 
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
+EXPORT_SYMBOL_NOVERS(__muldi3);
 
 #ifdef __LP64__
 extern void __divdi3(void);
 extern void __udivdi3(void);
+extern void __umoddi3(void);
+extern void __moddi3(void);
 
 EXPORT_SYMBOL_NOVERS(__divdi3);
 EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
+EXPORT_SYMBOL_NOVERS(__moddi3);
 #endif
 
 #ifndef __LP64__
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pci-dma.c linux-2.4.20/arch/parisc/kernel/pci-dma.c
--- linux-2.4.19/arch/parisc/kernel/pci-dma.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pci-dma.c	2002-10-04 00:41:29.000000000 +0000
@@ -1,5 +1,7 @@
 /*
-** Dynamic DMA mapping support.
+** PARISC 1.1 Dynamic DMA mapping support.
+** This implementation is for PA-RISC platforms that do not support
+** I/O TLBs (aka DMA address translation hardware).
 ** See Documentation/DMA-mapping.txt for interface definitions.
 **
 **      (c) Copyright 1999,2000 Hewlett-Packard Company
@@ -7,15 +9,10 @@
 **	(c) Copyright 2000 Philipp Rumpf <prumpf@tux.org>
 **      (c) Copyright 2000 John Marvin
 **
-** This implementation is for PA-RISC platforms that do not support
-** I/O TLBs (aka DMA address translation hardware).
-**
 ** "leveraged" from 2.3.47: arch/ia64/kernel/pci-dma.c.
 ** (I assume it's from David Mosberger-Tang but there was no Copyright)
 **
 ** AFAIK, all PA7100LC and PA7300LC platforms can use this code.
-** All PA2.0 machines but V-class can alias xxx_alloc_consistent()
-** to use regular cacheable memory.
 **
 ** - ggg
 */
@@ -117,7 +114,7 @@
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
 	do {
-		pte_t * pte = pte_alloc_kernel(pmd, vaddr);
+		pte_t * pte = pte_alloc(NULL, pmd, vaddr);
 		if (!pte)
 			return -ENOMEM;
 		if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
@@ -139,7 +136,7 @@
 	do {
 		pmd_t *pmd;
 		
-		pmd = pmd_alloc_kernel(dir, vaddr);
+		pmd = pmd_alloc(NULL, dir, vaddr);
 		if (!pmd)
 			return -ENOMEM;
 		if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))
@@ -510,7 +507,6 @@
 	pa11_dma_sync_sg			/* dma_sync_sg */
 };
 
-struct pci_dma_ops *hppa_dma_ops;
 
 static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pci.c linux-2.4.20/arch/parisc/kernel/pci.c
--- linux-2.4.19/arch/parisc/kernel/pci.c	2000-12-06 19:46:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pci.c	2002-10-04 00:41:09.000000000 +0000
@@ -6,25 +6,32 @@
  *
  * Copyright (C) 1997, 1998 Ralf Baechle
  * Copyright (C) 1999 SuSE GmbH
- * Copyright (C) 1999 Hewlett-Packard Company
- * Copyright (C) 1999, 2000 Grant Grundler
+ * Copyright (C) 1999-2001 Hewlett-Packard Company
+ * Copyright (C) 1999-2001 Grant Grundler
  */
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>		/* for __init and __devinit */
 #include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>	/* for memcpy() */
+#include <linux/slab.h>
 
+#include <asm/io.h>
 #include <asm/system.h>
+#include <asm/cache.h>		/* for L1_CACHE_BYTES */
 
-#ifdef CONFIG_PCI
+#define DEBUG_RESOURCES 0
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBGC(x...)     printk(KERN_DEBUG x)
+#else
+# define DBGC(x...)
+#endif
 
-#undef DEBUG_RESOURCES
 
-#ifdef DEBUG_RESOURCES
-#define DBG_RES(x...)	printk(x)
+#if DEBUG_RESOURCES
+#define DBG_RES(x...)	printk(KERN_DEBUG x)
 #else
 #define DBG_RES(x...)
 #endif
@@ -42,14 +49,13 @@
 struct pci_port_ops *pci_port;
 struct pci_bios_ops *pci_bios;
 
-struct pci_hba_data *hba_list = NULL;
-int hba_count = 0;
+int pci_hba_count = 0;
 
 /*
 ** parisc_pci_hba used by pci_port->in/out() ops to lookup bus data.
 */
 #define PCI_HBA_MAX 32
-static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
+struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX];
 
 
 /********************************************************************
@@ -58,24 +64,31 @@
 **
 *********************************************************************/
 
-#define PCI_PORT_HBA(a) ((a)>>16)
-#define PCI_PORT_ADDR(a) ((a) & 0xffffUL)
+/* EISA port numbers and PCI port numbers share the same interface.  Some
+ * machines have both EISA and PCI adapters installed.  Rather than turn
+ * pci_port into an array, we reserve bus 0 for EISA and call the EISA
+ * routines if the access is to a port on bus 0.  We don't want to fix
+ * EISA and ISA drivers which assume port space is <= 0xffff.
+ */
 
-/* KLUGE : inb needs to be defined differently for PCI devices than
-** for other bus interfaces. Doing this at runtime sucks but is the
-** only way one driver binary can support devices on different bus types.
-**
-*/
+#ifdef CONFIG_EISA
+#define EISA_IN(size) if (EISA_bus && (b == 0)) return eisa_in##size(addr)
+#define EISA_OUT(size) if (EISA_bus && (b == 0)) return eisa_out##size(d, addr)
+#else
+#define EISA_IN(size)
+#define EISA_OUT(size)
+#endif
 
 #define PCI_PORT_IN(type, size) \
 u##size in##type (int addr) \
 { \
 	int b = PCI_PORT_HBA(addr); \
 	u##size d = (u##size) -1; \
+	EISA_IN(size); \
 	ASSERT(pci_port); /* make sure services are defined */ \
 	ASSERT(parisc_pci_hba[b]); /* make sure ioaddr are "fixed up" */ \
 	if (parisc_pci_hba[b] == NULL) { \
-		printk(KERN_WARNING "\nPCI Host Bus Adapter %d not registered. in" #size "(0x%x) returning -1\n", b, addr); \
+		printk(KERN_WARNING "\nPCI or EISA Host Bus Adapter %d not registered. in" #size "(0x%x) returning -1\n", b, addr); \
 	} else { \
 		d = pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
 	} \
@@ -91,6 +104,7 @@
 void out##type (u##size d, int addr) \
 { \
 	int b = PCI_PORT_HBA(addr); \
+	EISA_OUT(size); \
 	ASSERT(pci_port); \
 	pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
 }
@@ -106,15 +120,13 @@
  */
 void pcibios_init(void)
 {
-	ASSERT(pci_bios != NULL);
+	if (!pci_bios)
+		return;
 
-	if (pci_bios)
-	{
-		if (pci_bios->init) {
-			(*pci_bios->init)();
-		} else {
-			printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
-		}
+	if (pci_bios->init) {
+		pci_bios->init();
+	} else {
+		printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
 	}
 }
 
@@ -124,17 +136,10 @@
 {
 	ASSERT(pci_bios != NULL);
 
-        /* If this is a bridge, get the current bases */
-	if (bus->self) {
-		pci_read_bridge_bases(bus);
-	}
-
-	if (pci_bios) {
-		if (pci_bios->fixup_bus) {
-			(*pci_bios->fixup_bus)(bus);
-		} else {
-			printk(KERN_WARNING "pci_bios != NULL but fixup_bus() is!\n");
-		}
+	if (pci_bios->fixup_bus) {
+		pci_bios->fixup_bus(bus);
+	} else {
+		printk(KERN_WARNING "pci_bios != NULL but fixup_bus() is!\n");
 	}
 }
 
@@ -144,14 +149,6 @@
 	return str;
 }
 
-#endif /* defined(CONFIG_PCI) */
-
-
-
-/* -------------------------------------------------------------------
-** linux-2.4: NEW STUFF 
-** --------------------
-*/
 
 /*
 ** Used in drivers/pci/quirks.c
@@ -201,19 +198,11 @@
 ** ------------------------------------
 ** PAT PDC systems need this routine. PA legacy PDC does not.
 **
-** Used by alpha/arm: 
-** alpha/kernel/pci.c:common_init_pci()
-** (or arm/kernel/pci.c:pcibios_init())
-**    drivers/pci/setup.c:pci_assign_unassigned_resources()
-**        drivers/pci/setup.c:pdev_assign_unassigned_resources()
-**            arch/<foo>/kernel/pci.c:pcibios_update_resource()
-**
-** When BAR's are configured by linux, this routine
-** will update configuration space with the "normalized"
-** address. "root" indicates where the range starts and res
-** is some portion of that range.
+** When BAR's are configured by linux, this routine will update
+** configuration space with the "normalized" address. "root" indicates
+** where the range starts and res is some portion of that range.
 **
-** For all PA-RISC systems except V-class, root->start would be zero.
+** VCLASS: For all PA-RISC systems except V-class, root->start would be zero.
 **
 ** PAT PDC can tell us which MMIO ranges are available or already in use.
 ** I/O port space and such are not memory mapped anyway for PA-Risc.
@@ -234,7 +223,7 @@
 		barnum, res->start, res->end, (int) res->flags);
 
 	if (barnum >= PCI_BRIDGE_RESOURCES) {
-		/* handled in pbus_set_ranges_data() */
+		/* handled in PCI-PCI bridge specific support */
 		return;
 	}
 
@@ -248,8 +237,7 @@
 	if (res->flags & IORESOURCE_IO) {
 		barval = PCI_PORT_ADDR(res->start);
 	} else if (res->flags & IORESOURCE_MEM) {
-		/* This should work for VCLASS too */
-		barval = res->start & 0xffffffffUL;
+		barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->sysdata), res->start);
 	} else {
 		panic("pcibios_update_resource() WTF? flags not IO or MEM");
 	}
@@ -267,7 +255,7 @@
 	    == (PCI_BASE_ADDRESS_SPACE_MEMORY
 		| PCI_BASE_ADDRESS_MEM_TYPE_64)) {
 		pci_write_config_dword(dev, where+4, 0);
-		printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name);
+		DBGC("PCIBIOS: dev %s type 64-bit\n", dev->name);
 	}
 }
 
@@ -290,25 +278,78 @@
 pcibios_set_master(struct pci_dev *dev)
 {
 	u8 lat;
+
+	/* If someone already mucked with this, don't touch it. */
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
 	if (lat >= 16) return;
 
 	/*
 	** HP generally has fewer devices on the bus than other architectures.
+	** upper byte is PCI_LATENCY_TIMER.
 	*/
-	printk("PCIBIOS: Setting latency timer of %s to 128\n", dev->slot_name);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
+        pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
+				(0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+}
+
+
+void __init
+pcibios_init_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev = bus->self;
+
+	/* We deal only with pci controllers and pci-pci bridges. */
+	if (dev && (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+		return;
+	
+	if (dev) {
+		/* PCI-PCI bridge - set the cache line and default latency
+		   (32) for primary and secondary buses. */
+		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 32);
+
+		/* Read bridge control */
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bus->bridge_ctl);
+	}
+
+	/* Set FBB bit for now. Disable ISA IO forwarding. Enable PERR/SERR */
+	bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK | 
+			   PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
 }
 
 
 /*
-** called by drivers/pci/setup-res.c:pbus_set_ranges().
+** KLUGE: Link the child and parent resources - generic PCI didn't
+*/
+static void
+pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+{
+	if (!r->parent) {
+		r->parent = hba_res;
+
+		/* reverse link is harder *sigh*  */
+		if (r->parent->child) {
+			if (r->parent->sibling) {
+				struct resource *next = r->parent->sibling;
+				while (next->sibling)
+					 next = next->sibling;
+				next->sibling = r;
+			} else {
+				r->parent->sibling = r;
+			}
+		} else
+			r->parent->child = r;
+	}
+}
+
+/*
+** called by drivers/pci/setup-res.c:pci_setup_bridge().
 */
 void pcibios_fixup_pbus_ranges(
 	struct pci_bus *bus,
 	struct pbus_set_ranges_data *ranges
 	)
 {
+	struct pci_hba_data *hba = HBA_DATA(bus->sysdata);
+
 	/*
 	** I/O space may see busnumbers here. Something
 	** in the form of 0xbbxxxx where bb is the bus num
@@ -319,9 +360,20 @@
 	ranges->io_start = PCI_PORT_ADDR(ranges->io_start);
 	ranges->io_end   = PCI_PORT_ADDR(ranges->io_end);
 
+	/* Convert MMIO addr to PCI addr (undo global virtualization) */
+	ranges->mem_start = PCI_BUS_ADDR(hba, ranges->mem_start);
+	ranges->mem_end   = PCI_BUS_ADDR(hba, ranges->mem_end);
+
 	DBG_RES("pcibios_fixup_pbus_ranges(%02x, [%lx,%lx %lx,%lx])\n", bus->number,
 		ranges->io_start, ranges->io_end,
 		ranges->mem_start, ranges->mem_end);
+
+	/* KLUGE ALERT
+	** if this resource isn't linked to a "parent", then it seems
+	** to be a child of the HBA - lets link it in.
+	*/
+	pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
+	pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
 }
 
 #define MAX(val1, val2)   ((val1) > (val2) ? (val1) : (val2))
@@ -337,13 +389,15 @@
 ** than res->start.
 */
 void __devinit
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long alignment)
 {
 	unsigned long mask, align;
 
-	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx)\n",
+	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
 		((struct pci_dev *) data)->slot_name,
-		res->parent, res->start, res->end, (int) res->flags, size);
+		res->parent, res->start, res->end,
+		(int) res->flags, size, alignment);
 
 	/* has resource already been aligned/assigned? */
 	if (res->parent)
@@ -360,107 +414,15 @@
 	/*
 	** WARNING : caller is expected to update "end" field.
 	** We can't since it might really represent the *size*.
-	** The difference is "end = start + size" vs "end += size".
+	** The difference is "end = start + size" vs "end += start".
 	*/
 }
 
 
-#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
-
-void __devinit
-pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
-{
-	struct pbus_set_ranges_data inner;
-	struct pci_dev *dev;
-	struct pci_dev *bridge = bus->self;
-	struct list_head *ln;
-
-	/* set reasonable default "window" for pcibios_align_resource */
-	inner.io_start  = inner.io_end  = 0;
-	inner.mem_start = inner.mem_end = 0;
-
-	/* Collect information about how our direct children are layed out. */
-	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-		int i;
-		dev = pci_dev_b(ln);
-
-		/* Skip bridges here - we'll catch them below */
-		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
-			continue;
-
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource res;
-			unsigned long size;
-
-			if (dev->resource[i].flags == 0)
-				continue;
-
-			memcpy(&res, &dev->resource[i], sizeof(res));
-			size = res.end - res.start + 1;
-
-			if (res.flags & IORESOURCE_IO) {
-				res.start = inner.io_end;
-				pcibios_align_resource(dev, &res, size);
-				inner.io_end += res.start + size;
-			} else if (res.flags & IORESOURCE_MEM) {
-				res.start = inner.mem_end;
-				pcibios_align_resource(dev, &res, size);
-				inner.mem_end = res.start + size;
-			}
-
-		DBG_RES("    %s  inner size %lx/%x IO %lx MEM %lx\n",
-			dev->slot_name,
-			size, res.flags, inner.io_end, inner.mem_end);
-		}
-	}
-
-	/* And for all of the subordinate busses. */
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
-		pcibios_size_bridge(pci_bus_b(ln), &inner);
-
-	/* turn the ending locations into sizes (subtract start) */
-	inner.io_end -= inner.io_start - 1;
-	inner.mem_end -= inner.mem_start - 1;
-
-	/* Align the sizes up by bridge rules */
-	inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
-	inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
-
-	/* PPB - PCI bridge Device will normaller also have "outer" != NULL. */
-	if (bridge) {
-		/* Adjust the bus' allocation requirements */
-		/* PPB's pci device Bridge resources */
-
-		bus->resource[0] = &bridge->resource[PCI_BRIDGE_RESOURCES];
-		bus->resource[1] = &bridge->resource[PCI_BRIDGE_RESOURCES + 1];
-		
-		bus->resource[0]->start = bus->resource[1]->start  = 0;
-		bus->resource[0]->parent= bus->resource[1]->parent = NULL;
-
-		bus->resource[0]->end    = inner.io_end;
-		bus->resource[0]->flags  = IORESOURCE_IO;
-
-		bus->resource[1]->end    = inner.mem_end;
-		bus->resource[1]->flags  = IORESOURCE_MEM;
-	}
-
-	/* adjust parent's resource requirements */
-	if (outer) {
-		outer->io_end = ROUND_UP(outer->io_end, 4*1024);
-		outer->io_end += inner.io_end;
-
-		outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
-		outer->mem_end += inner.mem_end;
-	}
-}
-
-#undef ROUND_UP
-
-
 int __devinit
 pcibios_enable_device(struct pci_dev *dev)
 {
-	u16 cmd, old_cmd;
+	u16 cmd;
 	int idx;
 
 	/*
@@ -468,12 +430,13 @@
 	** enable all the same bits. We just make sure they are here.
 	*/
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
 
 	/*
 	** See if any resources have been allocated
+	** While "regular" PCI devices only use 0-5, Bridges use a few
+	** beyond that for window registers.
 	*/
-        for (idx=0; idx<6; idx++) {
+        for (idx=0; idx<DEVICE_COUNT_RESOURCE; idx++) {
 		struct resource *r = &dev->resource[idx];
 		if (r->flags & IORESOURCE_IO)
 			cmd |= PCI_COMMAND_IO;
@@ -482,7 +445,7 @@
 	}
 
 	/*
-	** System error and Parity Error reporting are enabled by default.
+	** Enable System error and Parity Error reporting by default.
 	** Devices that do NOT want those behaviors should clear them
 	** (eg PCI graphics, possibly networking).
 	** Interfaces like SCSI certainly should not. We want the
@@ -491,30 +454,48 @@
 	*/
 	cmd |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
 
-	if (cmd != old_cmd) {
-		printk("PCIBIOS: Enabling device %s (%04x -> %04x)\n",
-			dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
+	/* If bridge/bus controller has FBB enabled, child must too. */
+	if (dev->bus->bridge_ctl & PCI_BRIDGE_CTL_FAST_BACK)
+		cmd |= PCI_COMMAND_FAST_BACK;
 
+	DBGC("PCIBIOS: Enabling device %s cmd 0x%04x\n", dev->slot_name, cmd);
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
 	return 0;
 }
 
-
-void __devinit
-pcibios_assign_unassigned_resources(struct pci_bus *bus)
+void __init
+pcibios_setup_host_bridge(struct pci_bus *bus)
 {
-	struct list_head *ln;
+	ASSERT(pci_bios != NULL);
 
-        for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next)
+#if 0
+	if (pci_bios)
 	{
-		pdev_assign_unassigned_resources(pci_dev_b(ln));
+		if (pci_bios->setup_host_bridge) {
+			(*pci_bios->setup_host_bridge)(bus);
+		}
 	}
+#endif
+}
 
-        /* And for all of the sub-busses.  */
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
-		pcibios_assign_unassigned_resources(pci_bus_b(ln));
 
+/*
+** Mostly copied from drivers/pci/setup-bus.c:pci_assign_unassigned_resources()
+*/
+void __devinit
+pcibios_assign_unassigned_resources(struct pci_bus *bus)
+{
+	/* from drivers/pci/setup-bus.c */
+	extern void pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges);
+
+	struct pbus_set_ranges_data ranges;
+
+	ranges.io_end = ranges.io_start
+				= bus->resource[0]->start + PCIBIOS_MIN_IO;
+	ranges.mem_end = ranges.mem_start
+				= bus->resource[1]->start + PCIBIOS_MIN_MEM;
+	ranges.found_vga = 0;
+	pbus_assign_resources(bus, &ranges);
 }
 
 /*
@@ -522,14 +503,9 @@
 */
 void pcibios_register_hba(struct pci_hba_data *hba)
 {
-	hba->next = hba_list;
-	hba_list = hba;
-
-	ASSERT(hba_count < PCI_HBA_MAX);
+	ASSERT(pci_hba_count < PCI_HBA_MAX);
 
-	/*
-	** pci_port->in/out() uses parisc_pci_hba to lookup parameter.
-	*/
-	parisc_pci_hba[hba_count] = hba;
-	hba->hba_num = hba_count++;
+	/* pci_port->in/out() uses parisc_pci_hba to lookup parameter. */
+	parisc_pci_hba[pci_hba_count] = hba;
+	hba->hba_num = pci_hba_count++;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pdc.c linux-2.4.20/arch/parisc/kernel/pdc.c
--- linux-2.4.19/arch/parisc/kernel/pdc.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pdc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,217 +0,0 @@
-/* arch/parisc/kernel/pdc.c  - safe pdc access routines
- *
- * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
- * portions Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
- *
- * only these routines should be used out of the real kernel (i.e. everything
- * using virtual addresses) for obvious reasons */
-
-/*	I think it would be in everyone's best interest to follow this
- *	guidelines when writing PDC wrappers:
- *
- *	 - the name of the pdc wrapper should match one of the macros
- *	   used for the first two arguments
- *	 - don't use caps for random parts of the name
- *	 - use ASSERT_ALIGN to ensure the aligment of the arguments is
- *	   correct
- *	 - use __pa() to convert virtual (kernel) pointers to physical
- *	   ones.
- *	 - the name of the struct used for pdc return values should equal
- *	   one of the macros used for the first two arguments to the
- *	   corresponding PDC call
- *	 - keep the order of arguments
- *	 - don't be smart (setting trailing NUL bytes for strings, return
- *	   something useful even if the call failed) unless you are sure
- *	   it's not going to affect functionality or performance
- *
- *	Example:
- *	int pdc_cache_info(struct pdc_cache_info *cache_info )
- *	{
- *		ASSERT_ALIGN(cache_info, 8);
- *	
- *		return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
- *	}
- *					prumpf	991016	
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-#include <asm/pdc.h>
-#include <asm/real.h>
-#include <asm/system.h>
-
-
-#define ASSERT_ALIGN(ptr, align)					\
-	do { if(((unsigned long)(ptr)) & (align-1)) {			\
-		printk("PDC: %s:%d  %s() called with "	\
-			"unaligned argument from %p", __FILE__, __LINE__, \
-			__FUNCTION__, __builtin_return_address(0));	\
-									\
-		return -1;						\
-	} } while(0)
-	
-/* verify address can be accessed without an HPMC */
-int pdc_add_valid(void *address)
-{
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, (unsigned long)address);
-}
-
-#if 0
-int pdc_chassis_warn(struct pdc_chassis_warn *address)
-{
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(address), 0);
-}
-#endif
-
-int pdc_chassis_disp(unsigned long disp)
-{
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
-}
-
-int pdc_chassis_info(void *pdc_result, void *chassis_info, unsigned long len)
-{
-	ASSERT_ALIGN(pdc_result, 4);
-	ASSERT_ALIGN(chassis_info, 4);
-	return mem_pdc_call(PDC_CHASSIS,PDC_RETURN_CHASSIS_INFO, 
-	        __pa(pdc_result), __pa(chassis_info), len);
-}
-
-int pdc_hpa_processor(void *address)
-{
-	/* We're using 0 for the last parameter just to make sure.
-	   It's actually HVERSION dependant.  And remember, life is
-	   hard without a backspace. */
-	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_HPA, PDC_HPA_PROCESSOR, __pa(address),0);
-}
-
-#if 0
-int pdc_hpa_modules(void *address)
-{
-	return mem_pdc_call(PDC_HPA, PDC_HPA_MODULES, address);
-}
-#endif
-
-int pdc_iodc_read(void *address, void * hpa, unsigned int index,
-	void * iodc_data, unsigned int iodc_data_size)
-{
-	ASSERT_ALIGN(address, 4);
-	ASSERT_ALIGN(iodc_data, 8);
-	return mem_pdc_call(PDC_IODC, PDC_IODC_READ, 
-		__pa(address), hpa, index, __pa(iodc_data), iodc_data_size);
-}
-
-
-int pdc_system_map_find_mods(void *pdc_mod_info, 
-	void *mod_path, int index)
-{
-	return mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE,
-		__pa(pdc_mod_info), __pa(mod_path), (long)index);
-}
-
-
-int pdc_model_info(struct pdc_model *model) {
-	ASSERT_ALIGN(model, 8);
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_INFO,__pa(model),0);
-}
-
-/* get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) */ 
-int pdc_model_sysmodel(char * name)
-{
-	struct pdc_model_sysmodel sys_model;
-	int retval;
-	
-	ASSERT_ALIGN(&sys_model, 8);
-	ASSERT_ALIGN(name, 4);
-
-	sys_model.mod_len = 0;
-	retval = mem_pdc_call(PDC_MODEL,PDC_MODEL_SYSMODEL,__pa(&sys_model),
-		    OS_ID_HPUX,__pa(name));
-	
-	if (retval == PDC_RET_OK) 
-	    name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
-	else
-	    name[0] = 0;
-	
-	return retval;
-}
-
-/* id: 0 = cpu revision, 1 = boot-rom-version */
-int pdc_model_versions(struct pdc_model_cpuid *cpu_id, int id) {
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_VERSIONS,__pa(cpu_id),id);
-}
-
-int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) {
-	cpu_id->cpuid = 0; /* preset zero (call maybe not implemented!) */
-	return mem_pdc_call(PDC_MODEL,6,__pa(cpu_id),0);  /* 6="return CPU ID" */
-}
-
-int pdc_cache_info(struct pdc_cache_info *cache_info) {
-	ASSERT_ALIGN(cache_info, 8);
-
-	return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
-}
-
-#ifndef __LP64__
-int pdc_btlb_info( struct pdc_btlb_info *btlb ) {
-	int status;
-	status = mem_pdc_call(PDC_BLOCK_TLB,PDC_BTLB_INFO,__pa(btlb),0);
-	if (status<0) btlb->max_size = 0;
-	return status;
-}
-
-int pdc_mem_map_hpa(void *r_addr, void *mod_path) {
-	return mem_pdc_call(PDC_MEM_MAP,PDC_MEM_MAP_HPA,
-		__pa(r_addr),__pa(mod_path));
-}
-
-int pdc_lan_station_id(char *lan_addr, void *net_hpa) {
-	struct pdc_lan_station_id id;
-	unsigned char *addr;
-	
-	if (mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
-			__pa(&id), net_hpa) < 0)
-		addr = 0;	/* FIXME: else read MAC from NVRAM */
-	    else
-		addr = id.addr;
-	if (addr)
-		memmove( lan_addr, addr, PDC_LAN_STATION_ID_SIZE);
-	    else
-		memset( lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
-	return (addr != 0);
-}
-#endif
-
-
-/* Similar to PDC_PAT stuff in pdcpat.c - but added for Forte/Allegro boxes */
-int pdc_pci_irt_size(void *r_addr, void *hpa)
-{
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
-		__pa(r_addr), hpa);
-
-}
-
-int pdc_pci_irt(void *r_addr, void *hpa, void *tbl)
-{
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
-		__pa(r_addr), hpa, __pa(tbl));
-}
-
-/* access the TOD clock */
-int pdc_tod_read(struct pdc_tod *tod)
-{
-	ASSERT_ALIGN(tod, 8);
-	return mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(tod), 0);
-}
-
-int pdc_tod_set(unsigned long sec, unsigned long usec)
-{
-	return mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/pdc_cons.c linux-2.4.20/arch/parisc/kernel/pdc_cons.c
--- linux-2.4.19/arch/parisc/kernel/pdc_cons.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/pdc_cons.c	2002-10-04 00:41:14.000000000 +0000
@@ -1,100 +1,49 @@
+/*
+ *  linux/arch/parisc/kernel/pdc_console.c
+ *
+ *  The PDC console is a simple console, which can be used for debugging 
+ *  boot related problems on HP PA-RISC machines.
+ *
+ *  This code uses the ROM (=PDC) based functions to read and write characters
+ *  from and to PDC's boot path.
+ *  Since all character read from that path must be polled, this code never
+ *  can or will be a fully functional linux console.
+ */
+
+/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems. 
+ * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
+#undef EARLY_BOOTUP_DEBUG
+
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/console.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <asm/page.h>
 #include <asm/types.h>
 #include <asm/system.h>
-#include <asm/pdc.h>	/* for iodc_call() proto and friends */
-#include <asm/real.h>
+#include <asm/pdc.h>		/* for iodc_call() proto and friends */
 
-static int __attribute__((aligned(8)))   iodc_retbuf[32];
-static char __attribute__((aligned(64))) iodc_dbuf[4096];
-
-/*
- * pdc_putc:
- * Console character print using IODC.
- *
- * Note that only these special chars are architected for console IODC io:
- * BEL, BS, CR, and LF. Others are passed through.
- * Since the HP console requires CR+LF to perform a 'newline', we translate
- * "\n" to "\r\n".
- */
-
-static int posx;	/* for simple TAB-Simulation... */
-
-/* XXX Should we spinlock posx usage */
-
-void pdc_putc(unsigned char c)
-{
-	unsigned int n;
-	unsigned long flags;
-
-	switch (c) {
-	case '\n':
-		iodc_dbuf[0] = '\r'; 
-		iodc_dbuf[1] = '\n';
-               	n = 2;
-               	posx = 0;
-		break;
-	case '\t':
-		pdc_putc(' ');
-		while (posx & 7) 	/* expand TAB */
-			pdc_putc(' ');
-		return;		/* return since IODC can't handle this */
-	case '\b':
-		posx-=2;		/* BS */
-	default:
-		iodc_dbuf[0] = c;
-		n = 1;
-		posx++;
-		break;
-	}
-	{
-		real32_call(PAGE0->mem_cons.iodc_io,
-			(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
-			PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
-			__pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
-	}
-}
 
 static void pdc_console_write(struct console *co, const char *s, unsigned count)
 {
 	while(count--)
-		pdc_putc(*s++);
+		pdc_iodc_putc(*s++);
 }
 
-int pdc_console_wait_key(struct console *co)
+void pdc_outc(unsigned char c)
 {
-	int ch = 'X';
-	int status;
-
-	/* Bail if no console input device. */
-	if (!PAGE0->mem_kbd.iodc_io)
-		return 0;
-	
-	/* wait for a keyboard (rs232)-input */
-	do {
-		unsigned long flags;
-
-		save_flags(flags);
-		cli();
-		status = real32_call(PAGE0->mem_kbd.iodc_io,
-			(unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
-			PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
-			__pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
-		restore_flags(flags);
-		ch = *iodc_dbuf;	/* save the character directly to ch */
-	} while (*iodc_retbuf == 0);	/* wait for a key */
-	return ch;
+	pdc_iodc_outc(c);
 }
 
-int pdc_getc(void)
+
+int pdc_console_poll_key(struct console *co)
 {
-	return pdc_console_wait_key(NULL);
+	return pdc_iodc_getc();
 }
 
 static int pdc_console_setup(struct console *co, char *options)
@@ -102,17 +51,34 @@
 	return 0;
 }
 
+#ifdef CONFIG_PDC_CONSOLE
+static kdev_t pdc_console_device (struct console *c)
+{
+        return MKDEV(PDCCONS_MAJOR, 0);
+}
+#endif
+
+#ifdef CONFIG_PDC_CONSOLE
+#define PDC_CONSOLE_DEVICE pdc_console_device
+#else
+#define PDC_CONSOLE_DEVICE NULL
+#endif
+
 static struct console pdc_cons = {
 	name:		"ttyB",
 	write:		pdc_console_write,
+ 	device:		PDC_CONSOLE_DEVICE,
 	setup:		pdc_console_setup,
-	flags:		CON_PRINTBUFFER|CON_ENABLED,  // |CON_CONSDEV,
+	flags:		CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
 	index:		-1,
 };
 
 static int pdc_console_initialized;
 
-void pdc_console_init(void)
+extern unsigned long con_start;	/* kernel/printk.c */
+extern unsigned long log_end;	/* kernel/printk.c */
+  
+static void pdc_console_init_force(void)
 {
 	if (pdc_console_initialized)
 		return;
@@ -122,23 +88,32 @@
 	if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
 		memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));
 
-	pdc_console_write(0, "PDC Console Initialized\n", 24);
 	/* register the pdc console */
 	register_console(&pdc_cons);
 }
 
+void pdc_console_init(void)
+{
+#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE)
+	pdc_console_init_force();
+#endif
+#ifdef EARLY_BOOTUP_DEBUG
+	printk(KERN_INFO "Initialized PDC Console for debugging.\n");
+#endif
+}
+
 
 /* Unregister the pdc console with the printk console layer */
 void pdc_console_die(void)
 {
-	printk("Switching from PDC console\n");
 	if (!pdc_console_initialized)
 		return;
 	--pdc_console_initialized;
-	
-#ifdef CONFIG_VT_CONSOLE
-	schedule_console_callback();
-#endif
+
+	printk(KERN_INFO "Switching from PDC console\n");
+
+	/* Don't repeat what we've already printed */
+	con_start = log_end;
 
 	unregister_console(&pdc_cons);
 }
@@ -155,17 +130,17 @@
 void pdc_console_restart(void)
 {
 	struct console *console;
-	extern int log_size;
 
 	if (pdc_console_initialized)
 		return;
 
-	while ((console = console_drivers) != (struct console *)0)
+	while ((console = console_drivers) != NULL)
 		unregister_console(console_drivers);
 
-	log_size = 0;
-	pdc_console_init();
-	printk("Switched to PDC console\n");
-	return;
+	/* Don't repeat what we've already printed */
+	con_start = log_end;
+	
+	/* force registering the pdc console */
+	pdc_console_init_force();
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/perf.c linux-2.4.20/arch/parisc/kernel/perf.c
--- linux-2.4.19/arch/parisc/kernel/perf.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/perf.c	2002-10-04 00:41:10.000000000 +0000
@@ -0,0 +1,838 @@
+/*
+ *  Parisc performance counters
+ *  Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ *
+ *  This code is derived, with permission, from HP/UX sources.
+ *
+ *    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, 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.
+ */
+
+/*
+ *  Edited comment from original sources:
+ *
+ *  This driver programs the PCX-U/PCX-W performance counters
+ *  on the PA-RISC 2.0 chips.  The driver keeps all images now
+ *  internally to the kernel to hopefully eliminate the possiblity
+ *  of a bad image halting the CPU.  Also, there are different
+ *  images for the PCX-W and later chips vs the PCX-U chips.
+ *
+ *  Only 1 process is allowed to access the driver at any time,
+ *  so the only protection that is needed is at open and close.
+ *  A variable "perf_enabled" is used to hold the state of the
+ *  driver.  The spinlock "perf_lock" is used to protect the
+ *  modification of the state during open/close operations so
+ *  multiple processes don't get into the driver simultaneously.
+ *
+ *  This driver accesses the processor directly vs going through
+ *  the PDC INTRIGUE calls.  This is done to eliminate bugs introduced
+ *  in various PDC revisions.  The code is much more maintainable
+ *  and reliable this way vs having to debug on every version of PDC
+ *  on every box. 
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+
+#include <asm/gsc.h>
+#include <asm/uaccess.h>
+#include <asm/perf.h>
+#include <asm/processor.h>
+
+#include "perf_images.h"
+
+#define MAX_RDR_WORDS	24
+#define PERF_VERSION	2	/* derived from hpux's PI v2 interface */
+
+/* definition of RDR regs */
+struct rdr_tbl_ent {
+	uint16_t	width;
+	uint8_t		num_words;
+	uint8_t		write_control;
+};
+
+static int perf_processor_interface = UNKNOWN_INTF;
+static int perf_enabled = 0;
+static spinlock_t perf_lock;
+struct parisc_device *cpu_device = NULL;
+
+/* RDRs to write for PCX-W */
+static int perf_rdrs_W[] = 
+	{ 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
+
+/* RDRs to write for PCX-U */
+static int perf_rdrs_U[] =
+	{ 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
+
+/* RDR register descriptions for PCX-W */
+static struct rdr_tbl_ent perf_rdr_tbl_W[] = {
+	{ 19,	1,	8 },   /* RDR 0 */
+	{ 16,	1,	16 },  /* RDR 1 */
+	{ 72,	2,	0 },   /* RDR 2 */
+	{ 81,	2,	0 },   /* RDR 3 */
+	{ 328,	6,	0 },   /* RDR 4 */
+	{ 160,	3,	0 },   /* RDR 5 */
+	{ 336,	6,	0 },   /* RDR 6 */
+	{ 164,	3,	0 },   /* RDR 7 */
+	{ 0,	0,	0 },   /* RDR 8 */
+	{ 35,	1,	0 },   /* RDR 9 */
+	{ 6,	1,	0 },   /* RDR 10 */
+	{ 18,	1,	0 },   /* RDR 11 */
+	{ 13,	1,	0 },   /* RDR 12 */
+	{ 8,	1,	0 },   /* RDR 13 */
+	{ 8,	1,	0 },   /* RDR 14 */
+	{ 8,	1,	0 },   /* RDR 15 */
+	{ 1530,	24,	0 },   /* RDR 16 */
+	{ 16,	1,	0 },   /* RDR 17 */
+	{ 4,	1,	0 },   /* RDR 18 */
+	{ 0,	0,	0 },   /* RDR 19 */
+	{ 152,	3,	24 },  /* RDR 20 */
+	{ 152,	3,	24 },  /* RDR 21 */
+	{ 233,	4,	48 },  /* RDR 22 */
+	{ 233,	4,	48 },  /* RDR 23 */
+	{ 71,	2,	0 },   /* RDR 24 */
+	{ 71,	2,	0 },   /* RDR 25 */
+	{ 11,	1,	0 },   /* RDR 26 */
+	{ 18,	1,	0 },   /* RDR 27 */
+	{ 128,	2,	0 },   /* RDR 28 */
+	{ 0,	0,	0 },   /* RDR 29 */
+	{ 16,	1,	0 },   /* RDR 30 */
+	{ 16,	1,	0 },   /* RDR 31 */
+};
+
+/* RDR register descriptions for PCX-U */
+static struct rdr_tbl_ent perf_rdr_tbl_U[] = {
+	{ 19,	1,	8 },              /* RDR 0 */
+	{ 32,	1,	16 },             /* RDR 1 */
+	{ 20,	1,	0 },              /* RDR 2 */
+	{ 0,	0,	0 },              /* RDR 3 */
+	{ 344,	6,	0 },              /* RDR 4 */
+	{ 176,	3,	0 },              /* RDR 5 */
+	{ 336,	6,	0 },              /* RDR 6 */
+	{ 0,	0,	0 },              /* RDR 7 */
+	{ 0,	0,	0 },              /* RDR 8 */
+	{ 0,	0,	0 },              /* RDR 9 */
+	{ 28,	1,	0 },              /* RDR 10 */
+	{ 33,	1,	0 },              /* RDR 11 */
+	{ 0,	0,	0 },              /* RDR 12 */
+	{ 230,	4,	0 },              /* RDR 13 */
+	{ 32,	1,	0 },              /* RDR 14 */
+	{ 128,	2,	0 },              /* RDR 15 */
+	{ 1494,	24,	0 },              /* RDR 16 */
+	{ 18,	1,	0 },              /* RDR 17 */
+	{ 4,	1,	0 },              /* RDR 18 */
+	{ 0,	0,	0 },              /* RDR 19 */
+	{ 158,	3,	24 },             /* RDR 20 */
+	{ 158,	3,	24 },             /* RDR 21 */
+	{ 194,	4,	48 },             /* RDR 22 */
+	{ 194,	4,	48 },             /* RDR 23 */
+	{ 71,	2,	0 },              /* RDR 24 */
+	{ 71,	2,	0 },              /* RDR 25 */
+	{ 28,	1,	0 },              /* RDR 26 */
+	{ 33,	1,	0 },              /* RDR 27 */
+	{ 88,	2,	0 },              /* RDR 28 */
+	{ 32,	1,	0 },              /* RDR 29 */
+	{ 24,	1,	0 },              /* RDR 30 */
+	{ 16,	1,	0 },              /* RDR 31 */
+};
+
+/*
+ * A non-zero write_control in the above tables is a byte offset into
+ * this array.
+ */
+static uint64_t perf_bitmasks[] = {
+	0x0000000000000000,     /* first dbl word must be zero */
+	0xfdffe00000000000,     /* RDR0 bitmask */
+	0x003f000000000000,     /* RDR1 bitmask */
+	0x00ffffffffffffff,     /* RDR20-RDR21 bitmask (152 bits) */
+	0xffffffffffffffff,
+	0xfffffffc00000000,
+	0xffffffffffffffff,     /* RDR22-RDR23 bitmask (233 bits) */
+	0xffffffffffffffff,
+	0xfffffffffffffffc,
+	0xff00000000000000
+};
+
+/*
+ * Write control bitmasks for Pa-8700 processor given
+ * somethings have changed slightly.
+ */
+static uint64_t perf_bitmasks_piranha[] = {
+	0x0000000000000000,     /* first dbl word must be zero */
+	0xfdffe00000000000,     /* RDR0 bitmask */
+	0x003f000000000000,     /* RDR1 bitmask */
+	0x00ffffffffffffff,     /* RDR20-RDR21 bitmask (158 bits) */
+	0xffffffffffffffff,
+	0xfffffffc00000000,
+	0xffffffffffffffff,     /* RDR22-RDR23 bitmask (210 bits) */
+	0xffffffffffffffff,
+	0xffffffffffffffff,
+	0xfffc000000000000
+};
+
+static uint64_t *bitmask_array;   /* array of bitmasks to use */
+
+/******************************************************************************
+ * Function Prototypes
+ *****************************************************************************/
+static int perf_config(uint32_t *image_ptr);
+static int perf_release(struct inode *inode, struct file *file);
+static int perf_open(struct inode *inode, struct file *file);
+static ssize_t perf_read(struct file *file, char *buf, size_t cnt, loff_t *ppos);
+static ssize_t perf_write(struct file *file, const char *buf, size_t count, 
+	loff_t *ppos);
+static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	unsigned long arg);
+static void perf_start_counters(void);
+static int perf_stop_counters(uint32_t *raddr);
+static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
+static int perf_rdr_read_ubuf(uint32_t	rdr_num, uint64_t *buffer);
+static int perf_rdr_clear(uint32_t rdr_num);
+static int perf_write_image(uint64_t *memaddr);
+static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer);
+
+/* External Assembly Routines */
+extern uint64_t perf_rdr_shift_in_W (uint32_t rdr_num, uint16_t width);
+extern uint64_t perf_rdr_shift_in_U (uint32_t rdr_num, uint16_t width);
+extern void perf_rdr_shift_out_W (uint32_t rdr_num, uint64_t buffer);
+extern void perf_rdr_shift_out_U (uint32_t rdr_num, uint64_t buffer);
+extern void perf_intrigue_enable_perf_counters (void);
+extern void perf_intrigue_disable_perf_counters (void);
+
+/******************************************************************************
+ * Function Definitions
+ *****************************************************************************/
+
+
+/*
+ * configure:
+ *
+ * Configure the cpu with a given data image.  First turn off the counters, 
+ * then download the image, then turn the counters back on.
+ */
+static int perf_config(uint32_t *image_ptr)
+{
+	long error;
+	uint32_t raddr[4];
+
+	/* Stop the counters*/
+	error = perf_stop_counters(raddr);
+	if (error != 0) {
+		printk("perf_config: perf_stop_counters = %ld\n", error);
+		return -EINVAL; 
+	}
+
+printk("Preparing to write image\n");
+	/* Write the image to the chip */
+	error = perf_write_image((uint64_t *)image_ptr);
+	if (error != 0) {
+		printk("perf_config: DOWNLOAD = %ld\n", error);
+		return -EINVAL; 
+	}
+
+printk("Preparing to start counters\n");
+
+	/* Start the counters */
+	perf_start_counters();
+
+	return sizeof(uint32_t);
+}
+
+/*
+ * Open the device and initialize all of it's memory.  The device is only 
+ * opened once, but can be "queried" by multiple processes that know its
+ * file descriptor.
+ */
+static int perf_open(struct inode *inode, struct file *file)
+{
+	spin_lock(&perf_lock);
+	if (perf_enabled) {
+		spin_unlock(&perf_lock);
+		return -EBUSY;
+	}
+	perf_enabled = 1;
+ 	spin_unlock(&perf_lock);
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+/*
+ * Close the device.
+ */
+static int perf_release(struct inode *inode, struct file *file)
+{
+	spin_lock(&perf_lock);
+	perf_enabled = 0;
+	spin_unlock(&perf_lock);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+/*
+ * Read does nothing for this driver
+ */
+static ssize_t perf_read(struct file *file, char *buf, size_t cnt, loff_t *ppos)
+{
+	return 0;
+}
+
+/*
+ * write:
+ *
+ * This routine downloads the image to the chip.  It must be
+ * called on the processor that the download should happen
+ * on.
+ */
+static ssize_t perf_write(struct file *file, const char *buf, size_t count, 
+	loff_t *ppos)
+{
+	int err;
+	size_t image_size;
+	uint32_t image_type;
+	uint32_t interface_type;
+	uint32_t test;
+
+	if (perf_processor_interface == ONYX_INTF) 
+		image_size = PCXU_IMAGE_SIZE;
+	else if (perf_processor_interface == CUDA_INTF) 
+		image_size = PCXW_IMAGE_SIZE;
+	else 
+		return -EFAULT;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (count != sizeof(uint32_t))
+		return -EIO;
+
+	if ((err = copy_from_user(&image_type, buf, sizeof(uint32_t))) != 0) 
+		return err;
+
+	/* Get the interface type and test type */
+   	interface_type = (image_type >> 16) & 0xffff;
+	test           = (image_type & 0xffff);
+
+	/* Make sure everything makes sense */
+
+	/* First check the machine type is correct for
+	   the requested image */
+        if (((perf_processor_interface == CUDA_INTF) &&
+		       (interface_type != CUDA_INTF)) ||
+	    ((perf_processor_interface == ONYX_INTF) &&
+	               (interface_type != ONYX_INTF))) 
+		return -EINVAL;
+
+	/* Next check to make sure the requested image
+	   is valid */
+	if (((interface_type == CUDA_INTF) && 
+		       (test >= MAX_CUDA_IMAGES)) ||
+	    ((interface_type == ONYX_INTF) && 
+		       (test >= MAX_ONYX_IMAGES))) 
+		return -EINVAL;
+
+	/* Copy the image into the processor */
+	if (interface_type == CUDA_INTF) 
+		return perf_config(cuda_images[test]);
+	else
+		return perf_config(onyx_images[test]);
+
+	return count;
+}
+
+/*
+ * Patch the images that need to know the IVA addresses.
+ */
+static void perf_patch_images(void)
+{
+#if 0 /* FIXME!! */
+/* 
+ * NOTE:  this routine is VERY specific to the current TLB image.
+ * If the image is changed, this routine might also need to be changed.
+ */
+	extern void $i_itlb_miss_2_0();
+	extern void $i_dtlb_miss_2_0();
+	extern void PA2_0_iva();
+
+	/* 
+	 * We can only use the lower 32-bits, the upper 32-bits should be 0
+	 * anyway given this is in the kernel 
+	 */
+	uint32_t itlb_addr  = (uint32_t)&($i_itlb_miss_2_0);
+	uint32_t dtlb_addr  = (uint32_t)&($i_dtlb_miss_2_0);
+	uint32_t IVAaddress = (uint32_t)&PA2_0_iva;
+
+	if (perf_processor_interface == ONYX_INTF) {
+		/* clear last 2 bytes */
+		onyx_images[TLBMISS][15] &= 0xffffff00;  
+		/* set 2 bytes */
+		onyx_images[TLBMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[TLBMISS][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[TLBMISS][17] = itlb_addr;
+
+		/* clear last 2 bytes */
+		onyx_images[TLBHANDMISS][15] &= 0xffffff00;  
+		/* set 2 bytes */
+		onyx_images[TLBHANDMISS][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[TLBHANDMISS][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[TLBHANDMISS][17] = itlb_addr;
+
+		/* clear last 2 bytes */
+		onyx_images[BIG_CPI][15] &= 0xffffff00;  
+		/* set 2 bytes */
+		onyx_images[BIG_CPI][15] |= (0x000000ff&((dtlb_addr) >> 24));
+		onyx_images[BIG_CPI][16] = (dtlb_addr << 8)&0xffffff00;
+		onyx_images[BIG_CPI][17] = itlb_addr;
+
+	    onyx_images[PANIC][15] &= 0xffffff00;  /* clear last 2 bytes */
+	 	onyx_images[PANIC][15] |= (0x000000ff&((IVAaddress) >> 24)); /* set 2 bytes */
+		onyx_images[PANIC][16] = (IVAaddress << 8)&0xffffff00;
+
+
+	} else if (perf_processor_interface == CUDA_INTF) {
+		/* Cuda interface */
+		cuda_images[TLBMISS][16] =  
+			(cuda_images[TLBMISS][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[TLBMISS][17] = 
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[TLBMISS][18] = (itlb_addr << 16)&0xffff0000;
+
+		cuda_images[TLBHANDMISS][16] = 
+			(cuda_images[TLBHANDMISS][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[TLBHANDMISS][17] = 
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[TLBHANDMISS][18] = (itlb_addr << 16)&0xffff0000;
+
+		cuda_images[BIG_CPI][16] = 
+			(cuda_images[BIG_CPI][16]&0xffff0000) |
+			((dtlb_addr >> 8)&0x0000ffff);
+		cuda_images[BIG_CPI][17] = 
+			((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff);
+		cuda_images[BIG_CPI][18] = (itlb_addr << 16)&0xffff0000;
+	} else {
+		/* Unknown type */
+	}
+#endif
+}
+
+
+/*
+ * ioctl routine
+ * All routines effect the processor that they are executed on.  Thus you 
+ * must be running on the processor that you wish to change.
+ */
+
+static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	long error_start;
+	uint32_t raddr[4];	
+
+	switch (cmd) {
+
+	    case PA_PERF_ON:
+			/* Start the counters */
+			perf_start_counters();
+			return 0;
+
+	    case PA_PERF_OFF:
+			error_start = perf_stop_counters(raddr);
+			if (error_start != 0) {
+				printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
+				return -EFAULT;	
+			}
+
+			/* copy out the Counters */
+			if (copy_to_user((void *)arg, raddr, 
+					sizeof (raddr)) != 0) {
+				return -EFAULT;
+			}
+			return 0;
+
+	    case PA_PERF_VERSION:
+  	  		/* Return the version # */
+			return put_user(PERF_VERSION, (int *)arg);
+
+	    default:
+  	 		break;
+	}
+	return -ENOTTY;
+}
+
+static struct file_operations perf_fops = {
+	llseek: no_llseek,
+	read: perf_read,
+	write: perf_write,
+	ioctl: perf_ioctl,
+	open: perf_open,
+	release: perf_release
+};
+	
+static struct miscdevice perf_dev = {
+	MISC_DYNAMIC_MINOR,
+	PA_PERF_DEV,
+	&perf_fops
+};
+
+/*
+ * Initialize the module
+ */
+static int __init perf_init(void)
+{
+	/* Determine correct processor interface to use */
+	bitmask_array = perf_bitmasks;
+
+	if (boot_cpu_data.cpu_type == pcxu ||
+	    boot_cpu_data.cpu_type == pcxu_) {
+		perf_processor_interface = ONYX_INTF;
+	} else if (boot_cpu_data.cpu_type == pcxw ||
+		 boot_cpu_data.cpu_type == pcxw_ ||
+		 boot_cpu_data.cpu_type == pcxw2) {
+		perf_processor_interface = CUDA_INTF;
+		if (boot_cpu_data.cpu_type == pcxw2) 
+			bitmask_array = perf_bitmasks_piranha;
+	} else {
+		perf_processor_interface = UNKNOWN_INTF;
+		printk("Performance monitoring counters not supported on this processor\n");
+		return -ENODEV;
+	}
+
+	/* Patch the images to match the system */
+    	perf_patch_images();
+
+	spin_lock_init(&perf_lock);
+	misc_register(&perf_dev);
+
+	/* TODO: this only lets us access the first cpu.. what to do for SMP? */
+	cpu_device = cpu_data[0].dev;
+	printk("Performance monitoring counters enabled for %s\n",
+		cpu_data[0].dev->name);
+
+	return 0;
+}
+
+/*
+ * perf_start_counters(void)
+ *
+ * Start the counters.
+ */
+static void perf_start_counters(void)
+{
+	/* Enable performance monitor counters */
+	perf_intrigue_enable_perf_counters();
+}
+
+/*
+ * perf_stop_counters
+ *
+ * Stop the performance counters and save counts
+ * in a per_processor array.
+ */
+static int perf_stop_counters(uint32_t *raddr)
+{
+	uint64_t userbuf[MAX_RDR_WORDS];
+
+	/* Disable performance counters */
+	perf_intrigue_disable_perf_counters();
+
+	if (perf_processor_interface == ONYX_INTF) {
+		uint64_t tmp64;
+		/*
+		 * Read the counters
+		 */
+		if (!perf_rdr_read_ubuf(16, userbuf))
+			return -13;
+
+		/* Counter0 is bits 1398 thru 1429 */
+		tmp64 =  (userbuf[21] << 22) & 0x00000000ffc00000;
+		tmp64 |= (userbuf[22] >> 42) & 0x00000000003fffff;
+		/* OR sticky0 (bit 1430) to counter0 bit 32 */
+		tmp64 |= (userbuf[22] >> 10) & 0x0000000080000000;
+		raddr[0] = (uint32_t)tmp64;
+
+		/* Counter1 is bits 1431 thru 1462 */
+		tmp64 =  (userbuf[22] >> 9) & 0x00000000ffffffff;
+		/* OR sticky1 (bit 1463) to counter1 bit 32 */
+		tmp64 |= (userbuf[22] << 23) & 0x0000000080000000;
+		raddr[1] = (uint32_t)tmp64;
+
+		/* Counter2 is bits 1464 thru 1495 */
+		tmp64 =  (userbuf[22] << 24) & 0x00000000ff000000;
+		tmp64 |= (userbuf[23] >> 40) & 0x0000000000ffffff;
+		/* OR sticky2 (bit 1496) to counter2 bit 32 */
+		tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000;
+		raddr[2] = (uint32_t)tmp64;
+		
+		/* Counter3 is bits 1497 thru 1528 */
+		tmp64 =  (userbuf[23] >> 7) & 0x00000000ffffffff;
+		/* OR sticky3 (bit 1529) to counter3 bit 32 */
+		tmp64 |= (userbuf[23] << 25) & 0x0000000080000000;
+		raddr[3] = (uint32_t)tmp64;
+
+		/*
+		 * Zero out the counters
+		 */
+
+		/*
+		 * The counters and sticky-bits comprise the last 132 bits
+		 * (1398 - 1529) of RDR16 on a U chip.  We'll zero these
+		 * out the easy way: zero out last 10 bits of dword 21,
+		 * all of dword 22 and 58 bits (plus 6 don't care bits) of
+		 * dword 23.
+		 */
+		userbuf[21] &= 0xfffffffffffffc00;	/* 0 to last 10 bits */
+		userbuf[22] = 0;
+		userbuf[23] = 0;
+
+		/* 
+		 * Write back the zero'ed bytes + the image given
+		 * the read was destructive.
+		 */
+		perf_rdr_write(16, userbuf);
+	} else {
+
+		/*
+		 * Read RDR-15 which contains the counters and sticky bits 
+		 */
+		if (!perf_rdr_read_ubuf(15, userbuf)) {
+			return -13;
+		}
+
+		/* 
+		 * Clear out the counters
+		 */
+		perf_rdr_clear(15);
+
+		/*
+		 * Copy the counters 
+		 */
+		raddr[0] = (uint32_t)((userbuf[0] >> 32) & 0x00000000ffffffffUL);
+		raddr[1] = (uint32_t)(userbuf[0] & 0x00000000ffffffffUL);
+		raddr[2] = (uint32_t)((userbuf[1] >> 32) & 0x00000000ffffffffUL);
+		raddr[3] = (uint32_t)(userbuf[1] & 0x00000000ffffffffUL);
+	}
+ 
+	return 0;
+}
+
+/*
+ * perf_rdr_get_entry
+ *
+ * Retrieve a pointer to the description of what this
+ * RDR contains.
+ */
+static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
+{
+	if (perf_processor_interface == ONYX_INTF) {
+		return &perf_rdr_tbl_U[rdr_num];
+	} else {
+		return &perf_rdr_tbl_W[rdr_num];
+	}
+}
+
+/*
+ * perf_rdr_read_ubuf
+ *
+ * Read the RDR value into the buffer specified.
+ */
+static int perf_rdr_read_ubuf(uint32_t	rdr_num, uint64_t *buffer)
+{
+	uint64_t	data, data_mask = 0;
+	uint32_t	width, xbits, i;
+	struct rdr_tbl_ent *tentry;
+
+	tentry = perf_rdr_get_entry(rdr_num);
+	if ((width = tentry->width) == 0)
+		return 0;
+
+	/* Clear out buffer */
+	i = tentry->num_words;
+	while (i--) {
+		buffer[i] = 0;
+	}	
+
+	/* Check for bits an even number of 64 */
+	if ((xbits = width & 0x03f) != 0) {
+		data_mask = 1;
+		data_mask <<= (64 - xbits);
+		data_mask--;
+	}
+
+	/* Grab all of the data */
+	i = tentry->num_words;
+	while (i--) {
+
+		if (perf_processor_interface == ONYX_INTF) {
+			data = perf_rdr_shift_in_U(rdr_num, width);
+		} else {
+			data = perf_rdr_shift_in_W(rdr_num, width);
+		}
+		if (xbits) {
+			buffer[i] |= (data << (64 - xbits));
+			if (i) {
+				buffer[i-1] |= ((data >> xbits) & data_mask);
+			}
+		} else {
+			buffer[i] = data;
+		}
+	}
+
+	return 1;
+}
+
+/*
+ * perf_rdr_clear
+ *
+ * Zero out the given RDR register
+ */
+static int perf_rdr_clear(uint32_t	rdr_num)
+{
+	struct rdr_tbl_ent *tentry;
+	int32_t		i;
+
+	tentry = perf_rdr_get_entry(rdr_num);
+
+	if (tentry->width == 0) {
+		return -1;
+	}
+
+	i = tentry->num_words;
+	while (i--) {
+		if (perf_processor_interface == ONYX_INTF) {
+			perf_rdr_shift_out_U(rdr_num, 0UL);
+		} else {
+			perf_rdr_shift_out_W(rdr_num, 0UL);
+		}
+	}
+
+	return 0;
+}
+
+
+/*
+ * perf_write_image
+ *
+ * Write the given image out to the processor
+ */
+static int perf_write_image(uint64_t *memaddr)
+{
+	uint64_t buffer[MAX_RDR_WORDS];
+	uint64_t *bptr;
+	uint32_t dwords;
+	uint32_t *intrigue_rdr;
+	uint64_t *intrigue_bitmask, tmp64, proc_hpa, *ptr64;
+	struct rdr_tbl_ent *tentry;
+	int i;
+
+	/* Clear out counters */
+	if (perf_processor_interface == ONYX_INTF) {
+
+		perf_rdr_clear(16);
+
+		/* Toggle performance monitor */
+		perf_intrigue_enable_perf_counters();
+		perf_intrigue_disable_perf_counters();
+
+		intrigue_rdr = perf_rdrs_U;
+	} else {
+		perf_rdr_clear(15);
+		intrigue_rdr = perf_rdrs_W;
+	}
+
+	/* Write all RDRs */
+	while (*intrigue_rdr != -1) {
+		tentry = perf_rdr_get_entry(*intrigue_rdr);
+		perf_rdr_read_ubuf(*intrigue_rdr, buffer);
+		bptr   = &buffer[0];
+		dwords = tentry->num_words;
+		if (tentry->write_control) {
+			intrigue_bitmask = &bitmask_array[tentry->write_control >> 3];
+			while (dwords--) {
+				tmp64 = *intrigue_bitmask & *memaddr++;
+				tmp64 |= (~(*intrigue_bitmask++)) & *bptr;
+				*bptr++ = tmp64;
+			}
+		} else {
+			while (dwords--) {
+				*bptr++ = *memaddr++;
+			}
+		}
+
+		perf_rdr_write(*intrigue_rdr, buffer);
+		intrigue_rdr++;
+	}
+
+	/*
+	 * Now copy out the Runway stuff which is not in RDRs
+	 */
+
+	if (cpu_device == NULL)
+	{
+		printk(KERN_ERR "write_image: cpu_device not yet initialized!\n");
+		return -1;
+	}
+
+	proc_hpa = cpu_device->hpa;
+
+	/* Merge intrigue bits into Runway STATUS 0 */
+	ptr64 = (uint64_t *)(proc_hpa + 0x10); /* Runway STATUS 0 */
+	tmp64 = __raw_readq((u64 *)ptr64) & 0xffecffffffffffff;
+	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000), (u64 *)ptr64);
+	
+	/* Write RUNWAY DEBUG registers */
+	ptr64 = (uint64_t *)(proc_hpa + 0x40); /* Runway DEBUG 0 */
+	for (i = 0; i < 8; i++) {
+		__raw_writeq(*memaddr++, (u64 *)ptr64);
+		ptr64++;
+	}
+
+	return 0; 
+}
+
+/*
+ * perf_rdr_write
+ *
+ * Write the given RDR register with the contents
+ * of the given buffer.
+ */
+static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer)
+{
+	struct rdr_tbl_ent *tentry;
+	int32_t		i;
+
+printk("perf_rdr_write\n");
+	tentry = perf_rdr_get_entry(rdr_num);
+	if (tentry->width == 0) { return; }
+
+	i = tentry->num_words;
+	while (i--) {
+		if (perf_processor_interface == ONYX_INTF) {
+			perf_rdr_shift_out_U(rdr_num, buffer[i]);
+		} else {
+			perf_rdr_shift_out_W(rdr_num, buffer[i]);
+		}	
+	}
+printk("perf_rdr_write done\n");
+}
+
+module_init(perf_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/perf_asm.S linux-2.4.20/arch/parisc/kernel/perf_asm.S
--- linux-2.4.19/arch/parisc/kernel/perf_asm.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/perf_asm.S	2002-10-04 00:41:14.000000000 +0000
@@ -0,0 +1,1679 @@
+; 
+;   Purpose:
+;	This file has the overall purpose of suppyling low-level
+;   assembly to program the intrigue portion of the cpu.
+; 
+
+#include <linux/config.h>
+#include <asm/assembly.h>
+
+#ifdef __LP64__
+	.level		2.0w
+#endif /* __LP64__ */
+
+#define MTDIAG_1(gr)    .word 0x14201840 + gr*0x10000
+#define MTDIAG_2(gr)    .word 0x14401840 + gr*0x10000
+#define MFDIAG_1(gr)    .word 0x142008A0 + gr
+#define MFDIAG_2(gr)    .word 0x144008A0 + gr
+#define STDIAG(dr)      .word 0x14000AA0 + dr*0x200000
+#define SFDIAG(dr)      .word 0x14000BA0 + dr*0x200000
+#define DR2_SLOW_RET    53
+
+
+;
+; Enable the performance counters
+;
+; The coprocessor only needs to be enabled when
+; starting/stopping the coprocessor with the pmenb/pmdis.
+;
+	.text
+	.align 32
+
+	.export perf_intrigue_enable_perf_counters,code
+perf_intrigue_enable_perf_counters:
+	.proc
+	.callinfo  frame=0,NO_CALLS
+	.entry
+	
+	ldi     0x20,%r25                ; load up perfmon bit
+	mfctl   ccr,%r26                 ; get coprocessor register
+	or      %r25,%r26,%r26             ; set bit
+	mtctl   %r26,ccr                 ; turn on performance coprocessor
+	pmenb                           ; enable performance monitor
+	ssm     0,0                     ; dummy op to ensure completion
+	sync                            ; follow ERS
+	andcm   %r26,%r25,%r26             ; clear bit now 
+	mtctl   %r26,ccr                 ; turn off performance coprocessor
+	nop                             ; NOPs as specified in ERS
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	bve    (%r2)
+	nop
+	.exit
+	.procend
+
+	.export perf_intrigue_disable_perf_counters,code
+perf_intrigue_disable_perf_counters:
+	.proc
+	.callinfo  frame=0,NO_CALLS
+	.entry
+	ldi     0x20,%r25                ; load up perfmon bit
+	mfctl   ccr,%r26                 ; get coprocessor register
+	or      %r25,%r26,%r26             ; set bit
+	mtctl   %r26,ccr                 ; turn on performance coprocessor
+	pmdis                           ; disable performance monitor
+	ssm     0,0                     ; dummy op to ensure completion
+	andcm   %r26,%r25,%r26             ; clear bit now 
+	bve    (%r2)
+	mtctl   %r26,ccr                 ; turn off performance coprocessor
+	.exit
+	.procend
+
+;************************************************************************
+;*																		*
+;* Name: perf_rdr_shift_in_W												*
+;*																		*
+;* Description:															*
+;*	This routine shifts data in from the RDR in arg0 and returns		*
+;*	the result in ret0.  If the RDR is <= 64 bits in length, it			*
+;*	is shifted shifted backup immediately.  This is to compensate		*
+;*	for RDR10 which has bits that preclude PDC stack operations			*
+;*	when they are in the wrong state.									*
+;*																		*
+;* Arguments:															*
+;*	arg0 : rdr to be read												*
+;*	arg1 : bit length of rdr											*
+;*																		*
+;* Returns:																*
+;*	ret0 = next 64 bits of rdr data from staging register				*
+;*																		*
+;* Register usage:														*
+;*	arg0 : rdr to be read												*
+;*	arg1 : bit length of rdr											*
+;*	%r24  - original DR2 value											*
+;*	%r1   - scratch														*
+;*  %r29  - scratch														*
+;*																		*
+;* Returns:																*
+;*	ret0 = RDR data (right justified)									*
+;*																		*
+;************************************************************************
+
+	.export perf_rdr_shift_in_W,code
+perf_rdr_shift_in_W:
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+;
+; read(shift in) the RDR.
+;
+
+; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r29
+	MFDIAG_2	(24)
+	or		    %r24,%r29,%r29
+	MTDIAG_2	(29)			; set DR2_SLOW_RET
+
+	nop
+	nop
+	nop
+	nop	
+
+;
+; Cacheline start (32-byte cacheline)
+;
+	nop
+	nop
+	nop
+	extrd,u		arg1,63,6,%r1    ; setup shift amount based on bits to move 
+
+	mtsar		%r1
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr  		%r1,%r0		    ; branch to 8-instruction sequence
+	nop
+
+;
+; Cacheline start (32-byte cacheline)
+;
+
+	;
+	; RDR 0 sequence
+	;
+	SFDIAG		(0)		
+	ssm		    0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)					; mtdiag %dr1, %r1 
+	STDIAG		(0)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 1 sequence
+	;
+	sync			
+	ssm		    0,0
+	SFDIAG		(1)
+	ssm		    0,0
+	MFDIAG_1	(28)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	
+	;
+	; RDR 2 read sequence
+	;
+	SFDIAG		(2)		
+	ssm		    0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(2)
+	ssm		    0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 3 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 4 read sequence
+	;
+	sync				
+	ssm			0,0
+	SFDIAG		(4)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	; 
+	; RDR 5 read sequence
+	;
+	sync	
+	ssm			0,0
+	SFDIAG		(5)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 6 read sequence
+	;
+	sync	
+	ssm			0,0
+	SFDIAG		(6)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 7 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 8 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 9 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 10 read sequence
+	;
+	SFDIAG		(10)
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(10)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 11 read sequence
+	;
+	SFDIAG		(11)
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(11)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 12 read sequence
+	;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 13 read sequence
+	;
+	sync
+	ssm			0,0
+	SFDIAG		(13)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 14 read sequence
+	;
+	SFDIAG		(14)	
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(14)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 15 read sequence
+	;
+	sync				; RDR 15 read sequence
+	ssm			0,0
+	SFDIAG		(15)
+	ssm			0,0
+	MFDIAG_1	(28)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	
+	;
+	; RDR 16 read sequence
+	;
+	sync				; RDR 16 read sequence
+	ssm			0,0
+	SFDIAG		(16)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 17 read sequence
+	;
+	SFDIAG		(17)	
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(17)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 18 read sequence
+	;
+	SFDIAG		(18)	
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(18)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+;
+; RDR 19 read sequence
+;
+	b,n         perf_rdr_shift_in_W_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	;
+	; RDR 20 read sequence
+	;
+	sync
+	ssm			0,0
+	SFDIAG		(20)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 21 read sequence
+	;
+	sync
+	ssm			0,0
+	SFDIAG		(21)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 22 read sequence
+	;
+	sync
+	ssm			0,0
+	SFDIAG		(22)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 23 read sequence
+	;
+	sync		
+	ssm			0,0
+	SFDIAG		(23)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 24 read sequence
+	;
+	sync	
+	ssm			0,0
+	SFDIAG		(24)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 25 read sequence
+	;
+	sync
+	ssm			0,0
+	SFDIAG		(25)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 26 read sequence
+	;
+	SFDIAG		(26)		
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(26)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 27 read sequence
+	;
+	SFDIAG		(27)
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(27)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 28 read sequence
+	;
+	sync				
+	ssm			0,0
+	SFDIAG		(28)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 29 read sequence
+	;
+	sync		
+	ssm			0,0
+	SFDIAG		(29)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_W_leave
+	ssm			0,0
+	nop
+	
+	;
+	; RDR 30 read sequence
+	;
+	SFDIAG		(30)
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(30)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_W_leave
+	
+	;
+	; RDR 31 read sequence
+	;
+	sync		
+	ssm			0,0
+	SFDIAG		(31)
+	ssm			0,0
+	MFDIAG_1	(28)
+	nop
+	ssm			0,0
+	nop
+
+	;
+	; Fallthrough
+	;
+
+perf_rdr_shift_in_W_leave:
+	bve		    (%r2)
+	.exit
+	MTDIAG_2	(24)			; restore DR2
+	.procend
+
+
+;************************************************************************
+;*																		*
+;* Name: perf_rdr_shift_out_W												*
+;*																		*
+;* Description:															*
+;*	This routine moves data to the RDR's.  The double-word that			*
+;*	arg1 points to is loaded and moved into the staging register.		*
+;*	Then the STDIAG instruction for the RDR # in arg0 is called			*
+;*	to move the data to the RDR.										*
+;*																		*
+;* Arguments:															*
+;*	arg0 = rdr number													*
+;*	arg1 = 64-bit value to write										*
+;*	%r24 - DR2 | DR2_SLOW_RET											*
+;*	%r23 - original DR2 value											*
+;*																		*
+;* Returns:																*
+;*	None																*
+;*																		*
+;* Register usage:														*
+;*																		*
+;************************************************************************
+
+	.export perf_rdr_shift_out_W,code
+perf_rdr_shift_out_W:
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+;
+; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, the remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r24
+	MFDIAG_2	(23)
+	or		     %r24,%r23,%r24
+	MTDIAG_2	(24)			; set DR2_SLOW_RET
+
+	MTDIAG_1	(25)			; data to the staging register
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr		    %r1,%r0		    ; branch to 8-instruction sequence
+	nop
+
+	;
+	; RDR 0 write sequence
+	;
+	sync				; RDR 0 write sequence
+	ssm			0,0
+	STDIAG		(0)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm			0,0
+	nop
+
+	;
+	; RDR 1 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(1)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 2 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(2)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 3 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(3)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 4 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(4)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 5 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(5)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 6 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(6)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 7 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(7)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 8 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(8)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 9 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(9)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 10 write sequence
+	;
+	sync	
+	ssm		0,0
+	STDIAG		(10)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 11 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(11)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 12 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(12)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 13 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(13)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 14 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(14)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 15 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(15)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 16 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(16)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 17 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(17)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 18 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(18)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 19 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(19)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 20 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(20)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 21 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(21)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 22 write sequence
+	;
+	sync	
+	ssm		0,0
+	STDIAG		(22)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 23 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(23)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 24 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(24)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 25 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(25)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 26 write sequence
+	;
+	sync	
+	ssm		0,0
+	STDIAG		(10)
+	STDIAG		(26)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 27 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(11)
+	STDIAG		(27)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	ssm		0,0
+	nop
+
+	;
+	; RDR 28 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(28)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 29 write sequence
+	;
+	sync
+	ssm		0,0
+	STDIAG		(29)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 30 write sequence
+	;
+	sync	
+	ssm		0,0
+	STDIAG		(30)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+	;
+	; RDR 31 write sequence
+	;
+	sync				
+	ssm		0,0
+	STDIAG		(31)
+	ssm		0,0
+	b,n         perf_rdr_shift_out_W_leave
+	nop
+	ssm		0,0
+	nop
+
+perf_rdr_shift_out_W_leave:
+	bve		(%r2)
+	.exit
+	MTDIAG_2	(23)			; restore DR2
+	.procend
+
+
+;**************************** CHRIS ***********************************
+
+;************************************************************************
+;*																		*
+;* Name: rdr_shift_in_U													*
+;*																		*
+;* Description:															*
+;*	This routine shifts data in from the RDR in arg0 and returns		*
+;*	the result in ret0.  If the RDR is <= 64 bits in length, it			*
+;*	is shifted shifted backup immediately.  This is to compensate		*
+;*	for RDR10 which has bits that preclude PDC stack operations			*
+;*	when they are in the wrong state.									*
+;*																		*
+;* Arguments:															*
+;*	arg0 : rdr to be read												*
+;*	arg1 : bit length of rdr											*
+;*																		*
+;* Returns:																*
+;*	ret0 = next 64 bits of rdr data from staging register				*
+;*																		*
+;* Register usage:														*
+;*	arg0 : rdr to be read						                        *
+;*	arg1 : bit length of rdr					                        *
+;*	%r24 - original DR2 value											*
+;*	%r23 - DR2 | DR2_SLOW_RET											*
+;*	%r1  - scratch														*
+;*																		*
+;************************************************************************
+
+	.export perf_rdr_shift_in_U,code
+perf_rdr_shift_in_U:
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+
+; read(shift in) the RDR.
+;
+; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, remote diagnose registers.
+
+	depdi,z		1,DR2_SLOW_RET,1,%r29
+	MFDIAG_2	(24)
+	or			%r24,%r29,%r29
+	MTDIAG_2	(29)			; set DR2_SLOW_RET
+
+	nop
+	nop
+	nop
+	nop
+
+;
+; Start of next 32-byte cacheline
+;
+	nop
+	nop
+	nop
+	extrd,u		arg1,63,6,%r1
+
+	mtsar		%r1
+	shladd		arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr 		%r1,%r0		; branch to 8-instruction sequence
+	nop
+
+;
+; Start of next 32-byte cacheline
+;
+	SFDIAG		(0)		; RDR 0 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(0)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(1)		; RDR 1 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(1)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	sync				; RDR 2 read sequence
+	ssm			0,0
+	SFDIAG		(4)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 3 read sequence
+	ssm			0,0
+	SFDIAG		(3)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+
+	sync				; RDR 4 read sequence
+	ssm			0,0
+	SFDIAG		(4)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 5 read sequence
+	ssm			0,0
+	SFDIAG		(5)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 6 read sequence
+	ssm			0,0
+	SFDIAG		(6)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 7 read sequence
+	ssm			0,0
+	SFDIAG		(7)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	SFDIAG		(9)		; RDR 9 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(9)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(10)		; RDR 10 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(10)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(11)		; RDR 11 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(11)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(12)		; RDR 12 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(12)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+
+	SFDIAG		(13)		; RDR 13 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(13)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(14)		; RDR 14 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(14)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(15)		; RDR 15 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(15)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	sync				; RDR 16 read sequence
+	ssm			0,0
+	SFDIAG		(16)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	SFDIAG		(17)		; RDR 17 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(17)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(18)		; RDR 18 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(18)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	sync				; RDR 20 read sequence
+	ssm			0,0
+	SFDIAG		(20)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 21 read sequence
+	ssm			0,0
+	SFDIAG		(21)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 22 read sequence
+	ssm			0,0
+	SFDIAG		(22)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 23 read sequence
+	ssm			0,0
+	SFDIAG		(23)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 24 read sequence
+	ssm			0,0
+	SFDIAG		(24)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	sync				; RDR 25 read sequence
+	ssm			0,0
+	SFDIAG		(25)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	SFDIAG		(26)		; RDR 26 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(26)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(27)		; RDR 27 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(27)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	sync				; RDR 28 read sequence
+	ssm			0,0
+	SFDIAG		(28)
+	ssm			0,0
+	MFDIAG_1	(28)
+	b,n         perf_rdr_shift_in_U_leave
+	ssm			0,0
+	nop
+	
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	
+	SFDIAG		(30)		; RDR 30 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(30)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	
+	SFDIAG		(31)		; RDR 31 read sequence
+	ssm			0,0
+	MFDIAG_1	(28)
+	shrpd		ret0,%r0,%sar,%r1
+	MTDIAG_1	(1)
+	STDIAG		(31)
+	ssm			0,0
+	b,n         perf_rdr_shift_in_U_leave
+	nop
+
+perf_rdr_shift_in_U_leave:
+	bve		    (%r2)
+	.exit
+	MTDIAG_2	(24)			; restore DR2
+	.procend
+
+;************************************************************************
+;*																		*
+;* Name: rdr_shift_out_U												*
+;*																		*
+;* Description:															*
+;*	This routine moves data to the RDR's.  The double-word that			*
+;*	arg1 points to is loaded and moved into the staging register.		*
+;*	Then the STDIAG instruction for the RDR # in arg0 is called			*
+;*	to move the data to the RDR.										*
+;*																		*
+;* Arguments:															*
+;*	arg0 = rdr target													*
+;*	arg1 = buffer pointer												*
+;*																		*
+;* Returns:																*
+;*	None																*
+;*																		*
+;* Register usage:														*
+;*	arg0 = rdr target													*
+;*	arg1 = buffer pointer												*
+;*	%r24 - DR2 | DR2_SLOW_RET											*
+;*	%r23 - original DR2 value											*
+;*																		*
+;************************************************************************
+
+	.export perf_rdr_shift_out_U,code
+perf_rdr_shift_out_U:
+	.proc
+	.callinfo frame=0,NO_CALLS
+	.entry
+
+;
+; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
+; shifting is done, from or to, the remote diagnose registers.
+;
+
+	depdi,z		1,DR2_SLOW_RET,1,%r24
+	MFDIAG_2	(23)
+	or		%r24,%r23,%r24
+	MTDIAG_2	(24)			; set DR2_SLOW_RET
+
+	MTDIAG_1	(25)			; data to the staging register
+	shladd		 arg0,2,%r0,%r1	; %r1 = 4 * RDR number
+	blr		    %r1,%r0		    ; branch to 8-instruction sequence
+	nop
+
+;
+; 32-byte cachline aligned
+;
+
+	sync				; RDR 0 write sequence
+	ssm			0,0
+	STDIAG		(0)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 1 write sequence
+	ssm			0,0
+	STDIAG		(1)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 2 write sequence
+	ssm			0,0
+	STDIAG		(2)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 3 write sequence
+	ssm			0,0
+	STDIAG		(3)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 4 write sequence
+	ssm			0,0
+	STDIAG		(4)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 5 write sequence
+	ssm			0,0
+	STDIAG		(5)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 6 write sequence
+	ssm			0,0
+	STDIAG		(6)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 7 write sequence
+	ssm			0,0
+	STDIAG		(7)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 8 write sequence
+	ssm			0,0
+	STDIAG		(8)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 9 write sequence
+	ssm			0,0
+	STDIAG		(9)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 10 write sequence
+	ssm			0,0
+	STDIAG		(10)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 11 write sequence
+	ssm			0,0
+	STDIAG		(11)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 12 write sequence
+	ssm			0,0
+	STDIAG		(12)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 13 write sequence
+	ssm			0,0
+	STDIAG		(13)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 14 write sequence
+	ssm			0,0
+	STDIAG		(14)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 15 write sequence
+	ssm			0,0
+	STDIAG		(15)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 16 write sequence
+	ssm			0,0
+	STDIAG		(16)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 17 write sequence
+	ssm			0,0
+	STDIAG		(17)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 18 write sequence
+	ssm			0,0
+	STDIAG		(18)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 19 write sequence
+	ssm			0,0
+	STDIAG		(19)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 20 write sequence
+	ssm			0,0
+	STDIAG		(20)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 21 write sequence
+	ssm			0,0
+	STDIAG		(21)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 22 write sequence
+	ssm			0,0
+	STDIAG		(22)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 23 write sequence
+	ssm			0,0
+	STDIAG		(23)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 24 write sequence
+	ssm			0,0
+	STDIAG		(24)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 25 write sequence
+	ssm			0,0
+	STDIAG		(25)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 26 write sequence
+	ssm			0,0
+	STDIAG		(26)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 27 write sequence
+	ssm			0,0
+	STDIAG		(27)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 28 write sequence
+	ssm			0,0
+	STDIAG		(28)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 29 write sequence
+	ssm			0,0
+	STDIAG		(29)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 30 write sequence
+	ssm			0,0
+	STDIAG		(30)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+	sync				; RDR 31 write sequence
+	ssm			0,0
+	STDIAG		(31)
+	ssm			0,0
+	b,n         perf_rdr_shift_out_U_leave
+	nop
+	ssm			0,0
+	nop
+
+perf_rdr_shift_out_U_leave:
+	bve		(%r2)
+	.exit
+	MTDIAG_2	(23)			; restore DR2
+	.procend
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/perf_images.h linux-2.4.20/arch/parisc/kernel/perf_images.h
--- linux-2.4.19/arch/parisc/kernel/perf_images.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/perf_images.h	2002-10-04 00:41:09.000000000 +0000
@@ -0,0 +1,3122 @@
+#ifndef PERF_IMAGES_H
+#define PERF_IMAGES_H
+
+/* Magic numbers taken without modification from HPUX stuff */
+
+/*
+ * Imagine for use with the Onyx cpu interface
+ */
+
+#define PCXU_IMAGE_SIZE 584
+
+static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
+/*
+ * CPI:
+ *
+ * Counts the following:
+ *
+ * ctr0 : total cycles
+ * ctr1 : total cycles where nothing retired
+ * ctr2 : total instructions retired, including nullified
+ * ctr3 : total instructions retired, less nullified instructions
+ */
+         {
+         0x4c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe0e0e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
+         0x0101ffff, 0xfffff104, 0xe000c07f, 0xfffffffc,
+         0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
+         0x00000fff, 0xff00000f, 0xffff0000, 0x0fffff00,
+         0x000fffff, 0x00000000, 0x00000000, 0x00ffffff,
+         0xfffff000, 0x0000000f, 0xffffffff, 0xff000000,
+         0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000030, 0x00003c00, 0x067f080c, 0x02019fc0,
+         0x02804067, 0xf0009030, 0x19fc002c, 0x40067f08,
+         0x0c12019f, 0xc0028440, 0x67f00091, 0x3019fc00,
+         0x2fc007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
+         0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
+         0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
+         0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
+         0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
+         0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
+         0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
+         0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff},
+
+/* Bus utilization image (bus_util)
+ *
+ * ctr0 : counts address valid cycles
+ * ctr1 : counts data valid cycles
+ * ctr2 : counts overflow from counter 0
+ * ctr3 : counts overflow from counter 1
+ */
+         {
+         0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
+         0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0x0000000c, 0x00003c00, 0x07930000, 0x0041e4c0,
+         0x01002079, 0x3000800c, 0x1e4c0030, 0x00279300,
+         0x010049e4, 0xc0014022, 0x79300090, 0x0c9e4c00,
+         0x34004793, 0x00020051, 0xe4c00180, 0x24793000,
+         0xa00d1e4c, 0x00380067, 0x93000300, 0x59e4c001,
+         0xc0267930, 0x00b00d9e, 0x4c003fff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00100000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/*
+ * TLB counts (same as tlbStats image):
+ *
+ * Counts the following:
+ *
+ * ctr0: DTLB misses
+ * ctr1: ITLB misses
+ * ctr2: total cycles in the miss handlers
+ * ctr3: total cycles
+ */
+
+         {
+         0x0c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe7e7e0e0, 0x004e0004, 0x07ffffff, 0xffc01380,
+         0x0101ffff, 0xfffff104, 0xe000c06a, 0xafffc85c,
+         0x01380010, 0x1fffffff, 0xff000000, 0x00000000,
+         0x01b9e000, 0x0001b8c0, 0x00000000, 0x0fffff00,
+         0x000fffff, 0x00000000, 0x00000000, 0x00400000,
+         0x00001000, 0x00000004, 0x00000000, 0x01000000,
+         0x0000ffff, 0xfffffff0, 0x00000000, 0x0fffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55ff5, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c00, 0x01ff0001, 0x08007fc2,
+         0x02c1001f, 0xf0807100, 0x1bfc200c, 0x4806ff00,
+         0x03f001ff, 0xfe003c00, 0x7fff800f, 0x001fffe0,
+         0x03c007ff, 0xf800f001, 0xfffe003c, 0x007fff80,
+         0x0f001fff, 0xe003c007, 0xfff800f0, 0x01fffe00,
+         0x3c007fff, 0x800f001f, 0xffe003c0, 0x07fff800,
+         0xf001fffe, 0x003c007f, 0xff800f00, 0x1fffe003,
+         0xc007fff8, 0x00f001ff, 0xfe003c00, 0x7fff800f,
+         0x001fffe0, 0x03c007ff, 0xf800f001, 0xfffe003c,
+         0x007fff80, 0x0f001fff, 0xe003c007, 0xfff800f0,
+         0x01fffe00, 0x3c007fff, 0x800f001f, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/* tlbHandMiss
+ *
+ * ctr0: counts TLB misses 
+ * ctr1: counts dmisses inside tlb miss handlers 
+ * ctr2: counts cycles in the tlb miss handlers 
+ * ctr3: counts overflows of ctr2 
+ */
+{
+0x1c00c000,00000000,0x00060000,00000000,
+0xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
+0x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
+0x01380010,0x1fffffff,0xff000000,00000000,
+0x01b9e000,0x0001b8c0,00000000,0x0fffff00,
+0x000fffff,00000000,00000000,0x00400000,
+0x00001000,0x00000004,00000000,0x01000000,
+0x0000ffff,0xfffffff0,00000000,0x0fffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
+0xf0000000,0x00003c00,0x01fd0000,0x08007f42,
+0x0281001f,0xd080a100,0x19f42008,0x44067d08,
+0x0612019f,0x400084c0,0x67d00060,0x0047f400,
+0x042011fd,0x080b0404,0x7f4202c4,0x0167d080,
+0x311059f4,0x201c4816,0x7d000313,0x059f4001,
+0xfc007fff,0x800f001f,0xffe003c0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* branch_taken image (ptkn image)
+ *
+ * ctr0: overflow for ctr1
+ * ctr1: predicted taken branches, actually taken
+ * ctr2: all predicted taken branches (nullfied or not)
+ * ctr3: overflow for ctr2
+ */
+
+        {
+        0xcc01e000, 0x00000000, 0x00060000, 0x00000000,
+        0xa08080a0, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffff0000, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+        0xf0000000, 0x00003c00, 0x04f90000, 0x02013e40,
+        0x0081004f, 0x90004060, 0x13e40018, 0x0024f900,
+        0x0802093e, 0x40028102, 0x4f9000c0, 0x6093e400,
+        0x380014f9, 0x00010205, 0x3e4000c1, 0x014f9000,
+        0x506053e4, 0x001c0034, 0xf9000902, 0x0d3e4002,
+        0xc1034f90, 0x00d060d3, 0xe4003fff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xfffffc00,
+        0x00000000, 0x00000000, 0x00000000, 0x00000000,
+        0xffff0000, 0x00000000, 0xf0000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+        0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+        0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xffffffff, 0xf3ffffff, 0xffffffff,
+        0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+        0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+        0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+        0xffffffff, 0xffffffff },
+
+/* branch_nottaken (pntkn image)
+ *
+ * ctr0: overflow for ctr1
+ * ctr1: counts branches predicted not-taken, but actually taken
+ * ctr2: counts all predictable branches predicted not-taken
+ * ctr3: overflow for ctr2
+ */
+{
+0xcc01e000,00000000,0x00060000,00000000,
+0xc0c0c0e0,0xffb1fffb,0xfff7ffff,0xffffffff,
+0xffffffff,0xfffffffb,0x1fffbfff,0x7fffffff,
+0xfcc7ffff,0xffdffffa,0x5f000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+
+/* imiss image
+ *
+ * ctr0 : counts imiss aligned on 0
+ * ctr1 : counts imiss aligned on 4
+ * ctr2 : counts imiss aligned on 8
+ * ctr3 : counts imiss aligned on C
+ */
+         {
+         0x0c00c000, 0x00000000, 0x00010000, 0x00000000,
+         0xe7ebedee, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xfff55fff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c00, 0x007f0000, 0x01001fc0,
+         0x00408007, 0xf0002030, 0x01fc000c, 0x10007f00,
+         0x0405001f, 0xc0014180, 0x07f00060, 0x7001fc00,
+         0x1c20007f, 0x00080900, 0x1fc00242, 0x8007f000,
+         0xa0b001fc, 0x002c3000, 0x7f000c0d, 0x001fc003,
+         0x438007f0, 0x00e0f001, 0xfc003fff, 0xfffff800,
+         0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
+         0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
+         0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
+         0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
+         0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff},
+
+/* dmiss image
+ * 
+ * ctr0 : counts cycles
+ * ctr1 : counts cycles where something retired
+ * ctr2 : counts dmisses
+ * ctr3 : (same as ctr2)
+ */
+         {
+         0x3c00c000, 0x00000000, 0x00060000, 0x00000000,
+         0xe0e0e0e0, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xff000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffff0000, 0x00000000, 0x6fffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xf0000000,
+         0xf0000000, 0x00003c04, 0x007f0009, 0x02001fc0,
+         0x0280c007, 0xf000b040, 0x01fc0030, 0x14007f00,
+         0x0d06001f, 0xc00381c0, 0x07f000f0, 0x8001fc00,
+         0x2024007f, 0x00090a00, 0x1fc00282, 0xc007f000,
+         0xb0c001fc, 0x00303400, 0x7f000d0e, 0x001fc003,
+         0x83c007f0, 0x00f00001, 0xfc0023ff, 0xfffff800,
+         0xfffffffe, 0x003fffff, 0xff800fff, 0xffffe003,
+         0xfffffff8, 0x00ffffff, 0xfe003fff, 0xffff800f,
+         0xffffffe0, 0x03ffffff, 0xf800ffff, 0xfffe003f,
+         0xffffff80, 0x0fffffff, 0xe003ffff, 0xfff800ff,
+         0xfffffe00, 0x3fffffff, 0x800fffff, 0xffe00000,
+         0x00000000, 0x00000000, 0x00000000, 0x00000000,
+         0x6fff0000, 0x00000000, 0x60000000, 0x00000000,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xfffffc00, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xfffffc00, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffaaaa, 0xffffffff, 0xf3ffffff, 0xffffffff,
+         0xfdffffff, 0xffffffff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0xffffffff, 0xfffff9ff, 0xfe000000, 0x00000000,
+         0x00030000, 0x00000000, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+         0xffffffff, 0xffffffff },
+
+/* dcmiss 
+ *
+ * ctr0: counts store instructions retired 
+ * ctr1: counts load instructions retired
+ * ctr2: counts dmisses 
+ * ctr3: counts READ_SHARED_OR_PRIV and READ_PRIVATE transactions on Runway 
+ */
+{
+0x2c90c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf00000e8,0x00003c02,0x00bf0001,0x02002fc0,
+0x0080a00b,0xf0003040,0x02fc0010,0x1200bf00,
+0x0506002f,0xc00181a0,0x0bf00070,0x8002fc00,
+0x202200bf,0x00090a00,0x2fc00282,0xa00bf000,
+0xb0c002fc,0x00303200,0xbf000d0e,0x002fc003,
+0x83a00bf0,0x00ffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0x55555555,0xd5555555,
+0x55555555,0x75555555,0x5e1ffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf8000000,00000000,
+00000000,00000000,0xf4000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* big_cpi
+ *
+ * ctr0: counts total cycles 
+ * ctr1: counts overflows of ctr0 (for greater than 32-bit values) 
+ * ctr2: counts overflows of ctr3 (for greater than 32-bit values) 
+ * ctr3: counts unnullified instructions retired 
+ */
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe7e7e0e0,0x004e0004,0x07ffffff,0xffc01380,
+0x0101ffff,0xfffff104,0xe000c06a,0xafffc85c,
+0x01380010,0x1fffffff,0xff000000,00000000,
+0x01b9e000,0x0001b8c0,00000000,0x0fffff00,
+0x000fffff,00000000,00000000,0x00400000,
+0x00001000,0x00000004,00000000,0x01000000,
+0x0000ffff,0xfffffff0,00000000,0x0fffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff55ff5,0xffffffff,0xffffffff,0xf0000000,
+0xf0000010,0x00003c00,0x01760008,0x00025d80,
+0x02800417,0x6000c001,0x25d80038,0x04017600,
+0x0901025d,0x8002c044,0x176000d0,0x1125d800,
+0x3c2001f6,0x08080400,0x7d820203,0x001f6080,
+0x804027d8,0x20282009,0xf6080a0c,0x027d8202,
+0x81041f60,0x80c08107,0xd8203030,0x41f6080c,
+0x04127d82,0x0382049f,0x6080e0c1,0x27d82038,
+0x4006f608,0x081011bd,0x82030400,0xef6080a1,
+0x013bd820,0x384806f6,0x00081211,0xbd800304,
+0x80ef6000,0xa1213bd8,0x003bc007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x6fff0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* big_ls
+ *
+ * ctr0:counts the total number of cycles for which local_stall_A1 is asserted. 
+ * ctr1: is the overflow for counter 0. 
+ * ctr2: counts IFLUSH_AV 
+ * ctr3: is the overflow for counter 2. 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00029408,0x02f50002,0x0800bd40,
+0x0202802f,0x5000a000,0x4bd40004,0x0812f500,
+0x030804bd,0x40024281,0x2f5000b0,0x010bd400,
+0x100842f5,0x00060810,0xbd400302,0x842f5000,
+0xe0014bd4,0x00140852,0xf5000708,0x14bd4003,
+0x42852f50,0x00ff001f,0xffe003c0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x0df70000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* br_abort
+ *
+ * ctr0: counts BRAD_STALLH 
+ * ctr1: counts ONE_QUAD 
+ * ctr2: counts BR0_ABRT 
+ * ctr3: counts BR1_ABRT
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x1a250000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* isnt
+ *
+ * ctr0: counts the total number of cycles for which iside_notrans is asserted 
+ * ctr1: counts the number of times iside_notrans is asserted for 1-4 cycles 
+ * ctr2: counts the number of times iside_notrans is asserted for 5-7 cycles 
+ * ctr3: counts the number of times iside_notrans is asserted for > 7 cycles 
+ */
+{
+0x0c018000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xcfffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c20,0x03ff0808,0x1800ffc4,
+0x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
+0x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
+0x210003ff,0x00045800,0xffcc0214,0x003ff000,
+0x26800ffc,0xe0218003,0xff000278,0x00ffd002,
+0x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xcdff0000,00000000,0xc0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* quadrant
+ *
+ * ctr0: Total number of instructions in quadrant 0 
+ * ctr1: Total number of instructions in quadrant 1 
+ * ctr2: Total number of instructions in quadrant 2 
+ * ctr3: Total number of instructions in quadrant 3 
+ * Works only with 32-bit
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x004e0004,   0x07ffffff,   0xffc01380,
+   0x0101ffff,   0xfffff004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0x00000fff,   0xff00000f,   0xffff0000,   0x0fffff00,
+   0x000fffff,   0x00000000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000040f,   0xfffffffc,   0xff000000,
+   0x0080ffff,   0xffffcff0,   0x0000000c,   0x0fffffff,
+   0xfcff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xfff55ff5,   0x5fffffff,   0xffffffff,   0xf0000000,
+   0xf00000f0,   0x00003c00,   0x007f0000,   0x01001fc0,
+   0x00408007,   0xf0002030,   0x01fc000c,   0x10007f00,
+   0x0405001f,   0xc0014180,   0x07f00060,   0x7001fc00,
+   0x1c20007f,   0x00080900,   0x1fc00242,   0x8007f000,
+   0xa0b001fc,   0x002c3000,   0x7f000c0d,   0x001fc003,
+   0x438007f0,   0x00e0f001,   0xfc003fff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffffc00,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff},
+
+/* rw_pdfet (READ_PRIV transactions)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf8000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff},
+
+/* rw_wdfet (WRITEBACKS)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0x98000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff},
+
+/* shlib_cpi
+ *
+ * ctr0: Total number of instructions in quad 0 
+ * ctr1: Total number of CPU clock cycles in quad 0 
+ * ctr2: total instructions without nullified   
+ * ctr3: total number of CPU clock cycles 
+ */
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x004e0004,   0x07ffffff,   0xffc01380,
+   0x0101ffff,   0xfffff004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0x00000fff,   0xff00000f,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000000f,   0xfffffffc,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xfff77ff5,   0x7fffffff,   0xffffffff,   0xf0000000,
+   0xf00000a0,   0x00003c00,   0x01ff0005,   0x08007fc0,
+   0x03c1001f,   0xf08030c0,   0x07fc203c,   0x4001ff08,
+   0x0118007f,   0xc003c500,   0x1ff08031,   0xc007fc00,
+   0x3fffffff,   0xf800ffff,   0xfffe003f,   0xffffff80,
+   0x0fffffff,   0xe003ffff,   0xfff800ff,   0xfffffe00,
+   0x3fffffff,   0x800fffff,   0xffe003ff,   0xfffff800,
+   0xfffffffe,   0x003fffff,   0xff800fff,   0xffffe003,
+   0xfffffff8,   0x00ffffff,   0xfe003fff,   0xffff800f,
+   0xffffffe0,   0x03ffffff,   0xf800ffff,   0xfffe003f,
+   0xffffff80,   0x0fffffff,   0xe003ffff,   0xfff800ff,
+   0xfffffe00,   0x3fffffff,   0x800fffff,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff},
+
+
+/* addr_inv_abort_alu
+ *
+ * ctr0: counts ABORT_ALU0L 
+ * ctr1: counts ABORT_ALU1L 
+ * ctr2: counts ADDR0_INVALID 
+ * ctr3: counts ADDR1_INVALID 
+ */
+
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000d,0x01001fc0,
+0x03008007,0xf000f030,0x01fc0038,0x10007f00,
+0x0905001f,0xc0020180,0x07f000b0,0x7001fc00,
+0x2820007f,0x00050900,0x1fc00102,0x8007f000,
+0x70b001fc,0x00183000,0x7f00010d,0x001fc000,
+0x038007f0,0x0030f001,0xfc000bff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x65380000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+
+/* brad_stall
+ *
+ * ctr0: counts the total number of cycles for which brad_stall is asserted 
+ * ctr1: counts the number of times brad_stall is asserted for 1-4 cycles 
+ * ctr2: counts the number of times brad_stall is asserted for 5-7 cycles 
+ * ctr3: counts the number of times brad_stall is asserted for > 7 cycles 
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c20,0x03ff0808,0x1800ffc4,
+0x0204003f,0xf0004280,0x0ffc6020,0x8003ff00,
+0x043800ff,0xc8020c00,0x3ff00044,0x800ffca0,
+0x210003ff,0x00045800,0xffcc0214,0x003ff000,
+0x26800ffc,0xe0218003,0xff000278,0x00ffd002,
+0x1c003ff0,0x0028800f,0xfd002200,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x1bff0000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* cntl_in_pipel
+ *
+ * ctr0: counts the total number of cycles for which cntl_in_pipel is asserted 
+ * ctr1: counts the number of times cntl_in_pipel is asserted for 1-4 cycles 
+ * ctr2: counts the number of times cntl_in_pipel is asserted for 5-7 cycles 
+ * ctr3: counts the number of times cntl_in_pipel is asserted for > 7 cycles 
+ */
+{
+0x0c006000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x3fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00021c00,0x03ff0808,0x1000ffc4,
+0x0206003f,0xf0004200,0x0ffc6020,0xa003ff00,
+0x043000ff,0xc8020e00,0x3ff00044,0x000ffca0,
+0x212003ff,0x00045000,0xffcc0216,0x003ff000,
+0x26000ffc,0xe021a003,0xff000270,0x00ffd002,
+0x1e003ff0,0x0028000f,0xfd002220,0x03ff0001,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x3fff0000,00000000,0x30000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+/* dsnt_xfh
+ *
+ * ctr0: counts dside_notrans 
+ * ctr1: counts xfhang 
+ * ctr2: is the overflow for ctr0 
+ * ctr3: is the overflow for ctr1 
+ */
+{
+0x0c018000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xcfffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x00030000,0x01f30000,0x00087cc0,
+0x0040041f,0x30002001,0x87cc000c,0x1001f300,
+0x0404087c,0xc0014104,0x1f300060,0x4187cc00,
+0x1c2001f3,0x00080808,0x7cc00242,0x041f3000,
+0xa08187cc,0x002c3001,0xf3000c0c,0x087cc003,
+0x43041f30,0x00e0c187,0xcc003fc0,0x07fff800,
+0xf001fffe,0x003c007f,0xff800f00,0x1fffe003,
+0xc007fff8,0x00f001ff,0xfe003c00,0x7fff800f,
+0x001fffe0,0x03c007ff,0xf800f001,0xfffe003c,
+0x007fff80,0x0f001fff,0xe003c007,0xfff800f0,
+0x01fffe00,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xcb3f0000,00000000,0xc0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff }, 
+
+/* fet_sig1
+ *
+ * ctr0: counts ICORE_AV 
+ * ctr1: counts ITRANS_STALL 
+ * ctr2: counts SEL_PCQH 
+ * ctr3: counts OUT_OF_CONTEXT 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x07c10000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff},
+
+/* fet_sig2
+ *
+ * ctr0: counts ICORE_AV  
+ * ctr1: counts IRTN_AV 
+ * ctr2: counts ADDRESS_INC 
+ * ctr3: counts ADDRESS_DEC 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x06930000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_1
+ *
+ * ctr0: counts HIT_RETRY0 
+ * ctr1: counts HIT_RETRY1 
+ * ctr2: counts GO_TAG_E 
+ * ctr3: counts GO_TAG_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x71c10000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_2
+ *
+ * ctr0: counts HIT_DM0 
+ * ctr1: counts HIT_DM1 
+ * ctr2: counts GO_STORE_E 
+ * ctr3: counts GO_STORE_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x72930000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_3
+ *
+ * ctr0: counts HIT_DV0 
+ * ctr1: counts HIT_DV1 
+ * ctr2: counts STBYPT_E (load bypasses from store queue) 
+ * ctr3: counts STBYPT_O
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f0002,0x01001fc0,
+0x00c08007,0xf0000030,0x01fc0004,0x10007f00,
+0x0605001f,0xc001c180,0x07f00040,0x7001fc00,
+0x1420007f,0x000a0900,0x1fc002c2,0x8007f000,
+0x80b001fc,0x00243000,0x7f000e0d,0x001fc003,
+0xc38007f0,0x00c0f001,0xfc0037ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x77250000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* g7_4
+ *
+ * ctr0: counts HIT_DIRTY0 
+ * ctr1: counts HIT_DIRTY1 
+ * ctr2: counts CA_BYP_E (quick launch) 
+ * ctr3: counts CA_BYP_O 
+ */
+{
+0x0c00e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x7fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x7bb70000,00000000,0x70000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+
+/* mpb_labort
+ *
+ * ctr0: counts L_ABORT_ALU0L
+ * ctr1: counts L_ABORT_ALU1L 
+ * ctr2: counts MPB0H 
+ * ctr3: counts MPB1H 
+ */
+{
+0x0c00c000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffa5ffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x6fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+00000000,0x0003f800,0x007f000e,0x01001fc0,
+0x03c08007,0xf000c030,0x01fc0034,0x10007f00,
+0x0a05001f,0xc002c180,0x07f00080,0x7001fc00,
+0x2420007f,0x00060900,0x1fc001c2,0x8007f000,
+0x40b001fc,0x00143000,0x7f00020d,0x001fc000,
+0xc38007f0,0x0000f001,0xfc0007ff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x605c0000,00000000,0x60000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffaaaa,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* panic
+ *
+ * ctr0: is the overflow for counter 1 
+ * ctr1: counts traps and RFI's 
+ * ctr2: counts panic traps 
+ * ctr3: is the overflow for counter 2
+ */
+{
+0x0c002000,00000000,0x00060000,00000000,
+0xe7efe0e0,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffffc,
+0x41380030,0x1aabfff2,0x17000000,00000000,
+0x01b80000,0x3effffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,00000000,0x00400000,
+0x00001fff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x1fffffff,0xffffffff,
+0xfff7fff7,0xffffffff,0xffffffff,0xf0000000,
+0xb0000000,0x00012c04,0x05790804,0x14013e44,
+0x0008004f,0x90000040,0x15e46000,0xc0047920,
+0x004a003e,0x40011080,0x0f900024,0x4003e460,
+0x00c80479,0x00023301,0x1e400100,0x4157d080,
+0x514053f4,0x40048014,0xfd000104,0x055f4600,
+0x4c0147d2,0x0014a043,0xf4001508,0x10fd0003,
+0x44043f46,0x004c8147,0xd0003330,0x51f40014,
+0x04257908,0x0c14093e,0x44020802,0x4f900080,
+0x4095e460,0x20c02479,0x20084a08,0x3e400310,
+0x820f9000,0xa44083e4,0x6020c824,0x79000a33,
+0x091e4003,0x3c007fff,0x800f001f,0xffe00000,
+00000000,00000000,00000000,00000000,
+0x10400000,00000000,0x10000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rare_inst
+ *
+ * ctr0: counts sync and syncdma instructions 
+ * ctr1: counts pxtlbx,x instructions 
+ * ctr2: counts ixtlbt instructions 
+ * ctr3: counts cycles 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xe0e0e0e0,0x004e000c,0x000843fc,0x85c09380,
+0x0121ebfd,0xff217124,0xe0004000,0x943fc85f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xe00000e0,0x00003c00,0x007f0001,0x01001fc0,
+0x00408007,0xf0003030,0x01fc000c,0x10007f00,
+0x0505001f,0xc0014180,0x07f00070,0x7001fc00,
+0x1c20007f,0x00090900,0x1fc00242,0x8007f000,
+0xb0b001fc,0x002c3000,0x7f000d0d,0x001fc003,
+0x438007f0,0x00f0f001,0xfc003fff,0xfffff800,
+0xfffffffe,0x003fffff,0xff800fff,0xffffe003,
+0xfffffff8,0x00ffffff,0xfe003fff,0xffff800f,
+0xffffffe0,0x03ffffff,0xf800ffff,0xfffe003f,
+0xffffff80,0x0fffffff,0xe003ffff,0xfff800ff,
+0xfffffe00,0x3fffffff,0x800fffff,0xffe00000,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rw_dfet (for D-cache misses and writebacks)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf0000000,00000000,
+00000000,00000000,0x98000000,00000000,
+0xffffffff,0xffffffff,0x0fffffff,0xffffffff,
+00000000,00000000,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* rw_ifet (I-cache misses -- actually dumb READ transactions)
+ *
+ * ctr0: counts address valid cycles 
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xd0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff,00000000,00000000,
+0xffffffff,0xffffffff },
+
+
+/* rw_sdfet (READ_SHARED_OR_PRIVATE transactions)
+ *
+ * ctr0: counts address valid cycles
+ * ctr1: counts *all* data valid cycles 
+ * ctr2: is the overflow from counter 0 
+ * ctr3: is the overflow from counter 1 
+ */
+{
+0x0c01e000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x0000000c,0x00003c00,0x07930000,0x0041e4c0,
+0x01002079,0x3000800c,0x1e4c0030,0x00279300,
+0x010049e4,0xc0014022,0x79300090,0x0c9e4c00,
+0x34004793,0x00020051,0xe4c00180,0x24793000,
+0xa00d1e4c,0x00380067,0x93000300,0x59e4c001,
+0xc0267930,0x00b00d9e,0x4c003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00100000,00000000,0xf4000000,00000000,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+00000000,00000000,00000000,00000000,
+0xffffffff,0xffffffff },
+
+
+/* spec_ifet
+ *
+ * ICORE_AV fires for every request which the Instruction Fetch Unit sends
+ * to the Runway Interface Block.  Hence, this counts all I-misses, speculative
+ * or not, but does *not* include I-cache prefetches, which are generated by
+ * RIB.
+ * IRTN_AV fires twice for every I-cache miss returning from RIB to the IFU.
+ * It will not fire if a second I-cache miss is issued from the IFU to RIB
+ * before the first returns.  Therefore, if the IRTN_AV count is much less
+ * than 2x the ICORE_AV count, many speculative I-cache misses are occuring
+ * which are "discovered" to be incorrect fairly quickly.
+ * The ratio of I-cache miss transactions on Runway to the ICORE_AV count is
+ * a measure of the effectiveness of instruction prefetching.  This ratio
+ * should be between 1 and 2.  If it is close to 1, most prefetches are
+ * eventually called for by the IFU; if it is close to 2, almost no prefetches
+ * are useful and they are wasted bus traffic.
+ *
+ * ctr0: counts ICORE_AV 
+ * ctr1: counts IRTN_AV 
+ * ctr2: counts all non-coherent READ transactions on Runway. (TTYPE D0) 
+ *	This should be just I-cache miss and I-prefetch transactions.
+ * ctr3: counts total processor cycles 
+ */
+{
+0x0c000000,00000000,0x00060000,00000000,
+0xefefefef,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0x0fffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0x00000008,0x00030c00,0x01bf0001,0x00806fc0,
+0x00c1001b,0xf0005048,0x06fc001c,0x2001bf00,
+0x0908806f,0xc002c300,0x1bf000d0,0xc806fc00,
+0x3fffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0x06bf0000,00000000,00000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00110000,00000000,0xd0ffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0x00ffffff,0xffffffff,
+0xffffffff,0xffffffff,00000000,00000000,
+0xffffffff,0xffffffff },
+
+/* st_cond0
+ *
+ * ctr0: is the overflow for ctr1
+ * ctr1: counts major ops 0C and 0E (fp ops, not fmac or fmpyadd) 
+ * ctr2: counts B,L (including long and push) and GATE (including nullified),
+ *	 predicted not-taken
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc13380,
+0x0101ffff,0xffa1f057,0xe000407f,0xdfffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond1
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major ops 1x (most of the load/stores) 
+ * ctr2: counts CMPB (dw) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc01b80,
+0x0101ffff,0xffb7f03d,0xe000407f,0xffffc8ff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond2
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major op 03 
+ * ctr2: counts CMPIB (dw) predicted not taken. 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc09780,
+0x0101ffff,0xff21f077,0xe000407f,0xffffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond3
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major ops 06 & 26 
+ * ctr2: counts BB, BVB, MOVB, MOVIB (incl. nullified) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc03780,
+0x0101ffff,0xff29f016,0xe000407f,0xffffe97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_cond4
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts major op 2E 
+ * ctr2: counts CMPB, CMPIB, ADDB, ADDIB (incl. nullified) predicted not-taken 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0e0c0e0,0xffffffff,0xffffffff,0xffc17780,
+0x0101ffff,0xff21f014,0xe000407f,0xffffe9ff,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_unpred0
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts BE and BE,L 
+ * ctr2: counts BE and BE,L including nullified 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0c0c0e0,0xffffffff,0xffffffff,0xffdf5bbf,
+0xffffffff,0xff25f7d6,0xefffffff,0xffffc97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* st_unpred1
+ *
+ * ctr0: is the overflow for ctr1 
+ * ctr1: counts BLR, BV, BVE, BVE,L 
+ * ctr2: counts BLR, BV, BVE, BVE,L including nullified 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0x4c01e000,00000000,0x00060000,00000000,
+0xe0c0c0e0,0xffffffff,0xffffffff,0xffc15f80,
+0x0501ff7f,0xff21f057,0xe001407f,0xdfffc87f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf0000060,0x00003c00,0x04f90000,0x02013e40,
+0x0081004f,0x90004060,0x13e40018,0x0024f900,
+0x0802093e,0x40028102,0x4f9000c0,0x6093e400,
+0x380014f9,0x00010205,0x3e4000c1,0x014f9000,
+0x506053e4,0x001c0034,0xf9000902,0x0d3e4002,
+0xc1034f90,0x00d060d3,0xe4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+
+/* unpred
+ *
+ * ctr0: counts non-nullified unpredictable branches 
+ * ctr1: is the overflow for ctr0 
+ * ctr2: counts all unpredictable branches (nullified or not) 
+ * ctr3: is the overflow for ctr2 
+ */
+{
+0xcc01e000,00000000,0x00060000,00000000,
+0x20202020,0xff31ffff,0xfff7fffe,0x97ffcc7f,
+0xfffffdff,0xffa5fff3,0x1fffffff,0x7fffe97f,
+0xffffffff,0xffffffff,0xff000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffff0000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xf0000000,
+0xf00000a0,0x00003c00,0x02f50000,0x0004bd40,
+0x0040802f,0x50002020,0x4bd4000c,0x0042f500,
+0x040014bd,0x40014084,0x2f500060,0x214bd400,
+0x1c2002f5,0x00080804,0xbd400242,0x802f5000,
+0xa0a04bd4,0x002c2042,0xf5000c08,0x14bd4003,
+0x42842f50,0x00e0a14b,0xd4003fff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xfffffc00,
+00000000,00000000,00000000,00000000,
+0xffff0000,00000000,0xf0000000,00000000,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xfffffc00,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xfffffc00,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xffffffff,0xf3ffffff,0xffffffff,
+0xfdffffff,0xffffffff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0xffffffff,0xfffff9ff,0xfe000000,00000000,
+0x00030000,00000000,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+0xffffffff,0xffffffff },
+   
+
+/* go_store
+ *
+ * ctr0: Overflow for counter 2 
+ * ctr1: Overflow for counter 3 
+ * ctr2: count of GO_STORE_E signal 
+ * ctr3: count of GO_STORE_O signal 
+ */
+
+   {
+   0x0c00e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffa5ffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xff000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x7fffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xf0000000,
+   0x00000000,   0x0000c000,   0x067c0000,   0x01019f00,
+   0x00408067,   0xc0002030,   0x19f0000c,   0x000e7c00,
+   0x0401039f,   0x00014080,   0xe7c00060,   0x3039f000,
+   0x1c00167c,   0x00080105,   0x9f000240,   0x8167c000,
+   0xa03059f0,   0x002c001e,   0x7c000c01,   0x079f0003,
+   0x4081e7c0,   0x00e03079,   0xf0003fc0,   0x07fff800,
+   0xf001fffe,   0x003c007f,   0xff800f00,   0x1fffe003,
+   0xc007fff8,   0x00f001ff,   0xfe003c00,   0x7fff800f,
+   0x001fffe0,   0x03c007ff,   0xf800f001,   0xfffe003c,
+   0x007fff80,   0x0f001fff,   0xe003c007,   0xfff800f0,
+   0x01fffe00,   0x3c007fff,   0x800f001f,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0x70130000,   0x00000000,   0x70000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffaaaa,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffaaaa,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff
+   },
+
+
+/* shlib_call
+ *
+ * ctr0: SharedLib call Depth1 
+ * ctr1: SharedLib call Depth2 
+ * ctr2: SharedLib call Depth3 
+ * ctr3: SharedLib call Depth>3 
+ */
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xc76fa005,   0x07dd7e9c,   0x87115b80,
+   0x01100200,   0x07200004,   0xe000407f,   0xfffffffc,
+   0x01380010,   0x1fffffff,   0xff000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xf0000000,
+   0xf0000000,   0x00003c20,   0x01ff0808,   0x04007fc0,
+   0x0003001f,   0xf0000180,   0x07fc4010,   0x5001ff00,
+   0x001c007f,   0xc2000a00,   0x1ff18022,   0x4007fc20,
+   0x00b001ff,   0x10003800,   0x7fc8004d,   0x001ff100,
+   0x03c007fc,   0x60012001,   0xff280144,   0x007fc600,
+   0x13001ff2,   0x00058007,   0xfcc00550,   0x01ff2000,
+   0x5c007fca,   0x001a001f,   0xf3801640,   0x07fca001,
+   0xb001ff30,   0x0078007f,   0xd0005d00,   0x1ff30007,
+   0xc007fce0,   0x022001ff,   0x48018400,   0x7fce0023,
+   0x001ff400,   0x098007fd,   0x20065001,   0xff40009c,
+   0x007fd200,   0x3fffffff,   0x800fffff,   0xffe00000,
+   0x00000000,   0x00000000,   0x00000000,   0x00000000,
+   0xffff0000,   0x00000000,   0xf0000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xfffffc00,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xfffffc00,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xf3ffffff,   0xffffffff,
+   0xfdffffff,   0xffffffff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0xffffffff,   0xfffff9ff,   0xfe000000,   0x00000000,
+   0x00030000,   0x00000000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff
+   }
+};
+#define PCXW_IMAGE_SIZE 576
+
+static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = {
+/*
+ * CPI:     FROM CPI.IDF (Image 0)
+ *
+ * Counts the following:
+ *
+ * ctr0 : total cycles
+ * ctr1 : total cycles where nothing retired
+ * ctr2 : total instructions retired, including nullified
+ * ctr3 : total instructions retired, less nullified instructions
+ */
+   {
+   0x4c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x60f00000,   0x0fffff00,   0x000fffff,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00ffffff, 
+   0xfffff000,   0x0000000f,   0xffffffff,   0xff000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x00270000,   0x00000055, 
+   0x0200000e,   0x4d300000,   0x00000000,   0x0ff00002, 
+   0x70000000,   0x00000020,   0x0000e400,   0x00000ff0, 
+   0x00000000,   0x00000000,   0x00000055,   0xffffff00, 
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00000,   0x00000030,   0x00000000, 
+   0x00157fff,   0xffc00000,   0x034c0000,   0x00000000, 
+   0x03fc0000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* Bus utilization image   FROM BUS_UTIL.IDF (Image 1)
+ *
+ * ctr0 : counts address valid cycles
+ * ctr1 : counts data valid cycles
+ * ctr2 : counts overflow from counter 0
+ * ctr3 : counts overflow from counter 1
+ */
+         {
+	 0x0c01e000, 0x00000000, 0x00060000, 0x00000000,
+	 0xefefefef, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffff00, 0x00000000,
+	 0xf0ffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffff0000, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+	 0x00000000, 0x00000000, 0x00001b00, 0xaa000000,
+	 0x00000001, 0x30700000, 0x00055aaf, 0xf0000000,
+	 0x01b00000, 0x00000000, 0x00001037, 0x00000000,
+	 0x55aaff00, 0x00c00000, 0x1b55aa00, 0x00000000,
+	 0x0001fff0, 0xcfffff00, 0x00000000, 0x0f0fffff,
+	 0xffffffff, 0xffffffff, 0x30ffff0c, 0xfffff000,
+	 0x00000000, 0x00ffffff, 0xffffffff, 0xfffffff3,
+	 0x0ffff0cf, 0xffff0000, 0x00000000, 0x00ffffff,
+	 0xffffffff, 0xfffffff3, 0x0ffff0cf, 0xffff0000,
+	 0x00000000, 0x0fffffff, 0xffffffff, 0xffffff30,
+	 0xfff70000, 0x000055aa, 0xff000000, 0x000006d5,
+	 0x40000000, 0x00000000, 0x731c0000, 0x000156ab,
+	 0xfc000000, 0x00000000, 0xffff0000, 0x00000000,
+	 0xf0000000, 0x00000000, 0x00ffffff, 0xff3fffff,
+	 0xffffffff, 0xffcfffff, 0xfff7fbfc, 0x00000000,
+	 0x00ffffff, 0xff3fffff, 0xffffffff, 0xffcfffff,
+	 0xfff7fbfc, 0x00000000, 0xffffffff, 0xffffff3f,
+	 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
+	 0x00000000, 0x00000000, 0xffffffff, 0xffffff3f,
+	 0xffffffff, 0xffffff7f, 0xffffffff, 0xfffffefc,
+	 0x00000000, 0x00000000, 0xffffffff, 0xfffff9ff,
+	 0xfe000000, 0x00000000, 0xffffffff, 0xfffff9ff,
+	 0xfe000000, 0x00000000, 0x00100000, 0x00000000,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+	 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+   },
+
+/*
+ * TLB counts:    FROM TLBSTATS.IDF (Image 2)
+ *
+ * Counts the following:
+ *
+ * ctr0: DTLB misses
+ * ctr1: ITLB misses
+ * ctr2: total cycles in the miss handlers
+ * ctr3: total cycles
+ */
+
+   {
+   0x0c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000, 
+   0x00001000,   0x00000004,   0x00000000,   0x01000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x00800000,   0x00153f7f, 
+   0x55000000,   0xaf800000,   0xc0000000,   0x0403f240, 
+   0x00000000,   0x00001010,   0x00004700,   0x00000ff0, 
+   0x00000000,   0x00000000,   0x00000055,   0xffffff00, 
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00000,   0x00000000,   0x00000000, 
+   0x00157fff,   0xffc00000,   0x00000000,   0x3fc00000, 
+   0x00040000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* tlbhandler  FROM tlbHandMiss.idf (Image 3)
+ *
+ * ctr0: TLB misses
+ * ctr1: dmisses inside the TLB miss handler
+ * ctr2: cycles in the TLB miss handler
+ * ctr3: overflow of ctr2
+ */
+   {
+   0x1c00c000,   0x00000000,   0x00060000,   0x00000000, 
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001, 
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff, 
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000, 
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff, 
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000, 
+   0x00001000,   0x00000004,   0x00000000,   0x01000000, 
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0x006c0000,   0x01000054, 
+   0x02000002,   0xc3200000,   0xc00aa000,   0x0c03f240, 
+   0x00000000,   0x00001010,   0x000044f4,   0x00000c00, 
+   0xaa0000f0,   0x0f0000b0,   0x00005005,   0x0f5f0000, 
+   0x0001f000,   0x0000ff00,   0x00000000,   0x0f000000, 
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000, 
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000, 
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0000000, 
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000, 
+   0x00000000,   0x00000000,   0x00055fff,   0xfff00000, 
+   0x00000000,   0x0ff00a00,   0x000f0000,   0x24004000, 
+   0x15400001,   0x40c00003,   0x3da00000,   0x0002a800, 
+   0x00ff0000,   0x00000000,   0x6fff0000,   0x00000000, 
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch_taken image  FROM PTKN.IDF (Image 4)
+ *
+ * ctr0: mispredicted branches
+ * ctr1: predicted taken branches, actually taken
+ * ctr2: predicted taken branches (includes nullfied)
+ * ctr3: all branches
+ */
+
+   {
+   0xcc01e000,   0x00000000,   0x00000000,   0x00000000, 
+   0xa08080a0,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfffffeff,   0xfffeffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x0f0fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch_nottaken  FROM PNTKN.IDF (Image 5)
+ *
+ * ctr0: mispredicted branches
+ * ctr1: branches predicted not-taken, but actually taken
+ * ctr2: branches predicted not-taken (includes nullified)
+ * ctr3: all branches
+ */
+   {
+   0xcc01e000,   0x00000000,   0x00000000,   0x00000000, 
+   0xe0c0c0e0,   0xffffffff,   0xffffffff,   0xffefffff, 
+   0xffffbfff,   0xfffffeff,   0xfffeffff,   0xfffffeff, 
+   0xfffffffe,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x0f0fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+   
+/* IMISS image (Image 6)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* DMISS image (Image 7)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* dmiss_access image    FROM DMISS_RATIO.IDF  (Image 8)
+ * 
+ * ctr0 : all loads and stores that retire (even lines)
+ * ctr1 : all loads and stores that retire (odd lines)
+ * ctr2 : dcache misses of retired loads/stores
+ * ctr3 : all READ_PRIV and READ_SHAR_OR_PRIV on Runway
+ *        (Speculative and Non-Speculative)
+ */
+   {
+   0x2d81e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x10101010,   0x00ffffff,   0xa003ffff,   0xfe800fff, 
+   0xfffa003f,   0xffffe8ff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd2280a00,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000005,   0x555ff900, 
+   0x80200000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x00005555,   0xff80bf8b,   0xab030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x15153fe0,   0x27628880, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000001, 
+   0x5557fc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00110000,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xf8ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+
+/* big_cpi image  (Image 9)
+ * 
+ * ctr0 : Total number of CPU clock cycles. 
+ * ctr1 : Unused 
+ * ctr2 : Unused
+ * ctr3 : Total number of Non-Nullified instructions retired. 
+ */
+   {
+   0x0c00c000,   0x00000000,   0x00060000,   0x00000000,
+   0xe7e7e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xfff00000,   0x07ffff00,   0x07ffffff,   0x6007ffff,
+   0xa00007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0x603001c1,   0xe0000001,   0xc0c00000,   0x00000fff,
+   0xff00000f,   0xffff0000,   0x00000000,   0x00400000,
+   0x00001000,   0x00000004,   0x00000000,   0x01000000,
+   0x0000ffff,   0xfffffff0,   0x00000000,   0x0fffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00550005,   0x00220000,
+   0x0000000c,   0x71f00000,   0x00f00aa0,   0x0aaff000,
+   0x00005002,   0x20000000,   0x0000c413,   0x00000c0f,
+   0x00aa0000,   0xff00b600,   0x000500a0,   0x00000300,
+   0x000cc3f0,   0x0000c0f0,   0x0aa0000f,   0xff000000,
+   0x011000a0,   0x05503000,   0x00d03700,   0x00000f00,
+   0xaa005500,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0xf000aa00,
+   0x11000a00,   0x55000000,   0x0d037000,   0x00c0f00a,
+   0xa0055000,   0x0db00005,   0x5002a000,   0x00300000,
+   0xf40f0000,   0x0c0f00aa,   0x0000ff10,   0x27400000,
+   0x00008000,   0x00c00003,   0x037c0000,   0x003c02a8,
+   0x02abfc00,   0x00000000,   0x6fff0000,   0x00000000,
+   0x60000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* big_ls image  (Image 10)
+ * 
+ * ctr0 : Total number of CPU clock cycles during which local_stall_A1 is asserted 
+ * ctr1 : Overflow of Counter 0 
+ * ctr2 : Total number of IFLUSH_AV 
+ * ctr3 : Overflow of Counter 2 
+ */
+   {
+   0x0c000000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x28880001,   0x54000000,
+   0x00000004,   0xb6200000,   0x000aaaa0,   0x05555288,
+   0x80000010,   0x00000000,   0x0000486e,   0x00000000,
+   0xaaaa0055,   0x55002888,   0x00545401,   0x03030000,
+   0x0007b000,   0x0000ff00,   0x00000000,   0x05000000,
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00000000,
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0xa0000000,   0x00055fff,   0xfff00000,
+   0x00aa0000,   0x05502a2a,   0x00151500,   0x0a220015,
+   0x40400000,   0x00000001,   0xe2980000,   0x0002aaa8,
+   0x01555400,   0x00000000,   0x0df70000,   0x00000000,
+   0x00000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* br_abort image  (Image 12)
+ * 
+ * ctr0 : Total number of BRAD_STALLH
+ * ctr1 : Total number of ONE_QUAD
+ * ctr2 : Total number of BR0_ABRT
+ * ctr3 : Total number of BR1_ABRT
+ */
+
+   {
+   0x0c002000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0xffffffff,   0xffffffff,   0xff0fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x1077ffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x551b0000,   0x00000000,
+   0x0000000c,   0xd4f00000,   0x00000000,   0x0ffff001,
+   0xb0000000,   0x00000000,   0x0000fd4c,   0x00000000,
+   0x000000ff,   0xff00ff1b,   0x00000000,   0x00000000,
+   0x0000d000,   0x0000ff00,   0x00000000,   0x0e0fffff,
+   0xffffffff,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0xffffffff,   0xffffffff,   0xfff00000,
+   0x00400000,   0x00000000,   0x00ffff00,   0x2a86c000,
+   0x00000000,   0x00000000,   0xf50c0000,   0x00000000,
+   0x03fffc00,   0x00000000,   0x1a250000,   0x00000000,
+   0x10000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffafff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+
+/* isnt image  (Image 13)
+ * 
+ * ctr0 : Total number of cycles for which iside_notrans is asserted. 
+ * ctr1 : Total number of times iside_notrans is asserted for 1-4 cycles. 
+ * ctr2 : Total number of times iside_notrans is asserted for 5-7 cycles. 
+ * ctr3 : Total number of times iside_notrans is asserted for > 7 cycles. 
+ */
+
+   {
+   0x0c018000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xc0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x22000000,   0x000001bc,
+   0x10000006,   0x00900000,   0x50000000,   0x00055a20,
+   0x00000000,   0x00016060,   0x0000c021,   0x00000540,
+   0x00000000,   0x55002200,   0x00000000,   0x56bc4000,
+   0x00048000,   0x0000ff00,   0x00000000,   0x17000000,
+   0x0000055f,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00000000,   0x000055ff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0x00000000,
+   0x000055ff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0x80000000,   0x00015bf3,   0xf5500000,
+   0x02210000,   0x00100000,   0x00005500,   0x08800000,
+   0x00001545,   0x85000001,   0x80240000,   0x11000000,
+   0x00015400,   0x00000000,   0xcdff0000,   0x00000000,
+   0xc0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* quadrant image  (image 14)
+ * 
+ * ctr0 : Total number of instructions in quadrant 0. 
+ * ctr1 : Total number of instructions in quadrant 1. 
+ * ctr2 : Total number of instructions in quadrant 2. 
+ * ctr3 : Total number of instructions in quadrant 3. 
+ *
+ * Only works for 32-bit applications.
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x0007ffff,
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0xf0000000,   0x0fffff00,   0x000fffff,   0x00000fff,
+   0xff00000f,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000040f,   0xfffffffc,   0xff000000,
+   0x0080ffff,   0xffffcff0,   0x0000000c,   0x0fffffff,
+   0xfcff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x551b0000,   0x00000000,
+   0x00000003,   0x17000000,   0x00000000,   0x0ffff001,
+   0xb0000000,   0x00000000,   0x00000173,   0x00000000,
+   0x000000ff,   0xff00ff1b,   0x00000000,   0x00000000,
+   0x000f1ff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xff7f0000,   0x00000000,   0x00fffff0,   0x2a86c000,
+   0x00000000,   0x00000003,   0x05f00000,   0x00000000,
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* rw_pdfet image (Image 15)
+ * 
+ * ctr0 : Total of all READ_PRIV address valid cycles. 
+ * ctr1 : Total of all READ_PRIV data valid cycles. 
+ * ctr2 : Overflow of Counter 0. 
+ * ctr3 : Overflow of Counter 1. 
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00001b00,   0xaa000000,
+   0x00000001,   0x30700000,   0x00055aaf,   0xf0000000,
+   0x01b00000,   0x00000000,   0x00001037,   0x00000000,
+   0x55aaff00,   0x00c00000,   0x1b55aa00,   0x00000000,
+   0x0001fff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xfff70000,   0x000055aa,   0xff000000,   0x000006d5,
+   0x40000000,   0x00000000,   0x731c0000,   0x000156ab,
+   0xfc000000,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00100000,   0x00000000,
+   0xf8000000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   },
+
+
+/* rw_wdfet image  (Image 16)
+ * 
+ * ctr0 : Counts total number of writeback transactions. 
+ * ctr1 : Total number of data valid Runway cycles. 
+ * ctr2 : Overflow of Counter 0. 
+ * ctr3 : Overflow of Counter 1. 
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xefefefef,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x00001b00,   0xaa000000,
+   0x00000001,   0x30700000,   0x00055aaf,   0xf0000000,
+   0x01b00000,   0x00000000,   0x00001037,   0x00000000,
+   0x55aaff00,   0x00c00000,   0x1b55aa00,   0x00000000,
+   0x0001fff0,   0xcfffff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xffffffff,   0x30ffff0c,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xfffffff3,
+   0x0ffff0cf,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffffffff,   0xfffffff3,   0x0ffff0cf,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffff30,
+   0xfff70000,   0x000055aa,   0xff000000,   0x000006d5,
+   0x40000000,   0x00000000,   0x731c0000,   0x000156ab,
+   0xfc000000,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00100000,   0x00000000,
+   0x98000000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffffff,
+   },
+
+/* shlib_cpi image  (Image 17)
+ * 
+ * ctr0 : Total number of instructions in quadrant 0. 
+ * ctr1 : Total number of CPU clock cycles in quadrant 0. 
+ * ctr2 : Total number of Non-Nullified instructions retired. 
+ * ctr3 : Total number of CPU clock cycles. 
+ *
+ * Only works for 32-bit shared libraries.
+ */
+
+   {
+   0x0c01e000,   0x00000000,   0x00060000,   0x00000000,
+   0xe0e0e0e0,   0x00001fff,   0xfc00007f,   0xfff00001,
+   0xffffc000,   0x07ffff00,   0x07ffffff,   0x0007ffff,
+   0xff0007ff,   0xffff0007,   0xffffff00,   0x00000000,
+   0xf0150000,   0x0fffff00,   0x000fffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ffffff,
+   0xffcff000,   0x0000000f,   0xfffffffc,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0x27000000,   0x00000055,
+   0x02000005,   0x7f500000,   0xc0000000,   0x000ff270,
+   0x00000000,   0x00000000,   0x00007700,   0x00000ff0,
+   0x00000000,   0x0000ffff,   0xffffffff,   0xffffff00,
+   0x00000000,   0x0000ff00,   0x00000000,   0x0f0fffff,
+   0xffffffff,   0xfffff000,   0x00000000,   0x000ff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x00ff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x00ff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xfff00000,
+   0x00000000,   0x0ff00000,   0x000000a0,   0x3fffffff,
+   0xffffffff,   0xffc00000,   0x03d40000,   0x20000000,
+   0x0003fc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff7fbfc,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff7fbfc,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00030000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* flop image  (Image 18)
+ * 
+ * ctr0 : Total number of floating point instructions (opcode = 0xc). 
+ * ctr1 : Total number of floating point instructions (opcode = 0xe, 0x6, 0x2e, 0x26). 
+ * ctr2 : Unused
+ * ctr3 : Unused 
+ */
+
+   {
+   0x0001e000,   0x00000000,   0x00000000,   0x00000000,
+   0x00001010,   0x33ffffff,   0x006fffff,   0xfc5fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000,
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900,
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000,
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000,
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff,
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000,
+   0x00000000,   0x00000002,   0x67840000,   0x00000000,
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000,
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* cachemiss image    FROM I_D_MISSES.IDF  (Image 19)
+ *
+ * ctr0 : icache misses for retired instructions
+ * ctr1 : total cycles
+ * ctr2 : dcache misses for retired instructions
+ * ctr3 : number of retired instructions
+ */
+   {
+   0x2801e000,   0x00000000,   0x00010000,   0x00000000, 
+   0x00001000,   0xffffffff,   0xffffffff,   0xfff00fff, 
+   0xfffa3fff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf0ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xf2fdf0f0,   0xf0f0f0f0, 
+   0xffffffff,   0xf6c00000,   0x00000000,   0x0ff55800, 
+   0x90000000,   0x00000000,   0x0000b0ff,   0xfffffff0, 
+   0x00000003,   0x0100bfff,   0x3f3f3f3f,   0x3f3f5555, 
+   0x555fffff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xfff00000,   0x000301b0,   0x2fefcfcf, 
+   0xcfcfcfcf,   0xd5555557,   0xf7b40000,   0x00000000, 
+   0x03c14000,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* branch   FROM br_report3.idf 
+ *
+ * ctr0 : Total number of mispredicted branches. 
+ * ctr1 : Some Non-Nullified unpredictable branches. 
+ * ctr2 : Total number of branches (Nullified + Non-Nullified)
+ *        (Unpredicted+ Predicted Taken +Predicted Not Taken). 
+ *	  Total of All Branches.
+ * ctr3 : Remaining Non-Nullified unpredictable branches.
+ */
+   {
+   0x4001e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0xffffffff,   0xff9fffff,   0xfe0fffff, 
+   0xffffbaff,   0xfdffc0ff,   0xfffdffff,   0xfffffeff, 
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf4ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* crstack  FROM crs_report.idf
+ *
+ * ctr0: correctly predicted branches by the pop_latch
+ * ctr1: some procedure returns
+ * ctr2: all branches, (includes nullified)
+ * ctr3: remaining procedure returns
+ */
+   {
+   0x4001e000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0xffffffff,   0xffa10300,   0x000fffff, 
+   0xffffbaf8,   0x3000007f,   0xffffffff,   0xfffffeff, 
+   0xff7fffff,   0xffffffff,   0xffffff00,   0x00000000, 
+   0xf2ffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000, 
+   0x00000000,   0x00000000,   0xd22d0000,   0x00000000, 
+   0x0000000b,   0x46000000,   0x00000000,   0x0ffff900, 
+   0x90000000,   0x00000000,   0x0000907e,   0x00000000, 
+   0x000000ff,   0xff00bfdf,   0x03030303,   0x03030000, 
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000, 
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffff0000,   0x00000000,   0xf0ffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000, 
+   0x00000000,   0x0fffffff,   0xffffffff,   0xffffffff, 
+   0xffff5555,   0x55500000,   0x003f3ff0,   0x2766c000, 
+   0x00000000,   0x00000002,   0x67840000,   0x00000000, 
+   0x03fffc00,   0x00000000,   0xffff0000,   0x00000000, 
+   0xf0000000,   0x00000000,   0x00ffffff,   0xff3fffff, 
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000, 
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff, 
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f, 
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc, 
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff, 
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff, 
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   },
+
+/* icache_report image 
+ * 
+ * ctr0 : Icache misses actually used by the core. 
+ * ctr1 : ICORE_AV (Icache misses the core THINKS it needs, including fetching down speculative paths). 
+ * ctr2 : READs on Runway (Icache misses that made it out to Runway, including
+ *	  prefetches).
+ * ctr3 : Prefetch returns (1x and 2x). 
+ */
+   {
+   0x00000000,   0x00000000,   0x00010000,   0x00000000,
+   0x00000000,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffff00,   0x00000000,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffff0000,   0x00000000,   0x00000000,   0x00000000,
+   0x00000000,   0x00000000,   0xd2002d00,   0x00000000,
+   0x0000000b,   0x46000000,   0x0000000f,   0xf00ff900,
+   0x00900000,   0x00000000,   0x0000907e,   0x00000000,
+   0x0000ff00,   0xff83bf03,   0xdf030303,   0x03030000,
+   0x000dbfff,   0xffffff00,   0x00000000,   0x000fffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xfffff000,
+   0x00000000,   0x00ffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffff0000,   0x00000000,   0x80ffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffff0000,
+   0x00000000,   0x4fffffff,   0xffffffff,   0xffffffff,
+   0xffff5555,   0x55500000,   0x3f003f80,   0x274026c0,
+   0x00000000,   0x00000002,   0x67840000,   0x00000003,
+   0xfc03fc00,   0x00000000,   0x0eff0000,   0x00000000,
+   0x00000000,   0x00000000,   0x00ffffff,   0xff3fffff,
+   0xffffffff,   0xffcfffff,   0xfff6fb7c,   0x00000000,
+   0x00ffffff,   0xff3fffff,   0xffffffff,   0xffcfffff,
+   0xfff6fb7c,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffff0fff,   0xffffff3f,
+   0xffffffff,   0xffffff7f,   0xffffffff,   0xfffffefc,
+   0x00000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0xffffffff,   0xfffff9ff,
+   0xfe000000,   0x00000000,   0x00130000,   0x00000000,
+   0xd0ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0x00ffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   0xffffffff,   0xffffffff,   0xffffffff,   0xffffffff,
+   
+   }
+
+};
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/power.c linux-2.4.20/arch/parisc/kernel/power.c
--- linux-2.4.19/arch/parisc/kernel/power.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/power.c	2002-10-04 00:41:12.000000000 +0000
@@ -0,0 +1,377 @@
+/*
+ * linux/arch/parisc/kernel/power.c
+ * HP PARISC soft power switch support driver
+ *
+ * Copyright (c) 2001-2002 Helge Deller <deller@gmx.de>
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ *
+ * 
+ *  HINT:
+ *  Support of the soft power switch button may be enabled or disabled at
+ *  runtime through the "/proc/sys/kernel/power" procfs entry.
+ */ 
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+
+#include <asm/gsc.h>
+#include <asm/pdc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/led.h>
+#include <asm/led.h>
+#include <asm/uaccess.h>
+
+
+#ifdef DEBUG
+# define DPRINTK(x) printk x
+#else
+# define DPRINTK(x) do { } while (0)
+#endif
+
+
+/* filename in /proc which can be used to enable/disable the power switch */
+#define SYSCTL_FILENAME		"sys/kernel/power"
+
+
+#define DIAG_CODE(code)		(0x14000000 + ((code)<<5))
+
+/* this will go to processor.h or any other place... */
+/* taken from PCXL ERS page 82 */
+#define MFCPU_X(rDiagReg, t_ch, t_th, code) \
+	(DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
+	
+#define MTCPU(dr, gr)		MFCPU_X(dr, gr,  0, 0x12)       /* move value of gr to dr[dr] */
+#define MFCPU_C(dr, gr)		MFCPU_X(dr, gr,  0, 0x30)	/* for dr0 and dr8 only ! */
+#define MFCPU_T(dr, gr)		MFCPU_X(dr,  0, gr, 0xa0)	/* all dr except dr0 and dr8 */
+	
+#define __getDIAG(dr) ( { 			\
+        register unsigned long __res asm("r28");\
+	 __asm__ __volatile__ (			\
+		".word %1\n nop\n" : "=&r" (__res) : "i" (MFCPU_T(dr,28)) \
+	);					\
+	__res;					\
+} )
+
+
+static void deferred_poweroff(void *dummy)
+{
+	extern int cad_pid;	/* from kernel/sys.c */
+	if (kill_proc(cad_pid, SIGINT, 1)) {
+		/* just in case killing init process failed */
+		machine_power_off();
+	}
+}
+
+/*
+ * This function gets called from interrupt context.
+ * As it's called within an interrupt, it wouldn't sync if we don't
+ * use schedule_task().
+ */
+
+static void poweroff(void)
+{
+	static int powering_off;
+	static struct tq_struct poweroff_tq = {
+		routine: deferred_poweroff,
+	};
+
+	if (powering_off)
+		return;
+
+	powering_off++;
+	schedule_task(&poweroff_tq);
+}
+
+
+/* local time-counter for shutdown */
+static int shutdown_timer;
+
+/* check, give feedback and start shutdown after one second */
+static void process_shutdown(void)
+{
+	if (shutdown_timer == 0)
+		DPRINTK((KERN_INFO "Shutdown requested...\n"));
+
+	shutdown_timer++;
+	
+	/* wait until the button was pressed for 1 second */
+	if (shutdown_timer == HZ) {
+		static char msg[] = "Shutting down...";
+		DPRINTK((KERN_INFO "%s\n", msg));
+#ifdef CONFIG_CHASSIS_LCD_LED
+		lcd_print(msg);
+#endif
+		poweroff();
+	}
+}
+
+
+/* main power switch tasklet struct (scheduled from time.c) */
+DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
+
+/* soft power switch enabled/disabled */
+#ifdef CONFIG_PROC_FS
+static int pwrsw_enabled = 1;
+#else
+#define pwrsw_enabled (1)
+#endif
+
+/*
+ * On gecko style machines (e.g. 712/xx and 715/xx) 
+ * the power switch status is stored in Bit 0 ("the highest bit")
+ * of CPU diagnose register 25.
+ * 
+ */
+static void gecko_tasklet_func(unsigned long unused)
+{
+	if (!pwrsw_enabled)
+		return;
+
+	if (__getDIAG(25) & 0x80000000) {
+		/* power switch button not pressed or released again */
+		/* Warning: Some machines do never reset this DIAG flag! */
+		shutdown_timer = 0;
+	} else {
+		process_shutdown();
+	}
+}
+
+
+
+/*
+ * Check the power switch status which is read from the
+ * real I/O location at soft_power_reg.
+ * Bit 31 ("the lowest bit) is the status of the power switch.
+ */
+
+static void polling_tasklet_func(unsigned long soft_power_reg)
+{
+        unsigned long current_status;
+	
+	if (!pwrsw_enabled)
+		return;
+
+	current_status = gsc_readl(soft_power_reg);
+	if (current_status & 0x1) {
+		/* power switch button not pressed */
+		shutdown_timer = 0;
+	} else {
+		process_shutdown();
+	}
+}
+
+
+/*
+ * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2) 
+ */
+#if 0
+static void powerfail_interrupt(int code, void *x, struct pt_regs *regs)
+{
+	printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n");
+	poweroff();
+}
+#endif
+
+
+
+
+/* 
+ * /proc filesystem support 
+ */
+
+#ifdef CONFIG_SYSCTL
+static int power_proc_read(char *page, char **start, off_t off, int count, 
+	int *eof, void *data)
+{
+	char *out = page;
+	int len;
+
+	out += sprintf(out, "Software power switch support: ");
+	out += sprintf(out, pwrsw_enabled ? "enabled (1)" : "disabled (0)" );
+	out += sprintf(out, "\n");
+
+	len = out - page - off;
+	if (len < count) {
+		*eof = 1;
+		if (len <= 0) return 0;
+	} else {
+		len = count;
+	}
+	*start = page + off;
+	return len;
+}
+
+static int power_proc_write(struct file *file, const char *buf, 
+	unsigned long count, void *data)
+{
+	char *cur, lbuf[count];
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	memset(lbuf, 0, count);
+
+	copy_from_user(lbuf, buf, count);
+	cur = lbuf;
+
+	/* skip initial spaces */
+	while (*cur && isspace(*cur))
+		cur++;
+
+	switch (*cur) {
+	case '0':	pwrsw_enabled = 0;
+			break;
+	case '1':	pwrsw_enabled = 1;
+			break;
+	default:	printk(KERN_CRIT "/proc/" SYSCTL_FILENAME 
+					": Parse error: only '0' or '1' allowed!\n");
+			return -EINVAL;
+	} /* switch() */
+
+	return count;
+}
+
+static struct proc_dir_entry *ent;
+
+static void __init power_create_procfs(void)
+{
+	if (!power_tasklet.func)
+		return;
+	
+	ent = create_proc_entry(SYSCTL_FILENAME, S_IFREG|S_IRUGO|S_IWUSR, 0);
+	if (!ent) return;
+	
+	ent->nlink = 1;
+	ent->read_proc = power_proc_read;
+	ent->write_proc = power_proc_write;
+	ent->owner = THIS_MODULE;
+}
+
+static void __exit power_remove_procfs(void)
+{
+	remove_proc_entry(SYSCTL_FILENAME, NULL);
+}
+
+#else
+#define power_create_procfs()	do { } while (0)
+#define power_remove_procfs()	do { } while (0)
+#endif	/* CONFIG_SYSCTL */
+
+
+
+/* parisc_panic_event() is called by the panic handler.
+ * As soon as a panic occurs, our tasklets above will not be
+ * executed any longer. This function then re-enables the 
+ * soft-power switch and allows the user to switch off the system
+ */
+static int parisc_panic_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	/* re-enable the soft-power switch */
+	pdc_soft_power_button(0);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block parisc_panic_block = {
+	notifier_call: parisc_panic_event,
+	priority: INT_MAX,
+};
+
+
+static int __init power_init(void)
+{
+	unsigned long ret;
+	unsigned long soft_power_reg = 0;
+
+#if 0
+	request_irq( IRQ_FROM_REGION(CPU_IRQ_REGION)+2, &powerfail_interrupt,
+		0, "powerfail", NULL);
+#endif
+
+	/* enable the soft power switch if possible */
+	ret = pdc_soft_power_info(&soft_power_reg);
+	if (ret == PDC_OK)
+		ret = pdc_soft_power_button(1);
+	if (ret != PDC_OK)
+		soft_power_reg = -1UL;
+	
+	switch (soft_power_reg) {
+	case 0:		printk(KERN_INFO "Gecko-style soft power switch enabled.\n");
+			power_tasklet.func = gecko_tasklet_func;
+			break;
+			
+	case -1UL:	printk(KERN_INFO "Soft power switch support not available.\n");
+			return -ENODEV;
+	
+	default:	printk(KERN_INFO "Soft power switch enabled, polling @ 0x%08lx.\n",
+				soft_power_reg);
+			power_tasklet.data = soft_power_reg;
+			power_tasklet.func = polling_tasklet_func;
+	}
+
+	/* Register a call for panic conditions. */
+	notifier_chain_register(&panic_notifier_list, &parisc_panic_block);
+
+	power_create_procfs();
+	tasklet_enable(&power_tasklet);
+
+	return 0;
+}
+
+static void __exit power_exit(void)
+{
+	if (!power_tasklet.func)
+		return;
+
+	tasklet_disable(&power_tasklet);
+	notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block);
+	power_remove_procfs();
+	power_tasklet.func = NULL;
+	pdc_soft_power_button(0);
+}
+
+module_init(power_init);
+module_exit(power_exit);
+
+
+MODULE_AUTHOR("Helge Deller");
+MODULE_DESCRIPTION("Soft power switch driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+
+EXPORT_NO_SYMBOLS;
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/process.c linux-2.4.20/arch/parisc/kernel/process.c
--- linux-2.4.19/arch/parisc/kernel/process.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/process.c	2002-10-04 00:41:30.000000000 +0000
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/elf.h>
+#include <linux/personality.h>
 
 #include <asm/machdep.h>
 #include <asm/offset.h>
@@ -36,19 +37,12 @@
 #include <asm/gsc.h>
 #include <asm/processor.h>
 
-spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED;
+int hlt_counter;
 
-#ifdef __LP64__
-/* The 64-bit code should work equally well in 32-bit land but I didn't
- * want to take the time to confirm that.  -PB
- */
-extern unsigned int ret_from_kernel_thread;
-#else
-asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
-#endif
-
-
-int hlt_counter=0;
+/*
+ * Power off function, if any
+ */ 
+void (*pm_power_off)(void);
 
 void disable_hlt(void)
 {
@@ -81,35 +75,86 @@
 	}
 }
 
-void __init reboot_setup(char *str, int *ints)
-{
-}
 
-struct notifier_block *mach_notifier;
+#ifdef __LP64__
+#define COMMAND_GLOBAL  0xfffffffffffe0030UL
+#else
+#define COMMAND_GLOBAL  0xfffe0030
+#endif
+
+#define CMD_RESET       5       /* reset any module */
 
-void machine_restart(char *ptr)
+/*
+** The Wright Brothers and Gecko systems have a H/W problem
+** (Lasi...'nuf said) may cause a broadcast reset to lockup
+** the system. An HVERSION dependent PDC call was developed
+** to perform a "safe", platform specific broadcast reset instead
+** of kludging up all the code.
+**
+** Older machines which do not implement PDC_BROADCAST_RESET will
+** return (with an error) and the regular broadcast reset can be
+** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
+** the PDC call will not return (the system will be reset).
+*/
+void machine_restart(char *cmd)
 {
-	notifier_call_chain(&mach_notifier, MACH_RESTART, ptr);
+#ifdef FASTBOOT_SELFTEST_SUPPORT
+	/*
+	 ** If user has modified the Firmware Selftest Bitmap,
+	 ** run the tests specified in the bitmap after the
+	 ** system is rebooted w/PDC_DO_RESET.
+	 **
+	 ** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
+	 **
+	 ** Using "directed resets" at each processor with the MEM_TOC
+	 ** vector cleared will also avoid running destructive
+	 ** memory self tests. (Not implemented yet)
+	 */
+	if (ftc_bitmap) {
+		pdc_do_firm_test_reset(ftc_bitmap);
+	}
+#endif
+
+	/* "Normal" system reset */
+	pdc_do_reset();
+
+	/* Nope...box should reset with just CMD_RESET now */
+	gsc_writel(CMD_RESET, COMMAND_GLOBAL);
+
+	/* Wait for RESET to lay us to rest. */
+	while (1) ;
+
 }
 
 void machine_halt(void)
 {
-	notifier_call_chain(&mach_notifier, MACH_HALT, NULL);
+	/*
+	** The LED/ChassisCodes are updated by the led_halt()
+	** function, called by the reboot notifier chain.
+	*/
 }
 
-void machine_power_on(void)
-{
-	notifier_call_chain(&mach_notifier, MACH_POWER_ON, NULL);
-}
 
+/*
+ * This routine is called from sys_reboot to actually turn off the
+ * machine 
+ */
 void machine_power_off(void)
 {
-	notifier_call_chain(&mach_notifier, MACH_POWER_OFF, NULL);
-}
+	/* If there is a registered power off handler, call it. */
+	if(pm_power_off)
+		pm_power_off();
+
+	/* Put the soft power button back under hardware control.
+	 * If the user had already pressed the power button, the
+	 * following call will immediately power off. */
+	pdc_soft_power_button(0);
 
+	/* It seems we have no way to power the system off via
+	 * software. The user has to press the button himself. */
 
-void machine_heartbeat(void)
-{
+	printk(KERN_EMERG "System shut down completed.\n"
+	       KERN_EMERG "Please power this system off now.");
 }
 
 
@@ -138,6 +183,9 @@
 
 void flush_thread(void)
 {
+	/* Only needs to handle fpu stuff or perf monitors.
+	** REVISIT: several arches implement a "lazy fpu state".
+	*/
 	set_fs(USER_DS);
 }
 
@@ -148,6 +196,7 @@
 /*
  * Fill in the FPU structure for a core dump.
  */
+
 int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
 {
 	memcpy(r, regs->fr, sizeof *r);
@@ -176,7 +225,13 @@
 	    struct task_struct * p, struct pt_regs * pregs)
 {
 	struct pt_regs * cregs = &(p->thread.regs);
-	long ksp;
+	
+	/* We have to use void * instead of a function pointer, because
+	 * function pointers aren't a pointer to the function on 64-bit.
+	 * Make them const so the compiler knows they live in .text */
+	extern void * const ret_from_kernel_thread;
+	extern void * const child_return;
+	extern void * const hpux_child_return;
 
 	*cregs = *pregs;
 
@@ -193,34 +248,37 @@
 	 * in zero for usp.
 	 */
 	if (usp == 0) {
-		/* Kernel Thread */
-		ksp = (((unsigned long)(p)) + TASK_SZ_ALGN);
-		cregs->ksp = ksp;	    /* always return to kernel */
-#ifdef __LP64__
+		/* kernel thread */
+		cregs->ksp = (((unsigned long)(p)) + TASK_SZ_ALGN);
+		/* Must exit via ret_from_kernel_thread in order
+		 * to call schedule_tail()
+		 */
 		cregs->kpc = (unsigned long) &ret_from_kernel_thread;
-#else
-		cregs->kpc = (unsigned long) ret_from_kernel_thread;
-#endif
-
 		/*
 		 * Copy function and argument to be called from
 		 * ret_from_kernel_thread.
 		 */
+#ifdef __LP64__
+		cregs->gr[27] = pregs->gr[27];
+#endif
 		cregs->gr[26] = pregs->gr[26];
 		cregs->gr[25] = pregs->gr[25];
-
 	} else {
-		/* User Thread:
-		 *
-		 * Use same stack depth as parent when in wrapper
-		 *
+		/* user thread */
+		/*
 		 * Note that the fork wrappers are responsible
-		 * for setting gr[20] and gr[21].
+		 * for setting gr[21].
 		 */
 
+		/* Use same stack depth as parent */
 		cregs->ksp = ((unsigned long)(p))
-			+ (pregs->gr[20] & (INIT_TASK_SIZE - 1));
-		cregs->kpc = pregs->gr[21];
+			+ (pregs->gr[21] & (INIT_TASK_SIZE - 1));
+		cregs->gr[30] = usp;
+		if (p->personality == PER_HPUX) {
+			cregs->kpc = (unsigned long) &hpux_child_return;
+		} else {
+			cregs->kpc = (unsigned long) &child_return;
+		}
 	}
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/processor.c linux-2.4.20/arch/parisc/kernel/processor.c
--- linux-2.4.19/arch/parisc/kernel/processor.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/processor.c	2002-10-04 00:41:11.000000000 +0000
@@ -0,0 +1,374 @@
+/*    $Id: processor.c,v 1.13 2002/07/04 19:33:01 grundler Exp $
+ *
+ *    Initial setup-routines for HP 9000 based hardware.
+ *
+ *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *    Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
+ *    Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
+ *    Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
+ *    Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *    Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
+ *
+ *    Initial PA-RISC Version: 04-23-1999 by Helge Deller
+ *
+ *    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, 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.
+ *
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#define PCI_DEBUG
+#include <linux/pci.h>
+#undef PCI_DEBUG
+
+#include <asm/cache.h>
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/pdc.h>
+#include <asm/irq.h>		/* for struct irq_region */
+
+struct system_cpuinfo_parisc boot_cpu_data;
+struct cpuinfo_parisc cpu_data[NR_CPUS];
+
+/*
+**  	PARISC CPU driver - claim "device" and initialize CPU data structures.
+**
+** Consolidate per CPU initialization into (mostly) one module.
+** Monarch CPU will initialize boot_cpu_data which shouldn't
+** change once the system has booted.
+**
+** The callback *should* do per-instance initialization of
+** everything including the monarch. "Per CPU" init code in
+** setup.c:start_parisc() has migrated here and start_parisc()
+** will call register_parisc_driver(&cpu_driver) before calling do_inventory().
+**
+** The goal of consolidating CPU initialization into one place is
+** to make sure all CPU's get initialized the same way.
+** The code path not shared is how PDC hands control of the CPU to the OS.
+** The initialization of OS data structures is the same (done below).
+*/
+
+/**
+ * processor_probe - Determine if processor driver should claim this device.
+ * @dev: The device which has been found.
+ *
+ * Determine if processor driver should claim this chip (return 0) or not 
+ * (return 1).  If so, initialize the chip and tell other partners in crime 
+ * they have work to do.
+ */
+static int __init processor_probe(struct parisc_device *dev)
+{
+	unsigned long txn_addr;
+	unsigned long cpuid;
+	struct cpuinfo_parisc *p;
+
+#ifndef CONFIG_SMP
+	if (boot_cpu_data.cpu_count > 0) {
+		printk(KERN_INFO "CONFIG_SMP=n  ignoring additional CPUs\n");
+		return 1;
+	}
+#endif
+
+	/* logical CPU ID and update global counter
+	 * May get overwritten by PAT code.
+	 */
+	cpuid = boot_cpu_data.cpu_count;
+	txn_addr = dev->hpa;	/* for legacy PDC */
+
+#ifdef __LP64__
+	if (is_pdc_pat()) {
+		ulong status;
+		unsigned long bytecnt;
+	        pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
+#undef USE_PAT_CPUID
+#ifdef USE_PAT_CPUID
+		struct pdc_pat_cpu_num cpu_info;
+#endif
+
+		status = pdc_pat_cell_module(&bytecnt, dev->pcell_loc,
+			dev->mod_index, PA_VIEW, &pa_pdc_cell);
+
+		ASSERT(PDC_OK == status);
+
+		/* verify it's the same as what do_pat_inventory() found */
+		ASSERT(dev->mod_info == pa_pdc_cell.mod_info);
+		ASSERT(dev->pmod_loc == pa_pdc_cell.mod_location);
+
+		txn_addr = pa_pdc_cell.mod[0];   /* id_eid for IO sapic */
+
+#ifdef USE_PAT_CPUID
+/* We need contiguous numbers for cpuid. Firmware's notion
+ * of cpuid is for physical CPUs and we just don't care yet.
+ * We'll care when we need to query PAT PDC about a CPU *after*
+ * boot time (ie shutdown a CPU from an OS perspective).
+ */
+		/* get the cpu number */
+		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa);
+
+		ASSERT(PDC_OK == status);
+
+		if (cpu_info.cpu_num >= NR_CPUS) {
+			printk(KERN_WARNING "IGNORING CPU at 0x%x,"
+				" cpu_slot_id > NR_CPUS"
+				" (%ld > %d)\n",
+				dev->hpa, cpu_info.cpu_num, NR_CPUS);
+			/* Ignore CPU since it will only crash */
+			boot_cpu_data.cpu_count--;
+			return 1;
+		} else {
+			cpuid = cpu_info.cpu_num;
+		}
+#endif
+	}
+#endif
+
+	p = &cpu_data[cpuid];
+	boot_cpu_data.cpu_count++;
+
+	/* initialize counters */
+	memset(p, 0, sizeof(struct cpuinfo_parisc));
+
+	p->dev = dev;		/* Save IODC data in case we need it */
+	p->hpa = dev->hpa;	/* save CPU hpa */
+	p->cpuid = cpuid;	/* save CPU id */
+	p->txn_addr = txn_addr;	/* save CPU IRQ address */
+#ifdef CONFIG_SMP
+	p->lock = SPIN_LOCK_UNLOCKED;
+
+	/*
+	** FIXME: review if any other initialization is clobbered
+	**	for boot_cpu by the above memset().
+	*/
+
+	/* stolen from init_percpu_prof() */
+	cpu_data[cpuid].prof_counter = 1;
+	cpu_data[cpuid].prof_multiplier = 1;
+#endif
+
+	/*
+	** CONFIG_SMP: init_smp_config() will attempt to get CPU's into
+	** OS control. RENDEZVOUS is the default state - see mem_set above.
+	**	p->state = STATE_RENDEZVOUS;
+	*/
+
+	/*
+	** itimer and ipi IRQ handlers are statically initialized in
+	** arch/parisc/kernel/irq.c. ie Don't need to register them.
+	*/
+	p->region = irq_region[IRQ_FROM_REGION(CPU_IRQ_REGION)];
+
+	return 0;
+}
+
+/**
+ * collect_boot_cpu_data - Fill the boot_cpu_data structure.
+ *
+ * This function collects and stores the generic processor information
+ * in the boot_cpu_data structure.
+ */
+void __init collect_boot_cpu_data(void)
+{
+	memset(&boot_cpu_data, 0, sizeof(boot_cpu_data));
+
+	boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
+
+	/* get CPU-Model Information... */
+#define p ((unsigned long *)&boot_cpu_data.pdc.model)
+	if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK)
+		printk(KERN_INFO 
+			"model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
+#undef p
+
+	if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK)
+		printk(KERN_INFO "vers  %08lx\n", 
+			boot_cpu_data.pdc.versions);
+
+	if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK)
+		printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n",
+			(boot_cpu_data.pdc.cpuid >> 5) & 127,
+			boot_cpu_data.pdc.cpuid & 31,
+			boot_cpu_data.pdc.cpuid);
+
+	if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK)
+		printk(KERN_INFO "capabilities 0x%lx\n",
+			boot_cpu_data.pdc.capabilities);
+
+	if (pdc_model_sysmodel(boot_cpu_data.pdc.sys_model_name) == PDC_OK)
+		printk(KERN_INFO "model %s\n",
+			boot_cpu_data.pdc.sys_model_name);
+
+	boot_cpu_data.hversion =  boot_cpu_data.pdc.model.hversion;
+	boot_cpu_data.sversion =  boot_cpu_data.pdc.model.sversion;
+
+	boot_cpu_data.cpu_type =
+			parisc_get_cpu_type(boot_cpu_data.hversion);
+
+	boot_cpu_data.cpu_name = cpu_name_version[boot_cpu_data.cpu_type][0];
+	boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
+}
+
+
+/**
+ * init_cpu_profiler - enable/setup per cpu profiling hooks.
+ * @cpunum: The processor instance.
+ *
+ * FIXME: doesn't do much yet...
+ */
+static inline void __init
+init_percpu_prof(int cpunum)
+{
+	cpu_data[cpunum].prof_counter = 1;
+	cpu_data[cpunum].prof_multiplier = 1;
+}
+
+
+/**
+ * init_per_cpu - Handle individual processor initializations.
+ * @cpunum: logical processor number.
+ *
+ * This function handles initialization for *every* CPU
+ * in the system:
+ *
+ * o Set "default" CPU width for trap handlers
+ *
+ * o Enable FP coprocessor
+ *   REVISIT: this could be done in the "code 22" trap handler.
+ *	(frowands idea - that way we know which processes need FP
+ *	registers saved on the interrupt stack.)
+ *   NEWS FLASH: wide kernels need FP coprocessor enabled to handle
+ *	formatted printing of %lx for example (double divides I think)
+ *
+ * o Enable CPU profiling hooks.
+ */
+int __init init_per_cpu(int cpunum)
+{
+	int ret;
+	struct pdc_coproc_cfg coproc_cfg;
+
+	ret = pdc_coproc_cfg(&coproc_cfg);
+
+	if(ret >= 0 && coproc_cfg.ccr_functional) {
+		mtctl(coproc_cfg.ccr_functional, 10);  /* 10 == Coprocessor Control Reg */
+
+		/* FWIW, FP rev/model is a more accurate way to determine
+		** CPU type. CPU rev/model has some ambiguous cases.
+		*/
+		cpu_data[cpunum].fp_rev = coproc_cfg.revision;
+		cpu_data[cpunum].fp_model = coproc_cfg.model;
+
+		printk(KERN_INFO  "FP[%d] enabled: Rev %ld Model %ld\n",
+			cpunum, coproc_cfg.revision, coproc_cfg.model);
+
+		/*
+		** store status register to stack (hopefully aligned)
+		** and clear the T-bit.
+		*/
+		asm volatile ("fstd    %fr0,8(%sp)");
+
+	} else {
+		printk(KERN_WARNING  "WARNING: No FP CoProcessor?!"
+			" (coproc_cfg.ccr_functional == 0x%lx, expected 0xc0)\n"
+#ifdef __LP64__
+			"Halting Machine - FP required\n"
+#endif
+			, coproc_cfg.ccr_functional);
+#ifdef __LP64__
+		mdelay(100);	/* previous chars get pushed to console */
+		panic("FP CoProc not reported");
+#endif
+	}
+
+	/* FUTURE: Enable Performance Monitor : ccr bit 0x20 */
+	init_percpu_prof(cpunum);
+
+	return ret;
+}
+
+/*
+ * Display cpu info for all cpu's.
+ */
+int
+show_cpuinfo (struct seq_file *m, void *v)
+{
+	int	n;
+
+	for(n=0; n<boot_cpu_data.cpu_count; n++) {
+#ifdef CONFIG_SMP
+		if (0 == cpu_data[n].hpa)
+			continue;
+#ifdef ENTRY_SYS_CPUS
+#error iCOD support wants to show CPU state here
+#endif
+#endif
+		seq_printf(m, "processor\t: %d\n"
+				"cpu family\t: PA-RISC %s\n",
+				 n, boot_cpu_data.family_name);
+
+		seq_printf(m, "cpu\t\t: %s\n",  boot_cpu_data.cpu_name );
+
+		/* cpu MHz */
+		seq_printf(m, "cpu MHz\t\t: %d.%06d\n",
+				 boot_cpu_data.cpu_hz / 1000000,
+				 boot_cpu_data.cpu_hz % 1000000  );
+
+		seq_printf(m, "model\t\t: %s\n"
+				"model name\t: %s\n",
+				 boot_cpu_data.pdc.sys_model_name,
+				 cpu_data[n].dev ? 
+				 cpu_data[n].dev->name : "Unknown" );
+
+		seq_printf(m, "hversion\t: 0x%08x\n"
+			        "sversion\t: 0x%08x\n",
+				 boot_cpu_data.hversion,
+				 boot_cpu_data.sversion );
+
+		/* print cachesize info */
+		show_cache_info(m);
+
+		seq_printf(m, "bogomips\t: %lu.%02lu\n",
+			     loops_per_jiffy / (500000 / HZ),
+			     (loops_per_jiffy / (5000 / HZ)) % 100);
+
+		seq_printf(m, "software id\t: %ld\n\n",
+				boot_cpu_data.pdc.model.sw_id);
+	}
+	return 0;
+}
+
+static struct parisc_device_id processor_tbl[] = {
+	{ HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID },
+	{ 0, }
+};
+
+static struct parisc_driver cpu_driver = {
+	name:		"CPU",
+	id_table:	processor_tbl,
+	probe:		processor_probe
+};
+
+/**
+ * processor_init - Processor initalization procedure.
+ *
+ * Register this driver.
+ */
+void __init processor_init(void)
+{
+	register_parisc_driver(&cpu_driver);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/ptrace.c linux-2.4.20/arch/parisc/kernel/ptrace.c
--- linux-2.4.19/arch/parisc/kernel/ptrace.c	2001-09-18 23:56:19.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/ptrace.c	2002-10-04 00:41:11.000000000 +0000
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/personality.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -31,6 +32,47 @@
 #define PT_SINGLESTEP	0x10000
 #define PT_BLOCKSTEP	0x20000
 
+/* PSW bits we allow the debugger to modify */
+#define USER_PSW_BITS	(PSW_N | PSW_V | PSW_CB)
+
+#undef DEBUG_PTRACE
+
+#ifdef DEBUG_PTRACE
+#define DBG(x)	printk x
+#else
+#define DBG(x)
+#endif
+
+#ifdef __LP64__
+
+#define CHILD_IS_32BIT	(child->personality == PER_LINUX_32BIT)
+
+/* This function is needed to translate 32 bit pt_regs offsets in to
+ * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
+ * will request offset 12 if it wants gr3, but the lower 32 bits of
+ * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
+ * This code relies on a 32 bit pt_regs being comprised of 32 bit values
+ * except for the fp registers which (a) are 64 bits, and (b) follow
+ * the gr registers at the start of pt_regs.  The 32 bit pt_regs should
+ * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
+ * being 64 bit in both cases.
+ */
+
+static long translate_usr_offset(long offset)
+{
+	if (offset < 0)
+		return -1;
+	else if (offset <= 32*4)	/* gr[0..31] */
+		return offset * 2 + 4;
+	else if (offset <= 32*4+32*8)	/* gr[0..31] + fr[0..31] */
+		return offset + 32*4;
+	else if (offset < sizeof(struct pt_regs)/2 + 32*4)
+		return offset * 2 + 4 - 32*8;
+	else
+		return -1;
+}
+#endif
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -49,6 +91,9 @@
 {
 	struct task_struct *child;
 	long ret;
+#ifdef DEBUG_PTRACE
+	long oaddr=addr, odata=data;
+#endif
 
 	lock_kernel();
 	ret = -EPERM;
@@ -91,14 +136,33 @@
 	switch (request) {
 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
 	case PTRACE_PEEKDATA: {
-		unsigned long tmp;
 		int copied;
 
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		ret = -EIO;
-		if (copied != sizeof(tmp))
-			goto out_tsk;
-		ret = put_user(tmp,(unsigned long *) data);
+#ifdef __LP64__
+		if (CHILD_IS_32BIT) {
+			unsigned int tmp;
+
+			addr &= 0xffffffffL;
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				goto out_tsk;
+			ret = put_user(tmp,(unsigned int *) data);
+			DBG(("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
+				request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
+				pid, oaddr, odata, ret, tmp));
+		}
+		else
+#endif
+		{
+			unsigned long tmp;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				goto out_tsk;
+			ret = put_user(tmp,(unsigned long *) data);
+		}
 		goto out_tsk;
 	}
 
@@ -106,22 +170,53 @@
 	case PTRACE_POKETEXT: /* write the word at location addr. */
 	case PTRACE_POKEDATA:
 		ret = 0;
-		if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
-			goto out_tsk;
+#ifdef __LP64__
+		if (CHILD_IS_32BIT) {
+			unsigned int tmp = (unsigned int)data;
+			DBG(("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
+				request == PTRACE_POKETEXT ? "TEXT" : "DATA",
+				pid, oaddr, odata));
+			addr &= 0xffffffffL;
+			if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
+				goto out_tsk;
+		}
+		else
+#endif
+		{
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				goto out_tsk;
+		}
 		ret = -EIO;
 		goto out_tsk;
 
-	/* Read the word at location addr in the USER area.  This will need
-	   to change when the kernel no longer saves all regs on a syscall. */
+	/* Read the word at location addr in the USER area.  For ptraced
+	   processes, the kernel saves all regs on a syscall. */
 	case PTRACE_PEEKUSR: {
-		unsigned long tmp;
-
 		ret = -EIO;
-		if ((addr & 3) || (unsigned long) addr >= sizeof(struct pt_regs))
-			goto out_tsk;
-
-		tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
-		ret = put_user(tmp, (unsigned long *) data);
+#ifdef __LP64__
+		if (CHILD_IS_32BIT) {
+			unsigned int tmp;
+
+			if (addr & (sizeof(int)-1))
+				goto out_tsk;
+			if ((addr = translate_usr_offset(addr)) < 0)
+				goto out_tsk;
+
+			tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
+			ret = put_user(tmp, (unsigned int *) data);
+			DBG(("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
+				pid, oaddr, odata, ret, addr, tmp));
+		}
+		else
+#endif
+		{
+			unsigned long tmp;
+
+			if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
+				goto out_tsk;
+			tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
+			ret = put_user(tmp, (unsigned long *) data);
+		}
 		goto out_tsk;
 	}
 
@@ -133,25 +228,73 @@
 	   exit. */
 	case PTRACE_POKEUSR:
 		ret = -EIO;
-		if ((addr & 3) || (unsigned long) addr >= sizeof(struct pt_regs))
-			goto out_tsk;
-		/* XXX This test probably needs adjusting.  We probably want to
-		 * allow writes to some bits of PSW, and may want to block writes
-		 * to (some) space registers.  Some register values written here
-		 * may be ignored in entry.S:syscall_restore_rfi; e.g. iaoq is
-		 * written with r31/r31+4, and not with the values in pt_regs.
+		/* Some register values written here may be ignored in
+		 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
+		 * r31/r31+4, and not with the values in pt_regs.
+		 */
+		 /* PT_PSW=0, so this is valid for 32 bit processes under 64
+		 * bit kernels.
 		 */
-		/* Allow writing of gr1-gr31, fr*, sr*, iasq*, iaoq*, sar */
-		if (addr == PT_PSW || (addr > PT_IAOQ1 && addr != PT_SAR))
+		if (addr == PT_PSW) {
+			/* PT_PSW=0, so this is valid for 32 bit processes
+			 * under 64 bit kernels.
+			 *
+			 * Allow writing to Nullify, Divide-step-correction,
+			 * and carry/borrow bits.
+			 * BEWARE, if you set N, and then single step, it wont
+			 * stop on the nullified instruction.
+			 */
+			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
+				pid, oaddr, odata));
+			data &= USER_PSW_BITS;
+			task_regs(child)->gr[0] &= ~USER_PSW_BITS;
+			task_regs(child)->gr[0] |= data;
+			ret = 0;
 			goto out_tsk;
-
-		*(unsigned long *) ((char *) task_regs(child) + addr) = data;
-		ret = 0;
-		goto out_tsk;
+		}
+#ifdef __LP64__
+		if (CHILD_IS_32BIT) {
+			if (addr & (sizeof(int)-1))
+				goto out_tsk;
+			if ((addr = translate_usr_offset(addr)) < 0)
+				goto out_tsk;
+			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
+				pid, oaddr, odata, addr));
+			if (addr >= PT_FR0 && addr <= PT_FR31) {
+				/* Special case, fp regs are 64 bits anyway */
+				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
+				ret = 0;
+			}
+			else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
+					addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
+					addr == PT_SAR+4) {
+				/* Zero the top 32 bits */
+				*(unsigned int *) ((char *) task_regs(child) + addr - 4) = 0;
+				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
+				ret = 0;
+			}
+			goto out_tsk;
+		}
+		else
+#endif
+		{
+			if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
+				goto out_tsk;
+			if ((addr >= PT_GR1 && addr <= PT_GR31) ||
+					addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
+					(addr >= PT_FR0 && addr <= PT_FR31) ||
+					addr == PT_SAR) {
+				*(unsigned long *) ((char *) task_regs(child) + addr) = data;
+				ret = 0;
+			}
+			goto out_tsk;
+		}
 
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT:
 		ret = -EIO;
+		DBG(("sys_ptrace(%s)\n",
+			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"));
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
 		child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
@@ -168,12 +311,14 @@
 		 * sigkill.  perhaps it should be put in the status
 		 * that it wants to exit.
 		 */
+		DBG(("sys_ptrace(KILL)\n"));
 		if (child->state == TASK_ZOMBIE)	/* already dead */
 			goto out_tsk;
 		child->exit_code = SIGKILL;
 		goto out_wake_notrap;
 
 	case PTRACE_SINGLEBLOCK:
+		DBG(("sys_ptrace(SINGLEBLOCK)\n"));
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
@@ -189,6 +334,7 @@
 		goto out_wake;
 
 	case PTRACE_SINGLESTEP:
+		DBG(("sys_ptrace(SINGLESTEP)\n"));
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
@@ -208,10 +354,7 @@
 			pa_psw(child)->y = 0;
 			pa_psw(child)->z = 0;
 			pa_psw(child)->b = 0;
-			pa_psw(child)->r = 0;
-			pa_psw(child)->t = 0;
-			pa_psw(child)->h = 0;
-			pa_psw(child)->l = 0;
+			ptrace_disable(child);
 			/* Don't wake up the child, but let the
 			   parent know something happened. */
 			si.si_code = TRAP_TRACE;
@@ -249,11 +392,7 @@
 	}
 
 out_wake_notrap:
-	/* make sure the trap bits are not set */
-	pa_psw(child)->r = 0;
-	pa_psw(child)->t = 0;
-	pa_psw(child)->h = 0;
-	pa_psw(child)->l = 0;
+	ptrace_disable(child);
 out_wake:
 	wake_up_process(child);
 	ret = 0;
@@ -261,6 +400,8 @@
 	free_task_struct(child);
 out:
 	unlock_kernel();
+	DBG(("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+		request, pid, oaddr, odata, ret));
 	return ret;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/real1.c linux-2.4.20/arch/parisc/kernel/real1.c
--- linux-2.4.19/arch/parisc/kernel/real1.c	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/real1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,154 +0,0 @@
-/*
- *
- * 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) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
- *
- * most of these calls might reasonably be moved to ../kernel -PB
- *
- * The basic principle is to construct a stack frame in C then call
- * some assembly which adopts that stack, does some rfi magic, may
- * switch wide/narrow mode, and calls the routine described by the
- * 'fn' parameter WHICH IS NOT A FUNCTION POINTER!!!!!!!!!!!!!!!!
- */
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <stdarg.h>
-#include <asm/pgtable.h>		/* for __pa() */
-#include <asm/pdc.h>
-
-static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
-
-/***************** 32-bit real-mode calls ***********/
-/* The struct below is used
- * to overlay real_stack (real2.S), preparing a 32-bit call frame.
- * real32_call_asm() then uses this stack in narrow real mode
- */
-
-struct narrow_stack {
-    /* use int, not long which is 64 bits */
-    unsigned int arg13;
-    unsigned int arg12;
-    unsigned int arg11;
-    unsigned int arg10;
-    unsigned int arg9;
-    unsigned int arg8;
-    unsigned int arg7;
-    unsigned int arg6;
-    unsigned int arg5;
-    unsigned int arg4;
-    unsigned int arg3;
-    unsigned int arg2;
-    unsigned int arg1;
-    unsigned int arg0;
-    unsigned int frame_marker[8];
-    unsigned int sp;
-    /* in reality, there's nearly 8k of stack after this */
-};
-
-long
-real32_call(unsigned long fn, ...)
-{
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    extern struct narrow_stack real_stack;
-    extern unsigned long real32_call_asm(unsigned int *,
-				unsigned int *, unsigned int);
-    
-    va_start(args, fn);
-    real_stack.arg0 = va_arg(args, unsigned int);
-    real_stack.arg1 = va_arg(args, unsigned int);
-    real_stack.arg2 = va_arg(args, unsigned int);
-    real_stack.arg3 = va_arg(args, unsigned int);
-    real_stack.arg4 = va_arg(args, unsigned int);
-    real_stack.arg5 = va_arg(args, unsigned int);
-    real_stack.arg6 = va_arg(args, unsigned int);
-    real_stack.arg7 = va_arg(args, unsigned int);
-    real_stack.arg8 = va_arg(args, unsigned int);
-    real_stack.arg9 = va_arg(args, unsigned int);
-    real_stack.arg10 = va_arg(args, unsigned int);
-    real_stack.arg11 = va_arg(args, unsigned int);
-    real_stack.arg12 = va_arg(args, unsigned int);
-    real_stack.arg13 = va_arg(args, unsigned int);
-    va_end(args);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
-}
-
-#ifdef __LP64__
-/***************** 64-bit real-mode calls ***********/
-
-struct wide_stack {
-    unsigned long arg0;
-    unsigned long arg1;
-    unsigned long arg2;
-    unsigned long arg3;
-    unsigned long arg4;
-    unsigned long arg5;
-    unsigned long arg6;
-    unsigned long arg7;
-    unsigned long arg8;
-    unsigned long arg9;
-    unsigned long arg10;
-    unsigned long arg11;
-    unsigned long arg12;
-    unsigned long arg13;
-    unsigned long frame_marker[2];	/* rp, previous sp */
-    unsigned long sp;
-    /* in reality, there's nearly 8k of stack after this */
-};
-
-long
-real64_call(unsigned long fn, ...)
-{
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    extern struct wide_stack real_stack;
-    extern unsigned long real64_call_asm(unsigned long *,
-				unsigned long *, unsigned long);
-    
-    va_start(args, fn);
-    real_stack.arg0 = va_arg(args, unsigned long);
-    real_stack.arg1 = va_arg(args, unsigned long);
-    real_stack.arg2 = va_arg(args, unsigned long);
-    real_stack.arg3 = va_arg(args, unsigned long);
-    real_stack.arg4 = va_arg(args, unsigned long);
-    real_stack.arg5 = va_arg(args, unsigned long);
-    real_stack.arg6 = va_arg(args, unsigned long);
-    real_stack.arg7 = va_arg(args, unsigned long);
-    real_stack.arg8 = va_arg(args, unsigned long);
-    real_stack.arg9 = va_arg(args, unsigned long);
-    real_stack.arg10 = va_arg(args, unsigned long);
-    real_stack.arg11 = va_arg(args, unsigned long);
-    real_stack.arg12 = va_arg(args, unsigned long);
-    real_stack.arg13 = va_arg(args, unsigned long);
-    va_end(args);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc_hi;
-	    fn <<= 32;
-	    fn |= PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
-}
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/real2.S linux-2.4.20/arch/parisc/kernel/real2.S
--- linux-2.4.19/arch/parisc/kernel/real2.S	2000-12-05 20:29:39.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/real2.S	2002-10-04 00:41:20.000000000 +0000
@@ -7,7 +7,6 @@
  * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com)
  *
  */
-#define __ASSEMBLY__
 #include <asm/assembly.h>
 #include <asm/psw.h>
 
@@ -31,8 +30,11 @@
 
 /************************ 32-bit real-mode calls ***********************/
 /* This can be called in both narrow and wide kernels */
+
 	.text
+
 	.export real32_call_asm
+
 	/* unsigned long real32_call_asm(unsigned int *sp,
 	 *		unsigned int *arg0p,
 	 *		unsigned int iodc_fn)
@@ -40,6 +42,7 @@
 	 *	arg0p points to where saved arg values may be found
 	 *	iodc_fn is the IODC function to call
 	 */
+
 real32_call_asm:
 	STREG	%rp, -RP_OFFSET(%sp)	/* save RP */
 #ifdef __LP64__
@@ -61,7 +64,7 @@
 	ldw	-12(%arg1), %arg3
 	ldw	-4(%arg1), %arg1	/* obviously must do this one last! */
 
-	tophys	%sp
+	tophys_r1  %sp
 
 	b,l	rfi_virt2real,%r2
 	nop
@@ -88,7 +91,7 @@
 	b,l	rfi_real2virt,%r2
 	nop
 
-	tovirt	%sp
+	tovirt_r1 %sp
 	LDREG	-REG_SZ(%sp), %sp	/* restore SP */
 #ifdef __LP64__
 	LDREG	-1*REG_SZ(%sp), %r27
@@ -150,14 +153,14 @@
 	nop
 	nop
 	
-	mtsm		0		/* disable interruptions */
+	rsm             (PSW_SM_Q|PSW_SM_I),%r0  /* disable Q & I bits to load iia queue */
 	mtctl		0, %cr17	/* space 0 */
 	mtctl		0, %cr17
 	load32		PA(rfi_v2r_1), %r1
 	mtctl		%r1, %cr18
 	ldo		4(%r1), %r1
 	mtctl		%r1, %cr18
-	load32		PDC_PSW, %r1
+	load32          REAL_MODE_PSW, %r1
 	mtctl		%r1, %cr22
 	rfi
 	
@@ -170,7 +173,7 @@
 	nop
 	nop
 rfi_v2r_1:
-	tophys	%r2
+	tophys_r1 %r2
 	bv	0(%r2)
 	nop
 
@@ -187,7 +190,7 @@
 	nop
 	nop
 	
-	mtsm		0		/* disable interruptions */
+	rsm             PSW_SM_Q,%r0    /* disable Q bit to load iia queue */
 	mtctl		0, %cr17	/* space 0 */
 	mtctl		0, %cr17
 	load32		(rfi_r2v_1), %r1
@@ -207,7 +210,7 @@
 	nop
 	nop
 rfi_r2v_1:
-	tovirt	%r2
+	tovirt_r1 %r2
 	bv	0(%r2)
 	nop
 
@@ -246,7 +249,7 @@
 	ldd	7*REG_SZ(%arg1), %r19
 	ldd	1*REG_SZ(%arg1), %arg1		/* do this one last! */
 
-	tophys	%sp
+	tophys_r1 %sp
 
 	b,l	rfi_virt2real,%r2
 	nop
@@ -265,10 +268,18 @@
 	b,l	rfi_real2virt,%r2
 	nop
 
-	tovirt	%sp
+	tovirt_r1 %sp
 	ldd	-8(%sp), %sp		/* restore SP */
 	ldd	-0x10(%sp), %rp		/* restore RP */
 	bv	0(%rp)
 	nop
 
 #endif
+	.export pc_in_user_space
+	.text
+	/* Doesn't belong here but I couldn't find a nicer spot. */
+	/* Should never get called, only used by profile stuff in time.c */
+pc_in_user_space:
+	bv,n	0(%rp)
+	nop
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/sba_iommu.c linux-2.4.20/arch/parisc/kernel/sba_iommu.c
--- linux-2.4.19/arch/parisc/kernel/sba_iommu.c	2001-10-12 22:35:53.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/sba_iommu.c	2002-10-04 00:41:13.000000000 +0000
@@ -15,7 +15,6 @@
 ** This module initializes the IOC (I/O Controller) found on B1000/C3000/
 ** J5000/J7000/N-class/L-class machines and their successors.
 **
-** FIXME: Multi-IOC support missing - depends on hp_device data
 ** FIXME: add DMA hint support programming in both sba and lba modules.
 */
 
@@ -28,7 +27,7 @@
 
 #include <linux/mm.h>
 #include <linux/string.h>
-#define PCI_DEBUG		/* for ASSERT */
+#undef PCI_DEBUG		/* for ASSERT */
 #include <linux/pci.h>
 #undef PCI_DEBUG
 
@@ -36,19 +35,19 @@
 #include <asm/io.h>
 #include <asm/dma.h>		/* for DMA_CHUNK_SIZE */
 
-#include <asm/hardware.h>	/* for register_driver() stuff */
+#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
 #include <asm/gsc.h>		/* FIXME: for gsc_read/gsc_write */
 
 #include <linux/proc_fs.h>
 #include <asm/runway.h>		/* for proc_runway_root */
-
+#include <asm/pdc.h>		/* for PDC_MODEL_* */
 
 #define MODULE_NAME "SBA"
 
 /*
 ** The number of debug flags is a clue - this code is fragile.
 ** Don't even think about messing with it unless you have
-** plenty of 710's to sacrafice to the computer gods. :^)
+** plenty of 710's to sacrifice to the computer gods. :^)
 */
 #undef DEBUG_SBA_INIT
 #undef DEBUG_SBA_RUN
@@ -56,12 +55,9 @@
 #undef DEBUG_SBA_RESOURCE
 #undef ASSERT_PDIR_SANITY
 #undef DEBUG_LARGE_SG_ENTRIES
+#undef DEBUG_DMB_TRAP
 
-#if 1
-#define SBA_INLINE
-#else
 #define SBA_INLINE	__inline__
-#endif
 
 #ifdef DEBUG_SBA_INIT
 #define DBG_INIT(x...)	printk(x)
@@ -95,73 +91,43 @@
 ** allocated and free'd/purged at a time might make this
 ** less interesting).
 */
-#if 0
 #define DELAYED_RESOURCE_CNT	16
-#else
-#undef DELAYED_RESOURCE_CNT
-#endif
 
 #define DEFAULT_DMA_HINT_REG	0
 
-#define ASTRO_RUNWAY_PORT    0x582
-#define ASTRO_ROPES_PORT     0x780
-
-#define IKE_MERCED_PORT      0x803
-#define IKE_ROPES_PORT       0x781
-
-int sba_driver_callback(struct hp_device *, struct pa_iodc_driver *);
+#define ASTRO_RUNWAY_PORT	0x582
+#define ASTRO_ROPES_PORT	0x780
 
-static struct pa_iodc_driver sba_drivers_for[] = {
+#define IKE_MERCED_PORT		0x803
+#define IKE_ROPES_PORT		0x781
 
-/* FIXME: why is SVERSION checked? */
-
-   {HPHW_IOA, ASTRO_RUNWAY_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-   {HPHW_BCPORT, ASTRO_ROPES_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-#if 0
-/* FIXME : N-class! Use a different "callback"? */
-   {HPHW_BCPORT, IKE_MERCED_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-
-   {HPHW_BCPORT, IKE_ROPES_PORT, 0x0, 0xb, 0, 0x10,
-		DRIVER_CHECK_HVERSION +
-		DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
-                MODULE_NAME, "I/O MMU", (void *) sba_driver_callback},
-#endif
-
-   {0,0,0,0,0,0,
-   0,
-   (char *) NULL, (char *) NULL, (void *) NULL }
-};
+#define REO_MERCED_PORT		0x804
+#define REO_ROPES_PORT		0x782
 
+#define REOG_MERCED_PORT	0x805
+#define REOG_ROPES_PORT		0x783
 
 #define SBA_FUNC_ID	0x0000	/* function id */
 #define SBA_FCLASS	0x0008	/* function class, bist, header, rev... */
 
-#define IS_ASTRO(id) ( \
-    (((id)->hw_type == HPHW_IOA) && ((id)->hversion == ASTRO_RUNWAY_PORT)) || \
-    (((id)->hw_type == HPHW_BCPORT) && ((id)->hversion == ASTRO_ROPES_PORT))  \
-)
+#define IS_ASTRO(id) \
+(((id)->hversion == ASTRO_RUNWAY_PORT) || ((id)->hversion == ASTRO_ROPES_PORT))
+
+#define IS_IKE(id) \
+(((id)->hversion == IKE_MERCED_PORT) || ((id)->hversion == IKE_ROPES_PORT))
 
-#define CONFIG_FUNC_SIZE 4096   /* SBA configuration function reg set */
+#define SBA_FUNC_SIZE 4096   /* SBA configuration function reg set */
 
 #define ASTRO_IOC_OFFSET 0x20000
 /* Ike's IOC's occupy functions 2 and 3 (not 0 and 1) */
-#define IKE_IOC_OFFSET(p) ((p+2)*CONFIG_FUNC_SIZE)
+#define IKE_IOC_OFFSET(p) ((p+2)*SBA_FUNC_SIZE)
 
 #define IOC_CTRL          0x8	/* IOC_CTRL offset */
-#define IOC_CTRL_TE       (0x1 << 0) /* TOC Enable */
-#define IOC_CTRL_RM       (0x1 << 8) /* Real Mode */
-#define IOC_CTRL_NC       (0x1 << 9) /* Non Coherent Mode */
+#define IOC_CTRL_TC       (1 << 0) /* TOC Enable */
+#define IOC_CTRL_CE       (1 << 1) /* Coalesce Enable */
+#define IOC_CTRL_DE       (1 << 2) /* Dillon Enable */
+#define IOC_CTRL_RM       (1 << 8) /* Real Mode */
+#define IOC_CTRL_NC       (1 << 9) /* Non Coherent Mode */
 
 #define MAX_IOC		2	/* per Ike. Astro only has 1 */
 
@@ -233,18 +199,22 @@
 
 
 struct ioc {
-	char    *ioc_hpa;	/* I/O MMU base address */
+	unsigned long	ioc_hpa;	/* I/O MMU base address */
 	char	*res_map;	/* resource map, bit == pdir entry */
 	u64	*pdir_base;	/* physical base address */
 
-	unsigned long	*res_hint;	/* next available IOVP - circular search */
+	unsigned long	*res_hint;	/* next avail IOVP - circular search */
+	spinlock_t	res_lock;
+	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
 	unsigned int	res_bitshift;	/* from the LEFT! */
 	unsigned int	res_size;	/* size of resource map in bytes */
 	unsigned int	hint_shift_pdir;
-	spinlock_t	res_lock;
-	unsigned long	hint_mask_pdir;		/* bits used for DMA hints */
-#ifdef DELAYED_RESOURCE_CNT
-	dma_addr_t res_delay[DELAYED_RESOURCE_CNT];
+#if DELAYED_RESOURCE_CNT > 0
+	int saved_cnt;
+	struct sba_dma_pair {
+		dma_addr_t	iova;
+		size_t		size;
+	} saved[DELAYED_RESOURCE_CNT];
 #endif
 
 #ifdef CONFIG_PROC_FS
@@ -269,23 +239,32 @@
 };
 
 struct sba_device {
-	struct sba_device	*next;	/* list of LBA's in system */
-	struct hp_device	*iodc;	/* data about dev from firmware */
-	char			*sba_hpa; /* base address */
+	struct sba_device	*next;	/* list of SBA's in system */
+	struct parisc_device	*dev;	/* dev found in bus walk */
+	struct parisc_device_id	*iodc;	/* data about dev from firmware */
+	const char 		*name;
+	unsigned long		sba_hpa; /* base address */
 	spinlock_t		sba_lock;
-	unsigned int			flags;  /* state/functionality enabled */
-	unsigned int			hw_rev;  /* HW revision of chip */
+	unsigned int		flags;  /* state/functionality enabled */
+	unsigned int		hw_rev;  /* HW revision of chip */
 
-	unsigned int			num_ioc;  /* number of on-board IOC's */
+	unsigned int		num_ioc;  /* number of on-board IOC's */
 	struct ioc		ioc[MAX_IOC];
 };
 
 
 static struct sba_device *sba_list;
-static int sba_count;
+
+static unsigned long ioc_needs_fdc = 0;
 
 /* Ratio of Host MEM to IOV Space size */
-static unsigned long sba_mem_ratio = 4;
+static unsigned long sba_mem_ratio = 8;
+
+/* global count of IOMMUs in the system */
+static unsigned int global_ioc_cnt = 0;
+
+/* PA8700 (Piranha 2.2) bug workaround */
+static unsigned long piranha_bad_128k = 0;
 
 /* Looks nice and keeps the compiler happy */
 #define SBA_DEV(d) ((struct sba_device *) (d))
@@ -299,73 +278,75 @@
 **
 ** BE WARNED: register writes are posted.
 **  (ie follow writes which must reach HW with a read)
+**
+** Superdome (in particular, REO) allows only 64-bit CSR accesses.
 */
-#define READ_U8(addr)  gsc_readb(addr)
-#define READ_U16(addr) gsc_readw((u16 *) (addr))
-#define READ_U32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-#define READ_REG8(addr)  gsc_readb(addr)
-#define READ_REG16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_REG32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define READ_REG64(addr) le64_to_cpu(gsc_readq((u64 *) (addr)))
-#define WRITE_REG8(value, addr) gsc_writeb(value, addr)
-#define WRITE_REG16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
-#define WRITE_REG64(value, addr) gsc_writeq(cpu_to_le64(value), (u64 *) (addr))
+#define READ_REG32(addr)	 le32_to_cpu(__raw_readl(addr))
+#define READ_REG64(addr)	 le64_to_cpu(__raw_readq(addr))
+#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr)
+#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr)
+
+#ifdef __LP64__
+#define READ_REG(addr)		READ_REG64(addr)
+#define WRITE_REG(value, addr)	WRITE_REG64(value, addr)
+#else
+#define READ_REG(addr)		READ_REG32(addr)
+#define WRITE_REG(value, addr)	WRITE_REG32(value, addr)
+#endif
 
 #ifdef DEBUG_SBA_INIT
 
+/* NOTE: When __LP64__ isn't defined, READ_REG64() is two 32-bit reads */
+
+/**
+ * sba_dump_ranges - debugging only - print ranges assigned to this IOA
+ * @hpa: base address of the sba
+ *
+ * Print the MMIO and IO Port address ranges forwarded by an Astro/Ike/RIO
+ * IO Adapter (aka Bus Converter).
+ */
 static void
-sba_dump_ranges(char *hpa)
+sba_dump_ranges(unsigned long hpa)
 {
-	printk("SBA at 0x%p\n", hpa);
-	printk("IOS_DIST_BASE   : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_BASE+4),
-			READ_REG32(hpa+IOS_DIST_BASE));
-	printk("IOS_DIST_MASK   : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_MASK+4),
-			READ_REG32(hpa+IOS_DIST_MASK));
-	printk("IOS_DIST_ROUTE  : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIST_ROUTE+4),
-			READ_REG32(hpa+IOS_DIST_ROUTE));
-	printk("\n");
-	printk("IOS_DIRECT_BASE : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_BASE+4),
-			READ_REG32(hpa+IOS_DIRECT_BASE));
-	printk("IOS_DIRECT_MASK : %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_MASK+4),
-			READ_REG32(hpa+IOS_DIRECT_MASK));
-	printk("IOS_DIRECT_ROUTE: %08x %08x\n",
-			READ_REG32(hpa+IOS_DIRECT_ROUTE+4),
-			READ_REG32(hpa+IOS_DIRECT_ROUTE));
+	DBG_INIT("SBA at 0x%lx\n", hpa);
+	DBG_INIT("IOS_DIST_BASE   : %Lx\n", READ_REG64(hpa+IOS_DIST_BASE));
+	DBG_INIT("IOS_DIST_MASK   : %Lx\n", READ_REG64(hpa+IOS_DIST_MASK));
+	DBG_INIT("IOS_DIST_ROUTE  : %Lx\n", READ_REG64(hpa+IOS_DIST_ROUTE));
+	DBG_INIT("\n");
+	DBG_INIT("IOS_DIRECT_BASE : %Lx\n", READ_REG64(hpa+IOS_DIRECT_BASE));
+	DBG_INIT("IOS_DIRECT_MASK : %Lx\n", READ_REG64(hpa+IOS_DIRECT_MASK));
+	DBG_INIT("IOS_DIRECT_ROUTE: %Lx\n", READ_REG64(hpa+IOS_DIRECT_ROUTE));
 }
 
+/**
+ * sba_dump_tlb - debugging only - print IOMMU operating parameters
+ * @hpa: base address of the IOMMU
+ *
+ * Print the size/location of the IO MMU PDIR.
+ */
 static void
-sba_dump_tlb(char *hpa)
+sba_dump_tlb(unsigned long hpa)
 {
-	printk("IO TLB at 0x%p\n", hpa);
-	printk("IOC_IBASE   : %08x %08x\n",
-			READ_REG32(hpa+IOC_IBASE+4),
-			READ_REG32(hpa+IOC_IBASE));
-	printk("IOC_IMASK   : %08x %08x\n",
-			READ_REG32(hpa+IOC_IMASK+4),
-			READ_REG32(hpa+IOC_IMASK));
-	printk("IOC_TCNFG   : %08x %08x\n",
-			READ_REG32(hpa+IOC_TCNFG+4),
-			READ_REG32(hpa+IOC_TCNFG));
-	printk("IOC_PDIR_BASE: %08x %08x\n",
-			READ_REG32(hpa+IOC_PDIR_BASE+4),
-			READ_REG32(hpa+IOC_PDIR_BASE));
-	printk("\n");
+	DBG_INIT("IO TLB at 0x%lx\n", hpa);
+	DBG_INIT("IOC_IBASE    : %Lx\n", READ_REG64(hpa+IOC_IBASE));
+	DBG_INIT("IOC_IMASK    : %Lx\n", READ_REG64(hpa+IOC_IMASK));
+	DBG_INIT("IOC_TCNFG    : %Lx\n", READ_REG64(hpa+IOC_TCNFG));
+	DBG_INIT("IOC_PDIR_BASE: %Lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
+	DBG_INIT("\n");
 }
 #endif
 
 
 #ifdef ASSERT_PDIR_SANITY
 
+/**
+ * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ * @pide: pdir index.
+ *
+ * Print one entry of the IO MMU PDIR in human readable form.
+ */
 static void
 sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
 {
@@ -374,24 +355,30 @@
 	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
 	uint rcnt;
 
-	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
+	printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
 		 msg,
 		 rptr, pide & (BITS_PER_LONG - 1), *rptr);
 
 	rcnt = 0;
 	while (rcnt < BITS_PER_LONG) {
-		printk("%s %2d %p %016Lx\n",
+		printk(KERN_DEBUG "%s %2d %p %016Lx\n",
 			(rcnt == (pide & (BITS_PER_LONG - 1)))
 				? "    -->" : "       ",
 			rcnt, ptr, *ptr );
 		rcnt++;
 		ptr++;
 	}
-	printk(msg);
+	printk(KERN_DEBUG "%s", msg);
 }
 
 
-/* Verify the resource map and pdir state is consistent */
+/**
+ * sba_check_pdir - debugging only - consistency checker
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ *
+ * Verify the resource map and pdir state is consistent
+ */
 static int
 sba_check_pdir(struct ioc *ioc, char *msg)
 {
@@ -428,15 +415,23 @@
 }
 
 
+/**
+ * sba_dump_sg - debugging only - print Scatter-Gather list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg: head of the SG list
+ * @nents: number of entries in SG list
+ *
+ * print the SG list so we can verify it's correct by hand.
+ */
 static void
 sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
 	while (nents-- > 0) {
-		printk(" %d : %08lx/%05x %p/%05x\n",
+		printk(KERN_DEBUG " %d : %08lx/%05x %p/%05x\n",
 				nents,
 				(unsigned long) sg_dma_address(startsg),
 				sg_dma_len(startsg),
-				startsg->address, startsg->length);
+				sg_virt_addr(startsg), startsg->length);
 		startsg++;
 	}
 }
@@ -445,25 +440,6 @@
 
 
 
-/*
-** One time initialization to let the world know the LBA was found.
-** This is the only routine which is NOT static.
-** Must be called exactly once before pci_init().
-*/
-void __init
-sba_init(void)
-{
-	sba_list = (struct sba_device *) NULL;
-	sba_count = 0;
-
-#ifdef DEBUG_SBA_INIT
-	sba_dump_ranges((char *) 0xFED00000L);
-#endif
-
-	register_driver(sba_drivers_for);
-}
-
-
 
 /**************************************************************
 *
@@ -489,13 +465,15 @@
 #define RESMAP_IDX_MASK   (sizeof(unsigned long) - 1)
 
 
-/*
-** Perf optimizations:
-** o search for log2(size) bits at a time.
-**
-** Search should use register width as "stride" to search the res_map. 
-*/
-
+/**
+ * sba_search_bitmap - find free space in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @bits_wanted: number of entries we need.
+ *
+ * Find consecutive free bits in resource bitmap.
+ * Each bit represents one entry in the IO Pdir.
+ * Cool perf optimization: search for log2(size) bits at a time.
+ */
 static SBA_INLINE unsigned long
 sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
 {
@@ -512,7 +490,6 @@
 				*res_ptr = RESMAP_MASK(bits_wanted);
 				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
 				pide <<= 3;	/* convert to bit address */
-				ASSERT(0 != pide);
 				break;
 			}
 		}
@@ -536,7 +513,7 @@
 		}
 		mask = RESMAP_MASK(bits_wanted) >> bitshiftcnt;
 
-		DBG_RES("sba_search_bitmap() o %ld %p", o, res_ptr);
+		DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
 		while(res_ptr < res_end)
 		{ 
 			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
@@ -546,7 +523,6 @@
 				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
 				pide <<= 3;	/* convert to bit address */
 				pide += bitshiftcnt;
-				ASSERT(0 != pide);
 				break;
 			}
 			mask >>= o;
@@ -562,11 +538,24 @@
 	}
 
 	/* wrapped ? */
-	ioc->res_hint = (res_end == res_ptr) ? (unsigned long *) ioc->res_map : res_ptr;
+	if (res_end <= res_ptr) {
+		ioc->res_hint = (unsigned long *) ioc->res_map;
+		ioc->res_bitshift = 0;
+	} else {
+		ioc->res_hint = res_ptr;
+	}
 	return (pide);
 }
 
 
+/**
+ * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @size: number of bytes to create a mapping for
+ *
+ * Given a size, find consecutive unmarked and then mark those bits in the
+ * resource bit map.
+ */
 static int
 sba_alloc_range(struct ioc *ioc, size_t size)
 {
@@ -577,8 +566,8 @@
 	unsigned long pide;
 
 	ASSERT(pages_needed);
-	ASSERT((pages_needed * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(pages_needed < BITS_PER_LONG);
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
 	ASSERT(0 == (size & ~IOVP_MASK));
 
 	/*
@@ -590,7 +579,7 @@
 	if (pide >= (ioc->res_size << 3)) {
 		pide = sba_search_bitmap(ioc, pages_needed);
 		if (pide >= (ioc->res_size << 3))
-			panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", ioc->ioc_hpa);
+			panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
 	}
 
 #ifdef ASSERT_PDIR_SANITY
@@ -600,8 +589,8 @@
 	}
 #endif
 
-	DBG_RES("sba_alloc_range(%x) %d -> %lx hint %x/%x\n",
-		size, pages_needed, pide,
+	DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
+		__FUNCTION__, size, pages_needed, pide,
 		(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
 		ioc->res_bitshift );
 
@@ -622,9 +611,14 @@
 }
 
 
-/*
-** clear bits in the ioc's resource map
-*/
+/**
+ * sba_free_range - unmark bits in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova: IO virtual address which was previously allocated.
+ * @size: number of bytes to create a mapping for
+ *
+ * clear bits in the ioc's resource map
+ */
 static SBA_INLINE void
 sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
 {
@@ -638,8 +632,8 @@
 	/* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
 	unsigned long m = RESMAP_MASK(bits_not_wanted) >> (pide & (BITS_PER_LONG - 1));
 
-	DBG_RES("sba_free_range( ,%x,%x) %x/%lx %x %p %lx\n",
-		(uint) iova, size,
+	DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n",
+		__FUNCTION__, (uint) iova, size,
 		bits_not_wanted, m, pide, res_ptr, *res_ptr);
 
 #ifdef CONFIG_PROC_FS
@@ -648,8 +642,8 @@
 
 	ASSERT(m != 0);
 	ASSERT(bits_not_wanted);
-	ASSERT((bits_not_wanted * IOVP_SIZE) < DMA_CHUNK_SIZE);
-	ASSERT(bits_not_wanted < BITS_PER_LONG);
+	ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(bits_not_wanted <= BITS_PER_LONG);
 	ASSERT((*res_ptr & m) == m); /* verify same bits are set */
 	*res_ptr &= ~m;
 }
@@ -667,31 +661,37 @@
 typedef unsigned long space_t;
 #define KERNEL_SPACE 0
 
-/*
-* SBA Mapping Routine
-*
-* Given a virtual address (vba, arg2) and space id, (sid, arg1)
-* sba_io_pdir_entry() loads the I/O PDIR entry pointed to by
-* pdir_ptr (arg0). Each IO Pdir entry consists of 8 bytes as
-* shown below (MSB == bit 0):
-*
-*  0                    19                                 51   55       63
-* +-+---------------------+----------------------------------+----+--------+
-* |V|        U            |            PPN[43:12]            | U  |   VI   |
-* +-+---------------------+----------------------------------+----+--------+
-*
-*  V  == Valid Bit
-*  U  == Unused
-* PPN == Physical Page Number
-* VI  == Virtual Index (aka Coherent Index)
-*
-* The physical address fields are filled with the results of the LPA
-* instruction.  The virtual index field is filled with the results of
-* of the LCI (Load Coherence Index) instruction.  The 8 bits used for
-* the virtual index are bits 12:19 of the value returned by LCI.
-*
-* We need to pre-swap the bytes since PCX-W is Big Endian.
-*/
+/**
+ * sba_io_pdir_entry - fill in one IO PDIR entry
+ * @pdir_ptr:  pointer to IO PDIR entry
+ * @sid: process Space ID
+ * @vba: Virtual CPU address of buffer to map
+ *
+ * SBA Mapping Routine
+ *
+ * Given a virtual address (vba, arg2) and space id, (sid, arg1)
+ * sba_io_pdir_entry() loads the I/O PDIR entry pointed to by
+ * pdir_ptr (arg0). Each IO Pdir entry consists of 8 bytes as
+ * shown below (MSB == bit 0):
+ *
+ *  0                    19                                 51   55       63
+ * +-+---------------------+----------------------------------+----+--------+
+ * |V|        U            |            PPN[43:12]            | U  |   VI   |
+ * +-+---------------------+----------------------------------+----+--------+
+ *
+ *  V  == Valid Bit
+ *  U  == Unused
+ * PPN == Physical Page Number
+ * VI  == Virtual Index (aka Coherent Index)
+ *
+ * The physical address fields are filled with the results of the LPA
+ * instruction.  The virtual index field is filled with the results of
+ * of the LCI (Load Coherence Index) instruction.  The 8 bits used for
+ * the virtual index are bits 12:19 of the value returned by LCI.
+ *
+ * We need to pre-swap the bytes since PCX-W is Big Endian.
+ */
+
 
 void SBA_INLINE
 sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba)
@@ -699,9 +699,11 @@
 	u64 pa; /* physical address */
 	register unsigned ci; /* coherent index */
 
-	/* We currently only support kernel addresses */
-	ASSERT(sid == 0);
-	ASSERT(((unsigned long) vba & 0xc0000000UL) == 0xc0000000UL);
+	/* We currently only support kernel addresses.
+	 * fdc instr below will need to reload sr1 with KERNEL_SPACE
+	 * once we try to support direct DMA to user space.
+	 */
+	ASSERT(sid == KERNEL_SPACE);
 
 	pa = virt_to_phys(vba);
 	pa &= ~4095ULL;			/* clear out offset bits */
@@ -712,25 +714,41 @@
 
 	pa |= 0x8000000000000000ULL;	/* set "valid" bit */
 	*pdir_ptr = cpu_to_le64(pa);	/* swap and store into I/O Pdir */
+
+	/*
+	 * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set
+	 * (bit #61, big endian), we have to flush and sync every time
+	 * IO-PDIR is changed in Ike/Astro.
+	 */
+	if (ioc_needs_fdc) {
+		asm volatile("fdc 0(%%sr1,%0)\n\tsync" : : "r" (pdir_ptr));
+	}
 }
 
 
-/***********************************************************
- * The Ike PCOM (Purge Command Register) is to purge
- * stale entries in the IO TLB when unmapping entries.
+/**
+ * sba_mark_invalid - invalidate one or more IO PDIR entries
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova:  IO Virtual Address mapped earlier
+ * @byte_cnt:  number of bytes this mapping covers.
+ *
+ * Marking the IO PDIR entry(ies) as Invalid and invalidate
+ * corresponding IO TLB entry. The Ike PCOM (Purge Command Register)
+ * is to purge stale entries in the IO TLB when unmapping entries.
  *
  * The PCOM register supports purging of multiple pages, with a minium
  * of 1 page and a maximum of 2GB. Hardware requires the address be
  * aligned to the size of the range being purged. The size of the range
- * must be a power of 2.
- ***********************************************************/
+ * must be a power of 2. The "Cool perf optimization" in the
+ * allocation routine helps keep that true.
+ */
 static SBA_INLINE void
 sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
 {
 	u32 iovp = (u32) SBA_IOVP(ioc,iova);
 
 	/* Even though this is a big-endian machine, the entries
-	** in the iopdir are swapped. That's why we clear the byte
+	** in the iopdir are little endian. That's why we clear the byte
 	** at +7 instead of at +0.
 	*/
 	int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
@@ -775,32 +793,45 @@
 		} while (byte_cnt > 0);
 	}
 
-	WRITE_REG32(iovp, ioc->ioc_hpa+IOC_PCOM);
+	WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
 }
 
+/**
+ * sba_dma_supported - PCI driver can query DMA support
+ * @dev: instance of PCI owned by the driver that's asking
+ * @mask:  number of address bits this PCI device can handle
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static int
 sba_dma_supported( struct pci_dev *dev, u64 mask)
 {
 	if (dev == NULL) {
-		printk(MODULE_NAME ": EISA/ISA/et al not supported\n");
+		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
 		BUG();
 		return(0);
 	}
 
 	dev->dma_mask = mask;	/* save it */
 
-	/* only support PCI devices */
-	return((int) (mask >= 0xffffffff));
+	/* only support 32-bit PCI devices - no DAC support (yet) */
+	return((int) (mask == 0xffffffff));
 }
 
 
-/*
-** map_single returns a fully formed IOVA
-*/
+/**
+ * sba_map_single - map one buffer and return IOVA for DMA
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @addr:  driver buffer to map.
+ * @size:  number of bytes to map in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static dma_addr_t
 sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
+	struct ioc *ioc;
 	unsigned long flags; 
 	dma_addr_t iovp;
 	dma_addr_t offset;
@@ -808,9 +839,14 @@
 	int pide;
 
 	ASSERT(size > 0);
+	ASSERT(size <= DMA_CHUNK_SIZE);
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
 
 	/* save offset bits */
-	offset = ((dma_addr_t) addr) & ~IOVP_MASK;
+	offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
 
 	/* round up to nearest IOVP_SIZE */
 	size = (size + offset + ~IOVP_MASK) & IOVP_MASK;
@@ -827,7 +863,8 @@
 	pide = sba_alloc_range(ioc, size);
 	iovp = (dma_addr_t) pide << IOVP_SHIFT;
 
-	DBG_RUN("sba_map_single() 0x%p -> 0x%lx", addr, (long) iovp | offset);
+	DBG_RUN("%s() 0x%p -> 0x%lx",
+		__FUNCTION__, addr, (long) iovp | offset);
 
 	pdir_start = &(ioc->pdir_base[pide]);
 
@@ -860,72 +897,85 @@
 }
 
 
+/**
+ * sba_unmap_single - unmap one IOVA and free resources
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @iova:  IOVA of driver buffer previously mapped.
+ * @size:  number of bytes mapped in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static void
 sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
 {
-#ifdef FIXME
-/* Multi-IOC (ie N-class) :  need to lookup IOC from dev
-** o If we can't know about lba PCI data structs, that eliminates ->sysdata.
-** o walking up pcidev->parent dead ends at elroy too
-** o leaves hashing dev->bus->number into some lookup.
-**   (may only work for N-class)
-** o use (struct pci_hba) and put fields in there for DMA.
-**   (ioc and per device dma_hint.)
-**
-** Last one seems the clearest and most promising.
-** sba_dma_supported() fill in those fields when the driver queries
-** the system for support.
-*/
-	struct ioc *ioc = (struct ioc *) ((struct pci_hba *) (dev->sysdata))->dma_data;
-#else
-	struct ioc *ioc = &sba_list->ioc[0];
+	struct ioc *ioc;
+#if DELAYED_RESOURCE_CNT > 0
+	struct sba_dma_pair *d;
 #endif
-	
 	unsigned long flags; 
 	dma_addr_t offset;
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
 	offset = iova & ~IOVP_MASK;
 
-	DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size);
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long) iova, size);
 
 	iova ^= offset;        /* clear offset bits */
 	size += offset;
 	size = ROUNDUP(size, IOVP_SIZE);
 
-	ASSERT(0 != iova);
-
 	spin_lock_irqsave(&ioc->res_lock, flags);
+
 #ifdef CONFIG_PROC_FS
 	ioc->usingle_calls++;
 	ioc->usingle_pages += size >> IOVP_SHIFT;
 #endif
-#ifdef DELAYED_RESOURCE_CNT
-	if (ioc->saved_cnt < DELAYED_RESOURCE_CNT) {
-		ioc->saved_iova[ioc->saved_cnt] = iova;
-		ioc->saved_size[ioc->saved_cnt] = size;
-		ioc_saved_cnt++;
-	} else {
-		do {
-#endif
-			sba_mark_invalid(ioc, iova, size);
-			sba_free_range(ioc, iova, size);
 
-#ifdef DELAYED_RESOURCE_CNT
-			ioc->saved_cnt--;
-			iova = ioc->saved_iova[ioc->saved_cnt];
-			size = ioc->saved_size[ioc->saved_cnt];
-		} while (ioc->saved_cnt)
-
-		/* flush purges */
-		(void) (volatile) READ_REG32(ioc->ioc_hpa+IOC_PCOM);
+#if DELAYED_RESOURCE_CNT > 0
+	d = &(ioc->saved[ioc->saved_cnt]);
+	d->iova = iova;
+	d->size = size;
+	if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
+		int cnt = ioc->saved_cnt;
+		while (cnt--) {
+			sba_mark_invalid(ioc, d->iova, d->size);
+			sba_free_range(ioc, d->iova, d->size);
+			d--;
+		}
+		ioc->saved_cnt = 0;
+		READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
 	}
-#else
-	/* flush purges */
-	READ_REG32(ioc->ioc_hpa+IOC_PCOM);
-#endif
+#else /* DELAYED_RESOURCE_CNT == 0 */
+	sba_mark_invalid(ioc, iova, size);
+	sba_free_range(ioc, iova, size);
+	READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+#endif /* DELAYED_RESOURCE_CNT == 0 */
 	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
+	** For Astro based systems this isn't a big deal WRT performance.
+	** As long as 2.4 kernels copyin/copyout data from/to userspace,
+	** we don't need the syncdma. The issue here is I/O MMU cachelines
+	** are *not* coherent in all cases.  May be hwrev dependent.
+	** Need to investigate more.
+	asm volatile("syncdma");	
+	*/
 }
 
 
+/**
+ * sba_alloc_consistent - allocate/map shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @dma_handle:  IOVA of new buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static void *
 sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
 {
@@ -948,6 +998,15 @@
 }
 
 
+/**
+ * sba_free_consistent - free/unmap shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @vaddr:  virtual address IOVA of "consistent" buffer.
+ * @dma_handler:  IO virtual address of "consistent" buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static void
 sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
@@ -955,27 +1014,6 @@
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
-/*
-** Two address ranges are "virtually contiguous" iff:
-** 1) end of prev == start of next, or...	 append case
-** 3) end of next == start of prev		 prepend case
-**
-** and they are DMA contiguous *iff*:
-** 2) end of prev and start of next are both on a page boundry
-**
-** (shift left is a quick trick to mask off upper bits)
-*/
-#define DMA_CONTIG(__X, __Y) \
-	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
-
-/*
-** Assumption is two transactions are mutually exclusive.
-** ie both go to different parts of memory.
-** If both are true, then both transaction are on the same page.
-*/
-#define DMA_SAME_PAGE(s1,e1,s2,e2) \
-	( ((((s1) ^ (s2)) >> PAGE_SHIFT) == 0) \
-		&& ((((e1) ^ (e2)) >> PAGE_SHIFT) == 0) )
 
 /*
 ** Since 0 is a valid pdir_base index value, can't use that
@@ -988,6 +1026,17 @@
 int dump_run_sg = 0;
 #endif
 
+
+/**
+ * sba_fill_pdir - write allocated SG entries into IO PDIR
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * Take preprocessed SG list and write corresponding entries
+ * in the IO PDIR.
+ */
+
 static SBA_INLINE int
 sba_fill_pdir(
 	struct ioc *ioc,
@@ -1006,16 +1055,16 @@
 
 #ifdef DEBUG_LARGE_SG_ENTRIES
 		if (dump_run_sg)
-			printk(" %d : %08lx/%05x %p/%05x\n",
+			printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n",
 				nents,
 				(unsigned long) sg_dma_address(startsg), cnt,
-				startsg->address, startsg->length
+				sg_virt_address(startsg), startsg->length
 		);
 #else
 		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
 				nents,
 				(unsigned long) sg_dma_address(startsg), cnt,
-				startsg->address, startsg->length
+				sg_virt_addr(startsg), startsg->length
 		);
 #endif
 		/*
@@ -1024,11 +1073,10 @@
 		if (sg_dma_address(startsg) & PIDE_FLAG) {
 			u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG;
 			dma_offset = (unsigned long) pide & ~IOVP_MASK;
-			pide >>= IOVP_SHIFT;
-			pdirp = &(ioc->pdir_base[pide]);
 			sg_dma_address(startsg) = 0;
-			++dma_sg;
-			sg_dma_address(dma_sg) = (pide << IOVP_SHIFT) + dma_offset;
+			dma_sg++;
+			sg_dma_address(dma_sg) = pide;
+			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
 			n_mappings++;
 		}
 
@@ -1036,9 +1084,12 @@
 		** Look for a VCONTIG chunk
 		*/
 		if (cnt) {
-			unsigned long vaddr = (unsigned long) startsg->address;
+			unsigned long vaddr = (unsigned long) sg_virt_addr(startsg);
 			ASSERT(pdirp);
 
+			/* Since multiple Vcontig blocks could make up
+			** one DMA stream, *add* cnt to dma_len.
+			*/
 			sg_dma_len(dma_sg) += cnt;
 			cnt += dma_offset;
 			dma_offset=0;	/* only want offset on first chunk */
@@ -1062,133 +1113,142 @@
 }
 
 
-
 /*
-** First pass is to walk the SG list and determine where the breaks are
-** in the DMA stream. Allocates PDIR entries but does not fill them.
-** Returns the number of DMA chunks.
+** Two address ranges are DMA contiguous *iff* "end of prev" and
+** "start of next" are both on a page boundry.
 **
-** Doing the fill seperate from the coalescing/allocation keeps the
-** code simpler. Future enhancement could make one pass through
-** the sglist do both.
+** (shift left is a quick trick to mask off upper bits)
 */
+#define DMA_CONTIG(__X, __Y) \
+	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
+
+
+/**
+ * sba_coalesce_chunks - preprocess the SG list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * First pass is to walk the SG list and determine where the breaks are
+ * in the DMA stream. Allocates PDIR entries but does not fill them.
+ * Returns the number of DMA chunks.
+ *
+ * Doing the fill seperate from the coalescing/allocation keeps the
+ * code simpler. Future enhancement could make one pass through
+ * the sglist do both.
+ */
 static SBA_INLINE int
 sba_coalesce_chunks( struct ioc *ioc,
 	struct scatterlist *startsg,
 	int nents)
 {
+	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */
+	unsigned long vcontig_len;         /* len of VCONTIG chunk */
+	unsigned long vcontig_end;
+	struct scatterlist *dma_sg;        /* next DMA stream head */
+	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
 	int n_mappings = 0;
 
 	while (nents > 0) {
-		struct scatterlist *dma_sg;  /* next DMA stream head */
-		unsigned long dma_offset, dma_len;   /* start/len of DMA stream */
-		struct scatterlist *chunksg; /* virtually contig chunk head */
-		unsigned long chunk_addr, chunk_len; /* start/len of VCONTIG chunk */
+		unsigned long vaddr = (unsigned long) sg_virt_addr(startsg); 
 
 		/*
 		** Prepare for first/next DMA stream
 		*/
-		dma_sg = chunksg = startsg;
-		dma_len = chunk_len  = startsg->length;
-		chunk_addr = (unsigned long) startsg->address;
-		dma_offset = 0UL;
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = startsg->length;
+		vcontig_end +=  vaddr;
+		dma_offset = vaddr & ~IOVP_MASK;
+
+		/* PARANOID: clear entries */
+		sg_dma_address(startsg) = 0;
+		sg_dma_len(startsg) = 0;
 
 		/*
 		** This loop terminates one iteration "early" since
 		** it's always looking one "ahead".
 		*/
 		while (--nents > 0) {
-			/* ptr to coalesce prev and next */
-			struct scatterlist *prev_sg = startsg;
-			unsigned long prev_end = (unsigned long) prev_sg->address + prev_sg->length;
-			unsigned long current_end;
+			unsigned long vaddr;	/* tmp */
+
+			startsg++;
 
 			/* PARANOID: clear entries */
 			sg_dma_address(startsg) = 0;
 			sg_dma_len(startsg) = 0;
 
-			/* Now start looking ahead */
-			startsg++;
-			current_end  = (unsigned long) startsg->address + startsg->length;
+			/* catch brokenness in SCSI layer */
+			ASSERT(startsg->length <= DMA_CHUNK_SIZE);
 
 			/*
-			** First look for virtually contiguous blocks.
-			** PARISC needs this since it's cache is virtually
-			** indexed and we need the associated virtual
-			** address for each I/O address we map.
-			**
-			** 1) can we *prepend* the next transaction?
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
 			*/
-			if (current_end == (unsigned long) prev_sg->address)
-			{
-				/* prepend : get new offset */
-				chunksg = startsg;
-				chunk_addr = (unsigned long) prev_sg->address;
-				chunk_len += startsg->length;
-				dma_len   += startsg->length;
-				continue;
-			}
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+				break;
 
 			/*
-			** 2) or append the next transaction?
+			** Then look for virtually contiguous blocks.
+			** PARISC needs to associate a virtual address
+			** with each IO address mapped. The CPU cache is
+			** virtually tagged and the IOMMU uses part
+			** of the virtual address to participate in
+			** CPU cache coherency.
+			**
+			** append the next transaction?
 			*/
-			if  (prev_end == (unsigned long) startsg->address)
+			vaddr = (unsigned long) sg_virt_addr(startsg);
+			if  (vcontig_end == vaddr)
 			{
-				chunk_len += startsg->length;
-				dma_len   += startsg->length;
+				vcontig_len += startsg->length;
+				vcontig_end += startsg->length;
+				dma_len     += startsg->length;
 				continue;
 			}
 
 #ifdef DEBUG_LARGE_SG_ENTRIES
-			dump_run_sg = (chunk_len > IOVP_SIZE);
+			dump_run_sg = (vcontig_len > IOVP_SIZE);
 #endif
+
 			/*
 			** Not virtually contigous.
 			** Terminate prev chunk.
 			** Start a new chunk.
 			**
-			** Once we start a new VCONTIG chunk, the offset
+			** Once we start a new VCONTIG chunk, dma_offset
 			** can't change. And we need the offset from the first
 			** chunk - not the last one. Ergo Successive chunks
 			** must start on page boundaries and dove tail
 			** with it's predecessor.
 			*/
-			sg_dma_len(prev_sg) = chunk_len;
+			sg_dma_len(vcontig_sg) = vcontig_len;
 
-			chunk_len = startsg->length;
-			dma_offset |= (chunk_addr & ~IOVP_MASK);
-			ASSERT((0 == (chunk_addr & ~IOVP_MASK)) ||
-				(dma_offset == (chunk_addr & ~IOVP_MASK)));
+			vcontig_sg = startsg;
+			vcontig_len = startsg->length;
 
-#if 0
 			/*
-			** 4) do the chunks end/start on page boundaries?
-			**  Easier than 3 since no offsets are involved.
+			** 3) do the entries end/start on page boundaries?
+			**    Don't update vcontig_end until we've checked.
 			*/
-			if (DMA_CONTIG(prev_end, startsg->address))
+			if (DMA_CONTIG(vcontig_end, vaddr))
 			{
-				/*
-				** Yes.
-				** Reset chunk ptr.
-				*/
-				chunksg = startsg;
-				chunk_addr = (unsigned long) startsg->address;
-
+				vcontig_end = vcontig_len + vaddr;
+				dma_len += vcontig_len;
 				continue;
-			} else
-#endif
-			{
+			} else {
 				break;
 			}
 		}
 
 		/*
 		** End of DMA Stream
-		** Terminate chunk.
+		** Terminate last VCONTIG block.
 		** Allocate space for DMA stream.
 		*/
-		sg_dma_len(startsg) = chunk_len;
+		sg_dma_len(vcontig_sg) = vcontig_len;
 		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
+		ASSERT(dma_len <= DMA_CHUNK_SIZE);
 		sg_dma_address(dma_sg) =
 			PIDE_FLAG 
 			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
@@ -1200,24 +1260,34 @@
 }
 
 
-/*
-** And this algorithm still generally only ends up coalescing entries
-** that happens to be on the same page due to how sglists are assembled.
-*/
+/**
+ * sba_map_sg - map Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static int
 sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
 {
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
+	struct ioc *ioc;
 	int coalesced, filled = 0;
 	unsigned long flags;
 
 	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
 
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
 	/* Fast path single entry scatterlists. */
 	if (nents == 1) {
-		sg_dma_address(sglist)= sba_map_single(dev, sglist->address,
+		sg_dma_address(sglist) = sba_map_single(dev,
+						sg_virt_addr(sglist),
 						sglist->length, direction);
-		sg_dma_len(sglist)= sglist->length;
+		sg_dma_len(sglist)     = sglist->length;
 		return 1;
 	}
 
@@ -1272,16 +1342,29 @@
 }
 
 
+/**
+ * sba_unmap_sg - unmap Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
 static void 
 sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
 {
-	struct ioc *ioc = &sba_list->ioc[0];  /* FIXME : see Multi-IOC below */
+	struct ioc *ioc;
 #ifdef ASSERT_PDIR_SANITY
 	unsigned long flags;
 #endif
 
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
-		__FUNCTION__, nents, sglist->address, sglist->length);
+		__FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
+
+	ASSERT(dev->sysdata);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
 
 #ifdef CONFIG_PROC_FS
 	ioc->usg_calls++;
@@ -1295,10 +1378,11 @@
 
 	while (sg_dma_len(sglist) && nents--) {
 
+		sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
 #ifdef CONFIG_PROC_FS
-	ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
+		ioc->usg_pages += ((sg_dma_address(sglist) & ~IOVP_MASK) + sg_dma_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
+		ioc->usingle_calls--;	/* kluge since call is unmap_sg() */
 #endif
-		sba_unmap_single(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction);
 		++sglist;
 	}
 
@@ -1359,21 +1443,117 @@
 *   Initialization and claim
 *
 ***************************************************************/
+#define PIRANHA_ADDR_MASK	0x00160000UL /* bit 17,18,20 */
+#define PIRANHA_ADDR_VAL	0x00060000UL /* bit 17,18 on */
+static void *
+sba_alloc_pdir(unsigned int pdir_size)
+{
+        unsigned long pdir_base;
+	unsigned long pdir_order = get_order(pdir_size);
+
+	pdir_base = __get_free_pages(GFP_KERNEL, pdir_order);
+	if (NULL == (void *) pdir_base)
+		panic("sba_ioc_init() could not allocate I/O Page Table\n");
+
+	/* If this is not PA8700 (PCX-W2)
+	**	OR newer than ver 2.2
+	**	OR in a system that doesn't need VINDEX bits from SBA,
+	**
+	** then we aren't exposed to the HW bug.
+	*/
+	if ( ((boot_cpu_data.pdc.cpuid >> 5) & 0x7f) != 0x13
+			|| (boot_cpu_data.pdc.versions > 0x202)
+			|| (boot_cpu_data.pdc.capabilities & 0x08L) )
+		return (void *) pdir_base;
+
+	/*
+	 * PA8700 (PCX-W2, aka piranha) silent data corruption fix
+	 *
+	 * An interaction between PA8700 CPU (Ver 2.2 or older) and
+	 * Ike/Astro can cause silent data corruption. This is only
+	 * a problem if the I/O PDIR is located in memory such that
+	 * (little-endian)  bits 17 and 18 are on and bit 20 is off.
+	 *
+	 * Since the max IO Pdir size is 2MB, by cleverly allocating the
+	 * right physical address, we can either avoid (IOPDIR <= 1MB)
+	 * or minimize (2MB IO Pdir) the problem if we restrict the
+	 * IO Pdir to a maximum size of 2MB-128K (1902K).
+	 *
+	 * Because we always allocate 2^N sized IO pdirs, either of the
+	 * "bad" regions will be the last 128K if at all. That's easy
+	 * to test for.
+	 * 
+	 */
+	if (pdir_order <= (19-12)) {
+		if (((virt_to_phys(pdir_base)+pdir_size-1) & PIRANHA_ADDR_MASK) == PIRANHA_ADDR_VAL) {
+			/* allocate a new one on 512k alignment */
+			unsigned long new_pdir = __get_free_pages(GFP_KERNEL, (19-12));
+			/* release original */
+			free_pages(pdir_base, pdir_order);
+
+			pdir_base = new_pdir;
+
+			/* release excess */
+			while (pdir_order < (19-12)) {
+				new_pdir += pdir_size;
+				free_pages(new_pdir, pdir_order);
+				pdir_order +=1;
+				pdir_size <<=1;
+			}
+		}
+	} else {
+		/*
+		** 1MB or 2MB Pdir
+		** Needs to be aligned on an "odd" 1MB boundary.
+		*/
+		unsigned long new_pdir = __get_free_pages(GFP_KERNEL, pdir_order+1); /* 2 or 4MB */
+
+		/* release original */
+		free_pages( pdir_base, pdir_order);
+
+		/* release first 1MB */
+		free_pages(new_pdir, 20-12);
+
+		pdir_base = new_pdir + 1024*1024;
+
+		if (pdir_order > (20-12)) {
+			/*
+			** 2MB Pdir.
+			**
+			** Flag tells init_bitmap() to mark bad 128k as used
+			** and to reduce the size by 128k.
+			*/
+			piranha_bad_128k = 1;
+
+			new_pdir += 3*1024*1024;
+			/* release last 1MB */
+			free_pages(new_pdir, 20-12);
+
+			/* release unusable 128KB */
+			free_pages(new_pdir - 128*1024 , 17-12);
+
+			pdir_size -= 128*1024;
+		}
+	}
+
+	memset((void *) pdir_base, 0, pdir_size);
+	return (void *) pdir_base;
+}
 
 
 static void
-sba_ioc_init(struct ioc *ioc)
+sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
 {
-	extern unsigned long mem_max;          /* arch.../setup.c */
-	extern void lba_init_iregs(void *, u32, u32);   /* arch.../lba_pci.c */
+	/* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
+	extern void lba_set_iregs(struct parisc_device *, u32, u32);
 
 	u32 iova_space_size, iova_space_mask;
-	void * pdir_base;
 	int pdir_size, iov_order;
+	unsigned long physmem;
+	struct parisc_device *lba;
 
 	/*
 	** Determine IOVA Space size from memory size.
-	** Using "mem_max" is a kluge.
 	**
 	** Ideally, PCI drivers would register the maximum number
 	** of DMA they can have outstanding for each device they
@@ -1385,20 +1565,24 @@
 	** While we have 32-bits "IOVA" space, top two 2 bits are used
 	** for DMA hints - ergo only 30 bits max.
 	*/
+
+	physmem = num_physpages << PAGE_SHIFT;
+	iova_space_size = (u32) (physmem/(sba_mem_ratio*global_ioc_cnt));
+
 	/* limit IOVA space size to 1MB-1GB */
-	if (mem_max < (sba_mem_ratio*1024*1024)) {
+	if (iova_space_size < 1024*1024) {
 		iova_space_size = 1024*1024;
+	}
 #ifdef __LP64__
-	} else if (mem_max > (sba_mem_ratio*512*1024*1024)) {
+	else if (iova_space_size > 512*1024*1024) {
 		iova_space_size = 512*1024*1024;
-#endif
-	} else {
-		iova_space_size = (u32) (mem_max/sba_mem_ratio);
 	}
+#endif
 
 	/*
 	** iova space must be log2() in size.
 	** thus, pdir/res_map will also be log2().
+	** PIRANHA BUG: Exception is when IO Pdir is 2MB (gets reduced)
 	*/
 	iov_order = get_order(iova_space_size >> (IOVP_SHIFT-PAGE_SHIFT));
 	ASSERT(iov_order <= (30 - IOVP_SHIFT));   /* iova_space_size <= 1GB */
@@ -1407,35 +1591,27 @@
 
 	ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
 
-	ASSERT(pdir_size < 4*1024*1024);   /* max pdir size < 4MB */
+	ASSERT(pdir_size < 4*1024*1024);   /* max pdir size == 2MB */
 
 	/* Verify it's a power of two */
 	ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
 
-	DBG_INIT("%s() hpa 0x%p mem %dMBIOV %dMB (%d bits) PDIR size 0x%0x",
-		__FUNCTION__, ioc->ioc_hpa, (int) (mem_max>>20),
+	DBG_INIT("%s() hpa 0x%lx mem %dMB IOV %dMB (%d bits) PDIR size 0x%0x\n",
+		__FUNCTION__, ioc->ioc_hpa, (int) (physmem>>20),
 		iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
 
 	/* FIXME : DMA HINTs not used */
 	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
 	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
 
-	ioc->pdir_base =
-	pdir_base = (void *) __get_free_pages(GFP_KERNEL, get_order(pdir_size));
-	if (NULL == pdir_base)
-	{
-		panic(__FILE__ ":%s() could not allocate I/O Page Table\n", __FUNCTION__);
-	}
-	memset(pdir_base, 0, pdir_size);
+	ioc->pdir_base = sba_alloc_pdir(pdir_size);
 
-	DBG_INIT("sba_ioc_init() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
-		pdir_base, pdir_size,
+	DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
+		__FUNCTION__, ioc->pdir_base, pdir_size,
 		ioc->hint_shift_pdir, ioc->hint_mask_pdir);
 
-	ASSERT((((unsigned long) pdir_base) & PAGE_MASK) == (unsigned long) pdir_base);
-	WRITE_REG64(virt_to_phys(pdir_base), (u64 *)(ioc->ioc_hpa+IOC_PDIR_BASE));
-
-	DBG_INIT(" base %p\n", pdir_base);
+	ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+	WRITE_REG64(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
 
 	/* build IMASK for IOC and Elroy */
 	iova_space_mask =  0xffffffff;
@@ -1448,8 +1624,8 @@
 	ioc->ibase = IOC_IOVA_SPACE_BASE | 1;	/* bit 0 == enable bit */
 	ioc->imask = iova_space_mask;	/* save it */
 
-	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", __FUNCTION__,
-		ioc->ibase, ioc->imask);
+	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
+		__FUNCTION__, ioc->ibase, ioc->imask);
 
 	/*
 	** FIXME: Hint registers are programmed with default hint
@@ -1460,22 +1636,26 @@
 	/*
 	** setup Elroy IBASE/IMASK registers as well.
 	*/
-	lba_init_iregs(ioc->ioc_hpa, ioc->ibase, ioc->imask);
+	for (lba = sba->child; lba; lba = lba->sibling) {
+		int rope_num = (lba->hpa >> 13) & 0xf;
+		if (rope_num >> 3 == ioc_num)
+			lba_set_iregs(lba, ioc->ibase, ioc->imask);
+	}
 
 	/*
 	** Program the IOC's ibase and enable IOVA translation
 	*/
-	WRITE_REG32(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
-	WRITE_REG32(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
+	WRITE_REG(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
+	WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
 
 	/* Set I/O PDIR Page size to 4K */
-	WRITE_REG32(0, ioc->ioc_hpa+IOC_TCNFG);
+	WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG);
 
 	/*
 	** Clear I/O TLB of any possible entries.
-	** (Yes. This is a it paranoid...but so what)
+	** (Yes. This is a bit paranoid...but so what)
 	*/
-	WRITE_REG32(0 | 31, ioc->ioc_hpa+IOC_PCOM);
+	WRITE_REG(0 | 31, ioc->ioc_hpa+IOC_PCOM);
 
 	DBG_INIT("%s() DONE\n", __FUNCTION__);
 }
@@ -1498,23 +1678,24 @@
 { 
 	int i;
 	int num_ioc;
-	u32 ioc_ctl;
+	u64 ioc_ctl;
+
+	ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+	DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
+		__FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
+	ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
+	ioc_ctl |= IOC_CTRL_TC;	/* Astro: firmware enables this */
 
-	ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
-	DBG_INIT("%s() hpa 0x%p ioc_ctl 0x%x ->", __FUNCTION__, sba_dev->sba_hpa, ioc_ctl );
-	ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC);
-	ASSERT(ioc_ctl & IOC_CTRL_TE);	/* astro: firmware enables this */
-
-	WRITE_REG32(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
-
-#ifdef SBA_DEBUG_INIT
-	ioc_ctl = READ_REG32(sba_dev->sba_hpa+IOC_CTRL);
-	DBG_INIT(" 0x%x\n", ioc_ctl );
+	WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
+
+#ifdef DEBUG_SBA_INIT
+	ioc_ctl = READ_REG64(sba_dev->sba_hpa+IOC_CTRL);
+	DBG_INIT(" 0x%Lx\n", ioc_ctl);
 #endif
 
 	if (IS_ASTRO(sba_dev->iodc)) {
 		/* PAT_PDC (L-class) also reports the same goofy base */
-		sba_dev->ioc[0].ioc_hpa = (char *) ASTRO_IOC_OFFSET;
+		sba_dev->ioc[0].ioc_hpa = ASTRO_IOC_OFFSET;
 		num_ioc = 1;
 	} else {
 		sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0;
@@ -1522,26 +1703,25 @@
 	}
 
 	sba_dev->num_ioc = num_ioc;
-	for( i = 0; i < num_ioc; i++)
-	{
-		(unsigned long) sba_dev->ioc[i].ioc_hpa += (unsigned long) sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
+	for (i = 0; i < num_ioc; i++) {
+		sba_dev->ioc[i].ioc_hpa += sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
 
 		/*
 		** Make sure the box crashes if we get any errors on a rope.
 		*/
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
-		WRITE_REG32(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL);
+		WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
 
 		/* flush out the writes */
-		READ_REG32(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+		READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
 
-		sba_ioc_init(&(sba_dev->ioc[i]));
+		sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
 	}
 }
 
@@ -1555,11 +1735,10 @@
 	*/
 	sba_dev->next = sba_list;
 	sba_list = sba_dev;
-	sba_count++;
 
 	for(i=0; i< sba_dev->num_ioc; i++) {
 		int res_size;
-#ifdef CONFIG_DMB_TRAP
+#ifdef DEBUG_DMB_TRAP
 		extern void iterate_pages(unsigned long , unsigned long ,
 					  void (*)(pte_t * , unsigned long),
 					  unsigned long );
@@ -1567,13 +1746,20 @@
 #endif
 		/* resource map size dictated by pdir_size */
 		res_size = sba_dev->ioc[i].pdir_size/sizeof(u64); /* entries */
+
+		/* Second part of PIRANHA BUG */
+		if (piranha_bad_128k) {
+			res_size -= (128*1024)/sizeof(u64);
+		}
+
 		res_size >>= 3;  /* convert bit count to byte count */
-		DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, res_size);
+		DBG_INIT("%s() res_size 0x%x\n",
+			__FUNCTION__, res_size);
 
 		sba_dev->ioc[i].res_size = res_size;
 		sba_dev->ioc[i].res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(res_size));
 
-#ifdef CONFIG_DMB_TRAP
+#ifdef DEBUG_DMB_TRAP
 		iterate_pages( sba_dev->ioc[i].res_map, res_size,
 				set_data_memory_break, 0);
 #endif
@@ -1594,39 +1780,66 @@
 		sba_dev->ioc[i].pdir_base[0] = 0xeeffc0addbba0080ULL;
 #endif
 
-#ifdef CONFIG_DMB_TRAP
+		/* Third (and last) part of PIRANHA BUG */
+		if (piranha_bad_128k) {
+			/* region from +1408K to +1536 is un-usable. */
+
+			int idx_start = (1408*1024/sizeof(u64)) >> 3;
+			int idx_end   = (1536*1024/sizeof(u64)) >> 3;
+			long *p_start = (long *) &(sba_dev->ioc[i].res_map[idx_start]);
+			long *p_end   = (long *) &(sba_dev->ioc[i].res_map[idx_end]);
+
+			/* mark that part of the io pdir busy */
+			while (p_start < p_end)
+				*p_start++ = -1;
+				
+		}
+
+#ifdef DEBUG_DMB_TRAP
 		iterate_pages( sba_dev->ioc[i].res_map, res_size,
 				set_data_memory_break, 0);
 		iterate_pages( sba_dev->ioc[i].pdir_base, sba_dev->ioc[i].pdir_size,
 				set_data_memory_break, 0);
 #endif
 
-		DBG_INIT("sba_common_init() %d res_map %x %p\n",
-					i, res_size, sba_dev->ioc[i].res_map);
+		DBG_INIT("%s() %d res_map %x %p\n",
+			__FUNCTION__, i, res_size, sba_dev->ioc[i].res_map);
 	}
 
 	sba_dev->sba_lock = SPIN_LOCK_UNLOCKED;
+	ioc_needs_fdc = boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC;
+
+#ifdef DEBUG_SBA_INIT
+	/*
+	 * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit set
+	 * (bit #61, big endian), we have to flush and sync every time
+	 * IO-PDIR is changed in Ike/Astro.
+	 */
+	if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) {
+		printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n");
+	} else {
+		printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n");
+	}
+#endif
 }
 
 #ifdef CONFIG_PROC_FS
 static int sba_proc_info(char *buf, char **start, off_t offset, int len)
 {
 	struct sba_device *sba_dev = sba_list;
-/* FIXME: Multi-IOC support broken! */
-	struct ioc *ioc = &sba_dev->ioc[0];
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Multi-IOC support! */
 	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
 	unsigned long i = 0, avg = 0, min, max;
 
 	sprintf(buf, "%s rev %d.%d\n",
-		parisc_getHWdescription(sba_dev->iodc->hw_type,
-			sba_dev->iodc->hversion, sba_dev->iodc->sversion),
+		sba_dev->name,
 		(sba_dev->hw_rev & 0x7) + 1,
 		(sba_dev->hw_rev & 0x18) >> 3
 		);
 	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
 		buf,
-		((ioc->res_size << 3) * sizeof(u64)), /* 8 bits per byte */
-		total_pages);                  /* 8 bits per byte */
+		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
+		total_pages);
 
 	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
 		total_pages - ioc->used_pages, ioc->used_pages,
@@ -1645,46 +1858,72 @@
 	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
 		buf, min, avg, max);
 
-	sprintf(buf, "%spci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
+	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
 		buf, ioc->msingle_calls, ioc->msingle_pages,
 		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
 
 	/* KLUGE - unmap_sg calls unmap_single for each mapped page */
-	min = ioc->usingle_calls - ioc->usg_calls;
+	min = ioc->usingle_calls;
 	max = ioc->usingle_pages - ioc->usg_pages;
-	sprintf(buf, "%spci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",
+	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
 		buf, min, max,
 		(int) ((max * 1000)/min));
 
-	sprintf(buf, "%spci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",
+	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
 		buf, ioc->msg_calls, ioc->msg_pages,
 		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
 
-	sprintf(buf, "%spci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n",
+	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
 		buf, ioc->usg_calls, ioc->usg_pages,
 		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
 
 	return strlen(buf);
 }
 
+#if 0
+/* XXX too much output - exceeds 4k limit and needs to be re-written */
 static int
 sba_resource_map(char *buf, char **start, off_t offset, int len)
 {
 	struct sba_device *sba_dev = sba_list;
-	struct ioc *ioc = &sba_dev->ioc[0];
-	unsigned long *res_ptr = (unsigned long *)ioc->res_map;
+	struct ioc *ioc = &sba_dev->ioc[0];	/* FIXME: Mutli-IOC suppoer! */
+	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
 	int i;
 
-	for(i = 0; i < (ioc->res_size / sizeof(unsigned long)); ++i, ++res_ptr) {
+	buf[0] = '\0';
+	for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) {
 		if ((i & 7) == 0)
 		    strcat(buf,"\n   ");
-		sprintf(buf, "%s %08lx", buf, *res_ptr);
+		sprintf(buf, "%s %08x", buf, *res_ptr);
 	}
 	strcat(buf, "\n");
 
 	return strlen(buf);
 }
-#endif
+#endif /* 0 */
+#endif /* CONFIG_PROC_FS */
+
+static struct parisc_device_id sba_tbl[] = {
+	{ HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
+	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REOG_MERCED_PORT, 0xc },
+/* These two entries commented out because we don't find them in a
+ * buswalk yet.  If/when we do, they would cause us to think we had
+ * many more SBAs then we really do.
+ *	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, ASTRO_ROPES_PORT, 0xc },
+ *	{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_ROPES_PORT, 0xc },
+ */
+	{ 0, }
+};
+
+int sba_driver_callback(struct parisc_device *);
+
+static struct parisc_driver sba_driver = {
+	name:		MODULE_NAME,
+	id_table:	sba_tbl,
+	probe:		sba_driver_callback,
+};
 
 /*
 ** Determine if lba should claim this chip (return 0) or not (return 1).
@@ -1692,47 +1931,75 @@
 ** have work to do.
 */
 int
-sba_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+sba_driver_callback(struct parisc_device *dev)
 {
 	struct sba_device *sba_dev;
 	u32 func_class;
 	int i;
+	char *version;
 
-	if (IS_ASTRO(d)) {
+#ifdef DEBUG_SBA_INIT
+	sba_dump_ranges(dev->hpa);
+#endif
+
+	/* Read HW Rev First */
+	func_class = READ_REG(dev->hpa + SBA_FCLASS);
+
+	if (IS_ASTRO(&dev->id)) {
+		unsigned long fclass;
 		static char astro_rev[]="Astro ?.?";
 
-		/* Read HW Rev First */
-		func_class = READ_REG32(d->hpa);
+		/* Astro is broken...Read HW Rev First */
+		fclass = READ_REG(dev->hpa);
 
-		astro_rev[6] = '1' + (char) (func_class & 0x7);
-		astro_rev[8] = '0' + (char) ((func_class & 0x18) >> 3);
-		dri->version = astro_rev;
-	} else {
-		static char ike_rev[]="Ike rev ?";
+		astro_rev[6] = '1' + (char) (fclass & 0x7);
+		astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
+		version = astro_rev;
 
-		/* Read HW Rev First */
-		func_class = READ_REG32(d->hpa + SBA_FCLASS);
+	} else if (IS_IKE(&dev->id)) {
+		static char ike_rev[]="Ike rev ?";
 
 		ike_rev[8] = '0' + (char) (func_class & 0xff);
-		dri->version = ike_rev;
+		version = ike_rev;
+	} else {
+		static char reo_rev[]="REO rev ?";
+
+		reo_rev[8] = '0' + (char) (func_class & 0xff);
+		version = reo_rev;
+	}
+
+	if (!global_ioc_cnt) {
+		global_ioc_cnt = count_parisc_driver(&sba_driver);
+
+		/* Only Astro has one IOC per SBA */
+		if (!IS_ASTRO(&dev->id))
+			global_ioc_cnt *= 2;
 	}
 
-	printk("%s found %s at 0x%p\n", dri->name, dri->version, d->hpa);
+	printk(KERN_INFO "%s found %s at 0x%lx\n",
+		MODULE_NAME, version, dev->hpa);
+
+#ifdef DEBUG_SBA_INIT
+	sba_dump_tlb(dev->hpa);
+#endif
 
 	sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
-	if (NULL == sba_dev)
-	{
-		printk(MODULE_NAME " - couldn't alloc sba_device\n");
+	if (NULL == sba_dev) {
+		printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
 		return(1);
 	}
+
+	dev->sysdata = (void *) sba_dev;
 	memset(sba_dev, 0, sizeof(struct sba_device));
+
 	for(i=0; i<MAX_IOC; i++)
 		spin_lock_init(&(sba_dev->ioc[i].res_lock));
 
-
+	sba_dev->dev = dev;
 	sba_dev->hw_rev = func_class;
-	sba_dev->iodc = d;
-	sba_dev->sba_hpa = d->hpa;  /* faster access */
+	sba_dev->iodc = &dev->id;
+	sba_dev->name = dev->name;
+	sba_dev->sba_hpa = dev->hpa;  /* faster access */
 
 	sba_get_pat_resources(sba_dev);
 	sba_hw_init(sba_dev);
@@ -1741,12 +2008,46 @@
 	hppa_dma_ops = &sba_ops;
 
 #ifdef CONFIG_PROC_FS
-	if (IS_ASTRO(d)) {
+	if (IS_ASTRO(&dev->id)) {
 		create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info);
-	} else {
+	} else if (IS_IKE(&dev->id)) {
 		create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info);
+	} else {
+		create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info);
 	}
+#if 0
 	create_proc_info_entry("bitmap", 0, proc_runway_root, sba_resource_map);
 #endif
+#endif
 	return 0;
 }
+
+/*
+** One time initialization to let the world know the SBA was found.
+** This is the only routine which is NOT static.
+** Must be called exactly once before pci_init().
+*/
+void __init sba_init(void)
+{
+	register_parisc_driver(&sba_driver);
+}
+
+
+/**
+ * sba_get_iommu - Assign the iommu pointer for the pci bus controller.
+ * @dev: The parisc device.
+ *
+ * This function searches through the registerd IOMMU's and returns the
+ * appropriate IOMMU data for the given parisc PCI controller.
+ */
+void * sba_get_iommu(struct parisc_device *pci_hba)
+{
+	struct sba_device *sba = (struct sba_device *) pci_hba->parent->sysdata;
+	char t = pci_hba->parent->id.hw_type;
+	int iocnum = (pci_hba->hw_path >> 3);	/* rope # */
+
+	if ((t!=HPHW_IOA) && (t!=HPHW_BCPORT))
+		BUG();
+
+	return &(sba->ioc[iocnum]);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/semaphore.c linux-2.4.20/arch/parisc/kernel/semaphore.c
--- linux-2.4.19/arch/parisc/kernel/semaphore.c	2001-04-18 00:19:25.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/semaphore.c	2002-10-04 00:41:29.000000000 +0000
@@ -1,131 +1,100 @@
 /*
- * Just taken from alpha implementation.
- * This can't work well, perhaps.
- */
-/*
- *  Generic semaphore code. Buyer beware. Do your own
- * specific changes in <asm/semaphore-helper.h>
+ * Semaphore implementation Copyright (c) 2001 Matthew Wilcox, Hewlett-Packard
  */
 
 #include <linux/sched.h>
-#include <asm/semaphore-helper.h>
+#include <linux/spinlock.h>
 
 /*
- * Semaphores are implemented using a two-way counter:
- * The "count" variable is decremented for each process
- * that tries to sleep, while the "waking" variable is
- * incremented when the "up()" code goes to wake up waiting
- * processes.
- *
- * Notably, the inline "up()" and "down()" functions can
- * efficiently test if they need to do any extra work (up
- * needs to do something only if count was negative before
- * the increment operation.
- *
- * waking_non_zero() (from asm/semaphore.h) must execute
- * atomically.
- *
- * When __up() is called, the count was negative before
- * incrementing it, and we need to wake up somebody.
- *
- * This routine adds one to the count of processes that need to
- * wake up and exit.  ALL waiting processes actually wake up but
- * only the one that gets to the "waking" field first will gate
- * through and acquire the semaphore.  The others will go back
- * to sleep.
- *
- * Note that these functions are only called when there is
- * contention on the lock, and as such all this is the
- * "non-critical" part of the whole semaphore business. The
- * critical part is the inline stuff in <asm/semaphore.h>
- * where we want to avoid any extra jumps and calls.
+ * Semaphores are complex as we wish to avoid using two variables.
+ * `count' has multiple roles, depending on its value.  If it is positive
+ * or zero, there are no waiters.  The functions here will never be
+ * called; see <asm/semaphore.h>
+ *
+ * When count is -1 it indicates there is at least one task waiting
+ * for the semaphore.
+ *
+ * When count is less than that, there are '- count - 1' wakeups
+ * pending.  ie if it has value -3, there are 2 wakeups pending.
+ *
+ * Note that these functions are only called when there is contention
+ * on the lock, and as such all this is the "non-critical" part of the
+ * whole semaphore business. The critical part is the inline stuff in
+ * <asm/semaphore.h> where we want to avoid any extra jumps and calls.
  */
 void __up(struct semaphore *sem)
 {
-	wake_one_more(sem);
+	sem->count--;
 	wake_up(&sem->wait);
 }
 
-/*
- * Perform the "down" function.  Return zero for semaphore acquired,
- * return negative for signalled out of the function.
- *
- * If called from __down, the return is ignored and the wait loop is
- * not interruptible.  This means that a task waiting on a semaphore
- * using "down()" cannot be killed until someone does an "up()" on
- * the semaphore.
- *
- * If called from __down_interruptible, the return value gets checked
- * upon return.  If the return value is negative then the task continues
- * with the negative value in the return register (it can be tested by
- * the caller).
- *
- * Either form may be used in conjunction with "up()".
- *
- */
-
+#define wakers(count) (-1 - count)
 
-#define DOWN_HEAD(task_state)						\
+#define DOWN_HEAD							\
+	int ret = 0;							\
+	DECLARE_WAITQUEUE(wait, current);				\
 									\
+	/* Note that someone is waiting */				\
+	if (sem->count == 0)						\
+		sem->count = -1;					\
 									\
-	current->state = (task_state);					\
-	add_wait_queue(&sem->wait, &wait);				\
-									\
-	/*								\
-	 * Ok, we're set up.  sem->count is known to be less than zero	\
-	 * so we must wait.						\
-	 *								\
-	 * We can let go the lock for purposes of waiting.		\
-	 * We re-acquire it after awaking so as to protect		\
-	 * all semaphore operations.					\
-	 *								\
-	 * If "up()" is called before we call waking_non_zero() then	\
-	 * we will catch it right away.  If it is called later then	\
-	 * we will have to go through a wakeup cycle to catch it.	\
-	 *								\
-	 * Multiple waiters contend for the semaphore lock to see	\
-	 * who gets to gate through and who has to wait some more.	\
-	 */								\
-	for (;;) {
-
-#define DOWN_TAIL(task_state)			\
-		current->state = (task_state);	\
-	}					\
-	current->state = TASK_RUNNING;		\
-	remove_wait_queue(&sem->wait, &wait);
+	/* protected by the sentry still -- use unlocked version */	\
+	wait.flags = WQ_FLAG_EXCLUSIVE;					\
+	__add_wait_queue_tail(&sem->wait, &wait);			\
+ lost_race:								\
+	spin_unlock_irq(&sem->sentry);					\
+
+#define DOWN_TAIL							\
+	spin_lock_irq(&sem->sentry);					\
+	if (wakers(sem->count) == 0 && ret == 0)			\
+		goto lost_race;	/* Someone stole our wakeup */		\
+	__remove_wait_queue(&sem->wait, &wait);				\
+	current->state = TASK_RUNNING;					\
+	if (!waitqueue_active(&sem->wait) && (sem->count < 0))		\
+		sem->count = wakers(sem->count);
+
+#define UPDATE_COUNT							\
+	sem->count += (sem->count < 0) ? 1 : - 1;
+	
 
 void __down(struct semaphore * sem)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DOWN_HEAD
+
+	for(;;) {
+		set_task_state(current, TASK_UNINTERRUPTIBLE);
+		/* we can _read_ this without the sentry */
+		if (sem->count != -1)
+			break;
+ 		schedule();
+ 	}
 
-	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
-	if (waking_non_zero(sem))
-		break;
-	schedule();
-	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+	DOWN_TAIL
+	UPDATE_COUNT
 }
 
 int __down_interruptible(struct semaphore * sem)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	int ret = 0;
+	DOWN_HEAD
 
-	DOWN_HEAD(TASK_INTERRUPTIBLE)
+	for(;;) {
+		set_task_state(current, TASK_INTERRUPTIBLE);
+		/* we can _read_ this without the sentry */
+		if (sem->count != -1)
+			break;
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+		schedule();
+	}
 
-	ret = waking_non_zero_interruptible(sem, current);
-	if (ret)
-	{
-		if (ret == 1)
-			/* ret != 0 only if we get interrupted -arca */
-			ret = 0;
-		break;
+	DOWN_TAIL
+
+	if (!ret) {
+		UPDATE_COUNT
 	}
-	schedule();
-	DOWN_TAIL(TASK_INTERRUPTIBLE)
-	return ret;
-}
 
-int __down_trylock(struct semaphore * sem)
-{
-	return waking_non_zero_trylock(sem);
+	return ret;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/parisc/kernel/setup.c linux-2.4.20/arch/parisc/kernel/setup.c
--- linux-2.4.19/arch/parisc/kernel/setup.c	2001-02-09 19:29:44.000000000 +0000
+++ linux-2.4.20/arch/parisc/kernel/setup.c	2002-10-04 00:41:30.000000000 +0000
@@ -1,12 +1,13 @@
 /*    $Id: setup.c,v 1.8 2000/02/02 04:42:38 prumpf Exp $
  *
  *    Initial setup-routines for HP 9000 based hardware.
- * 
+ *
  *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
- *    Modifications for PA-RISC (C) 1999 Helge Deller <helge.deller@ruhr-uni-bochum.de>
+ *    Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
  *    Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
  *    Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
  *    Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
+ *    Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
  *
  *    Initial PA-RISC Version: 04-23-1999 by Helge Deller
  *
@@ -19,596 +20,308 @@
  *    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.
  *
  */
 
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/ptrace.h>
-#include <linux/sched.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/user.h>
-#include <linux/tty.h>
 #include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
+#include <linux/kernel.h>
+#include <linux/blk.h>          /* for initrd_start and initrd_end */
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/console.h>
-#include <linux/bootmem.h>
-#include <linux/delay.h>
+#include <linux/seq_file.h>
+#define PCI_DEBUG
 #include <linux/pci.h>
-#include <linux/threads.h>
+#undef PCI_DEBUG
+#include <linux/proc_fs.h>
 
-#include <asm/cache.h>
-#include <asm/hardware.h>	/* for register_driver() stuff */
 #include <asm/processor.h>
-#include <asm/page.h>
 #include <asm/pdc.h>
 #include <asm/led.h>
-#include <asm/real.h>
-#include <asm/system.h>
 #include <asm/machdep.h>	/* for pa7300lc_init() proto */
 
-#include <asm/irq.h>		/* for struct irq_region */
-#include <asm/pdcpat.h>		/* for PA_VIEW PDC_PAT_CPU_GET_NUMBER etc */
-
-#include <linux/proc_fs.h>
-
 #define COMMAND_LINE_SIZE 1024
 char	saved_command_line[COMMAND_LINE_SIZE];
+char	command_line[COMMAND_LINE_SIZE];
 
-/*
-** KLUGE ALERT!
-**
-** We *really* should be using a combination of request_resource()
-** and request_region()! But request_region() requires kmalloc since
-** returns a new struct resource. And kmalloc just isn't available
-** until after mem_init() is called from start_kernel().
-**
-** FIXME: assume contiguous memory initially.
-**     Additional chunks of memory might be added to sysram_resource.sibling.
-*/
-static struct resource sysrom_resource  = {
-	name: "System ROM", start: 0x0f0000000UL, end: 0x0f00fffffUL,
-	flags: IORESOURCE_BUSY | IORESOURCE_MEM,
-	parent: &iomem_resource, sibling: NULL, child: NULL };
-
-static struct resource pdcdata_resource;
-
-static struct resource sysram_resource  = {
-	name: "System RAM", start: 0UL, end: ~0UL /* bogus */,
-	flags: IORESOURCE_MEM,
-	parent: &iomem_resource, sibling: &sysrom_resource, child: &pdcdata_resource};
-
-extern char _text;	/* start of kernel code, defined by linker */
-extern int  data_start; 
-extern char _edata;	/* end of data, begin BSS, defined by linker */
-extern char _end;	/* end of BSS, defined by linker */
-
-static struct resource data_resource    = {
-	name: "kernel Data", start: virt_to_phys(&data_start), end: virt_to_phys(&_end)-1,
-	flags: IORESOURCE_BUSY | IORESOURCE_MEM,
-	parent: &sysram_resource, sibling: NULL, child: NULL};
-
-static struct resource code_resource = {
-	name: "Kernel Code", start: virt_to_phys(&_text), end: virt_to_phys(&data_start)-1,
-	flags: IORESOURCE_BUSY | IORESOURCE_MEM,
-	parent: &sysram_resource, sibling: &data_resource, child: NULL};
-
-static struct resource pdcdata_resource = {
-	name: "PDC data (Page Zero)", start: 0, end: 0x9ff,
-	flags: IORESOURCE_BUSY | IORESOURCE_MEM,
-	parent: &sysram_resource, sibling: &code_resource, child: NULL};
-
-
+/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
+struct proc_dir_entry * proc_runway_root = NULL;
+struct proc_dir_entry * proc_gsc_root = NULL;
 
+#ifdef CONFIG_EISA
+int EISA_bus;	/* This has to go somewhere in architecture specific code. */
+#endif
 
-struct system_cpuinfo_parisc boot_cpu_data;
-struct cpuinfo_parisc cpu_data[NR_CPUS];
-
-extern void do_inventory(void);
-extern void cache_init(void);
-extern struct hp_device * register_module(void *hpa);
-
-static int cpu_driver_callback(struct hp_device *, struct pa_iodc_driver *);
-
-static struct pa_iodc_driver cpu_drivers_for[] = {
-	{HPHW_NPROC, 0x0, 0x0, 0x0, 0, 0,
-		DRIVER_CHECK_HWTYPE,
-		"CPU", "PARISC", (void *) cpu_driver_callback},
-	{0,0,0,0,0,0,
-		0,
-		(char *) NULL, (char *) NULL, (void *) NULL }
-};
+void __init setup_cmdline(char **cmdline_p)
+{
+	extern unsigned int boot_args[];
 
-static long fallback_cpu_hpa[] = { 0xfffa0000L, 0xfffbe000L, 0x0 };
+	/* Collect stuff passed in from the boot loader */
 
+	/* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */
+	if (boot_args[0] < 64) {
+		/* called from hpux boot loader */
+		saved_command_line[0] = '\0';
+	} else {
+		strcpy(saved_command_line, (char *)__va(boot_args[1]));
 
-/*
-**  	PARISC CPU driver - claim "device" and initialize CPU data structures.
-**
-** Consolidate per CPU initialization into (mostly) one module.
-** Monarch CPU will initialize boot_cpu_data which shouldn't
-** change once the system has booted.
-**
-** The callback *should* do per-instance initialization of
-** everything including the monarch. Some of the code that's
-** in setup.c:start_parisc() should migrate here and start_parisc()
-** should "register_driver(cpu_driver_for)" before calling
-** do_inventory().
-**
-** The goal of consolidating CPU initialization into one place is
-** to make sure all CPU's get initialized the same way.
-** It would be nice if the even the manarch through the exact same code path.
-** (up to rendevous at least).
-*/
-#undef ASSERT
-#define ASSERT(expr) \
-	if(!(expr)) { \
-		printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
-		panic(#expr); \
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
+		{
+		    initrd_start = (unsigned long)__va(boot_args[2]);
+		    initrd_end = (unsigned long)__va(boot_args[3]);
+		}
+#endif
 	}
 
-static int
-cpu_driver_callback(struct hp_device *d, struct pa_iodc_driver *dri)
+	strcpy(command_line, saved_command_line);
+	*cmdline_p = command_line;
+}
+
+#ifdef CONFIG_PA11
+void __init dma_ops_init(void)
 {
-#ifdef __LP64__
-	extern int pdc_pat;	/* arch/parisc/kernel/inventory.c */
-	static unsigned long pdc_result[32] __attribute__ ((aligned (8))) = {0,0,0,0};
-#endif
-	struct cpuinfo_parisc *p;
+	switch (boot_cpu_data.cpu_type) {
+	case pcx:
+		/*
+		 * We've got way too many dependencies on 1.1 semantics
+		 * to support 1.0 boxes at this point.
+		 */
+		panic(	"PA-RISC Linux currently only supports machines that conform to\n"
+			"the PA-RISC 1.1 or 2.0 architecture specification.\n");
 
-#ifndef CONFIG_SMP
-	if (boot_cpu_data.cpu_count > 0) {
-		printk(KERN_INFO "CONFIG_SMP disabled - not claiming addional CPUs\n");
-		return(1);
+	case pcxs:
+	case pcxt:
+		hppa_dma_ops = &pcx_dma_ops;
+		break;
+	case pcxl2:
+		pa7300lc_init();
+	case pcxl: /* falls through */
+		hppa_dma_ops = &pcxl_dma_ops;
+		break;
+	default:
+		break;
 	}
+}
 #endif
 
-	p = &cpu_data[boot_cpu_data.cpu_count];
-	boot_cpu_data.cpu_count++;
-
-/* TODO: Enable FP regs - done early in start_parisc() now */
-
-	/* initialize counters */
-	memset(p, 0, sizeof(struct cpuinfo_parisc));
+extern int init_per_cpu(int cpuid);
+extern void collect_boot_cpu_data(void);
 
-	p->hpa = (unsigned long) d->hpa; /* save CPU hpa */
+void __init setup_arch(char **cmdline_p)
+{
+	init_per_cpu(smp_processor_id());	/* Set Modes & Enable FP */
 
 #ifdef __LP64__
-	if (pdc_pat) {
-		ulong status;
-	        pdc_pat_cell_mod_maddr_block_t pa_pdc_cell;
-
-		status = pdc_pat_cell_module(& pdc_result, d->pcell_loc,
-			d->mod_index, PA_VIEW, & pa_pdc_cell);
-
-		ASSERT(PDC_RET_OK == status);
-
-		/* verify it's the same as what do_pat_inventory() found */
-		ASSERT(d->mod_info == pa_pdc_cell.mod_info);
-		ASSERT(d->pmod_loc == pa_pdc_cell.mod_location);
-		ASSERT(d->mod_path == pa_pdc_cell.mod_path);
-
-		p->txn_addr = pa_pdc_cell.mod[0];   /* id_eid for IO sapic */
-
-		/* get the cpu number */
-		status = mem_pdc_call( PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
-				__pa(& pdc_result), d->hpa);
+	printk(KERN_INFO "The 64-bit Kernel has started...\n");
+#else
+	printk(KERN_INFO "The 32-bit Kernel has started...\n");
+#endif
 
-		ASSERT(PDC_RET_OK == status);
+	pdc_console_init();
 
-		p->cpuid = pdc_result[0];
+#ifdef CONFIG_PDC_NARROW
+	printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
+#endif
+	setup_pdc();
+	setup_cmdline(cmdline_p);
+	collect_boot_cpu_data();
+	do_memory_inventory();  /* probe for physical memory */
+	cache_init();
+	paging_init();
 
-	} else
+#ifdef CONFIG_CHASSIS_LCD_LED
+	/* initialize the LCD/LED after boot_cpu_data is available ! */
+        led_init();				/* LCD/LED initialization */
 #endif
-	{
-		p->txn_addr = (unsigned long) d->hpa;	/* for normal parisc */
 
-		/* logical CPU ID and update global counter */
-		p->cpuid = boot_cpu_data.cpu_count - 1;
-	}
+#ifdef CONFIG_PA11
+	dma_ops_init();
+#endif
 
-	/*
-	** itimer and ipi IRQ handlers are statically initialized in
-	** arch/parisc/kernel/irq.c
-	*/
-	p->region = irq_region[IRQ_FROM_REGION(CPU_IRQ_REGION)];
+#ifdef CONFIG_VT
+# if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+        conswitchp = &dummy_con;        /* we use take_over_console() later ! */
+# endif
+#endif
 
-	return(0);
 }
 
+/*
+ * Display cpu info for all cpu's.
+ * for parisc this is in processor.c
+ */
+extern int show_cpuinfo (struct seq_file *m, void *v);
 
-void __xchg_called_with_bad_pointer(void)
+static void *
+c_start (struct seq_file *m, loff_t *pos)
 {
-    printk(KERN_EMERG "xchg() called with bad pointer !\n");
+    	/* Looks like the caller will call repeatedly until we return
+	 * 0, signaling EOF perhaps.  This could be used to sequence
+	 * through CPUs for example.  Since we print all cpu info in our
+	 * show_cpuinfo() disregarding 'pos' (which I assume is 'v' above)
+	 * we only allow for one "position".  */
+	return ((long)*pos < 1) ? (void *)1 : NULL;
 }
 
-
-/* Some versions of IODC don't list the CPU, and since we don't walk
- * the bus yet, we have to probe for processors at well known hpa
- * addresses.  
- */
-
-void __init register_fallback_cpu (void)
+static void *
+c_next (struct seq_file *m, void *v, loff_t *pos)
 {
-	struct hp_device *d = NULL;
-	int i = 0;
-	
-#ifdef CONFIG_SMP
-#error "Revisit CPU fallback addresses for SMP (Assuming bus walk hasn't been implemented)"
-#endif
-	printk ("No CPUs reported by firmware - probing...\n");
-	
-	while (fallback_cpu_hpa[i]) {
-		
-		d = register_module ((void *) fallback_cpu_hpa[i]);
-		
-		if (d > 0) {
-			printk ("Found CPU at %lx\n", fallback_cpu_hpa[i]);
-			cpu_driver_callback (d, 0);
-			return;
-		}
-		
-		i++;
-	}
-	
-	panic ("No CPUs found.  System halted.\n");
-	return;
+	++*pos;
+	return c_start(m, pos);
 }
 
-
-/*
- * Get CPU information and store it in the boot_cpu_data structure.  */
-void __init collect_boot_cpu_data(void)
+static void
+c_stop (struct seq_file *m, void *v)
 {
-	memset(&boot_cpu_data,0,sizeof(boot_cpu_data));
-
-	boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
-
-	/* get CPU-Model Information... */
-#define p ((unsigned long *)&boot_cpu_data.pdc.model)
-	if(pdc_model_info(&boot_cpu_data.pdc.model)==0)
-		printk("model	%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
-			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
-#undef p
-
-	if(pdc_model_versions(&boot_cpu_data.pdc.versions, 0)==0)
-		printk("vers	%08lx\n", boot_cpu_data.pdc.versions.cpuid);
-
-	if(pdc_model_cpuid(&boot_cpu_data.pdc.cpuid)==0)
-		printk("cpuid	%08lx\n", boot_cpu_data.pdc.cpuid.cpuid);
-	
-	printk("CPUID	vers %ld rev %ld\n",
-		(boot_cpu_data.pdc.cpuid.cpuid >> 5) & 127,
-		boot_cpu_data.pdc.cpuid.cpuid & 31);
-
-	if (pdc_model_sysmodel(boot_cpu_data.pdc.sys_model_name)==0)
-		printk("model	%s\n",boot_cpu_data.pdc.sys_model_name);
-
-	boot_cpu_data.model_name = parisc_getHWdescription(HPHW_NPROC,
-		boot_cpu_data.pdc.model.hversion>>4,
-		boot_cpu_data.pdc.model.sversion>>8);
-	
-	boot_cpu_data.hversion =  boot_cpu_data.pdc.model.hversion;
-	boot_cpu_data.sversion =  boot_cpu_data.pdc.model.sversion;
-
-	boot_cpu_data.cpu_type =
-			parisc_get_cpu_type(boot_cpu_data.pdc.model.hversion);
-
-	boot_cpu_data.cpu_name = cpu_name_version[boot_cpu_data.cpu_type][0];
-	boot_cpu_data.family_name = cpu_name_version[boot_cpu_data.cpu_type][1];
 }
 
+struct seq_operations cpuinfo_op = {
+	start:	c_start,
+	next:	c_next,
+	stop:	c_stop,
+	show:	show_cpuinfo
+};
 
-#ifdef __LP64__
-#define COMMAND_GLOBAL  0xfffffffffffe0030UL
-#else
-#define COMMAND_GLOBAL  0xfffe0030
-#endif
-
-#define CMD_RESET       5       /* reset any module */
-
-/*
-** The Wright Brothers and Gecko systems have a H/W problem
-** (Lasi...'nuf said) may cause a broadcast reset to lockup
-** the system. An HVERSION dependent PDC call was developed
-** to perform a "safe", platform specific broadcast reset instead
-** of kludging up all the code.
-**
-** Older machines which do not implement PDC_BROADCAST_RESET will
-** return (with an error) and the regular broadcast reset can be
-** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
-** the PDC call will not return (the system will be reset).
-*/
-static int
-reset_parisc(struct notifier_block *self, unsigned long command, void *ptr)
+static void parisc_proc_mkdir(void)
 {
-	printk("%s: %s(cmd=%lu)\n", __FILE__, __FUNCTION__, command);
-
-	switch(command) {
-	case MACH_RESTART:
-#ifdef FASTBOOT_SELFTEST_SUPPORT
-		/*
-		** If user has modified the Firmware Selftest Bitmap,
-		** run the tests specified in the bitmap after the
-		** system is rebooted w/PDC_DO_RESET.
-		**
-		** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
-		**
-		** Using "directed resets" at each processor with the MEM_TOC
-		** vector cleared will also avoid running destructive
-		** memory self tests. (Not implemented yet)
-		*/
-		if (ftc_bitmap) {
-			mem_pdc_call( PDC_BROADCAST_RESET,
-				PDC_DO_FIRM_TEST_RESET, PDC_FIRM_TEST_MAGIC,
-				ftc_bitmap);
+	/*
+	** Can't call proc_mkdir() until after proc_root_init() has been
+	** called by start_kernel(). In other words, this code can't
+	** live in arch/.../setup.c because start_parisc() calls
+	** start_kernel().
+	*/
+	switch (boot_cpu_data.cpu_type) {
+	case pcxl:
+	case pcxl2:
+		if (NULL == proc_gsc_root)
+		{
+			proc_gsc_root = proc_mkdir("bus/gsc", 0);
 		}
-#endif
-
-		/* "Normal" system reset */
-		(void) mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET,
-			0L, 0L, 0L);
-
-		/* Nope...box should reset with just CMD_RESET now */
-		gsc_writel(CMD_RESET, COMMAND_GLOBAL);
-
-		/* Wait for RESET to lay us to rest. */
-		while (1) ;
-
 		break;
+        case pcxt_:
+        case pcxu:
+        case pcxu_:
+        case pcxw:
+        case pcxw_:
+        case pcxw2:
+                if (NULL == proc_runway_root)
+                {
+                        proc_runway_root = proc_mkdir("bus/runway", 0);
+                }
+                break;
 	}
-	return NOTIFY_DONE;
 }
 
-static struct notifier_block parisc_block = { reset_parisc, NULL, 0 };
+static struct resource central_bus = {
+	name:	"Central Bus",
+	start:	(unsigned long)0xfffffffffff80000,
+	end:    (unsigned long)0xfffffffffffaffff,
+	flags:	IORESOURCE_MEM,
+};
 
+static struct resource local_broadcast = {
+	name:	"Local Broadcast",
+	start:	(unsigned long)0xfffffffffffb0000,
+	end:	(unsigned long)0xfffffffffffdffff,
+	flags:	IORESOURCE_MEM,
+};
 
-/*  start_parisc() will be called from head.S to setup our new memory_start 
-    and actually start our kernel !
-    Memory-Layout is:
-	- Kernel-Image (code+data+BSS)
-	- Stack (stack-size see below!, stack-setup-code is in head.S)
-	- memory_start at end of stack..
-*/
-
-unsigned long mem_start, mem_max;
-unsigned long start_pfn, max_pfn;
-extern asmlinkage void __init start_kernel(void);
-
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
+static struct resource global_broadcast = {
+	name:	"Global Broadcast",
+	start:	(unsigned long)0xfffffffffffe0000,
+	end:	(unsigned long)0xffffffffffffffff,
+	flags:	IORESOURCE_MEM,
+};
 
-void __init start_parisc(unsigned arg0, unsigned arg1,
-			 unsigned arg2, unsigned arg3)
+int __init parisc_init_resources(void)
 {
-	register unsigned long ccr;
-	unsigned long memory_start;
-
-	/* Clear BSS */
+	int result;
 
-	{
-		char *p = &_edata, *q = &_end;
-
-		while (p < q) {
-			*p++ = 0;
-		}
+	result = request_resource(&iomem_resource, &central_bus);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %s address space!\n", 
+		       __FILE__, central_bus.name);
+		return result;
 	}
 
-
-	pdc_console_init();
-
-#ifdef __LP64__
-	printk("The 64-bit Kernel has started...\n");
-#else
-	printk("The 32-bit Kernel has started...\n");
-#endif
-
-	/*
-	** Enable FP coprocessor
-	**
-	** REVISIT: ccr should be set by PDC_COPROC results to support PA1.0.
-	** Hardcoding works for PA1.1 processors.
-	**
-	** REVISIT: this could be done in the "code 22" trap handler.
-	** (frowands idea - that way we know which processes need FP
-	** registers saved on the interrupt stack.)
-	**
-	** NEWS FLASH: wide kernels need FP coprocessor enabled to handle
-	** formatted printing of %lx for example (double divides I think)
-	*/
-	ccr = 0xc0;
-	mtctl(ccr, 10);
-	printk("Enabled FP coprocessor\n");
-
-#ifdef __LP64__
-	printk( "If this is the LAST MESSAGE YOU SEE, you're probably using\n"
-		"32-bit millicode by mistake.\n");
-#endif
-
-	memory_start = (unsigned long) &_end;
-	memory_start = (memory_start + PAGE_SIZE) & PAGE_MASK;
-	printk("Free memory starts at: 0x%lx\n", memory_start);
-
-	/* Collect stuff passed in from the boot loader */
-	printk(KERN_WARNING  "%s(0x%x,0x%x,0x%x,0x%x)\n", 
-		    __FUNCTION__, arg0, arg1, arg2, arg3);
-
-	/* arg0 is free-mem start, arg1 is ptr to command line */
-	if (arg0 < 64) {
-		/* called from hpux boot loader */
-		saved_command_line[0] = '\0';
-	} else {
-		strcpy(saved_command_line, (char *)__va(arg1));
-		printk("PALO command line: '%s'\nPALO initrd %x-%x\n",
-		    saved_command_line, arg2, arg3);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-		if (arg2 != 0) /* did palo pass us a ramdisk? */
-		{
-		    initrd_start = (unsigned long)__va(arg2);
-		    initrd_end = (unsigned long)__va(arg3);
-		}
-#endif
+	result = request_resource(&iomem_resource, &local_broadcast);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %saddress space!\n", 
+		       __FILE__, local_broadcast.name);
+		return result;
 	}
 
-	mem_start = __pa(memory_start);
-#define MAX_MEM (512*1024*1024)
-	mem_max = (PAGE0->imm_max_mem > MAX_MEM ? MAX_MEM : PAGE0->imm_max_mem);
-
-	collect_boot_cpu_data();
+	result = request_resource(&iomem_resource, &global_broadcast);
+	if (result < 0) {
+		printk(KERN_ERR 
+		       "%s: failed to claim %s address space!\n", 
+		       __FILE__, global_broadcast.name);
+		return result;
+	}
 
-	/* initialize the LCD/LED after boot_cpu_data is available ! */
-        led_init();				/* LCD/LED initialization */
+	return 0;
+}
 
-	do_inventory();				/* probe for hardware */
-        register_driver(cpu_drivers_for);	/* claim all the CPUs */
+extern void gsc_init(void);
+extern void processor_init(void);
+extern void ccio_init(void);
+extern void dino_init(void);
+extern void iosapic_init(void);
+extern void lba_init(void);
+extern void sba_init(void);
+extern void eisa_init(void);
 
-	if (boot_cpu_data.cpu_count == 0)
-	    register_fallback_cpu();
+void __init parisc_init(void)
+{
+	parisc_proc_mkdir();
+	parisc_init_resources();
+	do_device_inventory();                  /* probe for hardware */
 
-	printk("CPU(s): %d x %s at %d.%06d MHz\n", 
+	processor_init();
+	printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
 			boot_cpu_data.cpu_count,
 			boot_cpu_data.cpu_name,
-			boot_cpu_data.cpu_hz / 1000000, 
+			boot_cpu_data.cpu_hz / 1000000,
 			boot_cpu_data.cpu_hz % 1000000	);
 
-	switch (boot_cpu_data.cpu_type) {
-	case pcx:
-	case pcxs:
-	case pcxt:
-		hppa_dma_ops = &pcx_dma_ops;
-		break;
-	case pcxl2:
-		pa7300lc_init();
-	case pcxl: /* falls through */
-		hppa_dma_ops = &pcxl_dma_ops;
-		break;
-	default:
-		break;
-	}
-
-#if 1
-	/* KLUGE! this really belongs in kernel/resource.c! */
-	iomem_resource.end = ~0UL;
-#endif
-	sysram_resource.end = mem_max - 1;
-	notifier_chain_register(&mach_notifier, &parisc_block);
-	start_kernel(); 	/* now back to arch-generic code... */
-}
-
-void __init setup_arch(char **cmdline_p)
-{
-	unsigned long bootmap_size;
-	unsigned long start_pfn;
-	unsigned long mem_free;
-
-	*cmdline_p = saved_command_line;
-
-	/* initialize bootmem */
-
-	start_pfn = PFN_UP(mem_start);
-	max_pfn = PFN_DOWN(mem_max);
-
-	bootmap_size = init_bootmem(start_pfn, max_pfn);
-
-	mem_start += bootmap_size;
-	mem_free = mem_max - mem_start;
-
-	/* free_bootmem handles rounding nicely */
-	printk("free_bootmem(0x%lx, 0x%lx)\n", (unsigned long)mem_start,
-			(unsigned long)mem_free);
-	free_bootmem(mem_start, mem_free);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	printk("initrd: %08x-%08x\n", (int) initrd_start, (int) initrd_end);
-
-	if (initrd_end != 0) {
-		initrd_below_start_ok = 1;
-		reserve_bootmem(__pa(initrd_start), initrd_end - initrd_start);
-	}
+	/* These are in a non-obvious order, will fix when we have an iotree */
+#if defined(CONFIG_IOSAPIC)
+	iosapic_init();
 #endif
-
-	cache_init();
-
-	paging_init();
-
-	if((unsigned long)&init_task_union&(INIT_TASK_SIZE - 1)) {
-		printk("init_task_union not aligned.  Please recompile the kernel after changing the first line in arch/parisc/kernel/init_task.c from \n\"#define PAD 0\" to\n\"#define PAD 1\" or vice versa\n");
-		for(;;);
-	}
-
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	/* nothing */
-#elif CONFIG_VT
-#if   defined(CONFIG_STI_CONSOLE)
-	conswitchp = &dummy_con;	/* we use take_over_console() later ! */
-#elif defined(CONFIG_IODC_CONSOLE)
-	conswitchp = &prom_con;		/* it's currently really "prom_con" */
-#elif defined(CONFIG_DUMMY_CONSOLE)
-	conswitchp = &dummy_con;
+#if defined(CONFIG_IOMMU_SBA)
+	sba_init();
 #endif
+#if defined(CONFIG_PCI_LBA)
+	lba_init();
 #endif
 
-}
-
-#ifdef CONFIG_PROC_FS
-/*
- *	Get CPU information for use by procfs.
- */
-
-int get_cpuinfo(char *buffer)
-{
-	char		  *p = buffer;
-	int		  n;
+	/* CCIO before any potential subdevices */
+#if defined(CONFIG_IOMMU_CCIO)
+	ccio_init();
+#endif
 
-	for(n=0; n<boot_cpu_data.cpu_count; n++) {
-#ifdef CONFIG_SMP
-		if (!(cpu_online_map & (1<<n)))
-			continue;
-#endif
-		p += sprintf(p, "processor\t: %d\n"
-				"cpu family\t: PA-RISC %s\n",
-				n, boot_cpu_data.family_name);
-
-		p += sprintf(p, "cpu\t\t: %s\n",  boot_cpu_data.cpu_name );
-	
-		/* cpu MHz */
-		p += sprintf(p, "cpu MHz\t\t: %d.%06d\n",
-				 boot_cpu_data.cpu_hz / 1000000, 
-				 boot_cpu_data.cpu_hz % 1000000  );
-
-		p += sprintf(p, "model\t\t: %s\n"
-				"model name\t: %s\n",
-				boot_cpu_data.pdc.sys_model_name,
-				boot_cpu_data.model_name);
-
-		p += sprintf(p, "hversion\t: 0x%08x\n"
-			        "sversion\t: 0x%08x\n",
-				boot_cpu_data.hversion,
-				boot_cpu_data.sversion );
-
-		p += get_cache_info(p);
-		/* print cachesize info ? */
-		p += sprintf(p, "bogomips\t: %lu.%02lu\n",
-			     (loops_per_sec+2500)/500000,
-			     ((loops_per_sec+2500)/5000) % 100);
-	}
-	return p - buffer;
-}
+	/*
+	 * Need to register Asp & Wax before the EISA adapters for the IRQ
+	 * regions.  EISA must come before PCI mem_map.mape beresou00:00:00.000000000 +00-
 #define LBø_CFG_RD(size, mask) \
 stati before PCI m, mask) \
 statii before PCI m, maspanic,25 +71 of consoliam_map_bus.name);
+		return result;
 	}bits, and (b) fvice.
+ * @dev: The sevice wh+	 */
+	wait_on_irq(cpu, where);
irq(cpu, whget_user(f->read_ess IAl/ptrace.c
--- lirently reallyops_per_s IRQ_REGION(i@dev: The dev)
 {ev: The sevice wh+	 */
+	wai whget_user
-#elif define>ifr_ifrumepage: h_data.model_na before PCIies 0x%lx\n",
+			boot_cpu_data.pdc.capabilities);
+
+	if (pdc_mo. 
+	 */
+	hget_user(f->read_ess IAl/ptrace.c
--- fine CMD_RESET       5      ################
r Asp & Wax 4 @@
 	 * on the srdc_mo. 
+	 */############
r Asp & Wax 4 @@
 	 * o_cpu_data.pdc+	sync
+	bv@
  * ernels view ontf(p, "cpu MHz\ti_eoi_addr"cpu MHz\ti[MM’„MEM;
+		rintf(p,_data.pdc.cap o_cpu_data.pdc+	sync
+	bv@
m, void *v, loff_t *pos)
 {
-	strHz\ti_eoi_addr"cpu MHISA_INT_MASK, mace_mask);
-	restore_flags(flags);
-}
-
-static unsigned i *v, lfor Sz\tiu, where)"cpu MHz\ti[MM’„MEM;
+	ask_struct, i\
+	hogical CPU ID ando\n\"# L;
+	
+	swilso get opportunity to send e 0:		printk(KERN_INFO "Gecko-style spe loallocating at 0/07/0{
+		/* calle senb e 0:		printk(KERN_INFO  get opportunity to send e 0:&	printk(KERN_INFOo. 
+	 */
+	hget_yvhr->re)boot_cpu_data,+	hgat_yvhr->re)boot_cpu_data,+	hgat_yvhr->re)be-statict oppore unsi(p);
-		/* er)
+	ENTRY_Nple.  Since we print aNTRY_Nple.  STRY_NAME(hpux_uni  Semented_wrapper)
+	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTR_free_range(NTRY_NDMPoff_t *pos)	#ifdef DELAYED_RESOURCE_CNT
-			ioc->saved_cnt--;
+			idva = ioc->saved_iova[ioc->saved_cnt];
-			size = 
+	
+	swic
--- lirently re_yvhr->re)boo/* er)
+	ENTRY_Npsignal.c	200q_ops = {
-	iosapic_di0000 20000
@@urrentloallocating at 0/07/0{
+		/e use take_over_conput_u{
+		/* calle"/Config.iux/init.h>
+#includ  <linux/sched.h>
+#i m, me <linux/mc146818rtc.h>		/ed(CONFIG_I818rtc.h>		/ed(CONFIG_ma_ops;
-		t)
 {
 	u32 iovNTRY_NAMEwai whgetinclY_Nple.  STple.  STRY_NAegister Asp & WaxUP(x)	(((x) + PAGE_SIZE-1)free_range(NTRYTRY_NDMPof