
From: Ralf Baechle <ralf@linux-mips.org>

Update the generic MIPS code.  Highlights are oprofile for MIPS, initially for
the PMC-Sierra RM9000.  We're also taking a significantly more aggressive
approach to the TLB exception handlers which now are runtime generated and
provide an upto 20% speedup on certain micro benchmarks.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 /dev/null                                    |  885 ---------------------------
 25-akpm/arch/mips/Makefile                   |   24 
 25-akpm/arch/mips/kernel/Makefile            |    8 
 25-akpm/arch/mips/kernel/irq-rm9000.c        |  149 ++++
 25-akpm/arch/mips/kernel/irq.c               |    2 
 25-akpm/arch/mips/kernel/linux32.c           |    2 
 25-akpm/arch/mips/kernel/mips_ksyms.c        |    7 
 25-akpm/arch/mips/kernel/module.c            |    2 
 25-akpm/arch/mips/kernel/process.c           |   43 +
 25-akpm/arch/mips/kernel/scall32-o32.S       |  209 ++----
 25-akpm/arch/mips/kernel/scall64-64.S        |   10 
 25-akpm/arch/mips/kernel/scall64-o32.S       |   67 --
 25-akpm/arch/mips/kernel/semaphore.c         |    3 
 25-akpm/arch/mips/kernel/setup.c             |   23 
 25-akpm/arch/mips/kernel/signal-common.h     |  136 ++++
 25-akpm/arch/mips/kernel/signal.c            |  149 ----
 25-akpm/arch/mips/kernel/signal32.c          |   20 
 25-akpm/arch/mips/kernel/signal_n32.c        |   51 -
 25-akpm/arch/mips/kernel/smp.c               |    4 
 25-akpm/arch/mips/kernel/syscall.c           |   18 
 25-akpm/arch/mips/kernel/time.c              |    3 
 25-akpm/arch/mips/kernel/traps.c             |   34 -
 25-akpm/arch/mips/kernel/vmlinux.lds.S       |    1 
 25-akpm/arch/mips/lib-64/dump_tlb.c          |    8 
 25-akpm/arch/mips/math-emu/cp1emu.c          |    2 
 25-akpm/arch/mips/math-emu/dp_add.c          |    2 
 25-akpm/arch/mips/math-emu/dp_cmp.c          |    2 
 25-akpm/arch/mips/math-emu/dp_div.c          |    2 
 25-akpm/arch/mips/math-emu/dp_fint.c         |    2 
 25-akpm/arch/mips/math-emu/dp_flong.c        |    2 
 25-akpm/arch/mips/math-emu/dp_frexp.c        |    2 
 25-akpm/arch/mips/math-emu/dp_fsp.c          |    2 
 25-akpm/arch/mips/math-emu/dp_logb.c         |    2 
 25-akpm/arch/mips/math-emu/dp_modf.c         |    2 
 25-akpm/arch/mips/math-emu/dp_mul.c          |    2 
 25-akpm/arch/mips/math-emu/dp_scalb.c        |    2 
 25-akpm/arch/mips/math-emu/dp_simple.c       |    2 
 25-akpm/arch/mips/math-emu/dp_sqrt.c         |    2 
 25-akpm/arch/mips/math-emu/dp_sub.c          |    2 
 25-akpm/arch/mips/math-emu/dp_tint.c         |    2 
 25-akpm/arch/mips/math-emu/dp_tlong.c        |    2 
 25-akpm/arch/mips/math-emu/ieee754.c         |    2 
 25-akpm/arch/mips/math-emu/ieee754.h         |    2 
 25-akpm/arch/mips/math-emu/ieee754d.c        |    2 
 25-akpm/arch/mips/math-emu/ieee754dp.c       |    2 
 25-akpm/arch/mips/math-emu/ieee754dp.h       |    2 
 25-akpm/arch/mips/math-emu/ieee754int.h      |    2 
 25-akpm/arch/mips/math-emu/ieee754m.c        |    2 
 25-akpm/arch/mips/math-emu/ieee754sp.c       |    2 
 25-akpm/arch/mips/math-emu/ieee754sp.h       |    2 
 25-akpm/arch/mips/math-emu/ieee754xcpt.c     |    2 
 25-akpm/arch/mips/math-emu/sp_add.c          |    2 
 25-akpm/arch/mips/math-emu/sp_cmp.c          |    2 
 25-akpm/arch/mips/math-emu/sp_div.c          |    2 
 25-akpm/arch/mips/math-emu/sp_fdp.c          |    2 
 25-akpm/arch/mips/math-emu/sp_fint.c         |    2 
 25-akpm/arch/mips/math-emu/sp_flong.c        |    2 
 25-akpm/arch/mips/math-emu/sp_frexp.c        |    2 
 25-akpm/arch/mips/math-emu/sp_logb.c         |    2 
 25-akpm/arch/mips/math-emu/sp_modf.c         |    2 
 25-akpm/arch/mips/math-emu/sp_mul.c          |    2 
 25-akpm/arch/mips/math-emu/sp_scalb.c        |    2 
 25-akpm/arch/mips/math-emu/sp_simple.c       |    2 
 25-akpm/arch/mips/math-emu/sp_sqrt.c         |    2 
 25-akpm/arch/mips/math-emu/sp_sub.c          |    2 
 25-akpm/arch/mips/math-emu/sp_tint.c         |    2 
 25-akpm/arch/mips/math-emu/sp_tlong.c        |    2 
 25-akpm/arch/mips/mm/Makefile                |   39 -
 25-akpm/arch/mips/mm/c-r4k.c                 |   78 +-
 25-akpm/arch/mips/mm/c-sb1.c                 |    2 
 25-akpm/arch/mips/mm/cache.c                 |   13 
 25-akpm/arch/mips/mm/cerr-sb1.c              |   22 
 25-akpm/arch/mips/mm/cex-sb1.S               |    1 
 25-akpm/arch/mips/mm/dma-ip32.c              |  382 +++++++++++
 25-akpm/arch/mips/mm/init.c                  |    3 
 25-akpm/arch/mips/mm/pg-r4k.c                |   17 
 25-akpm/arch/mips/mm/pg-sb1.c                |  257 ++++---
 25-akpm/arch/mips/mm/pgtable-32.c            |    4 
 25-akpm/arch/mips/mm/pgtable-64.c            |    1 
 25-akpm/arch/mips/mm/pgtable.c               |    1 
 25-akpm/arch/mips/mm/sc-rm7k.c               |    6 
 25-akpm/arch/mips/mm/tlb-andes.c             |    1 
 25-akpm/arch/mips/mm/tlb-sb1.c               |    3 
 25-akpm/arch/mips/mm/tlbex-fault.S           |   28 
 25-akpm/arch/mips/mm/tlbex.c                 |  764 +++++++++++++++++++++--
 25-akpm/arch/mips/oprofile/Kconfig           |   23 
 25-akpm/arch/mips/oprofile/Makefile          |   15 
 25-akpm/arch/mips/oprofile/common.c          |  106 +++
 25-akpm/arch/mips/oprofile/op_impl.h         |   37 +
 25-akpm/arch/mips/oprofile/op_model_rm9000.c |  137 ++++
 25-akpm/arch/mips/pci/pci.c                  |    6 
 25-akpm/include/asm-mips/addrspace.h         |    1 
 25-akpm/include/asm-mips/bitops.h            |   14 
 25-akpm/include/asm-mips/bootinfo.h          |    1 
 25-akpm/include/asm-mips/break.h             |    2 
 25-akpm/include/asm-mips/cpu-features.h      |   23 
 25-akpm/include/asm-mips/cpu-info.h          |    1 
 25-akpm/include/asm-mips/debug.h             |    4 
 25-akpm/include/asm-mips/elf.h               |   24 
 25-akpm/include/asm-mips/gt64120.h           |  227 +++++-
 25-akpm/include/asm-mips/hardirq.h           |    3 
 25-akpm/include/asm-mips/hazards.h           |   85 +-
 25-akpm/include/asm-mips/io.h                |  530 +++++++---------
 25-akpm/include/asm-mips/irq_cpu.h           |    1 
 25-akpm/include/asm-mips/m48t37.h            |   35 +
 25-akpm/include/asm-mips/mach-generic/ide.h  |   82 +-
 25-akpm/include/asm-mips/mipsregs.h          |  101 ++-
 25-akpm/include/asm-mips/mmu_context.h       |   28 
 25-akpm/include/asm-mips/pgtable-32.h        |    2 
 25-akpm/include/asm-mips/pmon.h              |   39 -
 25-akpm/include/asm-mips/prefetch.h          |   44 +
 25-akpm/include/asm-mips/processor.h         |    5 
 25-akpm/include/asm-mips/r4kcache.h          |   15 
 25-akpm/include/asm-mips/reg.h               |  129 +++
 25-akpm/include/asm-mips/sigcontext.h        |    5 
 25-akpm/include/asm-mips/spinlock.h          |    1 
 25-akpm/include/asm-mips/stackframe.h        |   20 
 25-akpm/include/asm-mips/string.h            |    4 
 25-akpm/include/asm-mips/uaccess.h           |   27 
 25-akpm/include/asm-mips/unistd.h            |    3 
 arch/mips/lib/csum_partial_copy.c            |    0 
 121 files changed, 3275 insertions(+), 2071 deletions(-)

diff -puN arch/mips/kernel/irq.c~mips-generic-mips-updates arch/mips/kernel/irq.c
--- 25/arch/mips/kernel/irq.c~mips-generic-mips-updates	2005-01-29 11:25:48.562486688 -0800
+++ 25-akpm/arch/mips/kernel/irq.c	2005-01-29 11:25:48.725461912 -0800
@@ -125,7 +125,7 @@ void __init init_IRQ(void)
 		irq_desc[i].action  = NULL;
 		irq_desc[i].depth   = 1;
 		irq_desc[i].handler = &no_irq_type;
-		irq_desc[i].lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&irq_desc[i].lock);
 	}
 
 	arch_init_irq();
diff -puN /dev/null arch/mips/kernel/irq-rm9000.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/kernel/irq-rm9000.c	2005-01-29 11:25:48.726461760 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * 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.
+ *
+ * Handler for RM9000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm9k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void mask_rm9k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x1000 << (irq - irq_base));
+}
+
+static inline void rm9k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm9k_cpu_irq_startup(unsigned int irq)
+{
+	rm9k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm9k_cpu_irq_shutdown	rm9k_cpu_irq_disable
+
+/*
+ * Performance counter interrupts are global on all processors.
+ */
+static void local_rm9k_perfcounter_irq_startup(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+
+	rm9k_cpu_irq_enable(irq);
+}
+
+static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 0, 1);
+
+	return 0;
+}
+
+static void local_rm9k_perfcounter_irq_shutdown(void *args)
+{
+	unsigned int irq = (unsigned int) args;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm9k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
+{
+	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1);
+}
+
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm9k_cpu_irq_end.
+ */
+static void rm9k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm9k_irq(irq);
+}
+
+static void rm9k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm9k_irq(irq);
+}
+
+static hw_irq_controller rm9k_irq_controller = {
+	"RM9000",
+	rm9k_cpu_irq_startup,
+	rm9k_cpu_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+static hw_irq_controller rm9k_perfcounter_irq = {
+	"RM9000",
+	rm9k_perfcounter_irq_startup,
+	rm9k_perfcounter_irq_shutdown,
+	rm9k_cpu_irq_enable,
+	rm9k_cpu_irq_disable,
+	rm9k_cpu_irq_ack,
+	rm9k_cpu_irq_end,
+};
+
+unsigned int rm9000_perfcount_irq;
+
+EXPORT_SYMBOL(rm9000_perfcount_irq);
+
+void __init rm9k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x0000f000);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm9k_irq_controller;
+	}
+
+	rm9000_perfcount_irq = base + 1;
+	irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq;
+
+	irq_base = base;
+}
diff -puN arch/mips/kernel/linux32.c~mips-generic-mips-updates arch/mips/kernel/linux32.c
--- 25/arch/mips/kernel/linux32.c~mips-generic-mips-updates	2005-01-29 11:25:48.564486384 -0800
+++ 25-akpm/arch/mips/kernel/linux32.c	2005-01-29 11:25:48.727461608 -0800
@@ -99,7 +99,7 @@ int cp_compat_stat(struct kstat *stat, s
 }
 
 asmlinkage unsigned long
-sys32_mmap2(unsigned long addr, size_t len, unsigned long prot,
+sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
          unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
 	struct file * file = NULL;
diff -puN arch/mips/kernel/Makefile~mips-generic-mips-updates arch/mips/kernel/Makefile
--- 25/arch/mips/kernel/Makefile~mips-generic-mips-updates	2005-01-29 11:25:48.565486232 -0800
+++ 25-akpm/arch/mips/kernel/Makefile	2005-01-29 11:25:48.728461456 -0800
@@ -8,6 +8,9 @@ obj-y		+= cpu-probe.o branch.o entry.o g
 		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
 		   time.o traps.o unaligned.o
 
+binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
+			   irix5sys.o sysirix.o
+
 ifdef CONFIG_MODULES
 obj-y				+= mips_ksyms.o module.o
 obj-$(CONFIG_MIPS32)		+= module-elf32.o
@@ -35,15 +38,16 @@ obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o 
 
 obj-$(CONFIG_SMP)		+= smp.o
 
+obj-$(CONFIG_NO_ISA)		+= dma-no-isa.o
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
 obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
+obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
 obj-$(CONFIG_IRQ_MV64340)	+= irq-mv6434x.o
 
 obj-$(CONFIG_MIPS32)		+= scall32-o32.o
 obj-$(CONFIG_MIPS64)		+= scall64-64.o
-obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
-				   irixinv.o
+obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o linux32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
diff -puN arch/mips/kernel/mips_ksyms.c~mips-generic-mips-updates arch/mips/kernel/mips_ksyms.c
--- 25/arch/mips/kernel/mips_ksyms.c~mips-generic-mips-updates	2005-01-29 11:25:48.566486080 -0800
+++ 25-akpm/arch/mips/kernel/mips_ksyms.c	2005-01-29 11:25:48.728461456 -0800
@@ -5,9 +5,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03 by Ralf Baechle
+ * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle
  * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
  */
+#include <linux/config.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
@@ -60,3 +62,6 @@ EXPORT_SYMBOL(__strnlen_user_asm);
 EXPORT_SYMBOL(csum_partial);
 
 EXPORT_SYMBOL(invalid_pte_table);
+#ifdef CONFIG_GENERIC_IRQ_PROBE
+EXPORT_SYMBOL(probe_irq_mask);
+#endif
diff -puN arch/mips/kernel/module.c~mips-generic-mips-updates arch/mips/kernel/module.c
--- 25/arch/mips/kernel/module.c~mips-generic-mips-updates	2005-01-29 11:25:48.568485776 -0800
+++ 25-akpm/arch/mips/kernel/module.c	2005-01-29 11:25:48.728461456 -0800
@@ -2,7 +2,7 @@
 #include <linux/spinlock.h>
 
 static LIST_HEAD(dbe_list);
-static spinlock_t dbe_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dbe_lock);
 
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_dbetables(unsigned long addr)
diff -puN arch/mips/kernel/process.c~mips-generic-mips-updates arch/mips/kernel/process.c
--- 25/arch/mips/kernel/process.c~mips-generic-mips-updates	2005-01-29 11:25:48.570485472 -0800
+++ 25-akpm/arch/mips/kernel/process.c	2005-01-29 11:25:48.729461304 -0800
@@ -113,19 +113,15 @@ int copy_thread(int nr, unsigned long cl
 	*childregs = *regs;
 	childregs->regs[7] = 0;	/* Clear error flag */
 
-#ifdef CONFIG_BINFMT_IRIX
+#if defined(CONFIG_BINFMT_IRIX)
 	if (current->personality != PER_LINUX) {
 		/* Under IRIX things are a little different. */
-		childregs->regs[2] = 0;
 		childregs->regs[3] = 1;
-		regs->regs[2] = p->pid;
 		regs->regs[3] = 0;
-	} else
-#endif
-	{
-		childregs->regs[2] = 0;	/* Child gets zero as return value */
-		regs->regs[2] = p->pid;
 	}
+#endif
+	childregs->regs[2] = 0;	/* Child gets zero as return value */
+	regs->regs[2] = p->pid;
 
 	if (childregs->cp0_status & ST0_CU0) {
 		childregs->regs[28] = (unsigned long) ti;
@@ -153,6 +149,36 @@ int copy_thread(int nr, unsigned long cl
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
 {
 	memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
+
+	return 1;
+}
+
+void dump_regs(elf_greg_t *gp, struct pt_regs *regs)
+{
+	int i;
+
+	for (i = 0; i < EF_R0; i++)
+		gp[i] = 0;
+	gp[EF_R0] = 0;
+	for (i = 1; i <= 31; i++)
+		gp[EF_R0 + i] = regs->regs[i];
+	gp[EF_R26] = 0;
+	gp[EF_R27] = 0;
+	gp[EF_LO] = regs->lo;
+	gp[EF_HI] = regs->hi;
+	gp[EF_CP0_EPC] = regs->cp0_epc;
+	gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
+	gp[EF_CP0_STATUS] = regs->cp0_status;
+	gp[EF_CP0_CAUSE] = regs->cp0_cause;
+#ifdef EF_UNUSED0
+	gp[EF_UNUSED0] = 0;
+#endif
+}
+
+int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
+{
+	memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
+
 	return 1;
 }
 
@@ -263,7 +289,6 @@ arch_initcall(frame_info_init);
  */
 unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	extern void ret_from_fork(void);
 	struct thread_struct *t = &tsk->thread;
 
 	/* New born processes are a special case */
diff -L arch/mips/kernel/reg.c -puN arch/mips/kernel/reg.c~mips-generic-mips-updates /dev/null
--- 25/arch/mips/kernel/reg.c
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,69 +0,0 @@
-/*
- * offset.c: Calculate pt_regs and task_struct indices.
- *
- * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-
-#define text(t) __asm__("\n@@@" t)
-#define _offset(type, member) ((unsigned long) &(((type *)NULL)->member))
-#define index(string, ptr, member) \
-	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)/sizeof(long)))
-#define size(string, size) \
-	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
-#define linefeed text("")
-
-void output_ptreg_defines(void)
-{
-	text("/* MIPS pt_regs indices. */");
-	index("#define EF_R0     ", struct pt_regs, regs[0]);
-	index("#define EF_R1     ", struct pt_regs, regs[1]);
-	index("#define EF_R2     ", struct pt_regs, regs[2]);
-	index("#define EF_R3     ", struct pt_regs, regs[3]);
-	index("#define EF_R4     ", struct pt_regs, regs[4]);
-	index("#define EF_R5     ", struct pt_regs, regs[5]);
-	index("#define EF_R6     ", struct pt_regs, regs[6]);
-	index("#define EF_R7     ", struct pt_regs, regs[7]);
-	index("#define EF_R8     ", struct pt_regs, regs[8]);
-	index("#define EF_R9     ", struct pt_regs, regs[9]);
-	index("#define EF_R10    ", struct pt_regs, regs[10]);
-	index("#define EF_R11    ", struct pt_regs, regs[11]);
-	index("#define EF_R12    ", struct pt_regs, regs[12]);
-	index("#define EF_R13    ", struct pt_regs, regs[13]);
-	index("#define EF_R14    ", struct pt_regs, regs[14]);
-	index("#define EF_R15    ", struct pt_regs, regs[15]);
-	index("#define EF_R16    ", struct pt_regs, regs[16]);
-	index("#define EF_R17    ", struct pt_regs, regs[17]);
-	index("#define EF_R18    ", struct pt_regs, regs[18]);
-	index("#define EF_R19    ", struct pt_regs, regs[19]);
-	index("#define EF_R20    ", struct pt_regs, regs[20]);
-	index("#define EF_R21    ", struct pt_regs, regs[21]);
-	index("#define EF_R22    ", struct pt_regs, regs[22]);
-	index("#define EF_R23    ", struct pt_regs, regs[23]);
-	index("#define EF_R24    ", struct pt_regs, regs[24]);
-	index("#define EF_R25    ", struct pt_regs, regs[25]);
-	index("#define EF_R26    ", struct pt_regs, regs[26]);
-	index("#define EF_R27    ", struct pt_regs, regs[27]);
-	index("#define EF_R28    ", struct pt_regs, regs[28]);
-	index("#define EF_R29    ", struct pt_regs, regs[29]);
-	index("#define EF_R30    ", struct pt_regs, regs[30]);
-	index("#define EF_R31    ", struct pt_regs, regs[31]);
-	linefeed;
-	index("#define EF_LO     ", struct pt_regs, lo);
-	index("#define EF_HI     ", struct pt_regs, hi);
-	linefeed;
-	index("#define EF_EPC    ", struct pt_regs, cp0_epc);
-	index("#define EF_BVADDR ", struct pt_regs, cp0_badvaddr);
-	index("#define EF_STATUS ", struct pt_regs, cp0_status);
-	index("#define EF_CAUSE  ", struct pt_regs, cp0_cause);
-	linefeed;
-	size("#define EF_SIZE   ", struct pt_regs);
-	linefeed;
-}
diff -puN arch/mips/kernel/scall32-o32.S~mips-generic-mips-updates arch/mips/kernel/scall32-o32.S
--- 25/arch/mips/kernel/scall32-o32.S~mips-generic-mips-updates	2005-01-29 11:25:48.573485016 -0800
+++ 25-akpm/arch/mips/kernel/scall32-o32.S	2005-01-29 11:25:48.732460848 -0800
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -32,26 +33,30 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 	lw	t1, PT_EPC(sp)		# skip syscall on return
 
+#if defined(CONFIG_BINFMT_IRIX)
 	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
+	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
+#endif
 	addiu	t1, 4			# skip to next instruction
 	sw	t1, PT_EPC(sp)
 	beqz	t0, illegal_syscall
 
-	/* XXX Put both in one cacheline, should save a bit. */
-	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;
+	sll	t0, v0, 3
+	la	t1, sys_call_table
+	addu	t1, t0
+	lw	t2, (t1)		# syscall routine
+	lw	t3, 4(t1)		# >= 0 if we need stack arguments
+	beqz	t2, illegal_syscall
 
-	subu	t0, t3, 5		# 5 or more arguments?
 	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
-	bgez	t0, stackargs
+	bgez	t3, stackargs
 
 stack_done:
-	sw	a3, PT_R26(sp)          # save for syscall restart
-	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
-	and	t0, t1, t0
+	and	t0, t1
 	bnez	t0, syscall_trace_entry	# -> yes
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -70,9 +75,9 @@ o32_syscall_exit:
 	local_irq_disable		# make sure need_resched and
 					# signals dont change between
 					# sampling and return
-	LONG_L	a2, TI_FLAGS($28)	# current->work
+	lw	a2, TI_FLAGS($28)	# current->work
 	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2, t0
+	and	t0, a2
 	bnez	t0, o32_syscall_exit_work
 
 	j	restore_partial
@@ -116,49 +121,48 @@ syscall_trace_entry:
 	 */
 stackargs:
 	lw	t0, PT_R29(sp)		# get old user stack pointer
-	subu	t3, 4
-	sll	t1, t3, 2		# stack valid?
 
-	addu	t1, t0			# end address
-	or	t0, t1
-	bltz	t0, bad_stack		# -> sp is bad
-
-	lw	t0, PT_R29(sp)		# get old user stack pointer
-	PTR_LA	t1, 4f			# copy 1 to 3 arguments
-	sll	t3, t3, 4
-	subu	t1, t3
-	jr	t1
-
-	/* Ok, copy the args from the luser stack to the kernel stack */
 	/*
-	 * I know Ralf doesn't like nops but this avoids code
-	 * duplication for R3000 targets (and this is the
-	 * only place where ".set reorder" doesn't help).
-	 * Harald.
+	 * We intentionally keep the kernel stack a little below the top of
+	 * userspace so we don't have to do a slower byte accurate check here.
+	 */
+	lw	t5, TI_ADDR_LIMIT($28)
+	addu	t4, t0, 32
+	and	t5, t4
+	bltz	t5, bad_stack		# -> sp is bad
+
+	/* Ok, copy the args from the luser stack to the kernel stack.
+	 * t3 is the precomputed number of instruction bytes needed to
+	 * load or store arguments 6-8.
 	 */
+
+	la	t1, 5f			# load up to 3 arguments
+	subu	t1, t3
+1:	lw	t5, 16(t0)		# argument #5 from usp
 	.set    push
 	.set    noreorder
 	.set	nomacro
-1:	lw	t1, 24(t0)		# argument #7 from usp
-	nop
-	sw	t1, 24(sp)
-	nop
-2:	lw	t1, 20(t0)		# argument #5 from usp
-	nop
-	sw	t1, 20(sp)
-	nop
-3:	lw	t1, 16(t0)		# argument #5 from usp
-	nop
-	sw	t1, 16(sp)
-	nop
-4:	.set	pop
+	jr	t1
+	 addiu	t1, 6f - 5f
 
-	j	stack_done		# go back
+2:	lw	t8, 28(t0)		# argument #8 from usp
+3:	lw	t7, 24(t0)		# argument #7 from usp
+4:	lw	t6, 20(t0)		# argument #6 from usp
+5:	jr	t1
+	 sw	t5, 16(sp)		# argument #5 to ksp
+
+	sw	t8, 28(sp)		# argument #8 to ksp
+	sw	t7, 24(sp)		# argument #7 to ksp
+	sw	t6, 20(sp)		# argument #6 to ksp
+6:	j	stack_done		# go back
+	 nop
+	.set	pop
 
 	.section __ex_table,"a"
 	PTR	1b,bad_stack
 	PTR	2b,bad_stack
 	PTR	3b,bad_stack
+	PTR	4b,bad_stack
 	.previous
 
 	/*
@@ -177,7 +181,7 @@ bad_stack:
 	 * The system call does not exist in this kernel
 	 */
 illegal_syscall:
-	li	v0, ENOSYS			# error
+	li	v0, -ENOSYS			# error
 	sw	v0, PT_R2(sp)
 	li	t0, 1				# set error flag
 	sw	t0, PT_R7(sp)
@@ -238,12 +242,12 @@ illegal_syscall:
 	sw	v0, PT_R2(sp)		# result
 
 	/* Success, so skip usual error handling garbage.  */
-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
+	lw	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
 	and	t0, a2, t0
 	bnez	t0, 1f
 
-	b	o32_syscall_exit
+	j	o32_syscall_exit
 
 1:	SAVE_STATIC
 	move	a0, sp
@@ -269,69 +273,49 @@ bad_alignment:
 	END(sys_sysmips)
 
 	LEAF(sys_syscall)
-	lw	t0, PT_R29(sp)			# user sp
-
-	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
-	beqz	v0, enosys
-
-	sll	v0, a0, 2
-	la	v1, sys_syscall
-	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
+#if defined(CONFIG_BINFMT_IRIX)
+	sltiu	v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
+#else
+	subu	t0, a0, __NR_O32_Linux	# check syscall number
+	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
+#endif
+	sll	t1, t0, 3
+	beqz	v0, einval
 
-	beqz	t2, enosys			# null function pointer?
+	lw	t2, sys_call_table(t1)		# syscall routine
 
-	andi	v0, t0, 0x3			# unaligned stack pointer?
-	bnez	v0, sigsegv
+#if defined(CONFIG_BINFMT_IRIX)
+	li	v1, 4000			# nr of sys_syscall
+#else
+	li	v1, 4000 - __NR_O32_Linux	# index of sys_syscall
+#endif
+	beq	t0, v1, einval			# do not recurse
 
-	addu	v0, t0, 16			# v0 = usp + 16
-	addu	t1, v0, 12			# 3 32-bit arguments
-	lw	v1, TI_ADDR_LIMIT($28)
-	or	v0, v0, t1
-	and	v1, v1, v0
-	bltz	v1, efault
+	/* Some syscalls like execve get their arguments from struct pt_regs
+	   and claim zero arguments in the syscall table. Thus we have to
+	   assume the worst case and shuffle around all potential arguments.
+	   If you want performance, don't use indirect syscalls. */
 
 	move	a0, a1				# shift argument registers
 	move	a1, a2
 	move	a2, a3
-
-1:	lw	a3, 16(t0)
-2:	lw	t3, 20(t0)
-3:	lw	t4, 24(t0)
-
-	.section	__ex_table, "a"
-	.word	1b, efault
-	.word	2b, efault
-	.word	3b, efault
-	.previous
-
-	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
-1:
-
-	sw	t3, 16(sp)
-	sw	v1, 20(sp)
+	lw	a3, 16(sp)
+	lw	t4, 20(sp)
+	lw	t5, 24(sp)
+	lw	t6, 28(sp)
+	sw	t4, 16(sp)
+	sw	t5, 20(sp)
+	sw	t6, 24(sp)
+	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
+	sw	a1, PT_R5(sp)			# syscalls expect them there
+	sw	a2, PT_R6(sp)
+	sw	a3, PT_R7(sp)
+	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
 	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
+einval:	li	v0, -EINVAL
+	jr	ra
 	END(sys_syscall)
 
 	.macro	fifty ptr, nargs, from=1, to=50
@@ -349,12 +333,14 @@ out:	jr	ra
 	.endm
 
 	.macro	syscalltable
+#if defined(CONFIG_BINFMT_IRIX)
 	mille	sys_ni_syscall		0	/*    0 -  999 SVR4 flavour */
-	#include "irix5sys.h"			/* 1000 - 1999 32-bit IRIX */
+	mille	sys_ni_syscall		0	/* 1000 - 1999 32-bit IRIX */
 	mille	sys_ni_syscall		0	/* 2000 - 2999 BSD43 flavour */
 	mille	sys_ni_syscall		0	/* 3000 - 3999 POSIX flavour */
+#endif
 
-	sys	sys_syscall		0	/* 4000 */
+	sys	sys_syscall		8	/* 4000 */
 	sys	sys_exit		1
 	sys	sys_fork		0
 	sys	sys_read		3
@@ -405,7 +391,7 @@ out:	jr	ra
 	sys	sys_ni_syscall		0	/* was signal(2) */
 	sys	sys_geteuid		0
 	sys	sys_getegid		0	/* 4050 */
-	sys	sys_acct		0
+	sys	sys_acct		1
 	sys	sys_umount		2
 	sys	sys_ni_syscall		0
 	sys	sys_ioctl		3
@@ -485,7 +471,7 @@ out:	jr	ra
 	sys	sys_init_module		5
 	sys	sys_delete_module	1
 	sys	sys_ni_syscall		0	/* 4130	was get_kernel_syms */
-	sys	sys_quotactl		0
+	sys	sys_quotactl		4
 	sys	sys_getpgid		1
 	sys	sys_fchdir		1
 	sys	sys_bdflush		2
@@ -506,7 +492,7 @@ out:	jr	ra
 	sys	sys_sysmips		4
 	sys	sys_ni_syscall		0	/* 4150 */
 	sys	sys_getsid		1
-	sys	sys_fdatasync		0
+	sys	sys_fdatasync		1
 	sys	sys_sysctl		1
 	sys	sys_mlock		2
 	sys	sys_munlock		2	/* 4155 */
@@ -640,19 +626,16 @@ out:	jr	ra
 
 	.endm
 
+	/* We pre-compute the number of _instruction_ bytes needed to
+	   load or store the arguments 6-8. Negative values are ignored. */
+
 	.macro  sys function, nargs
 	PTR	\function
+	LONG	(\nargs << 2) - (5 << 2)
 	.endm
 
 	.align	3
-sys_call_table:
+	.type	sys_call_table,@object
+EXPORT(sys_call_table)
 	syscalltable
 	.size	sys_call_table, . - sys_call_table
-
-	.macro	sys function, nargs
-	.byte	\nargs
-	.endm
-
-sys_narg_table:
-	syscalltable
-	.size	sys_narg_table, . - sys_narg_table
diff -puN arch/mips/kernel/scall64-64.S~mips-generic-mips-updates arch/mips/kernel/scall64-64.S
--- 25/arch/mips/kernel/scall64-64.S~mips-generic-mips-updates	2005-01-29 11:25:48.574484864 -0800
+++ 25-akpm/arch/mips/kernel/scall64-64.S	2005-01-29 11:25:48.733460696 -0800
@@ -53,8 +53,10 @@ NESTED(handle_sys64, PT_SIZE, sp)
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
-	LONG_L	t0, TI_FLAGS($28)
-	bltz	t0, syscall_trace_entry	# syscall tracing enabled?
+	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
+	and	t0, t1, t0
+	bnez	t0, syscall_trace_entry
 
 	jalr	t2			# Do The Real Thing (TM)
 
@@ -112,7 +114,7 @@ syscall_trace_entry:
 
 illegal_syscall:
 	/* This also isn't a 64-bit syscall, throw an error.  */
-	li	v0, ENOSYS			# error
+	li	v0, -ENOSYS			# error
 	sd	v0, PT_R2(sp)
 	li	t0, 1				# set error flag
 	sd	t0, PT_R7(sp)
@@ -173,8 +175,8 @@ illegal_syscall:
 	sd	v0, PT_R2(sp)		# result
 
 	/* Success, so skip usual error handling garbage.  */
-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, a2, t0
 	bnez	t0, 1f
 
diff -puN arch/mips/kernel/scall64-o32.S~mips-generic-mips-updates arch/mips/kernel/scall64-o32.S
--- 25/arch/mips/kernel/scall64-o32.S~mips-generic-mips-updates	2005-01-29 11:25:48.576484560 -0800
+++ 25-akpm/arch/mips/kernel/scall64-o32.S	2005-01-29 11:25:48.734460544 -0800
@@ -6,6 +6,7 @@
  * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
  *
  * Hairy, the userspace application uses a different argument passing
  * convention than the kernel, so we have to translate things from o32
@@ -43,6 +44,8 @@ NESTED(handle_sys, PT_SIZE, sp)
  RESTORE_ALL
 #endif
 
+	/* We don't want to stumble over broken sign extensions from
+	   userland. O32 does never use the upper half. */
 	sll	a0, a0, 0
 	sll	a1, a1, 0
 	sll	a2, a2, 0
@@ -68,11 +71,13 @@ NESTED(handle_sys, PT_SIZE, sp)
 1:	lw	a4, 16(t0)		# argument #5 from usp
 2:	lw	a5, 20(t0)		# argument #6 from usp
 3:	lw	a6, 24(t0)		# argument #7 from usp
+4:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
 
 	.section __ex_table,"a"
 	PTR	1b, bad_stack
 	PTR	2b, bad_stack
 	PTR	3b, bad_stack
+	PTR	4b, bad_stack
 	.previous
 
 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
@@ -91,7 +96,7 @@ NESTED(handle_sys, PT_SIZE, sp)
 	sd	v0, PT_R0(sp)		# flag for syscall restarting
 1:	sd	v0, PT_R2(sp)		# result
 
-FEXPORT(o32_syscall_exit)
+o32_syscall_exit:
 	local_irq_disable		# make need_resched and
 					# signals dont change between
 					# sampling and return
@@ -109,12 +114,12 @@ o32_syscall_exit_work:
 
 trace_a_syscall:
 	SAVE_STATIC
-	sd	a4, PT_R8(sp)
+	sd	a4, PT_R8(sp)		# Save argument registers
 	sd	a5, PT_R9(sp)
 	sd	a6, PT_R10(sp)
-	sd	a7, PT_R11(sp)
+	sd	a7, PT_R11(sp)		# For indirect syscalls
 
-	move	s0, t2
+	move	s0, t2			# Save syscall pointer
 	move	a0, sp
 	li	a1, 0
 	jal	do_syscall_trace
@@ -125,7 +130,8 @@ trace_a_syscall:
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
-	ld	a6, PT_R10(sp)		# For indirect syscalls
+	ld	a6, PT_R10(sp)
+	ld	a7, PT_R11(sp)		# For indirect syscalls
 	jalr	s0
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -162,40 +168,17 @@ not_o32_scall:
 #else
 	j	handle_sys64
 #endif
-
-illegal_syscall:
-	/* This also isn't a 64-bit syscall, throw an error.  */
-	li	v0, ENOSYS		# error
-	sd	v0, PT_R2(sp)
-	li	t0, 1			# set error flag
-	sd	t0, PT_R7(sp)
-	j	o32_syscall_exit
 	END(handle_sys)
 
 LEAF(sys32_syscall)
-	ld	t0, PT_R29(sp)		# user sp
-
 	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
-	beqz	v0, enosys
+	beqz	v0, einval
 
 	dsll	v0, a0, 3
-	dla	v1, sys32_syscall
 	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
 
-	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, TI_ADDR_LIMIT($28)
-	or	v0, v0, t1
-	and	v1, v1, v0
-	bnez	v1, efault
+	li	v1, 4000		# indirect syscall number
+	beq	a0, v1, einval		# do not recurse
 
 	move	a0, a1			# shift argument registers
 	move	a1, a2
@@ -203,25 +186,21 @@ LEAF(sys32_syscall)
 	move	a3, a4
 	move	a4, a5
 	move	a5, a6
+	move	a6, a7
+	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
+	sd	a1, PT_R5(sp)		# syscalls expect them there
+	sd	a2, PT_R6(sp)
+	sd	a3, PT_R7(sp)
+	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
 	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
+einval:	li	v0, -EINVAL
+	jr	ra
 	END(sys32_syscall)
 
 	.align	3
-	.type	sys_call_table,@object;
+	.type	sys_call_table,@object
 sys_call_table:
 	PTR	sys32_syscall			/* 4000 */
 	PTR	sys_exit
diff -puN arch/mips/kernel/semaphore.c~mips-generic-mips-updates arch/mips/kernel/semaphore.c
--- 25/arch/mips/kernel/semaphore.c~mips-generic-mips-updates	2005-01-29 11:25:48.577484408 -0800
+++ 25-akpm/arch/mips/kernel/semaphore.c	2005-01-29 11:25:48.735460392 -0800
@@ -15,7 +15,6 @@
  * indicate that some process(es) are waiting for the semaphore.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init.h>
@@ -64,7 +63,7 @@ static inline int __sem_update_count(str
 		: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
 		: "r" (incr), "m" (sem->count));
 	} else {
-		static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+		static DEFINE_SPINLOCK(semaphore_lock);
 		unsigned long flags;
 
 		spin_lock_irqsave(&semaphore_lock, flags);
diff -puN arch/mips/kernel/setup.c~mips-generic-mips-updates arch/mips/kernel/setup.c
--- 25/arch/mips/kernel/setup.c~mips-generic-mips-updates	2005-01-29 11:25:48.578484256 -0800
+++ 25-akpm/arch/mips/kernel/setup.c	2005-01-29 11:25:48.736460240 -0800
@@ -281,12 +281,12 @@ static inline void bootmem_init(void)
 		initrd_reserve_bootmem = 1;
 	} else {
 		unsigned long tmp;
-		unsigned long *initrd_header;
+		u32 *initrd_header;
 
-		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
+		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
 		if (tmp < reserved_end)
 			tmp += PAGE_SIZE;
-		initrd_header = (unsigned long *)tmp;
+		initrd_header = (u32 *)tmp;
 		if (initrd_header[0] == 0x494E5244) {
 			initrd_start = (unsigned long)&initrd_header[2];
 			initrd_end = initrd_start + initrd_header[1];
@@ -425,8 +425,10 @@ static inline void bootmem_init(void)
 		if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
 			printk("initrd extends beyond end of memory "
 			       "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
-			       sizeof(long) * 2, CPHYSADDR(initrd_end),
-			       sizeof(long) * 2, PFN_PHYS(max_low_pfn));
+			       sizeof(long) * 2,
+			       (unsigned long long)CPHYSADDR(initrd_end),
+			       sizeof(long) * 2,
+			       (unsigned long long)PFN_PHYS(max_low_pfn));
 			initrd_start = initrd_end = 0;
 			initrd_reserve_bootmem = 0;
 		}
@@ -441,10 +443,21 @@ static inline void resource_init(void)
 {
 	int i;
 
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+	/*
+	 * The 64bit code in 32bit object format trick can't represent
+	 * 64bit wide relocations for linker script symbols.
+	 */
+	code_resource.start = CPHYSADDR(&_text);
+	code_resource.end = CPHYSADDR(&_etext) - 1;
+	data_resource.start = CPHYSADDR(&_etext);
+	data_resource.end = CPHYSADDR(&_edata) - 1;
+#else
 	code_resource.start = virt_to_phys(&_text);
 	code_resource.end = virt_to_phys(&_etext) - 1;
 	data_resource.start = virt_to_phys(&_etext);
 	data_resource.end = virt_to_phys(&_edata) - 1;
+#endif
 
 	/*
 	 * Request address space for all standard RAM.
diff -puN arch/mips/kernel/signal32.c~mips-generic-mips-updates arch/mips/kernel/signal32.c
--- 25/arch/mips/kernel/signal32.c~mips-generic-mips-updates	2005-01-29 11:25:48.580483952 -0800
+++ 25-akpm/arch/mips/kernel/signal32.c	2005-01-29 11:25:48.737460088 -0800
@@ -37,7 +37,7 @@ typedef union sigval32 {
 	s32 sival_ptr;
 } sigval_t32;
 
-typedef struct compat_siginfo{
+typedef struct compat_siginfo {
 	int si_signo;
 	int si_code;
 	int si_errno;
@@ -106,7 +106,7 @@ typedef struct compat_siginfo{
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
 
 /* 32-bit compatibility types */
 
@@ -192,6 +192,7 @@ static inline int get_sigset(sigset_t *k
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
+
 save_static_function(sys32_sigsuspend);
 __attribute_used__ noinline static int
 _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -333,8 +334,7 @@ asmlinkage int sys32_sigaltstack(nabi_no
 	return ret;
 }
 
-static asmlinkage int restore_sigcontext32(struct pt_regs *regs,
-					   struct sigcontext32 *sc)
+static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
 {
 	int err = 0;
 	__u32 used_math;
@@ -391,7 +391,7 @@ struct sigframe {
 struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_code[2];			/* signal trampoline */
-	struct compat_siginfo_t rs_info;
+	compat_siginfo_t rs_info;
 	struct ucontext32 rs_uc;
 };
 
@@ -442,7 +442,9 @@ int copy_siginfo_to_user32(compat_siginf
 	return err;
 }
 
-asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys32_sigreturn);
+__attribute_used__ noinline static void
+_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -478,7 +480,9 @@ badframe:
 	force_sig(SIGSEGV, current);
 }
 
-asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe32 *frame;
 	sigset_t set;
@@ -761,7 +765,7 @@ static inline void handle_signal(unsigne
 	}
 }
 
-asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+int do_signal32(sigset_t *oldset, struct pt_regs *regs)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
diff -puN arch/mips/kernel/signal.c~mips-generic-mips-updates arch/mips/kernel/signal.c
--- 25/arch/mips/kernel/signal.c~mips-generic-mips-updates	2005-01-29 11:25:48.581483800 -0800
+++ 25-akpm/arch/mips/kernel/signal.c	2005-01-29 11:25:48.739459784 -0800
@@ -28,12 +28,15 @@
 #include <asm/sim.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
 
 #define DEBUG_SIG 0
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+static int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -151,53 +154,6 @@ asmlinkage int sys_sigaltstack(nabi_no_r
 	return do_sigaltstack(uss, uoss, usp);
 }
 
-asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
-{
-	int err = 0;
-	unsigned int used_math;
-
-	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
-	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
-	err |= __get_user(regs->hi, &sc->sc_mdhi);
-	err |= __get_user(regs->lo, &sc->sc_mdlo);
-
-#define restore_gp_reg(i) do {						\
-	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
-} while(0)
-	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
-	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
-	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
-	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
-	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
-	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
-	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
-	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
-	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
-	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
-	restore_gp_reg(31);
-#undef restore_gp_reg
-
-	err |= __get_user(used_math, &sc->sc_used_math);
-	conditional_used_math(used_math);
-
-	preempt_disable();
-
-	if (used_math()) {
-		/* restore fpu context if we have used it before */
-		own_fpu();
-		err |= restore_fp_context(sc);
-	} else {
-		/* signal handler may have used FPU.  Give it up. */
-		lose_fpu();
-	}
-
-	preempt_enable();
-
-	return err;
-}
-
 #if PLAT_TRAMPOLINE_STUFF_LINE
 #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
 #else
@@ -221,7 +177,9 @@ struct rt_sigframe {
 };
 
 #ifdef CONFIG_TRAD_SIGNALS
-asmlinkage void sys_sigreturn(struct pt_regs regs)
+save_static_function(sys_sigreturn);
+__attribute_used__ noinline static void
+_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct sigframe *frame;
 	sigset_t blocked;
@@ -258,7 +216,9 @@ badframe:
 }
 #endif
 
-asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sys_rt_sigreturn);
+__attribute_used__ noinline static void
+_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe *frame;
 	sigset_t set;
@@ -299,85 +259,6 @@ badframe:
 	force_sig(SIGSEGV, current);
 }
 
-inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
-{
-	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]);		\
-} while(0)
-	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
-	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
-	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
-	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
-	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
-	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
-	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
-	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
-	save_gp_reg(31);
-#undef save_gp_reg
-
-	err |= __put_user(regs->hi, &sc->sc_mdhi);
-	err |= __put_user(regs->lo, &sc->sc_mdlo);
-	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
-	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
-
-	err |= __put_user(!!used_math(), &sc->sc_used_math);
-
-	if (!used_math())
-		goto out;
-
-	/*
-	 * Save FPU state to signal context.  Signal handler will "inherit"
-	 * current FPU state.
-	 */
-	preempt_disable();
-
-	if (!is_fpu_owner()) {
-		own_fpu();
-		restore_fp(current);
-	}
-	err |= save_fp_context(sc);
-
-	preempt_enable();
-
-out:
-	return err;
-}
-
-/*
- * Determine which stack to use..
- */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-	size_t frame_size)
-{
-	unsigned long sp, almask;
-
-	/* 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) && (sas_ss_flags (sp) == 0))
-		sp = current->sas_ss_sp + current->sas_ss_size;
-
-	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
-	else
-		almask = ALMASK;
-
-	return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1));
-}
-
 #ifdef CONFIG_TRAD_SIGNALS
 static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	int signr, sigset_t *set)
@@ -396,8 +277,7 @@ static void inline setup_frame(struct k_
 	 *         syscall
 	 */
 	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		__builtin_memset(frame->sf_code, '0',
-		                 PLAT_TRAMPOLINE_STUFF_LINE);
+		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
 	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->sf_code);
@@ -453,8 +333,7 @@ static void inline setup_rt_frame(struct
 	 *         syscall
 	 */
 	if (PLAT_TRAMPOLINE_STUFF_LINE)
-		__builtin_memset(frame->rs_code, '0',
-		                 PLAT_TRAMPOLINE_STUFF_LINE);
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
 	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->rs_code);
@@ -558,7 +437,7 @@ static inline void handle_signal(unsigne
 extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
 extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
 
-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
@@ -612,8 +491,6 @@ no_signal:
 	return 0;
 }
 
-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
-
 /*
  * notification of userspace execution resumption
  * - triggered by current->work.notify_resume
diff -puN /dev/null arch/mips/kernel/signal-common.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/kernel/signal-common.h	2005-01-29 11:25:48.740459632 -0800
@@ -0,0 +1,136 @@
+/*
+ * 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) 1991, 1992  Linus Torvalds
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+static inline int
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	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]);		\
+} while(0)
+	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+	save_gp_reg(31);
+#undef save_gp_reg
+
+	err |= __put_user(regs->hi, &sc->sc_mdhi);
+	err |= __put_user(regs->lo, &sc->sc_mdlo);
+	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+
+	err |= __put_user(!!used_math(), &sc->sc_used_math);
+
+	if (!used_math())
+		goto out;
+
+	/*
+	 * Save FPU state to signal context.  Signal handler will "inherit"
+	 * current FPU state.
+	 */
+	preempt_disable();
+
+	if (!is_fpu_owner()) {
+		own_fpu();
+		restore_fp(current);
+	}
+	err |= save_fp_context(sc);
+
+	preempt_enable();
+
+out:
+	return err;
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	int err = 0;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->hi, &sc->sc_mdhi);
+	err |= __get_user(regs->lo, &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {						\
+	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+} while(0)
+	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+	restore_gp_reg(31);
+#undef restore_gp_reg
+
+	err |= __get_user(!!used_math(), &sc->sc_used_math);
+	conditional_used_math(used_math);
+
+	preempt_disable();
+
+	if (used_math()) {
+		/* restore fpu context if we have used it before */
+		own_fpu();
+		err |= restore_fp_context(sc);
+	} else {
+		/* signal handler may have used FPU.  Give it up. */
+		lose_fpu();
+	}
+
+	preempt_enable();
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp, almask;
+
+	/* 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) && (sas_ss_flags (sp) == 0))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+	else
+		almask = ALMASK;
+
+	return (void *)((sp - frame_size) & almask);
+}
diff -puN arch/mips/kernel/signal_n32.c~mips-generic-mips-updates arch/mips/kernel/signal_n32.c
--- 25/arch/mips/kernel/signal_n32.c~mips-generic-mips-updates	2005-01-29 11:25:48.583483496 -0800
+++ 25-akpm/arch/mips/kernel/signal_n32.c	2005-01-29 11:25:48.741459480 -0800
@@ -35,9 +35,12 @@
 #include <asm/ucontext.h>
 #include <asm/system.h>
 #include <asm/fpu.h>
+#include <asm/cpu-features.h>
+
+#include "signal-common.h"
 
 /*
- * Including <asm/unistd.h would give use the 64-bit syscall numbers ...
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
 #define __NR_N32_rt_sigreturn		6211
 #define __NR_N32_restart_syscall	6214
@@ -59,17 +62,22 @@ struct ucontextn32 {
 	sigset_t            uc_sigmask;   /* mask last for extensibility */
 };
 
+#if PLAT_TRAMPOLINE_STUFF_LINE
+#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+#else
+#define __tramp
+#endif
+
 struct rt_sigframe_n32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
-	struct siginfo rs_info;
+	u32 rs_code[2] __tramp;		/* signal trampoline */
+	struct siginfo rs_info __tramp;
 	struct ucontextn32 rs_uc;
 };
 
-extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
-extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
-
-asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+save_static_function(sysn32_rt_sigreturn);
+__attribute_used__ noinline static void
+_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
 	struct rt_sigframe_n32 *frame;
 	sigset_t set;
@@ -118,31 +126,6 @@ badframe:
 	force_sig(SIGSEGV, current);
 }
 
-/*
- * Determine which stack to use..
- */
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-	size_t frame_size)
-{
-	unsigned long sp;
-
-	/* 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) && (sas_ss_flags (sp) == 0))
-		sp = current->sas_ss_sp + current->sas_ss_size;
-
-	return (void *)((sp - frame_size) & ALMASK);
-}
-
 void setup_rt_frame_n32(struct k_sigaction * ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
@@ -160,8 +143,10 @@ void setup_rt_frame_n32(struct k_sigacti
 	 *         li      v0, __NR_rt_sigreturn
 	 *         syscall
 	 */
+	if (PLAT_TRAMPOLINE_STUFF_LINE)
+		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
 	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
-	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
+	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
 	flush_cache_sigtramp((unsigned long) frame->rs_code);
 
 	/* Create siginfo.  */
diff -puN arch/mips/kernel/smp.c~mips-generic-mips-updates arch/mips/kernel/smp.c
--- 25/arch/mips/kernel/smp.c~mips-generic-mips-updates	2005-01-29 11:25:48.584483344 -0800
+++ 25-akpm/arch/mips/kernel/smp.c	2005-01-29 11:25:48.741459480 -0800
@@ -18,7 +18,6 @@
  * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  * Copyright (C) 2000, 2001, 2003 Broadcom Corporation
  */
-#include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -94,6 +93,7 @@ static void smp_tune_scheduling (void)
 }
 
 extern void __init calibrate_delay(void);
+extern ATTRIB_NORET void cpu_idle(void);
 
 /*
  * First C code run on the secondary CPUs after being started up by
@@ -123,7 +123,7 @@ asmlinkage void start_secondary(void)
 	cpu_idle();
 }
 
-spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(smp_call_lock);
 
 struct call_data_struct *call_data;
 
diff -puN arch/mips/kernel/syscall.c~mips-generic-mips-updates arch/mips/kernel/syscall.c
--- 25/arch/mips/kernel/syscall.c~mips-generic-mips-updates	2005-01-29 11:25:48.586483040 -0800
+++ 25-akpm/arch/mips/kernel/syscall.c	2005-01-29 11:25:48.742459328 -0800
@@ -3,10 +3,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
+#include <linux/a.out.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/mm.h>
@@ -66,11 +67,7 @@ unsigned long arch_get_unmapped_area(str
 	int do_color_align;
 	unsigned long task_size;
 
-#ifdef CONFIG_MIPS32
-	task_size = TASK_SIZE;
-#else
-	task_size = (current->thread.mflags & MF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
-#endif
+	task_size = STACK_TOP;
 
 	if (flags & MAP_FIXED) {
 		/*
@@ -116,7 +113,7 @@ unsigned long arch_get_unmapped_area(str
 }
 
 /* common code for old and new mmaps */
-static inline long
+static inline unsigned long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
         unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
@@ -140,8 +137,9 @@ out:
 	return error;
 }
 
-asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
-                                  int flags, int fd, off_t offset)
+asmlinkage unsigned long
+old_mmap(unsigned long addr, unsigned long len, int prot,
+	int flags, int fd, off_t offset)
 {
 	unsigned long result;
 
@@ -155,7 +153,7 @@ out:
 	return result;
 }
 
-asmlinkage long
+asmlinkage unsigned long
 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
           unsigned long flags, unsigned long fd, unsigned long pgoff)
 {
diff -puN arch/mips/kernel/time.c~mips-generic-mips-updates arch/mips/kernel/time.c
--- 25/arch/mips/kernel/time.c~mips-generic-mips-updates	2005-01-29 11:25:48.587482888 -0800
+++ 25-akpm/arch/mips/kernel/time.c	2005-01-29 11:25:48.743459176 -0800
@@ -11,7 +11,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -53,7 +52,7 @@ EXPORT_SYMBOL(jiffies_64);
  */
 extern volatile unsigned long wall_jiffies;
 
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 
 /*
  * By default we provide the null RTC ops
diff -puN arch/mips/kernel/traps.c~mips-generic-mips-updates arch/mips/kernel/traps.c
--- 25/arch/mips/kernel/traps.c~mips-generic-mips-updates	2005-01-29 11:25:48.589482584 -0800
+++ 25-akpm/arch/mips/kernel/traps.c	2005-01-29 11:25:48.744459024 -0800
@@ -38,12 +38,9 @@
 #include <asm/watch.h>
 #include <asm/types.h>
 
-extern asmlinkage void handle_mod(void);
+extern asmlinkage void handle_tlbm(void);
 extern asmlinkage void handle_tlbl(void);
 extern asmlinkage void handle_tlbs(void);
-extern asmlinkage void __xtlb_mod(void);
-extern asmlinkage void __xtlb_tlbl(void);
-extern asmlinkage void __xtlb_tlbs(void);
 extern asmlinkage void handle_adel(void);
 extern asmlinkage void handle_ades(void);
 extern asmlinkage void handle_ibe(void);
@@ -82,7 +79,12 @@ void show_stack(struct task_struct *task
 	long stackdata;
 	int i;
 
-	sp = sp ? sp : (unsigned long *) &sp;
+	if (!sp) {
+		if (task && task != current)
+			sp = (unsigned long *) task->thread.reg29;
+		else
+			sp = (unsigned long *) &sp;
+	}
 
 	printk("Stack :");
 	i = 0;
@@ -110,8 +112,12 @@ void show_trace(struct task_struct *task
 	const int field = 2 * sizeof(unsigned long);
 	unsigned long addr;
 
-	if (!stack)
-		stack = (unsigned long*)&stack;
+	if (!stack) {
+		if (task && task != current)
+			stack = (unsigned long *) task->thread.reg29;
+		else
+			stack = (unsigned long *) &stack;
+	}
 
 	printk("Call Trace:");
 #ifdef CONFIG_KALLSYMS
@@ -244,7 +250,7 @@ void show_registers(struct pt_regs *regs
 	printk("\n");
 }
 
-static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_lock);
 
 NORET_TYPE void __die(const char * str, struct pt_regs * regs,
 	const char * file, const char * func, unsigned long line)
@@ -1001,16 +1007,10 @@ void __init trap_init(void)
 	if (board_be_init)
 		board_be_init();
 
-#ifdef CONFIG_MIPS32
-	set_except_vector(1, handle_mod);
+	set_except_vector(1, handle_tlbm);
 	set_except_vector(2, handle_tlbl);
 	set_except_vector(3, handle_tlbs);
-#endif
-#ifdef CONFIG_MIPS64
-	set_except_vector(1, __xtlb_mod);
-	set_except_vector(2, __xtlb_tlbl);
-	set_except_vector(3, __xtlb_tlbs);
-#endif
+
 	set_except_vector(4, handle_adel);
 	set_except_vector(5, handle_ades);
 
@@ -1047,7 +1047,7 @@ void __init trap_init(void)
 		 * unaligned ldc1/sdc1 exception.  The handlers have not been
 		 * written yet.  Well, anyway there is no R6000 machine on the
 		 * current list of targets for Linux/MIPS.
-		 * (Duh, crap, there is someone with a tripple R6k machine)
+		 * (Duh, crap, there is someone with a triple R6k machine)
 		 */
 		//set_except_vector(14, handle_mc);
 		//set_except_vector(15, handle_ndc);
diff -puN arch/mips/kernel/vmlinux.lds.S~mips-generic-mips-updates arch/mips/kernel/vmlinux.lds.S
--- 25/arch/mips/kernel/vmlinux.lds.S~mips-generic-mips-updates	2005-01-29 11:25:48.590482432 -0800
+++ 25-akpm/arch/mips/kernel/vmlinux.lds.S	2005-01-29 11:25:48.745458872 -0800
@@ -156,6 +156,7 @@ SECTIONS
 	*(.options)
 	*(.pdr)
 	*(.reginfo)
+	*(.mdebug*)
   }
 
   /* This is the MIPS specific mdebug section.  */
diff -puN arch/mips/lib-64/dump_tlb.c~mips-generic-mips-updates arch/mips/lib-64/dump_tlb.c
--- 25/arch/mips/lib-64/dump_tlb.c~mips-generic-mips-updates	2005-01-29 11:25:48.591482280 -0800
+++ 25-akpm/arch/mips/lib-64/dump_tlb.c	2005-01-29 11:25:48.745458872 -0800
@@ -148,16 +148,16 @@ void dump_list_process(struct task_struc
 	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
 
 	page_dir = pgd_offset(t->mm, 0);
-	printk("page_dir == %08lx\n", (unsigned long) page_dir);
+	printk("page_dir == %016lx\n", (unsigned long) page_dir);
 
 	pgd = pgd_offset(t->mm, addr);
-	printk("pgd == %08lx, ", (unsigned long) pgd);
+	printk("pgd == %016lx\n", (unsigned long) pgd);
 
 	pmd = pmd_offset(pgd, addr);
-	printk("pmd == %08lx, ", (unsigned long) pmd);
+	printk("pmd == %016lx\n", (unsigned long) pmd);
 
 	pte = pte_offset(pmd, addr);
-	printk("pte == %08lx, ", (unsigned long) pte);
+	printk("pte == %016lx\n", (unsigned long) pte);
 
 	page = *pte;
 	printk("page == %08lx\n", pte_val(page));
diff -puN arch/mips/lib/csum_partial_copy.c~mips-generic-mips-updates arch/mips/lib/csum_partial_copy.c
diff -puN arch/mips/Makefile~mips-generic-mips-updates arch/mips/Makefile
--- 25/arch/mips/Makefile~mips-generic-mips-updates	2005-01-29 11:25:48.594481824 -0800
+++ 25-akpm/arch/mips/Makefile	2005-01-29 11:25:48.746458720 -0800
@@ -673,6 +673,8 @@ libs-$(CONFIG_MIPS64)	+= arch/mips/lib-6
 
 core-y			+= arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
 
+drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
+
 ifdef CONFIG_LASAT
 rom.bin rom.sw: vmlinux
 	$(call descend,arch/mips/lasat/image,$@)
@@ -744,36 +746,16 @@ define filechk_gen-asm-offset.h
 	 echo "#endif /* _ASM_OFFSET_H */" )
 endef
 
-define filechk_gen-asm-reg.h
-	(set -e; \
-	 echo "#ifndef _ASM_REG_H"; \
-	 echo "#define _ASM_REG_H"; \
-	 echo "/*"; \
-	 echo " * DO NOT MODIFY."; \
-	 echo " *"; \
-	 echo " * This file was generated by arch/$(ARCH)/Makefile"; \
-	 echo " *"; \
-	 echo " */"; \
-	 echo ""; \
-	 sed -ne "/^@@@/s///p"; \
-	 echo "#endif /* _ASM_REG_H */" )
-endef
-
-prepare: include/asm-$(ARCH)/offset.h \
-	 include/asm-$(ARCH)/reg.h
+prepare: include/asm-$(ARCH)/offset.h
 
 arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \
 				   include/config/MARKER
 
 include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s
 	$(call filechk,gen-asm-offset.h)
-include/asm-$(ARCH)/reg.h: arch/$(ARCH)/kernel/reg.s
-	$(call filechk,gen-asm-reg.h)
 
 CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
 	       include/asm-$(ARCH)/offset.h \
-	       include/asm-$(ARCH)/reg.h.tmp \
-	       include/asm-$(ARCH)/reg.h \
 	       vmlinux.32 \
 	       vmlinux.64 \
 	       vmlinux.ecoff
diff -puN arch/mips/math-emu/cp1emu.c~mips-generic-mips-updates arch/mips/math-emu/cp1emu.c
--- 25/arch/mips/math-emu/cp1emu.c~mips-generic-mips-updates	2005-01-29 11:25:48.596481520 -0800
+++ 25-akpm/arch/mips/math-emu/cp1emu.c	2005-01-29 11:25:48.747458568 -0800
@@ -2,7 +2,7 @@
  * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
  *
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
diff -puN arch/mips/math-emu/dp_add.c~mips-generic-mips-updates arch/mips/math-emu/dp_add.c
--- 25/arch/mips/math-emu/dp_add.c~mips-generic-mips-updates	2005-01-29 11:25:48.597481368 -0800
+++ 25-akpm/arch/mips/math-emu/dp_add.c	2005-01-29 11:25:48.748458416 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_cmp.c~mips-generic-mips-updates arch/mips/math-emu/dp_cmp.c
--- 25/arch/mips/math-emu/dp_cmp.c~mips-generic-mips-updates	2005-01-29 11:25:48.598481216 -0800
+++ 25-akpm/arch/mips/math-emu/dp_cmp.c	2005-01-29 11:25:48.748458416 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_div.c~mips-generic-mips-updates arch/mips/math-emu/dp_div.c
--- 25/arch/mips/math-emu/dp_div.c~mips-generic-mips-updates	2005-01-29 11:25:48.599481064 -0800
+++ 25-akpm/arch/mips/math-emu/dp_div.c	2005-01-29 11:25:48.748458416 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_fint.c~mips-generic-mips-updates arch/mips/math-emu/dp_fint.c
--- 25/arch/mips/math-emu/dp_fint.c~mips-generic-mips-updates	2005-01-29 11:25:48.601480760 -0800
+++ 25-akpm/arch/mips/math-emu/dp_fint.c	2005-01-29 11:25:48.749458264 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_flong.c~mips-generic-mips-updates arch/mips/math-emu/dp_flong.c
--- 25/arch/mips/math-emu/dp_flong.c~mips-generic-mips-updates	2005-01-29 11:25:48.602480608 -0800
+++ 25-akpm/arch/mips/math-emu/dp_flong.c	2005-01-29 11:25:48.749458264 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_frexp.c~mips-generic-mips-updates arch/mips/math-emu/dp_frexp.c
--- 25/arch/mips/math-emu/dp_frexp.c~mips-generic-mips-updates	2005-01-29 11:25:48.603480456 -0800
+++ 25-akpm/arch/mips/math-emu/dp_frexp.c	2005-01-29 11:25:48.749458264 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_fsp.c~mips-generic-mips-updates arch/mips/math-emu/dp_fsp.c
--- 25/arch/mips/math-emu/dp_fsp.c~mips-generic-mips-updates	2005-01-29 11:25:48.605480152 -0800
+++ 25-akpm/arch/mips/math-emu/dp_fsp.c	2005-01-29 11:25:48.750458112 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_logb.c~mips-generic-mips-updates arch/mips/math-emu/dp_logb.c
--- 25/arch/mips/math-emu/dp_logb.c~mips-generic-mips-updates	2005-01-29 11:25:48.606480000 -0800
+++ 25-akpm/arch/mips/math-emu/dp_logb.c	2005-01-29 11:25:48.750458112 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_modf.c~mips-generic-mips-updates arch/mips/math-emu/dp_modf.c
--- 25/arch/mips/math-emu/dp_modf.c~mips-generic-mips-updates	2005-01-29 11:25:48.607479848 -0800
+++ 25-akpm/arch/mips/math-emu/dp_modf.c	2005-01-29 11:25:48.750458112 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_mul.c~mips-generic-mips-updates arch/mips/math-emu/dp_mul.c
--- 25/arch/mips/math-emu/dp_mul.c~mips-generic-mips-updates	2005-01-29 11:25:48.608479696 -0800
+++ 25-akpm/arch/mips/math-emu/dp_mul.c	2005-01-29 11:25:48.751457960 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_scalb.c~mips-generic-mips-updates arch/mips/math-emu/dp_scalb.c
--- 25/arch/mips/math-emu/dp_scalb.c~mips-generic-mips-updates	2005-01-29 11:25:48.610479392 -0800
+++ 25-akpm/arch/mips/math-emu/dp_scalb.c	2005-01-29 11:25:48.751457960 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_simple.c~mips-generic-mips-updates arch/mips/math-emu/dp_simple.c
--- 25/arch/mips/math-emu/dp_simple.c~mips-generic-mips-updates	2005-01-29 11:25:48.611479240 -0800
+++ 25-akpm/arch/mips/math-emu/dp_simple.c	2005-01-29 11:25:48.751457960 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_sqrt.c~mips-generic-mips-updates arch/mips/math-emu/dp_sqrt.c
--- 25/arch/mips/math-emu/dp_sqrt.c~mips-generic-mips-updates	2005-01-29 11:25:48.612479088 -0800
+++ 25-akpm/arch/mips/math-emu/dp_sqrt.c	2005-01-29 11:25:48.752457808 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_sub.c~mips-generic-mips-updates arch/mips/math-emu/dp_sub.c
--- 25/arch/mips/math-emu/dp_sub.c~mips-generic-mips-updates	2005-01-29 11:25:48.614478784 -0800
+++ 25-akpm/arch/mips/math-emu/dp_sub.c	2005-01-29 11:25:48.752457808 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_tint.c~mips-generic-mips-updates arch/mips/math-emu/dp_tint.c
--- 25/arch/mips/math-emu/dp_tint.c~mips-generic-mips-updates	2005-01-29 11:25:48.615478632 -0800
+++ 25-akpm/arch/mips/math-emu/dp_tint.c	2005-01-29 11:25:48.753457656 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/dp_tlong.c~mips-generic-mips-updates arch/mips/math-emu/dp_tlong.c
--- 25/arch/mips/math-emu/dp_tlong.c~mips-generic-mips-updates	2005-01-29 11:25:48.616478480 -0800
+++ 25-akpm/arch/mips/math-emu/dp_tlong.c	2005-01-29 11:25:48.753457656 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754.c~mips-generic-mips-updates arch/mips/math-emu/ieee754.c
--- 25/arch/mips/math-emu/ieee754.c~mips-generic-mips-updates	2005-01-29 11:25:48.618478176 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754.c	2005-01-29 11:25:48.753457656 -0800
@@ -8,7 +8,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754d.c~mips-generic-mips-updates arch/mips/math-emu/ieee754d.c
--- 25/arch/mips/math-emu/ieee754d.c~mips-generic-mips-updates	2005-01-29 11:25:48.619478024 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754d.c	2005-01-29 11:25:48.754457504 -0800
@@ -3,7 +3,7 @@
  *
  * MIPS floating point support
  *
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  *  This program is free software; you can distribute it and/or modify it
diff -puN arch/mips/math-emu/ieee754dp.c~mips-generic-mips-updates arch/mips/math-emu/ieee754dp.c
--- 25/arch/mips/math-emu/ieee754dp.c~mips-generic-mips-updates	2005-01-29 11:25:48.620477872 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754dp.c	2005-01-29 11:25:48.754457504 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754dp.h~mips-generic-mips-updates arch/mips/math-emu/ieee754dp.h
--- 25/arch/mips/math-emu/ieee754dp.h~mips-generic-mips-updates	2005-01-29 11:25:48.622477568 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754dp.h	2005-01-29 11:25:48.754457504 -0800
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754.h~mips-generic-mips-updates arch/mips/math-emu/ieee754.h
--- 25/arch/mips/math-emu/ieee754.h~mips-generic-mips-updates	2005-01-29 11:25:48.623477416 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754.h	2005-01-29 11:25:48.755457352 -0800
@@ -3,7 +3,7 @@
 */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754int.h~mips-generic-mips-updates arch/mips/math-emu/ieee754int.h
--- 25/arch/mips/math-emu/ieee754int.h~mips-generic-mips-updates	2005-01-29 11:25:48.625477112 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754int.h	2005-01-29 11:25:48.755457352 -0800
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754m.c~mips-generic-mips-updates arch/mips/math-emu/ieee754m.c
--- 25/arch/mips/math-emu/ieee754m.c~mips-generic-mips-updates	2005-01-29 11:25:48.626476960 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754m.c	2005-01-29 11:25:48.756457200 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754sp.c~mips-generic-mips-updates arch/mips/math-emu/ieee754sp.c
--- 25/arch/mips/math-emu/ieee754sp.c~mips-generic-mips-updates	2005-01-29 11:25:48.627476808 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754sp.c	2005-01-29 11:25:48.756457200 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754sp.h~mips-generic-mips-updates arch/mips/math-emu/ieee754sp.h
--- 25/arch/mips/math-emu/ieee754sp.h~mips-generic-mips-updates	2005-01-29 11:25:48.629476504 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754sp.h	2005-01-29 11:25:48.757457048 -0800
@@ -4,7 +4,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/ieee754xcpt.c~mips-generic-mips-updates arch/mips/math-emu/ieee754xcpt.c
--- 25/arch/mips/math-emu/ieee754xcpt.c~mips-generic-mips-updates	2005-01-29 11:25:48.630476352 -0800
+++ 25-akpm/arch/mips/math-emu/ieee754xcpt.c	2005-01-29 11:25:48.757457048 -0800
@@ -1,6 +1,6 @@
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_add.c~mips-generic-mips-updates arch/mips/math-emu/sp_add.c
--- 25/arch/mips/math-emu/sp_add.c~mips-generic-mips-updates	2005-01-29 11:25:48.631476200 -0800
+++ 25-akpm/arch/mips/math-emu/sp_add.c	2005-01-29 11:25:48.757457048 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_cmp.c~mips-generic-mips-updates arch/mips/math-emu/sp_cmp.c
--- 25/arch/mips/math-emu/sp_cmp.c~mips-generic-mips-updates	2005-01-29 11:25:48.633475896 -0800
+++ 25-akpm/arch/mips/math-emu/sp_cmp.c	2005-01-29 11:25:48.758456896 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_div.c~mips-generic-mips-updates arch/mips/math-emu/sp_div.c
--- 25/arch/mips/math-emu/sp_div.c~mips-generic-mips-updates	2005-01-29 11:25:48.634475744 -0800
+++ 25-akpm/arch/mips/math-emu/sp_div.c	2005-01-29 11:25:48.758456896 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_fdp.c~mips-generic-mips-updates arch/mips/math-emu/sp_fdp.c
--- 25/arch/mips/math-emu/sp_fdp.c~mips-generic-mips-updates	2005-01-29 11:25:48.635475592 -0800
+++ 25-akpm/arch/mips/math-emu/sp_fdp.c	2005-01-29 11:25:48.759456744 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_fint.c~mips-generic-mips-updates arch/mips/math-emu/sp_fint.c
--- 25/arch/mips/math-emu/sp_fint.c~mips-generic-mips-updates	2005-01-29 11:25:48.637475288 -0800
+++ 25-akpm/arch/mips/math-emu/sp_fint.c	2005-01-29 11:25:48.759456744 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_flong.c~mips-generic-mips-updates arch/mips/math-emu/sp_flong.c
--- 25/arch/mips/math-emu/sp_flong.c~mips-generic-mips-updates	2005-01-29 11:25:48.638475136 -0800
+++ 25-akpm/arch/mips/math-emu/sp_flong.c	2005-01-29 11:25:48.759456744 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_frexp.c~mips-generic-mips-updates arch/mips/math-emu/sp_frexp.c
--- 25/arch/mips/math-emu/sp_frexp.c~mips-generic-mips-updates	2005-01-29 11:25:48.639474984 -0800
+++ 25-akpm/arch/mips/math-emu/sp_frexp.c	2005-01-29 11:25:48.760456592 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_logb.c~mips-generic-mips-updates arch/mips/math-emu/sp_logb.c
--- 25/arch/mips/math-emu/sp_logb.c~mips-generic-mips-updates	2005-01-29 11:25:48.640474832 -0800
+++ 25-akpm/arch/mips/math-emu/sp_logb.c	2005-01-29 11:25:48.760456592 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_modf.c~mips-generic-mips-updates arch/mips/math-emu/sp_modf.c
--- 25/arch/mips/math-emu/sp_modf.c~mips-generic-mips-updates	2005-01-29 11:25:48.642474528 -0800
+++ 25-akpm/arch/mips/math-emu/sp_modf.c	2005-01-29 11:25:48.760456592 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_mul.c~mips-generic-mips-updates arch/mips/math-emu/sp_mul.c
--- 25/arch/mips/math-emu/sp_mul.c~mips-generic-mips-updates	2005-01-29 11:25:48.643474376 -0800
+++ 25-akpm/arch/mips/math-emu/sp_mul.c	2005-01-29 11:25:48.761456440 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_scalb.c~mips-generic-mips-updates arch/mips/math-emu/sp_scalb.c
--- 25/arch/mips/math-emu/sp_scalb.c~mips-generic-mips-updates	2005-01-29 11:25:48.644474224 -0800
+++ 25-akpm/arch/mips/math-emu/sp_scalb.c	2005-01-29 11:25:48.761456440 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_simple.c~mips-generic-mips-updates arch/mips/math-emu/sp_simple.c
--- 25/arch/mips/math-emu/sp_simple.c~mips-generic-mips-updates	2005-01-29 11:25:48.646473920 -0800
+++ 25-akpm/arch/mips/math-emu/sp_simple.c	2005-01-29 11:25:48.761456440 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_sqrt.c~mips-generic-mips-updates arch/mips/math-emu/sp_sqrt.c
--- 25/arch/mips/math-emu/sp_sqrt.c~mips-generic-mips-updates	2005-01-29 11:25:48.647473768 -0800
+++ 25-akpm/arch/mips/math-emu/sp_sqrt.c	2005-01-29 11:25:48.762456288 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_sub.c~mips-generic-mips-updates arch/mips/math-emu/sp_sub.c
--- 25/arch/mips/math-emu/sp_sub.c~mips-generic-mips-updates	2005-01-29 11:25:48.648473616 -0800
+++ 25-akpm/arch/mips/math-emu/sp_sub.c	2005-01-29 11:25:48.762456288 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_tint.c~mips-generic-mips-updates arch/mips/math-emu/sp_tint.c
--- 25/arch/mips/math-emu/sp_tint.c~mips-generic-mips-updates	2005-01-29 11:25:48.649473464 -0800
+++ 25-akpm/arch/mips/math-emu/sp_tint.c	2005-01-29 11:25:48.763456136 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/math-emu/sp_tlong.c~mips-generic-mips-updates arch/mips/math-emu/sp_tlong.c
--- 25/arch/mips/math-emu/sp_tlong.c~mips-generic-mips-updates	2005-01-29 11:25:48.651473160 -0800
+++ 25-akpm/arch/mips/math-emu/sp_tlong.c	2005-01-29 11:25:48.763456136 -0800
@@ -3,7 +3,7 @@
  */
 /*
  * MIPS floating point support
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
  * http://www.algor.co.uk
  *
  * ########################################################################
diff -puN arch/mips/mm/cache.c~mips-generic-mips-updates arch/mips/mm/cache.c
--- 25/arch/mips/mm/cache.c~mips-generic-mips-updates	2005-01-29 11:25:48.652473008 -0800
+++ 25-akpm/arch/mips/mm/cache.c	2005-01-29 11:25:48.763456136 -0800
@@ -45,10 +45,17 @@ EXPORT_SYMBOL(_dma_cache_inv);
 
 #endif /* CONFIG_DMA_NONCOHERENT */
 
-asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
+/*
+ * We could optimize the case where the cache argument is not BCACHE but
+ * that seems very atypical use ...
+ */
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
+	unsigned int cache)
 {
-	/* This should flush more selectivly ...  */
-	__flush_cache_all();
+	if (verify_area(VERIFY_WRITE, (void *) addr, bytes))
+		return -EFAULT;
+
+	flush_icache_range(addr, addr + bytes);
 
 	return 0;
 }
diff -puN arch/mips/mm/cerr-sb1.c~mips-generic-mips-updates arch/mips/mm/cerr-sb1.c
--- 25/arch/mips/mm/cerr-sb1.c~mips-generic-mips-updates	2005-01-29 11:25:48.653472856 -0800
+++ 25-akpm/arch/mips/mm/cerr-sb1.c	2005-01-29 11:25:48.764455984 -0800
@@ -251,14 +251,14 @@ static const uint8_t parity[256] = {
 
 /* 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
+	0x0738C808099264FFULL,
+	0x38C808099264FF07ULL,
+	0xC808099264FF0738ULL,
+	0x08099264FF0738C8ULL,
+	0x099264FF0738C808ULL,
+	0x9264FF0738C80809ULL,
+	0x64FF0738C8080992ULL,
+	0xFF0738C808099264ULL
 };
 
 /* Calculate the parity on a range of bits */
@@ -330,9 +330,9 @@ static uint32_t extract_ic(unsigned shor
 				    ((lru >> 4) & 0x3),
 				    ((lru >> 6) & 0x3));
 		}
-		va = (taglo & 0xC0000FFFFFFFE000) | addr;
+		va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
 		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
-			va |= 0x3FFFF00000000000;
+			va |= 0x3FFFF00000000000ULL;
 		valid = ((taghi >> 29) & 1);
 		if (valid) {
 			tlo_tmp = taglo & 0xfff3ff;
@@ -473,7 +473,7 @@ static uint32_t extract_dc(unsigned shor
 		: "r" ((way << 13) | addr));
 
 		taglo = ((unsigned long long)taglohi << 32) | taglolo;
-		pa = (taglo & 0xFFFFFFE000) | addr;
+		pa = (taglo & 0xFFFFFFE000ULL) | addr;
 		if (way == 0) {
 			lru = (taghi >> 14) & 0xff;
 			prom_printf("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
diff -puN arch/mips/mm/cex-sb1.S~mips-generic-mips-updates arch/mips/mm/cex-sb1.S
--- 25/arch/mips/mm/cex-sb1.S~mips-generic-mips-updates	2005-01-29 11:25:48.655472552 -0800
+++ 25-akpm/arch/mips/mm/cex-sb1.S	2005-01-29 11:25:48.765455832 -0800
@@ -15,7 +15,6 @@
  * 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/asm.h>
diff -puN arch/mips/mm/c-r4k.c~mips-generic-mips-updates arch/mips/mm/c-r4k.c
--- 25/arch/mips/mm/c-r4k.c~mips-generic-mips-updates	2005-01-29 11:25:48.656472400 -0800
+++ 25-akpm/arch/mips/mm/c-r4k.c	2005-01-29 11:25:48.766455680 -0800
@@ -238,6 +238,22 @@ static inline void r4k_blast_scache_page
 		r4k_blast_scache_page = blast_scache128_page;
 }
 
+static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
+
+static inline void r4k_blast_scache_page_indexed_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (sc_lsize == 16)
+		r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
+	else if (sc_lsize == 32)
+		r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
+	else if (sc_lsize == 64)
+		r4k_blast_scache_page_indexed = blast_scache64_page_indexed;
+	else if (sc_lsize == 128)
+		r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
+}
+
 static void (* r4k_blast_scache)(void);
 
 static inline void r4k_blast_scache_setup(void)
@@ -318,9 +334,6 @@ static inline void local_r4k_flush_cache
 {
 	struct mm_struct *mm = args;
 
-	if (!cpu_has_dc_aliases)
-		return;
-
 	if (!cpu_context(smp_processor_id(), mm))
 		return;
 
@@ -340,6 +353,9 @@ static inline void local_r4k_flush_cache
 
 static void r4k_flush_cache_mm(struct mm_struct *mm)
 {
+	if (!cpu_has_dc_aliases)
+		return;
+
 	on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
 }
 
@@ -359,13 +375,6 @@ static inline void local_r4k_flush_cache
 	pmd_t *pmdp;
 	pte_t *ptep;
 
-	/*
-	 * If ownes no valid ASID yet, cannot possibly have gotten
-	 * this page into the cache.
-	 */
-	if (cpu_context(smp_processor_id(), mm) == 0)
-		return;
-
 	page &= PAGE_MASK;
 	pgdp = pgd_offset(mm, page);
 	pmdp = pmd_offset(pgdp, page);
@@ -385,8 +394,11 @@ static inline void local_r4k_flush_cache
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
 			r4k_blast_dcache_page(page);
+			if (exec && !cpu_icache_snoops_remote_store)
+				r4k_blast_scache_page(page);
+		}
 		if (exec)
 			r4k_blast_icache_page(page);
 
@@ -398,8 +410,11 @@ static inline void local_r4k_flush_cache
 	 * to work correctly.
 	 */
 	page = INDEX_BASE + (page & (dcache_size - 1));
-	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
 		r4k_blast_dcache_page_indexed(page);
+		if (exec && !cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page_indexed(page);
+	}
 	if (exec) {
 		if (cpu_has_vtag_icache) {
 			int cpu = smp_processor_id();
@@ -416,6 +431,13 @@ static void r4k_flush_cache_page(struct 
 {
 	struct flush_cache_page_args args;
 
+	/*
+	 * If ownes no valid ASID yet, cannot possibly have gotten
+	 * this page into the cache.
+	 */
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
+		return;
+
 	args.vma = vma;
 	args.page = page;
 
@@ -442,14 +464,15 @@ static inline void local_r4k_flush_icach
 	struct flush_icache_range_args *fir_args = args;
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
 	unsigned long start = fir_args->start;
 	unsigned long end = fir_args->end;
 	unsigned long addr, aend;
 
 	if (!cpu_has_ic_fills_f_dc) {
-		if (end - start > dcache_size)
+		if (end - start > dcache_size) {
 			r4k_blast_dcache();
-		else {
+		} else {
 			addr = start & ~(dc_lsize - 1);
 			aend = (end - 1) & ~(dc_lsize - 1);
 
@@ -461,6 +484,23 @@ static inline void local_r4k_flush_icach
 				addr += dc_lsize;
 			}
 		}
+
+		if (!cpu_icache_snoops_remote_store) {
+			if (end - start > scache_size) {
+				r4k_blast_scache();
+			} else {
+				addr = start & ~(sc_lsize - 1);
+				aend = (end - 1) & ~(sc_lsize - 1);
+
+				while (1) {
+					/* Hit_Writeback_Inv_D */
+					protected_writeback_scache_line(addr);
+					if (addr == aend)
+						break;
+					addr += sc_lsize;
+				}
+			}
+		}
 	}
 
 	if (end - start > icache_size)
@@ -527,6 +567,8 @@ static inline void local_r4k_flush_icach
 	if (!cpu_has_ic_fills_f_dc) {
 		unsigned long addr = (unsigned long) page_address(page);
 		r4k_blast_dcache_page(addr);
+		if (!cpu_icache_snoops_remote_store)
+			r4k_blast_scache_page(addr);
 		ClearPageDcacheDirty(page);
 	}
 
@@ -669,10 +711,13 @@ static void local_r4k_flush_cache_sigtra
 {
 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long sc_lsize = current_cpu_data.scache.linesz;
 	unsigned long addr = (unsigned long) arg;
 
 	R4600_HIT_CACHEOP_WAR_IMPL;
 	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	if (!cpu_icache_snoops_remote_store)
+		protected_writeback_scache_line(addr & ~(sc_lsize - 1));
 	protected_flush_icache_line(addr & ~(ic_lsize - 1));
 	if (MIPS4K_ICACHE_REFILL_WAR) {
 		__asm__ __volatile__ (
@@ -739,8 +784,8 @@ static inline void rm7k_erratum31(void)
 	}
 }
 
-static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way",
-	"5-way", "6-way", "7-way", "8-way"
+static char *way_string[] __initdata = { NULL, "direct mapped", "2-way",
+	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
 };
 
 static void __init probe_pcache(void)
@@ -1178,6 +1223,7 @@ void __init ld_mmu_r4xx0(void)
 	r4k_blast_icache_page_indexed_setup();
 	r4k_blast_icache_setup();
 	r4k_blast_scache_page_setup();
+	r4k_blast_scache_page_indexed_setup();
 	r4k_blast_scache_setup();
 
 	/*
diff -puN arch/mips/mm/c-sb1.c~mips-generic-mips-updates arch/mips/mm/c-sb1.c
--- 25/arch/mips/mm/c-sb1.c~mips-generic-mips-updates	2005-01-29 11:25:48.657472248 -0800
+++ 25-akpm/arch/mips/mm/c-sb1.c	2005-01-29 11:25:48.767455528 -0800
@@ -503,7 +503,7 @@ void ld_mmu_sb1(void)
 	/* Special cache error handler for SB1 */
 	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_sb1, 0x80);
 	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
-	memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+	memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
 
 	probe_cache_sizes();
 
diff -puN /dev/null arch/mips/mm/dma-ip32.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/mm/dma-ip32.c	2005-01-29 11:25:48.769455224 -0800
@@ -0,0 +1,382 @@
+/*
+ * 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  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ * IP32 changes by Ilya.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/ip32/crime.h>
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian)
+ * 3. All other devices see memory as one big chunk at 0x40000000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK	0x3fffffff
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK;
+		memset(ret, 0, size);
+		if(dev==NULL)
+		    addr+= CRIME_HI_MEM_BASE;
+		*dma_handle = addr;
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t * dma_handle, int gfp)
+{
+	void *ret;
+
+	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+	if (ret) {
+		dma_cache_wback_inv((unsigned long) ret, size);
+		ret = UNCAC_ADDR(ret);
+	}
+
+	return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+	dma_addr_t dma_handle)
+{
+	unsigned long addr = (unsigned long) vaddr;
+
+	addr = CAC_ADDR(addr);
+	free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	unsigned long addr = (unsigned long) ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_cache_wback(addr, size);
+		break;
+
+	case DMA_FROM_DEVICE:
+		dma_cache_inv(addr, size);
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		dma_cache_wback_inv(addr, size);
+		break;
+
+	default:
+		BUG();
+	}
+
+	addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+	    addr+=CRIME_HI_MEM_BASE;
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		break;
+
+	case DMA_FROM_DEVICE:
+		break;
+
+	case DMA_BIDIRECTIONAL:
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		unsigned long addr;
+
+		addr = (unsigned long) page_address(sg->page)+sg->offset;
+		if (addr)
+			__dma_sync(addr, sg->length, direction);
+		addr = __pa(addr)&RAM_OFFSET_MASK;;
+		if(dev == NULL)
+			addr +=  CRIME_HI_MEM_BASE;
+		sg->dma_address = (dma_addr_t)addr;
+	}
+
+	return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+	dma_cache_wback_inv(addr, size);
+	addr = __pa(addr)&RAM_OFFSET_MASK;;
+	if(dev == NULL)
+		addr +=  CRIME_HI_MEM_BASE;
+
+	return (dma_addr_t)addr;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction != DMA_TO_DEVICE) {
+		unsigned long addr;
+
+		dma_address&=RAM_OFFSET_MASK;
+		addr = dma_address + PAGE_OFFSET;
+		if(dma_address>=256*1024*1024)
+			addr+=CRIME_HI_MEM_BASE;
+		dma_cache_wback_inv(addr, size);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (direction == DMA_TO_DEVICE)
+		return;
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		addr = (unsigned long) page_address(sg->page);
+		if (!addr)
+			continue;
+		dma_cache_wback_inv(addr + sg->offset, sg->length);
+	}
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+	size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+	unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	dma_handle&=RAM_OFFSET_MASK;
+	addr = dma_handle + offset + PAGE_OFFSET;
+	if(dma_handle>=256*1024*1024)
+	    addr+=CRIME_HI_MEM_BASE;
+	__dma_sync(addr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+	enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++)
+		__dma_sync((unsigned long)page_address(sg->page),
+		           sg->length, direction);
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < 0x00ffffff)
+		return 0;
+
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(dma_addr_t dma_addr)
+{
+	return 1;
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
+{
+	if (direction == DMA_NONE)
+		return;
+
+	dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
diff -puN arch/mips/mm/init.c~mips-generic-mips-updates arch/mips/mm/init.c
--- 25/arch/mips/mm/init.c~mips-generic-mips-updates	2005-01-29 11:25:48.659471944 -0800
+++ 25-akpm/arch/mips/mm/init.c	2005-01-29 11:25:48.769455224 -0800
@@ -61,7 +61,7 @@ unsigned long setup_zero_pages(void)
 	else
 		order = 0;
 
-	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
+	empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
 	if (!empty_zero_page)
 		panic("Oh boy, that early out of memory?");
 
@@ -74,7 +74,6 @@ unsigned long setup_zero_pages(void)
 
 	size = PAGE_SIZE << order;
 	zero_page_mask = (size - 1) & PAGE_MASK;
-	memset((void *)empty_zero_page, 0, size);
 
 	return 1UL << order;
 }
diff -puN arch/mips/mm/Makefile~mips-generic-mips-updates arch/mips/mm/Makefile
--- 25/arch/mips/mm/Makefile~mips-generic-mips-updates	2005-01-29 11:25:48.660471792 -0800
+++ 25-akpm/arch/mips/mm/Makefile	2005-01-29 11:25:48.770455072 -0800
@@ -3,7 +3,7 @@
 #
 
 obj-y				+= cache.o extable.o fault.o init.o pgtable.o \
-				   tlbex.o
+				   tlbex.o tlbex-fault.o
 
 obj-$(CONFIG_MIPS32)		+= ioremap.o pgtable-32.o
 obj-$(CONFIG_MIPS64)		+= pgtable-64.o
@@ -27,40 +27,6 @@ obj-$(CONFIG_CPU_TX39XX)	+= c-tx39.o pg-
 obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
 
-#
-# TLB exception handling code differs between 32-bit and 64-bit kernels.
-#
-ifdef CONFIG_MIPS32
-obj-$(CONFIG_CPU_R3000)		+= tlbex32-r3k.o
-obj-$(CONFIG_CPU_TX49XX)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R4300)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R4X00)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_VR41XX)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R5432)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
-obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
-endif
-ifdef CONFIG_MIPS64
-obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R4X00)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R5432)		+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_RM7000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_RM9000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_R10000)	+= tlb64-glue-r4k.o
-obj-$(CONFIG_CPU_SB1)		+= tlb64-glue-sb1.o
-obj-$(CONFIG_CPU_MIPS64)	+= tlb64-glue-r4k.o
-endif
-
-
 obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm7k.o
@@ -68,8 +34,11 @@ obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm
 #
 # Choose one DMA coherency model
 #
+ifndef CONFIG_OWN_DMA
 obj-$(CONFIG_DMA_COHERENT)	+= dma-coherent.o
 obj-$(CONFIG_DMA_NONCOHERENT)	+= dma-noncoherent.o
+endif
 obj-$(CONFIG_DMA_IP27)		+= dma-ip27.o
+obj-$(CONFIG_DMA_IP32)		+= dma-ip32.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff -puN arch/mips/mm/pg-r4k.c~mips-generic-mips-updates arch/mips/mm/pg-r4k.c
--- 25/arch/mips/mm/pg-r4k.c~mips-generic-mips-updates	2005-01-29 11:25:48.661471640 -0800
+++ 25-akpm/arch/mips/mm/pg-r4k.c	2005-01-29 11:25:48.771454920 -0800
@@ -3,9 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -58,12 +57,6 @@ void copy_page(void *to, void *from) __a
 EXPORT_SYMBOL(copy_page);
 
 /*
- * An address fits into a single register so it's safe to use 64-bit registers
- * if we have 64-bit adresses.
- */
-#define cpu_has_64bit_registers	cpu_has_64bit_addresses
-
-/*
  * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
  * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
  * an Origin 200.
@@ -145,7 +138,7 @@ static inline void __build_load_reg(int 
 	union mips_instruction mi;
 	unsigned int width;
 
-	if (cpu_has_64bit_registers) {
+	if (cpu_has_64bit_gp_regs) {
 		mi.i_format.opcode     = ld_op;
 		width = 8;
 	} else {
@@ -266,7 +259,7 @@ static inline void build_addiu_a2_a0(uns
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
 	mi.i_format.rt         = 6;		/* $a2 */
 	mi.i_format.simmediate = offset;
@@ -280,7 +273,7 @@ static inline void build_addiu_a1(unsign
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 5;		/* $a1 */
 	mi.i_format.rt         = 5;		/* $a1 */
 	mi.i_format.simmediate = offset;
@@ -296,7 +289,7 @@ static inline void build_addiu_a0(unsign
 
 	BUG_ON(offset > 0x7fff);
 
-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
 	mi.i_format.rt         = 4;		/* $a0 */
 	mi.i_format.simmediate = offset;
diff -puN arch/mips/mm/pg-sb1.c~mips-generic-mips-updates arch/mips/mm/pg-sb1.c
--- 25/arch/mips/mm/pg-sb1.c~mips-generic-mips-updates	2005-01-29 11:25:48.663471336 -0800
+++ 25-akpm/arch/mips/mm/pg-sb1.c	2005-01-29 11:25:48.773454616 -0800
@@ -2,6 +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, Inc.
+ * Copyright (C) 2005 Thiemo Seufer
  *
  * Written by Justin Carlson of SiByte, Inc.
  *         and Kip Walker of Broadcom Corp.
@@ -39,11 +40,7 @@
 #define SB1_PREF_STORE_STREAMED_HINT "5"
 #endif
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 static inline void clear_page_cpu(void *page)
-#else
-void clear_page(void *page)
-#endif
 {
 	unsigned char *addr = (unsigned char *) page;
 	unsigned char *end = addr + PAGE_SIZE;
@@ -57,90 +54,143 @@ void clear_page(void *page)
 	 * since we know we're on an SB1, we force the assembler to take
 	 * 64-bit operands to speed things up
 	 */
-	do {
-		__asm__ __volatile__(
-		"	.set	mips4		\n"
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
 #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"
-#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     */
+	"	daddiu	%0, %0, 128	\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%0)  \n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"1:	sd	$0, -128(%0)	\n"  /* Throw out a cacheline of 0's */
+	"	sd	$0, -120(%0)	\n"
+	"	sd	$0, -112(%0)	\n"
+	"	sd	$0, -104(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
+	"	daddiu	%0, %0, -128	\n"
 #endif
-		"	.set	mips0		\n"
-		:
-		: "r" (addr)
-		: "memory");
-		addr += 32;
-	} while (addr != end);
+	"	sd	$0, 0(%0)	\n"  /* Throw out a cacheline of 0's */
+	"1:	sd	$0, 8(%0)	\n"
+	"	sd	$0, 16(%0)	\n"
+	"	sd	$0, 24(%0)	\n"
+	"	daddiu	%0, %0, 32	\n"
+	"	bnel	%0, %1, 1b	\n"
+	"	 sd	$0, 0(%0)	\n"
+	"	.set	pop		\n"
+	: "+r" (addr)
+	: "r" (end)
+	: "memory");
 }
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 static inline void copy_page_cpu(void *to, void *from)
-#else
-void copy_page(void *to, void *from)
-#endif
 {
-	unsigned char *src = from;
-	unsigned char *dst = to;
+	unsigned char *src = (unsigned char *)from;
+	unsigned char *dst = (unsigned char *)to;
 	unsigned char *end = src + PAGE_SIZE;
 
 	/*
-	 * 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
-	 *
 	 * 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
 	 * ends up copying a lot more data than is commonly used, so this seems
 	 * to make sense in terms of reducing cache pollution, but I've no real
 	 * performance data to back this up
 	 */
-
-	do {
-		__asm__ __volatile__(
-		"	.set	mips4					\n"
+	__asm__ __volatile__(
+	"	.set	push		\n"
+	"	.set	mips4		\n"
+	"	.set	noreorder	\n"
 #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_LOAD_STREAMED_HINT  ",  32(%0)\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"
-#endif
-		"1:	lw	$2,  0(%0)	\n"  /* Block copy a cacheline */
-		"	lw	$3,  4(%0)	\n"
-		"	lw	$4,  8(%0)	\n"
-		"	lw	$5, 12(%0)	\n"
-		"	lw	$6, 16(%0)	\n"
-		"	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"
+	"	daddiu	%0, %0, 128	\n"
+	"	daddiu	%1, %1, 128	\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"  /* Prefetch the first 4 lines */
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -96(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -64(%0)\n"
+	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%1)\n"
+	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"1:	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%1)\n"
+# ifdef CONFIG_MIPS64
+	"	ld	$8, -128(%0)	\n"  /* Block copy a cacheline */
+	"	ld	$9, -120(%0)	\n"
+	"	ld	$10, -112(%0)	\n"
+	"	ld	$11, -104(%0)	\n"
+	"	sd	$8, -128(%1)	\n"
+	"	sd	$9, -120(%1)	\n"
+	"	sd	$10, -112(%1)	\n"
+	"	sd	$11, -104(%1)	\n"
+# else
+	"	lw	$2, -128(%0)	\n"  /* Block copy a cacheline */
+	"	lw	$3, -124(%0)	\n"
+	"	lw	$6, -120(%0)	\n"
+	"	lw	$7, -116(%0)	\n"
+	"	lw	$8, -112(%0)	\n"
+	"	lw	$9, -108(%0)	\n"
+	"	lw	$10, -104(%0)	\n"
+	"	lw	$11, -100(%0)	\n"
+	"	sw	$2, -128(%1)	\n"
+	"	sw	$3, -124(%1)	\n"
+	"	sw	$6, -120(%1)	\n"
+	"	sw	$7, -116(%1)	\n"
+	"	sw	$8, -112(%1)	\n"
+	"	sw	$9, -108(%1)	\n"
+	"	sw	$10, -104(%1)	\n"
+	"	sw	$11, -100(%1)	\n"
+# endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+	"	 pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
+	"	daddiu	%0, %0, -128	\n"
+	"	daddiu	%1, %1, -128	\n"
+#endif
+#ifdef CONFIG_MIPS64
+	"	ld	$8, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	ld	$9, 8(%0)	\n"
+	"	ld	$10, 16(%0)	\n"
+	"	ld	$11, 24(%0)	\n"
+	"	sd	$8, 0(%1)	\n"
+	"	sd	$9, 8(%1)	\n"
+	"	sd	$10, 16(%1)	\n"
+	"	sd	$11, 24(%1)	\n"
+#else
+	"	lw	$2, 0(%0)	\n"  /* Block copy a cacheline */
+	"1:	lw	$3, 4(%0)	\n"
+	"	lw	$6, 8(%0)	\n"
+	"	lw	$7, 12(%0)	\n"
+	"	lw	$8, 16(%0)	\n"
+	"	lw	$9, 20(%0)	\n"
+	"	lw	$10, 24(%0)	\n"
+	"	lw	$11, 28(%0)	\n"
+	"	sw	$2, 0(%1)	\n"
+	"	sw	$3, 4(%1)	\n"
+	"	sw	$6, 8(%1)	\n"
+	"	sw	$7, 12(%1)	\n"
+	"	sw	$8, 16(%1)	\n"
+	"	sw	$9, 20(%1)	\n"
+	"	sw	$10, 24(%1)	\n"
+	"	sw	$11, 28(%1)	\n"
+#endif
+	"	daddiu	%0, %0, 32	\n"
+	"	daddiu	%1, %1, 32	\n"
+	"	bnel	%0, %2, 1b	\n"
+#ifdef CONFIG_MIPS64
+	"	 ld	$8, 0(%0)	\n"
+#else
+	"	 lw	$2, 0(%0)	\n"
+#endif
+	"	.set	pop		\n"
+	: "+r" (src), "+r" (dst)
+	: "r" (end)
+#ifdef CONFIG_MIPS64
+	: "$8","$9","$10","$11","memory");
+#else
+	: "$2","$3","$6","$7","$8","$9","$10","$11","memory");
 #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"
-		"	.set	mips0		\n"
-		:
-		: "r" (src), "r" (dst)
-		: "$2","$3","$4","$5","$6","$7","$8","$9","memory");
-		src += 32;
-		dst += 32;
-	} while (src != end);
 }
 
 
@@ -151,10 +201,10 @@ void copy_page(void *to, void *from)
  * particular CPU. 
  */
 typedef struct dmadscr_s {
-	uint64_t  dscr_a;
-	uint64_t  dscr_b;
-	uint64_t  pad_a;
-	uint64_t  pad_b;
+	u64 dscr_a;
+	u64 dscr_b;
+	u64 pad_a;
+	u64 pad_b;
 } dmadscr_t;
 
 static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
@@ -162,14 +212,14 @@ static dmadscr_t page_descr[NR_CPUS] __a
 void sb1_dma_init(void)
 {
 	int cpu = smp_processor_id();
-	uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+	u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
 
-	__raw_writeq(base_val,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
-	__raw_writeq(base_val | M_DM_DSCR_BASE_RESET,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
-	__raw_writeq(base_val | M_DM_DSCR_BASE_ENABL,
-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
+		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
 void clear_page(void *page)
@@ -177,46 +227,61 @@ void clear_page(void *page)
 	int cpu = smp_processor_id();
 
 	/* if the page is above Kseg0, use old way */
-	if (KSEGX(page) != CAC_BASE)
+	if ((long)KSEGX(page) != (long)CKSEG0)
 		return clear_page_cpu(page);
 
-	page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
 
 	/*
 	 * Don't really want to do it this way, but there's no
 	 * reliable way to delay completion detection.
 	 */
-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+			   M_DM_DSCR_BASE_INTERRUPT))))
 		;
-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
 void copy_page(void *to, void *from)
 {
-	unsigned long from_phys = PHYSADDR(from);
-	unsigned long to_phys = PHYSADDR(to);
+	unsigned long from_phys = CPHYSADDR(from);
+	unsigned long to_phys = CPHYSADDR(to);
 	int cpu = smp_processor_id();
 
 	/* if either page is above Kseg0, use old way */
-	if ((KSEGX(to) != CAC_BASE) || (KSEGX(from) != CAC_BASE))
+	if ((long)KSEGX(to) != (long)CKSEG0
+	    || (long)KSEGX(from) != (long)CKSEG0)
 		return copy_page_cpu(to, from);
 
-	page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
-	page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+	page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+	page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
 
 	/*
 	 * Don't really want to do it this way, but there's no
 	 * reliable way to delay completion detection.
 	 */
-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
+	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
+				    M_DM_DSCR_BASE_INTERRUPT))))
 		;
-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
 }
 
-#endif
+#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+
+void clear_page(void *page)
+{
+	return clear_page_cpu(page);
+}
+
+void copy_page(void *to, void *from)
+{
+	return copy_page_cpu(to, from);
+}
+
+#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */
 
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
diff -puN arch/mips/mm/pgtable-32.c~mips-generic-mips-updates arch/mips/mm/pgtable-32.c
--- 25/arch/mips/mm/pgtable-32.c~mips-generic-mips-updates	2005-01-29 11:25:48.665471032 -0800
+++ 25-akpm/arch/mips/mm/pgtable-32.c	2005-01-29 11:25:48.773454616 -0800
@@ -71,8 +71,8 @@ void __init pagetable_init(void)
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
-	pgd_init((unsigned long)swapper_pg_dir +
-	         sizeof(pgd_t ) * USER_PTRS_PER_PGD);
+	pgd_init((unsigned long)swapper_pg_dir
+		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
 
 #ifdef CONFIG_HIGHMEM
 	pgd_base = swapper_pg_dir;
diff -puN arch/mips/mm/pgtable-64.c~mips-generic-mips-updates arch/mips/mm/pgtable-64.c
--- 25/arch/mips/mm/pgtable-64.c~mips-generic-mips-updates	2005-01-29 11:25:48.666470880 -0800
+++ 25-akpm/arch/mips/mm/pgtable-64.c	2005-01-29 11:25:48.774454464 -0800
@@ -55,5 +55,4 @@ void __init pagetable_init(void)
 	/* 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);
 }
diff -puN arch/mips/mm/pgtable.c~mips-generic-mips-updates arch/mips/mm/pgtable.c
--- 25/arch/mips/mm/pgtable.c~mips-generic-mips-updates	2005-01-29 11:25:48.667470728 -0800
+++ 25-akpm/arch/mips/mm/pgtable.c	2005-01-29 11:25:48.774454464 -0800
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
diff -puN arch/mips/mm/sc-rm7k.c~mips-generic-mips-updates arch/mips/mm/sc-rm7k.c
--- 25/arch/mips/mm/sc-rm7k.c~mips-generic-mips-updates	2005-01-29 11:25:48.669470424 -0800
+++ 25-akpm/arch/mips/mm/sc-rm7k.c	2005-01-29 11:25:48.774454464 -0800
@@ -96,13 +96,13 @@ static void rm7k_sc_inv(unsigned long ad
 }
 
 /*
- * This function is executed in the uncached segment KSEG1.
+ * This function is executed in the uncached segment CKSEG1.
  * It must not touch the stack, because the stack pointer still points
- * into KSEG0.
+ * into CKSEG0.
  *
  * Three options:
  *	- Write it in assembly and guarantee that we don't use the stack.
- *	- Disable caching for KSEG0 before calling it.
+ *	- Disable caching for CKSEG0 before calling it.
  *	- Pray that GCC doesn't randomly start using the stack.
  *
  * This being Linux, we obviously take the least sane of those options -
diff -L arch/mips/mm/tlb64-glue-r4k.S -puN arch/mips/mm/tlb64-glue-r4k.S~mips-generic-mips-updates /dev/null
--- 25/arch/mips/mm/tlb64-glue-r4k.S
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,41 +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 <linux/init.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	.macro	__BUILD_cli
-	CLI
-	.endm
-
-	.macro	__BUILD_sti
-	STI
-	.endm
-
-	.macro	__BUILD_kmode
-	KMODE
-	.endm
-
-	.macro	tlb_handler name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	tlb_handler	xtlb_mod kmode 1
-	tlb_handler	xtlb_tlbl kmode 0
-	tlb_handler	xtlb_tlbs kmode 1
diff -L arch/mips/mm/tlb64-glue-sb1.S -puN arch/mips/mm/tlb64-glue-sb1.S~mips-generic-mips-updates /dev/null
--- 25/arch/mips/mm/tlb64-glue-sb1.S
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,66 +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 <linux/init.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/war.h>
-
-	.macro	__BUILD_cli
-	CLI
-	.endm
-
-	.macro	__BUILD_sti
-	STI
-	.endm
-
-	.macro	__BUILD_kmode
-	KMODE
-	.endm
-
-	.macro	tlb_handler name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	.macro	tlb_handler_m3 name interruptible writebit
-	NESTED(__\name, PT_SIZE, sp)
-	dmfc0	k0, CP0_BADVADDR
-	dmfc0	k1, CP0_ENTRYHI
-	xor	k0, k1
-	dsrl	k0, k0, PAGE_SHIFT + 1
-	bnez	k0, 1f
-	SAVE_ALL
-	dmfc0	a2, CP0_BADVADDR
-	__BUILD_\interruptible
-	li	a1, \writebit
-	sd	a2, PT_BVADDR(sp)
-	move	a0, sp
-	jal	do_page_fault
-1:
-	j	ret_from_exception
-	END(__\name)
-	.endm
-
-	tlb_handler	xtlb_mod kmode 1
-#if BCM1250_M3_WAR
-	tlb_handler_m3	xtlb_tlbl kmode 0
-#else
-	tlb_handler	xtlb_tlbl kmode 0
-#endif
-	tlb_handler	xtlb_tlbs kmode 1
diff -puN arch/mips/mm/tlb-andes.c~mips-generic-mips-updates arch/mips/mm/tlb-andes.c
--- 25/arch/mips/mm/tlb-andes.c~mips-generic-mips-updates	2005-01-29 11:25:48.672469968 -0800
+++ 25-akpm/arch/mips/mm/tlb-andes.c	2005-01-29 11:25:48.776454160 -0800
@@ -7,7 +7,6 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
  */
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -L arch/mips/mm/tlbex32-mips32.S -puN arch/mips/mm/tlbex32-mips32.S~mips-generic-mips-updates /dev/null
--- 25/arch/mips/mm/tlbex32-mips32.S
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,253 +0,0 @@
-/*
- * TLB exception handling code for MIPS32 CPUs.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-cpu abstraction and reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * Pete Popov, ppopov@pacbell.net
- * Added 36 bit phys address support.
- * Copyright (C) 2002 MontaVista Software, Inc.
- */
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-
-/* We really only support 36 bit physical addresses on MIPS32 */
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
-#define PTE_SIZE        8
-#define PTEP_INDX_MSK	0xff0
-#define PTE_INDX_MSK	0xff8
-#define PTE_INDX_SHIFT 9
-#define CONVERT_PTE(pte)
-#define PTE_MAKEWRITE_HIGH(pte, ptr) \
-	lw	pte, PTE_HALF(ptr); \
-	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, PTE_HALF(ptr); \
-	lw	pte, 0(ptr);
-
-#define PTE_MAKEVALID_HIGH(pte, ptr) \
-	lw	pte, PTE_HALF(ptr); \
-	ori	pte, pte, _PAGE_VALID; \
-	sw	pte, PTE_HALF(ptr); \
-	lw	pte, 0(ptr);
-
-#else
-
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_HALF        0
-#define PTE_SIZE	4
-#define PTEP_INDX_MSK	0xff8
-#define PTE_INDX_MSK	0xffc
-#define PTE_INDX_SHIFT	10
-#define CONVERT_PTE(pte) srl pte, pte, 6
-#define PTE_MAKEWRITE_HIGH(pte, ptr)
-#define PTE_MAKEVALID_HIGH(pte, ptr)
-
-#endif  /* CONFIG_64BIT_PHYS_ADDR */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define GET_PTE_OFF(reg)
-#else
-#define GET_PTE_OFF(reg)	srl	reg, reg, 1
-#endif
-
-/*
- * ABUSE of CPP macros 101.
- *
- * After this macro runs, the pte faulted on is
- * in register PTE, a ptr into the table in which
- * the pte belongs is in PTR.
- */
-
-#ifdef CONFIG_SMP
-#define GET_PGD(scratch, ptr)        \
-	mfc0    ptr, CP0_CONTEXT;    \
-	la      scratch, pgd_current;\
-	srl     ptr, 23;             \
-	sll     ptr, 2;              \
-	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);
-#else
-#define GET_PGD(scratch, ptr)    \
-	lw	ptr, pgd_current;
-#endif
-
-#define LOAD_PTE(pte, ptr) \
-	GET_PGD(pte, ptr)          \
-	mfc0	pte, CP0_BADVADDR; \
-	srl	pte, pte, _PGDIR_SHIFT; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, (ptr); \
-	srl	pte, pte, PTE_INDX_SHIFT; \
-	and	pte, pte, PTE_INDX_MSK; \
-	addu	ptr, ptr, pte; \
-	PTE_L	pte, (ptr);
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr, tmp) \
-	ori	ptr, ptr, PTE_SIZE; \
-	xori	ptr, ptr, PTE_SIZE; \
-	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
-	CONVERT_PTE(tmp); \
-	P_MTC0	tmp, CP0_ENTRYLO1; \
-	PTE_L	ptr, PTE_HALF(ptr); \
-	CONVERT_PTE(ptr); \
-	P_MTC0	ptr, CP0_ENTRYLO0;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	PTE_L	pte, (ptr);
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	PTE_S	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	PTE_L	pte, (ptr);
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	PTE_S	pte, (ptr);
-
-	.set	noreorder
-
-	.align	5
-	NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-invalid_tlbl:
-#ifdef TLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-	tlbp
-	PTE_PRESENT(k0, k1, nopage_tlbl)
-	PTE_MAKEVALID_HIGH(k0, k1)
-	PTE_MAKEVALID(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbl:
-	DO_FAULT(0)
-	END(handle_tlbl)
-
-	.align	5
-	NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-        li      k0,0
-	LOAD_PTE(k0, k1)
-	tlbp				# find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_MAKEWRITE_HIGH(k0, k1)
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbs:
-	DO_FAULT(1)
-	END(handle_tlbs)
-
-	.align	5
-	NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	LOAD_PTE(k0, k1)
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	PTE_L	k0, (k1)
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-	PTE_MAKEWRITE_HIGH(k0, k1)
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1, k0)
-	nop
-	b	1f
-	 tlbwi
-1:
-	nop
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-	END(handle_mod)
-
diff -L arch/mips/mm/tlbex32-r3k.S -puN arch/mips/mm/tlbex32-r3k.S~mips-generic-mips-updates /dev/null
--- 25/arch/mips/mm/tlbex32-r3k.S
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,194 +0,0 @@
-/*
- * TLB exception handling code for R2000/R3000.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-CPU abstraction reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Further modifications to make this work:
- * Copyright (c) 1998 Harald Koerfgen
- * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
- * Copyright (c) 2001 Ralf Baechle
- * Copyright (c) 2001 MIPS Technologies, Inc.
- */
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-	/* ABUSE of CPP macros 101. */
-
-	/* After this macro runs, the pte faulted on is
-	 * in register PTE, a ptr into the table in which
-	 * the pte belongs is in PTR.
-	 */
-#define LOAD_PTE(pte, ptr) \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, pgd_current; \
-	srl	pte, pte, 22; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_CONTEXT; \
-	lw	ptr, (ptr); \
-	andi	pte, pte, 0xffc; \
-	addu	ptr, ptr, pte; \
-	lw	pte, (ptr); \
-	nop;
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr) \
-	lw	ptr, (ptr)	; \
-	nop			; \
-	mtc0	ptr, CP0_ENTRYLO0; \
-	nop;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	.set	macro; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat; \
-	.set	nomacro;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	.set	push;       \
-	.set	reorder;    \
-	 lw	pte, (ptr); \
-	.set	pop;
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	sw	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	.set    push;       \
-	.set    reorder;    \
-	lw      pte, (ptr); \
-	.set    pop;
-
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	sw	pte, (ptr);
-
-/*
- * The index register may have the probe fail bit set,
- * because we would trap on access kseg2, i.e. without refill.
- */
-#define TLB_WRITE(reg) \
-	mfc0	reg, CP0_INDEX; \
-	nop; \
-	bltz    reg, 1f; \
-	 nop; \
-	tlbwi; \
-	j	2f; \
-	 nop; \
-1:	tlbwr; \
-2:
-
-#define RET(reg) \
-	mfc0	reg, CP0_EPC; \
-	nop; \
-	jr	reg; \
-	 rfe
-
-	.set	noreorder
-
-	.align	5
-NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-
-#ifdef TLB_OPTIMIZE
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-        tlbp
-        PTE_PRESENT(k0, k1, nopage_tlbl)
-        PTE_MAKEVALID(k0, k1)
-        PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbl:
-#endif
-
-	DO_FAULT(0)
-END(handle_tlbl)
-
-NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-
-#ifdef TLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp                            # find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1)
-	TLB_WRITE(k0)
-	RET(k0)
-nopage_tlbs:
-#endif
-
-	DO_FAULT(1)
-END(handle_tlbs)
-
-	.align	5
-NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	LOAD_PTE(k0, k1)
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	.set	push
-	.set    reorder
-	lw	k0, (k1)
-	.set    pop
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1)
-	tlbwi
-	RET(k0)
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-END(handle_mod)
diff -L arch/mips/mm/tlbex32-r4k.S -puN arch/mips/mm/tlbex32-r4k.S~mips-generic-mips-updates /dev/null
--- 25/arch/mips/mm/tlbex32-r4k.S
+++ /dev/null	2003-09-15 06:40:47.000000000 -0700
@@ -1,262 +0,0 @@
-/*
- * TLB exception handling code for r4k.
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * Multi-cpu abstraction and reworking:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/offset.h>
-#include <asm/cachectl.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/pgtable-bits.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-#include <asm/war.h>
-
-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PTE_L		ld
-#define PTE_S		sd
-#define PTE_SRL		dsrl
-#define P_MTC0		dmtc0
-#define PTE_SIZE	8
-#define PTEP_INDX_MSK	0xff0
-#define PTE_INDX_MSK	0xff8
-#define PTE_INDX_SHIFT	9
-#else
-#define PTE_L		lw
-#define PTE_S		sw
-#define PTE_SRL		srl
-#define P_MTC0		mtc0
-#define PTE_SIZE	4
-#define PTEP_INDX_MSK	0xff8
-#define PTE_INDX_MSK	0xffc
-#define PTE_INDX_SHIFT	10
-#endif
-
-/*
- * ABUSE of CPP macros 101.
- *
- * After this macro runs, the pte faulted on is
- * in register PTE, a ptr into the table in which
- * the pte belongs is in PTR.
- */
-
-#ifdef CONFIG_SMP
-#define GET_PGD(scratch, ptr)        \
-	mfc0    ptr, CP0_CONTEXT;    \
-	la      scratch, pgd_current;\
-	srl     ptr, 23;             \
-	sll     ptr, 2;              \
-	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);
-#else
-#define GET_PGD(scratch, ptr)    \
-	lw	ptr, pgd_current;
-#endif
-
-#define LOAD_PTE(pte, ptr) \
-	GET_PGD(pte, ptr)          \
-	mfc0	pte, CP0_BADVADDR; \
-	srl	pte, pte, _PGDIR_SHIFT; \
-	sll	pte, pte, 2; \
-	addu	ptr, ptr, pte; \
-	mfc0	pte, CP0_BADVADDR; \
-	lw	ptr, (ptr); \
-	srl	pte, pte, PTE_INDX_SHIFT; \
-	and	pte, pte, PTE_INDX_MSK; \
-	addu	ptr, ptr, pte; \
-	PTE_L	pte, (ptr);
-
-	/* This places the even/odd pte pair in the page
-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
-	 * TMP as a scratch register.
-	 */
-#define PTE_RELOAD(ptr, tmp) \
-	ori	ptr, ptr, PTE_SIZE; \
-	xori	ptr, ptr, PTE_SIZE; \
-	PTE_L	tmp, PTE_SIZE(ptr); \
-	PTE_L	ptr, 0(ptr); \
-	PTE_SRL	tmp, tmp, 6; \
-	P_MTC0	tmp, CP0_ENTRYLO1; \
-	PTE_SRL	ptr, ptr, 6; \
-	P_MTC0	ptr, CP0_ENTRYLO0;
-
-#define DO_FAULT(write) \
-	.set	noat; \
-	SAVE_ALL; \
-	mfc0	a2, CP0_BADVADDR; \
-	KMODE; \
-	.set	at; \
-	move	a0, sp; \
-	jal	do_page_fault; \
-	 li	a1, write; \
-	j	ret_from_exception; \
-	 nop; \
-	.set	noat;
-
-	/* Check is PTE is present, if not then jump to LABEL.
-	 * PTR points to the page table where this PTE is located,
-	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
-	 */
-#define PTE_PRESENT(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
-	bnez	pte, label; \
-	 PTE_L	pte, (ptr);
-
-	/* Make PTE valid, store result in PTR. */
-#define PTE_MAKEVALID(pte, ptr) \
-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
-	PTE_S	pte, (ptr);
-
-	/* Check if PTE can be written to, if not branch to LABEL.
-	 * Regardless restore PTE with value from PTR when done.
-	 */
-#define PTE_WRITABLE(pte, ptr, label) \
-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
-	bnez	pte, label; \
-	 PTE_L	pte, (ptr);
-
-	/* Make PTE writable, update software status bits as well,
-	 * then store at PTR.
-	 */
-#define PTE_MAKEWRITE(pte, ptr) \
-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
-			   _PAGE_VALID | _PAGE_DIRTY); \
-	PTE_S	pte, (ptr);
-
-
-	.set	noreorder
-
-/*
- * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
- * 2. A timing hazard exists for the TLBP instruction.
- *
- *      stalling_instruction
- *      TLBP
- *
- * The JTLB is being read for the TLBP throughout the stall generated by the
- * previous instruction. This is not really correct as the stalling instruction
- * can modify the address used to access the JTLB.  The failure symptom is that
- * the TLBP instruction will use an address created for the stalling instruction
- * and not the address held in C0_ENHI and thus report the wrong results.
- *
- * The software work-around is to not allow the instruction preceding the TLBP
- * to stall - make it an NOP or some other instruction guaranteed not to stall.
- *
- * Errata 2 will not be fixed.  This errata is also on the R5000.
- *
- * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
- */
-#define R5K_HAZARD nop
-
-	/*
-	 * Note for many R4k variants tlb probes cannot be executed out
-	 * of the instruction cache else you get bogus results.
-	 */
-	.align	5
-	NESTED(handle_tlbl, PT_SIZE, sp)
-	.set	noat
-#if BCM1250_M3_WAR
-	mfc0	k0, CP0_BADVADDR
-	mfc0	k1, CP0_ENTRYHI
-	xor	k0, k1
-	srl	k0, k0, PAGE_SHIFT+1
-	beqz	k0, 1f
-	 nop
-	.set	mips3
-	eret
-	.set	mips0
-1:
-#endif
-invalid_tlbl:
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	/* Test present bit in entry. */
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp
-	PTE_PRESENT(k0, k1, nopage_tlbl)
-	PTE_MAKEVALID(k0, k1)
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbl:
-	DO_FAULT(0)
-	END(handle_tlbl)
-
-	.align	5
-	NESTED(handle_tlbs, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-        li      k0,0
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp				# find faulting entry
-	PTE_WRITABLE(k0, k1, nopage_tlbs)
-	PTE_MAKEWRITE(k0, k1)
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nopage_tlbs:
-	DO_FAULT(1)
-	END(handle_tlbs)
-
-	.align	5
-	NESTED(handle_mod, PT_SIZE, sp)
-	.set	noat
-#ifdef TLB_OPTIMIZE
-	.set	mips3
-	LOAD_PTE(k0, k1)
-	R5K_HAZARD
-	tlbp					# find faulting entry
-	andi	k0, k0, _PAGE_WRITE
-	beqz	k0, nowrite_mod
-	 PTE_L	k0, (k1)
-
-	/* Present and writable bits set, set accessed and dirty bits. */
-	PTE_MAKEWRITE(k0, k1)
-
-	/* Now reload the entry into the tlb. */
-	PTE_RELOAD(k1, k0)
-	mtc0_tlbw_hazard
-	tlbwi
-	nop
-	tlbw_eret_hazard
-	.set	mips3
-	eret
-	.set	mips0
-#endif
-
-nowrite_mod:
-	DO_FAULT(1)
-	END(handle_mod)
diff -puN arch/mips/mm/tlbex.c~mips-generic-mips-updates arch/mips/mm/tlbex.c
--- 25/arch/mips/mm/tlbex.c~mips-generic-mips-updates	2005-01-29 11:25:48.678469056 -0800
+++ 25-akpm/arch/mips/mm/tlbex.c	2005-01-29 11:25:48.787452488 -0800
@@ -5,7 +5,7 @@
  *
  * Synthesize TLB refill handlers at runtime.
  *
- * Copyright (C) 2004 by Thiemo Seufer
+ * Copyright (C) 2004,2005 by Thiemo Seufer
  */
 
 #include <stdarg.h>
@@ -19,11 +19,11 @@
 
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
-#include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 #include <asm/inst.h>
 #include <asm/elf.h>
 #include <asm/smp.h>
+#include <asm/war.h>
 
 /* #define DEBUG_TLB */
 
@@ -44,6 +44,11 @@ static __init int __attribute__((unused)
 	return BCM1250_M3_WAR;
 }
 
+static __init int __attribute__((unused)) r10000_llsc_war(void)
+{
+	return R10000_LLSC_WAR;
+}
+
 /*
  * A little micro-assembler, intended for TLB refill handler
  * synthesizing. It is intentionally kept simple, does only support
@@ -84,13 +89,14 @@ enum fields
 enum opcode {
 	insn_invalid,
 	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
-	insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne,
-	insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
 	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
 	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
-	insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe,
-	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
-	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
+	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+	insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
+	insn_tlbwr, insn_xor, insn_xori
 };
 
 struct insn {
@@ -114,6 +120,7 @@ static __initdata struct insn insn_table
 	{ insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD },
 	{ insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM },
 	{ insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM },
+	{ insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM },
 	{ insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM },
 	{ insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM },
 	{ insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM },
@@ -134,12 +141,16 @@ static __initdata struct insn insn_table
 	{ insn_jal, M(jal_op,0,0,0,0,0), JIMM },
 	{ insn_jr, M(spec_op,0,0,0,0,jr_op), RS },
 	{ insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM },
 	{ insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD },
 	{ insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD },
 	{ insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM },
 	{ insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 },
+	{ insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM },
+	{ insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM },
 	{ insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE },
 	{ insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE },
@@ -341,6 +352,7 @@ I_u3u1u2(_addu);
 I_u2u1u3(_andi);
 I_u3u1u2(_and);
 I_u1u2s3(_beq);
+I_u1u2s3(_beql);
 I_u1s2(_bgez);
 I_u1s2(_bgezl);
 I_u1s2(_bltz);
@@ -361,12 +373,16 @@ I_u1(_j);
 I_u1(_jal);
 I_u1(_jr);
 I_u2s3u1(_ld);
+I_u2s3u1(_ll);
+I_u2s3u1(_lld);
 I_u1s2(_lui);
 I_u2s3u1(_lw);
 I_u1u2(_mfc0);
 I_u1u2(_mtc0);
 I_u2u1u3(_ori);
 I_0(_rfe);
+I_u2s3u1(_sc);
+I_u2s3u1(_scd);
 I_u2s3u1(_sd);
 I_u2u1u3(_sll);
 I_u2u1u3(_sra);
@@ -389,8 +405,14 @@ enum label_id {
 	label_leave,
 	label_vmalloc,
 	label_vmalloc_done,
-	label_tlbwr_hazard,
-	label_split
+	label_tlbw_hazard,
+	label_split,
+	label_nopage_tlbl,
+	label_nopage_tlbs,
+	label_nopage_tlbm,
+	label_smp_pgtable_change,
+	label_r3000_write_probe_fail,
+	label_r3000_write_probe_ok
 };
 
 struct label {
@@ -416,8 +438,14 @@ L_LA(_second_part)
 L_LA(_leave)
 L_LA(_vmalloc)
 L_LA(_vmalloc_done)
-L_LA(_tlbwr_hazard)
+L_LA(_tlbw_hazard)
 L_LA(_split)
+L_LA(_nopage_tlbl)
+L_LA(_nopage_tlbs)
+L_LA(_nopage_tlbm)
+L_LA(_smp_pgtable_change)
+L_LA(_r3000_write_probe_fail)
+L_LA(_r3000_write_probe_ok)
 
 /* convenience macros for instructions */
 #ifdef CONFIG_MIPS64
@@ -431,6 +459,8 @@ L_LA(_split)
 # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
 # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
 # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
 #else
 # define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
 # define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
@@ -442,28 +472,33 @@ L_LA(_split)
 # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
 # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
 # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
+# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
+# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
 #endif
 
 #define i_b(buf, off) i_beq(buf, 0, 0, off)
+#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
+#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
 #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
+#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
 #define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
 #define i_nop(buf) i_sll(buf, 0, 0, 0)
 #define i_ssnop(buf) i_sll(buf, 0, 0, 1)
 #define i_ehb(buf) i_sll(buf, 0, 0, 3)
 
-#if CONFIG_MIPS64
-static __init int in_compat_space_p(long addr)
+#ifdef CONFIG_MIPS64
+static __init int __attribute__((unused)) in_compat_space_p(long addr)
 {
 	/* Is this address in 32bit compat space? */
 	return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
 }
 
-static __init int rel_highest(long val)
+static __init int __attribute__((unused)) rel_highest(long val)
 {
 	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
 }
 
-static __init int rel_higher(long val)
+static __init int __attribute__((unused)) rel_higher(long val)
 {
 	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
 }
@@ -550,22 +585,33 @@ static __init void resolve_relocs(struct
 				__resolve_relocs(rel, l);
 }
 
-static __init void copy_handler(struct reloc *rel, struct label *lab,
-				u32 *first, u32 *end, u32* target)
+static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
+			       long off)
 {
-	long off = (long)(target - first);
-
-	memcpy(target, first, (end - first) * sizeof(u32));
-
 	for (; rel->lab != label_invalid; rel++)
 		if (rel->addr >= first && rel->addr < end)
 			rel->addr += off;
+}
 
+static __init void move_labels(struct label *lab, u32 *first, u32 *end,
+			       long off)
+{
 	for (; lab->lab != label_invalid; lab++)
 		if (lab->addr >= first && lab->addr < end)
 			lab->addr += off;
 }
 
+static __init void copy_handler(struct reloc *rel, struct label *lab,
+				u32 *first, u32 *end, u32 *target)
+{
+	long off = (long)(target - first);
+
+	memcpy(target, first, (end - first) * sizeof(u32));
+
+	move_relocs(rel, first, end, off);
+	move_labels(lab, first, end, off);
+}
+
 static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
 							  u32 *addr)
 {
@@ -594,6 +640,20 @@ static void __attribute__((unused)) il_b
 	i_b(p, 0);
 }
 
+static void il_beqz(u32 **p, struct reloc **r, unsigned int reg,
+		    enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqz(p, reg, 0);
+}
+
+static void __attribute__((unused))
+il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
+{
+	r_mips_pc16(r, *p, l);
+	i_beqzl(p, reg, 0);
+}
+
 static void il_bnez(u32 **p, struct reloc **r, unsigned int reg,
 		    enum label_id l)
 {
@@ -608,7 +668,7 @@ static void il_bgezl(u32 **p, struct rel
 	i_bgezl(p, reg, 0);
 }
 
-/* The only registers allowed in TLB handlers. */
+/* The only general purpose registers allowed in TLB handlers. */
 #define K0		26
 #define K1		27
 
@@ -642,7 +702,6 @@ static __initdata u32 tlb_handler[128];
 static __initdata struct label labels[128];
 static __initdata struct reloc relocs[128];
 
-#ifdef CONFIG_MIPS32
 /*
  * The R3000 TLB handler is simple.
  */
@@ -676,10 +735,11 @@ static void __init build_r3000_tlb_refil
 		panic("TLB refill handler space exceeded");
 
 	printk("Synthesized TLB handler (%u instructions).\n",
-	       p - tlb_handler);
+	       (unsigned int)(p - tlb_handler));
 #ifdef DEBUG_TLB
 	{
 		int i;
+
 		for (i = 0; i < (p - tlb_handler); i++)
 			printk("%08x\n", tlb_handler[i]);
 	}
@@ -688,7 +748,6 @@ static void __init build_r3000_tlb_refil
 	memcpy((void *)CAC_BASE, tlb_handler, 0x80);
 	flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
 }
-#endif /* CONFIG_MIPS32 */
 
 /*
  * The R4000 TLB handler is much more complicated. We have two
@@ -738,12 +797,22 @@ static __init void __attribute__((unused
 }
 
 /*
- * Write random TLB entry, and care about the hazards from the
- * preceeding mtc0 and for the following eret.
+ * Write random or indexed TLB entry, and care about the hazards from
+ * the preceeding mtc0 and for the following eret.
  */
-static __init void build_tlb_write_random_entry(u32 **p, struct label **l,
-						struct reloc **r)
+enum tlb_write_entry { tlb_random, tlb_indexed };
+
+static __init void build_tlb_write_entry(u32 **p, struct label **l,
+					 struct reloc **r,
+					 enum tlb_write_entry wmode)
 {
+	void(*tlbw)(u32 **) = NULL;
+
+	switch (wmode) {
+	case tlb_random: tlbw = i_tlbwr; break;
+	case tlb_indexed: tlbw = i_tlbwi; break;
+	}
+
 	switch (current_cpu_data.cputype) {
 	case CPU_R4000PC:
 	case CPU_R4000SC:
@@ -753,11 +822,11 @@ static __init void build_tlb_write_rando
 	case CPU_R4400MC:
 		/*
 		 * This branch uses up a mtc0 hazard nop slot and saves
-		 * two nops after the tlbwr.
+		 * two nops after the tlbw instruction.
 		 */
-		il_bgezl(p, r, 0, label_tlbwr_hazard);
-		i_tlbwr(p);
-		l_tlbwr_hazard(l, *p);
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
 		i_nop(p);
 		break;
 
@@ -766,12 +835,13 @@ static __init void build_tlb_write_rando
 	case CPU_R5000:
 	case CPU_R5000A:
 	case CPU_5KC:
+	case CPU_TX49XX:
 	case CPU_AU1000:
 	case CPU_AU1100:
 	case CPU_AU1500:
 	case CPU_AU1550:
 		i_nop(p);
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_R10000:
@@ -781,24 +851,32 @@ static __init void build_tlb_write_rando
 	case CPU_4KSC:
 	case CPU_20KC:
 	case CPU_25KF:
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_NEVADA:
 		i_nop(p); /* QED specifies 2 nops hazard */
 		/*
 		 * This branch uses up a mtc0 hazard nop slot and saves
-		 * a nop after the tlbwr.
+		 * a nop after the tlbw instruction.
 		 */
-		il_bgezl(p, r, 0, label_tlbwr_hazard);
-		i_tlbwr(p);
-		l_tlbwr_hazard(l, *p);
+		il_bgezl(p, r, 0, label_tlbw_hazard);
+		tlbw(p);
+		l_tlbw_hazard(l, *p);
+		break;
+
+	case CPU_RM7000:
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
 		break;
 
 	case CPU_4KEC:
 	case CPU_24K:
 		i_ehb(p);
-		i_tlbwr(p);
+		tlbw(p);
 		break;
 
 	case CPU_RM9000:
@@ -812,13 +890,32 @@ static __init void build_tlb_write_rando
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
-		i_tlbwr(p);
+		tlbw(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		i_ssnop(p);
 		break;
 
+	case CPU_VR4111:
+	case CPU_VR4121:
+	case CPU_VR4122:
+	case CPU_VR4181:
+	case CPU_VR4181A:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		i_nop(p);
+		i_nop(p);
+		break;
+
+	case CPU_VR4131:
+	case CPU_VR4133:
+		i_nop(p);
+		i_nop(p);
+		tlbw(p);
+		break;
+
 	default:
 		panic("No TLB refill handler yet (CPU type: %d)",
 		      current_cpu_data.cputype);
@@ -826,7 +923,7 @@ static __init void build_tlb_write_rando
 	}
 }
 
-#if CONFIG_MIPS64
+#ifdef CONFIG_MIPS64
 /*
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pmd entry.
@@ -844,7 +941,7 @@ build_get_pmde64(u32 **p, struct label *
 	il_bltz(p, r, tmp, label_vmalloc);
 	/* No i_nop needed here, since the next insn doesn't touch TMP. */
 
-# ifdef CONFIG_SMP
+#ifdef CONFIG_SMP
 	/*
 	 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
 	 * stored in CONTEXT.
@@ -852,7 +949,17 @@ build_get_pmde64(u32 **p, struct label *
 	if (in_compat_space_p(pgdc)) {
 		i_dmfc0(p, ptr, C0_CONTEXT);
 		i_dsra(p, ptr, ptr, 23);
+		i_ld(p, ptr, 0, ptr);
 	} else {
+#ifdef CONFIG_BUILD_ELF64
+		i_dmfc0(p, ptr, C0_CONTEXT);
+		i_dsrl(p, ptr, ptr, 23);
+		i_dsll(p, ptr, ptr, 3);
+		i_LA_mostly(p, tmp, pgdc);
+		i_daddu(p, ptr, ptr, tmp);
+		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, rel_lo(pgdc), ptr);
+#else
 		i_dmfc0(p, ptr, C0_CONTEXT);
 		i_lui(p, tmp, rel_highest(pgdc));
 		i_dsll(p, ptr, ptr, 9);
@@ -860,12 +967,13 @@ build_get_pmde64(u32 **p, struct label *
 		i_dsrl32(p, ptr, ptr, 0);
 		i_and(p, ptr, ptr, tmp);
 		i_dmfc0(p, tmp, C0_BADVADDR);
+		i_ld(p, ptr, 0, ptr);
+#endif
 	}
-	i_ld(p, ptr, 0, ptr);
-# else
+#else
 	i_LA_mostly(p, ptr, pgdc);
 	i_ld(p, ptr, rel_lo(pgdc), ptr);
-# endif
+#endif
 
 	l_vmalloc_done(l, *p);
 	i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
@@ -902,13 +1010,14 @@ build_get_pgd_vmalloc64(u32 **p, struct 
 	}
 }
 
-#else /* CONFIG_MIPS32 */
+#else /* !CONFIG_MIPS64 */
 
 /*
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pgd entry.
  */
-static __init void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
+static __init void __attribute__((unused))
+build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
 {
 	long pgdc = (long)pgd_current;
 
@@ -928,17 +1037,13 @@ static __init void build_get_pgde32(u32 
 	i_sll(p, tmp, tmp, PGD_T_LOG2);
 	i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
 }
-#endif /* CONFIG_MIPS32 */
+
+#endif /* !CONFIG_MIPS64 */
 
 static __init void build_adjust_context(u32 **p, unsigned int ctx)
 {
-	unsigned int shift = 0;
-	unsigned int mask = 0xff0;
-
-#if !defined(CONFIG_MIPS64) && !defined(CONFIG_64BIT_PHYS_ADDR)
-	shift++;
-	mask |= 0x008;
-#endif
+	unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
 
 	switch (current_cpu_data.cputype) {
 	case CPU_VR41XX:
@@ -994,7 +1099,7 @@ static __init void build_update_entries(
 	 * Kernel is a special case. Only a few CPUs use it.
 	 */
 #ifdef CONFIG_64BIT_PHYS_ADDR
-	if (cpu_has_64bit_gp_regs) {
+	if (cpu_has_64bits) {
 		i_ld(p, tmp, 0, ptep); /* get even pte */
 		i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
 		i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
@@ -1049,20 +1154,20 @@ static void __init build_r4000_tlb_refil
 		i_MFC0(&p, K0, C0_BADVADDR);
 		i_MFC0(&p, K1, C0_ENTRYHI);
 		i_xor(&p, K0, K0, K1);
-		i_SRL(&p, K0, K0, PAGE_SHIFT+1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
 		il_bnez(&p, &r, K0, label_leave);
 		/* No need for i_nop */
 	}
 
 #ifdef CONFIG_MIPS64
-	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd ptr in K1 */
+	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
 #else
-	build_get_pgde32(&p, K0, K1); /* get pgd ptr in K1 */
+	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
 #endif
 
 	build_get_ptep(&p, K0, K1);
 	build_update_entries(&p, K0, K1);
-	build_tlb_write_random_entry(&p, &l, &r);
+	build_tlb_write_entry(&p, &l, &r, tlb_random);
 	l_leave(&l, p);
 	i_eret(&p); /* return from trap */
 
@@ -1121,6 +1226,7 @@ static void __init build_r4000_tlb_refil
 			i_nop(&f);
 		else {
 			copy_handler(relocs, labels, split, split + 1, f);
+			move_labels(labels, f, f + 1, -1);
 			f++;
 			split++;
 		}
@@ -1132,7 +1238,8 @@ static void __init build_r4000_tlb_refil
 #endif /* CONFIG_MIPS64 */
 
 	resolve_relocs(relocs, labels);
-	printk("Synthesized TLB handler (%u instructions).\n", final_len);
+	printk("Synthesized TLB refill handler (%u instructions).\n",
+	       final_len);
 
 #ifdef DEBUG_TLB
 	{
@@ -1147,10 +1254,530 @@ static void __init build_r4000_tlb_refil
 	flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
 }
 
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+#define __tlb_handler_align \
+	__attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
+
+/*
+ * 128 instructions for the fastpath handler is generous and should
+ * never be exceeded.
+ */
+#define FASTPATH_SIZE 128
+
+u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
+u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
+
+static void __init
+iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_lld(p, pte, offset, ptr);
+	else
+# endif
+		i_LL(p, pte, offset, ptr);
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_ld(p, pte, offset, ptr);
+	else
+# endif
+		i_LW(p, pte, offset, ptr);
+#endif
+}
+
+static void __init
+iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
+	unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_scd(p, pte, offset, ptr);
+	else
+# endif
+		i_SC(p, pte, offset, ptr);
+
+	if (r10000_llsc_war())
+		il_beqzl(p, r, pte, label_smp_pgtable_change);
+	else
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		/* no i_nop needed */
+		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+		il_beqz(p, r, pte, label_smp_pgtable_change);
+		/* no i_nop needed */
+		i_lw(p, pte, 0, ptr);
+	} else
+		i_nop(p);
+# else
+	i_nop(p);
+# endif
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (cpu_has_64bits)
+		i_sd(p, pte, offset, ptr);
+	else
+# endif
+		i_SW(p, pte, offset, ptr);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+	if (!cpu_has_64bits) {
+		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_ori(p, pte, pte, _PAGE_VALID);
+		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+		i_lw(p, pte, 0, ptr);
+	}
+# endif
+#endif
+}
+
+/*
+ * Check if PTE is present, if not then jump to LABEL. PTR points to
+ * the page table where this PTE is located, PTE will be re-loaded
+ * with it's original value.
+ */
+static void __init
+build_pte_present(u32 **p, struct label **l, struct reloc **r,
+		  unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE valid, store result in PTR. */
+static void __init
+build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be written to, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_writable(u32 **p, struct label **l, struct reloc **r,
+		   unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+	il_bnez(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/* Make PTE writable, update software status bits as well, then store
+ * at PTR.
+ */
+static void __init
+build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+		 unsigned int ptr)
+{
+	i_ori(p, pte, pte,
+	      _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+	iPTE_SW(p, r, pte, 0, ptr);
+}
+
+/*
+ * Check if PTE can be modified, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __init
+build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
+		     unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+	i_andi(p, pte, pte, _PAGE_WRITE);
+	il_beqz(p, r, pte, lid);
+	iPTE_LW(p, l, pte, 0, ptr);
+}
+
+/*
+ * R3000 style TLB load/store/modify handlers.
+ */
+
+/* This places the pte in the page table at PTR into ENTRYLO0. */
+static void __init
+build_r3000_pte_reload(u32 **p, unsigned int ptr)
+{
+	i_lw(p, ptr, 0, ptr);
+	i_nop(p); /* load delay */
+	i_mtc0(p, ptr, C0_ENTRYLO0);
+	i_nop(p); /* cp0 delay */
+}
+
+/*
+ * The index register may have the probe fail bit set,
+ * because we would trap on access kseg2, i.e. without refill.
+ */
+static void __init
+build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
+		      unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_INDEX);
+	i_nop(p); /* cp0 delay */
+	il_bltz(p, r, tmp, label_r3000_write_probe_fail);
+	i_nop(p); /* branch delay */
+	i_tlbwi(p);
+	il_b(p, r, label_r3000_write_probe_ok);
+	i_nop(p); /* branch delay */
+	l_r3000_write_probe_fail(l, *p);
+	i_tlbwr(p);
+	l_r3000_write_probe_ok(l, *p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
+				   unsigned int ptr)
+{
+	long pgdc = (long)pgd_current;
+
+	i_mfc0(p, pte, C0_BADVADDR);
+	i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
+	i_lw(p, ptr, rel_lo(pgdc), ptr);
+	i_srl(p, pte, pte, 22); /* load delay */
+	i_sll(p, pte, pte, 2);
+	i_addu(p, ptr, ptr, pte);
+	i_mfc0(p, pte, C0_CONTEXT);
+	i_lw(p, ptr, 0, ptr); /* cp0 delay */
+	i_andi(p, pte, pte, 0xffc); /* load delay */
+	i_addu(p, ptr, ptr, pte);
+	i_lw(p, pte, 0, ptr);
+	i_nop(p); /* load delay */
+	i_tlbp(p);
+}
+
+static void __init
+build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
+{
+	i_mfc0(p, tmp, C0_EPC);
+	i_nop(p); /* cp0 delay */
+	i_jr(p, tmp);
+	i_rfe(p); /* branch delay */
+}
+
+static void __init build_r3000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	build_r3000_tlb_write(&p, &l, &r, K0);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r3000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r3000_tlbchange_handler_head(&p, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	build_make_write(&p, &r, K0, K1);
+	build_r3000_pte_reload(&p, K1);
+	i_tlbwi(&p);
+	build_r3000_tlbchange_handler_tail(&p, K0);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
+/*
+ * R4000 style TLB load/store/modify handlers.
+ */
+static void __init
+build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int pte,
+				   unsigned int ptr)
+{
+#ifdef CONFIG_MIPS64
+	build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
+#else
+	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
+#endif
+
+	i_MFC0(p, pte, C0_BADVADDR);
+	i_LW(p, ptr, 0, ptr);
+	i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+	i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+	i_ADDU(p, ptr, ptr, pte);
+
+#ifdef CONFIG_SMP
+	l_smp_pgtable_change(l, *p);
+# endif
+	iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
+	build_tlb_probe_entry(p);
+}
+
+static void __init
+build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
+				   struct reloc **r, unsigned int tmp,
+				   unsigned int ptr)
+{
+	i_ori(p, ptr, ptr, sizeof(pte_t));
+	i_xori(p, ptr, ptr, sizeof(pte_t));
+	build_update_entries(p, tmp, ptr);
+	build_tlb_write_entry(p, l, r, tlb_indexed);
+	l_leave(l, *p);
+	i_eret(p); /* return from trap */
+
+#ifdef CONFIG_MIPS64
+	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+#endif
+}
+
+static void __init build_r4000_tlb_load_handler(void)
+{
+	u32 *p = handle_tlbl;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	if (bcm1250_m3_war()) {
+		i_MFC0(&p, K0, C0_BADVADDR);
+		i_MFC0(&p, K1, C0_ENTRYHI);
+		i_xor(&p, K0, K0, K1);
+		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		il_bnez(&p, &r, K0, label_leave);
+		/* No need for i_nop */
+	}
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_make_valid(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbl(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbl) > FASTPATH_SIZE)
+		panic("TLB load handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbl));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbl[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_store_handler(void)
+{
+	u32 *p = handle_tlbs;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbs(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbs) > FASTPATH_SIZE)
+		panic("TLB store handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbs));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbs[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
+}
+
+static void __init build_r4000_tlb_modify_handler(void)
+{
+	u32 *p = handle_tlbm;
+	struct label *l = labels;
+	struct reloc *r = relocs;
+
+	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(labels, 0, sizeof(labels));
+	memset(relocs, 0, sizeof(relocs));
+
+	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	/* Present and writable bits set, set accessed and dirty bits. */
+	build_make_write(&p, &r, K0, K1);
+	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+	l_nopage_tlbm(&l, p);
+	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+	i_nop(&p);
+
+	if ((p - handle_tlbm) > FASTPATH_SIZE)
+		panic("TLB modify handler fastpath space exceeded");
+
+	resolve_relocs(relocs, labels);
+	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
+	       (unsigned int)(p - handle_tlbm));
+
+#ifdef DEBUG_TLB
+	{
+		int i;
+
+		for (i = 0; i < FASTPATH_SIZE; i++)
+			printk("%08x\n", handle_tlbm[i]);
+	}
+#endif
+
+	flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
+}
+
 void __init build_tlb_refill_handler(void)
 {
+	/*
+	 * The refill handler is generated per-CPU, multi-node systems
+	 * may have local storage for it. The other handlers are only
+	 * needed once.
+	 */
+	static int run_once = 0;
+
 	switch (current_cpu_data.cputype) {
-#ifdef CONFIG_MIPS32
 	case CPU_R2000:
 	case CPU_R3000:
 	case CPU_R3000A:
@@ -1159,13 +1786,18 @@ void __init build_tlb_refill_handler(voi
 	case CPU_TX3922:
 	case CPU_TX3927:
 		build_r3000_tlb_refill_handler();
+		if (!run_once) {
+			build_r3000_tlb_load_handler();
+			build_r3000_tlb_store_handler();
+			build_r3000_tlb_modify_handler();
+			run_once++;
+		}
 		break;
 
 	case CPU_R6000:
 	case CPU_R6000A:
 		panic("No R6000 TLB refill handler yet");
 		break;
-#endif
 
 	case CPU_R8000:
 		panic("No R8000 TLB refill handler yet");
@@ -1173,5 +1805,11 @@ void __init build_tlb_refill_handler(voi
 
 	default:
 		build_r4000_tlb_refill_handler();
+		if (!run_once) {
+			build_r4000_tlb_load_handler();
+			build_r4000_tlb_store_handler();
+			build_r4000_tlb_modify_handler();
+			run_once++;
+		}
 	}
 }
diff -puN /dev/null arch/mips/mm/tlbex-fault.S
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/mm/tlbex-fault.S	2005-01-29 11:25:48.788452336 -0800
@@ -0,0 +1,28 @@
+/*
+ * 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/mipsregs.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.macro tlb_do_page_fault, write
+	NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
+	SAVE_ALL
+	MFC0	a2, CP0_BADVADDR
+	KMODE
+	move	a0, sp
+	REG_S	a2, PT_BVADDR(sp)
+	li	a1, \write
+	jal	do_page_fault
+	j	ret_from_exception
+	END(tlb_do_page_fault_\write)
+	.endm
+
+	tlb_do_page_fault 0
+	tlb_do_page_fault 1
diff -puN arch/mips/mm/tlb-sb1.c~mips-generic-mips-updates arch/mips/mm/tlb-sb1.c
--- 25/arch/mips/mm/tlb-sb1.c~mips-generic-mips-updates	2005-01-29 11:25:48.679468904 -0800
+++ 25-akpm/arch/mips/mm/tlb-sb1.c	2005-01-29 11:25:48.788452336 -0800
@@ -17,7 +17,6 @@
  * 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>
 #include <asm/bootinfo.h>
@@ -25,7 +24,7 @@
 
 extern void build_tlb_refill_handler(void);
 
-#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
 
 /* Dump the current entry* and pagemask registers */
 static inline void dump_cur_tlb_regs(void)
diff -puN /dev/null arch/mips/oprofile/common.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/oprofile/common.c	2005-01-29 11:25:48.789452184 -0800
@@ -0,0 +1,106 @@
+/*
+ * 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) 2004 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
+
+#include "op_impl.h"
+
+extern struct op_mips_model op_model_mipsxx __attribute__((weak));
+extern struct op_mips_model op_model_rm9000 __attribute__((weak));
+
+static struct op_mips_model *model;
+
+static struct op_counter_config ctr[20];
+
+static int op_mips_setup(void)
+{
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr);
+
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->cpu_setup, 0, 0, 1);
+
+        return 0;
+}
+
+static int op_mips_create_files(struct super_block * sb, struct dentry * root)
+{
+	int i;
+
+	for (i = 0; i < model->num_counters; ++i) {
+		struct dentry *dir;
+		char buf[3];
+
+		snprintf(buf, sizeof buf, "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+		/* Dummies.  */
+		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	return 0;
+}
+
+static int op_mips_start(void)
+{
+	on_each_cpu(model->cpu_start, NULL, 0, 1);
+
+	return 0;
+}
+
+static void op_mips_stop(void)
+{
+	/* Disable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_stop, NULL, 0, 1);
+}
+
+void __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	struct op_mips_model *lmodel = NULL;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_24K:
+		lmodel = &op_model_mipsxx;
+		break;
+
+	case CPU_RM9000:
+		lmodel = &op_model_rm9000;
+		break;
+	};
+
+	if (!lmodel)
+		return;
+
+	if (lmodel->init())
+		return;
+
+	model = lmodel;
+
+	ops->create_files = op_mips_create_files;
+	ops->setup = op_mips_setup;
+	ops->start = op_mips_start;
+	ops->stop = op_mips_stop;
+	ops->cpu_type = lmodel->cpu_type;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       lmodel->cpu_type);
+}
+
+void oprofile_arch_exit(void)
+{
+	model->exit();
+}
diff -puN /dev/null arch/mips/oprofile/Kconfig
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/oprofile/Kconfig	2005-01-29 11:25:48.790452032 -0800
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff -puN /dev/null arch/mips/oprofile/Makefile
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/oprofile/Makefile	2005-01-29 11:25:48.790452032 -0800
@@ -0,0 +1,15 @@
+EXTRA_CFLAGS := -Werror
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+oprofile-y				:= $(DRIVER_OBJS) common.o
+
+oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
diff -puN /dev/null arch/mips/oprofile/op_impl.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/oprofile/op_impl.h	2005-01-29 11:25:48.790452032 -0800
@@ -0,0 +1,37 @@
+/**
+ * @file arch/alpha/oprofile/op_impl.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Richard Henderson <rth@twiddle.net>
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long count;
+	/* Dummies because I am too lazy to hack the userspace tools.  */
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long exl;
+	unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks.  */
+struct op_mips_model {
+	void (*reg_setup) (struct op_counter_config *);
+	void (*cpu_setup) (void * dummy);
+	int (*init)(void);
+	void (*exit)(void);
+	void (*cpu_start)(void *args);
+	void (*cpu_stop)(void *args);
+	char *cpu_type;
+	unsigned char num_counters;
+};
+
+#endif
diff -puN /dev/null arch/mips/oprofile/op_model_rm9000.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/arch/mips/oprofile/op_model_rm9000.c	2005-01-29 11:25:48.791451880 -0800
@@ -0,0 +1,137 @@
+/*
+ * 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) 2004 by Ralf Baechle
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
+#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
+#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
+#define RM9K_COUNTER1_USER		(1ULL    <<  9)
+#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
+#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
+
+#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
+#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
+#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
+#define RM9K_COUNTER2_USER		(1ULL    << 25)
+#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
+#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
+
+extern unsigned int rm9000_perfcount_irq;
+
+static struct rm9k_register_config {
+	unsigned int control;
+	unsigned int reset_counter1;
+	unsigned int reset_counter2;
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_reg_setup(struct op_counter_config *ctr)
+{
+	unsigned int control = 0;
+
+	/* Compute the performance counter control word.  */
+	/* For now count kernel and user mode */
+	if (ctr[0].enabled)
+		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
+		           RM9K_COUNTER1_KERNEL |
+		           RM9K_COUNTER1_USER |
+		           RM9K_COUNTER1_ENABLE;
+	if (ctr[1].enabled)
+		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
+		           RM9K_COUNTER2_KERNEL |
+		           RM9K_COUNTER2_USER |
+		           RM9K_COUNTER2_ENABLE;
+	reg.control = control;
+
+	reg.reset_counter1 = 0x80000000 - ctr[0].count;
+	reg.reset_counter2 = 0x80000000 - ctr[1].count;
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_cpu_setup (void *args)
+{
+	uint64_t perfcount;
+
+	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
+	write_c0_perfcount(perfcount);
+}
+
+static void rm9000_cpu_start(void *args)
+{
+	/* Start all counters on current CPU */
+	write_c0_perfcontrol(reg.control);
+}
+
+static void rm9000_cpu_stop(void *args)
+{
+	/* Stop all counters on current CPU */
+	write_c0_perfcontrol(0);
+}
+
+static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
+	struct pt_regs *regs)
+{
+	unsigned int control = read_c0_perfcontrol();
+	uint32_t counter1, counter2;
+	uint64_t counters;
+
+	/*
+	 * RM9000 combines two 32-bit performance counters into a single
+	 * 64-bit coprocessor zero register.  To avoid a race updating the
+	 * registers we need to stop the counters while we're messing with
+	 * them ...
+	 */
+	write_c0_perfcontrol(0);
+
+	counters = read_c0_perfcount();
+	counter1 = counters;
+	counter2 = counters >> 32;
+
+	if (control & RM9K_COUNTER1_OVERFLOW) {
+		oprofile_add_sample(regs, 0);
+		counter1 = reg.reset_counter1;
+	}
+	if (control & RM9K_COUNTER2_OVERFLOW) {
+		oprofile_add_sample(regs, 1);
+		counter2 = reg.reset_counter2;
+	}
+
+	counters = ((uint64_t)counter2 << 32) | counter1;
+	write_c0_perfcount(counters);
+	write_c0_perfcontrol(reg.control);
+
+	return IRQ_HANDLED;
+}
+
+static int rm9000_init(void)
+{
+	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+	                   0, "Perfcounter", NULL);
+}
+
+static void rm9000_exit(void)
+{
+	free_irq(rm9000_perfcount_irq, NULL);
+}
+
+struct op_mips_model op_model_rm9000 = {
+	.reg_setup	= rm9000_reg_setup,
+	.cpu_setup	= rm9000_cpu_setup,
+	.init		= rm9000_init,
+	.exit		= rm9000_exit,
+	.cpu_start	= rm9000_cpu_start,
+	.cpu_stop	= rm9000_cpu_stop,
+	.cpu_type	= "mips/rm9000",
+	.num_counters	= 2
+};
diff -puN arch/mips/pci/pci.c~mips-generic-mips-updates arch/mips/pci/pci.c
--- 25/arch/mips/pci/pci.c~mips-generic-mips-updates	2005-01-29 11:25:48.682468448 -0800
+++ 25-akpm/arch/mips/pci/pci.c	2005-01-29 11:25:48.792451728 -0800
@@ -59,7 +59,7 @@ pcibios_align_resource(void *data, struc
 
 	if (res->flags & IORESOURCE_IO) {
 		/* Make sure we start at our min on all hoses */
-		if (start - hose->io_resource->start < PCIBIOS_MIN_IO)
+		if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
 			start = PCIBIOS_MIN_IO + hose->io_resource->start;
 
 		/*
@@ -69,7 +69,7 @@ pcibios_align_resource(void *data, struc
 			start = (start + 0x3ff) & ~0x3ff;
 	} else if (res->flags & IORESOURCE_MEM) {
 		/* Make sure we start at our min on all hoses */
-		if (start - hose->mem_resource->start < PCIBIOS_MIN_MEM)
+		if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
 			start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
 	}
 
@@ -294,6 +294,8 @@ pcibios_resource_to_bus(struct pci_dev *
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(PCIBIOS_MIN_IO);
+EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
 #endif
 
 char *pcibios_setup(char *str)
diff -puN include/asm-mips/addrspace.h~mips-generic-mips-updates include/asm-mips/addrspace.h
--- 25/include/asm-mips/addrspace.h~mips-generic-mips-updates	2005-01-29 11:25:48.683468296 -0800
+++ 25-akpm/include/asm-mips/addrspace.h	2005-01-29 11:25:48.792451728 -0800
@@ -126,6 +126,7 @@
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
     || defined (CONFIG_CPU_NEVADA)					\
+    || defined (CONFIG_CPU_TX49XX)					\
     || defined (CONFIG_CPU_MIPS64)
 #define	KUSIZE			0x0000010000000000	/* 2^^40 */
 #define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
diff -puN include/asm-mips/bitops.h~mips-generic-mips-updates include/asm-mips/bitops.h
--- 25/include/asm-mips/bitops.h~mips-generic-mips-updates	2005-01-29 11:25:48.685467992 -0800
+++ 25-akpm/include/asm-mips/bitops.h	2005-01-29 11:25:48.794451424 -0800
@@ -92,7 +92,7 @@ static inline void set_bit(unsigned long
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a |= mask;
 		__bi_local_irq_restore(flags);
@@ -152,7 +152,7 @@ static inline void clear_bit(unsigned lo
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a &= ~mask;
 		__bi_local_irq_restore(flags);
@@ -214,7 +214,7 @@ static inline void change_bit(unsigned l
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		*a ^= mask;
 		__bi_local_irq_restore(flags);
@@ -293,7 +293,7 @@ static inline int test_and_set_bit(unsig
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a |= mask;
@@ -320,7 +320,7 @@ static inline int __test_and_set_bit(uns
 	int retval;
 
 	a += nr >> SZLONG_LOG;
-	mask = 1 << (nr & SZLONG_MASK);
+	mask = 1UL << (nr & SZLONG_MASK);
 	retval = (mask & *a) != 0;
 	*a |= mask;
 
@@ -385,7 +385,7 @@ static inline int test_and_clear_bit(uns
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a &= ~mask;
@@ -474,7 +474,7 @@ static inline int test_and_change_bit(un
 		__bi_flags;
 
 		a += nr >> SZLONG_LOG;
-		mask = 1 << (nr & SZLONG_MASK);
+		mask = 1UL << (nr & SZLONG_MASK);
 		__bi_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a ^= mask;
diff -puN include/asm-mips/bootinfo.h~mips-generic-mips-updates include/asm-mips/bootinfo.h
--- 25/include/asm-mips/bootinfo.h~mips-generic-mips-updates	2005-01-29 11:25:48.686467840 -0800
+++ 25-akpm/include/asm-mips/bootinfo.h	2005-01-29 11:25:48.794451424 -0800
@@ -195,6 +195,7 @@
 #define  MACH_CASIO_E55		5	/* CASIO CASSIOPEIA E-10/15/55/65 */
 #define  MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (Mbase) */
 #define  MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
+#define  MACH_NEC_CMBVR4133	8	/* CMB VR4133 Board */
 
 #define MACH_GROUP_HP_LJ	20	/* Hewlett Packard LaserJet	*/
 #define  MACH_HP_LASERJET	1
diff -puN include/asm-mips/break.h~mips-generic-mips-updates include/asm-mips/break.h
--- 25/include/asm-mips/break.h~mips-generic-mips-updates	2005-01-29 11:25:48.688467536 -0800
+++ 25-akpm/include/asm-mips/break.h	2005-01-29 11:25:48.794451424 -0800
@@ -27,7 +27,7 @@
 #define BRK_STACKOVERFLOW 9	/* For Ada stackchecking */
 #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
 #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
-#define BRK_MULOVF	1023	/* Multiply overflow */
 #define BRK_BUG		512	/* Used by BUG() */
+#define BRK_MULOVF	1023	/* Multiply overflow */
 
 #endif /* __ASM_BREAK_H */
diff -puN include/asm-mips/cpu-features.h~mips-generic-mips-updates include/asm-mips/cpu-features.h
--- 25/include/asm-mips/cpu-features.h~mips-generic-mips-updates	2005-01-29 11:25:48.689467384 -0800
+++ 25-akpm/include/asm-mips/cpu-features.h	2005-01-29 11:25:48.795451272 -0800
@@ -3,11 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003 Ralf Baechle
+ * Copyright (C) 2003, 2004 Ralf Baechle
  */
 #ifndef __ASM_CPU_FEATURES_H
 #define __ASM_CPU_FEATURES_H
 
+#include <linux/config.h>
+
 #include <asm/cpu.h>
 #include <asm/cpu-info.h>
 #include <cpu-feature-overrides.h>
@@ -75,6 +77,25 @@
 #endif
 
 /*
+ * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
+ * such as the R10000 have I-Caches that snoop local stores; the embedded ones
+ * don't.  For maintaining I-cache coherency this means we need to flush the
+ * D-cache all the way back to whever the I-cache does refills from, so the
+ * I-cache has a chance to see the new data at all.  Then we have to flush the
+ * I-cache also.
+ * Note we may have been rescheduled and may no longer be running on the CPU
+ * that did the store so we can't optimize this into only doing the flush on
+ * the local CPU.
+ */
+#ifndef cpu_icache_snoops_remote_store
+#ifdef CONFIG_SMP
+#define cpu_icache_snoops_remote_store	(cpu_data[0].icache.flags & MIPS_IC_SNOOPS_REMOTE)
+#else
+#define cpu_icache_snoops_remote_store	1
+#endif
+#endif
+
+/*
  * Certain CPUs may throw bizarre exceptions if not the whole cacheline
  * contains valid instructions.  For these we ensure proper alignment of
  * signal trampolines and pad them to the size of a full cache lines with
diff -puN include/asm-mips/cpu-info.h~mips-generic-mips-updates include/asm-mips/cpu-info.h
--- 25/include/asm-mips/cpu-info.h~mips-generic-mips-updates	2005-01-29 11:25:48.691467080 -0800
+++ 25-akpm/include/asm-mips/cpu-info.h	2005-01-29 11:25:48.795451272 -0800
@@ -37,6 +37,7 @@ struct cache_desc {
 #define MIPS_CACHE_VTAG		0x00000002	/* Virtually tagged cache */
 #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
 #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
+#define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
 
 struct cpuinfo_mips {
 	unsigned long		udelay_val;
diff -puN include/asm-mips/debug.h~mips-generic-mips-updates include/asm-mips/debug.h
--- 25/include/asm-mips/debug.h~mips-generic-mips-updates	2005-01-29 11:25:48.692466928 -0800
+++ 25-akpm/include/asm-mips/debug.h	2005-01-29 11:25:48.796451120 -0800
@@ -29,9 +29,9 @@
 #include <linux/kernel.h>
 
 #define db_assert(x)  if (!(x)) { \
-	panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+	panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); }
 #define db_warn(x)  if (!(x)) { \
-	printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+	printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); }
 #define db_verify(x, y) db_assert(x y)
 #define db_verify_warn(x, y) db_warn(x y)
 #define db_run(x)  do { x; } while (0)
diff -puN include/asm-mips/elf.h~mips-generic-mips-updates include/asm-mips/elf.h
--- 25/include/asm-mips/elf.h~mips-generic-mips-updates	2005-01-29 11:25:48.693466776 -0800
+++ 25-akpm/include/asm-mips/elf.h	2005-01-29 11:25:48.797450968 -0800
@@ -23,7 +23,8 @@
 #define EF_MIPS_ABI_O64		0x00002000	/* O32 extended for 64 bit.  */
 
 #define PT_MIPS_REGINFO		0x70000000
-#define PT_MIPS_OPTIONS		0x70000001
+#define PT_MIPS_RTPROC		0x70000001
+#define PT_MIPS_OPTIONS		0x70000002
 
 /* Flags in the e_flags field of the header */
 #define EF_MIPS_NOREORDER	0x00000001
@@ -40,9 +41,10 @@
 #define DT_MIPS_ICHECKSUM	0x70000003
 #define DT_MIPS_IVERSION	0x70000004
 #define DT_MIPS_FLAGS		0x70000005
-  #define RHF_NONE		  0
-  #define RHF_HARDWAY		  1
-  #define RHF_NOTPOT		  2
+	#define RHF_NONE	0x00000000
+	#define RHF_HARDWAY	0x00000001
+	#define RHF_NOTPOT	0x00000002
+	#define RHF_SGI_ONLY	0x00000010
 #define DT_MIPS_BASE_ADDRESS	0x70000006
 #define DT_MIPS_CONFLICT	0x70000008
 #define DT_MIPS_LIBLIST		0x70000009
@@ -222,18 +224,22 @@ do {	current->thread.mflags &= ~MF_ABI_M
 
 #endif /* CONFIG_MIPS64 */
 
+extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
+extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
+
+#define ELF_CORE_COPY_REGS(elf_regs, regs)			\
+	dump_regs((elf_greg_t *)&(elf_regs), regs);
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs)			\
+	dump_task_fpu(tsk, elf_fpregs)
+
 #endif /* __KERNEL__ */
 
 /* This one accepts IRIX binaries.  */
-#define irix_elf_check_arch(hdr)	((hdr)->e_machine == EM_MIPS)
+#define irix_elf_check_arch(hdr)	((hdr)->e_flags & RHF_SGI_ONLY)
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
 
-#define ELF_CORE_COPY_REGS(_dest,_regs)				\
-	memcpy((char *) &_dest, (char *) _regs,			\
-	       sizeof(struct pt_regs));
-
 /* This yields a mask that user programs can use to figure out what
    instruction set this cpu supports.  This could be done in userspace,
    but it's not easy, and we've already done it here.  */
diff -puN include/asm-mips/gt64120.h~mips-generic-mips-updates include/asm-mips/gt64120.h
--- 25/include/asm-mips/gt64120.h~mips-generic-mips-updates	2005-01-29 11:25:48.695466472 -0800
+++ 25-akpm/include/asm-mips/gt64120.h	2005-01-29 11:25:48.799450664 -0800
@@ -1,6 +1,9 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 2004, 2005  MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  *
  *  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
@@ -18,20 +21,20 @@
 #ifndef _ASM_GT64120_H
 #define _ASM_GT64120_H
 
-#include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
-#define MSK(n)                    ((1 << (n)) - 1)
+#define MSK(n)			((1 << (n)) - 1)
 
 /*
  *  Register offset addresses
  */
+/* CPU Configuration.  */
 #define GT_CPU_OFS		0x000
 
-/*
- * Interrupt Registers
- */
+#define GT_MULTI_OFS		0x120
+
+/* CPU Address Decode.  */
 #define GT_SCS10LD_OFS		0x008
 #define GT_SCS10HD_OFS		0x010
 #define GT_SCS32LD_OFS		0x018
@@ -45,6 +48,7 @@
 #define GT_PCI0M0LD_OFS		0x058
 #define GT_PCI0M0HD_OFS		0x060
 #define GT_ISD_OFS		0x068
+
 #define GT_PCI0M1LD_OFS		0x080
 #define GT_PCI0M1HD_OFS		0x088
 #define GT_PCI1IOLD_OFS		0x090
@@ -53,10 +57,14 @@
 #define GT_PCI1M0HD_OFS		0x0a8
 #define GT_PCI1M1LD_OFS		0x0b0
 #define GT_PCI1M1HD_OFS		0x0b8
+#define GT_PCI1M1LD_OFS		0x0b0
+#define GT_PCI1M1HD_OFS		0x0b8
+
+#define GT_SCS10AR_OFS		0x0d0
+#define GT_SCS32AR_OFS		0x0d8
+#define GT_CS20R_OFS		0x0e0
+#define GT_CS3BOOTR_OFS		0x0e8
 
-/*
- * GT64120A only
- */
 #define GT_PCI0IOREMAP_OFS	0x0f0
 #define GT_PCI0M0REMAP_OFS	0x0f8
 #define GT_PCI0M1REMAP_OFS	0x100
@@ -64,6 +72,19 @@
 #define GT_PCI1M0REMAP_OFS	0x110
 #define GT_PCI1M1REMAP_OFS	0x118
 
+/* CPU Error Report.  */
+#define GT_CPUERR_ADDRLO_OFS	0x070
+#define GT_CPUERR_ADDRHI_OFS	0x078
+
+#define GT_CPUERR_DATALO_OFS	0x128			/* GT-64120A only  */
+#define GT_CPUERR_DATAHI_OFS	0x130			/* GT-64120A only  */
+#define GT_CPUERR_PARITY_OFS	0x138			/* GT-64120A only  */
+
+/* CPU Sync Barrier.  */
+#define GT_PCI0SYNC_OFS		0x0c0
+#define GT_PCI1SYNC_OFS		0x0c8
+
+/* SDRAM and Device Address Decode.  */
 #define GT_SCS0LD_OFS		0x400
 #define GT_SCS0HD_OFS		0x404
 #define GT_SCS1LD_OFS		0x408
@@ -83,37 +104,138 @@
 #define GT_BOOTLD_OFS		0x440
 #define GT_BOOTHD_OFS		0x444
 
-#define GT_SDRAM_B0_OFS	    	0x44c
+#define GT_ADERR_OFS		0x470
+
+/* SDRAM Configuration.  */
 #define GT_SDRAM_CFG_OFS	0x448
-#define GT_SDRAM_B2_OFS		0x454
+
 #define GT_SDRAM_OPMODE_OFS	0x474
 #define GT_SDRAM_BM_OFS		0x478
 #define GT_SDRAM_ADDRDECODE_OFS	0x47c
 
-#define GT_PCI0_CMD_OFS		0xc00	/* GT64120A only */
+/* SDRAM Parameters.  */
+#define GT_SDRAM_B0_OFS		0x44c
+#define GT_SDRAM_B1_OFS		0x450
+#define GT_SDRAM_B2_OFS		0x454
+#define GT_SDRAM_B3_OFS		0x458
+
+/* Device Parameters.  */
+#define GT_DEV_B0_OFS		0x45c
+#define GT_DEV_B1_OFS		0x460
+#define GT_DEV_B2_OFS		0x464
+#define GT_DEV_B3_OFS		0x468
+#define GT_DEV_BOOT_OFS		0x46c
+
+/* ECC.  */
+#define GT_ECC_ERRDATALO	0x480			/* GT-64120A only  */
+#define GT_ECC_ERRDATAHI	0x484			/* GT-64120A only  */
+#define GT_ECC_MEM		0x488			/* GT-64120A only  */
+#define GT_ECC_CALC		0x48c			/* GT-64120A only  */
+#define GT_ECC_ERRADDR		0x490			/* GT-64120A only  */
+
+/* DMA Record.  */
+#define GT_DMA0_CNT_OFS		0x800
+#define GT_DMA1_CNT_OFS		0x804
+#define GT_DMA2_CNT_OFS		0x808
+#define GT_DMA3_CNT_OFS		0x80c
+#define GT_DMA0_SA_OFS		0x810
+#define GT_DMA1_SA_OFS		0x814
+#define GT_DMA2_SA_OFS		0x818
+#define GT_DMA3_SA_OFS		0x81c
+#define GT_DMA0_DA_OFS		0x820
+#define GT_DMA1_DA_OFS		0x824
+#define GT_DMA2_DA_OFS		0x828
+#define GT_DMA3_DA_OFS		0x82c
+#define GT_DMA0_NEXT_OFS	0x830
+#define GT_DMA1_NEXT_OFS	0x834
+#define GT_DMA2_NEXT_OFS	0x838
+#define GT_DMA3_NEXT_OFS	0x83c
+
+#define GT_DMA0_CUR_OFS		0x870
+#define GT_DMA1_CUR_OFS		0x874
+#define GT_DMA2_CUR_OFS		0x878
+#define GT_DMA3_CUR_OFS		0x87c
+
+/* DMA Channel Control.  */
+#define GT_DMA0_CTRL_OFS	0x840
+#define GT_DMA1_CTRL_OFS	0x844
+#define GT_DMA2_CTRL_OFS	0x848
+#define GT_DMA3_CTRL_OFS	0x84c
+
+/* DMA Arbiter.  */
+#define GT_DMA_ARB_OFS		0x860
+
+/* Timer/Counter.  */
+#define GT_TC0_OFS		0x850
+#define GT_TC1_OFS		0x854
+#define GT_TC2_OFS		0x858
+#define GT_TC3_OFS		0x85c
+
+#define GT_TC_CONTROL_OFS	0x864
+
+/* PCI Internal.  */
+#define GT_PCI0_CMD_OFS		0xc00
 #define GT_PCI0_TOR_OFS		0xc04
-#define GT_PCI0_BS_SCS10_OFS    0xc08
-#define GT_PCI0_BS_SCS32_OFS    0xc0c
-#define GT_INTRCAUSE_OFS	0xc18
-#define GT_INTRMASK_OFS		0xc1c	/* GT64120A only */
+#define GT_PCI0_BS_SCS10_OFS	0xc08
+#define GT_PCI0_BS_SCS32_OFS	0xc0c
+#define GT_PCI0_BS_CS20_OFS	0xc10
+#define GT_PCI0_BS_CS3BT_OFS	0xc14
+
+#define GT_PCI1_IACK_OFS	0xc30
 #define GT_PCI0_IACK_OFS	0xc34
+
 #define GT_PCI0_BARE_OFS	0xc3c
-#define GT_HINTRCAUSE_OFS	0xc98	/* GT64120A only */
-#define GT_HINTRMASK_OFS	0xc9c	/* GT64120A only */
-#define GT_PCI1_CFGADDR_OFS	0xcf0	/* GT64120A only */
-#define GT_PCI1_CFGDATA_OFS	0xcf4	/* GT64120A only */
+#define GT_PCI0_PREFMBR_OFS	0xc40
+
+#define GT_PCI0_SCS10_BAR_OFS	0xc48
+#define GT_PCI0_SCS32_BAR_OFS	0xc4c
+#define GT_PCI0_CS20_BAR_OFS	0xc50
+#define GT_PCI0_CS3BT_BAR_OFS	0xc54
+#define GT_PCI0_SSCS10_BAR_OFS	0xc58
+#define GT_PCI0_SSCS32_BAR_OFS	0xc5c
+
+#define GT_PCI0_SCS3BT_BAR_OFS	0xc64
+
+#define GT_PCI1_CMD_OFS		0xc80
+#define GT_PCI1_TOR_OFS		0xc84
+#define GT_PCI1_BS_SCS10_OFS	0xc88
+#define GT_PCI1_BS_SCS32_OFS	0xc8c
+#define GT_PCI1_BS_CS20_OFS	0xc90
+#define GT_PCI1_BS_CS3BT_OFS	0xc94
+
+#define GT_PCI1_BARE_OFS	0xcbc
+#define GT_PCI1_PREFMBR_OFS	0xcc0
+
+#define GT_PCI1_SCS10_BAR_OFS	0xcc8
+#define GT_PCI1_SCS32_BAR_OFS	0xccc
+#define GT_PCI1_CS20_BAR_OFS	0xcd0
+#define GT_PCI1_CS3BT_BAR_OFS	0xcd4
+#define GT_PCI1_SSCS10_BAR_OFS	0xcd8
+#define GT_PCI1_SSCS32_BAR_OFS	0xcdc
+
+#define GT_PCI1_SCS3BT_BAR_OFS	0xce4
+
+#define GT_PCI1_CFGADDR_OFS	0xcf0
+#define GT_PCI1_CFGDATA_OFS	0xcf4
 #define GT_PCI0_CFGADDR_OFS	0xcf8
 #define GT_PCI0_CFGDATA_OFS	0xcfc
 
+/* Interrupts.  */
+#define GT_INTRCAUSE_OFS	0xc18
+#define GT_INTRMASK_OFS		0xc1c
+
+#define GT_PCI0_ICMASK_OFS	0xc24
+#define GT_PCI0_SERR0MASK_OFS	0xc28
+
+#define GT_CPU_INTSEL_OFS	0xc70
+#define GT_PCI0_INTSEL_OFS	0xc74
+
+#define GT_HINTRCAUSE_OFS	0xc98
+#define GT_HINTRMASK_OFS	0xc9c
+
+#define GT_PCI0_HICMASK_OFS	0xca4
+#define GT_PCI1_SERR1MASK_OFS	0xca8
 
-/*
- * Timer/Counter.  GT64120A only.
- */
-#define GT_TC0_OFS		0x850
-#define GT_TC1_OFS		0x854
-#define GT_TC2_OFS		0x858
-#define GT_TC3_OFS		0x85C
-#define GT_TC_CONTROL_OFS	0x864
 
 /*
  * I2O Support Registers
@@ -167,9 +289,9 @@
 /*
  *  Register encodings
  */
-#define GT_CPU_ENDIAN_SHF       12
-#define GT_CPU_ENDIAN_MSK       (MSK(1) << GT_CPU_ENDIAN_SHF)
-#define GT_CPU_ENDIAN_BIT       GT_CPU_ENDIAN_MSK
+#define GT_CPU_ENDIAN_SHF	12
+#define GT_CPU_ENDIAN_MSK	(MSK(1) << GT_CPU_ENDIAN_SHF)
+#define GT_CPU_ENDIAN_BIT	GT_CPU_ENDIAN_MSK
 #define GT_CPU_WR_SHF		16
 #define GT_CPU_WR_MSK		(MSK(1) << GT_CPU_WR_SHF)
 #define GT_CPU_WR_BIT		GT_CPU_WR_MSK
@@ -177,6 +299,15 @@
 #define GT_CPU_WR_DDDD		1
 
 
+#define GT_PCI_DCRM_SHF		21
+#define GT_PCI_LD_SHF		0
+#define GT_PCI_LD_MSK		(MSK(15) << GT_PCI_LD_SHF)
+#define GT_PCI_HD_SHF		0
+#define GT_PCI_HD_MSK		(MSK(7) << GT_PCI_HD_SHF)
+#define GT_PCI_REMAP_SHF	0
+#define GT_PCI_REMAP_MSK	(MSK(11) << GT_PCI_REMAP_SHF)
+
+
 #define GT_CFGADDR_CFGEN_SHF	31
 #define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
 #define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
@@ -285,7 +416,7 @@
 #define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
 
 #define GT_SDRAM_CFG_NINTERLEAVE_SHF	14
-#define GT_SDRAM_CFG_NINTERLEAVE_MSK    (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+#define GT_SDRAM_CFG_NINTERLEAVE_MSK	(MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
 #define GT_SDRAM_CFG_NINTERLEAVE_BIT	GT_SDRAM_CFG_NINTERLEAVE_MSK
 
 #define GT_SDRAM_CFG_RMW_SHF		15
@@ -370,7 +501,7 @@
 #define GT_PCI0_CFGADDR_REGNUM_SHF	2
 #define GT_PCI0_CFGADDR_REGNUM_MSK	(MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
 #define GT_PCI0_CFGADDR_FUNCTNUM_SHF	8
-#define GT_PCI0_CFGADDR_FUNCTNUM_MSK    (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK	(MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
 #define GT_PCI0_CFGADDR_DEVNUM_SHF	11
 #define GT_PCI0_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
 #define GT_PCI0_CFGADDR_BUSNUM_SHF	16
@@ -379,18 +510,18 @@
 #define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
 #define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
 
-#define GT_PCI0_CMD_MBYTESWAP_SHF       0
-#define GT_PCI0_CMD_MBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
-#define GT_PCI0_CMD_MBYTESWAP_BIT       GT_PCI0_CMD_MBYTESWAP_MSK
-#define GT_PCI0_CMD_MWORDSWAP_SHF       10
-#define GT_PCI0_CMD_MWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
-#define GT_PCI0_CMD_MWORDSWAP_BIT       GT_PCI0_CMD_MWORDSWAP_MSK
-#define GT_PCI0_CMD_SBYTESWAP_SHF       16
-#define GT_PCI0_CMD_SBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
-#define GT_PCI0_CMD_SBYTESWAP_BIT       GT_PCI0_CMD_SBYTESWAP_MSK
-#define GT_PCI0_CMD_SWORDSWAP_SHF       11
-#define GT_PCI0_CMD_SWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
-#define GT_PCI0_CMD_SWORDSWAP_BIT       GT_PCI0_CMD_SWORDSWAP_MSK
+#define GT_PCI0_CMD_MBYTESWAP_SHF	0
+#define GT_PCI0_CMD_MBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT	GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_MWORDSWAP_SHF	10
+#define GT_PCI0_CMD_MWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+#define GT_PCI0_CMD_MWORDSWAP_BIT	GT_PCI0_CMD_MWORDSWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF	16
+#define GT_PCI0_CMD_SBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT	GT_PCI0_CMD_SBYTESWAP_MSK
+#define GT_PCI0_CMD_SWORDSWAP_SHF	11
+#define GT_PCI0_CMD_SWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+#define GT_PCI0_CMD_SWORDSWAP_BIT	GT_PCI0_CMD_SWORDSWAP_MSK
 
 /*
  *  Misc
@@ -401,8 +532,8 @@
 #define GT_DEF_PCI0_MEM0_SIZE	0x02000000UL
 #define GT_DEF_BASE		0x14000000UL
 
-#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)   /* Max 256MB bank */
-#define GT_LATTIM_MIN    	6		      /* Minimum lat	*/
+#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)	/* Max 256MB bank  */
+#define GT_LATTIM_MIN		6			/* Minimum lat  */
 
 /*
  * The gt64120_dep.h file must define the following macros
diff -puN include/asm-mips/hardirq.h~mips-generic-mips-updates include/asm-mips/hardirq.h
--- 25/include/asm-mips/hardirq.h~mips-generic-mips-updates	2005-01-29 11:25:48.696466320 -0800
+++ 25-akpm/include/asm-mips/hardirq.h	2005-01-29 11:25:48.799450664 -0800
@@ -3,14 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-#include <linux/config.h>
 #include <linux/threads.h>
 #include <linux/irq.h>
 
diff -puN include/asm-mips/hazards.h~mips-generic-mips-updates include/asm-mips/hazards.h
--- 25/include/asm-mips/hazards.h~mips-generic-mips-updates	2005-01-29 11:25:48.697466168 -0800
+++ 25-akpm/include/asm-mips/hazards.h	2005-01-29 11:25:48.800450512 -0800
@@ -16,6 +16,10 @@
 	sll	$0, $0, 1
 	.endm
 
+	.macro	_ehb
+	sll	$0, $0, 3
+	.endm
+
 /*
  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
@@ -23,17 +27,19 @@
  */
 #ifdef CONFIG_CPU_RM9000
 
-#define mtc0_tlbw_hazard						\
-	.set	push;							\
-	.set	mips32;							\
-	_ssnop; _ssnop; _ssnop; _ssnop;					\
+	.macro	mtc0_tlbw_hazard
+	.set	push
+	.set	mips32
+	_ssnop; _ssnop; _ssnop; _ssnop
 	.set	pop
+	.endm
 
-#define tlbw_eret_hazard						\
-	.set	push;							\
-	.set	mips32;							\
-	_ssnop; _ssnop; _ssnop; _ssnop;					\
+	.macro	tlbw_eret_hazard
+	.set	push
+	.set	mips32
+	_ssnop; _ssnop; _ssnop; _ssnop
 	.set	pop
+	.endm
 
 #else
 
@@ -43,9 +49,12 @@
  * hazard so this is nice trick to have an optimal code for a range of
  * processors.
  */
-#define mtc0_tlbw_hazard						\
+	.macro	mtc0_tlbw_hazard
 	b	. + 8
-#define tlbw_eret_hazard
+	.endm
+
+	.macro	tlbw_eret_hazard
+	.endm
 #endif
 
 /*
@@ -58,31 +67,51 @@
 /*
  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
  */
-	.macro	ehb
-	sll	$0, $0, 3
-	.endm
 
-#define irq_enable_hazard						\
-	ehb		# irq_enable_hazard
+#define irq_enable_hazard
+	_ehb
 
-#define irq_disable_hazard						\
-	ehb		# irq_disable_hazard
+#define irq_disable_hazard
+	_ehb
 
-#else
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+
+/*
+ * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+ */
 
 #define irq_enable_hazard
+
 #define irq_disable_hazard
 
+#else
+
+/*
+ * Classic MIPS needs 1 - 3 nops or ssnops
+ */
+#define irq_enable_hazard
+#define irq_disable_hazard						\
+	_ssnop; _ssnop; _ssnop
+
 #endif
 
 #else /* __ASSEMBLY__ */
 
+__asm__(
+	"	.macro	_ssnop					\n\t"
+	"	sll	$0, $2, 1				\n\t"
+	"	.endm						\n\t"
+	"							\n\t"
+	"	.macro	_ehb					\n\t"
+	"	sll	$0, $0, 3				\n\t"
+	"	.endm						\n\t");
+
+#ifdef CONFIG_CPU_RM9000
 /*
  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
  * for data translations should not occur for 3 cpu cycles.
  */
-#ifdef CONFIG_CPU_RM9000
 
 #define mtc0_tlbw_hazard()						\
 	__asm__ __volatile__(						\
@@ -125,27 +154,23 @@
  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
  */
 __asm__(
-	"	.macro	ehb					\n\t"
-	"	sll	$0, $0, 3				\n\t"
-	"	.endm						\n\t"
-	"							\n\t"
 	"	.macro\tirq_enable_hazard			\n\t"
-	"	ehb						\n\t"
+	"	_ehb						\n\t"
 	"	.endm						\n\t"
 	"							\n\t"
 	"	.macro\tirq_disable_hazard			\n\t"
-	"	ehb						\n\t"
+	"	_ehb						\n\t"
 	"	.endm");
 
 #define irq_enable_hazard()						\
 	__asm__ __volatile__(						\
-	"ehb\t\t\t\t# irq_enable_hazard")
+	"_ehb\t\t\t\t# irq_enable_hazard")
 
 #define irq_disable_hazard()						\
 	__asm__ __volatile__(						\
-	"ehb\t\t\t\t# irq_disable_hazard")
+	"_ehb\t\t\t\t# irq_disable_hazard")
 
-#elif defined(CONFIG_CPU_R10000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
 
 /*
  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
@@ -170,10 +195,6 @@ __asm__(
  */
 
 __asm__(
-	"	.macro	_ssnop					\n\t"
-	"	sll	$0, $2, 1				\n\t"
-	"	.endm						\n\t"
-	"							\n\t"
 	"	#						\n\t"
 	"	# There is a hazard but we do not care		\n\t"
 	"	#						\n\t"
diff -puN include/asm-mips/io.h~mips-generic-mips-updates include/asm-mips/io.h
--- 25/include/asm-mips/io.h~mips-generic-mips-updates	2005-01-29 11:25:48.699465864 -0800
+++ 25-akpm/include/asm-mips/io.h	2005-01-29 11:25:48.804449904 -0800
@@ -6,21 +6,26 @@
  * Copyright (C) 1994, 1995 Waldorf GmbH
  * Copyright (C) 1994 - 2000 Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004, 2005  MIPS Technologies, Inc.  All rights reserved.
+ *	Author:	Maciej W. Rozycki <macro@mips.com>
  */
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <linux/kernel.h>
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
+#include <asm/bug.h>
+#include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
 #include <asm/page.h>
 #include <asm/pgtable-bits.h>
 #include <asm/processor.h>
-#include <asm/byteorder.h>
+
 #include <mangle-port.h>
 
 /*
@@ -29,34 +34,54 @@
 #undef CONF_SLOWDOWN_IO
 
 /*
- * Sane hardware offers swapping of I/O space accesses in hardware; less
- * sane hardware forces software to fiddle with this ...
+ * Raw operations are never swapped in software.  Otoh values that raw
+ * operations are working on may or may not have been swapped by the bus
+ * hardware.  An example use would be for flash memory that's used for
+ * execute in place.
  */
-#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
+# define __raw_ioswabb(x)	(x)
+# define __raw_ioswabw(x)	(x)
+# define __raw_ioswabl(x)	(x)
+# define __raw_ioswabq(x)	(x)
 
-#define __ioswab8(x) (x)
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
 
-#ifdef CONFIG_SGI_IP22
+# define ioswabb(x)		(x)
+# ifdef CONFIG_SGI_IP22
 /*
  * IP22 seems braindead enough to swap 16bits values in hardware, but
  * not 32bits.  Go figure... Can't tell without documentation.
  */
-#define __ioswab16(x) (x)
-#else
-#define __ioswab16(x) swab16(x)
-#endif
-#define __ioswab32(x) swab32(x)
-#define __ioswab64(x) swab64(x)
+#  define ioswabw(x)		(x)
+# else
+#  define ioswabw(x)		le16_to_cpu(x)
+# endif
+# define ioswabl(x)		le32_to_cpu(x)
+# define ioswabq(x)		le64_to_cpu(x)
 
 #else
 
-#define __ioswab8(x) (x)
-#define __ioswab16(x) (x)
-#define __ioswab32(x) (x)
-#define __ioswab64(x) (x)
+# define ioswabb(x)		(x)
+# define ioswabw(x)		(x)
+# define ioswabl(x)		(x)
+# define ioswabq(x)		(x)
 
 #endif
 
+/*
+ * Native bus accesses never swapped.
+ */
+#define bus_ioswabb(x)		(x)
+#define bus_ioswabw(x)		(x)
+#define bus_ioswabl(x)		(x)
+#define bus_ioswabq(x)		(x)
+
+#define __bus_ioswabq		bus_ioswabq
+
 #define IO_SPACE_LIMIT 0xffff
 
 /*
@@ -239,114 +264,214 @@ static inline void * __ioremap_mode(phys
 
 static inline void iounmap(volatile void __iomem *addr)
 {
-	if (cpu_has_64bits)
+	if (cpu_has_64bit_addresses)
 		return;
 
 	__iounmap(addr);
 }
 
-#define __raw_readb(addr)						\
-	(*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr)))
-#define __raw_readw(addr)						\
-	(*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr)))
-#define __raw_readl(addr)						\
-	(*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr)))
-#ifdef CONFIG_MIPS32
-#define ____raw_readq(addr)						\
-({									\
-	u64 __res;							\
-									\
-	__asm__ __volatile__ (						\
-		"	.set	mips3		# ____raw_readq	\n"	\
-		"	ld	%L0, (%1)			\n"	\
-		"	dsra32	%M0, %L0, 0			\n"	\
-		"	sll	%L0, %L0, 0			\n"	\
-		"	.set	mips0				\n"	\
-		: "=r" (__res)						\
-		: "r" (__swizzle_addr_q((unsigned long)(addr))));	\
-	__res;								\
-})
-#define __raw_readq(addr)						\
-({									\
-	unsigned long __flags;						\
-	u64 __res;							\
-									\
-	local_irq_save(__flags);					\
-	__res = ____raw_readq(addr);					\
-	local_irq_restore(__flags);					\
-	__res;								\
-})
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_readq(addr)						\
-	(*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)))
-#define __raw_readq(addr)	____raw_readq(addr)
-#endif
 
-#define readb(addr)		__ioswab8(__raw_readb(addr))
-#define readw(addr)		__ioswab16(__raw_readw(addr))
-#define readl(addr)		__ioswab32(__raw_readl(addr))
-#define readq(addr)		__ioswab64(__raw_readq(addr))
-#define readb_relaxed(addr)	readb(addr)
-#define readw_relaxed(addr)	readw(addr)
-#define readl_relaxed(addr)	readl(addr)
-#define readq_relaxed(addr)	readq(addr)
-
-#define __raw_writeb(b,addr)						\
-do {									\
-	((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b));	\
-} while (0)
-
-#define __raw_writew(w,addr)						\
-do {									\
-	((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w));	\
-} while (0)
-
-#define __raw_writel(l,addr)						\
-do {									\
-	((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l));	\
-} while (0)
-
-#ifdef CONFIG_MIPS32
-#define ____raw_writeq(val,addr)					\
-do {									\
-	u64 __tmp;							\
-									\
-	__asm__ __volatile__ (						\
-		"	.set	mips3				\n"	\
-		"	dsll32	%L0, %L0, 0	# ____raw_writeq\n"	\
-		"	dsrl32	%L0, %L0, 0			\n"	\
-		"	dsll32	%M0, %M0, 0			\n"	\
-		"	or	%L0, %L0, %M0			\n"	\
-		"	sd	%L0, (%2)			\n"	\
-		"	.set	mips0				\n"	\
-		: "=r" (__tmp)						\
-		: "0" ((unsigned long long)val),			\
-		  "r" (__swizzle_addr_q((unsigned long)(addr))));	\
-} while (0)
-
-#define __raw_writeq(val,addr)						\
-do {									\
-	unsigned long __flags;						\
-									\
-	local_irq_save(__flags);					\
-	____raw_writeq(val, addr);					\
-	local_irq_restore(__flags);					\
-} while (0)
-#endif
-#ifdef CONFIG_MIPS64
-#define ____raw_writeq(q,addr)						\
-do {									\
-	*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q);	\
-} while (0)
+#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)			\
+									\
+static inline void pfx##write##bwlq(type val,				\
+				    volatile void __iomem *mem)		\
+{									\
+	volatile type *__mem;						\
+	type __val;							\
+									\
+	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
+									\
+	__val = pfx##ioswab##bwlq(val);					\
+									\
+	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
+		*__mem = __val;						\
+	else if (cpu_has_64bits) {					\
+		unsigned long __flags;					\
+		type __tmp;						\
+									\
+		if (irq)						\
+			local_irq_save(__flags);			\
+		__asm__ __volatile__(					\
+			".set	mips3"		"\t\t# __writeq""\n\t"	\
+			"dsll32	%L0, %L0, 0"			"\n\t"	\
+			"dsrl32	%L0, %L0, 0"			"\n\t"	\
+			"dsll32	%M0, %M0, 0"			"\n\t"	\
+			"or	%L0, %L0, %M0"			"\n\t"	\
+			"sd	%L0, %2"			"\n\t"	\
+			".set	mips0"				"\n"	\
+			: "=r" (__tmp)					\
+			: "0" (__val), "m" (*__mem));			\
+		if (irq)						\
+			local_irq_restore(__flags);			\
+	} else								\
+		BUG();							\
+}									\
+									\
+static inline type pfx##read##bwlq(volatile void __iomem *mem)		\
+{									\
+	volatile type *__mem;						\
+	type __val;							\
+									\
+	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
+									\
+	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
+		__val = *__mem;						\
+	else if (cpu_has_64bits) {					\
+		unsigned long __flags;					\
+									\
+		local_irq_save(__flags);				\
+		__asm__ __volatile__(					\
+			".set	mips3"		"\t\t# __readq"	"\n\t"	\
+			"ld	%L0, %1"			"\n\t"	\
+			"dsra32	%M0, %L0, 0"			"\n\t"	\
+			"sll	%L0, %L0, 0"			"\n\t"	\
+			".set	mips0"				"\n"	\
+			: "=r" (__val)					\
+			: "m" (*__mem));				\
+		local_irq_restore(__flags);				\
+	} else {							\
+		__val = 0;						\
+		BUG();							\
+	}								\
+									\
+	return pfx##ioswab##bwlq(__val);				\
+}
 
-#define __raw_writeq(q,addr)	____raw_writeq(q, addr)
-#endif
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)			\
+									\
+static inline void pfx##out##bwlq##p(type val, unsigned long port)	\
+{									\
+	volatile type *__addr;						\
+	type __val;							\
+									\
+	port = __swizzle_addr_##bwlq(port);				\
+	__addr = (void *)(mips_io_port_base + port);			\
+									\
+	__val = pfx##ioswab##bwlq(val);					\
+									\
+	if (sizeof(type) != sizeof(u64)) {				\
+		*__addr = __val;					\
+		slow;							\
+	} else								\
+		BUILD_BUG();						\
+}									\
+									\
+static inline type pfx##in##bwlq##p(unsigned long port)			\
+{									\
+	volatile type *__addr;						\
+	type __val;							\
+									\
+	port = __swizzle_addr_##bwlq(port);				\
+	__addr = (void *)(mips_io_port_base + port);			\
+									\
+	if (sizeof(type) != sizeof(u64)) {				\
+		__val = *__addr;					\
+		slow;							\
+	} else {							\
+		__val = 0;						\
+		BUILD_BUG();						\
+	}								\
+									\
+	return pfx##ioswab##bwlq(__val);				\
+}
+
+#define __BUILD_MEMORY_PFX(bus, bwlq, type)				\
+									\
+__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
+									\
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)				\
+__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO(bwlq, type)						\
+									\
+__BUILD_MEMORY_PFX(, bwlq, type)					\
+__BUILD_MEMORY_PFX(__raw_, bwlq, type)					\
+__BUILD_MEMORY_PFX(bus_, bwlq, type)					\
+__BUILD_IOPORT_PFX(, bwlq, type)					\
+__BUILD_IOPORT_PFX(__raw_, bwlq, type)
+
+#define __BUILDIO(bwlq, type)						\
+									\
+__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
+
+BUILDIO(b, u8)
+BUILDIO(w, u16)
+BUILDIO(l, u32)
+BUILDIO(q, u64)
+
+__BUILDIO(q, u64)
+
+#define readb_relaxed			readb
+#define readw_relaxed			readw
+#define readl_relaxed			readl
+#define readq_relaxed			readq
+
+/*
+ * Some code tests for these symbols
+ */
+#define readq				readq
+#define writeq				writeq
+
+#define __BUILD_MEMORY_STRING(bwlq, type)				\
+									\
+static inline void writes##bwlq(volatile void __iomem *mem, void *addr,	\
+				unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		__raw_write##bwlq(*__addr, mem);			\
+		__addr++;						\
+	}								\
+}									\
+									\
+static inline void reads##bwlq(volatile void __iomem *mem, void *addr,	\
+			       unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		*__addr = __raw_read##bwlq(mem);			\
+		__addr++;						\
+	}								\
+}
+
+#define __BUILD_IOPORT_STRING(bwlq, type)				\
+									\
+static inline void outs##bwlq(unsigned long port, void *addr,		\
+			      unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		__raw_out##bwlq(*__addr, port);				\
+		__addr++;						\
+	}								\
+}									\
+									\
+static inline void ins##bwlq(unsigned long port, void *addr,		\
+			     unsigned int count)			\
+{									\
+	volatile type *__addr = addr;					\
+									\
+	while (count--) {						\
+		*__addr = __raw_in##bwlq(port);				\
+		__addr++;						\
+	}								\
+}
+
+#define BUILDSTRING(bwlq, type)						\
+									\
+__BUILD_MEMORY_STRING(bwlq, type)					\
+__BUILD_IOPORT_STRING(bwlq, type)
+
+BUILDSTRING(b, u8)
+BUILDSTRING(w, u16)
+BUILDSTRING(l, u32)
+BUILDSTRING(q, u64)
 
-#define writeb(b,addr)		__raw_writeb(__ioswab8(b),(addr))
-#define writew(w,addr)		__raw_writew(__ioswab16(w),(addr))
-#define writel(l,addr)		__raw_writel(__ioswab32(l),(addr))
-#define writeq(q,addr)		__raw_writeq(__ioswab64(q),(addr))
 
 /* Depends on MIPS II instruction set */
 #define mmiowb() asm volatile ("sync" ::: "memory")
@@ -394,7 +519,7 @@ do {									\
  *     address should have been obtained by ioremap.
  *     Returns 1 on a match.
  */
-static inline int check_signature(unsigned long io_addr,
+static inline int check_signature(char __iomem *io_addr,
 	const unsigned char *signature, int length)
 {
 	int retval = 0;
@@ -410,177 +535,6 @@ out:
 	return retval;
 }
 
-static inline void __outb(unsigned char val, unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
-}
-
-static inline void __outw(unsigned short val, unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
-}
-
-static inline void __outl(unsigned int val, unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
-}
-
-static inline void __outb_p(unsigned char val, unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
-	SLOW_DOWN_IO;
-}
-
-static inline void __outw_p(unsigned short val, unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
-	SLOW_DOWN_IO;
-}
-
-static inline void __outl_p(unsigned int val, unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
-	SLOW_DOWN_IO;
-}
-
-#define outb(val, port)		__outb(val, port)
-#define outw(val, port)		__outw(val, port)
-#define outl(val, port)		__outl(val, port)
-#define outb_p(val, port)	__outb_p(val, port)
-#define outw_p(val, port)	__outw_p(val, port)
-#define outl_p(val, port)	__outl_p(val, port)
-
-static inline unsigned char __inb(unsigned long port)
-{
-	port = __swizzle_addr_b(port);
-
-	return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
-}
-
-static inline unsigned short __inw(unsigned long port)
-{
-	port = __swizzle_addr_w(port);
-
-	return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
-}
-
-static inline unsigned int __inl(unsigned long port)
-{
-	port = __swizzle_addr_l(port);
-
-	return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
-}
-
-static inline unsigned char __inb_p(unsigned long port)
-{
-	u8 __val;
-
-	port = __swizzle_addr_b(port);
-
-	__val = *(volatile u8 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab8(__val);
-}
-
-static inline unsigned short __inw_p(unsigned long port)
-{
-	u16 __val;
-
-	port = __swizzle_addr_w(port);
-
-	__val = *(volatile u16 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab16(__val);
-}
-
-static inline unsigned int __inl_p(unsigned long port)
-{
-	u32 __val;
-
-	port = __swizzle_addr_l(port);
-
-	__val = *(volatile u32 *)(mips_io_port_base + port);
-	SLOW_DOWN_IO;
-
-	return __ioswab32(__val);
-}
-
-#define inb(port)	__inb(port)
-#define inw(port)	__inw(port)
-#define inl(port)	__inl(port)
-#define inb_p(port)	__inb_p(port)
-#define inw_p(port)	__inw_p(port)
-#define inl_p(port)	__inl_p(port)
-
-static inline void __outsb(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outb(*(u8 *)addr, port);
-		addr++;
-	}
-}
-
-static inline void __insb(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u8 *)addr = inb(port);
-		addr++;
-	}
-}
-
-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outw(*(u16 *)addr, port);
-		addr += 2;
-	}
-}
-
-static inline void __insw(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u16 *)addr = inw(port);
-		addr += 2;
-	}
-}
-
-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		outl(*(u32 *)addr, port);
-		addr += 4;
-	}
-}
-
-static inline void __insl(unsigned long port, void *addr, unsigned int count)
-{
-	while (count--) {
-		*(u32 *)addr = inl(port);
-		addr += 4;
-	}
-}
-
-#define outsb(port, addr, count)	__outsb(port, addr, count)
-#define insb(port, addr, count)		__insb(port, addr, count)
-#define outsw(port, addr, count)	__outsw(port, addr, count)
-#define insw(port, addr, count)		__insw(port, addr, count)
-#define outsl(port, addr, count)	__outsl(port, addr, count)
-#define insl(port, addr, count)		__insl(port, addr, count)
-
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
diff -puN include/asm-mips/irq_cpu.h~mips-generic-mips-updates include/asm-mips/irq_cpu.h
--- 25/include/asm-mips/irq_cpu.h~mips-generic-mips-updates	2005-01-29 11:25:48.700465712 -0800
+++ 25-akpm/include/asm-mips/irq_cpu.h	2005-01-29 11:25:48.804449904 -0800
@@ -15,5 +15,6 @@
 
 extern void mips_cpu_irq_init(int irq_base);
 extern void rm7k_cpu_irq_init(int irq_base);
+extern void rm9k_cpu_irq_init(int irq_base);
 
 #endif /* _ASM_IRQ_CPU_H */
diff -puN /dev/null include/asm-mips/m48t37.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/include/asm-mips/m48t37.h	2005-01-29 11:25:48.804449904 -0800
@@ -0,0 +1,35 @@
+/*
+ *  Registers for the SGS-Thomson M48T37 Timekeeper RAM chip
+ */
+#ifndef _ASM_M48T37_H
+#define _ASM_M48T37_H
+
+#include <linux/spinlock.h>
+
+extern spinlock_t rtc_lock;
+
+struct m48t37_rtc {
+	volatile u8	pad[0x7ff0];    /* NVRAM */
+	volatile u8	flags;
+	volatile u8	century;
+	volatile u8	alarm_sec;
+	volatile u8	alarm_min;
+	volatile u8	alarm_hour;
+	volatile u8	alarm_data;
+	volatile u8	interrupts;
+	volatile u8	watchdog;
+	volatile u8	control;
+	volatile u8	sec;
+	volatile u8	min;
+	volatile u8	hour;
+	volatile u8	day;
+	volatile u8	date;
+	volatile u8	month;
+	volatile u8	year;
+};
+
+#define M48T37_RTC_SET		0x80
+#define M48T37_RTC_STOPPED	0x80
+#define M48T37_RTC_READ		0x40
+
+#endif /* _ASM_M48T37_H */
diff -puN include/asm-mips/mach-generic/ide.h~mips-generic-mips-updates include/asm-mips/mach-generic/ide.h
--- 25/include/asm-mips/mach-generic/ide.h~mips-generic-mips-updates	2005-01-29 11:25:48.701465560 -0800
+++ 25-akpm/include/asm-mips/mach-generic/ide.h	2005-01-29 11:25:48.805449752 -0800
@@ -16,6 +16,8 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
 
 #ifndef MAX_HWIFS
 # ifdef CONFIG_BLK_DEV_IDEPCI
@@ -27,32 +29,68 @@
 
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
+static __inline__ int ide_probe_legacy(void)
+{
+#ifdef CONFIG_PCI
+	struct pci_dev *dev;
+	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL ||
+	    (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) {
+		pci_dev_put(dev);
+
+		return 1;
+	}
+	return 0;
+#elif defined(CONFIG_EISA) || defined(CONFIG_ISA)
+	return 1;
+#else
+	return 0;
+#endif
+}
+
 static __inline__ int ide_default_irq(unsigned long base)
 {
-	switch (base) {
-		case 0x1f0: return 14;
-		case 0x170: return 15;
-		case 0x1e8: return 11;
-		case 0x168: return 10;
-		case 0x1e0: return 8;
-		case 0x160: return 12;
+	if (ide_probe_legacy())
+		switch (base) {
+		case 0x1f0:
+			return 14;
+		case 0x170:
+			return 15;
+		case 0x1e8:
+			return 11;
+		case 0x168:
+			return 10;
+		case 0x1e0:
+			return 8;
+		case 0x160:
+			return 12;
 		default:
 			return 0;
-	}
+		}
+	else
+		return 0;
 }
 
 static __inline__ unsigned long ide_default_io_base(int index)
 {
-	switch (index) {
-		case 0:	return 0x1f0;
-		case 1:	return 0x170;
-		case 2: return 0x1e8;
-		case 3: return 0x168;
-		case 4: return 0x1e0;
-		case 5: return 0x160;
+	if (ide_probe_legacy())
+		switch (index) {
+		case 0:
+			return 0x1f0;
+		case 1:
+			return 0x170;
+		case 2:
+			return 0x1e8;
+		case 3:
+			return 0x168;
+		case 4:
+			return 0x1e0;
+		case 5:
+			return 0x160;
 		default:
 			return 0;
-	}
+		}
+	else
+		return 0;
 }
 
 #define IDE_ARCH_OBSOLETE_INIT
@@ -64,7 +102,17 @@ static __inline__ unsigned long ide_defa
 #define ide_init_default_irq(base)	ide_default_irq(base)
 #endif
 
-#include <asm-generic/ide_iops.h>
+/* MIPS port and memory-mapped I/O string operations.  */
+
+#define __ide_insw	insw
+#define __ide_insl	insl
+#define __ide_outsw	outsw
+#define __ide_outsl	outsl
+
+#define __ide_mm_insw	readsw
+#define __ide_mm_insl	readsl
+#define __ide_mm_outsw	writesw
+#define __ide_mm_outsl	writesl
 
 #endif /* __KERNEL__ */
 
diff -puN include/asm-mips/mipsregs.h~mips-generic-mips-updates include/asm-mips/mipsregs.h
--- 25/include/asm-mips/mipsregs.h~mips-generic-mips-updates	2005-01-29 11:25:48.703465256 -0800
+++ 25-akpm/include/asm-mips/mipsregs.h	2005-01-29 11:25:48.807449448 -0800
@@ -533,31 +533,50 @@
 #ifndef __ASSEMBLY__
 
 /*
- * Functions to access the r10k performance counter and control registers
+ * Functions to access the R10000 performance counters.  These are basically
+ * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
+ * performance counter number encoded into bits 1 ... 5 of the instruction.
+ * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
+ * disassembler these will look like an access to sel 0 or 1.
  */
-#define read_r10k_perf_cntr(counter)                            \
-({ unsigned int __res;                                          \
-        __asm__ __volatile__(                                   \
-        "mfpc\t%0, "STR(counter)                                \
-        : "=r" (__res));                                        \
-        __res;})
+#define read_r10k_perf_cntr(counter)				\
+({								\
+	unsigned int __res;					\
+	__asm__ __volatile__(					\
+	"mfpc\t%0, %1"						\
+        : "=r" (__res)						\
+	: "i" (counter));					\
+								\
+        __res;							\
+})
 
 #define write_r10k_perf_cntr(counter,val)                       \
-        __asm__ __volatile__(                                   \
-        "mtpc\t%0, "STR(counter)                                \
-        : : "r" (val));
-
-#define read_r10k_perf_cntl(counter)                            \
-({ unsigned int __res;                                          \
-        __asm__ __volatile__(                                   \
-        "mfps\t%0, "STR(counter)                                \
-        : "=r" (__res));                                        \
-        __res;})
+do {								\
+	__asm__ __volatile__(					\
+	"mtpc\t%0, %1"						\
+	:							\
+	: "r" (val), "i" (counter));				\
+} while (0)
+
+#define read_r10k_perf_event(counter)				\
+({								\
+	unsigned int __res;					\
+	__asm__ __volatile__(					\
+	"mfps\t%0, %1"						\
+        : "=r" (__res)						\
+	: "i" (counter));					\
+								\
+        __res;							\
+})
 
 #define write_r10k_perf_cntl(counter,val)                       \
-        __asm__ __volatile__(                                   \
-        "mtps\t%0, "STR(counter)                                \
-        : : "r" (val));
+do {								\
+	__asm__ __volatile__(					\
+	"mtps\t%0, %1"						\
+	:							\
+	: "r" (val), "i" (counter));				\
+} while (0)
+
 
 /*
  * Macros to access the system control coprocessor
@@ -579,8 +598,10 @@
 })
 
 #define __read_64bit_c0_register(source, sel)				\
-({ unsigned long __res;							\
-	if (sel == 0)							\
+({ unsigned long long __res;						\
+	if (sizeof(unsigned long) == 4)					\
+		__res = __read_64bit_c0_split(source, sel);		\
+	else if (sel == 0)						\
 		__asm__ __volatile__(					\
 			".set\tmips3\n\t"				\
 			"dmfc0\t%0, " #source "\n\t"			\
@@ -611,7 +632,9 @@ do {									\
 
 #define __write_64bit_c0_register(register, sel, value)			\
 do {									\
-	if (sel == 0)							\
+	if (sizeof(unsigned long) == 4)					\
+		__write_64bit_c0_split(register, sel, value);		\
+	else if (sel == 0)						\
 		__asm__ __volatile__(					\
 			".set\tmips3\n\t"				\
 			"dmtc0\t%z0, " #register "\n\t"			\
@@ -627,8 +650,8 @@ do {									\
 
 #define __read_ulong_c0_register(reg, sel)				\
 	((sizeof(unsigned long) == 4) ?					\
-	__read_32bit_c0_register(reg, sel) :				\
-	__read_64bit_c0_register(reg, sel))
+	(unsigned long) __read_32bit_c0_register(reg, sel) :		\
+	(unsigned long) __read_64bit_c0_register(reg, sel))
 
 #define __write_ulong_c0_register(reg, sel, val)			\
 do {									\
@@ -822,6 +845,10 @@ do {									\
 #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
 #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
 
+/* RM9000 PerfControl performance counter control register */
+#define read_c0_perfcontrol()	__read_32bit_c0_register($22, 0)
+#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
+
 #define read_c0_diag()		__read_32bit_c0_register($22, 0)
 #define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
 
@@ -846,6 +873,30 @@ do {									\
 #define read_c0_depc()		__read_ulong_c0_register($24, 0)
 #define write_c0_depc(val)	__write_ulong_c0_register($24, 0, val)
 
+/*
+ * MIPS32 / MIPS64 performance counters
+ */
+#define read_c0_perfctrl0()	__read_32bit_c0_register($25, 0)
+#define write_c0_perfctrl0(val)	__write_32bit_c0_register($25, 0, val)
+#define read_c0_perfcntr0()	__read_32bit_c0_register($25, 1)
+#define write_c0_perfcntr0(val)	__write_32bit_c0_register($25, 1, val)
+#define read_c0_perfctrl1()	__read_32bit_c0_register($25, 2)
+#define write_c0_perfctrl1(val)	__write_32bit_c0_register($25, 2, val)
+#define read_c0_perfcntr1()	__read_32bit_c0_register($25, 3)
+#define write_c0_perfcntr1(val)	__write_32bit_c0_register($25, 3, val)
+#define read_c0_perfctrl2()	__read_32bit_c0_register($25, 4)
+#define write_c0_perfctrl2(val)	__write_32bit_c0_register($25, 4, val)
+#define read_c0_perfcntr2()	__read_32bit_c0_register($25, 5)
+#define write_c0_perfcntr2(val)	__write_32bit_c0_register($25, 5, val)
+#define read_c0_perfctrl3()	__read_32bit_c0_register($25, 6)
+#define write_c0_perfctrl3(val)	__write_32bit_c0_register($25, 6, val)
+#define read_c0_perfcntr3()	__read_32bit_c0_register($25, 7)
+#define write_c0_perfcntr3(val)	__write_32bit_c0_register($25, 7, val)
+
+/* RM9000 PerfCount performance counter register */
+#define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
+#define write_c0_perfcount(val)	__write_64bit_c0_register($25, 0, val)
+
 #define read_c0_ecc()		__read_32bit_c0_register($26, 0)
 #define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
 
diff -puN include/asm-mips/mmu_context.h~mips-generic-mips-updates include/asm-mips/mmu_context.h
--- 25/include/asm-mips/mmu_context.h~mips-generic-mips-updates	2005-01-29 11:25:48.704465104 -0800
+++ 25-akpm/include/asm-mips/mmu_context.h	2005-01-29 11:25:48.807449448 -0800
@@ -19,26 +19,30 @@
 #include <asm/tlbflush.h>
 
 /*
- * For the fast tlb miss handlers, we currently keep a per cpu array
- * of pointers to the current pgd for each processor. Also, the proc.
- * id is stuffed into the context register. This should be changed to
- * use the processor id via current->processor, where current is stored
- * in watchhi/lo. The context register should be used to contiguously
- * map the page tables.
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
  */
+extern unsigned long pgd_current[];
+
 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
 	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
+
 #ifdef CONFIG_MIPS32
-#define TLBMISS_HANDLER_SETUP() \
-	write_c0_context((unsigned long) smp_processor_id() << 23); \
+#define TLBMISS_HANDLER_SETUP()						\
+	write_c0_context((unsigned long) smp_processor_id() << 23);	\
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-#ifdef CONFIG_MIPS64
-#define TLBMISS_HANDLER_SETUP() \
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()						\
 	write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-extern unsigned long pgd_current[];
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()						\
+	write_c0_context((unsigned long) smp_processor_id() << 23);	\
+	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+#endif
 
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
@@ -150,7 +154,7 @@ static inline void
 activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
 	unsigned long flags;
-	int cpu = smp_processor_id();
+	unsigned int cpu = smp_processor_id();
 
 	local_irq_save(flags);
 
diff -puN include/asm-mips/pgtable-32.h~mips-generic-mips-updates include/asm-mips/pgtable-32.h
--- 25/include/asm-mips/pgtable-32.h~mips-generic-mips-updates	2005-01-29 11:25:48.706464800 -0800
+++ 25-akpm/include/asm-mips/pgtable-32.h	2005-01-29 11:25:48.808449296 -0800
@@ -98,7 +98,7 @@ extern int add_temporary_entry(unsigned 
 
 extern void load_pgd(unsigned long pg_dir);
 
-extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
 
 /*
  * Empty pgd/pmd entries point to the invalid_pte_table.
diff -puN include/asm-mips/pmon.h~mips-generic-mips-updates include/asm-mips/pmon.h
--- 25/include/asm-mips/pmon.h~mips-generic-mips-updates	2005-01-29 11:25:48.707464648 -0800
+++ 25-akpm/include/asm-mips/pmon.h	2005-01-29 11:25:48.809449144 -0800
@@ -4,22 +4,43 @@
  * for more details.
  *
  * Copyright (C) 2004 by Ralf Baechle
+ *
+ * The cpustart method is a PMC-Sierra's function to start the secondary CPU.
+ * Stock PMON 2000 has the smpfork, semlock and semunlock methods instead.
  */
 #ifndef _ASM_PMON_H
 #define _ASM_PMON_H
 
 struct callvectors {
-	int	(*open) (char*, int, int);		/*	 0 */
-	int	(*close) (int);				/*	 4 */
-	int	(*read) (int, void*, int);		/*	 8 */
-	int	(*write) (int, void*, int);		/*	12 */
-	off_t	(*lseek) (int, off_t, int);		/*	16 */
-	int	(*printf) (const char*, ...);		/*	20 */
-	void	(*cacheflush) (void);			/*	24 */
-	char*	(*gets) (char*);			/*	28 */
-	int	(*cpustart) (int, void *, int, int);	/*	32 */
+	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*);
+	union {
+		int	(*smpfork) (unsigned long cp, char *sp);
+		int	(*cpustart) (long, long, long, long);
+	} _s;
+	int	(*semlock) (int sem);
+	void	(*semunlock) (int sem);
 };
 
 extern struct callvectors *debug_vectors;
 
+#define pmon_open(name, flags, mode)	debug_vectors->open(name, flage, mode)
+#define pmon_close(fd)			debug_vectors->close(fd)
+#define pmon_read(fd, buf, count)	debug_vectors->read(fd, buf, count)
+#define pmon_write(fd, buf, count)	debug_vectors->write(fd, buf, count)
+#define pmon_lseek(fd, off, whence)	debug_vectors->lseek(fd, off, whence)
+#define pmon_printf(fmt...)		debug_vectors->printf(fmt)
+#define pmon_cacheflush()		debug_vectors->cacheflush()
+#define pmon_gets(s)			debug_vectors->gets(s)
+#define pmon_cpustart(n, f, sp, gp)	debug_vectors->_s.cpustart(n, f, sp, gp)
+#define pmon_smpfork(cp, sp)		debug_vectors->_s.smpfork(cp, sp)
+#define pmon_semlock(sem)		debug_vectors->semlock(sem)
+#define pmon_semunlock(sem)		debug_vectors->semunlock(sem)
+
 #endif /* _ASM_PMON_H */
diff -puN include/asm-mips/prefetch.h~mips-generic-mips-updates include/asm-mips/prefetch.h
--- 25/include/asm-mips/prefetch.h~mips-generic-mips-updates	2005-01-29 11:25:48.708464496 -0800
+++ 25-akpm/include/asm-mips/prefetch.h	2005-01-29 11:25:48.809449144 -0800
@@ -8,6 +8,8 @@
 #ifndef __ASM_PREFETCH_H
 #define __ASM_PREFETCH_H
 
+#include <linux/config.h>
+
 /*
  * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
  * rather than wasting time we pretend these processors don't support
@@ -41,4 +43,46 @@
 #define Pref_WriteBackInvalidate	25
 #define Pref_PrepareForStore		30
 
+#ifdef __ASSEMBLY__
+
+	.macro	__pref hint addr
+#ifdef CONFIG_CPU_HAS_PREFETCH
+	pref	\hint, \addr
+#endif
+	.endm
+
+	.macro	pref_load addr
+	__pref	Pref_Load, \addr
+	.endm
+
+	.macro	pref_store addr
+	__pref	Pref_Store, \addr
+	.endm
+
+	.macro	pref_load_streamed addr
+	__pref	Pref_LoadStreamed, \addr
+	.endm
+
+	.macro	pref_store_streamed addr
+	__pref	Pref_StoreStreamed, \addr
+	.endm
+
+	.macro	pref_load_retained addr
+	__pref	Pref_LoadRetained, \addr
+	.endm
+
+	.macro	pref_store_retained addr
+	__pref	Pref_StoreRetained, \addr
+	.endm
+
+	.macro	pref_wback_inv addr
+	__pref	Pref_WriteBackInvalidate, \addr
+	.endm
+
+	.macro	pref_prepare_for_store addr
+	__pref	Pref_PrepareForStore, \addr
+	.endm
+
+#endif
+
 #endif /* __ASM_PREFETCH_H */
diff -puN include/asm-mips/processor.h~mips-generic-mips-updates include/asm-mips/processor.h
--- 25/include/asm-mips/processor.h~mips-generic-mips-updates	2005-01-29 11:25:48.710464192 -0800
+++ 25-akpm/include/asm-mips/processor.h	2005-01-29 11:25:48.809449144 -0800
@@ -66,11 +66,6 @@ extern unsigned int vced_count, vcei_cou
 	PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
 #endif
 
-/*
- * Size of io_bitmap in longwords.
- */
-#define IO_BITMAP_SIZE	2048
-
 #define NUM_FPU_REGS	32
 
 typedef __u64 fpureg_t;
diff -puN include/asm-mips/r4kcache.h~mips-generic-mips-updates include/asm-mips/r4kcache.h
--- 25/include/asm-mips/r4kcache.h~mips-generic-mips-updates	2005-01-29 11:25:48.711464040 -0800
+++ 25-akpm/include/asm-mips/r4kcache.h	2005-01-29 11:25:48.810448992 -0800
@@ -117,6 +117,21 @@ static inline void protected_writeback_d
 		: "i" (Hit_Writeback_Inv_D), "r" (addr));
 }
 
+static inline void protected_writeback_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		".set mips3\n"
+		"1:\tcache %0,(%1)\n"
+		"2:\t.set mips0\n\t"
+		".set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		STR(PTR)"\t1b,2b\n\t"
+		".previous"
+		:
+		: "i" (Hit_Writeback_Inv_SD), "r" (addr));
+}
+
 /*
  * This one is RM7000-specific
  */
diff -puN /dev/null include/asm-mips/reg.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/include/asm-mips/reg.h	2005-01-29 11:25:48.811448840 -0800
@@ -0,0 +1,129 @@
+/*
+ * Various register offset definitions for debuggers, core file
+ * examiners and whatnot.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ * Copyright (C) 1995, 1999 Silicon Graphics
+ */
+#ifndef __ASM_MIPS_REG_H
+#define __ASM_MIPS_REG_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_MIPS32) || defined(WANT_COMPAT_REG_H)
+
+#define EF_R0			6
+#define EF_R1			7
+#define EF_R2			8
+#define EF_R3			9
+#define EF_R4			10
+#define EF_R5			11
+#define EF_R6			12
+#define EF_R7			13
+#define EF_R8			14
+#define EF_R9			15
+#define EF_R10			16
+#define EF_R11			17
+#define EF_R12			18
+#define EF_R13			19
+#define EF_R14			20
+#define EF_R15			21
+#define EF_R16			22
+#define EF_R17			23
+#define EF_R18			24
+#define EF_R19			25
+#define EF_R20			26
+#define EF_R21			27
+#define EF_R22			28
+#define EF_R23			29
+#define EF_R24			30
+#define EF_R25			31
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26			32
+#define EF_R27			33
+
+#define EF_R28			34
+#define EF_R29			35
+#define EF_R30			36
+#define EF_R31			37
+
+/*
+ * Saved special registers
+ */
+#define EF_LO			38
+#define EF_HI			39
+
+#define EF_CP0_EPC		40
+#define EF_CP0_BADVADDR		41
+#define EF_CP0_STATUS		42
+#define EF_CP0_CAUSE		43
+#define EF_UNUSED0		44
+
+#define EF_SIZE			180
+
+#endif
+
+#if CONFIG_MIPS64
+
+#define EF_R0			 0
+#define EF_R1			 1
+#define EF_R2			 2
+#define EF_R3			 3
+#define EF_R4			 4
+#define EF_R5			 5
+#define EF_R6			 6
+#define EF_R7			 7
+#define EF_R8			 8
+#define EF_R9			 9
+#define EF_R10			10
+#define EF_R11			11
+#define EF_R12			12
+#define EF_R13			13
+#define EF_R14			14
+#define EF_R15			15
+#define EF_R16			16
+#define EF_R17			17
+#define EF_R18			18
+#define EF_R19			19
+#define EF_R20			20
+#define EF_R21			21
+#define EF_R22			22
+#define EF_R23			23
+#define EF_R24			24
+#define EF_R25			25
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26			26
+#define EF_R27			27
+
+
+#define EF_R28			28
+#define EF_R29			29
+#define EF_R30			30
+#define EF_R31			31
+
+/*
+ * Saved special registers
+ */
+#define EF_LO			32
+#define EF_HI			33
+
+#define EF_CP0_EPC		34
+#define EF_CP0_BADVADDR		35
+#define EF_CP0_STATUS		36
+#define EF_CP0_CAUSE		37
+
+#define EF_SIZE			304	/* size in bytes */
+
+#endif /* CONFIG_MIPS64 */
+
+#endif /* __ASM_MIPS_REG_H */
diff -puN include/asm-mips/sigcontext.h~mips-generic-mips-updates include/asm-mips/sigcontext.h
--- 25/include/asm-mips/sigcontext.h~mips-generic-mips-updates	2005-01-29 11:25:48.713463736 -0800
+++ 25-akpm/include/asm-mips/sigcontext.h	2005-01-29 11:25:48.811448840 -0800
@@ -41,8 +41,6 @@ struct sigcontext {
                                                                                 
 #if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
 
-#include <linux/types.h>
-
 /*
  * Keep this struct definition in sync with the sigcontext fragment
  * in arch/mips/tools/offset.c
@@ -66,6 +64,9 @@ struct sigcontext {
 };
 
 #ifdef __KERNEL__
+
+#include <linux/posix_types.h>
+
 struct sigcontext32 {
 	__u32	sc_regmask;		/* Unused */
 	__u32	sc_status;
diff -puN include/asm-mips/spinlock.h~mips-generic-mips-updates include/asm-mips/spinlock.h
--- 25/include/asm-mips/spinlock.h~mips-generic-mips-updates	2005-01-29 11:25:48.714463584 -0800
+++ 25-akpm/include/asm-mips/spinlock.h	2005-01-29 11:25:48.812448688 -0800
@@ -9,6 +9,7 @@
 #ifndef _ASM_SPINLOCK_H
 #define _ASM_SPINLOCK_H
 
+#include <linux/config.h>
 #include <asm/war.h>
 
 /*
diff -puN include/asm-mips/stackframe.h~mips-generic-mips-updates include/asm-mips/stackframe.h
--- 25/include/asm-mips/stackframe.h~mips-generic-mips-updates	2005-01-29 11:25:48.716463280 -0800
+++ 25-akpm/include/asm-mips/stackframe.h	2005-01-29 11:25:48.812448688 -0800
@@ -64,7 +64,7 @@
 		addu	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 #endif
-#ifdef CONFIG_MIPS64
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
 		MFC0	k1, CP0_CONTEXT
 		dsra	k1, 23
 		lui	k0, %hi(pgd_current)
@@ -74,6 +74,12 @@
 		daddu	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 #endif
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+		MFC0	k1, CP0_CONTEXT
+		dsrl	k1, 23
+		dsll	k1, k1, 3
+		LONG_L	k1, kernelsp(k1)
+#endif
 		.endm
 
 		.macro	set_saved_sp stackp temp temp2
@@ -83,13 +89,18 @@
 		sll	\temp, 2
 		LONG_S	\stackp, kernelsp(\temp)
 #endif
-#ifdef CONFIG_MIPS64
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
 		lw	\temp, TI_CPU(gp)
 		dsll	\temp, 3
 		lui	\temp2, %hi(kernelsp)
 		daddu	\temp, \temp2
 		LONG_S	\stackp, %lo(kernelsp)(\temp)
 #endif
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+		lw	\temp, TI_CPU(gp)
+		dsll	\temp, 3
+		LONG_S	\stackp, kernelsp(\temp)
+#endif
 		.endm
 #else
 		.macro	get_saved_sp	/* Uniprocessor variation */
@@ -104,6 +115,7 @@
 
 		.macro	SAVE_SOME
 		.set	push
+		.set	noat
 		.set	reorder
 		mfc0	k0, CP0_STATUS
 		sll	k0, 3		/* extract cu0 bit */
@@ -278,16 +290,16 @@
 
 		.macro	RESTORE_ALL
 		RESTORE_TEMP
-		RESTORE_AT
 		RESTORE_STATIC
+		RESTORE_AT
 		RESTORE_SOME
 		RESTORE_SP
 		.endm
 
 		.macro	RESTORE_ALL_AND_RET
 		RESTORE_TEMP
-		RESTORE_AT
 		RESTORE_STATIC
+		RESTORE_AT
 		RESTORE_SOME
 		RESTORE_SP_AND_RET
 		.endm
diff -puN include/asm-mips/string.h~mips-generic-mips-updates include/asm-mips/string.h
--- 25/include/asm-mips/string.h~mips-generic-mips-updates	2005-01-29 11:25:48.717463128 -0800
+++ 25-akpm/include/asm-mips/string.h	2005-01-29 11:25:48.813448536 -0800
@@ -18,6 +18,8 @@
  */
 #ifdef CONFIG_MIPS32
 
+#ifndef IN_STRING_C
+
 #define __HAVE_ARCH_STRCPY
 static __inline__ char *strcpy(char *__dest, __const__ char *__src)
 {
@@ -96,6 +98,8 @@ static __inline__ int strcmp(__const__ c
   return __res;
 }
 
+#endif /* !defined(IN_STRING_C) */
+
 #define __HAVE_ARCH_STRNCMP
 static __inline__ int
 strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
diff -puN include/asm-mips/uaccess.h~mips-generic-mips-updates include/asm-mips/uaccess.h
--- 25/include/asm-mips/uaccess.h~mips-generic-mips-updates	2005-01-29 11:25:48.719462824 -0800
+++ 25-akpm/include/asm-mips/uaccess.h	2005-01-29 11:25:48.814448384 -0800
@@ -150,7 +150,7 @@ static inline int verify_area(int type, 
  * Returns zero on success, or -EFAULT on error.
  */
 #define put_user(x,ptr)	\
-	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * get_user: - Get a simple variable from user space.
@@ -170,7 +170,7 @@ static inline int verify_area(int type, 
  * On error, the variable @x is set to zero.
  */
 #define get_user(x,ptr) \
-	__get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_check((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __put_user: - Write a simple value into user space, with less checking.
@@ -192,7 +192,7 @@ static inline int verify_area(int type, 
  * Returns zero on success, or -EFAULT on error.
  */
 #define __put_user(x,ptr) \
-	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__put_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 /*
  * __get_user: - Get a simple variable from user space, with less checking.
@@ -215,7 +215,7 @@ static inline int verify_area(int type, 
  * On error, the variable @x is set to zero.
  */
 #define __get_user(x,ptr) \
-	__get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
@@ -232,9 +232,10 @@ struct __large_struct { unsigned long bu
 
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
-	long __gu_err = 0;						\
 	__typeof(*(ptr)) __gu_val = 0;					\
 	long __gu_addr;							\
+	long __gu_err = 0;						\
+									\
 	might_sleep();							\
 	__gu_addr = (long) (ptr);					\
 	switch (size) {							\
@@ -244,17 +245,18 @@ struct __large_struct { unsigned long bu
 	case 8: __GET_USER_DW(__gu_err); break;				\
 	default: __get_user_unknown(); break;				\
 	}								\
-	 x = (__typeof__(*(ptr))) __gu_val;				\
+	x = (__typeof__(*(ptr))) __gu_val;				\
 	__gu_err;							\
 })
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
 	__typeof__(*(ptr)) __gu_val = 0;				\
-	long __gu_addr = (long) (ptr);					\
+	long __gu_addr;							\
 	long __gu_err;							\
 									\
 	might_sleep();							\
+	__gu_addr = (long) (ptr);					\
 	__gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size);	\
 									\
 	if (likely(!__gu_err)) {					\
@@ -267,7 +269,7 @@ struct __large_struct { unsigned long bu
 		}							\
 	}								\
 	x = (__typeof__(*(ptr))) __gu_val;				\
-	 __gu_err;							\
+	__gu_err;							\
 })
 
 #define __get_user_asm(insn,__gu_err)					\
@@ -324,9 +326,10 @@ extern void __get_user_unknown(void);
 
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
-	long __pu_err = 0;						\
 	__typeof__(*(ptr)) __pu_val;					\
 	long __pu_addr;							\
+	long __pu_err = 0;						\
+									\
 	might_sleep();							\
 	__pu_val = (x);							\
 	__pu_addr = (long) (ptr);					\
@@ -342,11 +345,13 @@ extern void __get_user_unknown(void);
 
 #define __put_user_check(x,ptr,size)					\
 ({									\
-	__typeof__(*(ptr)) __pu_val = (x);				\
-	long __pu_addr = (long) (ptr);					\
+	__typeof__(*(ptr)) __pu_val;					\
+	long __pu_addr;							\
 	long __pu_err;							\
 									\
 	might_sleep();							\
+	__pu_val = (x);							\
+	__pu_addr = (long) (ptr);					\
 	__pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size);	\
 									\
 	if (likely(!__pu_err)) {					\
diff -puN include/asm-mips/unistd.h~mips-generic-mips-updates include/asm-mips/unistd.h
--- 25/include/asm-mips/unistd.h~mips-generic-mips-updates	2005-01-29 11:25:48.720462672 -0800
+++ 25-akpm/include/asm-mips/unistd.h	2005-01-29 11:25:48.815448232 -0800
@@ -1100,6 +1100,9 @@ type name (atype a,btype b,ctype c,dtype
 #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 #ifdef __KERNEL__
+
+#include <linux/config.h>
+
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
_
