aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile_3218
-rw-r--r--arch/sh/kernel/Makefile_645
-rw-r--r--arch/sh/kernel/cf-enabler.c168
-rw-r--r--arch/sh/kernel/cpu/clock.c10
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c85
-rw-r--r--arch/sh/kernel/cpu/sh2a/probe.c7
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c331
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S14
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/softfloat.c73
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c310
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c37
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c19
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c50
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c19
-rw-r--r--arch/sh/kernel/debugtraps.S13
-rw-r--r--arch/sh/kernel/disassemble.c573
-rw-r--r--arch/sh/kernel/entry-common.S54
-rw-r--r--arch/sh/kernel/ftrace.c133
-rw-r--r--arch/sh/kernel/head_32.S12
-rw-r--r--arch/sh/kernel/idle.c81
-rw-r--r--arch/sh/kernel/kgdb.c285
-rw-r--r--arch/sh/kernel/kgdb_jmp.S33
-rw-r--r--arch/sh/kernel/kgdb_stub.c1052
-rw-r--r--arch/sh/kernel/pm.c88
-rw-r--r--arch/sh/kernel/process_32.c81
-rw-r--r--arch/sh/kernel/process_64.c111
-rw-r--r--arch/sh/kernel/ptrace_64.c186
-rw-r--r--arch/sh/kernel/setup.c1
-rw-r--r--arch/sh/kernel/sh_bios.c65
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c37
-rw-r--r--arch/sh/kernel/sh_ksyms_64.c5
-rw-r--r--arch/sh/kernel/signal_32.c1
-rw-r--r--arch/sh/kernel/signal_64.c154
-rw-r--r--arch/sh/kernel/sys_sh.c92
-rw-r--r--arch/sh/kernel/time_32.c12
-rw-r--r--arch/sh/kernel/time_64.c5
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c5
-rw-r--r--arch/sh/kernel/traps_32.c36
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.c3
42 files changed, 2203 insertions, 2068 deletions
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 48edfb145fb4..2e1b86e16ab5 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -4,25 +4,31 @@
4 4
5extra-y := head_32.o init_task.o vmlinux.lds 5extra-y := head_32.o init_task.o vmlinux.lds
6 6
7obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ 7ifdef CONFIG_FUNCTION_TRACER
8 ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \ 8# Do not profile debug and lowlevel utilities
9 syscalls_32.o time_32.o topology.o traps.o traps_32.o 9CFLAGS_REMOVE_ftrace.o = -pg
10endif
11
12obj-y := debugtraps.o idle.o io.o io_generic.o irq.o \
13 machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
14 sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o \
15 traps.o traps_32.o
10 16
11obj-y += cpu/ timers/ 17obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/ 18obj-$(CONFIG_VSYSCALL) += vsyscall/
13obj-$(CONFIG_SMP) += smp.o 19obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
15obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o 20obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
16obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o 21obj-$(CONFIG_KGDB) += kgdb.o
17obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 22obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o 23obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 24obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 25obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
21obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 26obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
22obj-$(CONFIG_PM) += pm.o
23obj-$(CONFIG_STACKTRACE) += stacktrace.o 27obj-$(CONFIG_STACKTRACE) += stacktrace.o
24obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 28obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
25obj-$(CONFIG_KPROBES) += kprobes.o 29obj-$(CONFIG_KPROBES) += kprobes.o
26obj-$(CONFIG_GENERIC_GPIO) += gpio.o 30obj-$(CONFIG_GENERIC_GPIO) += gpio.o
31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
32obj-$(CONFIG_DUMP_CODE) += disassemble.o
27 33
28EXTRA_CFLAGS += -Werror 34EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index c97660b2b48d..fe425d7f6871 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -1,21 +1,18 @@
1extra-y := head_64.o init_task.o vmlinux.lds 1extra-y := head_64.o init_task.o vmlinux.lds
2 2
3obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ 3obj-y := debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
4 ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \ 4 ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
5 syscalls_64.o time_64.o topology.o traps.o traps_64.o 5 syscalls_64.o time_64.o topology.o traps.o traps_64.o
6 6
7obj-y += cpu/ timers/ 7obj-y += cpu/ timers/
8obj-$(CONFIG_VSYSCALL) += vsyscall/ 8obj-$(CONFIG_VSYSCALL) += vsyscall/
9obj-$(CONFIG_SMP) += smp.o 9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
11obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o 10obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
12obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
13obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 11obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
14obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o 12obj-$(CONFIG_MODULES) += sh_ksyms_64.o module.o
15obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
16obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 14obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
17obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 15obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
18obj-$(CONFIG_PM) += pm.o
19obj-$(CONFIG_STACKTRACE) += stacktrace.o 16obj-$(CONFIG_STACKTRACE) += stacktrace.o
20obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 17obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
21obj-$(CONFIG_GENERIC_GPIO) += gpio.o 18obj-$(CONFIG_GENERIC_GPIO) += gpio.o
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
deleted file mode 100644
index bea40339919b..000000000000
--- a/arch/sh/kernel/cf-enabler.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/* $Id: cf-enabler.c,v 1.4 2004/02/22 22:44:36 kkojima Exp $
2 *
3 * linux/drivers/block/cf-enabler.c
4 *
5 * Copyright (C) 1999 Niibe Yutaka
6 * Copyright (C) 2000 Toshiharu Nozawa
7 * Copyright (C) 2001 A&D Co., Ltd.
8 *
9 * Enable the CF configuration.
10 */
11
12#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/vmalloc.h>
15#include <linux/interrupt.h>
16#include <asm/io.h>
17#include <asm/irq.h>
18
19/*
20 * You can connect Compact Flash directly to the bus of SuperH.
21 * This is the enabler for that.
22 *
23 * SIM: How generic is this really? It looks pretty board, or at
24 * least SH sub-type, specific to me.
25 * I know it doesn't work on the Overdrive!
26 */
27
28/*
29 * 0xB8000000 : Attribute
30 * 0xB8001000 : Common Memory
31 * 0xBA000000 : I/O
32 */
33#if defined(CONFIG_CPU_SH4)
34/* SH4 can't access PCMCIA interface through P2 area.
35 * we must remap it with appropriate attribute bit of the page set.
36 * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
37
38#if defined(CONFIG_CF_AREA6)
39#define slot_no 0
40#else
41#define slot_no 1
42#endif
43
44/* use this pointer to access to directly connected compact flash io area*/
45void *cf_io_base;
46
47static int __init allocate_cf_area(void)
48{
49 pgprot_t prot;
50 unsigned long paddrbase, psize;
51
52 /* open I/O area window */
53 paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
54 psize = PAGE_SIZE;
55 prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
56 cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
57 if (!cf_io_base) {
58 printk("allocate_cf_area : can't open CF I/O window!\n");
59 return -ENOMEM;
60 }
61/* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
62 paddrbase, psize, prot.pgprot, cf_io_base);*/
63
64 /* XXX : do we need attribute and common-memory area also? */
65
66 return 0;
67}
68#endif
69
70static int __init cf_init_default(void)
71{
72/* You must have enabled the card, and set the level interrupt
73 * before reaching this point. Possibly in boot ROM or boot loader.
74 */
75#if defined(CONFIG_CPU_SH4)
76 allocate_cf_area();
77#endif
78
79 return 0;
80}
81
82#if defined(CONFIG_SH_SOLUTION_ENGINE)
83#include <mach-se/mach/se.h>
84#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
85#include <mach-se/mach/se7722.h>
86#elif defined(CONFIG_SH_7721_SOLUTION_ENGINE)
87#include <mach-se/mach/se7721.h>
88#endif
89
90/*
91 * SolutionEngine Seriese
92 *
93 * about MS770xSE
94 * 0xB8400000 : Common Memory
95 * 0xB8500000 : Attribute
96 * 0xB8600000 : I/O
97 *
98 * about MS7722SE
99 * 0xB0400000 : Common Memory
100 * 0xB0500000 : Attribute
101 * 0xB0600000 : I/O
102 */
103
104#if defined(CONFIG_SH_SOLUTION_ENGINE) || \
105 defined(CONFIG_SH_7722_SOLUTION_ENGINE) || \
106 defined(CONFIG_SH_7721_SOLUTION_ENGINE)
107static int __init cf_init_se(void)
108{
109 if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
110 return 0; /* Not detected */
111
112 if ((ctrl_inw(MRSHPC_CSR) & 0x0080) == 0) {
113 ctrl_outw(0x0674, MRSHPC_CPWCR); /* Card Vcc is 3.3v? */
114 } else {
115 ctrl_outw(0x0678, MRSHPC_CPWCR); /* Card Vcc is 5V */
116 }
117
118 /*
119 * PC-Card window open
120 * flag == COMMON/ATTRIBUTE/IO
121 */
122 /* common window open */
123 ctrl_outw(0x8a84, MRSHPC_MW0CR1);
124 if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
125 /* common mode & bus width 16bit SWAP = 1*/
126 ctrl_outw(0x0b00, MRSHPC_MW0CR2);
127 else
128 /* common mode & bus width 16bit SWAP = 0*/
129 ctrl_outw(0x0300, MRSHPC_MW0CR2);
130
131 /* attribute window open */
132 ctrl_outw(0x8a85, MRSHPC_MW1CR1);
133 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
134 /* attribute mode & bus width 16bit SWAP = 1*/
135 ctrl_outw(0x0a00, MRSHPC_MW1CR2);
136 else
137 /* attribute mode & bus width 16bit SWAP = 0*/
138 ctrl_outw(0x0200, MRSHPC_MW1CR2);
139
140 /* I/O window open */
141 ctrl_outw(0x8a86, MRSHPC_IOWCR1);
142 ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
143 if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
144 ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
145 else
146 ctrl_outw(0x0200, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 0*/
147
148 ctrl_outw(0x2000, MRSHPC_ICR);
149 ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
150 ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
151 return 0;
152}
153#else
154static int __init cf_init_se(void)
155{
156 return -1;
157}
158#endif
159
160static int __init cf_init(void)
161{
162 if (mach_is_se() || mach_is_7722se() || mach_is_7721se())
163 return cf_init_se();
164
165 return cf_init_default();
166}
167
168__initcall (cf_init);
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index b7e46d5bba43..7b17137536d6 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -117,6 +117,11 @@ int clk_enable(struct clk *clk)
117 unsigned long flags; 117 unsigned long flags;
118 int ret; 118 int ret;
119 119
120 if (!clk)
121 return -EINVAL;
122
123 clk_enable(clk->parent);
124
120 spin_lock_irqsave(&clock_lock, flags); 125 spin_lock_irqsave(&clock_lock, flags);
121 ret = __clk_enable(clk); 126 ret = __clk_enable(clk);
122 spin_unlock_irqrestore(&clock_lock, flags); 127 spin_unlock_irqrestore(&clock_lock, flags);
@@ -147,9 +152,14 @@ void clk_disable(struct clk *clk)
147{ 152{
148 unsigned long flags; 153 unsigned long flags;
149 154
155 if (!clk)
156 return;
157
150 spin_lock_irqsave(&clock_lock, flags); 158 spin_lock_irqsave(&clock_lock, flags);
151 __clk_disable(clk); 159 __clk_disable(clk);
152 spin_unlock_irqrestore(&clock_lock, flags); 160 spin_unlock_irqrestore(&clock_lock, flags);
161
162 clk_disable(clk->parent);
153} 163}
154EXPORT_SYMBOL_GPL(clk_disable); 164EXPORT_SYMBOL_GPL(clk_disable);
155 165
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 75fb03d35670..d29e69c156f0 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -261,9 +261,11 @@ asmlinkage void __init sh_cpu_init(void)
261 cache_init(); 261 cache_init();
262 262
263 if (raw_smp_processor_id() == 0) { 263 if (raw_smp_processor_id() == 0) {
264#ifdef CONFIG_MMU
264 shm_align_mask = max_t(unsigned long, 265 shm_align_mask = max_t(unsigned long,
265 current_cpu_data.dcache.way_size - 1, 266 current_cpu_data.dcache.way_size - 1,
266 PAGE_SIZE - 1); 267 PAGE_SIZE - 1);
268#endif
267 269
268 /* Boot CPU sets the cache shape */ 270 /* Boot CPU sets the cache shape */
269 detect_cache_shape(); 271 detect_cache_shape();
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 428450cc0809..45f85c77ef75 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -8,9 +8,10 @@ common-y += ex.o entry.o
8 8
9obj-$(CONFIG_SH_FPU) += fpu.o 9obj-$(CONFIG_SH_FPU) += fpu.o
10 10
11obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o 11obj-$(CONFIG_CPU_SUBTYPE_SH7201) += setup-sh7201.o clock-sh7201.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o 12obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o 13obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
14obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o 15obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o
15 16
16# Pinmux setup 17# Pinmux setup
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
new file mode 100644
index 000000000000..020a96fe961a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -0,0 +1,85 @@
1/*
2 * arch/sh/kernel/cpu/sh2a/clock-sh7201.c
3 *
4 * SH7201 support for the clock framework
5 *
6 * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk>
7 *
8 * Based on clock-sh4.c
9 * Copyright (C) 2005 Paul Mundt
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <asm/clock.h>
18#include <asm/freq.h>
19#include <asm/io.h>
20
21const static int pll1rate[]={1,2,3,4,6,8};
22const static int pfc_divisors[]={1,2,3,4,6,8,12};
23#define ifc_divisors pfc_divisors
24
25#if (CONFIG_SH_CLK_MD == 0)
26#define PLL2 (4)
27#elif (CONFIG_SH_CLK_MD == 2)
28#define PLL2 (2)
29#elif (CONFIG_SH_CLK_MD == 3)
30#define PLL2 (1)
31#else
32#error "Illegal Clock Mode!"
33#endif
34
35static void master_clk_init(struct clk *clk)
36{
37 clk->rate = 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
38}
39
40static struct clk_ops sh7201_master_clk_ops = {
41 .init = master_clk_init,
42};
43
44static void module_clk_recalc(struct clk *clk)
45{
46 int idx = (ctrl_inw(FREQCR) & 0x0007);
47 clk->rate = clk->parent->rate / pfc_divisors[idx];
48}
49
50static struct clk_ops sh7201_module_clk_ops = {
51 .recalc = module_clk_recalc,
52};
53
54static void bus_clk_recalc(struct clk *clk)
55{
56 int idx = (ctrl_inw(FREQCR) & 0x0007);
57 clk->rate = clk->parent->rate / pfc_divisors[idx];
58}
59
60static struct clk_ops sh7201_bus_clk_ops = {
61 .recalc = bus_clk_recalc,
62};
63
64static void cpu_clk_recalc(struct clk *clk)
65{
66 int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007);
67 clk->rate = clk->parent->rate / ifc_divisors[idx];
68}
69
70static struct clk_ops sh7201_cpu_clk_ops = {
71 .recalc = cpu_clk_recalc,
72};
73
74static struct clk_ops *sh7201_clk_ops[] = {
75 &sh7201_master_clk_ops,
76 &sh7201_module_clk_ops,
77 &sh7201_bus_clk_ops,
78 &sh7201_cpu_clk_ops,
79};
80
81void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
82{
83 if (idx < ARRAY_SIZE(sh7201_clk_ops))
84 *ops = sh7201_clk_ops[idx];
85}
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index 6e79132f6f30..e098e2f6aa08 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -18,16 +18,17 @@ int __init detect_cpu_and_cache_system(void)
18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */ 18 /* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
19 boot_cpu_data.flags |= CPU_HAS_OP32; 19 boot_cpu_data.flags |= CPU_HAS_OP32;
20 20
21#if defined(CONFIG_CPU_SUBTYPE_SH7203) 21#if defined(CONFIG_CPU_SUBTYPE_SH7201)
22 boot_cpu_data.type = CPU_SH7201;
23 boot_cpu_data.flags |= CPU_HAS_FPU;
24#elif defined(CONFIG_CPU_SUBTYPE_SH7203)
22 boot_cpu_data.type = CPU_SH7203; 25 boot_cpu_data.type = CPU_SH7203;
23 /* SH7203 has an FPU.. */
24 boot_cpu_data.flags |= CPU_HAS_FPU; 26 boot_cpu_data.flags |= CPU_HAS_FPU;
25#elif defined(CONFIG_CPU_SUBTYPE_SH7263) 27#elif defined(CONFIG_CPU_SUBTYPE_SH7263)
26 boot_cpu_data.type = CPU_SH7263; 28 boot_cpu_data.type = CPU_SH7263;
27 boot_cpu_data.flags |= CPU_HAS_FPU; 29 boot_cpu_data.flags |= CPU_HAS_FPU;
28#elif defined(CONFIG_CPU_SUBTYPE_SH7206) 30#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
29 boot_cpu_data.type = CPU_SH7206; 31 boot_cpu_data.type = CPU_SH7206;
30 /* While SH7206 has a DSP.. */
31 boot_cpu_data.flags |= CPU_HAS_DSP; 32 boot_cpu_data.flags |= CPU_HAS_DSP;
32#elif defined(CONFIG_CPU_SUBTYPE_MXG) 33#elif defined(CONFIG_CPU_SUBTYPE_MXG)
33 boot_cpu_data.type = CPU_MXG; 34 boot_cpu_data.type = CPU_MXG;
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
new file mode 100644
index 000000000000..0631e421c022
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -0,0 +1,331 @@
1/*
2 * SH7201 setup
3 *
4 * Copyright (C) 2008 Peter Griffin pgriffin@mpc-data.co.uk
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <linux/serial_sci.h>
14
15enum {
16 UNUSED = 0,
17
18 /* interrupt sources */
19 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
20 PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
21 ADC_ADI,
22 MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
23 MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
24 MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
25 MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
26 MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
27 MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
28 MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
29 RTC_ARM, RTC_PRD, RTC_CUP,
30 WDT,
31 IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
32 IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
33 IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
34
35 DMAC0_DMINT0, DMAC1_DMINT1,
36 DMAC2_DMINT2, DMAC3_DMINT3,
37
38 SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
39 SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
40 SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
41 SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
42 SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI,
43 SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI,
44 SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI,
45 SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI,
46
47 DMAC0_DMINTA, DMAC4_DMINT4, DMAC5_DMINT5, DMAC6_DMINT6,
48 DMAC7_DMINT7,
49
50 RCAN0_ERS, RCAN0_OVR,
51 RCAN0_SLE,
52 RCAN0_RM0, RCAN0_RM1,
53
54 RCAN1_ERS, RCAN1_OVR,
55 RCAN1_SLE,
56 RCAN1_RM0, RCAN1_RM1,
57
58 SSI0_SSII, SSI1_SSII,
59
60 TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0,
61 TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1,
62
63 /* interrupt groups */
64
65 IRQ, PINT, ADC,
66 MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
67 MTU23_ABCD, MTU24_ABCD, MTU25_UVW,
68 RTC, IIC30, IIC31, IIC32,
69 SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
70 RCAN0, RCAN1, TMR0, TMR1
71
72};
73
74static struct intc_vect vectors[] __initdata = {
75 INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
76 INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
77 INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
78 INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
79 INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
80 INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
81 INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
82 INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
83
84 INTC_IRQ(ADC_ADI, 92),
85
86 INTC_IRQ(MTU2_TGI0A, 108), INTC_IRQ(MTU2_TGI0B, 109),
87 INTC_IRQ(MTU2_TGI0C, 110), INTC_IRQ(MTU2_TGI0D, 111),
88 INTC_IRQ(MTU2_TCI0V, 112),
89 INTC_IRQ(MTU2_TGI0E, 113), INTC_IRQ(MTU2_TGI0F, 114),
90
91 INTC_IRQ(MTU2_TGI1A, 116), INTC_IRQ(MTU2_TGI1B, 117),
92 INTC_IRQ(MTU2_TCI1V, 120), INTC_IRQ(MTU2_TCI1U, 121),
93
94 INTC_IRQ(MTU2_TGI2A, 124), INTC_IRQ(MTU2_TGI2B, 125),
95 INTC_IRQ(MTU2_TCI2V, 128), INTC_IRQ(MTU2_TCI2U, 129),
96
97 INTC_IRQ(MTU2_TGI3A, 132), INTC_IRQ(MTU2_TGI3B, 133),
98 INTC_IRQ(MTU2_TGI3C, 134), INTC_IRQ(MTU2_TGI3D, 135),
99 INTC_IRQ(MTU2_TCI3V, 136),
100
101 INTC_IRQ(MTU2_TGI4A, 140), INTC_IRQ(MTU2_TGI4B, 141),
102 INTC_IRQ(MTU2_TGI4C, 142), INTC_IRQ(MTU2_TGI4D, 143),
103 INTC_IRQ(MTU2_TCI4V, 144),
104
105 INTC_IRQ(MTU2_TGI5U, 148), INTC_IRQ(MTU2_TGI5V, 149),
106 INTC_IRQ(MTU2_TGI5W, 150),
107
108 INTC_IRQ(RTC_ARM, 152), INTC_IRQ(RTC_PRD, 153),
109 INTC_IRQ(RTC_CUP, 154), INTC_IRQ(WDT, 156),
110
111 INTC_IRQ(IIC30_STPI, 157), INTC_IRQ(IIC30_NAKI, 158),
112 INTC_IRQ(IIC30_RXI, 159), INTC_IRQ(IIC30_TXI, 160),
113 INTC_IRQ(IIC30_TEI, 161),
114
115 INTC_IRQ(IIC31_STPI, 164), INTC_IRQ(IIC31_NAKI, 165),
116 INTC_IRQ(IIC31_RXI, 166), INTC_IRQ(IIC31_TXI, 167),
117 INTC_IRQ(IIC31_TEI, 168),
118
119 INTC_IRQ(IIC32_STPI, 170), INTC_IRQ(IIC32_NAKI, 171),
120 INTC_IRQ(IIC32_RXI, 172), INTC_IRQ(IIC32_TXI, 173),
121 INTC_IRQ(IIC32_TEI, 174),
122
123 INTC_IRQ(DMAC0_DMINT0, 176), INTC_IRQ(DMAC1_DMINT1, 177),
124 INTC_IRQ(DMAC2_DMINT2, 178), INTC_IRQ(DMAC3_DMINT3, 179),
125
126 INTC_IRQ(SCIF0_BRI, 180), INTC_IRQ(SCIF0_ERI, 181),
127 INTC_IRQ(SCIF0_RXI, 182), INTC_IRQ(SCIF0_TXI, 183),
128 INTC_IRQ(SCIF1_BRI, 184), INTC_IRQ(SCIF1_ERI, 185),
129 INTC_IRQ(SCIF1_RXI, 186), INTC_IRQ(SCIF1_TXI, 187),
130 INTC_IRQ(SCIF2_BRI, 188), INTC_IRQ(SCIF2_ERI, 189),
131 INTC_IRQ(SCIF2_RXI, 190), INTC_IRQ(SCIF2_TXI, 191),
132 INTC_IRQ(SCIF3_BRI, 192), INTC_IRQ(SCIF3_ERI, 193),
133 INTC_IRQ(SCIF3_RXI, 194), INTC_IRQ(SCIF3_TXI, 195),
134 INTC_IRQ(SCIF4_BRI, 196), INTC_IRQ(SCIF4_ERI, 197),
135 INTC_IRQ(SCIF4_RXI, 198), INTC_IRQ(SCIF4_TXI, 199),
136 INTC_IRQ(SCIF5_BRI, 200), INTC_IRQ(SCIF5_ERI, 201),
137 INTC_IRQ(SCIF5_RXI, 202), INTC_IRQ(SCIF5_TXI, 203),
138 INTC_IRQ(SCIF6_BRI, 204), INTC_IRQ(SCIF6_ERI, 205),
139 INTC_IRQ(SCIF6_RXI, 206), INTC_IRQ(SCIF6_TXI, 207),
140 INTC_IRQ(SCIF7_BRI, 208), INTC_IRQ(SCIF7_ERI, 209),
141 INTC_IRQ(SCIF7_RXI, 210), INTC_IRQ(SCIF7_TXI, 211),
142
143 INTC_IRQ(DMAC0_DMINTA, 212), INTC_IRQ(DMAC4_DMINT4, 216),
144 INTC_IRQ(DMAC5_DMINT5, 217), INTC_IRQ(DMAC6_DMINT6, 218),
145 INTC_IRQ(DMAC7_DMINT7, 219),
146
147 INTC_IRQ(RCAN0_ERS, 228), INTC_IRQ(RCAN0_OVR, 229),
148 INTC_IRQ(RCAN0_SLE, 230),
149 INTC_IRQ(RCAN0_RM0, 231), INTC_IRQ(RCAN0_RM1, 232),
150
151 INTC_IRQ(RCAN1_ERS, 234), INTC_IRQ(RCAN1_OVR, 235),
152 INTC_IRQ(RCAN1_SLE, 236),
153 INTC_IRQ(RCAN1_RM0, 237), INTC_IRQ(RCAN1_RM1, 238),
154
155 INTC_IRQ(SSI0_SSII, 244), INTC_IRQ(SSI1_SSII, 245),
156
157 INTC_IRQ(TMR0_CMIA0, 246), INTC_IRQ(TMR0_CMIB0, 247),
158 INTC_IRQ(TMR0_OVI0, 248),
159
160 INTC_IRQ(TMR1_CMIA1, 252), INTC_IRQ(TMR1_CMIB1, 253),
161 INTC_IRQ(TMR1_OVI1, 254),
162
163};
164
165static struct intc_group groups[] __initdata = {
166 INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
167 PINT4, PINT5, PINT6, PINT7),
168 INTC_GROUP(MTU20_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
169 INTC_GROUP(MTU20_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
170
171 INTC_GROUP(MTU21_AB, MTU2_TGI1A, MTU2_TGI1B),
172 INTC_GROUP(MTU21_VU, MTU2_TCI1V, MTU2_TCI1U),
173 INTC_GROUP(MTU22_AB, MTU2_TGI2A, MTU2_TGI2B),
174 INTC_GROUP(MTU22_VU, MTU2_TCI2V, MTU2_TCI2U),
175 INTC_GROUP(MTU23_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
176 INTC_GROUP(MTU24_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
177 INTC_GROUP(MTU25_UVW, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
178 INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP ),
179
180 INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
181 IIC30_TEI),
182 INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
183 IIC31_TEI),
184 INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
185 IIC32_TEI),
186
187 INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
188 INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
189 INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
190 INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
191 INTC_GROUP(SCIF4, SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI),
192 INTC_GROUP(SCIF5, SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI),
193 INTC_GROUP(SCIF6, SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI),
194 INTC_GROUP(SCIF7, SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI),
195
196 INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
197 RCAN0_SLE),
198 INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
199 RCAN1_SLE),
200
201 INTC_GROUP(TMR0, TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0),
202 INTC_GROUP(TMR1, TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1),
203};
204
205static struct intc_prio_reg prio_registers[] __initdata = {
206 { 0xfffe9418, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
207 { 0xfffe941a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
208 { 0xfffe9420, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI, 0 } },
209 { 0xfffe9800, 0, 16, 4, /* IPR06 */ { 0, MTU20_ABCD, MTU20_VEF, MTU21_AB } },
210 { 0xfffe9802, 0, 16, 4, /* IPR07 */ { MTU21_VU, MTU22_AB, MTU22_VU, MTU23_ABCD } },
211 { 0xfffe9804, 0, 16, 4, /* IPR08 */ { MTU2_TCI3V, MTU24_ABCD, MTU2_TCI4V, MTU25_UVW } },
212
213 { 0xfffe9806, 0, 16, 4, /* IPR09 */ { RTC, WDT, IIC30, 0 } },
214 { 0xfffe9808, 0, 16, 4, /* IPR10 */ { IIC31, IIC32, DMAC0_DMINT0, DMAC1_DMINT1 } },
215 { 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0 , SCIF1 } },
216 { 0xfffe980c, 0, 16, 4, /* IPR12 */ { SCIF2, SCIF3, SCIF4, SCIF5 } },
217 { 0xfffe980e, 0, 16, 4, /* IPR13 */ { SCIF6, SCIF7, DMAC0_DMINTA, DMAC4_DMINT4 } },
218 { 0xfffe9810, 0, 16, 4, /* IPR14 */ { DMAC5_DMINT5, DMAC6_DMINT6, DMAC7_DMINT7, 0 } },
219 { 0xfffe9812, 0, 16, 4, /* IPR15 */ { 0, RCAN0, RCAN1, 0 } },
220 { 0xfffe9814, 0, 16, 4, /* IPR16 */ { SSI0_SSII, SSI1_SSII, TMR0, TMR1 } },
221};
222
223static struct intc_mask_reg mask_registers[] __initdata = {
224 { 0xfffe9408, 0, 16, /* PINTER */
225 { 0, 0, 0, 0, 0, 0, 0, 0,
226 PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
227};
228
229static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups,
230 mask_registers, prio_registers, NULL);
231
232static struct plat_sci_port sci_platform_data[] = {
233 {
234 .mapbase = 0xfffe8000,
235 .flags = UPF_BOOT_AUTOCONF,
236 .type = PORT_SCIF,
237 .irqs = { 181, 182, 183, 180}
238 }, {
239 .mapbase = 0xfffe8800,
240 .flags = UPF_BOOT_AUTOCONF,
241 .type = PORT_SCIF,
242 .irqs = { 185, 186, 187, 184}
243 }, {
244 .mapbase = 0xfffe9000,
245 .flags = UPF_BOOT_AUTOCONF,
246 .type = PORT_SCIF,
247 .irqs = { 189, 186, 187, 188}
248 }, {
249 .mapbase = 0xfffe9800,
250 .flags = UPF_BOOT_AUTOCONF,
251 .type = PORT_SCIF,
252 .irqs = { 193, 194, 195, 192}
253 }, {
254 .mapbase = 0xfffea000,
255 .flags = UPF_BOOT_AUTOCONF,
256 .type = PORT_SCIF,
257 .irqs = { 196, 198, 199, 196}
258 }, {
259 .mapbase = 0xfffea800,
260 .flags = UPF_BOOT_AUTOCONF,
261 .type = PORT_SCIF,
262 .irqs = { 201, 202, 203, 200}
263 }, {
264 .mapbase = 0xfffeb000,
265 .flags = UPF_BOOT_AUTOCONF,
266 .type = PORT_SCIF,
267 .irqs = { 205, 206, 207, 204}
268 }, {
269 .mapbase = 0xfffeb800,
270 .flags = UPF_BOOT_AUTOCONF,
271 .type = PORT_SCIF,
272 .irqs = { 209, 210, 211, 208}
273 }, {
274 .flags = 0,
275 }
276};
277
278static struct platform_device sci_device = {
279 .name = "sh-sci",
280 .id = -1,
281 .dev = {
282 .platform_data = sci_platform_data,
283 },
284};
285
286static struct resource rtc_resources[] = {
287 [0] = {
288 .start = 0xffff0800,
289 .end = 0xffff2000 + 0x58 - 1,
290 .flags = IORESOURCE_IO,
291 },
292 [1] = {
293 /* Period IRQ */
294 .start = 153,
295 .flags = IORESOURCE_IRQ,
296 },
297 [2] = {
298 /* Carry IRQ */
299 .start = 154,
300 .flags = IORESOURCE_IRQ,
301 },
302 [3] = {
303 /* Alarm IRQ */
304 .start = 152,
305 .flags = IORESOURCE_IRQ,
306 },
307};
308
309static struct platform_device rtc_device = {
310 .name = "sh-rtc",
311 .id = -1,
312 .num_resources = ARRAY_SIZE(rtc_resources),
313 .resource = rtc_resources,
314};
315
316static struct platform_device *sh7201_devices[] __initdata = {
317 &sci_device,
318 &rtc_device,
319};
320
321static int __init sh7201_devices_setup(void)
322{
323 return platform_add_devices(sh7201_devices,
324 ARRAY_SIZE(sh7201_devices));
325}
326__initcall(sh7201_devices_setup);
327
328void __init plat_irq_setup(void)
329{
330 register_intc_controller(&intc_desc);
331}
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 3fe482dd05c1..b4106d0c68ec 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -52,7 +52,7 @@
52 * syscall # 52 * syscall #
53 * 53 *
54 */ 54 */
55#if defined(CONFIG_KGDB_NMI) 55#if defined(CONFIG_KGDB)
56NMI_VEC = 0x1c0 ! Must catch early for debounce 56NMI_VEC = 0x1c0 ! Must catch early for debounce
57#endif 57#endif
58 58
@@ -307,7 +307,7 @@ skip_restore:
3076: or k0, k2 ! Set the IMASK-bits 3076: or k0, k2 ! Set the IMASK-bits
308 ldc k2, ssr 308 ldc k2, ssr
309 ! 309 !
310#if defined(CONFIG_KGDB_NMI) 310#if defined(CONFIG_KGDB)
311 ! Clear in_nmi 311 ! Clear in_nmi
312 mov.l 6f, k0 312 mov.l 6f, k0
313 mov #0, k1 313 mov #0, k1
@@ -320,7 +320,7 @@ skip_restore:
320 320
321 .align 2 321 .align 2
3225: .long 0x00001000 ! DSP 3225: .long 0x00001000 ! DSP
323#ifdef CONFIG_KGDB_NMI 323#ifdef CONFIG_KGDB
3246: .long in_nmi 3246: .long in_nmi
325#endif 325#endif
3267: .long 0x30000000 3267: .long 0x30000000
@@ -376,9 +376,9 @@ tlb_miss:
376! 376!
377 .balign 512,0,512 377 .balign 512,0,512
378interrupt: 378interrupt:
379 mov.l 2f, k2
380 mov.l 3f, k3 379 mov.l 3f, k3
381#if defined(CONFIG_KGDB_NMI) 380#if defined(CONFIG_KGDB)
381 mov.l 2f, k2
382 ! Debounce (filter nested NMI) 382 ! Debounce (filter nested NMI)
383 mov.l @k2, k0 383 mov.l @k2, k0
384 mov.l 5f, k1 384 mov.l 5f, k1
@@ -390,16 +390,16 @@ interrupt:
390 rte 390 rte
391 nop 391 nop
392 .align 2 392 .align 2
3932: .long INTEVT
3935: .long NMI_VEC 3945: .long NMI_VEC
3946: .long in_nmi 3956: .long in_nmi
3950: 3960:
396#endif /* defined(CONFIG_KGDB_NMI) */ 397#endif /* defined(CONFIG_KGDB) */
397 bra handle_exception 398 bra handle_exception
398 mov #-1, k2 ! interrupt exception marker 399 mov #-1, k2 ! interrupt exception marker
399 400
400 .align 2 401 .align 2
4011: .long EXPEVT 4021: .long EXPEVT
4022: .long INTEVT
4033: .long ret_from_irq 4033: .long ret_from_irq
4044: .long ret_from_exception 4044: .long ret_from_exception
405 405
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index dac429726899..e5a0de39a2db 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -26,7 +26,7 @@
26#define fpu_error_trap_handler exception_error 26#define fpu_error_trap_handler exception_error
27#endif 27#endif
28 28
29#if !defined(CONFIG_KGDB_NMI) 29#if !defined(CONFIG_KGDB)
30#define kgdb_handle_exception exception_error 30#define kgdb_handle_exception exception_error
31#endif 31#endif
32 32
diff --git a/arch/sh/kernel/cpu/sh4/softfloat.c b/arch/sh/kernel/cpu/sh4/softfloat.c
index 2b747f3b02bd..42edf2e54e85 100644
--- a/arch/sh/kernel/cpu/sh4/softfloat.c
+++ b/arch/sh/kernel/cpu/sh4/softfloat.c
@@ -37,6 +37,7 @@
37 */ 37 */
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <cpu/fpu.h> 39#include <cpu/fpu.h>
40#include <asm/div64.h>
40 41
41#define LIT64( a ) a##LL 42#define LIT64( a ) a##LL
42 43
@@ -67,16 +68,16 @@ typedef unsigned long long float64;
67extern void float_raise(unsigned int flags); /* in fpu.c */ 68extern void float_raise(unsigned int flags); /* in fpu.c */
68extern int float_rounding_mode(void); /* in fpu.c */ 69extern int float_rounding_mode(void); /* in fpu.c */
69 70
70inline bits64 extractFloat64Frac(float64 a); 71bits64 extractFloat64Frac(float64 a);
71inline flag extractFloat64Sign(float64 a); 72flag extractFloat64Sign(float64 a);
72inline int16 extractFloat64Exp(float64 a); 73int16 extractFloat64Exp(float64 a);
73inline int16 extractFloat32Exp(float32 a); 74int16 extractFloat32Exp(float32 a);
74inline flag extractFloat32Sign(float32 a); 75flag extractFloat32Sign(float32 a);
75inline bits32 extractFloat32Frac(float32 a); 76bits32 extractFloat32Frac(float32 a);
76inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig); 77float64 packFloat64(flag zSign, int16 zExp, bits64 zSig);
77inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr); 78void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr);
78inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig); 79float32 packFloat32(flag zSign, int16 zExp, bits32 zSig);
79inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr); 80void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr);
80float64 float64_sub(float64 a, float64 b); 81float64 float64_sub(float64 a, float64 b);
81float32 float32_sub(float32 a, float32 b); 82float32 float32_sub(float32 a, float32 b);
82float32 float32_add(float32 a, float32 b); 83float32 float32_add(float32 a, float32 b);
@@ -86,11 +87,11 @@ float32 float32_div(float32 a, float32 b);
86float32 float32_mul(float32 a, float32 b); 87float32 float32_mul(float32 a, float32 b);
87float64 float64_mul(float64 a, float64 b); 88float64 float64_mul(float64 a, float64 b);
88float32 float64_to_float32(float64 a); 89float32 float64_to_float32(float64 a);
89inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 90void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
90 bits64 * z1Ptr); 91 bits64 * z1Ptr);
91inline void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 92void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
92 bits64 * z1Ptr); 93 bits64 * z1Ptr);
93inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr); 94void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr);
94 95
95static int8 countLeadingZeros32(bits32 a); 96static int8 countLeadingZeros32(bits32 a);
96static int8 countLeadingZeros64(bits64 a); 97static int8 countLeadingZeros64(bits64 a);
@@ -110,42 +111,42 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b);
110static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr, 111static void normalizeFloat32Subnormal(bits32 aSig, int16 * zExpPtr,
111 bits32 * zSigPtr); 112 bits32 * zSigPtr);
112 113
113inline bits64 extractFloat64Frac(float64 a) 114bits64 extractFloat64Frac(float64 a)
114{ 115{
115 return a & LIT64(0x000FFFFFFFFFFFFF); 116 return a & LIT64(0x000FFFFFFFFFFFFF);
116} 117}
117 118
118inline flag extractFloat64Sign(float64 a) 119flag extractFloat64Sign(float64 a)
119{ 120{
120 return a >> 63; 121 return a >> 63;
121} 122}
122 123
123inline int16 extractFloat64Exp(float64 a) 124int16 extractFloat64Exp(float64 a)
124{ 125{
125 return (a >> 52) & 0x7FF; 126 return (a >> 52) & 0x7FF;
126} 127}
127 128
128inline int16 extractFloat32Exp(float32 a) 129int16 extractFloat32Exp(float32 a)
129{ 130{
130 return (a >> 23) & 0xFF; 131 return (a >> 23) & 0xFF;
131} 132}
132 133
133inline flag extractFloat32Sign(float32 a) 134flag extractFloat32Sign(float32 a)
134{ 135{
135 return a >> 31; 136 return a >> 31;
136} 137}
137 138
138inline bits32 extractFloat32Frac(float32 a) 139bits32 extractFloat32Frac(float32 a)
139{ 140{
140 return a & 0x007FFFFF; 141 return a & 0x007FFFFF;
141} 142}
142 143
143inline float64 packFloat64(flag zSign, int16 zExp, bits64 zSig) 144float64 packFloat64(flag zSign, int16 zExp, bits64 zSig)
144{ 145{
145 return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig; 146 return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig;
146} 147}
147 148
148inline void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr) 149void shift64RightJamming(bits64 a, int16 count, bits64 * zPtr)
149{ 150{
150 bits64 z; 151 bits64 z;
151 152
@@ -338,12 +339,12 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign)
338 339
339} 340}
340 341
341inline float32 packFloat32(flag zSign, int16 zExp, bits32 zSig) 342float32 packFloat32(flag zSign, int16 zExp, bits32 zSig)
342{ 343{
343 return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig; 344 return (((bits32) zSign) << 31) + (((bits32) zExp) << 23) + zSig;
344} 345}
345 346
346inline void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr) 347void shift32RightJamming(bits32 a, int16 count, bits32 * zPtr)
347{ 348{
348 bits32 z; 349 bits32 z;
349 if (count == 0) { 350 if (count == 0) {
@@ -634,7 +635,7 @@ normalizeFloat64Subnormal(bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr)
634 *zExpPtr = 1 - shiftCount; 635 *zExpPtr = 1 - shiftCount;
635} 636}
636 637
637inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 638void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
638 bits64 * z1Ptr) 639 bits64 * z1Ptr)
639{ 640{
640 bits64 z1; 641 bits64 z1;
@@ -644,7 +645,7 @@ inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
644 *z0Ptr = a0 + b0 + (z1 < a1); 645 *z0Ptr = a0 + b0 + (z1 < a1);
645} 646}
646 647
647inline void 648void
648sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, 649sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
649 bits64 * z1Ptr) 650 bits64 * z1Ptr)
650{ 651{
@@ -656,11 +657,14 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
656{ 657{
657 bits64 b0, b1; 658 bits64 b0, b1;
658 bits64 rem0, rem1, term0, term1; 659 bits64 rem0, rem1, term0, term1;
659 bits64 z; 660 bits64 z, tmp;
660 if (b <= a0) 661 if (b <= a0)
661 return LIT64(0xFFFFFFFFFFFFFFFF); 662 return LIT64(0xFFFFFFFFFFFFFFFF);
662 b0 = b >> 32; 663 b0 = b >> 32;
663 z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : (a0 / b0) << 32; 664 tmp = a0;
665 do_div(tmp, b0);
666
667 z = (b0 << 32 <= a0) ? LIT64(0xFFFFFFFF00000000) : tmp << 32;
664 mul64To128(b, z, &term0, &term1); 668 mul64To128(b, z, &term0, &term1);
665 sub128(a0, a1, term0, term1, &rem0, &rem1); 669 sub128(a0, a1, term0, term1, &rem0, &rem1);
666 while (((sbits64) rem0) < 0) { 670 while (((sbits64) rem0) < 0) {
@@ -669,11 +673,13 @@ static bits64 estimateDiv128To64(bits64 a0, bits64 a1, bits64 b)
669 add128(rem0, rem1, b0, b1, &rem0, &rem1); 673 add128(rem0, rem1, b0, b1, &rem0, &rem1);
670 } 674 }
671 rem0 = (rem0 << 32) | (rem1 >> 32); 675 rem0 = (rem0 << 32) | (rem1 >> 32);
672 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; 676 tmp = rem0;
677 do_div(tmp, b0);
678 z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : tmp;
673 return z; 679 return z;
674} 680}
675 681
676inline void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr) 682void mul64To128(bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr)
677{ 683{
678 bits32 aHigh, aLow, bHigh, bLow; 684 bits32 aHigh, aLow, bHigh, bLow;
679 bits64 z0, zMiddleA, zMiddleB, z1; 685 bits64 z0, zMiddleA, zMiddleB, z1;
@@ -769,7 +775,8 @@ float32 float32_div(float32 a, float32 b)
769{ 775{
770 flag aSign, bSign, zSign; 776 flag aSign, bSign, zSign;
771 int16 aExp, bExp, zExp; 777 int16 aExp, bExp, zExp;
772 bits32 aSig, bSig, zSig; 778 bits32 aSig, bSig;
779 uint64_t zSig;
773 780
774 aSig = extractFloat32Frac(a); 781 aSig = extractFloat32Frac(a);
775 aExp = extractFloat32Exp(a); 782 aExp = extractFloat32Exp(a);
@@ -804,11 +811,13 @@ float32 float32_div(float32 a, float32 b)
804 aSig >>= 1; 811 aSig >>= 1;
805 ++zExp; 812 ++zExp;
806 } 813 }
807 zSig = (((bits64) aSig) << 32) / bSig; 814 zSig = (((bits64) aSig) << 32);
815 do_div(zSig, bSig);
816
808 if ((zSig & 0x3F) == 0) { 817 if ((zSig & 0x3F) == 0) {
809 zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32); 818 zSig |= (((bits64) bSig) * zSig != ((bits64) aSig) << 32);
810 } 819 }
811 return roundAndPackFloat32(zSign, zExp, zSig); 820 return roundAndPackFloat32(zSign, zExp, (bits32)zSig);
812 821
813} 822}
814 823
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index db913855c2fd..0e174af21874 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -229,7 +229,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
229} 229}
230 230
231/** 231/**
232 * sh7722_find_divisors - find divisor for setting rate 232 * sh7722_find_div_index - find divisor for setting rate
233 * 233 *
234 * All sh7722 clocks use the same set of multipliers/divisors. This function 234 * All sh7722 clocks use the same set of multipliers/divisors. This function
235 * chooses correct divisor to set the rate of clock with parent clock that 235 * chooses correct divisor to set the rate of clock with parent clock that
@@ -238,7 +238,7 @@ struct frqcr_context sh7722_get_clk_context(const char *name)
238 * @parent_rate: rate of parent clock 238 * @parent_rate: rate of parent clock
239 * @rate: requested rate to be set 239 * @rate: requested rate to be set
240 */ 240 */
241static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate) 241static int sh7722_find_div_index(unsigned long parent_rate, unsigned rate)
242{ 242{
243 unsigned div2 = parent_rate * 2 / rate; 243 unsigned div2 = parent_rate * 2 / rate;
244 int index; 244 int index;
@@ -247,12 +247,12 @@ static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
247 return -EINVAL; 247 return -EINVAL;
248 248
249 for (index = 1; index < ARRAY_SIZE(divisors2); index++) { 249 for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
250 if (div2 > divisors2[index] && div2 <= divisors2[index]) 250 if (div2 > divisors2[index - 1] && div2 <= divisors2[index])
251 break; 251 break;
252 } 252 }
253 if (index >= ARRAY_SIZE(divisors2)) 253 if (index >= ARRAY_SIZE(divisors2))
254 index = ARRAY_SIZE(divisors2) - 1; 254 index = ARRAY_SIZE(divisors2) - 1;
255 return divisors2[index]; 255 return index;
256} 256}
257 257
258static void sh7722_frqcr_recalc(struct clk *clk) 258static void sh7722_frqcr_recalc(struct clk *clk)
@@ -279,12 +279,12 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
279 return -EINVAL; 279 return -EINVAL;
280 280
281 /* look for multiplier/divisor pair */ 281 /* look for multiplier/divisor pair */
282 div = sh7722_find_divisors(parent_rate, rate); 282 div = sh7722_find_div_index(parent_rate, rate);
283 if (div<0) 283 if (div<0)
284 return div; 284 return div;
285 285
286 /* calculate new value of clock rate */ 286 /* calculate new value of clock rate */
287 clk->rate = parent_rate * 2 / div; 287 clk->rate = parent_rate * 2 / divisors2[div];
288 frqcr = ctrl_inl(FRQCR); 288 frqcr = ctrl_inl(FRQCR);
289 289
290 /* FIXME: adjust as algo_id specifies */ 290 /* FIXME: adjust as algo_id specifies */
@@ -353,7 +353,7 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
353 int part_div; 353 int part_div;
354 354
355 if (likely(!err)) { 355 if (likely(!err)) {
356 part_div = sh7722_find_divisors(parent_rate, 356 part_div = sh7722_find_div_index(parent_rate,
357 rate); 357 rate);
358 if (part_div > 0) { 358 if (part_div > 0) {
359 part_ctx = sh7722_get_clk_context( 359 part_ctx = sh7722_get_clk_context(
@@ -394,12 +394,12 @@ static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate)
394 int div; 394 int div;
395 395
396 /* look for multiplier/divisor pair */ 396 /* look for multiplier/divisor pair */
397 div = sh7722_find_divisors(parent_rate, rate); 397 div = sh7722_find_div_index(parent_rate, rate);
398 if (div < 0) 398 if (div < 0)
399 return clk->rate; 399 return clk->rate;
400 400
401 /* calculate new value of clock rate */ 401 /* calculate new value of clock rate */
402 return parent_rate * 2 / div; 402 return parent_rate * 2 / divisors2[div];
403} 403}
404 404
405static struct clk_ops sh7722_frqcr_clk_ops = { 405static struct clk_ops sh7722_frqcr_clk_ops = {
@@ -421,7 +421,7 @@ static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
421 int div; 421 int div;
422 422
423 r = ctrl_inl(clk->arch_flags); 423 r = ctrl_inl(clk->arch_flags);
424 div = sh7722_find_divisors(clk->parent->rate, rate); 424 div = sh7722_find_div_index(clk->parent->rate, rate);
425 if (div < 0) 425 if (div < 0)
426 return div; 426 return div;
427 r = (r & ~0xF) | div; 427 r = (r & ~0xF) | div;
@@ -516,16 +516,19 @@ static struct clk_ops sh7722_video_clk_ops = {
516static struct clk sh7722_umem_clock = { 516static struct clk sh7722_umem_clock = {
517 .name = "umem_clk", 517 .name = "umem_clk",
518 .ops = &sh7722_frqcr_clk_ops, 518 .ops = &sh7722_frqcr_clk_ops,
519 .flags = CLK_RATE_PROPAGATES,
519}; 520};
520 521
521static struct clk sh7722_sh_clock = { 522static struct clk sh7722_sh_clock = {
522 .name = "sh_clk", 523 .name = "sh_clk",
523 .ops = &sh7722_frqcr_clk_ops, 524 .ops = &sh7722_frqcr_clk_ops,
525 .flags = CLK_RATE_PROPAGATES,
524}; 526};
525 527
526static struct clk sh7722_peripheral_clock = { 528static struct clk sh7722_peripheral_clock = {
527 .name = "peripheral_clk", 529 .name = "peripheral_clk",
528 .ops = &sh7722_frqcr_clk_ops, 530 .ops = &sh7722_frqcr_clk_ops,
531 .flags = CLK_RATE_PROPAGATES,
529}; 532};
530 533
531static struct clk sh7722_sdram_clock = { 534static struct clk sh7722_sdram_clock = {
@@ -533,6 +536,11 @@ static struct clk sh7722_sdram_clock = {
533 .ops = &sh7722_frqcr_clk_ops, 536 .ops = &sh7722_frqcr_clk_ops,
534}; 537};
535 538
539static struct clk sh7722_r_clock = {
540 .name = "r_clk",
541 .rate = 32768,
542 .flags = CLK_RATE_PROPAGATES,
543};
536 544
537#ifndef CONFIG_CPU_SUBTYPE_SH7343 545#ifndef CONFIG_CPU_SUBTYPE_SH7343
538 546
@@ -567,12 +575,30 @@ static struct clk sh7722_video_clock = {
567 .ops = &sh7722_video_clk_ops, 575 .ops = &sh7722_video_clk_ops,
568}; 576};
569 577
570static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg, 578#define MSTPCR_ARCH_FLAGS(reg, bit) (((reg) << 8) | (bit))
571 int enable) 579#define MSTPCR_ARCH_FLAGS_REG(value) ((value) >> 8)
580#define MSTPCR_ARCH_FLAGS_BIT(value) ((value) & 0xff)
581
582static int sh7722_mstpcr_start_stop(struct clk *clk, int enable)
572{ 583{
573 unsigned long bit = clk->arch_flags; 584 unsigned long bit = MSTPCR_ARCH_FLAGS_BIT(clk->arch_flags);
585 unsigned long reg;
574 unsigned long r; 586 unsigned long r;
575 587
588 switch(MSTPCR_ARCH_FLAGS_REG(clk->arch_flags)) {
589 case 0:
590 reg = MSTPCR0;
591 break;
592 case 1:
593 reg = MSTPCR1;
594 break;
595 case 2:
596 reg = MSTPCR2;
597 break;
598 default:
599 return -EINVAL;
600 }
601
576 r = ctrl_inl(reg); 602 r = ctrl_inl(reg);
577 603
578 if (enable) 604 if (enable)
@@ -584,96 +610,175 @@ static int sh7722_mstpcr_start_stop(struct clk *clk, unsigned long reg,
584 return 0; 610 return 0;
585} 611}
586 612
587static void sh7722_mstpcr0_enable(struct clk *clk) 613static void sh7722_mstpcr_enable(struct clk *clk)
588{
589 sh7722_mstpcr_start_stop(clk, MSTPCR0, 1);
590}
591
592static void sh7722_mstpcr0_disable(struct clk *clk)
593{
594 sh7722_mstpcr_start_stop(clk, MSTPCR0, 0);
595}
596
597static void sh7722_mstpcr1_enable(struct clk *clk)
598{
599 sh7722_mstpcr_start_stop(clk, MSTPCR1, 1);
600}
601
602static void sh7722_mstpcr1_disable(struct clk *clk)
603{ 614{
604 sh7722_mstpcr_start_stop(clk, MSTPCR1, 0); 615 sh7722_mstpcr_start_stop(clk, 1);
605} 616}
606 617
607static void sh7722_mstpcr2_enable(struct clk *clk) 618static void sh7722_mstpcr_disable(struct clk *clk)
608{ 619{
609 sh7722_mstpcr_start_stop(clk, MSTPCR2, 1); 620 sh7722_mstpcr_start_stop(clk, 0);
610} 621}
611 622
612static void sh7722_mstpcr2_disable(struct clk *clk) 623static void sh7722_mstpcr_recalc(struct clk *clk)
613{ 624{
614 sh7722_mstpcr_start_stop(clk, MSTPCR2, 0); 625 if (clk->parent)
626 clk->rate = clk->parent->rate;
615} 627}
616 628
617static struct clk_ops sh7722_mstpcr0_clk_ops = { 629static struct clk_ops sh7722_mstpcr_clk_ops = {
618 .enable = sh7722_mstpcr0_enable, 630 .enable = sh7722_mstpcr_enable,
619 .disable = sh7722_mstpcr0_disable, 631 .disable = sh7722_mstpcr_disable,
620}; 632 .recalc = sh7722_mstpcr_recalc,
621
622static struct clk_ops sh7722_mstpcr1_clk_ops = {
623 .enable = sh7722_mstpcr1_enable,
624 .disable = sh7722_mstpcr1_disable,
625}; 633};
626 634
627static struct clk_ops sh7722_mstpcr2_clk_ops = { 635#define MSTPCR(_name, _parent, regnr, bitnr) \
628 .enable = sh7722_mstpcr2_enable, 636{ \
629 .disable = sh7722_mstpcr2_disable, 637 .name = _name, \
630}; 638 .arch_flags = MSTPCR_ARCH_FLAGS(regnr, bitnr), \
631 639 .ops = (void *)_parent, \
632#define DECLARE_MSTPCRN(regnr, bitnr, bitstr) \
633{ \
634 .name = "mstp" __stringify(regnr) bitstr, \
635 .arch_flags = bitnr, \
636 .ops = &sh7722_mstpcr ## regnr ## _clk_ops, \
637} 640}
638 641
639#define DECLARE_MSTPCR(regnr) \ 642static struct clk sh7722_mstpcr_clocks[] = {
640 DECLARE_MSTPCRN(regnr, 31, "31"), \ 643#if defined(CONFIG_CPU_SUBTYPE_SH7722)
641 DECLARE_MSTPCRN(regnr, 30, "30"), \ 644 MSTPCR("uram0", "umem_clk", 0, 28),
642 DECLARE_MSTPCRN(regnr, 29, "29"), \ 645 MSTPCR("xymem0", "bus_clk", 0, 26),
643 DECLARE_MSTPCRN(regnr, 28, "28"), \ 646 MSTPCR("tmu0", "peripheral_clk", 0, 15),
644 DECLARE_MSTPCRN(regnr, 27, "27"), \ 647 MSTPCR("cmt0", "r_clk", 0, 14),
645 DECLARE_MSTPCRN(regnr, 26, "26"), \ 648 MSTPCR("rwdt0", "r_clk", 0, 13),
646 DECLARE_MSTPCRN(regnr, 25, "25"), \ 649 MSTPCR("flctl0", "peripheral_clk", 0, 10),
647 DECLARE_MSTPCRN(regnr, 24, "24"), \ 650 MSTPCR("scif0", "peripheral_clk", 0, 7),
648 DECLARE_MSTPCRN(regnr, 23, "23"), \ 651 MSTPCR("scif1", "peripheral_clk", 0, 6),
649 DECLARE_MSTPCRN(regnr, 22, "22"), \ 652 MSTPCR("scif2", "peripheral_clk", 0, 5),
650 DECLARE_MSTPCRN(regnr, 21, "21"), \ 653 MSTPCR("i2c0", "peripheral_clk", 1, 9),
651 DECLARE_MSTPCRN(regnr, 20, "20"), \ 654 MSTPCR("rtc0", "r_clk", 1, 8),
652 DECLARE_MSTPCRN(regnr, 19, "19"), \ 655 MSTPCR("sdhi0", "peripheral_clk", 2, 18),
653 DECLARE_MSTPCRN(regnr, 18, "18"), \ 656 MSTPCR("keysc0", "r_clk", 2, 14),
654 DECLARE_MSTPCRN(regnr, 17, "17"), \ 657 MSTPCR("usbf0", "peripheral_clk", 2, 11),
655 DECLARE_MSTPCRN(regnr, 16, "16"), \ 658 MSTPCR("2dg0", "bus_clk", 2, 9),
656 DECLARE_MSTPCRN(regnr, 15, "15"), \ 659 MSTPCR("siu0", "bus_clk", 2, 8),
657 DECLARE_MSTPCRN(regnr, 14, "14"), \ 660 MSTPCR("vou0", "bus_clk", 2, 5),
658 DECLARE_MSTPCRN(regnr, 13, "13"), \ 661 MSTPCR("jpu0", "bus_clk", 2, 6),
659 DECLARE_MSTPCRN(regnr, 12, "12"), \ 662 MSTPCR("beu0", "bus_clk", 2, 4),
660 DECLARE_MSTPCRN(regnr, 11, "11"), \ 663 MSTPCR("ceu0", "bus_clk", 2, 3),
661 DECLARE_MSTPCRN(regnr, 10, "10"), \ 664 MSTPCR("veu0", "bus_clk", 2, 2),
662 DECLARE_MSTPCRN(regnr, 9, "09"), \ 665 MSTPCR("vpu0", "bus_clk", 2, 1),
663 DECLARE_MSTPCRN(regnr, 8, "08"), \ 666 MSTPCR("lcdc0", "bus_clk", 2, 0),
664 DECLARE_MSTPCRN(regnr, 7, "07"), \ 667#endif
665 DECLARE_MSTPCRN(regnr, 6, "06"), \ 668#if defined(CONFIG_CPU_SUBTYPE_SH7723)
666 DECLARE_MSTPCRN(regnr, 5, "05"), \ 669 /* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
667 DECLARE_MSTPCRN(regnr, 4, "04"), \ 670 MSTPCR("tlb0", "cpu_clk", 0, 31),
668 DECLARE_MSTPCRN(regnr, 3, "03"), \ 671 MSTPCR("ic0", "cpu_clk", 0, 30),
669 DECLARE_MSTPCRN(regnr, 2, "02"), \ 672 MSTPCR("oc0", "cpu_clk", 0, 29),
670 DECLARE_MSTPCRN(regnr, 1, "01"), \ 673 MSTPCR("l2c0", "sh_clk", 0, 28),
671 DECLARE_MSTPCRN(regnr, 0, "00") 674 MSTPCR("ilmem0", "cpu_clk", 0, 27),
672 675 MSTPCR("fpu0", "cpu_clk", 0, 24),
673static struct clk sh7722_mstpcr[] = { 676 MSTPCR("intc0", "cpu_clk", 0, 22),
674 DECLARE_MSTPCR(0), 677 MSTPCR("dmac0", "bus_clk", 0, 21),
675 DECLARE_MSTPCR(1), 678 MSTPCR("sh0", "sh_clk", 0, 20),
676 DECLARE_MSTPCR(2), 679 MSTPCR("hudi0", "peripheral_clk", 0, 19),
680 MSTPCR("ubc0", "cpu_clk", 0, 17),
681 MSTPCR("tmu0", "peripheral_clk", 0, 15),
682 MSTPCR("cmt0", "r_clk", 0, 14),
683 MSTPCR("rwdt0", "r_clk", 0, 13),
684 MSTPCR("dmac1", "bus_clk", 0, 12),
685 MSTPCR("tmu1", "peripheral_clk", 0, 11),
686 MSTPCR("flctl0", "peripheral_clk", 0, 10),
687 MSTPCR("scif0", "peripheral_clk", 0, 9),
688 MSTPCR("scif1", "peripheral_clk", 0, 8),
689 MSTPCR("scif2", "peripheral_clk", 0, 7),
690 MSTPCR("scif3", "bus_clk", 0, 6),
691 MSTPCR("scif4", "bus_clk", 0, 5),
692 MSTPCR("scif5", "bus_clk", 0, 4),
693 MSTPCR("msiof0", "bus_clk", 0, 2),
694 MSTPCR("msiof1", "bus_clk", 0, 1),
695 MSTPCR("meram0", "sh_clk", 0, 0),
696 MSTPCR("i2c0", "peripheral_clk", 1, 9),
697 MSTPCR("rtc0", "r_clk", 1, 8),
698 MSTPCR("atapi0", "sh_clk", 2, 28),
699 MSTPCR("adc0", "peripheral_clk", 2, 28),
700 MSTPCR("tpu0", "bus_clk", 2, 25),
701 MSTPCR("irda0", "peripheral_clk", 2, 24),
702 MSTPCR("tsif0", "bus_clk", 2, 22),
703 MSTPCR("icb0", "bus_clk", 2, 21),
704 MSTPCR("sdhi0", "bus_clk", 2, 18),
705 MSTPCR("sdhi1", "bus_clk", 2, 17),
706 MSTPCR("keysc0", "r_clk", 2, 14),
707 MSTPCR("usb0", "bus_clk", 2, 11),
708 MSTPCR("2dg0", "bus_clk", 2, 10),
709 MSTPCR("siu0", "bus_clk", 2, 8),
710 MSTPCR("veu1", "bus_clk", 2, 6),
711 MSTPCR("vou0", "bus_clk", 2, 5),
712 MSTPCR("beu0", "bus_clk", 2, 4),
713 MSTPCR("ceu0", "bus_clk", 2, 3),
714 MSTPCR("veu0", "bus_clk", 2, 2),
715 MSTPCR("vpu0", "bus_clk", 2, 1),
716 MSTPCR("lcdc0", "bus_clk", 2, 0),
717#endif
718#if defined(CONFIG_CPU_SUBTYPE_SH7343)
719 MSTPCR("uram0", "umem_clk", 0, 28),
720 MSTPCR("xymem0", "bus_clk", 0, 26),
721 MSTPCR("tmu0", "peripheral_clk", 0, 15),
722 MSTPCR("cmt0", "r_clk", 0, 14),
723 MSTPCR("rwdt0", "r_clk", 0, 13),
724 MSTPCR("scif0", "peripheral_clk", 0, 7),
725 MSTPCR("scif1", "peripheral_clk", 0, 6),
726 MSTPCR("scif2", "peripheral_clk", 0, 5),
727 MSTPCR("scif3", "peripheral_clk", 0, 4),
728 MSTPCR("i2c0", "peripheral_clk", 1, 9),
729 MSTPCR("i2c1", "peripheral_clk", 1, 8),
730 MSTPCR("sdhi0", "peripheral_clk", 2, 18),
731 MSTPCR("keysc0", "r_clk", 2, 14),
732 MSTPCR("usbf0", "peripheral_clk", 2, 11),
733 MSTPCR("siu0", "bus_clk", 2, 8),
734 MSTPCR("jpu0", "bus_clk", 2, 6),
735 MSTPCR("vou0", "bus_clk", 2, 5),
736 MSTPCR("beu0", "bus_clk", 2, 4),
737 MSTPCR("ceu0", "bus_clk", 2, 3),
738 MSTPCR("veu0", "bus_clk", 2, 2),
739 MSTPCR("vpu0", "bus_clk", 2, 1),
740 MSTPCR("lcdc0", "bus_clk", 2, 0),
741#endif
742#if defined(CONFIG_CPU_SUBTYPE_SH7366)
743 /* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
744 MSTPCR("tlb0", "cpu_clk", 0, 31),
745 MSTPCR("ic0", "cpu_clk", 0, 30),
746 MSTPCR("oc0", "cpu_clk", 0, 29),
747 MSTPCR("rsmem0", "sh_clk", 0, 28),
748 MSTPCR("xymem0", "cpu_clk", 0, 26),
749 MSTPCR("intc30", "peripheral_clk", 0, 23),
750 MSTPCR("intc0", "peripheral_clk", 0, 22),
751 MSTPCR("dmac0", "bus_clk", 0, 21),
752 MSTPCR("sh0", "sh_clk", 0, 20),
753 MSTPCR("hudi0", "peripheral_clk", 0, 19),
754 MSTPCR("ubc0", "cpu_clk", 0, 17),
755 MSTPCR("tmu0", "peripheral_clk", 0, 15),
756 MSTPCR("cmt0", "r_clk", 0, 14),
757 MSTPCR("rwdt0", "r_clk", 0, 13),
758 MSTPCR("flctl0", "peripheral_clk", 0, 10),
759 MSTPCR("scif0", "peripheral_clk", 0, 7),
760 MSTPCR("scif1", "bus_clk", 0, 6),
761 MSTPCR("scif2", "bus_clk", 0, 5),
762 MSTPCR("msiof0", "peripheral_clk", 0, 2),
763 MSTPCR("sbr0", "peripheral_clk", 0, 1),
764 MSTPCR("i2c0", "peripheral_clk", 1, 9),
765 MSTPCR("icb0", "bus_clk", 2, 27),
766 MSTPCR("meram0", "sh_clk", 2, 26),
767 MSTPCR("dacc0", "peripheral_clk", 2, 24),
768 MSTPCR("dacy0", "peripheral_clk", 2, 23),
769 MSTPCR("tsif0", "bus_clk", 2, 22),
770 MSTPCR("sdhi0", "bus_clk", 2, 18),
771 MSTPCR("mmcif0", "bus_clk", 2, 17),
772 MSTPCR("usb0", "bus_clk", 2, 11),
773 MSTPCR("siu0", "bus_clk", 2, 8),
774 MSTPCR("veu1", "bus_clk", 2, 7),
775 MSTPCR("vou0", "bus_clk", 2, 5),
776 MSTPCR("beu0", "bus_clk", 2, 4),
777 MSTPCR("ceu0", "bus_clk", 2, 3),
778 MSTPCR("veu0", "bus_clk", 2, 2),
779 MSTPCR("vpu0", "bus_clk", 2, 1),
780 MSTPCR("lcdc0", "bus_clk", 2, 0),
781#endif
677}; 782};
678 783
679static struct clk *sh7722_clocks[] = { 784static struct clk *sh7722_clocks[] = {
@@ -710,21 +815,30 @@ arch_init_clk_ops(struct clk_ops **ops, int type)
710 815
711int __init arch_clk_init(void) 816int __init arch_clk_init(void)
712{ 817{
713 struct clk *master; 818 struct clk *clk;
714 int i; 819 int i;
715 820
716 master = clk_get(NULL, "master_clk"); 821 clk = clk_get(NULL, "master_clk");
717 for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) { 822 for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
718 pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name); 823 pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
719 sh7722_clocks[i]->parent = master; 824 sh7722_clocks[i]->parent = clk;
720 clk_register(sh7722_clocks[i]); 825 clk_register(sh7722_clocks[i]);
721 } 826 }
722 clk_put(master); 827 clk_put(clk);
723 828
724 for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr); i++) { 829 clk_register(&sh7722_r_clock);
725 pr_debug( "Registering mstpcr '%s'\n", sh7722_mstpcr[i].name); 830
726 clk_register(&sh7722_mstpcr[i]); 831 for (i = 0; i < ARRAY_SIZE(sh7722_mstpcr_clocks); i++) {
832 pr_debug( "Registering mstpcr clock '%s'\n",
833 sh7722_mstpcr_clocks[i].name);
834 clk = clk_get(NULL, (void *) sh7722_mstpcr_clocks[i].ops);
835 sh7722_mstpcr_clocks[i].parent = clk;
836 sh7722_mstpcr_clocks[i].ops = &sh7722_mstpcr_clk_ops;
837 clk_register(&sh7722_mstpcr_clocks[i]);
838 clk_put(clk);
727 } 839 }
728 840
841 clk_recalc_rate(&sh7722_r_clock); /* make sure rate gets propagated */
842
729 return 0; 843 return 0;
730} 844}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 78881b4214da..0623e377f488 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -30,6 +30,7 @@ static struct resource iic0_resources[] = {
30 30
31static struct platform_device iic0_device = { 31static struct platform_device iic0_device = {
32 .name = "i2c-sh_mobile", 32 .name = "i2c-sh_mobile",
33 .id = 0, /* "i2c0" clock */
33 .num_resources = ARRAY_SIZE(iic0_resources), 34 .num_resources = ARRAY_SIZE(iic0_resources),
34 .resource = iic0_resources, 35 .resource = iic0_resources,
35}; 36};
@@ -50,6 +51,7 @@ static struct resource iic1_resources[] = {
50 51
51static struct platform_device iic1_device = { 52static struct platform_device iic1_device = {
52 .name = "i2c-sh_mobile", 53 .name = "i2c-sh_mobile",
54 .id = 1, /* "i2c1" clock */
53 .num_resources = ARRAY_SIZE(iic1_resources), 55 .num_resources = ARRAY_SIZE(iic1_resources),
54 .resource = iic1_resources, 56 .resource = iic1_resources,
55}; 57};
@@ -115,7 +117,22 @@ static struct plat_sci_port sci_platform_data[] = {
115 .mapbase = 0xffe00000, 117 .mapbase = 0xffe00000,
116 .flags = UPF_BOOT_AUTOCONF, 118 .flags = UPF_BOOT_AUTOCONF,
117 .type = PORT_SCIF, 119 .type = PORT_SCIF,
118 .irqs = { 80, 81, 83, 82 }, 120 .irqs = { 80, 80, 80, 80 },
121 }, {
122 .mapbase = 0xffe10000,
123 .flags = UPF_BOOT_AUTOCONF,
124 .type = PORT_SCIF,
125 .irqs = { 81, 81, 81, 81 },
126 }, {
127 .mapbase = 0xffe20000,
128 .flags = UPF_BOOT_AUTOCONF,
129 .type = PORT_SCIF,
130 .irqs = { 82, 82, 82, 82 },
131 }, {
132 .mapbase = 0xffe30000,
133 .flags = UPF_BOOT_AUTOCONF,
134 .type = PORT_SCIF,
135 .irqs = { 83, 83, 83, 83 },
119 }, { 136 }, {
120 .flags = 0, 137 .flags = 0,
121 } 138 }
@@ -139,18 +156,10 @@ static struct platform_device *sh7343_devices[] __initdata = {
139 156
140static int __init sh7343_devices_setup(void) 157static int __init sh7343_devices_setup(void)
141{ 158{
142 clk_always_enable("mstp031"); /* TLB */ 159 clk_always_enable("uram0"); /* URAM */
143 clk_always_enable("mstp030"); /* IC */ 160 clk_always_enable("xymem0"); /* XYMEM */
144 clk_always_enable("mstp029"); /* OC */ 161 clk_always_enable("veu0"); /* VEU */
145 clk_always_enable("mstp028"); /* URAM */ 162 clk_always_enable("vpu0"); /* VPU */
146 clk_always_enable("mstp026"); /* XYMEM */
147 clk_always_enable("mstp023"); /* INTC3 */
148 clk_always_enable("mstp022"); /* INTC */
149 clk_always_enable("mstp020"); /* SuperHyway */
150 clk_always_enable("mstp109"); /* I2C0 */
151 clk_always_enable("mstp108"); /* I2C1 */
152 clk_always_enable("mstp202"); /* VEU */
153 clk_always_enable("mstp201"); /* VPU */
154 163
155 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20); 164 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
156 platform_resource_setup_memory(&veu_device, "veu", 2 << 20); 165 platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
@@ -171,7 +180,7 @@ enum {
171 MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY, 180 MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY,
172 DMAC4, DMAC5, DMAC_DADERR, 181 DMAC4, DMAC5, DMAC_DADERR,
173 KEYSC, 182 KEYSC,
174 SCIF, SCIF1, SCIF2, SCIF3, SCIF4, 183 SCIF, SCIF1, SCIF2, SCIF3,
175 SIOF0, SIOF1, SIO, 184 SIOF0, SIOF1, SIO,
176 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, 185 FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
177 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, 186 I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index e17db39b97aa..839ae97a7fd2 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -32,6 +32,7 @@ static struct resource iic_resources[] = {
32 32
33static struct platform_device iic_device = { 33static struct platform_device iic_device = {
34 .name = "i2c-sh_mobile", 34 .name = "i2c-sh_mobile",
35 .id = 0, /* "i2c0" clock */
35 .num_resources = ARRAY_SIZE(iic_resources), 36 .num_resources = ARRAY_SIZE(iic_resources),
36 .resource = iic_resources, 37 .resource = iic_resources,
37}; 38};
@@ -176,19 +177,11 @@ static struct platform_device *sh7366_devices[] __initdata = {
176 177
177static int __init sh7366_devices_setup(void) 178static int __init sh7366_devices_setup(void)
178{ 179{
179 clk_always_enable("mstp031"); /* TLB */ 180 clk_always_enable("rsmem0"); /* RSMEM */
180 clk_always_enable("mstp030"); /* IC */ 181 clk_always_enable("xymem0"); /* XYMEM */
181 clk_always_enable("mstp029"); /* OC */ 182 clk_always_enable("veu1"); /* VEU-2 */
182 clk_always_enable("mstp028"); /* RSMEM */ 183 clk_always_enable("veu0"); /* VEU-1 */
183 clk_always_enable("mstp026"); /* XYMEM */ 184 clk_always_enable("vpu0"); /* VPU */
184 clk_always_enable("mstp023"); /* INTC3 */
185 clk_always_enable("mstp022"); /* INTC */
186 clk_always_enable("mstp020"); /* SuperHyway */
187 clk_always_enable("mstp109"); /* I2C */
188 clk_always_enable("mstp211"); /* USB */
189 clk_always_enable("mstp207"); /* VEU-2 */
190 clk_always_enable("mstp202"); /* VEU-1 */
191 clk_always_enable("mstp201"); /* VPU */
192 185
193 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); 186 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
194 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 187 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ef77ee1d9f53..50cf6838ec41 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -62,7 +62,7 @@ static struct resource usbf_resources[] = {
62 62
63static struct platform_device usbf_device = { 63static struct platform_device usbf_device = {
64 .name = "m66592_udc", 64 .name = "m66592_udc",
65 .id = -1, 65 .id = 0, /* "usbf0" clock */
66 .dev = { 66 .dev = {
67 .dma_mask = NULL, 67 .dma_mask = NULL,
68 .coherent_dma_mask = 0xffffffff, 68 .coherent_dma_mask = 0xffffffff,
@@ -87,6 +87,7 @@ static struct resource iic_resources[] = {
87 87
88static struct platform_device iic_device = { 88static struct platform_device iic_device = {
89 .name = "i2c-sh_mobile", 89 .name = "i2c-sh_mobile",
90 .id = 0, /* "i2c0" clock */
90 .num_resources = ARRAY_SIZE(iic_resources), 91 .num_resources = ARRAY_SIZE(iic_resources),
91 .resource = iic_resources, 92 .resource = iic_resources,
92}; 93};
@@ -147,6 +148,34 @@ static struct platform_device veu_device = {
147 .num_resources = ARRAY_SIZE(veu_resources), 148 .num_resources = ARRAY_SIZE(veu_resources),
148}; 149};
149 150
151static struct uio_info jpu_platform_data = {
152 .name = "JPU",
153 .version = "0",
154 .irq = 27,
155};
156
157static struct resource jpu_resources[] = {
158 [0] = {
159 .name = "JPU",
160 .start = 0xfea00000,
161 .end = 0xfea102d0,
162 .flags = IORESOURCE_MEM,
163 },
164 [1] = {
165 /* place holder for contiguous memory */
166 },
167};
168
169static struct platform_device jpu_device = {
170 .name = "uio_pdrv_genirq",
171 .id = 2,
172 .dev = {
173 .platform_data = &jpu_platform_data,
174 },
175 .resource = jpu_resources,
176 .num_resources = ARRAY_SIZE(jpu_resources),
177};
178
150static struct plat_sci_port sci_platform_data[] = { 179static struct plat_sci_port sci_platform_data[] = {
151 { 180 {
152 .mapbase = 0xffe00000, 181 .mapbase = 0xffe00000,
@@ -186,24 +215,21 @@ static struct platform_device *sh7722_devices[] __initdata = {
186 &sci_device, 215 &sci_device,
187 &vpu_device, 216 &vpu_device,
188 &veu_device, 217 &veu_device,
218 &jpu_device,
189}; 219};
190 220
191static int __init sh7722_devices_setup(void) 221static int __init sh7722_devices_setup(void)
192{ 222{
193 clk_always_enable("mstp031"); /* TLB */ 223 clk_always_enable("uram0"); /* URAM */
194 clk_always_enable("mstp030"); /* IC */ 224 clk_always_enable("xymem0"); /* XYMEM */
195 clk_always_enable("mstp029"); /* OC */ 225 clk_always_enable("rtc0"); /* RTC */
196 clk_always_enable("mstp028"); /* URAM */ 226 clk_always_enable("veu0"); /* VEU */
197 clk_always_enable("mstp026"); /* XYMEM */ 227 clk_always_enable("vpu0"); /* VPU */
198 clk_always_enable("mstp022"); /* INTC */ 228 clk_always_enable("jpu0"); /* JPU */
199 clk_always_enable("mstp020"); /* SuperHyway */
200 clk_always_enable("mstp109"); /* I2C */
201 clk_always_enable("mstp211"); /* USB */
202 clk_always_enable("mstp202"); /* VEU */
203 clk_always_enable("mstp201"); /* VPU */
204 229
205 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20); 230 platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
206 platform_resource_setup_memory(&veu_device, "veu", 2 << 20); 231 platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
232 platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
207 233
208 return platform_add_devices(sh7722_devices, 234 return platform_add_devices(sh7722_devices,
209 ARRAY_SIZE(sh7722_devices)); 235 ARRAY_SIZE(sh7722_devices));
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 6d9e6972cfc9..849770d780ae 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -215,6 +215,7 @@ static struct resource iic_resources[] = {
215 215
216static struct platform_device iic_device = { 216static struct platform_device iic_device = {
217 .name = "i2c-sh_mobile", 217 .name = "i2c-sh_mobile",
218 .id = 0, /* "i2c0" clock */
218 .num_resources = ARRAY_SIZE(iic_resources), 219 .num_resources = ARRAY_SIZE(iic_resources),
219 .resource = iic_resources, 220 .resource = iic_resources,
220}; 221};
@@ -231,19 +232,11 @@ static struct platform_device *sh7723_devices[] __initdata = {
231 232
232static int __init sh7723_devices_setup(void) 233static int __init sh7723_devices_setup(void)
233{ 234{
234 clk_always_enable("mstp031"); /* TLB */ 235 clk_always_enable("meram0"); /* MERAM */
235 clk_always_enable("mstp030"); /* IC */ 236 clk_always_enable("rtc0"); /* RTC */
236 clk_always_enable("mstp029"); /* OC */ 237 clk_always_enable("veu1"); /* VEU2H1 */
237 clk_always_enable("mstp024"); /* FPU */ 238 clk_always_enable("veu0"); /* VEU2H0 */
238 clk_always_enable("mstp022"); /* INTC */ 239 clk_always_enable("vpu0"); /* VPU */
239 clk_always_enable("mstp020"); /* SuperHyway */
240 clk_always_enable("mstp000"); /* MERAM */
241 clk_always_enable("mstp109"); /* I2C */
242 clk_always_enable("mstp108"); /* RTC */
243 clk_always_enable("mstp211"); /* USB */
244 clk_always_enable("mstp206"); /* VEU2H1 */
245 clk_always_enable("mstp202"); /* VEU2H0 */
246 clk_always_enable("mstp201"); /* VPU */
247 240
248 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); 241 platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
249 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); 242 platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 13b66746410a..591741383ee6 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -3,7 +3,7 @@
3 * 3 *
4 * Debug trap jump tables for SuperH 4 * Debug trap jump tables for SuperH
5 * 5 *
6 * Copyright (C) 2006 Paul Mundt 6 * Copyright (C) 2006 - 2008 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -12,12 +12,13 @@
12#include <linux/sys.h> 12#include <linux/sys.h>
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14 14
15#if !defined(CONFIG_SH_KGDB) 15#if !defined(CONFIG_KGDB)
16#define kgdb_handle_exception debug_trap_handler 16#define breakpoint_trap_handler debug_trap_handler
17#define singlestep_trap_handler debug_trap_handler
17#endif 18#endif
18 19
19#if !defined(CONFIG_SH_STANDARD_BIOS) 20#if !defined(CONFIG_SH_STANDARD_BIOS)
20#define sh_bios_handler debug_trap_handler 21#define sh_bios_handler debug_trap_handler
21#endif 22#endif
22 23
23 .data 24 .data
@@ -35,7 +36,7 @@ ENTRY(debug_trap_table)
35 .long debug_trap_handler /* 0x39 */ 36 .long debug_trap_handler /* 0x39 */
36 .long debug_trap_handler /* 0x3a */ 37 .long debug_trap_handler /* 0x3a */
37 .long debug_trap_handler /* 0x3b */ 38 .long debug_trap_handler /* 0x3b */
38 .long kgdb_handle_exception /* 0x3c */ 39 .long breakpoint_trap_handler /* 0x3c */
39 .long debug_trap_handler /* 0x3d */ 40 .long singlestep_trap_handler /* 0x3d */
40 .long bug_trap_handler /* 0x3e */ 41 .long bug_trap_handler /* 0x3e */
41 .long sh_bios_handler /* 0x3f */ 42 .long sh_bios_handler /* 0x3f */
diff --git a/arch/sh/kernel/disassemble.c b/arch/sh/kernel/disassemble.c
new file mode 100644
index 000000000000..64d5d8dded7c
--- /dev/null
+++ b/arch/sh/kernel/disassemble.c
@@ -0,0 +1,573 @@
1/*
2 * Disassemble SuperH instructions.
3 *
4 * Copyright (C) 1999 kaz Kojima
5 * Copyright (C) 2008 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/uaccess.h>
14
15/*
16 * Format of an instruction in memory.
17 */
18typedef enum {
19 HEX_0, HEX_1, HEX_2, HEX_3, HEX_4, HEX_5, HEX_6, HEX_7,
20 HEX_8, HEX_9, HEX_A, HEX_B, HEX_C, HEX_D, HEX_E, HEX_F,
21 REG_N, REG_M, REG_NM, REG_B,
22 BRANCH_12, BRANCH_8,
23 DISP_8, DISP_4,
24 IMM_4, IMM_4BY2, IMM_4BY4, PCRELIMM_8BY2, PCRELIMM_8BY4,
25 IMM_8, IMM_8BY2, IMM_8BY4,
26} sh_nibble_type;
27
28typedef enum {
29 A_END, A_BDISP12, A_BDISP8,
30 A_DEC_M, A_DEC_N,
31 A_DISP_GBR, A_DISP_PC, A_DISP_REG_M, A_DISP_REG_N,
32 A_GBR,
33 A_IMM,
34 A_INC_M, A_INC_N,
35 A_IND_M, A_IND_N, A_IND_R0_REG_M, A_IND_R0_REG_N,
36 A_MACH, A_MACL,
37 A_PR, A_R0, A_R0_GBR, A_REG_M, A_REG_N, A_REG_B,
38 A_SR, A_VBR, A_SSR, A_SPC, A_SGR, A_DBR,
39 F_REG_N, F_REG_M, D_REG_N, D_REG_M,
40 X_REG_N, /* Only used for argument parsing */
41 X_REG_M, /* Only used for argument parsing */
42 DX_REG_N, DX_REG_M, V_REG_N, V_REG_M,
43 FD_REG_N,
44 XMTRX_M4,
45 F_FR0,
46 FPUL_N, FPUL_M, FPSCR_N, FPSCR_M,
47} sh_arg_type;
48
49static struct sh_opcode_info {
50 char *name;
51 sh_arg_type arg[7];
52 sh_nibble_type nibbles[4];
53} sh_table[] = {
54 {"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
55 {"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
56 {"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
57 {"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
58 {"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
59 {"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
60 {"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
61 {"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
62 {"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
63 {"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
64 {"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
65 {"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
66 {"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
67 {"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
68 {"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
69 {"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
70 {"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
71 {"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
72 {"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
73 {"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
74 {"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
75 {"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
76 {"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
77 {"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
78 {"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
79 {"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
80 {"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
81 {"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
82 {"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
83 {"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
84 {"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
85 {"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
86 {"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}},
87 {"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}},
88 {"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
89 {"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
90 {"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
91 {"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
92 {"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
93 {"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
94 {"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
95 {"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}},
96 {"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
97 {"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
98 {"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
99 {"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
100 {"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
101 {"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
102 {"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}},
103 {"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
104 {"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
105 {"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
106 {"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
107 {"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
108 {"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
109 {"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
110 {"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
111 {"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
112 {"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
113 {"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
114 {"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
115 {"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
116 {"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
117 {"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
118 {"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}},
119 {"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
120 {"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
121 {"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}},
122 {"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
123 {"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}},
124 {"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
125 {"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
126 {"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
127 {"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
128 {"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
129 {"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}},
130 {"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}},
131 {"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
132 {"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}},
133 {"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
134 {"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
135 {"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}},
136 {"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}},
137 {"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}},
138 {"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
139 {"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}},
140 {"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
141 {"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
142 {"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
143 {"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
144 {"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
145 {"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}},
146 {"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}},
147 {"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}},
148 {"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}},
149 {"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
150 {"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
151 {"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
152 {"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
153 {"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
154 {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
155 {"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
156 {"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
157 {"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
158 {"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
159 {"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
160 {"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
161 {"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
162 {"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
163 {"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
164 {"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
165 {"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
166 {"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
167 {"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
168 {"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
169 {"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
170 {"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
171 {"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
172 {"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
173 {"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
174 {"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
175 {"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
176 {"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
177 {"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
178 {"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
179 {"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
180 {"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
181 {"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
182 {"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
183 {"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
184 {"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
185 {"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
186 {"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
187 {"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
188 {"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
189 {"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
190 {"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
191 {"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
192 {"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
193 {"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}},
194 {"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}},
195 {"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
196 {"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
197 {"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
198 {"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
199 {"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
200 {"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
201 {"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}},
202 {"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}},
203 {"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
204 {"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
205 {"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
206 {"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
207 {"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
208 {"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
209 {"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
210 {"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
211 {"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
212 {"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
213 {"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
214 {"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
215 {"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
216 {"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
217 {"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
218 {"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
219 {"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
220 {"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
221 {"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
222 {"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
223 {"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
224 {"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
225 {"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
226 {"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
227 {"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
228 {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
229 {"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
230 {"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
231 {"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
232 {"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
233 {"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
234 {"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
235 {"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
236 {"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
237 {"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
238 {"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
239 {"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
240 {"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
241 {"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
242 {"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
243 {"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
244 {"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
245 {"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
246 {"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
247 {"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}},
248 {"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
249 {"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
250 {"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
251 {"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}},
252 {"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
253 {"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
254 {"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
255 {"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
256 {"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
257 {"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
258 {"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
259 {"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
260 {"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
261 {"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
262 {"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
263 {"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
264 {"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
265 {"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
266 {"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
267 {"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
268 {"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
269 {"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
270 {"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
271 {"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
272 {"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
273 {"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
274 {"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
275 {"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
276 {"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
277 {"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
278 {"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
279 {"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
280 {"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
281 {"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
282 {"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
283 {"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
284 {"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}},
285 {"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
286 {"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
287 {"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
288 {"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
289 { 0 },
290};
291
292static void print_sh_insn(u32 memaddr, u16 insn)
293{
294 int relmask = ~0;
295 int nibs[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, (insn >> 4) & 0xf, insn & 0xf};
296 int lastsp;
297 struct sh_opcode_info *op = sh_table;
298
299 for (; op->name; op++) {
300 int n;
301 int imm = 0;
302 int rn = 0;
303 int rm = 0;
304 int rb = 0;
305 int disp_pc;
306 int disp_pc_addr = 0;
307
308 for (n = 0; n < 4; n++) {
309 int i = op->nibbles[n];
310
311 if (i < 16) {
312 if (nibs[n] == i)
313 continue;
314 goto fail;
315 }
316 switch (i) {
317 case BRANCH_8:
318 imm = (nibs[2] << 4) | (nibs[3]);
319 if (imm & 0x80)
320 imm |= ~0xff;
321 imm = ((char)imm) * 2 + 4 ;
322 goto ok;
323 case BRANCH_12:
324 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
325 if (imm & 0x800)
326 imm |= ~0xfff;
327 imm = imm * 2 + 4;
328 goto ok;
329 case IMM_4:
330 imm = nibs[3];
331 goto ok;
332 case IMM_4BY2:
333 imm = nibs[3] <<1;
334 goto ok;
335 case IMM_4BY4:
336 imm = nibs[3] <<2;
337 goto ok;
338 case IMM_8:
339 imm = (nibs[2] << 4) | nibs[3];
340 goto ok;
341 case PCRELIMM_8BY2:
342 imm = ((nibs[2] << 4) | nibs[3]) <<1;
343 relmask = ~1;
344 goto ok;
345 case PCRELIMM_8BY4:
346 imm = ((nibs[2] << 4) | nibs[3]) <<2;
347 relmask = ~3;
348 goto ok;
349 case IMM_8BY2:
350 imm = ((nibs[2] << 4) | nibs[3]) <<1;
351 goto ok;
352 case IMM_8BY4:
353 imm = ((nibs[2] << 4) | nibs[3]) <<2;
354 goto ok;
355 case DISP_8:
356 imm = (nibs[2] << 4) | (nibs[3]);
357 goto ok;
358 case DISP_4:
359 imm = nibs[3];
360 goto ok;
361 case REG_N:
362 rn = nibs[n];
363 break;
364 case REG_M:
365 rm = nibs[n];
366 break;
367 case REG_NM:
368 rn = (nibs[n] & 0xc) >> 2;
369 rm = (nibs[n] & 0x3);
370 break;
371 case REG_B:
372 rb = nibs[n] & 0x07;
373 break;
374 default:
375 return;
376 }
377 }
378
379 ok:
380 printk("%-8s ", op->name);
381 lastsp = (op->arg[0] == A_END);
382 disp_pc = 0;
383 for (n = 0; n < 6 && op->arg[n] != A_END; n++) {
384 if (n && op->arg[1] != A_END)
385 printk(", ");
386 switch (op->arg[n]) {
387 case A_IMM:
388 printk("#%d", (char)(imm));
389 break;
390 case A_R0:
391 printk("r0");
392 break;
393 case A_REG_N:
394 printk("r%d", rn);
395 break;
396 case A_INC_N:
397 printk("@r%d+", rn);
398 break;
399 case A_DEC_N:
400 printk("@-r%d", rn);
401 break;
402 case A_IND_N:
403 printk("@r%d", rn);
404 break;
405 case A_DISP_REG_N:
406 printk("@(%d,r%d)", imm, rn);
407 break;
408 case A_REG_M:
409 printk("r%d", rm);
410 break;
411 case A_INC_M:
412 printk("@r%d+", rm);
413 break;
414 case A_DEC_M:
415 printk("@-r%d", rm);
416 break;
417 case A_IND_M:
418 printk("@r%d", rm);
419 break;
420 case A_DISP_REG_M:
421 printk("@(%d,r%d)", imm, rm);
422 break;
423 case A_REG_B:
424 printk("r%d_bank", rb);
425 break;
426 case A_DISP_PC:
427 disp_pc = 1;
428 disp_pc_addr = imm + 4 + (memaddr & relmask);
429 printk("%08x <%pS>", disp_pc_addr,
430 (void *)disp_pc_addr);
431 break;
432 case A_IND_R0_REG_N:
433 printk("@(r0,r%d)", rn);
434 break;
435 case A_IND_R0_REG_M:
436 printk("@(r0,r%d)", rm);
437 break;
438 case A_DISP_GBR:
439 printk("@(%d,gbr)",imm);
440 break;
441 case A_R0_GBR:
442 printk("@(r0,gbr)");
443 break;
444 case A_BDISP12:
445 case A_BDISP8:
446 printk("%08x", imm + memaddr);
447 break;
448 case A_SR:
449 printk("sr");
450 break;
451 case A_GBR:
452 printk("gbr");
453 break;
454 case A_VBR:
455 printk("vbr");
456 break;
457 case A_SSR:
458 printk("ssr");
459 break;
460 case A_SPC:
461 printk("spc");
462 break;
463 case A_MACH:
464 printk("mach");
465 break;
466 case A_MACL:
467 printk("macl");
468 break;
469 case A_PR:
470 printk("pr");
471 break;
472 case A_SGR:
473 printk("sgr");
474 break;
475 case A_DBR:
476 printk("dbr");
477 break;
478 case FD_REG_N:
479 if (0)
480 goto d_reg_n;
481 case F_REG_N:
482 printk("fr%d", rn);
483 break;
484 case F_REG_M:
485 printk("fr%d", rm);
486 break;
487 case DX_REG_N:
488 if (rn & 1) {
489 printk("xd%d", rn & ~1);
490 break;
491 }
492 d_reg_n:
493 case D_REG_N:
494 printk("dr%d", rn);
495 break;
496 case DX_REG_M:
497 if (rm & 1) {
498 printk("xd%d", rm & ~1);
499 break;
500 }
501 case D_REG_M:
502 printk("dr%d", rm);
503 break;
504 case FPSCR_M:
505 case FPSCR_N:
506 printk("fpscr");
507 break;
508 case FPUL_M:
509 case FPUL_N:
510 printk("fpul");
511 break;
512 case F_FR0:
513 printk("fr0");
514 break;
515 case V_REG_N:
516 printk("fv%d", rn*4);
517 break;
518 case V_REG_M:
519 printk("fv%d", rm*4);
520 break;
521 case XMTRX_M4:
522 printk("xmtrx");
523 break;
524 default:
525 return;
526 }
527 }
528
529 if (disp_pc && strcmp(op->name, "mova") != 0) {
530 u32 val;
531
532 if (relmask == ~1)
533 __get_user(val, (u16 *)disp_pc_addr);
534 else
535 __get_user(val, (u32 *)disp_pc_addr);
536
537 printk(" ! %08x <%pS>", val, (void *)val);
538 }
539
540 return;
541 fail:
542 ;
543
544 }
545
546 printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
547}
548
549void show_code(struct pt_regs *regs)
550{
551 unsigned short *pc = (unsigned short *)regs->pc;
552 long i;
553
554 if (regs->pc & 0x1)
555 return;
556
557 printk("Code:\n");
558
559 for (i = -3 ; i < 6 ; i++) {
560 unsigned short insn;
561
562 if (__get_user(insn, pc + i)) {
563 printk(" (Bad address in pc)\n");
564 break;
565 }
566
567 printk("%s%08lx: ", (i ? " ": "->"), (unsigned long)(pc + i));
568 print_sh_insn((unsigned long)(pc + i), insn);
569 printk("\n");
570 }
571
572 printk("\n");
573}
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 5b7efc4016fa..d62359cfbbe2 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -308,15 +308,19 @@ ENTRY(system_call)
308 mov.l 1f, r9 308 mov.l 1f, r9
309 mov.l @r9, r8 ! Read from TRA (Trap Address) Register 309 mov.l @r9, r8 ! Read from TRA (Trap Address) Register
310#endif 310#endif
311
312 mov #OFF_TRA, r10
313 add r15, r10
314 mov.l r8, @r10 ! set TRA value to tra
315
311 /* 316 /*
312 * Check the trap type 317 * Check the trap type
313 */ 318 */
314 mov #((0x20 << 2) - 1), r9 319 mov #((0x20 << 2) - 1), r9
315 cmp/hi r9, r8 320 cmp/hi r9, r8
316 bt/s debug_trap ! it's a debug trap.. 321 bt/s debug_trap ! it's a debug trap..
317 mov #OFF_TRA, r9 322 nop
318 add r15, r9 323
319 mov.l r8, @r9 ! set TRA value to tra
320#ifdef CONFIG_TRACE_IRQFLAGS 324#ifdef CONFIG_TRACE_IRQFLAGS
321 mov.l 5f, r10 325 mov.l 5f, r10
322 jsr @r10 326 jsr @r10
@@ -371,47 +375,3 @@ syscall_exit:
371#endif 375#endif
3727: .long do_syscall_trace_enter 3767: .long do_syscall_trace_enter
3738: .long do_syscall_trace_leave 3778: .long do_syscall_trace_leave
374
375#ifdef CONFIG_FUNCTION_TRACER
376 .align 2
377 .globl _mcount
378 .type _mcount,@function
379 .globl mcount
380 .type mcount,@function
381_mcount:
382mcount:
383 mov.l r4, @-r15
384 mov.l r5, @-r15
385 mov.l r6, @-r15
386 mov.l r7, @-r15
387 sts.l pr, @-r15
388
389 mov.l @(20,r15),r4
390 sts pr, r5
391
392 mov.l 1f, r6
393 mov.l ftrace_stub, r7
394 cmp/eq r6, r7
395 bt skip_trace
396
397 mov.l @r6, r6
398 jsr @r6
399 nop
400
401skip_trace:
402
403 lds.l @r15+, pr
404 mov.l @r15+, r7
405 mov.l @r15+, r6
406 mov.l @r15+, r5
407 rts
408 mov.l @r15+, r4
409
410 .align 2
4111: .long ftrace_trace_function
412
413 .globl ftrace_stub
414ftrace_stub:
415 rts
416 nop
417#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
new file mode 100644
index 000000000000..4c3247477aa3
--- /dev/null
+++ b/arch/sh/kernel/ftrace.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2008 Matt Fleming <mjf@gentoo.org>
3 * Copyright (C) 2008 Paul Mundt <lethal@linux-sh.org>
4 *
5 * Code for replacing ftrace calls with jumps.
6 *
7 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
8 *
9 * Thanks goes to Ingo Molnar, for suggesting the idea.
10 * Mathieu Desnoyers, for suggesting postponing the modifications.
11 * Arjan van de Ven, for keeping me straight, and explaining to me
12 * the dangers of modifying code on the run.
13 */
14#include <linux/uaccess.h>
15#include <linux/ftrace.h>
16#include <linux/string.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <asm/ftrace.h>
20#include <asm/cacheflush.h>
21
22static unsigned char ftrace_nop[] = {
23 0x09, 0x00, /* nop */
24 0x09, 0x00, /* nop */
25};
26
27static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
28
29unsigned char *ftrace_nop_replace(void)
30{
31 return ftrace_nop;
32}
33
34static int is_sh_nop(unsigned char *ip)
35{
36 return strncmp(ip, ftrace_nop, sizeof(ftrace_nop));
37}
38
39unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
40{
41 /* Place the address in the memory table. */
42 if (addr == CALLER_ADDR)
43 __raw_writel(addr + MCOUNT_INSN_OFFSET, ftrace_replaced_code);
44 else
45 __raw_writel(addr, ftrace_replaced_code);
46
47 /*
48 * No locking needed, this must be called via kstop_machine
49 * which in essence is like running on a uniprocessor machine.
50 */
51 return ftrace_replaced_code;
52}
53
54int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
55 unsigned char *new_code)
56{
57 unsigned char replaced[MCOUNT_INSN_SIZE];
58
59 /*
60 * Note: Due to modules and __init, code can
61 * disappear and change, we need to protect against faulting
62 * as well as code changing. We do this by using the
63 * probe_kernel_* functions.
64 *
65 * No real locking needed, this code is run through
66 * kstop_machine, or before SMP starts.
67 */
68
69 /*
70 * If we're trying to nop out a call to a function, we instead
71 * place a call to the address after the memory table.
72 */
73 if (is_sh_nop(new_code) == 0)
74 __raw_writel(ip + MCOUNT_INSN_SIZE, (unsigned long)new_code);
75
76 /* read the text we want to modify */
77 if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
78 return -EFAULT;
79
80 /* Make sure it is what we expect it to be */
81 if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
82 return -EINVAL;
83
84 /* replace the text with the new text */
85 if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
86 return -EPERM;
87
88 flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
89
90 return 0;
91}
92
93int ftrace_update_ftrace_func(ftrace_func_t func)
94{
95 unsigned long ip = (unsigned long)(&ftrace_call);
96 unsigned char old[MCOUNT_INSN_SIZE], *new;
97
98 memcpy(old, (unsigned char *)(ip + MCOUNT_INSN_OFFSET), MCOUNT_INSN_SIZE);
99 new = ftrace_call_replace(ip, (unsigned long)func);
100
101 return ftrace_modify_code(ip + MCOUNT_INSN_OFFSET, old, new);
102}
103
104int ftrace_make_nop(struct module *mod,
105 struct dyn_ftrace *rec, unsigned long addr)
106{
107 unsigned char *new, *old;
108 unsigned long ip = rec->ip;
109
110 old = ftrace_call_replace(ip, addr);
111 new = ftrace_nop_replace();
112
113 return ftrace_modify_code(rec->ip, old, new);
114}
115
116int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
117{
118 unsigned char *new, *old;
119 unsigned long ip = rec->ip;
120
121 old = ftrace_nop_replace();
122 new = ftrace_call_replace(ip, addr);
123
124 return ftrace_modify_code(rec->ip, old, new);
125}
126
127int __init ftrace_dyn_arch_init(void *data)
128{
129 /* The return code is retured via data */
130 __raw_writel(0, (unsigned long)data);
131
132 return 0;
133}
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index ae0a382a82eb..788605ff7088 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -80,8 +80,14 @@ ENTRY(_stext)
80 mov.l 7f, r0 80 mov.l 7f, r0
81 ldc r0, r7_bank ! ... and initial thread_info 81 ldc r0, r7_bank ! ... and initial thread_info
82#endif 82#endif
83 83
84 ! Clear BSS area 84#ifndef CONFIG_SH_NO_BSS_INIT
85 /*
86 * Don't clear BSS if running on slow platforms such as an RTL simulation,
87 * remote memory via SHdebug link, etc. For these the memory can be guaranteed
88 * to be all zero on boot anyway.
89 */
90 ! Clear BSS area
85#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
86 mov.l 3f, r0 92 mov.l 3f, r0
87 cmp/eq #0, r0 ! skip clear if set to zero 93 cmp/eq #0, r0 ! skip clear if set to zero
@@ -97,6 +103,8 @@ ENTRY(_stext)
97 mov.l r0,@-r2 103 mov.l r0,@-r2
98 104
9910: 10510:
106#endif
107
100 ! Additional CPU initialization 108 ! Additional CPU initialization
101 mov.l 6f, r0 109 mov.l 6f, r0
102 jsr @r0 110 jsr @r0
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
new file mode 100644
index 000000000000..fe59ccfc1152
--- /dev/null
+++ b/arch/sh/kernel/idle.c
@@ -0,0 +1,81 @@
1/*
2 * The idle loop for all SuperH platforms.
3 *
4 * Copyright (C) 2002 - 2008 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/mm.h>
13#include <linux/pm.h>
14#include <linux/tick.h>
15#include <linux/preempt.h>
16#include <linux/thread_info.h>
17#include <linux/irqflags.h>
18#include <asm/pgalloc.h>
19#include <asm/system.h>
20#include <asm/atomic.h>
21
22static int hlt_counter;
23void (*pm_idle)(void);
24void (*pm_power_off)(void);
25EXPORT_SYMBOL(pm_power_off);
26
27static int __init nohlt_setup(char *__unused)
28{
29 hlt_counter = 1;
30 return 1;
31}
32__setup("nohlt", nohlt_setup);
33
34static int __init hlt_setup(char *__unused)
35{
36 hlt_counter = 0;
37 return 1;
38}
39__setup("hlt", hlt_setup);
40
41static void default_idle(void)
42{
43 if (!hlt_counter) {
44 clear_thread_flag(TIF_POLLING_NRFLAG);
45 smp_mb__after_clear_bit();
46 set_bl_bit();
47 stop_critical_timings();
48
49 while (!need_resched())
50 cpu_sleep();
51
52 start_critical_timings();
53 clear_bl_bit();
54 set_thread_flag(TIF_POLLING_NRFLAG);
55 } else
56 while (!need_resched())
57 cpu_relax();
58}
59
60void cpu_idle(void)
61{
62 set_thread_flag(TIF_POLLING_NRFLAG);
63
64 /* endless idle loop with no priority at all */
65 while (1) {
66 void (*idle)(void) = pm_idle;
67
68 if (!idle)
69 idle = default_idle;
70
71 tick_nohz_stop_sched_tick(1);
72 while (!need_resched())
73 idle();
74 tick_nohz_restart_sched_tick();
75
76 preempt_enable_no_resched();
77 schedule();
78 preempt_disable();
79 check_pgt_cache();
80 }
81}
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
new file mode 100644
index 000000000000..7c747e7d71b8
--- /dev/null
+++ b/arch/sh/kernel/kgdb.c
@@ -0,0 +1,285 @@
1/*
2 * SuperH KGDB support
3 *
4 * Copyright (C) 2008 Paul Mundt
5 *
6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/kgdb.h>
13#include <linux/kdebug.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <asm/cacheflush.h>
17
18char in_nmi = 0; /* Set during NMI to prevent re-entry */
19
20/* Macros for single step instruction identification */
21#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
22#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
23#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
24 (((op) & 0x7f ) << 1))
25#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
26#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
27#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
28#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
29 (((op) & 0x7ff) << 1))
30#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
31#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
32#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
33#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
34 (((op) & 0x7ff) << 1))
35#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
36#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
37#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
38#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
39#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
40#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
41#define OPCODE_RTS(op) ((op) == 0xb)
42#define OPCODE_RTE(op) ((op) == 0x2b)
43
44#define SR_T_BIT_MASK 0x1
45#define STEP_OPCODE 0xc33d
46
47/* Calculate the new address for after a step */
48static short *get_step_address(struct pt_regs *linux_regs)
49{
50 opcode_t op = __raw_readw(linux_regs->pc);
51 long addr;
52
53 /* BT */
54 if (OPCODE_BT(op)) {
55 if (linux_regs->sr & SR_T_BIT_MASK)
56 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
57 else
58 addr = linux_regs->pc + 2;
59 }
60
61 /* BTS */
62 else if (OPCODE_BTS(op)) {
63 if (linux_regs->sr & SR_T_BIT_MASK)
64 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
65 else
66 addr = linux_regs->pc + 4; /* Not in delay slot */
67 }
68
69 /* BF */
70 else if (OPCODE_BF(op)) {
71 if (!(linux_regs->sr & SR_T_BIT_MASK))
72 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
73 else
74 addr = linux_regs->pc + 2;
75 }
76
77 /* BFS */
78 else if (OPCODE_BFS(op)) {
79 if (!(linux_regs->sr & SR_T_BIT_MASK))
80 addr = linux_regs->pc + 4 + OPCODE_BTF_DISP(op);
81 else
82 addr = linux_regs->pc + 4; /* Not in delay slot */
83 }
84
85 /* BRA */
86 else if (OPCODE_BRA(op))
87 addr = linux_regs->pc + 4 + OPCODE_BRA_DISP(op);
88
89 /* BRAF */
90 else if (OPCODE_BRAF(op))
91 addr = linux_regs->pc + 4
92 + linux_regs->regs[OPCODE_BRAF_REG(op)];
93
94 /* BSR */
95 else if (OPCODE_BSR(op))
96 addr = linux_regs->pc + 4 + OPCODE_BSR_DISP(op);
97
98 /* BSRF */
99 else if (OPCODE_BSRF(op))
100 addr = linux_regs->pc + 4
101 + linux_regs->regs[OPCODE_BSRF_REG(op)];
102
103 /* JMP */
104 else if (OPCODE_JMP(op))
105 addr = linux_regs->regs[OPCODE_JMP_REG(op)];
106
107 /* JSR */
108 else if (OPCODE_JSR(op))
109 addr = linux_regs->regs[OPCODE_JSR_REG(op)];
110
111 /* RTS */
112 else if (OPCODE_RTS(op))
113 addr = linux_regs->pr;
114
115 /* RTE */
116 else if (OPCODE_RTE(op))
117 addr = linux_regs->regs[15];
118
119 /* Other */
120 else
121 addr = linux_regs->pc + instruction_size(op);
122
123 flush_icache_range(addr, addr + instruction_size(op));
124 return (short *)addr;
125}
126
127/*
128 * Replace the instruction immediately after the current instruction
129 * (i.e. next in the expected flow of control) with a trap instruction,
130 * so that returning will cause only a single instruction to be executed.
131 * Note that this model is slightly broken for instructions with delay
132 * slots (e.g. B[TF]S, BSR, BRA etc), where both the branch and the
133 * instruction in the delay slot will be executed.
134 */
135
136static unsigned long stepped_address;
137static opcode_t stepped_opcode;
138
139static void do_single_step(struct pt_regs *linux_regs)
140{
141 /* Determine where the target instruction will send us to */
142 unsigned short *addr = get_step_address(linux_regs);
143
144 stepped_address = (int)addr;
145
146 /* Replace it */
147 stepped_opcode = __raw_readw((long)addr);
148 *addr = STEP_OPCODE;
149
150 /* Flush and return */
151 flush_icache_range((long)addr, (long)addr +
152 instruction_size(stepped_opcode));
153}
154
155/* Undo a single step */
156static void undo_single_step(struct pt_regs *linux_regs)
157{
158 /* If we have stepped, put back the old instruction */
159 /* Use stepped_address in case we stopped elsewhere */
160 if (stepped_opcode != 0) {
161 __raw_writew(stepped_opcode, stepped_address);
162 flush_icache_range(stepped_address, stepped_address + 2);
163 }
164
165 stepped_opcode = 0;
166}
167
168void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
169{
170 int i;
171
172 for (i = 0; i < 16; i++)
173 gdb_regs[GDB_R0 + i] = regs->regs[i];
174
175 gdb_regs[GDB_PC] = regs->pc;
176 gdb_regs[GDB_PR] = regs->pr;
177 gdb_regs[GDB_SR] = regs->sr;
178 gdb_regs[GDB_GBR] = regs->gbr;
179 gdb_regs[GDB_MACH] = regs->mach;
180 gdb_regs[GDB_MACL] = regs->macl;
181
182 __asm__ __volatile__ ("stc vbr, %0" : "=r" (gdb_regs[GDB_VBR]));
183}
184
185void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
186{
187 int i;
188
189 for (i = 0; i < 16; i++)
190 regs->regs[GDB_R0 + i] = gdb_regs[GDB_R0 + i];
191
192 regs->pc = gdb_regs[GDB_PC];
193 regs->pr = gdb_regs[GDB_PR];
194 regs->sr = gdb_regs[GDB_SR];
195 regs->gbr = gdb_regs[GDB_GBR];
196 regs->mach = gdb_regs[GDB_MACH];
197 regs->macl = gdb_regs[GDB_MACL];
198
199 __asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
200}
201
202void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
203{
204 gdb_regs[GDB_R15] = p->thread.sp;
205 gdb_regs[GDB_PC] = p->thread.pc;
206}
207
208int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
209 char *remcomInBuffer, char *remcomOutBuffer,
210 struct pt_regs *linux_regs)
211{
212 unsigned long addr;
213 char *ptr;
214
215 /* Undo any stepping we may have done */
216 undo_single_step(linux_regs);
217
218 switch (remcomInBuffer[0]) {
219 case 'c':
220 case 's':
221 /* try to read optional parameter, pc unchanged if no parm */
222 ptr = &remcomInBuffer[1];
223 if (kgdb_hex2long(&ptr, &addr))
224 linux_regs->pc = addr;
225 case 'D':
226 case 'k':
227 atomic_set(&kgdb_cpu_doing_single_step, -1);
228
229 if (remcomInBuffer[0] == 's') {
230 do_single_step(linux_regs);
231 kgdb_single_step = 1;
232
233 atomic_set(&kgdb_cpu_doing_single_step,
234 raw_smp_processor_id());
235 }
236
237 return 0;
238 }
239
240 /* this means that we do not want to exit from the handler: */
241 return -1;
242}
243
244/*
245 * The primary entry points for the kgdb debug trap table entries.
246 */
247BUILD_TRAP_HANDLER(singlestep)
248{
249 unsigned long flags;
250 TRAP_HANDLER_DECL;
251
252 local_irq_save(flags);
253 regs->pc -= instruction_size(__raw_readw(regs->pc - 4));
254 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
255 local_irq_restore(flags);
256}
257
258
259BUILD_TRAP_HANDLER(breakpoint)
260{
261 unsigned long flags;
262 TRAP_HANDLER_DECL;
263
264 local_irq_save(flags);
265 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs);
266 local_irq_restore(flags);
267}
268
269int kgdb_arch_init(void)
270{
271 return 0;
272}
273
274void kgdb_arch_exit(void)
275{
276}
277
278struct kgdb_arch arch_kgdb_ops = {
279 /* Breakpoint instruction: trapa #0x3c */
280#ifdef CONFIG_CPU_LITTLE_ENDIAN
281 .gdb_bpt_instr = { 0x3c, 0xc3 },
282#else
283 .gdb_bpt_instr = { 0xc3, 0x3c },
284#endif
285};
diff --git a/arch/sh/kernel/kgdb_jmp.S b/arch/sh/kernel/kgdb_jmp.S
deleted file mode 100644
index 339bb1d7ff0b..000000000000
--- a/arch/sh/kernel/kgdb_jmp.S
+++ /dev/null
@@ -1,33 +0,0 @@
1#include <linux/linkage.h>
2
3ENTRY(setjmp)
4 add #(9*4), r4
5 sts.l pr, @-r4
6 mov.l r15, @-r4
7 mov.l r14, @-r4
8 mov.l r13, @-r4
9 mov.l r12, @-r4
10 mov.l r11, @-r4
11 mov.l r10, @-r4
12 mov.l r9, @-r4
13 mov.l r8, @-r4
14 rts
15 mov #0, r0
16
17ENTRY(longjmp)
18 mov.l @r4+, r8
19 mov.l @r4+, r9
20 mov.l @r4+, r10
21 mov.l @r4+, r11
22 mov.l @r4+, r12
23 mov.l @r4+, r13
24 mov.l @r4+, r14
25 mov.l @r4+, r15
26 lds.l @r4+, pr
27 mov r5, r0
28 tst r0, r0
29 bf 1f
30 mov #1, r0 ! in case val==0
311: rts
32 nop
33
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
deleted file mode 100644
index bf8ac4c71640..000000000000
--- a/arch/sh/kernel/kgdb_stub.c
+++ /dev/null
@@ -1,1052 +0,0 @@
1/*
2 * May be copied or modified under the terms of the GNU General Public
3 * License. See linux/COPYING for more information.
4 *
5 * Contains extracts from code by Glenn Engel, Jim Kingdon,
6 * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
7 * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
8 * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
9 *
10 * This version by Henry Bell <henry.bell@st.com>
11 * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
12 *
13 * Contains low-level support for remote debug using GDB.
14 *
15 * To enable debugger support, two things need to happen. A call to
16 * set_debug_traps() is necessary in order to allow any breakpoints
17 * or error conditions to be properly intercepted and reported to gdb.
18 * A breakpoint also needs to be generated to begin communication. This
19 * is most easily accomplished by a call to breakpoint() which does
20 * a trapa if the initialisation phase has been successfully completed.
21 *
22 * In this case, set_debug_traps() is not used to "take over" exceptions;
23 * other kernel code is modified instead to enter the kgdb functions here
24 * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
25 * see traps.c for kernel error exceptions).
26 *
27 * The following gdb commands are supported:
28 *
29 * Command Function Return value
30 *
31 * g return the value of the CPU registers hex data or ENN
32 * G set the value of the CPU registers OK or ENN
33 *
34 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
35 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
36 * XAA..AA,LLLL: Same, but data is binary (not hex) OK or ENN
37 *
38 * c Resume at current address SNN ( signal NN)
39 * cAA..AA Continue at address AA..AA SNN
40 * CNN; Resume at current address with signal SNN
41 * CNN;AA..AA Resume at address AA..AA with signal SNN
42 *
43 * s Step one instruction SNN
44 * sAA..AA Step one instruction from AA..AA SNN
45 * SNN; Step one instruction with signal SNN
46 * SNNAA..AA Step one instruction from AA..AA w/NN SNN
47 *
48 * k kill (Detach GDB)
49 *
50 * d Toggle debug flag
51 * D Detach GDB
52 *
53 * Hct Set thread t for operations, OK or ENN
54 * c = 'c' (step, cont), c = 'g' (other
55 * operations)
56 *
57 * qC Query current thread ID QCpid
58 * qfThreadInfo Get list of current threads (first) m<id>
59 * qsThreadInfo " " " " " (subsequent)
60 * qOffsets Get section offsets Text=x;Data=y;Bss=z
61 *
62 * TXX Find if thread XX is alive OK or ENN
63 * ? What was the last sigval ? SNN (signal NN)
64 * O Output to GDB console
65 *
66 * Remote communication protocol.
67 *
68 * A debug packet whose contents are <data> is encapsulated for
69 * transmission in the form:
70 *
71 * $ <data> # CSUM1 CSUM2
72 *
73 * <data> must be ASCII alphanumeric and cannot include characters
74 * '$' or '#'. If <data> starts with two characters followed by
75 * ':', then the existing stubs interpret this as a sequence number.
76 *
77 * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
78 * checksum of <data>, the most significant nibble is sent first.
79 * the hex digits 0-9,a-f are used.
80 *
81 * Receiver responds with:
82 *
83 * + - if CSUM is correct and ready for next packet
84 * - - if CSUM is incorrect
85 *
86 * Responses can be run-length encoded to save space. A '*' means that
87 * the next character is an ASCII encoding giving a repeat count which
88 * stands for that many repetitions of the character preceding the '*'.
89 * The encoding is n+29, yielding a printable character where n >=3
90 * (which is where RLE starts to win). Don't use an n > 126.
91 *
92 * So "0* " means the same as "0000".
93 */
94
95#include <linux/string.h>
96#include <linux/kernel.h>
97#include <linux/sched.h>
98#include <linux/smp.h>
99#include <linux/spinlock.h>
100#include <linux/delay.h>
101#include <linux/linkage.h>
102#include <linux/init.h>
103#include <linux/console.h>
104#include <linux/sysrq.h>
105#include <linux/module.h>
106#include <asm/system.h>
107#include <asm/cacheflush.h>
108#include <asm/current.h>
109#include <asm/signal.h>
110#include <asm/pgtable.h>
111#include <asm/ptrace.h>
112#include <asm/kgdb.h>
113#include <asm/io.h>
114
115/* Function pointers for linkage */
116kgdb_debug_hook_t *kgdb_debug_hook;
117kgdb_bus_error_hook_t *kgdb_bus_err_hook;
118
119int (*kgdb_getchar)(void);
120EXPORT_SYMBOL_GPL(kgdb_getchar);
121void (*kgdb_putchar)(int);
122EXPORT_SYMBOL_GPL(kgdb_putchar);
123
124static void put_debug_char(int c)
125{
126 if (!kgdb_putchar)
127 return;
128 (*kgdb_putchar)(c);
129}
130static int get_debug_char(void)
131{
132 if (!kgdb_getchar)
133 return -1;
134 return (*kgdb_getchar)();
135}
136
137/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
138#define BUFMAX 1024
139#define NUMREGBYTES (MAXREG*4)
140#define OUTBUFMAX (NUMREGBYTES*2+512)
141
142enum {
143 R0 = 0, R1, R2, R3, R4, R5, R6, R7,
144 R8, R9, R10, R11, R12, R13, R14, R15,
145 PC, PR, GBR, VBR, MACH, MACL, SR,
146 /* */
147 MAXREG
148};
149
150static unsigned int registers[MAXREG];
151struct kgdb_regs trap_registers;
152
153char kgdb_in_gdb_mode;
154char in_nmi; /* Set during NMI to prevent reentry */
155int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
156
157/* Default values for SCI (can override via kernel args in setup.c) */
158#ifndef CONFIG_KGDB_DEFPORT
159#define CONFIG_KGDB_DEFPORT 1
160#endif
161
162#ifndef CONFIG_KGDB_DEFBAUD
163#define CONFIG_KGDB_DEFBAUD 115200
164#endif
165
166#if defined(CONFIG_KGDB_DEFPARITY_E)
167#define CONFIG_KGDB_DEFPARITY 'E'
168#elif defined(CONFIG_KGDB_DEFPARITY_O)
169#define CONFIG_KGDB_DEFPARITY 'O'
170#else /* CONFIG_KGDB_DEFPARITY_N */
171#define CONFIG_KGDB_DEFPARITY 'N'
172#endif
173
174#ifdef CONFIG_KGDB_DEFBITS_7
175#define CONFIG_KGDB_DEFBITS '7'
176#else /* CONFIG_KGDB_DEFBITS_8 */
177#define CONFIG_KGDB_DEFBITS '8'
178#endif
179
180/* SCI/UART settings, used in kgdb_console_setup() */
181int kgdb_portnum = CONFIG_KGDB_DEFPORT;
182EXPORT_SYMBOL_GPL(kgdb_portnum);
183int kgdb_baud = CONFIG_KGDB_DEFBAUD;
184EXPORT_SYMBOL_GPL(kgdb_baud);
185char kgdb_parity = CONFIG_KGDB_DEFPARITY;
186EXPORT_SYMBOL_GPL(kgdb_parity);
187char kgdb_bits = CONFIG_KGDB_DEFBITS;
188EXPORT_SYMBOL_GPL(kgdb_bits);
189
190/* Jump buffer for setjmp/longjmp */
191static jmp_buf rem_com_env;
192
193/* TRA differs sh3/4 */
194#if defined(CONFIG_CPU_SH3)
195#define TRA 0xffffffd0
196#elif defined(CONFIG_CPU_SH4)
197#define TRA 0xff000020
198#endif
199
200/* Macros for single step instruction identification */
201#define OPCODE_BT(op) (((op) & 0xff00) == 0x8900)
202#define OPCODE_BF(op) (((op) & 0xff00) == 0x8b00)
203#define OPCODE_BTF_DISP(op) (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
204 (((op) & 0x7f ) << 1))
205#define OPCODE_BFS(op) (((op) & 0xff00) == 0x8f00)
206#define OPCODE_BTS(op) (((op) & 0xff00) == 0x8d00)
207#define OPCODE_BRA(op) (((op) & 0xf000) == 0xa000)
208#define OPCODE_BRA_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
209 (((op) & 0x7ff) << 1))
210#define OPCODE_BRAF(op) (((op) & 0xf0ff) == 0x0023)
211#define OPCODE_BRAF_REG(op) (((op) & 0x0f00) >> 8)
212#define OPCODE_BSR(op) (((op) & 0xf000) == 0xb000)
213#define OPCODE_BSR_DISP(op) (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
214 (((op) & 0x7ff) << 1))
215#define OPCODE_BSRF(op) (((op) & 0xf0ff) == 0x0003)
216#define OPCODE_BSRF_REG(op) (((op) >> 8) & 0xf)
217#define OPCODE_JMP(op) (((op) & 0xf0ff) == 0x402b)
218#define OPCODE_JMP_REG(op) (((op) >> 8) & 0xf)
219#define OPCODE_JSR(op) (((op) & 0xf0ff) == 0x400b)
220#define OPCODE_JSR_REG(op) (((op) >> 8) & 0xf)
221#define OPCODE_RTS(op) ((op) == 0xb)
222#define OPCODE_RTE(op) ((op) == 0x2b)
223
224#define SR_T_BIT_MASK 0x1
225#define STEP_OPCODE 0xc320
226#define BIOS_CALL_TRAP 0x3f
227
228/* Exception codes as per SH-4 core manual */
229#define ADDRESS_ERROR_LOAD_VEC 7
230#define ADDRESS_ERROR_STORE_VEC 8
231#define TRAP_VEC 11
232#define INVALID_INSN_VEC 12
233#define INVALID_SLOT_VEC 13
234#define NMI_VEC 14
235#define USER_BREAK_VEC 15
236#define SERIAL_BREAK_VEC 58
237
238/* Misc static */
239static int stepped_address;
240static short stepped_opcode;
241static char in_buffer[BUFMAX];
242static char out_buffer[OUTBUFMAX];
243
244static void kgdb_to_gdb(const char *s);
245
246/* Convert ch to hex */
247static int hex(const char ch)
248{
249 if ((ch >= 'a') && (ch <= 'f'))
250 return (ch - 'a' + 10);
251 if ((ch >= '0') && (ch <= '9'))
252 return (ch - '0');
253 if ((ch >= 'A') && (ch <= 'F'))
254 return (ch - 'A' + 10);
255 return (-1);
256}
257
258/* Convert the memory pointed to by mem into hex, placing result in buf.
259 Returns a pointer to the last char put in buf (null) */
260static char *mem_to_hex(const char *mem, char *buf, const int count)
261{
262 int i;
263 int ch;
264 unsigned short s_val;
265 unsigned long l_val;
266
267 /* Check for 16 or 32 */
268 if (count == 2 && ((long) mem & 1) == 0) {
269 s_val = *(unsigned short *) mem;
270 mem = (char *) &s_val;
271 } else if (count == 4 && ((long) mem & 3) == 0) {
272 l_val = *(unsigned long *) mem;
273 mem = (char *) &l_val;
274 }
275 for (i = 0; i < count; i++) {
276 ch = *mem++;
277 buf = pack_hex_byte(buf, ch);
278 }
279 *buf = 0;
280 return (buf);
281}
282
283/* Convert the hex array pointed to by buf into binary, to be placed in mem.
284 Return a pointer to the character after the last byte written */
285static char *hex_to_mem(const char *buf, char *mem, const int count)
286{
287 int i;
288 unsigned char ch;
289
290 for (i = 0; i < count; i++) {
291 ch = hex(*buf++) << 4;
292 ch = ch + hex(*buf++);
293 *mem++ = ch;
294 }
295 return (mem);
296}
297
298/* While finding valid hex chars, convert to an integer, then return it */
299static int hex_to_int(char **ptr, int *int_value)
300{
301 int num_chars = 0;
302 int hex_value;
303
304 *int_value = 0;
305
306 while (**ptr) {
307 hex_value = hex(**ptr);
308 if (hex_value >= 0) {
309 *int_value = (*int_value << 4) | hex_value;
310 num_chars++;
311 } else
312 break;
313 (*ptr)++;
314 }
315 return num_chars;
316}
317
318/* Copy the binary array pointed to by buf into mem. Fix $, #,
319 and 0x7d escaped with 0x7d. Return a pointer to the character
320 after the last byte written. */
321static char *ebin_to_mem(const char *buf, char *mem, int count)
322{
323 for (; count > 0; count--, buf++) {
324 if (*buf == 0x7d)
325 *mem++ = *(++buf) ^ 0x20;
326 else
327 *mem++ = *buf;
328 }
329 return mem;
330}
331
332/* Scan for the start char '$', read the packet and check the checksum */
333static void get_packet(char *buffer, int buflen)
334{
335 unsigned char checksum;
336 unsigned char xmitcsum;
337 int i;
338 int count;
339 char ch;
340
341 do {
342 /* Ignore everything until the start character */
343 while ((ch = get_debug_char()) != '$');
344
345 checksum = 0;
346 xmitcsum = -1;
347 count = 0;
348
349 /* Now, read until a # or end of buffer is found */
350 while (count < (buflen - 1)) {
351 ch = get_debug_char();
352
353 if (ch == '#')
354 break;
355
356 checksum = checksum + ch;
357 buffer[count] = ch;
358 count = count + 1;
359 }
360
361 buffer[count] = 0;
362
363 /* Continue to read checksum following # */
364 if (ch == '#') {
365 xmitcsum = hex(get_debug_char()) << 4;
366 xmitcsum += hex(get_debug_char());
367
368 /* Checksum */
369 if (checksum != xmitcsum)
370 put_debug_char('-'); /* Failed checksum */
371 else {
372 /* Ack successful transfer */
373 put_debug_char('+');
374
375 /* If a sequence char is present, reply
376 the sequence ID */
377 if (buffer[2] == ':') {
378 put_debug_char(buffer[0]);
379 put_debug_char(buffer[1]);
380
381 /* Remove sequence chars from buffer */
382 count = strlen(buffer);
383 for (i = 3; i <= count; i++)
384 buffer[i - 3] = buffer[i];
385 }
386 }
387 }
388 }
389 while (checksum != xmitcsum); /* Keep trying while we fail */
390}
391
392/* Send the packet in the buffer with run-length encoding */
393static void put_packet(char *buffer)
394{
395 int checksum;
396 char *src;
397 int runlen;
398 int encode;
399
400 do {
401 src = buffer;
402 put_debug_char('$');
403 checksum = 0;
404
405 /* Continue while we still have chars left */
406 while (*src) {
407 /* Check for runs up to 99 chars long */
408 for (runlen = 1; runlen < 99; runlen++) {
409 if (src[0] != src[runlen])
410 break;
411 }
412
413 if (runlen > 3) {
414 /* Got a useful amount, send encoding */
415 encode = runlen + ' ' - 4;
416 put_debug_char(*src); checksum += *src;
417 put_debug_char('*'); checksum += '*';
418 put_debug_char(encode); checksum += encode;
419 src += runlen;
420 } else {
421 /* Otherwise just send the current char */
422 put_debug_char(*src); checksum += *src;
423 src += 1;
424 }
425 }
426
427 /* '#' Separator, put high and low components of checksum */
428 put_debug_char('#');
429 put_debug_char(hex_asc_hi(checksum));
430 put_debug_char(hex_asc_lo(checksum));
431 }
432 while ((get_debug_char()) != '+'); /* While no ack */
433}
434
435/* A bus error has occurred - perform a longjmp to return execution and
436 allow handling of the error */
437static void kgdb_handle_bus_error(void)
438{
439 longjmp(rem_com_env, 1);
440}
441
442/* Translate SH-3/4 exception numbers to unix-like signal values */
443static int compute_signal(const int excep_code)
444{
445 int sigval;
446
447 switch (excep_code) {
448
449 case INVALID_INSN_VEC:
450 case INVALID_SLOT_VEC:
451 sigval = SIGILL;
452 break;
453 case ADDRESS_ERROR_LOAD_VEC:
454 case ADDRESS_ERROR_STORE_VEC:
455 sigval = SIGSEGV;
456 break;
457
458 case SERIAL_BREAK_VEC:
459 case NMI_VEC:
460 sigval = SIGINT;
461 break;
462
463 case USER_BREAK_VEC:
464 case TRAP_VEC:
465 sigval = SIGTRAP;
466 break;
467
468 default:
469 sigval = SIGBUS; /* "software generated" */
470 break;
471 }
472
473 return (sigval);
474}
475
476/* Make a local copy of the registers passed into the handler (bletch) */
477static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
478 int *gdb_regs)
479{
480 gdb_regs[R0] = regs->regs[R0];
481 gdb_regs[R1] = regs->regs[R1];
482 gdb_regs[R2] = regs->regs[R2];
483 gdb_regs[R3] = regs->regs[R3];
484 gdb_regs[R4] = regs->regs[R4];
485 gdb_regs[R5] = regs->regs[R5];
486 gdb_regs[R6] = regs->regs[R6];
487 gdb_regs[R7] = regs->regs[R7];
488 gdb_regs[R8] = regs->regs[R8];
489 gdb_regs[R9] = regs->regs[R9];
490 gdb_regs[R10] = regs->regs[R10];
491 gdb_regs[R11] = regs->regs[R11];
492 gdb_regs[R12] = regs->regs[R12];
493 gdb_regs[R13] = regs->regs[R13];
494 gdb_regs[R14] = regs->regs[R14];
495 gdb_regs[R15] = regs->regs[R15];
496 gdb_regs[PC] = regs->pc;
497 gdb_regs[PR] = regs->pr;
498 gdb_regs[GBR] = regs->gbr;
499 gdb_regs[MACH] = regs->mach;
500 gdb_regs[MACL] = regs->macl;
501 gdb_regs[SR] = regs->sr;
502 gdb_regs[VBR] = regs->vbr;
503}
504
505/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
506static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
507 struct kgdb_regs *regs)
508{
509 regs->regs[R0] = gdb_regs[R0];
510 regs->regs[R1] = gdb_regs[R1];
511 regs->regs[R2] = gdb_regs[R2];
512 regs->regs[R3] = gdb_regs[R3];
513 regs->regs[R4] = gdb_regs[R4];
514 regs->regs[R5] = gdb_regs[R5];
515 regs->regs[R6] = gdb_regs[R6];
516 regs->regs[R7] = gdb_regs[R7];
517 regs->regs[R8] = gdb_regs[R8];
518 regs->regs[R9] = gdb_regs[R9];
519 regs->regs[R10] = gdb_regs[R10];
520 regs->regs[R11] = gdb_regs[R11];
521 regs->regs[R12] = gdb_regs[R12];
522 regs->regs[R13] = gdb_regs[R13];
523 regs->regs[R14] = gdb_regs[R14];
524 regs->regs[R15] = gdb_regs[R15];
525 regs->pc = gdb_regs[PC];
526 regs->pr = gdb_regs[PR];
527 regs->gbr = gdb_regs[GBR];
528 regs->mach = gdb_regs[MACH];
529 regs->macl = gdb_regs[MACL];
530 regs->sr = gdb_regs[SR];
531 regs->vbr = gdb_regs[VBR];
532}
533
534/* Calculate the new address for after a step */
535static short *get_step_address(void)
536{
537 short op = *(short *) trap_registers.pc;
538 long addr;
539
540 /* BT */
541 if (OPCODE_BT(op)) {
542 if (trap_registers.sr & SR_T_BIT_MASK)
543 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
544 else
545 addr = trap_registers.pc + 2;
546 }
547
548 /* BTS */
549 else if (OPCODE_BTS(op)) {
550 if (trap_registers.sr & SR_T_BIT_MASK)
551 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
552 else
553 addr = trap_registers.pc + 4; /* Not in delay slot */
554 }
555
556 /* BF */
557 else if (OPCODE_BF(op)) {
558 if (!(trap_registers.sr & SR_T_BIT_MASK))
559 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
560 else
561 addr = trap_registers.pc + 2;
562 }
563
564 /* BFS */
565 else if (OPCODE_BFS(op)) {
566 if (!(trap_registers.sr & SR_T_BIT_MASK))
567 addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
568 else
569 addr = trap_registers.pc + 4; /* Not in delay slot */
570 }
571
572 /* BRA */
573 else if (OPCODE_BRA(op))
574 addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
575
576 /* BRAF */
577 else if (OPCODE_BRAF(op))
578 addr = trap_registers.pc + 4
579 + trap_registers.regs[OPCODE_BRAF_REG(op)];
580
581 /* BSR */
582 else if (OPCODE_BSR(op))
583 addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
584
585 /* BSRF */
586 else if (OPCODE_BSRF(op))
587 addr = trap_registers.pc + 4
588 + trap_registers.regs[OPCODE_BSRF_REG(op)];
589
590 /* JMP */
591 else if (OPCODE_JMP(op))
592 addr = trap_registers.regs[OPCODE_JMP_REG(op)];
593
594 /* JSR */
595 else if (OPCODE_JSR(op))
596 addr = trap_registers.regs[OPCODE_JSR_REG(op)];
597
598 /* RTS */
599 else if (OPCODE_RTS(op))
600 addr = trap_registers.pr;
601
602 /* RTE */
603 else if (OPCODE_RTE(op))
604 addr = trap_registers.regs[15];
605
606 /* Other */
607 else
608 addr = trap_registers.pc + 2;
609
610 flush_icache_range(addr, addr + 2);
611 return (short *) addr;
612}
613
614/* Set up a single-step. Replace the instruction immediately after the
615 current instruction (i.e. next in the expected flow of control) with a
616 trap instruction, so that returning will cause only a single instruction
617 to be executed. Note that this model is slightly broken for instructions
618 with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
619 and the instruction in the delay slot will be executed. */
620static void do_single_step(void)
621{
622 unsigned short *addr = 0;
623
624 /* Determine where the target instruction will send us to */
625 addr = get_step_address();
626 stepped_address = (int)addr;
627
628 /* Replace it */
629 stepped_opcode = *(short *)addr;
630 *addr = STEP_OPCODE;
631
632 /* Flush and return */
633 flush_icache_range((long) addr, (long) addr + 2);
634}
635
636/* Undo a single step */
637static void undo_single_step(void)
638{
639 /* If we have stepped, put back the old instruction */
640 /* Use stepped_address in case we stopped elsewhere */
641 if (stepped_opcode != 0) {
642 *(short*)stepped_address = stepped_opcode;
643 flush_icache_range(stepped_address, stepped_address + 2);
644 }
645 stepped_opcode = 0;
646}
647
648/* Send a signal message */
649static void send_signal_msg(const int signum)
650{
651 out_buffer[0] = 'S';
652 out_buffer[1] = hex_asc_hi(signum);
653 out_buffer[2] = hex_asc_lo(signum);
654 out_buffer[3] = 0;
655 put_packet(out_buffer);
656}
657
658/* Reply that all was well */
659static void send_ok_msg(void)
660{
661 strcpy(out_buffer, "OK");
662 put_packet(out_buffer);
663}
664
665/* Reply that an error occurred */
666static void send_err_msg(void)
667{
668 strcpy(out_buffer, "E01");
669 put_packet(out_buffer);
670}
671
672/* Empty message indicates unrecognised command */
673static void send_empty_msg(void)
674{
675 put_packet("");
676}
677
678/* Read memory due to 'm' message */
679static void read_mem_msg(void)
680{
681 char *ptr;
682 int addr;
683 int length;
684
685 /* Jmp, disable bus error handler */
686 if (setjmp(rem_com_env) == 0) {
687
688 kgdb_nofault = 1;
689
690 /* Walk through, have m<addr>,<length> */
691 ptr = &in_buffer[1];
692 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
693 if (hex_to_int(&ptr, &length)) {
694 ptr = 0;
695 if (length * 2 > OUTBUFMAX)
696 length = OUTBUFMAX / 2;
697 mem_to_hex((char *) addr, out_buffer, length);
698 }
699 if (ptr)
700 send_err_msg();
701 else
702 put_packet(out_buffer);
703 } else
704 send_err_msg();
705
706 /* Restore bus error handler */
707 kgdb_nofault = 0;
708}
709
710/* Write memory due to 'M' or 'X' message */
711static void write_mem_msg(int binary)
712{
713 char *ptr;
714 int addr;
715 int length;
716
717 if (setjmp(rem_com_env) == 0) {
718
719 kgdb_nofault = 1;
720
721 /* Walk through, have M<addr>,<length>:<data> */
722 ptr = &in_buffer[1];
723 if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
724 if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
725 if (binary)
726 ebin_to_mem(ptr, (char*)addr, length);
727 else
728 hex_to_mem(ptr, (char*)addr, length);
729 flush_icache_range(addr, addr + length);
730 ptr = 0;
731 send_ok_msg();
732 }
733 if (ptr)
734 send_err_msg();
735 } else
736 send_err_msg();
737
738 /* Restore bus error handler */
739 kgdb_nofault = 0;
740}
741
742/* Continue message */
743static void continue_msg(void)
744{
745 /* Try to read optional parameter, PC unchanged if none */
746 char *ptr = &in_buffer[1];
747 int addr;
748
749 if (hex_to_int(&ptr, &addr))
750 trap_registers.pc = addr;
751}
752
753/* Continue message with signal */
754static void continue_with_sig_msg(void)
755{
756 int signal;
757 char *ptr = &in_buffer[1];
758 int addr;
759
760 /* Report limitation */
761 kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
762
763 /* Signal */
764 hex_to_int(&ptr, &signal);
765 if (*ptr == ';')
766 ptr++;
767
768 /* Optional address */
769 if (hex_to_int(&ptr, &addr))
770 trap_registers.pc = addr;
771}
772
773/* Step message */
774static void step_msg(void)
775{
776 continue_msg();
777 do_single_step();
778}
779
780/* Step message with signal */
781static void step_with_sig_msg(void)
782{
783 continue_with_sig_msg();
784 do_single_step();
785}
786
787/* Send register contents */
788static void send_regs_msg(void)
789{
790 kgdb_regs_to_gdb_regs(&trap_registers, registers);
791 mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
792 put_packet(out_buffer);
793}
794
795/* Set register contents - currently can't set other thread's registers */
796static void set_regs_msg(void)
797{
798 kgdb_regs_to_gdb_regs(&trap_registers, registers);
799 hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
800 gdb_regs_to_kgdb_regs(registers, &trap_registers);
801 send_ok_msg();
802}
803
804#ifdef CONFIG_SH_KGDB_CONSOLE
805/*
806 * Bring up the ports..
807 */
808static int __init kgdb_serial_setup(void)
809{
810 struct console dummy;
811 return kgdb_console_setup(&dummy, 0);
812}
813#else
814#define kgdb_serial_setup() 0
815#endif
816
817/* The command loop, read and act on requests */
818static void kgdb_command_loop(const int excep_code, const int trapa_value)
819{
820 int sigval;
821
822 /* Enter GDB mode (e.g. after detach) */
823 if (!kgdb_in_gdb_mode) {
824 /* Do serial setup, notify user, issue preemptive ack */
825 printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
826 kgdb_in_gdb_mode = 1;
827 put_debug_char('+');
828 }
829
830 /* Reply to host that an exception has occurred */
831 sigval = compute_signal(excep_code);
832 send_signal_msg(sigval);
833
834 /* TRAP_VEC exception indicates a software trap inserted in place of
835 code by GDB so back up PC by one instruction, as this instruction
836 will later be replaced by its original one. Do NOT do this for
837 trap 0xff, since that indicates a compiled-in breakpoint which
838 will not be replaced (and we would retake the trap forever) */
839 if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
840 trap_registers.pc -= 2;
841
842 /* Undo any stepping we may have done */
843 undo_single_step();
844
845 while (1) {
846 out_buffer[0] = 0;
847 get_packet(in_buffer, BUFMAX);
848
849 /* Examine first char of buffer to see what we need to do */
850 switch (in_buffer[0]) {
851 case '?': /* Send which signal we've received */
852 send_signal_msg(sigval);
853 break;
854
855 case 'g': /* Return the values of the CPU registers */
856 send_regs_msg();
857 break;
858
859 case 'G': /* Set the value of the CPU registers */
860 set_regs_msg();
861 break;
862
863 case 'm': /* Read LLLL bytes address AA..AA */
864 read_mem_msg();
865 break;
866
867 case 'M': /* Write LLLL bytes address AA..AA, ret OK */
868 write_mem_msg(0); /* 0 = data in hex */
869 break;
870
871 case 'X': /* Write LLLL bytes esc bin address AA..AA */
872 if (kgdb_bits == '8')
873 write_mem_msg(1); /* 1 = data in binary */
874 else
875 send_empty_msg();
876 break;
877
878 case 'C': /* Continue, signum included, we ignore it */
879 continue_with_sig_msg();
880 return;
881
882 case 'c': /* Continue at address AA..AA (optional) */
883 continue_msg();
884 return;
885
886 case 'S': /* Step, signum included, we ignore it */
887 step_with_sig_msg();
888 return;
889
890 case 's': /* Step one instruction from AA..AA */
891 step_msg();
892 return;
893
894 case 'k': /* 'Kill the program' with a kernel ? */
895 break;
896
897 case 'D': /* Detach from program, send reply OK */
898 kgdb_in_gdb_mode = 0;
899 send_ok_msg();
900 get_debug_char();
901 return;
902
903 default:
904 send_empty_msg();
905 break;
906 }
907 }
908}
909
910/* There has been an exception, most likely a breakpoint. */
911static void handle_exception(struct pt_regs *regs)
912{
913 int excep_code, vbr_val;
914 int count;
915 int trapa_value = ctrl_inl(TRA);
916
917 /* Copy kernel regs (from stack) */
918 for (count = 0; count < 16; count++)
919 trap_registers.regs[count] = regs->regs[count];
920 trap_registers.pc = regs->pc;
921 trap_registers.pr = regs->pr;
922 trap_registers.sr = regs->sr;
923 trap_registers.gbr = regs->gbr;
924 trap_registers.mach = regs->mach;
925 trap_registers.macl = regs->macl;
926
927 asm("stc vbr, %0":"=r"(vbr_val));
928 trap_registers.vbr = vbr_val;
929
930 /* Get excode for command loop call, user access */
931 asm("stc r2_bank, %0":"=r"(excep_code));
932
933 /* Act on the exception */
934 kgdb_command_loop(excep_code, trapa_value);
935
936 /* Copy back the (maybe modified) registers */
937 for (count = 0; count < 16; count++)
938 regs->regs[count] = trap_registers.regs[count];
939 regs->pc = trap_registers.pc;
940 regs->pr = trap_registers.pr;
941 regs->sr = trap_registers.sr;
942 regs->gbr = trap_registers.gbr;
943 regs->mach = trap_registers.mach;
944 regs->macl = trap_registers.macl;
945
946 vbr_val = trap_registers.vbr;
947 asm("ldc %0, vbr": :"r"(vbr_val));
948}
949
950asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
951 unsigned long r6, unsigned long r7,
952 struct pt_regs __regs)
953{
954 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
955 handle_exception(regs);
956}
957
958/* Initialise the KGDB data structures and serial configuration */
959int __init kgdb_init(void)
960{
961 in_nmi = 0;
962 kgdb_nofault = 0;
963 stepped_opcode = 0;
964 kgdb_in_gdb_mode = 0;
965
966 if (kgdb_serial_setup() != 0) {
967 printk(KERN_NOTICE "KGDB: serial setup error\n");
968 return -1;
969 }
970
971 /* Init ptr to exception handler */
972 kgdb_debug_hook = handle_exception;
973 kgdb_bus_err_hook = kgdb_handle_bus_error;
974
975 /* Enter kgdb now if requested, or just report init done */
976 printk(KERN_NOTICE "KGDB: stub is initialized.\n");
977
978 return 0;
979}
980
981/* Make function available for "user messages"; console will use it too. */
982
983char gdbmsgbuf[BUFMAX];
984#define MAXOUT ((BUFMAX-2)/2)
985
986static void kgdb_msg_write(const char *s, unsigned count)
987{
988 int i;
989 int wcount;
990 char *bufptr;
991
992 /* 'O'utput */
993 gdbmsgbuf[0] = 'O';
994
995 /* Fill and send buffers... */
996 while (count > 0) {
997 bufptr = gdbmsgbuf + 1;
998
999 /* Calculate how many this time */
1000 wcount = (count > MAXOUT) ? MAXOUT : count;
1001
1002 /* Pack in hex chars */
1003 for (i = 0; i < wcount; i++)
1004 bufptr = pack_hex_byte(bufptr, s[i]);
1005 *bufptr = '\0';
1006
1007 /* Move up */
1008 s += wcount;
1009 count -= wcount;
1010
1011 /* Write packet */
1012 put_packet(gdbmsgbuf);
1013 }
1014}
1015
1016static void kgdb_to_gdb(const char *s)
1017{
1018 kgdb_msg_write(s, strlen(s));
1019}
1020
1021#ifdef CONFIG_SH_KGDB_CONSOLE
1022void kgdb_console_write(struct console *co, const char *s, unsigned count)
1023{
1024 /* Bail if we're not talking to GDB */
1025 if (!kgdb_in_gdb_mode)
1026 return;
1027
1028 kgdb_msg_write(s, count);
1029}
1030#endif
1031
1032#ifdef CONFIG_KGDB_SYSRQ
1033static void sysrq_handle_gdb(int key, struct tty_struct *tty)
1034{
1035 printk("Entering GDB stub\n");
1036 breakpoint();
1037}
1038
1039static struct sysrq_key_op sysrq_gdb_op = {
1040 .handler = sysrq_handle_gdb,
1041 .help_msg = "Gdb",
1042 .action_msg = "GDB",
1043};
1044
1045static int gdb_register_sysrq(void)
1046{
1047 printk("Registering GDB sysrq handler\n");
1048 register_sysrq_key('g', &sysrq_gdb_op);
1049 return 0;
1050}
1051module_init(gdb_register_sysrq);
1052#endif
diff --git a/arch/sh/kernel/pm.c b/arch/sh/kernel/pm.c
deleted file mode 100644
index 10ab62c9aede..000000000000
--- a/arch/sh/kernel/pm.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * Generic Power Management Routine
3 *
4 * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9#include <linux/suspend.h>
10#include <linux/delay.h>
11#include <linux/gfp.h>
12#include <asm/freq.h>
13#include <asm/io.h>
14#include <asm/watchdog.h>
15#include <asm/pm.h>
16
17#define INTR_OFFSET 0x600
18
19#define STBCR 0xffffff82
20#define STBCR2 0xffffff88
21
22#define STBCR_STBY 0x80
23#define STBCR_MSTP2 0x04
24
25#define MCR 0xffffff68
26#define RTCNT 0xffffff70
27
28#define MCR_RMODE 2
29#define MCR_RFSH 4
30
31void pm_enter(void)
32{
33 u8 stbcr, csr;
34 u16 frqcr, mcr;
35 u32 vbr_new, vbr_old;
36
37 set_bl_bit();
38
39 /* set wdt */
40 csr = sh_wdt_read_csr();
41 csr &= ~WTCSR_TME;
42 csr |= WTCSR_CKS_4096;
43 sh_wdt_write_csr(csr);
44 csr = sh_wdt_read_csr();
45 sh_wdt_write_cnt(0);
46
47 /* disable PLL1 */
48 frqcr = ctrl_inw(FRQCR);
49 frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
50 ctrl_outw(frqcr, FRQCR);
51
52 /* enable standby */
53 stbcr = ctrl_inb(STBCR);
54 ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
55
56 /* set self-refresh */
57 mcr = ctrl_inw(MCR);
58 ctrl_outw(mcr & ~MCR_RFSH, MCR);
59
60 /* set interrupt handler */
61 asm volatile("stc vbr, %0" : "=r" (vbr_old));
62 vbr_new = get_zeroed_page(GFP_ATOMIC);
63 udelay(50);
64 memcpy((void*)(vbr_new + INTR_OFFSET),
65 &wakeup_start, &wakeup_end - &wakeup_start);
66 asm volatile("ldc %0, vbr" : : "r" (vbr_new));
67
68 ctrl_outw(0, RTCNT);
69 ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
70
71 cpu_sleep();
72
73 asm volatile("ldc %0, vbr" : : "r" (vbr_old));
74
75 free_page(vbr_new);
76
77 /* enable PLL1 */
78 frqcr = ctrl_inw(FRQCR);
79 frqcr |= FRQCR_PSTBY;
80 ctrl_outw(frqcr, FRQCR);
81 udelay(50);
82 frqcr |= FRQCR_PLLEN;
83 ctrl_outw(frqcr, FRQCR);
84
85 ctrl_outb(stbcr, STBCR);
86
87 clear_bl_bit();
88}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index b965f0282c7d..ddafbbbab2ab 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -32,65 +32,8 @@
32#include <asm/fpu.h> 32#include <asm/fpu.h>
33#include <asm/syscalls.h> 33#include <asm/syscalls.h>
34 34
35static int hlt_counter;
36int ubc_usercnt = 0; 35int ubc_usercnt = 0;
37 36
38void (*pm_idle)(void);
39void (*pm_power_off)(void);
40EXPORT_SYMBOL(pm_power_off);
41
42static int __init nohlt_setup(char *__unused)
43{
44 hlt_counter = 1;
45 return 1;
46}
47__setup("nohlt", nohlt_setup);
48
49static int __init hlt_setup(char *__unused)
50{
51 hlt_counter = 0;
52 return 1;
53}
54__setup("hlt", hlt_setup);
55
56static void default_idle(void)
57{
58 if (!hlt_counter) {
59 clear_thread_flag(TIF_POLLING_NRFLAG);
60 smp_mb__after_clear_bit();
61 set_bl_bit();
62 while (!need_resched())
63 cpu_sleep();
64 clear_bl_bit();
65 set_thread_flag(TIF_POLLING_NRFLAG);
66 } else
67 while (!need_resched())
68 cpu_relax();
69}
70
71void cpu_idle(void)
72{
73 set_thread_flag(TIF_POLLING_NRFLAG);
74
75 /* endless idle loop with no priority at all */
76 while (1) {
77 void (*idle)(void) = pm_idle;
78
79 if (!idle)
80 idle = default_idle;
81
82 tick_nohz_stop_sched_tick(1);
83 while (!need_resched())
84 idle();
85 tick_nohz_restart_sched_tick();
86
87 preempt_enable_no_resched();
88 schedule();
89 preempt_disable();
90 check_pgt_cache();
91 }
92}
93
94void machine_restart(char * __unused) 37void machine_restart(char * __unused)
95{ 38{
96 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 39 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
@@ -115,8 +58,8 @@ void machine_power_off(void)
115void show_regs(struct pt_regs * regs) 58void show_regs(struct pt_regs * regs)
116{ 59{
117 printk("\n"); 60 printk("\n");
118 printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm); 61 printk("Pid : %d, Comm: \t\t%s\n", task_pid_nr(current), current->comm);
119 printk("CPU : %d %s (%s %.*s)\n", 62 printk("CPU : %d \t\t%s (%s %.*s)\n\n",
120 smp_processor_id(), print_tainted(), init_utsname()->release, 63 smp_processor_id(), print_tainted(), init_utsname()->release,
121 (int)strcspn(init_utsname()->version, " "), 64 (int)strcspn(init_utsname()->version, " "),
122 init_utsname()->version); 65 init_utsname()->version);
@@ -148,26 +91,16 @@ void show_regs(struct pt_regs * regs)
148 regs->mach, regs->macl, regs->gbr, regs->pr); 91 regs->mach, regs->macl, regs->gbr, regs->pr);
149 92
150 show_trace(NULL, (unsigned long *)regs->regs[15], regs); 93 show_trace(NULL, (unsigned long *)regs->regs[15], regs);
94 show_code(regs);
151} 95}
152 96
153/* 97/*
154 * Create a kernel thread 98 * Create a kernel thread
155 */ 99 */
156 100ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
157/* 101{
158 * This is the mechanism for creating a new kernel thread. 102 do_exit(fn(arg));
159 * 103}
160 */
161extern void kernel_thread_helper(void);
162__asm__(".align 5\n"
163 "kernel_thread_helper:\n\t"
164 "jsr @r5\n\t"
165 " nop\n\t"
166 "mov.l 1f, r1\n\t"
167 "jsr @r1\n\t"
168 " mov r0, r4\n\t"
169 ".align 2\n\t"
170 "1:.long do_exit");
171 104
172/* Don't use this in BL=1(cli). Or else, CPU resets! */ 105/* Don't use this in BL=1(cli). Or else, CPU resets! */
173int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 106int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index b7aa09235b51..a7e5f2e74bac 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -23,7 +23,6 @@
23#include <linux/reboot.h> 23#include <linux/reboot.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/proc_fs.h>
27#include <linux/io.h> 26#include <linux/io.h>
28#include <asm/syscalls.h> 27#include <asm/syscalls.h>
29#include <asm/uaccess.h> 28#include <asm/uaccess.h>
@@ -33,56 +32,6 @@
33 32
34struct task_struct *last_task_used_math = NULL; 33struct task_struct *last_task_used_math = NULL;
35 34
36static int hlt_counter = 1;
37
38#define HARD_IDLE_TIMEOUT (HZ / 3)
39
40static int __init nohlt_setup(char *__unused)
41{
42 hlt_counter = 1;
43 return 1;
44}
45
46static int __init hlt_setup(char *__unused)
47{
48 hlt_counter = 0;
49 return 1;
50}
51
52__setup("nohlt", nohlt_setup);
53__setup("hlt", hlt_setup);
54
55static inline void hlt(void)
56{
57 __asm__ __volatile__ ("sleep" : : : "memory");
58}
59
60/*
61 * The idle loop on a uniprocessor SH..
62 */
63void cpu_idle(void)
64{
65 /* endless idle loop with no priority at all */
66 while (1) {
67 if (hlt_counter) {
68 while (!need_resched())
69 cpu_relax();
70 } else {
71 local_irq_disable();
72 while (!need_resched()) {
73 local_irq_enable();
74 hlt();
75 local_irq_disable();
76 }
77 local_irq_enable();
78 }
79 preempt_enable_no_resched();
80 schedule();
81 preempt_disable();
82 }
83
84}
85
86void machine_restart(char * __unused) 35void machine_restart(char * __unused)
87{ 36{
88 extern void phys_stext(void); 37 extern void phys_stext(void);
@@ -97,13 +46,6 @@ void machine_halt(void)
97 46
98void machine_power_off(void) 47void machine_power_off(void)
99{ 48{
100#if 0
101 /* Disable watchdog timer */
102 ctrl_outl(0xa5000000, WTCSR);
103 /* Configure deep standby on sleep */
104 ctrl_outl(0x03, STBCR);
105#endif
106
107 __asm__ __volatile__ ( 49 __asm__ __volatile__ (
108 "sleep\n\t" 50 "sleep\n\t"
109 "synci\n\t" 51 "synci\n\t"
@@ -113,9 +55,6 @@ void machine_power_off(void)
113 panic("Unexpected wakeup!\n"); 55 panic("Unexpected wakeup!\n");
114} 56}
115 57
116void (*pm_power_off)(void) = machine_power_off;
117EXPORT_SYMBOL(pm_power_off);
118
119void show_regs(struct pt_regs * regs) 58void show_regs(struct pt_regs * regs)
120{ 59{
121 unsigned long long ah, al, bh, bl, ch, cl; 60 unsigned long long ah, al, bh, bl, ch, cl;
@@ -365,18 +304,6 @@ void show_regs(struct pt_regs * regs)
365 } 304 }
366} 305}
367 306
368struct task_struct * alloc_task_struct(void)
369{
370 /* Get task descriptor pages */
371 return (struct task_struct *)
372 __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE));
373}
374
375void free_task_struct(struct task_struct *p)
376{
377 free_pages((unsigned long) p, get_order(THREAD_SIZE));
378}
379
380/* 307/*
381 * Create a kernel thread 308 * Create a kernel thread
382 */ 309 */
@@ -662,41 +589,3 @@ unsigned long get_wchan(struct task_struct *p)
662#endif 589#endif
663 return pc; 590 return pc;
664} 591}
665
666/* Provide a /proc/asids file that lists out the
667 ASIDs currently associated with the processes. (If the DM.PC register is
668 examined through the debug link, this shows ASID + PC. To make use of this,
669 the PID->ASID relationship needs to be known. This is primarily for
670 debugging.)
671 */
672
673#if defined(CONFIG_SH64_PROC_ASIDS)
674static int
675asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
676{
677 int len=0;
678 struct task_struct *p;
679 read_lock(&tasklist_lock);
680 for_each_process(p) {
681 int pid = p->pid;
682
683 if (!pid)
684 continue;
685 if (p->mm)
686 len += sprintf(buf+len, "%5d : %02lx\n", pid,
687 asid_cache(smp_processor_id()));
688 else
689 len += sprintf(buf+len, "%5d : (none)\n", pid);
690 }
691 read_unlock(&tasklist_lock);
692 *eof = 1;
693 return len;
694}
695
696static int __init register_proc_asids(void)
697{
698 create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
699 return 0;
700}
701__initcall(register_proc_asids);
702#endif
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index e15b099c1f06..695097438f02 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -2,7 +2,7 @@
2 * arch/sh/kernel/ptrace_64.c 2 * arch/sh/kernel/ptrace_64.c
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 - 2007 Paul Mundt 5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * 6 *
7 * Started from SH3/4 version: 7 * Started from SH3/4 version:
8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 8 * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
@@ -29,6 +29,8 @@
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/seccomp.h> 30#include <linux/seccomp.h>
31#include <linux/tracehook.h> 31#include <linux/tracehook.h>
32#include <linux/elf.h>
33#include <linux/regset.h>
32#include <asm/io.h> 34#include <asm/io.h>
33#include <asm/uaccess.h> 35#include <asm/uaccess.h>
34#include <asm/pgtable.h> 36#include <asm/pgtable.h>
@@ -137,6 +139,165 @@ void user_disable_single_step(struct task_struct *child)
137 regs->sr &= ~SR_SSTEP; 139 regs->sr &= ~SR_SSTEP;
138} 140}
139 141
142static int genregs_get(struct task_struct *target,
143 const struct user_regset *regset,
144 unsigned int pos, unsigned int count,
145 void *kbuf, void __user *ubuf)
146{
147 const struct pt_regs *regs = task_pt_regs(target);
148 int ret;
149
150 /* PC, SR, SYSCALL */
151 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
152 &regs->pc,
153 0, 3 * sizeof(unsigned long long));
154
155 /* R1 -> R63 */
156 if (!ret)
157 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
158 regs->regs,
159 offsetof(struct pt_regs, regs[0]),
160 63 * sizeof(unsigned long long));
161 /* TR0 -> TR7 */
162 if (!ret)
163 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
164 regs->tregs,
165 offsetof(struct pt_regs, tregs[0]),
166 8 * sizeof(unsigned long long));
167
168 if (!ret)
169 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
170 sizeof(struct pt_regs), -1);
171
172 return ret;
173}
174
175static int genregs_set(struct task_struct *target,
176 const struct user_regset *regset,
177 unsigned int pos, unsigned int count,
178 const void *kbuf, const void __user *ubuf)
179{
180 struct pt_regs *regs = task_pt_regs(target);
181 int ret;
182
183 /* PC, SR, SYSCALL */
184 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
185 &regs->pc,
186 0, 3 * sizeof(unsigned long long));
187
188 /* R1 -> R63 */
189 if (!ret && count > 0)
190 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
191 regs->regs,
192 offsetof(struct pt_regs, regs[0]),
193 63 * sizeof(unsigned long long));
194
195 /* TR0 -> TR7 */
196 if (!ret && count > 0)
197 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
198 regs->tregs,
199 offsetof(struct pt_regs, tregs[0]),
200 8 * sizeof(unsigned long long));
201
202 if (!ret)
203 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
204 sizeof(struct pt_regs), -1);
205
206 return ret;
207}
208
209#ifdef CONFIG_SH_FPU
210int fpregs_get(struct task_struct *target,
211 const struct user_regset *regset,
212 unsigned int pos, unsigned int count,
213 void *kbuf, void __user *ubuf)
214{
215 int ret;
216
217 ret = init_fpu(target);
218 if (ret)
219 return ret;
220
221 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
222 &target->thread.fpu.hard, 0, -1);
223}
224
225static int fpregs_set(struct task_struct *target,
226 const struct user_regset *regset,
227 unsigned int pos, unsigned int count,
228 const void *kbuf, const void __user *ubuf)
229{
230 int ret;
231
232 ret = init_fpu(target);
233 if (ret)
234 return ret;
235
236 set_stopped_child_used_math(target);
237
238 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
239 &target->thread.fpu.hard, 0, -1);
240}
241
242static int fpregs_active(struct task_struct *target,
243 const struct user_regset *regset)
244{
245 return tsk_used_math(target) ? regset->n : 0;
246}
247#endif
248
249/*
250 * These are our native regset flavours.
251 */
252enum sh_regset {
253 REGSET_GENERAL,
254#ifdef CONFIG_SH_FPU
255 REGSET_FPU,
256#endif
257};
258
259static const struct user_regset sh_regsets[] = {
260 /*
261 * Format is:
262 * PC, SR, SYSCALL,
263 * R1 --> R63,
264 * TR0 --> TR7,
265 */
266 [REGSET_GENERAL] = {
267 .core_note_type = NT_PRSTATUS,
268 .n = ELF_NGREG,
269 .size = sizeof(long long),
270 .align = sizeof(long long),
271 .get = genregs_get,
272 .set = genregs_set,
273 },
274
275#ifdef CONFIG_SH_FPU
276 [REGSET_FPU] = {
277 .core_note_type = NT_PRFPREG,
278 .n = sizeof(struct user_fpu_struct) /
279 sizeof(long long),
280 .size = sizeof(long long),
281 .align = sizeof(long long),
282 .get = fpregs_get,
283 .set = fpregs_set,
284 .active = fpregs_active,
285 },
286#endif
287};
288
289static const struct user_regset_view user_sh64_native_view = {
290 .name = "sh64",
291 .e_machine = EM_SH,
292 .regsets = sh_regsets,
293 .n = ARRAY_SIZE(sh_regsets),
294};
295
296const struct user_regset_view *task_user_regset_view(struct task_struct *task)
297{
298 return &user_sh64_native_view;
299}
300
140long arch_ptrace(struct task_struct *child, long request, long addr, long data) 301long arch_ptrace(struct task_struct *child, long request, long addr, long data)
141{ 302{
142 int ret; 303 int ret;
@@ -195,10 +356,33 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
195 } 356 }
196 break; 357 break;
197 358
359 case PTRACE_GETREGS:
360 return copy_regset_to_user(child, &user_sh64_native_view,
361 REGSET_GENERAL,
362 0, sizeof(struct pt_regs),
363 (void __user *)data);
364 case PTRACE_SETREGS:
365 return copy_regset_from_user(child, &user_sh64_native_view,
366 REGSET_GENERAL,
367 0, sizeof(struct pt_regs),
368 (const void __user *)data);
369#ifdef CONFIG_SH_FPU
370 case PTRACE_GETFPREGS:
371 return copy_regset_to_user(child, &user_sh64_native_view,
372 REGSET_FPU,
373 0, sizeof(struct user_fpu_struct),
374 (void __user *)data);
375 case PTRACE_SETFPREGS:
376 return copy_regset_from_user(child, &user_sh64_native_view,
377 REGSET_FPU,
378 0, sizeof(struct user_fpu_struct),
379 (const void __user *)data);
380#endif
198 default: 381 default:
199 ret = ptrace_request(child, request, addr, data); 382 ret = ptrace_request(child, request, addr, data);
200 break; 383 break;
201 } 384 }
385
202 return ret; 386 return ret;
203} 387}
204 388
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e7152cc6930e..534247508572 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -417,6 +417,7 @@ void __init setup_arch(char **cmdline_p)
417} 417}
418 418
419static const char *cpu_name[] = { 419static const char *cpu_name[] = {
420 [CPU_SH7201] = "SH7201",
420 [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263", 421 [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
421 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", 422 [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
422 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 423 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index d1bcac4fa269..c852f7805728 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -8,69 +8,50 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <asm/sh_bios.h> 9#include <asm/sh_bios.h>
10 10
11#define BIOS_CALL_CONSOLE_WRITE 0 11#define BIOS_CALL_CONSOLE_WRITE 0
12#define BIOS_CALL_READ_BLOCK 1
13#define BIOS_CALL_ETH_NODE_ADDR 10 12#define BIOS_CALL_ETH_NODE_ADDR 10
14#define BIOS_CALL_SHUTDOWN 11 13#define BIOS_CALL_SHUTDOWN 11
15#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */ 14#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
16#define BIOS_CALL_GDB_GET_MODE_PTR 0xfe 15#define BIOS_CALL_GDB_DETACH 0xff
17#define BIOS_CALL_GDB_DETACH 0xff
18 16
19static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3) 17static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
18 long arg3)
20{ 19{
21 register long r0 __asm__("r0") = func; 20 register long r0 __asm__("r0") = func;
22 register long r4 __asm__("r4") = arg0; 21 register long r4 __asm__("r4") = arg0;
23 register long r5 __asm__("r5") = arg1; 22 register long r5 __asm__("r5") = arg1;
24 register long r6 __asm__("r6") = arg2; 23 register long r6 __asm__("r6") = arg2;
25 register long r7 __asm__("r7") = arg3; 24 register long r7 __asm__("r7") = arg3;
26 __asm__ __volatile__("trapa #0x3f" 25
27 : "=z" (r0) 26 __asm__ __volatile__("trapa #0x3f":"=z"(r0)
28 : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7) 27 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
29 : "memory"); 28 :"memory");
30 return r0; 29 return r0;
31} 30}
32 31
33
34void sh_bios_console_write(const char *buf, unsigned int len) 32void sh_bios_console_write(const char *buf, unsigned int len)
35{ 33{
36 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0); 34 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
37} 35}
38 36
39
40void sh_bios_char_out(char ch) 37void sh_bios_char_out(char ch)
41{ 38{
42 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0); 39 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
43}
44
45
46int sh_bios_in_gdb_mode(void)
47{
48 static char queried = 0;
49 static char *gdb_mode_p = 0;
50
51 if (!queried)
52 {
53 /* Query the gdb stub for address of its gdb mode variable */
54 long r = sh_bios_call(BIOS_CALL_GDB_GET_MODE_PTR, 0, 0, 0, 0);
55 if (r != ~0) /* BIOS returns -1 for unknown function */
56 gdb_mode_p = (char *)r;
57 queried = 1;
58 }
59 return (gdb_mode_p != 0 ? *gdb_mode_p : 0);
60} 40}
61 41
62void sh_bios_gdb_detach(void) 42void sh_bios_gdb_detach(void)
63{ 43{
64 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); 44 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
65} 45}
66EXPORT_SYMBOL(sh_bios_gdb_detach); 46EXPORT_SYMBOL_GPL(sh_bios_gdb_detach);
67 47
68void sh_bios_get_node_addr (unsigned char *node_addr) 48void sh_bios_get_node_addr(unsigned char *node_addr)
69{ 49{
70 sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0); 50 sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
71} 51}
52EXPORT_SYMBOL_GPL(sh_bios_get_node_addr);
72 53
73void sh_bios_shutdown(unsigned int how) 54void sh_bios_shutdown(unsigned int how)
74{ 55{
75 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); 56 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
76} 57}
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 92ae5e6c099e..528de2955c81 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -52,16 +52,12 @@ EXPORT_SYMBOL(__const_udelay);
52 52
53#define DECLARE_EXPORT(name) \ 53#define DECLARE_EXPORT(name) \
54 extern void name(void);EXPORT_SYMBOL(name) 54 extern void name(void);EXPORT_SYMBOL(name)
55#define MAYBE_DECLARE_EXPORT(name) \
56 extern void name(void) __weak;EXPORT_SYMBOL(name)
57 55
58/* These symbols are generated by the compiler itself */
59DECLARE_EXPORT(__udivsi3); 56DECLARE_EXPORT(__udivsi3);
60DECLARE_EXPORT(__sdivsi3); 57DECLARE_EXPORT(__sdivsi3);
58DECLARE_EXPORT(__lshrsi3);
61DECLARE_EXPORT(__ashrsi3); 59DECLARE_EXPORT(__ashrsi3);
62DECLARE_EXPORT(__ashlsi3); 60DECLARE_EXPORT(__ashlsi3);
63DECLARE_EXPORT(__ashrdi3);
64DECLARE_EXPORT(__ashldi3);
65DECLARE_EXPORT(__ashiftrt_r4_6); 61DECLARE_EXPORT(__ashiftrt_r4_6);
66DECLARE_EXPORT(__ashiftrt_r4_7); 62DECLARE_EXPORT(__ashiftrt_r4_7);
67DECLARE_EXPORT(__ashiftrt_r4_8); 63DECLARE_EXPORT(__ashiftrt_r4_8);
@@ -79,8 +75,7 @@ DECLARE_EXPORT(__ashiftrt_r4_23);
79DECLARE_EXPORT(__ashiftrt_r4_24); 75DECLARE_EXPORT(__ashiftrt_r4_24);
80DECLARE_EXPORT(__ashiftrt_r4_27); 76DECLARE_EXPORT(__ashiftrt_r4_27);
81DECLARE_EXPORT(__ashiftrt_r4_30); 77DECLARE_EXPORT(__ashiftrt_r4_30);
82DECLARE_EXPORT(__lshrsi3); 78DECLARE_EXPORT(__movstr);
83DECLARE_EXPORT(__lshrdi3);
84DECLARE_EXPORT(__movstrSI8); 79DECLARE_EXPORT(__movstrSI8);
85DECLARE_EXPORT(__movstrSI12); 80DECLARE_EXPORT(__movstrSI12);
86DECLARE_EXPORT(__movstrSI16); 81DECLARE_EXPORT(__movstrSI16);
@@ -95,31 +90,17 @@ DECLARE_EXPORT(__movstrSI48);
95DECLARE_EXPORT(__movstrSI52); 90DECLARE_EXPORT(__movstrSI52);
96DECLARE_EXPORT(__movstrSI56); 91DECLARE_EXPORT(__movstrSI56);
97DECLARE_EXPORT(__movstrSI60); 92DECLARE_EXPORT(__movstrSI60);
98#if __GNUC__ == 4 93DECLARE_EXPORT(__movstr_i4_even);
99DECLARE_EXPORT(__movmem); 94DECLARE_EXPORT(__movstr_i4_odd);
100#else 95DECLARE_EXPORT(__movstrSI12_i4);
101DECLARE_EXPORT(__movstr);
102#endif
103
104#if __GNUC__ == 4
105DECLARE_EXPORT(__movmem_i4_even); 96DECLARE_EXPORT(__movmem_i4_even);
106DECLARE_EXPORT(__movmem_i4_odd); 97DECLARE_EXPORT(__movmem_i4_odd);
107DECLARE_EXPORT(__movmemSI12_i4); 98DECLARE_EXPORT(__movmemSI12_i4);
108
109#if (__GNUC_MINOR__ >= 2 || defined(__GNUC_STM_RELEASE__))
110/*
111 * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST
112 * compiler which include backported patches.
113 */
114DECLARE_EXPORT(__udiv_qrnnd_16); 99DECLARE_EXPORT(__udiv_qrnnd_16);
115MAYBE_DECLARE_EXPORT(__sdivsi3_i4i); 100DECLARE_EXPORT(__sdivsi3_i4);
116MAYBE_DECLARE_EXPORT(__udivsi3_i4i); 101DECLARE_EXPORT(__udivsi3_i4);
117#endif 102DECLARE_EXPORT(__sdivsi3_i4i);
118#else /* GCC 3.x */ 103DECLARE_EXPORT(__udivsi3_i4i);
119DECLARE_EXPORT(__movstr_i4_even);
120DECLARE_EXPORT(__movstr_i4_odd);
121DECLARE_EXPORT(__movstrSI12_i4);
122#endif /* __GNUC__ == 4 */
123 104
124#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ 105#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
125 defined(CONFIG_SH7705_CACHE_32KB)) 106 defined(CONFIG_SH7705_CACHE_32KB))
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index 9324d32adacc..0d74d6b8774e 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -65,15 +65,16 @@ EXPORT_SYMBOL(copy_page);
65EXPORT_SYMBOL(__copy_user); 65EXPORT_SYMBOL(__copy_user);
66EXPORT_SYMBOL(empty_zero_page); 66EXPORT_SYMBOL(empty_zero_page);
67EXPORT_SYMBOL(memcpy); 67EXPORT_SYMBOL(memcpy);
68EXPORT_SYMBOL(memset);
68EXPORT_SYMBOL(__udelay); 69EXPORT_SYMBOL(__udelay);
69EXPORT_SYMBOL(__ndelay); 70EXPORT_SYMBOL(__ndelay);
70EXPORT_SYMBOL(__const_udelay); 71EXPORT_SYMBOL(__const_udelay);
72EXPORT_SYMBOL(strlen);
73EXPORT_SYMBOL(strcpy);
71 74
72/* Ugh. These come in from libgcc.a at link time. */ 75/* Ugh. These come in from libgcc.a at link time. */
73#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) 76#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)
74 77
75DECLARE_EXPORT(__sdivsi3); 78DECLARE_EXPORT(__sdivsi3);
76DECLARE_EXPORT(__sdivsi3_2);
77DECLARE_EXPORT(__muldi3);
78DECLARE_EXPORT(__udivsi3); 79DECLARE_EXPORT(__udivsi3);
79DECLARE_EXPORT(__div_table); 80DECLARE_EXPORT(__div_table);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 69d09c0b3498..77c21bde376a 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -533,7 +533,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
533{ 533{
534 int ret; 534 int ret;
535 535
536
537 /* Set up the stack frame */ 536 /* Set up the stack frame */
538 if (ka->sa.sa_flags & SA_SIGINFO) 537 if (ka->sa.sa_flags & SA_SIGINFO)
539 ret = setup_rt_frame(sig, ka, info, oldset, regs); 538 ret = setup_rt_frame(sig, ka, info, oldset, regs);
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index ce3e851dffcb..b22fdfaaa191 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -2,7 +2,7 @@
2 * arch/sh/kernel/signal_64.c 2 * arch/sh/kernel/signal_64.c
3 * 3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli 4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2008 Paul Mundt
6 * Copyright (C) 2004 Richard Curnow 6 * Copyright (C) 2004 Richard Curnow
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
@@ -43,10 +43,38 @@
43 43
44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
45 45
46static void 46static int
47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
48 sigset_t *oldset, struct pt_regs * regs); 48 sigset_t *oldset, struct pt_regs * regs);
49 49
50static inline void
51handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
52{
53 /* If we're not from a syscall, bail out */
54 if (regs->syscall_nr < 0)
55 return;
56
57 /* check for system call restart.. */
58 switch (regs->regs[REG_RET]) {
59 case -ERESTART_RESTARTBLOCK:
60 case -ERESTARTNOHAND:
61 no_system_call_restart:
62 regs->regs[REG_RET] = -EINTR;
63 regs->sr |= 1;
64 break;
65
66 case -ERESTARTSYS:
67 if (!(sa->sa_flags & SA_RESTART))
68 goto no_system_call_restart;
69 /* fallthrough */
70 case -ERESTARTNOINTR:
71 /* Decode syscall # */
72 regs->regs[REG_RET] = regs->syscall_nr;
73 regs->pc -= 4;
74 break;
75 }
76}
77
50/* 78/*
51 * Note that 'init' is a special process: it doesn't get signals it doesn't 79 * Note that 'init' is a special process: it doesn't get signals it doesn't
52 * want to handle. Thus you cannot kill init even with a SIGKILL even by 80 * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -80,21 +108,23 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
80 oldset = &current->blocked; 108 oldset = &current->blocked;
81 109
82 signr = get_signal_to_deliver(&info, &ka, regs, 0); 110 signr = get_signal_to_deliver(&info, &ka, regs, 0);
83
84 if (signr > 0) { 111 if (signr > 0) {
85 /* Whee! Actually deliver the signal. */ 112 if (regs->sr & 1)
86 handle_signal(signr, &info, &ka, oldset, regs); 113 handle_syscall_restart(regs, &ka.sa);
87 114
88 /* 115 /* Whee! Actually deliver the signal. */
89 * If a signal was successfully delivered, the saved sigmask 116 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
90 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK 117 /*
91 * flag. 118 * If a signal was successfully delivered, the
92 */ 119 * saved sigmask is in its frame, and we can
93 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 120 * clear the TIF_RESTORE_SIGMASK flag.
94 clear_thread_flag(TIF_RESTORE_SIGMASK); 121 */
95 122 if (test_thread_flag(TIF_RESTORE_SIGMASK))
96 tracehook_signal_handler(signr, &info, &ka, regs, 0); 123 clear_thread_flag(TIF_RESTORE_SIGMASK);
97 return 1; 124
125 tracehook_signal_handler(signr, &info, &ka, regs, 0);
126 return 1;
127 }
98 } 128 }
99 129
100no_signal: 130no_signal:
@@ -129,7 +159,6 @@ no_signal:
129/* 159/*
130 * Atomically swap in the new signal mask, and wait for a signal. 160 * Atomically swap in the new signal mask, and wait for a signal.
131 */ 161 */
132
133asmlinkage int 162asmlinkage int
134sys_sigsuspend(old_sigset_t mask, 163sys_sigsuspend(old_sigset_t mask,
135 unsigned long r3, unsigned long r4, unsigned long r5, 164 unsigned long r3, unsigned long r4, unsigned long r5,
@@ -235,20 +264,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
235 return do_sigaltstack(uss, uoss, REF_REG_SP); 264 return do_sigaltstack(uss, uoss, REF_REG_SP);
236} 265}
237 266
238
239/* 267/*
240 * Do a signal return; undo the signal stack. 268 * Do a signal return; undo the signal stack.
241 */ 269 */
242 270struct sigframe {
243struct sigframe
244{
245 struct sigcontext sc; 271 struct sigcontext sc;
246 unsigned long extramask[_NSIG_WORDS-1]; 272 unsigned long extramask[_NSIG_WORDS-1];
247 long long retcode[2]; 273 long long retcode[2];
248}; 274};
249 275
250struct rt_sigframe 276struct rt_sigframe {
251{
252 struct siginfo __user *pinfo; 277 struct siginfo __user *pinfo;
253 void *puc; 278 void *puc;
254 struct siginfo info; 279 struct siginfo info;
@@ -450,7 +475,6 @@ badframe:
450/* 475/*
451 * Set up a signal frame. 476 * Set up a signal frame.
452 */ 477 */
453
454static int 478static int
455setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, 479setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
456 unsigned long mask) 480 unsigned long mask)
@@ -504,8 +528,8 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
504void sa_default_restorer(void); /* See comments below */ 528void sa_default_restorer(void); /* See comments below */
505void sa_default_rt_restorer(void); /* See comments below */ 529void sa_default_rt_restorer(void); /* See comments below */
506 530
507static void setup_frame(int sig, struct k_sigaction *ka, 531static int setup_frame(int sig, struct k_sigaction *ka,
508 sigset_t *set, struct pt_regs *regs) 532 sigset_t *set, struct pt_regs *regs)
509{ 533{
510 struct sigframe __user *frame; 534 struct sigframe __user *frame;
511 int err = 0; 535 int err = 0;
@@ -596,23 +620,21 @@ static void setup_frame(int sig, struct k_sigaction *ka,
596 620
597 set_fs(USER_DS); 621 set_fs(USER_DS);
598 622
599#if DEBUG_SIG
600 /* Broken %016Lx */ 623 /* Broken %016Lx */
601 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 624 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
602 signal, 625 signal, current->comm, current->pid, frame,
603 current->comm, current->pid, frame, 626 regs->pc >> 32, regs->pc & 0xffffffff,
604 regs->pc >> 32, regs->pc & 0xffffffff, 627 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
605 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
606#endif
607 628
608 return; 629 return 0;
609 630
610give_sigsegv: 631give_sigsegv:
611 force_sigsegv(sig, current); 632 force_sigsegv(sig, current);
633 return -EFAULT;
612} 634}
613 635
614static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 636static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
615 sigset_t *set, struct pt_regs *regs) 637 sigset_t *set, struct pt_regs *regs)
616{ 638{
617 struct rt_sigframe __user *frame; 639 struct rt_sigframe __user *frame;
618 int err = 0; 640 int err = 0;
@@ -702,62 +724,46 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
702 724
703 set_fs(USER_DS); 725 set_fs(USER_DS);
704 726
705#if DEBUG_SIG 727 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
706 /* Broken %016Lx */ 728 signal, current->comm, current->pid, frame,
707 printk("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n", 729 regs->pc >> 32, regs->pc & 0xffffffff,
708 signal, 730 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
709 current->comm, current->pid, frame,
710 regs->pc >> 32, regs->pc & 0xffffffff,
711 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
712#endif
713 731
714 return; 732 return 0;
715 733
716give_sigsegv: 734give_sigsegv:
717 force_sigsegv(sig, current); 735 force_sigsegv(sig, current);
736 return -EFAULT;
718} 737}
719 738
720/* 739/*
721 * OK, we're invoking a handler 740 * OK, we're invoking a handler
722 */ 741 */
723 742static int
724static void
725handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 743handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
726 sigset_t *oldset, struct pt_regs * regs) 744 sigset_t *oldset, struct pt_regs * regs)
727{ 745{
728 /* Are we from a system call? */ 746 int ret;
729 if (regs->syscall_nr >= 0) {
730 /* If so, check system call restarting.. */
731 switch (regs->regs[REG_RET]) {
732 case -ERESTART_RESTARTBLOCK:
733 case -ERESTARTNOHAND:
734 no_system_call_restart:
735 regs->regs[REG_RET] = -EINTR;
736 break;
737
738 case -ERESTARTSYS:
739 if (!(ka->sa.sa_flags & SA_RESTART))
740 goto no_system_call_restart;
741 /* fallthrough */
742 case -ERESTARTNOINTR:
743 /* Decode syscall # */
744 regs->regs[REG_RET] = regs->syscall_nr;
745 regs->pc -= 4;
746 }
747 }
748 747
749 /* Set up the stack frame */ 748 /* Set up the stack frame */
750 if (ka->sa.sa_flags & SA_SIGINFO) 749 if (ka->sa.sa_flags & SA_SIGINFO)
751 setup_rt_frame(sig, ka, info, oldset, regs); 750 ret = setup_rt_frame(sig, ka, info, oldset, regs);
752 else 751 else
753 setup_frame(sig, ka, oldset, regs); 752 ret = setup_frame(sig, ka, oldset, regs);
753
754 if (ka->sa.sa_flags & SA_ONESHOT)
755 ka->sa.sa_handler = SIG_DFL;
756
757 if (ret == 0) {
758 spin_lock_irq(&current->sighand->siglock);
759 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
760 if (!(ka->sa.sa_flags & SA_NODEFER))
761 sigaddset(&current->blocked,sig);
762 recalc_sigpending();
763 spin_unlock_irq(&current->sighand->siglock);
764 }
754 765
755 spin_lock_irq(&current->sighand->siglock); 766 return ret;
756 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
757 if (!(ka->sa.sa_flags & SA_NODEFER))
758 sigaddset(&current->blocked,sig);
759 recalc_sigpending();
760 spin_unlock_irq(&current->sighand->siglock);
761} 767}
762 768
763asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) 769asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 38f098c9c72d..58dfc02c7af1 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -22,102 +22,10 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/ipc.h> 24#include <linux/ipc.h>
25#include <asm/cacheflush.h>
26#include <asm/syscalls.h> 25#include <asm/syscalls.h>
27#include <asm/uaccess.h> 26#include <asm/uaccess.h>
28#include <asm/unistd.h> 27#include <asm/unistd.h>
29 28
30unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
31EXPORT_SYMBOL(shm_align_mask);
32
33#ifdef CONFIG_MMU
34/*
35 * To avoid cache aliases, we map the shared page with same color.
36 */
37#define COLOUR_ALIGN(addr, pgoff) \
38 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
39 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
40
41unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
42 unsigned long len, unsigned long pgoff, unsigned long flags)
43{
44 struct mm_struct *mm = current->mm;
45 struct vm_area_struct *vma;
46 unsigned long start_addr;
47 int do_colour_align;
48
49 if (flags & MAP_FIXED) {
50 /* We do not accept a shared mapping if it would violate
51 * cache aliasing constraints.
52 */
53 if ((flags & MAP_SHARED) && (addr & shm_align_mask))
54 return -EINVAL;
55 return addr;
56 }
57
58 if (unlikely(len > TASK_SIZE))
59 return -ENOMEM;
60
61 do_colour_align = 0;
62 if (filp || (flags & MAP_SHARED))
63 do_colour_align = 1;
64
65 if (addr) {
66 if (do_colour_align)
67 addr = COLOUR_ALIGN(addr, pgoff);
68 else
69 addr = PAGE_ALIGN(addr);
70
71 vma = find_vma(mm, addr);
72 if (TASK_SIZE - len >= addr &&
73 (!vma || addr + len <= vma->vm_start))
74 return addr;
75 }
76
77 if (len > mm->cached_hole_size) {
78 start_addr = addr = mm->free_area_cache;
79 } else {
80 mm->cached_hole_size = 0;
81 start_addr = addr = TASK_UNMAPPED_BASE;
82 }
83
84full_search:
85 if (do_colour_align)
86 addr = COLOUR_ALIGN(addr, pgoff);
87 else
88 addr = PAGE_ALIGN(mm->free_area_cache);
89
90 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
91 /* At this point: (!vma || addr < vma->vm_end). */
92 if (unlikely(TASK_SIZE - len < addr)) {
93 /*
94 * Start a new search - just in case we missed
95 * some holes.
96 */
97 if (start_addr != TASK_UNMAPPED_BASE) {
98 start_addr = addr = TASK_UNMAPPED_BASE;
99 mm->cached_hole_size = 0;
100 goto full_search;
101 }
102 return -ENOMEM;
103 }
104 if (likely(!vma || addr + len <= vma->vm_start)) {
105 /*
106 * Remember the place where we stopped the search:
107 */
108 mm->free_area_cache = addr + len;
109 return addr;
110 }
111 if (addr + mm->cached_hole_size < vma->vm_start)
112 mm->cached_hole_size = vma->vm_start - addr;
113
114 addr = vma->vm_end;
115 if (do_colour_align)
116 addr = COLOUR_ALIGN(addr, pgoff);
117 }
118}
119#endif /* CONFIG_MMU */
120
121static inline long 29static inline long
122do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 30do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
123 unsigned long flags, int fd, unsigned long pgoff) 31 unsigned long flags, int fd, unsigned long pgoff)
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 23ca711c27d2..8457f83242c5 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -125,11 +125,6 @@ void handle_timer_tick(void)
125 if (current->pid) 125 if (current->pid)
126 profile_tick(CPU_PROFILING); 126 profile_tick(CPU_PROFILING);
127 127
128#ifdef CONFIG_HEARTBEAT
129 if (sh_mv.mv_heartbeat != NULL)
130 sh_mv.mv_heartbeat();
131#endif
132
133 /* 128 /*
134 * Here we are in the timer irq handler. We just have irqs locally 129 * Here we are in the timer irq handler. We just have irqs locally
135 * disabled but we don't know if the timer_bh is running on the other 130 * disabled but we don't know if the timer_bh is running on the other
@@ -277,11 +272,4 @@ void __init time_init(void)
277 ((sh_hpt_frequency + 500) / 1000) / 1000, 272 ((sh_hpt_frequency + 500) / 1000) / 1000,
278 ((sh_hpt_frequency + 500) / 1000) % 1000); 273 ((sh_hpt_frequency + 500) / 1000) % 1000);
279 274
280#if defined(CONFIG_SH_KGDB)
281 /*
282 * Set up kgdb as requested. We do it here because the serial
283 * init uses the timer vars we just set up for figuring baud.
284 */
285 kgdb_init();
286#endif
287} 275}
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index bbb2af1004d9..59d2a03e8b3c 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -240,11 +240,6 @@ static inline void do_timer_interrupt(void)
240 240
241 do_timer(1); 241 do_timer(1);
242 242
243#ifdef CONFIG_HEARTBEAT
244 if (sh_mv.mv_heartbeat != NULL)
245 sh_mv.mv_heartbeat();
246#endif
247
248 /* 243 /*
249 * If we have an externally synchronized Linux clock, then update 244 * If we have an externally synchronized Linux clock, then update
250 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 245 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index fe453c01f9c9..c3d237e1d566 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -34,7 +34,12 @@
34#define MTU2_TIER_1 0xfffe4384 34#define MTU2_TIER_1 0xfffe4384
35#define MTU2_TSR_1 0xfffe4385 35#define MTU2_TSR_1 0xfffe4385
36#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */ 36#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
37
38#if defined(CONFIG_CPU_SUBTYPE_SH7201)
39#define MTU2_TGRA_1 0xfffe4388
40#else
37#define MTU2_TGRA_1 0xfffe438a 41#define MTU2_TGRA_1 0xfffe438a
42#endif
38 43
39#define STBCR3 0xfffe0408 44#define STBCR3 0xfffe0408
40 45
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 1e5c74efbacc..88807a2aacc3 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -28,17 +28,6 @@
28#include <asm/fpu.h> 28#include <asm/fpu.h>
29#include <asm/kprobes.h> 29#include <asm/kprobes.h>
30 30
31#ifdef CONFIG_SH_KGDB
32#include <asm/kgdb.h>
33#define CHK_REMOTE_DEBUG(regs) \
34{ \
35 if (kgdb_debug_hook && !user_mode(regs))\
36 (*kgdb_debug_hook)(regs); \
37}
38#else
39#define CHK_REMOTE_DEBUG(regs)
40#endif
41
42#ifdef CONFIG_CPU_SH2 31#ifdef CONFIG_CPU_SH2
43# define TRAP_RESERVED_INST 4 32# define TRAP_RESERVED_INST 4
44# define TRAP_ILLEGAL_SLOT_INST 6 33# define TRAP_ILLEGAL_SLOT_INST 6
@@ -94,7 +83,6 @@ void die(const char * str, struct pt_regs * regs, long err)
94 83
95 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 84 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
96 85
97 CHK_REMOTE_DEBUG(regs);
98 print_modules(); 86 print_modules();
99 show_regs(regs); 87 show_regs(regs);
100 88
@@ -683,13 +671,12 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
683 error_code = lookup_exception_vector(); 671 error_code = lookup_exception_vector();
684 672
685 local_irq_enable(); 673 local_irq_enable();
686 CHK_REMOTE_DEBUG(regs);
687 force_sig(SIGILL, tsk); 674 force_sig(SIGILL, tsk);
688 die_if_no_fixup("reserved instruction", regs, error_code); 675 die_if_no_fixup("reserved instruction", regs, error_code);
689} 676}
690 677
691#ifdef CONFIG_SH_FPU_EMU 678#ifdef CONFIG_SH_FPU_EMU
692static int emulate_branch(unsigned short inst, struct pt_regs* regs) 679static int emulate_branch(unsigned short inst, struct pt_regs *regs)
693{ 680{
694 /* 681 /*
695 * bfs: 8fxx: PC+=d*2+4; 682 * bfs: 8fxx: PC+=d*2+4;
@@ -702,27 +689,32 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
702 * jsr: 4x0b: PC=Rn after PR=PC+4; 689 * jsr: 4x0b: PC=Rn after PR=PC+4;
703 * rts: 000b: PC=PR; 690 * rts: 000b: PC=PR;
704 */ 691 */
705 if ((inst & 0xfd00) == 0x8d00) { 692 if (((inst & 0xf000) == 0xb000) || /* bsr */
693 ((inst & 0xf0ff) == 0x0003) || /* bsrf */
694 ((inst & 0xf0ff) == 0x400b)) /* jsr */
695 regs->pr = regs->pc + 4;
696
697 if ((inst & 0xfd00) == 0x8d00) { /* bfs, bts */
706 regs->pc += SH_PC_8BIT_OFFSET(inst); 698 regs->pc += SH_PC_8BIT_OFFSET(inst);
707 return 0; 699 return 0;
708 } 700 }
709 701
710 if ((inst & 0xe000) == 0xa000) { 702 if ((inst & 0xe000) == 0xa000) { /* bra, bsr */
711 regs->pc += SH_PC_12BIT_OFFSET(inst); 703 regs->pc += SH_PC_12BIT_OFFSET(inst);
712 return 0; 704 return 0;
713 } 705 }
714 706
715 if ((inst & 0xf0df) == 0x0003) { 707 if ((inst & 0xf0df) == 0x0003) { /* braf, bsrf */
716 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; 708 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
717 return 0; 709 return 0;
718 } 710 }
719 711
720 if ((inst & 0xf0df) == 0x400b) { 712 if ((inst & 0xf0df) == 0x400b) { /* jmp, jsr */
721 regs->pc = regs->regs[(inst & 0x0f00) >> 8]; 713 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
722 return 0; 714 return 0;
723 } 715 }
724 716
725 if ((inst & 0xffff) == 0x000b) { 717 if ((inst & 0xffff) == 0x000b) { /* rts */
726 regs->pc = regs->pr; 718 regs->pc = regs->pr;
727 return 0; 719 return 0;
728 } 720 }
@@ -756,7 +748,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
756 inst = lookup_exception_vector(); 748 inst = lookup_exception_vector();
757 749
758 local_irq_enable(); 750 local_irq_enable();
759 CHK_REMOTE_DEBUG(regs);
760 force_sig(SIGILL, tsk); 751 force_sig(SIGILL, tsk);
761 die_if_no_fixup("illegal slot instruction", regs, inst); 752 die_if_no_fixup("illegal slot instruction", regs, inst);
762} 753}
@@ -868,10 +859,7 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
868 if (regs && user_mode(regs)) 859 if (regs && user_mode(regs))
869 return; 860 return;
870 861
871 printk("\nCall trace: "); 862 printk("\nCall trace:\n");
872#ifdef CONFIG_KALLSYMS
873 printk("\n");
874#endif
875 863
876 while (!kstack_end(sp)) { 864 while (!kstack_end(sp)) {
877 addr = *sp++; 865 addr = *sp++;
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index 95f4de0800ec..3f7e415be86a 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -59,8 +59,7 @@ int __init vsyscall_init(void)
59} 59}
60 60
61/* Setup a VMA at program startup for the vsyscall page */ 61/* Setup a VMA at program startup for the vsyscall page */
62int arch_setup_additional_pages(struct linux_binprm *bprm, 62int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
63 int executable_stack)
64{ 63{
65 struct mm_struct *mm = current->mm; 64 struct mm_struct *mm = current->mm;
66 unsigned long addr; 65 unsigned long addr;