Merge branch 'regmap-5.3' into regmap-next
[linux-2.6-block.git] / arch / xtensa / kernel / head.S
CommitLineData
5a0015d6
CZ
1/*
2 * arch/xtensa/kernel/head.S
3 *
4 * Xtensa Processor startup code.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
2d1c645c 10 * Copyright (C) 2001 - 2008 Tensilica Inc.
5a0015d6
CZ
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
15 * Kevin Chea
16 */
17
5a0015d6
CZ
18#include <asm/processor.h>
19#include <asm/page.h>
173d6681 20#include <asm/cacheasm.h>
c622b29d 21#include <asm/initialize_mmu.h>
f615136c 22#include <asm/mxregs.h>
5a0015d6 23
0ebdcb4d 24#include <linux/init.h>
adba09f0
CZ
25#include <linux/linkage.h>
26
5a0015d6
CZ
27/*
28 * This module contains the entry code for kernel images. It performs the
29 * minimal setup needed to call the generic C routines.
30 *
31 * Prerequisites:
32 *
33 * - The kernel image has been loaded to the actual address where it was
34 * compiled to.
35 * - a2 contains either 0 or a pointer to a list of boot parameters.
36 * (see setup.c for more details)
37 *
38 */
39
5a0015d6
CZ
40/*
41 * _start
42 *
43 * The bootloader passes a pointer to a list of boot parameters in a2.
44 */
45
46 /* The first bytes of the kernel image must be an instruction, so we
47 * manually allocate and define the literal constant we need for a jx
48 * instruction.
49 */
50
0ebdcb4d 51 __HEAD
e85e335f
MF
52 .begin no-absolute-literals
53
d1538c46
CZ
54ENTRY(_start)
55
e85e335f
MF
56 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
57 wsr a2, excsave1
f615136c 58 _j _SetupOCD
e85e335f
MF
59
60 .align 4
61 .literal_position
f615136c
MF
62_SetupOCD:
63 /*
64 * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
65 * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
66 * xt-gdb to single step via DEBUG exceptions received directly
67 * by ocd.
68 */
69 movi a1, 1
70 movi a0, 0
71 wsr a1, windowstart
72 wsr a0, windowbase
73 rsync
74
75 movi a1, LOCKLEVEL
76 wsr a1, ps
77 rsync
78
e85e335f
MF
79 .global _SetupMMU
80_SetupMMU:
81 Offset = _SetupMMU - _start
82
83#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
84 initialize_mmu
c5a771d0
MF
85#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
86 rsr a2, excsave1
40dc948f
MF
87 movi a3, XCHAL_KSEG_PADDR
88 bltu a2, a3, 1f
89 sub a2, a2, a3
90 movi a3, XCHAL_KSEG_SIZE
c5a771d0 91 bgeu a2, a3, 1f
40dc948f 92 movi a3, XCHAL_KSEG_CACHED_VADDR
c5a771d0
MF
93 add a2, a2, a3
94 wsr a2, excsave1
951:
96#endif
e85e335f 97#endif
e85e335f 98
03760270 99 movi a0, _startup
5a0015d6
CZ
100 jx a0
101
d1538c46 102ENDPROC(_start)
03760270 103 .end no-absolute-literals
d1538c46 104
49b424fe 105 __REF
e85e335f 106 .literal_position
d1538c46
CZ
107
108ENTRY(_startup)
5a0015d6 109
5a0015d6
CZ
110 /* Set a0 to 0 for the remaining initialization. */
111
112 movi a0, 0
113
53490121 114#if XCHAL_HAVE_VECBASE
a9f2fc62 115 movi a2, VECBASE_VADDR
53490121
MF
116 wsr a2, vecbase
117#endif
118
5a0015d6
CZ
119 /* Clear debugging registers. */
120
121#if XCHAL_HAVE_DEBUG
d83ff0bb 122#if XCHAL_NUM_IBREAK > 0
bc5378fc 123 wsr a0, ibreakenable
d83ff0bb 124#endif
bc5378fc 125 wsr a0, icount
5a0015d6 126 movi a1, 15
bc5378fc 127 wsr a0, icountlevel
5a0015d6 128
173d6681 129 .set _index, 0
7de7ac78 130 .rept XCHAL_NUM_DBREAK
bc5378fc 131 wsr a0, SREG_DBREAKC + _index
173d6681
CZ
132 .set _index, _index + 1
133 .endr
5a0015d6
CZ
134#endif
135
136 /* Clear CCOUNT (not really necessary, but nice) */
137
bc5378fc 138 wsr a0, ccount # not really necessary, but nice
5a0015d6
CZ
139
140 /* Disable zero-loops. */
141
142#if XCHAL_HAVE_LOOPS
bc5378fc 143 wsr a0, lcount
5a0015d6
CZ
144#endif
145
146 /* Disable all timers. */
147
173d6681 148 .set _index, 0
79fcf52b 149 .rept XCHAL_NUM_TIMERS
bc5378fc 150 wsr a0, SREG_CCOMPARE + _index
173d6681
CZ
151 .set _index, _index + 1
152 .endr
5a0015d6
CZ
153
154 /* Interrupt initialization. */
155
156 movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
bc5378fc
MF
157 wsr a0, intenable
158 wsr a2, intclear
5a0015d6
CZ
159
160 /* Disable coprocessors. */
161
eab5e7a7 162#if XCHAL_HAVE_CP
bc5378fc 163 wsr a0, cpenable
5a0015d6
CZ
164#endif
165
5a0015d6 166 /* Initialize the caches.
173d6681 167 * a2, a3 are just working registers (clobbered).
5a0015d6
CZ
168 */
169
173d6681
CZ
170#if XCHAL_DCACHE_LINE_LOCKABLE
171 ___unlock_dcache_all a2 a3
172#endif
173
174#if XCHAL_ICACHE_LINE_LOCKABLE
175 ___unlock_icache_all a2 a3
176#endif
177
178 ___invalidate_dcache_all a2 a3
179 ___invalidate_icache_all a2 a3
180
181 isync
5a0015d6 182
7bb516ca
MF
183 initialize_cacheattr
184
f615136c
MF
185#ifdef CONFIG_HAVE_SMP
186 movi a2, CCON # MX External Register to Configure Cache
187 movi a3, 1
188 wer a3, a2
189#endif
190
191 /* Setup stack and enable window exceptions (keep irqs disabled) */
192
193 movi a1, start_info
194 l32i a1, a1, 0
195
196 movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL
197 # WOE=1, INTLEVEL=LOCKLEVEL, UM=0
198 wsr a2, ps # (enable reg-windows; progmode stack)
199 rsync
200
f615136c
MF
201#ifdef CONFIG_SMP
202 /*
203 * Notice that we assume with SMP that cores have PRID
204 * supported by the cores.
205 */
206 rsr a2, prid
207 bnez a2, .Lboot_secondary
208
209#endif /* CONFIG_SMP */
210
5a0015d6
CZ
211 /* Unpack data sections
212 *
213 * The linker script used to build the Linux kernel image
214 * creates a table located at __boot_reloc_table_start
215 * that contans the information what data needs to be unpacked.
216 *
217 * Uses a2-a7.
218 */
219
220 movi a2, __boot_reloc_table_start
221 movi a3, __boot_reloc_table_end
222
2231: beq a2, a3, 3f # no more entries?
224 l32i a4, a2, 0 # start destination (in RAM)
225 l32i a5, a2, 4 # end desination (in RAM)
226 l32i a6, a2, 8 # start source (in ROM)
227 addi a2, a2, 12 # next entry
228 beq a4, a5, 1b # skip, empty entry
229 beq a4, a6, 1b # skip, source and dest. are the same
230
2312: l32i a7, a6, 0 # load word
232 addi a6, a6, 4
233 s32i a7, a4, 0 # store word
234 addi a4, a4, 4
235 bltu a4, a5, 2b
236 j 1b
237
2383:
239 /* All code and initialized data segments have been copied.
240 * Now clear the BSS segment.
241 */
242
8b307f9c
CZ
243 movi a2, __bss_start # start of BSS
244 movi a3, __bss_stop # end of BSS
5a0015d6 245
173d6681 246 __loopt a2, a3, a4, 2
5a0015d6 247 s32i a0, a2, 0
5029615e 248 __endla a2, a3, 4
5a0015d6
CZ
249
250#if XCHAL_DCACHE_IS_WRITEBACK
251
252 /* After unpacking, flush the writeback cache to memory so the
253 * instructions/data are available.
254 */
255
173d6681 256 ___flush_dcache_all a2 a3
5a0015d6 257#endif
e85e335f
MF
258 memw
259 isync
260 ___invalidate_icache_all a2 a3
261 isync
5a0015d6 262
f615136c 263 movi a6, 0
bc5378fc 264 xsr a6, excsave1
5a0015d6
CZ
265
266 /* init_arch kick-starts the linux kernel */
267
2da03d41
MF
268 call4 init_arch
269 call4 start_kernel
5a0015d6
CZ
270
271should_never_return:
272 j should_never_return
273
f615136c
MF
274#ifdef CONFIG_SMP
275.Lboot_secondary:
276
277 movi a2, cpu_start_ccount
2781:
32a7726c 279 memw
f615136c
MF
280 l32i a3, a2, 0
281 beqi a3, 0, 1b
282 movi a3, 0
283 s32i a3, a2, 0
f615136c 2841:
32a7726c 285 memw
f615136c
MF
286 l32i a3, a2, 0
287 beqi a3, 0, 1b
288 wsr a3, ccount
289 movi a3, 0
290 s32i a3, a2, 0
291 memw
292
293 movi a6, 0
294 wsr a6, excsave1
295
2da03d41 296 call4 secondary_start_kernel
f615136c
MF
297 j should_never_return
298
299#endif /* CONFIG_SMP */
300
d1538c46 301ENDPROC(_startup)
5a0015d6 302
49b424fe
MF
303#ifdef CONFIG_HOTPLUG_CPU
304
305ENTRY(cpu_restart)
306
307#if XCHAL_DCACHE_IS_WRITEBACK
308 ___flush_invalidate_dcache_all a2 a3
309#else
310 ___invalidate_dcache_all a2 a3
311#endif
312 memw
313 movi a2, CCON # MX External Register to Configure Cache
314 movi a3, 0
315 wer a3, a2
316 extw
317
318 rsr a0, prid
319 neg a2, a0
320 movi a3, cpu_start_id
32a7726c 321 memw
49b424fe
MF
322 s32i a2, a3, 0
323#if XCHAL_DCACHE_IS_WRITEBACK
324 dhwbi a3, 0
325#endif
3261:
32a7726c 327 memw
49b424fe
MF
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
350ENDPROC(cpu_restart)
351
352#endif /* CONFIG_HOTPLUG_CPU */
353
f615136c
MF
354/*
355 * DATA section
356 */
357
358 .section ".data.init.refok"
359 .align 4
360ENTRY(start_info)
361 .long init_thread_union + KERNEL_STACK_SIZE
362
adba09f0
CZ
363/*
364 * BSS section
365 */
366
02b7da37 367__PAGE_ALIGNED_BSS
e5083a63 368#ifdef CONFIG_MMU
adba09f0
CZ
369ENTRY(swapper_pg_dir)
370 .fill PAGE_SIZE, 1, 0
d1538c46 371END(swapper_pg_dir)
e5083a63 372#endif
adba09f0
CZ
373ENTRY(empty_zero_page)
374 .fill PAGE_SIZE, 1, 0
d1538c46 375END(empty_zero_page)