diff options
Diffstat (limited to 'arch/xtensa/kernel/head.S')
-rw-r--r-- | arch/xtensa/kernel/head.S | 181 |
1 files changed, 137 insertions, 44 deletions
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 7d740ebbe198..aeeb3cc8a410 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
20 | #include <asm/cacheasm.h> | 20 | #include <asm/cacheasm.h> |
21 | #include <asm/initialize_mmu.h> | 21 | #include <asm/initialize_mmu.h> |
22 | #include <asm/mxregs.h> | ||
22 | 23 | ||
23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
24 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
@@ -54,7 +55,7 @@ ENTRY(_start) | |||
54 | 55 | ||
55 | /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ | 56 | /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ |
56 | wsr a2, excsave1 | 57 | wsr a2, excsave1 |
57 | _j _SetupMMU | 58 | _j _SetupOCD |
58 | 59 | ||
59 | .align 4 | 60 | .align 4 |
60 | .literal_position | 61 | .literal_position |
@@ -62,6 +63,23 @@ ENTRY(_start) | |||
62 | .word _startup | 63 | .word _startup |
63 | 64 | ||
64 | .align 4 | 65 | .align 4 |
66 | _SetupOCD: | ||
67 | /* | ||
68 | * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). | ||
69 | * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow | ||
70 | * xt-gdb to single step via DEBUG exceptions received directly | ||
71 | * by ocd. | ||
72 | */ | ||
73 | movi a1, 1 | ||
74 | movi a0, 0 | ||
75 | wsr a1, windowstart | ||
76 | wsr a0, windowbase | ||
77 | rsync | ||
78 | |||
79 | movi a1, LOCKLEVEL | ||
80 | wsr a1, ps | ||
81 | rsync | ||
82 | |||
65 | .global _SetupMMU | 83 | .global _SetupMMU |
66 | _SetupMMU: | 84 | _SetupMMU: |
67 | Offset = _SetupMMU - _start | 85 | Offset = _SetupMMU - _start |
@@ -85,24 +103,11 @@ _SetupMMU: | |||
85 | 103 | ||
86 | ENDPROC(_start) | 104 | ENDPROC(_start) |
87 | 105 | ||
88 | __INIT | 106 | __REF |
89 | .literal_position | 107 | .literal_position |
90 | 108 | ||
91 | ENTRY(_startup) | 109 | ENTRY(_startup) |
92 | 110 | ||
93 | /* Disable interrupts and exceptions. */ | ||
94 | |||
95 | movi a0, LOCKLEVEL | ||
96 | wsr a0, ps | ||
97 | |||
98 | /* Start with a fresh windowbase and windowstart. */ | ||
99 | |||
100 | movi a1, 1 | ||
101 | movi a0, 0 | ||
102 | wsr a1, windowstart | ||
103 | wsr a0, windowbase | ||
104 | rsync | ||
105 | |||
106 | /* Set a0 to 0 for the remaining initialization. */ | 111 | /* Set a0 to 0 for the remaining initialization. */ |
107 | 112 | ||
108 | movi a0, 0 | 113 | movi a0, 0 |
@@ -154,17 +159,6 @@ ENTRY(_startup) | |||
154 | wsr a0, cpenable | 159 | wsr a0, cpenable |
155 | #endif | 160 | #endif |
156 | 161 | ||
157 | /* Set PS.INTLEVEL=LOCKLEVEL, PS.WOE=0, kernel stack, PS.EXCM=0 | ||
158 | * | ||
159 | * Note: PS.EXCM must be cleared before using any loop | ||
160 | * instructions; otherwise, they are silently disabled, and | ||
161 | * at most one iteration of the loop is executed. | ||
162 | */ | ||
163 | |||
164 | movi a1, LOCKLEVEL | ||
165 | wsr a1, ps | ||
166 | rsync | ||
167 | |||
168 | /* Initialize the caches. | 162 | /* Initialize the caches. |
169 | * a2, a3 are just working registers (clobbered). | 163 | * a2, a3 are just working registers (clobbered). |
170 | */ | 164 | */ |
@@ -182,6 +176,37 @@ ENTRY(_startup) | |||
182 | 176 | ||
183 | isync | 177 | isync |
184 | 178 | ||
179 | #ifdef CONFIG_HAVE_SMP | ||
180 | movi a2, CCON # MX External Register to Configure Cache | ||
181 | movi a3, 1 | ||
182 | wer a3, a2 | ||
183 | #endif | ||
184 | |||
185 | /* Setup stack and enable window exceptions (keep irqs disabled) */ | ||
186 | |||
187 | movi a1, start_info | ||
188 | l32i a1, a1, 0 | ||
189 | |||
190 | movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL | ||
191 | # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 | ||
192 | wsr a2, ps # (enable reg-windows; progmode stack) | ||
193 | rsync | ||
194 | |||
195 | /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/ | ||
196 | |||
197 | movi a2, debug_exception | ||
198 | wsr a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL | ||
199 | |||
200 | #ifdef CONFIG_SMP | ||
201 | /* | ||
202 | * Notice that we assume with SMP that cores have PRID | ||
203 | * supported by the cores. | ||
204 | */ | ||
205 | rsr a2, prid | ||
206 | bnez a2, .Lboot_secondary | ||
207 | |||
208 | #endif /* CONFIG_SMP */ | ||
209 | |||
185 | /* Unpack data sections | 210 | /* Unpack data sections |
186 | * | 211 | * |
187 | * The linker script used to build the Linux kernel image | 212 | * The linker script used to build the Linux kernel image |
@@ -234,24 +259,7 @@ ENTRY(_startup) | |||
234 | ___invalidate_icache_all a2 a3 | 259 | ___invalidate_icache_all a2 a3 |
235 | isync | 260 | isync |
236 | 261 | ||
237 | /* Setup stack and enable window exceptions (keep irqs disabled) */ | 262 | movi a6, 0 |
238 | |||
239 | movi a1, init_thread_union | ||
240 | addi a1, a1, KERNEL_STACK_SIZE | ||
241 | |||
242 | movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL | ||
243 | # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 | ||
244 | wsr a2, ps # (enable reg-windows; progmode stack) | ||
245 | rsync | ||
246 | |||
247 | /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/ | ||
248 | |||
249 | movi a2, debug_exception | ||
250 | wsr a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL | ||
251 | |||
252 | /* Set up EXCSAVE[1] to point to the exc_table. */ | ||
253 | |||
254 | movi a6, exc_table | ||
255 | xsr a6, excsave1 | 263 | xsr a6, excsave1 |
256 | 264 | ||
257 | /* init_arch kick-starts the linux kernel */ | 265 | /* init_arch kick-starts the linux kernel */ |
@@ -265,8 +273,93 @@ ENTRY(_startup) | |||
265 | should_never_return: | 273 | should_never_return: |
266 | j should_never_return | 274 | j should_never_return |
267 | 275 | ||
276 | #ifdef CONFIG_SMP | ||
277 | .Lboot_secondary: | ||
278 | |||
279 | movi a2, cpu_start_ccount | ||
280 | 1: | ||
281 | l32i a3, a2, 0 | ||
282 | beqi a3, 0, 1b | ||
283 | movi a3, 0 | ||
284 | s32i a3, a2, 0 | ||
285 | memw | ||
286 | 1: | ||
287 | l32i a3, a2, 0 | ||
288 | beqi a3, 0, 1b | ||
289 | wsr a3, ccount | ||
290 | movi a3, 0 | ||
291 | s32i a3, a2, 0 | ||
292 | memw | ||
293 | |||
294 | movi a6, 0 | ||
295 | wsr a6, excsave1 | ||
296 | |||
297 | movi a4, secondary_start_kernel | ||
298 | callx4 a4 | ||
299 | j should_never_return | ||
300 | |||
301 | #endif /* CONFIG_SMP */ | ||
302 | |||
268 | ENDPROC(_startup) | 303 | ENDPROC(_startup) |
269 | 304 | ||
305 | #ifdef CONFIG_HOTPLUG_CPU | ||
306 | |||
307 | ENTRY(cpu_restart) | ||
308 | |||
309 | #if XCHAL_DCACHE_IS_WRITEBACK | ||
310 | ___flush_invalidate_dcache_all a2 a3 | ||
311 | #else | ||
312 | ___invalidate_dcache_all a2 a3 | ||
313 | #endif | ||
314 | memw | ||
315 | movi a2, CCON # MX External Register to Configure Cache | ||
316 | movi a3, 0 | ||
317 | wer a3, a2 | ||
318 | extw | ||
319 | |||
320 | rsr a0, prid | ||
321 | neg a2, a0 | ||
322 | movi a3, cpu_start_id | ||
323 | s32i a2, a3, 0 | ||
324 | #if XCHAL_DCACHE_IS_WRITEBACK | ||
325 | dhwbi a3, 0 | ||
326 | #endif | ||
327 | 1: | ||
328 | l32i a2, a3, 0 | ||
329 | dhi a3, 0 | ||
330 | bne a2, a0, 1b | ||
331 | |||
332 | /* | ||
333 | * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions). | ||
334 | * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow | ||
335 | * xt-gdb to single step via DEBUG exceptions received directly | ||
336 | * by ocd. | ||
337 | */ | ||
338 | movi a1, 1 | ||
339 | movi a0, 0 | ||
340 | wsr a1, windowstart | ||
341 | wsr a0, windowbase | ||
342 | rsync | ||
343 | |||
344 | movi a1, LOCKLEVEL | ||
345 | wsr a1, ps | ||
346 | rsync | ||
347 | |||
348 | j _startup | ||
349 | |||
350 | ENDPROC(cpu_restart) | ||
351 | |||
352 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
353 | |||
354 | /* | ||
355 | * DATA section | ||
356 | */ | ||
357 | |||
358 | .section ".data.init.refok" | ||
359 | .align 4 | ||
360 | ENTRY(start_info) | ||
361 | .long init_thread_union + KERNEL_STACK_SIZE | ||
362 | |||
270 | /* | 363 | /* |
271 | * BSS section | 364 | * BSS section |
272 | */ | 365 | */ |