diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-22 17:46:24 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-22 17:46:24 -0500 |
commit | 25cf0398bdf365d027e171116aa4a281e9cd3c1c (patch) | |
tree | a8be3d3d314625a376be0e62c67809dc22274dd4 /arch/arm/kernel | |
parent | 9326845f45650f6af9953a4b6a31e89b54fab82f (diff) | |
parent | 59bdd133561a432c4655146e283caf85fa64c2fb (diff) |
Merge branch 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6 into devel-stable
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 7 | ||||
-rw-r--r-- | arch/arm/kernel/iwmmxt.S | 55 | ||||
-rw-r--r-- | arch/arm/kernel/pj4-cp0.c | 94 | ||||
-rw-r--r-- | arch/arm/kernel/relocate_kernel.S | 2 |
6 files changed, 147 insertions, 14 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 679851a9f589..c73abe4b7e72 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -51,6 +51,7 @@ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 | |||
51 | obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o | 51 | obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o |
52 | obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o | 52 | obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o |
53 | obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o | 53 | obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o |
54 | obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o | ||
54 | obj-$(CONFIG_IWMMXT) += iwmmxt.o | 55 | obj-$(CONFIG_IWMMXT) += iwmmxt.o |
55 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o | 56 | obj-$(CONFIG_CPU_HAS_PMU) += pmu.o |
56 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o | 57 | obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 34bbef0d2e7e..36199ffc4cc2 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -915,7 +915,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
915 | * A special ghost syscall is used for that (see traps.c). | 915 | * A special ghost syscall is used for that (see traps.c). |
916 | */ | 916 | */ |
917 | stmfd sp!, {r7, lr} | 917 | stmfd sp!, {r7, lr} |
918 | ldr r7, =1f @ it's 20 bits | 918 | ldr r7, 1f @ it's 20 bits |
919 | swi __ARM_NR_cmpxchg | 919 | swi __ARM_NR_cmpxchg |
920 | ldmfd sp!, {r7, pc} | 920 | ldmfd sp!, {r7, pc} |
921 | 1: .word __ARM_NR_cmpxchg | 921 | 1: .word __ARM_NR_cmpxchg |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index dd6b369ac69c..6bd82d25683c 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -85,9 +85,11 @@ ENTRY(stext) | |||
85 | mrc p15, 0, r9, c0, c0 @ get processor id | 85 | mrc p15, 0, r9, c0, c0 @ get processor id |
86 | bl __lookup_processor_type @ r5=procinfo r9=cpuid | 86 | bl __lookup_processor_type @ r5=procinfo r9=cpuid |
87 | movs r10, r5 @ invalid processor (r5=0)? | 87 | movs r10, r5 @ invalid processor (r5=0)? |
88 | THUMB( it eq ) @ force fixup-able long branch encoding | ||
88 | beq __error_p @ yes, error 'p' | 89 | beq __error_p @ yes, error 'p' |
89 | bl __lookup_machine_type @ r5=machinfo | 90 | bl __lookup_machine_type @ r5=machinfo |
90 | movs r8, r5 @ invalid machine (r5=0)? | 91 | movs r8, r5 @ invalid machine (r5=0)? |
92 | THUMB( it eq ) @ force fixup-able long branch encoding | ||
91 | beq __error_a @ yes, error 'a' | 93 | beq __error_a @ yes, error 'a' |
92 | bl __vet_atags | 94 | bl __vet_atags |
93 | #ifdef CONFIG_SMP_ON_UP | 95 | #ifdef CONFIG_SMP_ON_UP |
@@ -262,6 +264,7 @@ __create_page_tables: | |||
262 | mov pc, lr | 264 | mov pc, lr |
263 | ENDPROC(__create_page_tables) | 265 | ENDPROC(__create_page_tables) |
264 | .ltorg | 266 | .ltorg |
267 | .align | ||
265 | __enable_mmu_loc: | 268 | __enable_mmu_loc: |
266 | .long . | 269 | .long . |
267 | .long __enable_mmu | 270 | .long __enable_mmu |
@@ -282,6 +285,7 @@ ENTRY(secondary_startup) | |||
282 | bl __lookup_processor_type | 285 | bl __lookup_processor_type |
283 | movs r10, r5 @ invalid processor? | 286 | movs r10, r5 @ invalid processor? |
284 | moveq r0, #'p' @ yes, error 'p' | 287 | moveq r0, #'p' @ yes, error 'p' |
288 | THUMB( it eq ) @ force fixup-able long branch encoding | ||
285 | beq __error_p | 289 | beq __error_p |
286 | 290 | ||
287 | /* | 291 | /* |
@@ -308,6 +312,8 @@ ENTRY(__secondary_switched) | |||
308 | b secondary_start_kernel | 312 | b secondary_start_kernel |
309 | ENDPROC(__secondary_switched) | 313 | ENDPROC(__secondary_switched) |
310 | 314 | ||
315 | .align | ||
316 | |||
311 | .type __secondary_data, %object | 317 | .type __secondary_data, %object |
312 | __secondary_data: | 318 | __secondary_data: |
313 | .long . | 319 | .long . |
@@ -413,6 +419,7 @@ __fixup_smp_on_up: | |||
413 | mov pc, lr | 419 | mov pc, lr |
414 | ENDPROC(__fixup_smp) | 420 | ENDPROC(__fixup_smp) |
415 | 421 | ||
422 | .align | ||
416 | 1: .word . | 423 | 1: .word . |
417 | .word __smpalt_begin | 424 | .word __smpalt_begin |
418 | .word __smpalt_end | 425 | .word __smpalt_end |
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index b63b528f22a6..7fa3bb0d2397 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S | |||
@@ -19,6 +19,14 @@ | |||
19 | #include <asm/thread_info.h> | 19 | #include <asm/thread_info.h> |
20 | #include <asm/asm-offsets.h> | 20 | #include <asm/asm-offsets.h> |
21 | 21 | ||
22 | #if defined(CONFIG_CPU_PJ4) | ||
23 | #define PJ4(code...) code | ||
24 | #define XSC(code...) | ||
25 | #else | ||
26 | #define PJ4(code...) | ||
27 | #define XSC(code...) code | ||
28 | #endif | ||
29 | |||
22 | #define MMX_WR0 (0x00) | 30 | #define MMX_WR0 (0x00) |
23 | #define MMX_WR1 (0x08) | 31 | #define MMX_WR1 (0x08) |
24 | #define MMX_WR2 (0x10) | 32 | #define MMX_WR2 (0x10) |
@@ -58,11 +66,17 @@ | |||
58 | 66 | ||
59 | ENTRY(iwmmxt_task_enable) | 67 | ENTRY(iwmmxt_task_enable) |
60 | 68 | ||
61 | mrc p15, 0, r2, c15, c1, 0 | 69 | XSC(mrc p15, 0, r2, c15, c1, 0) |
62 | tst r2, #0x3 @ CP0 and CP1 accessible? | 70 | PJ4(mrc p15, 0, r2, c1, c0, 2) |
71 | @ CP0 and CP1 accessible? | ||
72 | XSC(tst r2, #0x3) | ||
73 | PJ4(tst r2, #0xf) | ||
63 | movne pc, lr @ if so no business here | 74 | movne pc, lr @ if so no business here |
64 | orr r2, r2, #0x3 @ enable access to CP0 and CP1 | 75 | @ enable access to CP0 and CP1 |
65 | mcr p15, 0, r2, c15, c1, 0 | 76 | XSC(orr r2, r2, #0x3) |
77 | XSC(mcr p15, 0, r2, c15, c1, 0) | ||
78 | PJ4(orr r2, r2, #0xf) | ||
79 | PJ4(mcr p15, 0, r2, c1, c0, 2) | ||
66 | 80 | ||
67 | ldr r3, =concan_owner | 81 | ldr r3, =concan_owner |
68 | add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area | 82 | add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area |
@@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable) | |||
179 | teqne r1, r2 @ or specified one? | 193 | teqne r1, r2 @ or specified one? |
180 | bne 1f @ no: quit | 194 | bne 1f @ no: quit |
181 | 195 | ||
182 | mrc p15, 0, r4, c15, c1, 0 | 196 | @ enable access to CP0 and CP1 |
183 | orr r4, r4, #0x3 @ enable access to CP0 and CP1 | 197 | XSC(mrc p15, 0, r4, c15, c1, 0) |
184 | mcr p15, 0, r4, c15, c1, 0 | 198 | XSC(orr r4, r4, #0xf) |
199 | XSC(mcr p15, 0, r4, c15, c1, 0) | ||
200 | PJ4(mrc p15, 0, r4, c1, c0, 2) | ||
201 | PJ4(orr r4, r4, #0x3) | ||
202 | PJ4(mcr p15, 0, r4, c1, c0, 2) | ||
203 | |||
185 | mov r0, #0 @ nothing to load | 204 | mov r0, #0 @ nothing to load |
186 | str r0, [r3] @ no more current owner | 205 | str r0, [r3] @ no more current owner |
187 | mrc p15, 0, r2, c2, c0, 0 | 206 | mrc p15, 0, r2, c2, c0, 0 |
188 | mov r2, r2 @ cpwait | 207 | mov r2, r2 @ cpwait |
189 | bl concan_save | 208 | bl concan_save |
190 | 209 | ||
191 | bic r4, r4, #0x3 @ disable access to CP0 and CP1 | 210 | @ disable access to CP0 and CP1 |
192 | mcr p15, 0, r4, c15, c1, 0 | 211 | XSC(bic r4, r4, #0x3) |
212 | XSC(mcr p15, 0, r4, c15, c1, 0) | ||
213 | PJ4(bic r4, r4, #0xf) | ||
214 | PJ4(mcr p15, 0, r4, c1, c0, 2) | ||
215 | |||
193 | mrc p15, 0, r2, c2, c0, 0 | 216 | mrc p15, 0, r2, c2, c0, 0 |
194 | mov r2, r2 @ cpwait | 217 | mov r2, r2 @ cpwait |
195 | 218 | ||
@@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore) | |||
277 | */ | 300 | */ |
278 | ENTRY(iwmmxt_task_switch) | 301 | ENTRY(iwmmxt_task_switch) |
279 | 302 | ||
280 | mrc p15, 0, r1, c15, c1, 0 | 303 | XSC(mrc p15, 0, r1, c15, c1, 0) |
281 | tst r1, #0x3 @ CP0 and CP1 accessible? | 304 | PJ4(mrc p15, 0, r1, c1, c0, 2) |
305 | @ CP0 and CP1 accessible? | ||
306 | XSC(tst r1, #0x3) | ||
307 | PJ4(tst r1, #0xf) | ||
282 | bne 1f @ yes: block them for next task | 308 | bne 1f @ yes: block them for next task |
283 | 309 | ||
284 | ldr r2, =concan_owner | 310 | ldr r2, =concan_owner |
@@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch) | |||
287 | teq r2, r3 @ next task owns it? | 313 | teq r2, r3 @ next task owns it? |
288 | movne pc, lr @ no: leave Concan disabled | 314 | movne pc, lr @ no: leave Concan disabled |
289 | 315 | ||
290 | 1: eor r1, r1, #3 @ flip Concan access | 316 | 1: @ flip Conan access |
291 | mcr p15, 0, r1, c15, c1, 0 | 317 | XSC(eor r1, r1, #0x3) |
318 | XSC(mcr p15, 0, r1, c15, c1, 0) | ||
319 | PJ4(eor r1, r1, #0xf) | ||
320 | PJ4(mcr p15, 0, r1, c1, c0, 2) | ||
292 | 321 | ||
293 | mrc p15, 0, r1, c2, c0, 0 | 322 | mrc p15, 0, r1, c2, c0, 0 |
294 | sub pc, lr, r1, lsr #32 @ cpwait and return | 323 | sub pc, lr, r1, lsr #32 @ cpwait and return |
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c new file mode 100644 index 000000000000..a4b1b0748fd3 --- /dev/null +++ b/arch/arm/kernel/pj4-cp0.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/pj4-cp0.c | ||
3 | * | ||
4 | * PJ4 iWMMXt coprocessor context switching and handling | ||
5 | * | ||
6 | * Copyright (c) 2010 Marvell International Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/signal.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <asm/thread_notify.h> | ||
21 | |||
22 | static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) | ||
23 | { | ||
24 | struct thread_info *thread = t; | ||
25 | |||
26 | switch (cmd) { | ||
27 | case THREAD_NOTIFY_FLUSH: | ||
28 | /* | ||
29 | * flush_thread() zeroes thread->fpstate, so no need | ||
30 | * to do anything here. | ||
31 | * | ||
32 | * FALLTHROUGH: Ensure we don't try to overwrite our newly | ||
33 | * initialised state information on the first fault. | ||
34 | */ | ||
35 | |||
36 | case THREAD_NOTIFY_EXIT: | ||
37 | iwmmxt_task_release(thread); | ||
38 | break; | ||
39 | |||
40 | case THREAD_NOTIFY_SWITCH: | ||
41 | iwmmxt_task_switch(thread); | ||
42 | break; | ||
43 | } | ||
44 | |||
45 | return NOTIFY_DONE; | ||
46 | } | ||
47 | |||
48 | static struct notifier_block iwmmxt_notifier_block = { | ||
49 | .notifier_call = iwmmxt_do, | ||
50 | }; | ||
51 | |||
52 | |||
53 | static u32 __init pj4_cp_access_read(void) | ||
54 | { | ||
55 | u32 value; | ||
56 | |||
57 | __asm__ __volatile__ ( | ||
58 | "mrc p15, 0, %0, c1, c0, 2\n\t" | ||
59 | : "=r" (value)); | ||
60 | return value; | ||
61 | } | ||
62 | |||
63 | static void __init pj4_cp_access_write(u32 value) | ||
64 | { | ||
65 | u32 temp; | ||
66 | |||
67 | __asm__ __volatile__ ( | ||
68 | "mcr p15, 0, %1, c1, c0, 2\n\t" | ||
69 | "mrc p15, 0, %0, c1, c0, 2\n\t" | ||
70 | "mov %0, %0\n\t" | ||
71 | "sub pc, pc, #4\n\t" | ||
72 | : "=r" (temp) : "r" (value)); | ||
73 | } | ||
74 | |||
75 | |||
76 | /* | ||
77 | * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy | ||
78 | * switch code handle iWMMXt context switching. | ||
79 | */ | ||
80 | static int __init pj4_cp0_init(void) | ||
81 | { | ||
82 | u32 cp_access; | ||
83 | |||
84 | cp_access = pj4_cp_access_read() & ~0xf; | ||
85 | pj4_cp_access_write(cp_access); | ||
86 | |||
87 | printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); | ||
88 | elf_hwcap |= HWCAP_IWMMXT; | ||
89 | thread_register_notifier(&iwmmxt_notifier_block); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | late_initcall(pj4_cp0_init); | ||
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index fd26f8d65151..9cf4cbf8f95b 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S | |||
@@ -59,6 +59,8 @@ relocate_new_kernel: | |||
59 | ldr r2,kexec_boot_atags | 59 | ldr r2,kexec_boot_atags |
60 | mov pc,lr | 60 | mov pc,lr |
61 | 61 | ||
62 | .align | ||
63 | |||
62 | .globl kexec_start_address | 64 | .globl kexec_start_address |
63 | kexec_start_address: | 65 | kexec_start_address: |
64 | .long 0x0 | 66 | .long 0x0 |