sh: Split out extable.c _32 and _64 variants.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index d35cacc..9f4bc3d 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -1,37 +1,5 @@
-#
-# Makefile for the Linux SuperH-specific parts of the memory manager.
-#
-
-obj-y			:= init.o extable.o consistent.o
-
-ifndef CONFIG_CACHE_OFF
-obj-$(CONFIG_CPU_SH2)		+= cache-sh2.o
-obj-$(CONFIG_CPU_SH3)		+= cache-sh3.o
-obj-$(CONFIG_CPU_SH4)		+= cache-sh4.o
-obj-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
+ifeq ($(CONFIG_SUPERH32),y)
+include ${srctree}/arch/sh/mm/Makefile_32
+else
+include ${srctree}/arch/sh/mm/Makefile_64
 endif
-
-mmu-y			:= tlb-nommu.o pg-nommu.o
-mmu-$(CONFIG_MMU)	:= fault.o clear_page.o copy_page.o tlb-flush.o	\
-			   ioremap.o
-
-obj-y			+= $(mmu-y)
-
-ifdef CONFIG_DEBUG_FS
-obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
-endif
-
-ifdef CONFIG_MMU
-obj-$(CONFIG_CPU_SH3)	+= tlb-sh3.o
-obj-$(CONFIG_CPU_SH4)	+= tlb-sh4.o
-ifndef CONFIG_CACHE_OFF
-obj-$(CONFIG_CPU_SH4)		+= pg-sh4.o
-obj-$(CONFIG_SH7705_CACHE_32KB)	+= pg-sh7705.o
-endif
-endif
-
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB)		+= pmb.o
-obj-$(CONFIG_NUMA)		+= numa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
new file mode 100644
index 0000000..cc68b26
--- /dev/null
+++ b/arch/sh/mm/Makefile_32
@@ -0,0 +1,37 @@
+#
+# Makefile for the Linux SuperH-specific parts of the memory manager.
+#
+
+obj-y			:= init.o extable_32.o consistent.o
+
+ifndef CONFIG_CACHE_OFF
+obj-$(CONFIG_CPU_SH2)		+= cache-sh2.o
+obj-$(CONFIG_CPU_SH3)		+= cache-sh3.o
+obj-$(CONFIG_CPU_SH4)		+= cache-sh4.o
+obj-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
+endif
+
+mmu-y			:= tlb-nommu.o pg-nommu.o
+mmu-$(CONFIG_MMU)	:= fault.o clear_page.o copy_page.o tlb-flush.o	\
+			   ioremap.o
+
+obj-y			+= $(mmu-y)
+
+ifdef CONFIG_DEBUG_FS
+obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
+endif
+
+ifdef CONFIG_MMU
+obj-$(CONFIG_CPU_SH3)	+= tlb-sh3.o
+obj-$(CONFIG_CPU_SH4)	+= tlb-sh4.o
+ifndef CONFIG_CACHE_OFF
+obj-$(CONFIG_CPU_SH4)		+= pg-sh4.o
+obj-$(CONFIG_SH7705_CACHE_32KB)	+= pg-sh7705.o
+endif
+endif
+
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_PMB)		+= pmb.o
+obj-$(CONFIG_NUMA)		+= numa.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
new file mode 100644
index 0000000..de964a1
--- /dev/null
+++ b/arch/sh/mm/Makefile_64
@@ -0,0 +1,11 @@
+#
+# Makefile for the Linux SuperH-specific parts of the memory manager.
+#
+
+obj-y			:= init.o extable_64.o consistent.o
+
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_PMB)		+= pmb.o
+obj-$(CONFIG_NUMA)		+= numa.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/extable.c b/arch/sh/mm/extable_32.c
similarity index 100%
rename from arch/sh/mm/extable.c
rename to arch/sh/mm/extable_32.c
diff --git a/arch/sh/mm/extable_64.c b/arch/sh/mm/extable_64.c
new file mode 100644
index 0000000..a2e6e05
--- /dev/null
+++ b/arch/sh/mm/extable_64.c
@@ -0,0 +1,80 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/mm/extable.c
+ *
+ * Copyright (C) 2003 Richard Curnow
+ * Copyright (C) 2003, 2004  Paul Mundt
+ *
+ * Cloned from the 2.5 SH version..
+ */
+#include <linux/rwsem.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern unsigned long copy_user_memcpy, copy_user_memcpy_end;
+extern void __copy_user_fixup(void);
+
+static const struct exception_table_entry __copy_user_fixup_ex = {
+	.fixup = (unsigned long)&__copy_user_fixup,
+};
+
+/* Some functions that may trap due to a bad user-mode address have too many loads
+   and stores in them to make it at all practical to label each one and put them all in
+   the main exception table.
+
+   In particular, the fast memcpy routine is like this.  It's fix-up is just to fall back
+   to a slow byte-at-a-time copy, which is handled the conventional way.  So it's functionally
+   OK to just handle any trap occurring in the fast memcpy with that fixup. */
+static const struct exception_table_entry *check_exception_ranges(unsigned long addr)
+{
+	if ((addr >= (unsigned long)&copy_user_memcpy) &&
+	    (addr <= (unsigned long)&copy_user_memcpy_end))
+		return &__copy_user_fixup_ex;
+
+	return NULL;
+}
+
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+		 const struct exception_table_entry *last,
+		 unsigned long value)
+{
+	const struct exception_table_entry *mid;
+
+	mid = check_exception_ranges(value);
+	if (mid)
+		return mid;
+
+        while (first <= last) {
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid;
+                else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+
+        return NULL;
+}
+
+int fixup_exception(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+
+	fixup = search_exception_tables(regs->pc);
+	if (fixup) {
+		regs->pc = fixup->fixup;
+		return 1;
+	}
+
+	return 0;
+}
+