aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-04-24 01:31:45 -0400
committerNicolas Pitre <nico@cam.org>2008-04-28 16:06:51 -0400
commit0ed1507183adea174bc4b6611b50d90e044730c2 (patch)
treec6f917503593997467052dcc5963e8387fb67f94
parent6b29e681aa7e80792e6e6be4ac2577014018c2fd (diff)
[ARM] Feroceon: Feroceon-specific WA-cache compatible {copy,clear}_user_page()
This patch implements a set of Feroceon-specific {copy,clear}_user_page() routines that perform more optimally than the generic implementations. This also deals with write-allocate caches (Feroceon can run L1 D in WA mode) which otherwise prevents Linux from booting. [nico: optimized the code even further] Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Tested-by: Sylver Bruneau <sylver.bruneau@googlemail.com> Tested-by: Martin Michlmayr <tbm@cyrius.com> Signed-off-by: Nicolas Pitre <nico@marvell.com>
-rw-r--r--arch/arm/mm/Kconfig5
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/copypage-feroceon.S95
-rw-r--r--arch/arm/mm/proc-feroceon.S4
-rw-r--r--include/asm-arm/page.h8
5 files changed, 110 insertions, 3 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index a92a577c1b65..33ed048502a3 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -372,7 +372,7 @@ config CPU_FEROCEON
372 select CPU_PABRT_NOIFAR 372 select CPU_PABRT_NOIFAR
373 select CPU_CACHE_VIVT 373 select CPU_CACHE_VIVT
374 select CPU_CP15_MMU 374 select CPU_CP15_MMU
375 select CPU_COPY_V4WB if MMU 375 select CPU_COPY_FEROCEON if MMU
376 select CPU_TLB_V4WBI if MMU 376 select CPU_TLB_V4WBI if MMU
377 377
378config CPU_FEROCEON_OLD_ID 378config CPU_FEROCEON_OLD_ID
@@ -523,6 +523,9 @@ config CPU_COPY_V4WT
523config CPU_COPY_V4WB 523config CPU_COPY_V4WB
524 bool 524 bool
525 525
526config CPU_COPY_FEROCEON
527 bool
528
526config CPU_COPY_V6 529config CPU_COPY_V6
527 bool 530 bool
528 531
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 44536a0b995a..32b2d2d213a6 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
36obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o 36obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
37obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o 37obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
38obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o 38obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
39obj-$(CONFIG_CPU_COPY_FEROCEON) += copypage-feroceon.o
39obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o 40obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o
40obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o 41obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
41obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o 42obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
diff --git a/arch/arm/mm/copypage-feroceon.S b/arch/arm/mm/copypage-feroceon.S
new file mode 100644
index 000000000000..7eb0d320d240
--- /dev/null
+++ b/arch/arm/mm/copypage-feroceon.S
@@ -0,0 +1,95 @@
1/*
2 * linux/arch/arm/lib/copypage-feroceon.S
3 *
4 * Copyright (C) 2008 Marvell Semiconductors
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This handles copy_user_page and clear_user_page on Feroceon
11 * more optimally than the generic implementations.
12 */
13#include <linux/linkage.h>
14#include <linux/init.h>
15#include <asm/asm-offsets.h>
16
17 .text
18 .align 5
19
20ENTRY(feroceon_copy_user_page)
21 stmfd sp!, {r4-r9, lr}
22 mov ip, #PAGE_SZ
231: mov lr, r1
24 ldmia r1!, {r2 - r9}
25 pld [lr, #32]
26 pld [lr, #64]
27 pld [lr, #96]
28 pld [lr, #128]
29 pld [lr, #160]
30 pld [lr, #192]
31 pld [lr, #224]
32 stmia r0, {r2 - r9}
33 ldmia r1!, {r2 - r9}
34 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
35 add r0, r0, #32
36 stmia r0, {r2 - r9}
37 ldmia r1!, {r2 - r9}
38 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
39 add r0, r0, #32
40 stmia r0, {r2 - r9}
41 ldmia r1!, {r2 - r9}
42 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
43 add r0, r0, #32
44 stmia r0, {r2 - r9}
45 ldmia r1!, {r2 - r9}
46 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
47 add r0, r0, #32
48 stmia r0, {r2 - r9}
49 ldmia r1!, {r2 - r9}
50 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
51 add r0, r0, #32
52 stmia r0, {r2 - r9}
53 ldmia r1!, {r2 - r9}
54 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
55 add r0, r0, #32
56 stmia r0, {r2 - r9}
57 ldmia r1!, {r2 - r9}
58 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
59 add r0, r0, #32
60 stmia r0, {r2 - r9}
61 subs ip, ip, #(32 * 8)
62 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
63 add r0, r0, #32
64 bne 1b
65 mcr p15, 0, ip, c7, c10, 4 @ drain WB
66 ldmfd sp!, {r4-r9, pc}
67
68 .align 5
69
70ENTRY(feroceon_clear_user_page)
71 stmfd sp!, {r4-r7, lr}
72 mov r1, #PAGE_SZ/32
73 mov r2, #0
74 mov r3, #0
75 mov r4, #0
76 mov r5, #0
77 mov r6, #0
78 mov r7, #0
79 mov ip, #0
80 mov lr, #0
811: stmia r0, {r2-r7, ip, lr}
82 subs r1, r1, #1
83 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line
84 add r0, r0, #32
85 bne 1b
86 mcr p15, 0, r1, c7, c10, 4 @ drain WB
87 ldmfd sp!, {r4-r7, pc}
88
89 __INITDATA
90
91 .type feroceon_user_fns, #object
92ENTRY(feroceon_user_fns)
93 .long feroceon_clear_user_page
94 .long feroceon_copy_user_page
95 .size feroceon_user_fns, . - feroceon_user_fns
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index f37abd710562..a02c1712b52d 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -440,7 +440,7 @@ __feroceon_old_id_proc_info:
440 .long cpu_feroceon_name 440 .long cpu_feroceon_name
441 .long feroceon_processor_functions 441 .long feroceon_processor_functions
442 .long v4wbi_tlb_fns 442 .long v4wbi_tlb_fns
443 .long v4wb_user_fns 443 .long feroceon_user_fns
444 .long feroceon_cache_fns 444 .long feroceon_cache_fns
445 .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info 445 .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
446#endif 446#endif
@@ -466,6 +466,6 @@ __feroceon_proc_info:
466 .long cpu_feroceon_name 466 .long cpu_feroceon_name
467 .long feroceon_processor_functions 467 .long feroceon_processor_functions
468 .long v4wbi_tlb_fns 468 .long v4wbi_tlb_fns
469 .long v4wb_user_fns 469 .long feroceon_user_fns
470 .long feroceon_cache_fns 470 .long feroceon_cache_fns
471 .size __feroceon_proc_info, . - __feroceon_proc_info 471 .size __feroceon_proc_info, . - __feroceon_proc_info
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index c86f68ee6511..5c22b0112106 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -71,6 +71,14 @@
71# endif 71# endif
72#endif 72#endif
73 73
74#ifdef CONFIG_CPU_COPY_FEROCEON
75# ifdef _USER
76# define MULTI_USER 1
77# else
78# define _USER feroceon
79# endif
80#endif
81
74#ifdef CONFIG_CPU_SA1100 82#ifdef CONFIG_CPU_SA1100
75# ifdef _USER 83# ifdef _USER
76# define MULTI_USER 1 84# define MULTI_USER 1