diff options
author | Nicolas Pitre <nicolas.pitre@linaro.org> | 2017-08-24 15:54:47 -0400 |
---|---|---|
committer | Nicolas Pitre <nicolas.pitre@linaro.org> | 2017-09-10 19:34:52 -0400 |
commit | 9520b1a1b5f7a34888e14de3cf2ee0ee5344e9fe (patch) | |
tree | 08d9c67e778a425d93af10bbaad866f61f447b1f | |
parent | 569dbb88e80deb68974ef6fdd6a13edb9d686261 (diff) |
ARM: head-common.S: speed up startup code
Let's use optimized routines such as memcpy to copy .data and memzero
to clear .bss in the startup code instead of doing it one word at a
time. Those routines don't use any global data so they're safe to use
even if .data and .bss segments are not initialized.
In the .data copy case a temporary stack is installed in the .bss area
as the actual kernel stack is located within the copied data area. The
XIP kernel linker script ensures a 8 byte alignment for that purpose.
Finally, make the .data copy and related pointers surrounded by
CONFIG_XIP_KERNEL to make it obvious what it is all about. This will
allow for further cleanups in the non-XIP linker script.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Chris Brandt <Chris.Brandt@renesas.com>
-rw-r--r-- | arch/arm/kernel/head-common.S | 76 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux-xip.lds.S | 2 |
2 files changed, 45 insertions, 33 deletions
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 8733012d231f..bf9c4e38eced 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -79,47 +79,59 @@ ENDPROC(__vet_atags) | |||
79 | */ | 79 | */ |
80 | __INIT | 80 | __INIT |
81 | __mmap_switched: | 81 | __mmap_switched: |
82 | adr r3, __mmap_switched_data | 82 | |
83 | 83 | mov r7, r1 | |
84 | ldmia r3!, {r4, r5, r6, r7} | 84 | mov r8, r2 |
85 | cmp r4, r5 @ Copy data segment if needed | 85 | mov r10, r0 |
86 | 1: cmpne r5, r6 | 86 | |
87 | ldrne fp, [r4], #4 | 87 | adr r4, __mmap_switched_data |
88 | strne fp, [r5], #4 | 88 | mov fp, #0 |
89 | bne 1b | 89 | |
90 | 90 | #ifdef CONFIG_XIP_KERNEL | |
91 | mov fp, #0 @ Clear BSS (and zero fp) | 91 | ARM( ldmia r4!, {r0, r1, r2, sp} ) |
92 | 1: cmp r6, r7 | 92 | THUMB( ldmia r4!, {r0, r1, r2, r3} ) |
93 | strcc fp, [r6],#4 | 93 | THUMB( mov sp, r3 ) |
94 | bcc 1b | 94 | sub r2, r2, r1 |
95 | 95 | bl memcpy @ copy .data to RAM | |
96 | ARM( ldmia r3, {r4, r5, r6, r7, sp}) | 96 | #endif |
97 | THUMB( ldmia r3, {r4, r5, r6, r7} ) | 97 | |
98 | THUMB( ldr sp, [r3, #16] ) | 98 | ARM( ldmia r4!, {r0, r1, sp} ) |
99 | str r9, [r4] @ Save processor ID | 99 | THUMB( ldmia r4!, {r0, r1, r3} ) |
100 | str r1, [r5] @ Save machine type | 100 | THUMB( mov sp, r3 ) |
101 | str r2, [r6] @ Save atags pointer | 101 | sub r1, r1, r0 |
102 | cmp r7, #0 | 102 | bl __memzero @ clear .bss |
103 | strne r0, [r7] @ Save control register values | 103 | |
104 | ldmia r4, {r0, r1, r2, r3} | ||
105 | str r9, [r0] @ Save processor ID | ||
106 | str r7, [r1] @ Save machine type | ||
107 | str r8, [r2] @ Save atags pointer | ||
108 | cmp r3, #0 | ||
109 | strne r10, [r3] @ Save control register values | ||
104 | b start_kernel | 110 | b start_kernel |
105 | ENDPROC(__mmap_switched) | 111 | ENDPROC(__mmap_switched) |
106 | 112 | ||
107 | .align 2 | 113 | .align 2 |
108 | .type __mmap_switched_data, %object | 114 | .type __mmap_switched_data, %object |
109 | __mmap_switched_data: | 115 | __mmap_switched_data: |
110 | .long __data_loc @ r4 | 116 | #ifdef CONFIG_XIP_KERNEL |
111 | .long _sdata @ r5 | 117 | .long _sdata @ r0 |
112 | .long __bss_start @ r6 | 118 | .long __data_loc @ r1 |
113 | .long _end @ r7 | 119 | .long _edata_loc @ r2 |
114 | .long processor_id @ r4 | 120 | .long __bss_stop @ sp (temporary stack in .bss) |
115 | .long __machine_arch_type @ r5 | 121 | #endif |
116 | .long __atags_pointer @ r6 | 122 | |
123 | .long __bss_start @ r0 | ||
124 | .long __bss_stop @ r1 | ||
125 | .long init_thread_union + THREAD_START_SP @ sp | ||
126 | |||
127 | .long processor_id @ r0 | ||
128 | .long __machine_arch_type @ r1 | ||
129 | .long __atags_pointer @ r2 | ||
117 | #ifdef CONFIG_CPU_CP15 | 130 | #ifdef CONFIG_CPU_CP15 |
118 | .long cr_alignment @ r7 | 131 | .long cr_alignment @ r3 |
119 | #else | 132 | #else |
120 | .long 0 @ r7 | 133 | .long 0 @ r3 |
121 | #endif | 134 | #endif |
122 | .long init_thread_union + THREAD_START_SP @ sp | ||
123 | .size __mmap_switched_data, . - __mmap_switched_data | 135 | .size __mmap_switched_data, . - __mmap_switched_data |
124 | 136 | ||
125 | /* | 137 | /* |
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index 8265b116218d..1598caada3bb 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S | |||
@@ -301,7 +301,7 @@ SECTIONS | |||
301 | } | 301 | } |
302 | #endif | 302 | #endif |
303 | 303 | ||
304 | BSS_SECTION(0, 0, 0) | 304 | BSS_SECTION(0, 0, 8) |
305 | _end = .; | 305 | _end = .; |
306 | 306 | ||
307 | STABS_DEBUG | 307 | STABS_DEBUG |