aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu')
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile5
-rw-r--r--arch/sh/kernel/cpu/sh2a/opcode_helper.c55
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c1
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S13
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile6
-rw-r--r--arch/sh/kernel/cpu/sh4/ex.S62
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c3
7 files changed, 71 insertions, 74 deletions
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 350972ae941..965fa2572b2 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -2,9 +2,8 @@
# Makefile for the Linux/SuperH SH-2A backends.
#
-obj-y := common.o probe.o
+obj-y := common.o probe.o opcode_helper.o
-common-y += $(addprefix ../sh2/, ex.o)
-common-y += $(addprefix ../sh2/, entry.o)
+common-y += $(addprefix ../sh2/, ex.o entry.o)
obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
diff --git a/arch/sh/kernel/cpu/sh2a/opcode_helper.c b/arch/sh/kernel/cpu/sh2a/opcode_helper.c
new file mode 100644
index 00000000000..9704b7926d8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/opcode_helper.c
@@ -0,0 +1,55 @@
+/*
+ * arch/sh/kernel/cpu/sh2a/opcode_helper.c
+ *
+ * Helper for the SH-2A 32-bit opcodes.
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <asm/system.h>
+
+/*
+ * Instructions on SH are generally fixed at 16-bits, however, SH-2A
+ * introduces some 32-bit instructions. Since there are no real
+ * constraints on their use (and they can be mixed and matched), we need
+ * to check the instruction encoding to work out if it's a true 32-bit
+ * instruction or not.
+ *
+ * Presently, 32-bit opcodes have only slight variations in what the
+ * actual encoding looks like in the first-half of the instruction, which
+ * makes it fairly straightforward to differentiate from the 16-bit ones.
+ *
+ * First 16-bits of encoding Used by
+ *
+ * 0011nnnnmmmm0001 mov.b, mov.w, mov.l, fmov.d,
+ * fmov.s, movu.b, movu.w
+ *
+ * 0011nnnn0iii1001 bclr.b, bld.b, bset.b, bst.b, band.b,
+ * bandnot.b, bldnot.b, bor.b, bornot.b,
+ * bxor.b
+ *
+ * 0000nnnniiii0000 movi20
+ * 0000nnnniiii0001 movi20s
+ */
+unsigned int instruction_size(unsigned int insn)
+{
+ /* Look for the common cases */
+ switch ((insn & 0xf00f)) {
+ case 0x0000: /* movi20 */
+ case 0x0001: /* movi20s */
+ case 0x3001: /* 32-bit mov/fmov/movu variants */
+ return 4;
+ }
+
+ /* And the special cases.. */
+ switch ((insn & 0xf08f)) {
+ case 0x3009: /* 32-bit b*.b bit operations */
+ return 4;
+ }
+
+ return 2;
+}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 426f6db01fc..f455c350978 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -18,6 +18,7 @@ int __init detect_cpu_and_cache_system(void)
{
/* Just SH7206 for now .. */
current_cpu_data.type = CPU_SH7206;
+ current_cpu_data.flags |= CPU_HAS_OP32;
current_cpu_data.dcache.ways = 4;
current_cpu_data.dcache.way_incr = (1 << 11);
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index ba3082d640b..2b2a9e02fb7 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -1,7 +1,7 @@
/*
* arch/sh/kernel/cpu/sh3/ex.S
*
- * The SH-3 exception vector table.
+ * The SH-3 and SH-4 exception vector table.
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
* Copyright (C) 2003 - 2006 Paul Mundt
@@ -9,7 +9,6 @@
* 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.
- *
*/
#include <linux/linkage.h>
@@ -36,8 +35,12 @@ ENTRY(exception_handling_table)
.long exception_error ! address error load
.long exception_error ! address error store /* 100 */
#endif
- .long exception_error ! fpu_exception /* 120 */
- .long exception_error /* 140 */
+#if defined(CONFIG_SH_FPU)
+ .long do_fpu_error /* 120 */
+#else
+ .long exception_error /* 120 */
+#endif
+ .long exception_error /* 140 */
.long system_call ! Unconditional Trap /* 160 */
.long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
.long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
@@ -55,4 +58,4 @@ ENTRY(user_break_point_trap)
* away offsets can be manually inserted in to their appropriate
* location via set_exception_table_{evt,vec}().
*/
- .balign 4096,0,4096
+ .balign 4096,0,4096
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 19ca68c7188..8add10bd826 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -2,10 +2,10 @@
# Makefile for the Linux/SuperH SH-4 backends.
#
-obj-y := ex.o probe.o common.o
-common-y += $(addprefix ../sh3/, entry.o)
+obj-y := probe.o common.o
+common-y += $(addprefix ../sh3/, entry.o ex.o)
-obj-$(CONFIG_SH_FPU) += fpu.o
+obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
# CPU subtype setup
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
deleted file mode 100644
index ac8ab57413c..00000000000
--- a/arch/sh/kernel/cpu/sh4/ex.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh4/ex.S
- *
- * The SH-4 exception vector table.
-
- * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2003 - 2006 Paul Mundt
- *
- * 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.
- *
- */
-#include <linux/linkage.h>
-
- .align 2
- .data
-
-ENTRY(exception_handling_table)
- .long exception_error /* 000 */
- .long exception_error
-#if defined(CONFIG_MMU)
- .long tlb_miss_load /* 040 */
- .long tlb_miss_store
- .long initial_page_write
- .long tlb_protection_violation_load
- .long tlb_protection_violation_store
- .long address_error_load
- .long address_error_store /* 100 */
-#else
- .long exception_error ! tlb miss load /* 040 */
- .long exception_error ! tlb miss store
- .long exception_error ! initial page write
- .long exception_error ! tlb prot violation load
- .long exception_error ! tlb prot violation store
- .long exception_error ! address error load
- .long exception_error ! address error store /* 100 */
-#endif
-#if defined(CONFIG_SH_FPU)
- .long do_fpu_error /* 120 */
-#else
- .long exception_error /* 120 */
-#endif
- .long exception_error /* 140 */
- .long system_call ! Unconditional Trap /* 160 */
- .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
- .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
-ENTRY(nmi_slot)
-#if defined (CONFIG_KGDB_NMI)
- .long debug_enter /* 1C0 */ ! Allow trap to debugger
-#else
- .long exception_none /* 1C0 */ ! Not implemented yet
-#endif
-ENTRY(user_break_point_trap)
- .long break_point_trap /* 1E0 */
-
- /*
- * Pad the remainder of the table out, exceptions residing in far
- * away offsets can be manually inserted in to their appropriate
- * location via set_exception_table_{evt,vec}().
- */
- .balign 4096,0,4096
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 7624677f662..d61dd599169 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -16,6 +16,7 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <asm/processor.h>
+#include <asm/system.h>
#include <asm/io.h>
/* The PR (precision) bit in the FP Status Register must be clear when
@@ -265,7 +266,7 @@ ieee_fpe_handler (struct pt_regs *regs)
nextpc = regs->pr;
finsn = *(unsigned short *) (regs->pc + 2);
} else {
- nextpc = regs->pc + 2;
+ nextpc = regs->pc + instruction_size(insn);
finsn = insn;
}