diff options
Diffstat (limited to 'arch/sh/lib')
-rw-r--r-- | arch/sh/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/sh/lib/__clear_user.S (renamed from arch/sh/lib/clear_page.S) | 48 | ||||
-rw-r--r-- | arch/sh/lib/copy_page.S | 11 | ||||
-rw-r--r-- | arch/sh/lib/delay.c | 5 | ||||
-rw-r--r-- | arch/sh/lib/mcount.S | 228 |
5 files changed, 233 insertions, 63 deletions
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index aaea580b65bb..a969b47c5463 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile | |||
@@ -23,8 +23,8 @@ obj-y += io.o | |||
23 | memcpy-y := memcpy.o | 23 | memcpy-y := memcpy.o |
24 | memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o | 24 | memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o |
25 | 25 | ||
26 | lib-$(CONFIG_MMU) += copy_page.o clear_page.o | 26 | lib-$(CONFIG_MMU) += copy_page.o __clear_user.o |
27 | lib-$(CONFIG_FUNCTION_TRACER) += mcount.o | 27 | lib-$(CONFIG_MCOUNT) += mcount.o |
28 | lib-y += $(memcpy-y) $(udivsi3-y) | 28 | lib-y += $(memcpy-y) $(udivsi3-y) |
29 | 29 | ||
30 | EXTRA_CFLAGS += -Werror | 30 | EXTRA_CFLAGS += -Werror |
diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/__clear_user.S index 8342bfbde64c..db1dca7aad14 100644 --- a/arch/sh/lib/clear_page.S +++ b/arch/sh/lib/__clear_user.S | |||
@@ -8,56 +8,10 @@ | |||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | 10 | ||
11 | /* | ||
12 | * clear_page | ||
13 | * @to: P1 address | ||
14 | * | ||
15 | * void clear_page(void *to) | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * r0 --- scratch | ||
20 | * r4 --- to | ||
21 | * r5 --- to + PAGE_SIZE | ||
22 | */ | ||
23 | ENTRY(clear_page) | ||
24 | mov r4,r5 | ||
25 | mov.l .Llimit,r0 | ||
26 | add r0,r5 | ||
27 | mov #0,r0 | ||
28 | ! | ||
29 | 1: | ||
30 | #if defined(CONFIG_CPU_SH4) | ||
31 | movca.l r0,@r4 | ||
32 | mov r4,r1 | ||
33 | #else | ||
34 | mov.l r0,@r4 | ||
35 | #endif | ||
36 | add #32,r4 | ||
37 | mov.l r0,@-r4 | ||
38 | mov.l r0,@-r4 | ||
39 | mov.l r0,@-r4 | ||
40 | mov.l r0,@-r4 | ||
41 | mov.l r0,@-r4 | ||
42 | mov.l r0,@-r4 | ||
43 | mov.l r0,@-r4 | ||
44 | #if defined(CONFIG_CPU_SH4) | ||
45 | ocbwb @r1 | ||
46 | #endif | ||
47 | cmp/eq r5,r4 | ||
48 | bf/s 1b | ||
49 | add #28,r4 | ||
50 | ! | ||
51 | rts | ||
52 | nop | ||
53 | |||
54 | .balign 4 | ||
55 | .Llimit: .long (PAGE_SIZE-28) | ||
56 | |||
57 | ENTRY(__clear_user) | 11 | ENTRY(__clear_user) |
58 | ! | 12 | ! |
59 | mov #0, r0 | 13 | mov #0, r0 |
60 | mov #0xe0, r1 ! 0xffffffe0 | 14 | mov #0xffffffe0, r1 |
61 | ! | 15 | ! |
62 | ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ] | 16 | ! r4..(r4+31)&~32 -------- not aligned [ Area 0 ] |
63 | ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] | 17 | ! (r4+31)&~32..(r4+r5)&~32 -------- aligned [ Area 1 ] |
diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S index 43de7e8e4e17..9d7b8bc51866 100644 --- a/arch/sh/lib/copy_page.S +++ b/arch/sh/lib/copy_page.S | |||
@@ -30,7 +30,9 @@ ENTRY(copy_page) | |||
30 | mov r4,r10 | 30 | mov r4,r10 |
31 | mov r5,r11 | 31 | mov r5,r11 |
32 | mov r5,r8 | 32 | mov r5,r8 |
33 | mov.l .Lpsz,r0 | 33 | mov #(PAGE_SIZE >> 10), r0 |
34 | shll8 r0 | ||
35 | shll2 r0 | ||
34 | add r0,r8 | 36 | add r0,r8 |
35 | ! | 37 | ! |
36 | 1: mov.l @r11+,r0 | 38 | 1: mov.l @r11+,r0 |
@@ -43,7 +45,6 @@ ENTRY(copy_page) | |||
43 | mov.l @r11+,r7 | 45 | mov.l @r11+,r7 |
44 | #if defined(CONFIG_CPU_SH4) | 46 | #if defined(CONFIG_CPU_SH4) |
45 | movca.l r0,@r10 | 47 | movca.l r0,@r10 |
46 | mov r10,r0 | ||
47 | #else | 48 | #else |
48 | mov.l r0,@r10 | 49 | mov.l r0,@r10 |
49 | #endif | 50 | #endif |
@@ -55,9 +56,6 @@ ENTRY(copy_page) | |||
55 | mov.l r3,@-r10 | 56 | mov.l r3,@-r10 |
56 | mov.l r2,@-r10 | 57 | mov.l r2,@-r10 |
57 | mov.l r1,@-r10 | 58 | mov.l r1,@-r10 |
58 | #if defined(CONFIG_CPU_SH4) | ||
59 | ocbwb @r0 | ||
60 | #endif | ||
61 | cmp/eq r11,r8 | 59 | cmp/eq r11,r8 |
62 | bf/s 1b | 60 | bf/s 1b |
63 | add #28,r10 | 61 | add #28,r10 |
@@ -68,9 +66,6 @@ ENTRY(copy_page) | |||
68 | rts | 66 | rts |
69 | nop | 67 | nop |
70 | 68 | ||
71 | .balign 4 | ||
72 | .Lpsz: .long PAGE_SIZE | ||
73 | |||
74 | /* | 69 | /* |
75 | * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); | 70 | * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); |
76 | * Return the number of bytes NOT copied | 71 | * Return the number of bytes NOT copied |
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index f3ddd2133e6f..faa8f86c0db4 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c | |||
@@ -21,13 +21,14 @@ void __delay(unsigned long loops) | |||
21 | 21 | ||
22 | inline void __const_udelay(unsigned long xloops) | 22 | inline void __const_udelay(unsigned long xloops) |
23 | { | 23 | { |
24 | xloops *= 4; | ||
24 | __asm__("dmulu.l %0, %2\n\t" | 25 | __asm__("dmulu.l %0, %2\n\t" |
25 | "sts mach, %0" | 26 | "sts mach, %0" |
26 | : "=r" (xloops) | 27 | : "=r" (xloops) |
27 | : "0" (xloops), | 28 | : "0" (xloops), |
28 | "r" (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) | 29 | "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)) |
29 | : "macl", "mach"); | 30 | : "macl", "mach"); |
30 | __delay(xloops); | 31 | __delay(++xloops); |
31 | } | 32 | } |
32 | 33 | ||
33 | void __udelay(unsigned long usecs) | 34 | void __udelay(unsigned long usecs) |
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 110fbfe1831f..84a57761f17e 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S | |||
@@ -1,14 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/lib/mcount.S | 2 | * arch/sh/lib/mcount.S |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Paul Mundt | 4 | * Copyright (C) 2008, 2009 Paul Mundt |
5 | * Copyright (C) 2008 Matt Fleming | 5 | * Copyright (C) 2008, 2009 Matt Fleming |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 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 | 8 | * License. See the file "COPYING" in the main directory of this archive |
9 | * for more details. | 9 | * for more details. |
10 | */ | 10 | */ |
11 | #include <asm/ftrace.h> | 11 | #include <asm/ftrace.h> |
12 | #include <asm/thread_info.h> | ||
13 | #include <asm/asm-offsets.h> | ||
12 | 14 | ||
13 | #define MCOUNT_ENTER() \ | 15 | #define MCOUNT_ENTER() \ |
14 | mov.l r4, @-r15; \ | 16 | mov.l r4, @-r15; \ |
@@ -28,6 +30,55 @@ | |||
28 | rts; \ | 30 | rts; \ |
29 | mov.l @r15+, r4 | 31 | mov.l @r15+, r4 |
30 | 32 | ||
33 | #ifdef CONFIG_STACK_DEBUG | ||
34 | /* | ||
35 | * Perform diagnostic checks on the state of the kernel stack. | ||
36 | * | ||
37 | * Check for stack overflow. If there is less than 1KB free | ||
38 | * then it has overflowed. | ||
39 | * | ||
40 | * Make sure the stack pointer contains a valid address. Valid | ||
41 | * addresses for kernel stacks are anywhere after the bss | ||
42 | * (after _ebss) and anywhere in init_thread_union (init_stack). | ||
43 | */ | ||
44 | #define STACK_CHECK() \ | ||
45 | mov #(THREAD_SIZE >> 10), r0; \ | ||
46 | shll8 r0; \ | ||
47 | shll2 r0; \ | ||
48 | \ | ||
49 | /* r1 = sp & (THREAD_SIZE - 1) */ \ | ||
50 | mov #-1, r1; \ | ||
51 | add r0, r1; \ | ||
52 | and r15, r1; \ | ||
53 | \ | ||
54 | mov #TI_SIZE, r3; \ | ||
55 | mov #(STACK_WARN >> 8), r2; \ | ||
56 | shll8 r2; \ | ||
57 | add r3, r2; \ | ||
58 | \ | ||
59 | /* Is the stack overflowing? */ \ | ||
60 | cmp/hi r2, r1; \ | ||
61 | bf stack_panic; \ | ||
62 | \ | ||
63 | /* If sp > _ebss then we're OK. */ \ | ||
64 | mov.l .L_ebss, r1; \ | ||
65 | cmp/hi r1, r15; \ | ||
66 | bt 1f; \ | ||
67 | \ | ||
68 | /* If sp < init_stack, we're not OK. */ \ | ||
69 | mov.l .L_init_thread_union, r1; \ | ||
70 | cmp/hs r1, r15; \ | ||
71 | bf stack_panic; \ | ||
72 | \ | ||
73 | /* If sp > init_stack && sp < _ebss, not OK. */ \ | ||
74 | add r0, r1; \ | ||
75 | cmp/hs r1, r15; \ | ||
76 | bt stack_panic; \ | ||
77 | 1: | ||
78 | #else | ||
79 | #define STACK_CHECK() | ||
80 | #endif /* CONFIG_STACK_DEBUG */ | ||
81 | |||
31 | .align 2 | 82 | .align 2 |
32 | .globl _mcount | 83 | .globl _mcount |
33 | .type _mcount,@function | 84 | .type _mcount,@function |
@@ -35,6 +86,19 @@ | |||
35 | .type mcount,@function | 86 | .type mcount,@function |
36 | _mcount: | 87 | _mcount: |
37 | mcount: | 88 | mcount: |
89 | STACK_CHECK() | ||
90 | |||
91 | #ifndef CONFIG_FUNCTION_TRACER | ||
92 | rts | ||
93 | nop | ||
94 | #else | ||
95 | #ifndef CONFIG_DYNAMIC_FTRACE | ||
96 | mov.l .Lfunction_trace_stop, r0 | ||
97 | mov.l @r0, r0 | ||
98 | tst r0, r0 | ||
99 | bf ftrace_stub | ||
100 | #endif | ||
101 | |||
38 | MCOUNT_ENTER() | 102 | MCOUNT_ENTER() |
39 | 103 | ||
40 | #ifdef CONFIG_DYNAMIC_FTRACE | 104 | #ifdef CONFIG_DYNAMIC_FTRACE |
@@ -52,16 +116,69 @@ mcount_call: | |||
52 | jsr @r6 | 116 | jsr @r6 |
53 | nop | 117 | nop |
54 | 118 | ||
119 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
120 | mov.l .Lftrace_graph_return, r6 | ||
121 | mov.l .Lftrace_stub, r7 | ||
122 | cmp/eq r6, r7 | ||
123 | bt 1f | ||
124 | |||
125 | mov.l .Lftrace_graph_caller, r0 | ||
126 | jmp @r0 | ||
127 | nop | ||
128 | |||
129 | 1: | ||
130 | mov.l .Lftrace_graph_entry, r6 | ||
131 | mov.l .Lftrace_graph_entry_stub, r7 | ||
132 | cmp/eq r6, r7 | ||
133 | bt skip_trace | ||
134 | |||
135 | mov.l .Lftrace_graph_caller, r0 | ||
136 | jmp @r0 | ||
137 | nop | ||
138 | |||
139 | .align 2 | ||
140 | .Lftrace_graph_return: | ||
141 | .long ftrace_graph_return | ||
142 | .Lftrace_graph_entry: | ||
143 | .long ftrace_graph_entry | ||
144 | .Lftrace_graph_entry_stub: | ||
145 | .long ftrace_graph_entry_stub | ||
146 | .Lftrace_graph_caller: | ||
147 | .long ftrace_graph_caller | ||
148 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
149 | |||
150 | .globl skip_trace | ||
55 | skip_trace: | 151 | skip_trace: |
56 | MCOUNT_LEAVE() | 152 | MCOUNT_LEAVE() |
57 | 153 | ||
58 | .align 2 | 154 | .align 2 |
59 | .Lftrace_trace_function: | 155 | .Lftrace_trace_function: |
60 | .long ftrace_trace_function | 156 | .long ftrace_trace_function |
61 | 157 | ||
62 | #ifdef CONFIG_DYNAMIC_FTRACE | 158 | #ifdef CONFIG_DYNAMIC_FTRACE |
159 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
160 | /* | ||
161 | * NOTE: Do not move either ftrace_graph_call or ftrace_caller | ||
162 | * as this will affect the calculation of GRAPH_INSN_OFFSET. | ||
163 | */ | ||
164 | .globl ftrace_graph_call | ||
165 | ftrace_graph_call: | ||
166 | mov.l .Lskip_trace, r0 | ||
167 | jmp @r0 | ||
168 | nop | ||
169 | |||
170 | .align 2 | ||
171 | .Lskip_trace: | ||
172 | .long skip_trace | ||
173 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
174 | |||
63 | .globl ftrace_caller | 175 | .globl ftrace_caller |
64 | ftrace_caller: | 176 | ftrace_caller: |
177 | mov.l .Lfunction_trace_stop, r0 | ||
178 | mov.l @r0, r0 | ||
179 | tst r0, r0 | ||
180 | bf ftrace_stub | ||
181 | |||
65 | MCOUNT_ENTER() | 182 | MCOUNT_ENTER() |
66 | 183 | ||
67 | .globl ftrace_call | 184 | .globl ftrace_call |
@@ -70,9 +187,18 @@ ftrace_call: | |||
70 | jsr @r6 | 187 | jsr @r6 |
71 | nop | 188 | nop |
72 | 189 | ||
190 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
191 | bra ftrace_graph_call | ||
192 | nop | ||
193 | #else | ||
73 | MCOUNT_LEAVE() | 194 | MCOUNT_LEAVE() |
195 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
74 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 196 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
75 | 197 | ||
198 | .align 2 | ||
199 | .Lfunction_trace_stop: | ||
200 | .long function_trace_stop | ||
201 | |||
76 | /* | 202 | /* |
77 | * NOTE: From here on the locations of the .Lftrace_stub label and | 203 | * NOTE: From here on the locations of the .Lftrace_stub label and |
78 | * ftrace_stub itself are fixed. Adding additional data here will skew | 204 | * ftrace_stub itself are fixed. Adding additional data here will skew |
@@ -80,7 +206,6 @@ ftrace_call: | |||
80 | * Place new labels either after the ftrace_stub body, or before | 206 | * Place new labels either after the ftrace_stub body, or before |
81 | * ftrace_caller. You have been warned. | 207 | * ftrace_caller. You have been warned. |
82 | */ | 208 | */ |
83 | .align 2 | ||
84 | .Lftrace_stub: | 209 | .Lftrace_stub: |
85 | .long ftrace_stub | 210 | .long ftrace_stub |
86 | 211 | ||
@@ -88,3 +213,98 @@ ftrace_call: | |||
88 | ftrace_stub: | 213 | ftrace_stub: |
89 | rts | 214 | rts |
90 | nop | 215 | nop |
216 | |||
217 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
218 | .globl ftrace_graph_caller | ||
219 | ftrace_graph_caller: | ||
220 | mov.l 2f, r0 | ||
221 | mov.l @r0, r0 | ||
222 | tst r0, r0 | ||
223 | bt 1f | ||
224 | |||
225 | mov.l 3f, r1 | ||
226 | jmp @r1 | ||
227 | nop | ||
228 | 1: | ||
229 | /* | ||
230 | * MCOUNT_ENTER() pushed 5 registers onto the stack, so | ||
231 | * the stack address containing our return address is | ||
232 | * r15 + 20. | ||
233 | */ | ||
234 | mov #20, r0 | ||
235 | add r15, r0 | ||
236 | mov r0, r4 | ||
237 | |||
238 | mov.l .Lprepare_ftrace_return, r0 | ||
239 | jsr @r0 | ||
240 | nop | ||
241 | |||
242 | MCOUNT_LEAVE() | ||
243 | |||
244 | .align 2 | ||
245 | 2: .long function_trace_stop | ||
246 | 3: .long skip_trace | ||
247 | .Lprepare_ftrace_return: | ||
248 | .long prepare_ftrace_return | ||
249 | |||
250 | .globl return_to_handler | ||
251 | return_to_handler: | ||
252 | /* | ||
253 | * Save the return values. | ||
254 | */ | ||
255 | mov.l r0, @-r15 | ||
256 | mov.l r1, @-r15 | ||
257 | |||
258 | mov #0, r4 | ||
259 | |||
260 | mov.l .Lftrace_return_to_handler, r0 | ||
261 | jsr @r0 | ||
262 | nop | ||
263 | |||
264 | /* | ||
265 | * The return value from ftrace_return_handler has the real | ||
266 | * address that we should return to. | ||
267 | */ | ||
268 | lds r0, pr | ||
269 | mov.l @r15+, r1 | ||
270 | rts | ||
271 | mov.l @r15+, r0 | ||
272 | |||
273 | |||
274 | .align 2 | ||
275 | .Lftrace_return_to_handler: | ||
276 | .long ftrace_return_to_handler | ||
277 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
278 | #endif /* CONFIG_FUNCTION_TRACER */ | ||
279 | |||
280 | #ifdef CONFIG_STACK_DEBUG | ||
281 | .globl stack_panic | ||
282 | stack_panic: | ||
283 | mov.l .Ldump_stack, r0 | ||
284 | jsr @r0 | ||
285 | nop | ||
286 | |||
287 | mov.l .Lpanic, r0 | ||
288 | jsr @r0 | ||
289 | mov.l .Lpanic_s, r4 | ||
290 | |||
291 | rts | ||
292 | nop | ||
293 | |||
294 | .align 2 | ||
295 | .L_ebss: | ||
296 | .long _ebss | ||
297 | .L_init_thread_union: | ||
298 | .long init_thread_union | ||
299 | .Lpanic: | ||
300 | .long panic | ||
301 | .Lpanic_s: | ||
302 | .long .Lpanic_str | ||
303 | .Ldump_stack: | ||
304 | .long dump_stack | ||
305 | |||
306 | .section .rodata | ||
307 | .align 2 | ||
308 | .Lpanic_str: | ||
309 | .string "Stack error" | ||
310 | #endif /* CONFIG_STACK_DEBUG */ | ||