blob: df88f98737f4f139968cdd0a2758c7132854f4a9 [file] [log] [blame]
Chris Zankel5a0015d2005-06-23 22:01:16 -07001/*
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 *
Marc Gauthier2d1c6452013-01-05 04:57:17 +040010 * Copyright (C) 2001 - 2008 Tensilica Inc.
Chris Zankel5a0015d2005-06-23 22:01:16 -070011 *
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
Chris Zankel5a0015d2005-06-23 22:01:16 -070018#include <asm/processor.h>
19#include <asm/page.h>
Chris Zankel173d6682006-12-10 02:18:48 -080020#include <asm/cacheasm.h>
Max Filippovc622b292012-11-19 07:00:41 +040021#include <asm/initialize_mmu.h>
Chris Zankel5a0015d2005-06-23 22:01:16 -070022
Tim Abbott0ebdcb42009-04-25 22:10:57 -040023#include <linux/init.h>
Chris Zankeladba09f2007-05-31 17:48:07 -070024#include <linux/linkage.h>
25
Chris Zankel5a0015d2005-06-23 22:01:16 -070026/*
27 * This module contains the entry code for kernel images. It performs the
28 * minimal setup needed to call the generic C routines.
29 *
30 * Prerequisites:
31 *
32 * - The kernel image has been loaded to the actual address where it was
33 * compiled to.
34 * - a2 contains either 0 or a pointer to a list of boot parameters.
35 * (see setup.c for more details)
36 *
37 */
38
Chris Zankel5a0015d2005-06-23 22:01:16 -070039/*
40 * _start
41 *
42 * The bootloader passes a pointer to a list of boot parameters in a2.
43 */
44
45 /* The first bytes of the kernel image must be an instruction, so we
46 * manually allocate and define the literal constant we need for a jx
47 * instruction.
48 */
49
Tim Abbott0ebdcb42009-04-25 22:10:57 -040050 __HEAD
Chris Zankeld1538c42012-11-16 16:16:20 -080051ENTRY(_start)
52
53 _j 2f
Chris Zankel5a0015d2005-06-23 22:01:16 -070054 .align 4
551: .word _startup
562: l32r a0, 1b
57 jx a0
58
Chris Zankeld1538c42012-11-16 16:16:20 -080059ENDPROC(_start)
60
Daniel Glöckner06a74762009-03-11 14:15:11 +010061 .section .init.text, "ax"
Chris Zankeld1538c42012-11-16 16:16:20 -080062
63ENTRY(_startup)
Chris Zankel5a0015d2005-06-23 22:01:16 -070064
65 /* Disable interrupts and exceptions. */
66
Chris Zankel173d6682006-12-10 02:18:48 -080067 movi a0, LOCKLEVEL
Max Filippovbc5378f2012-10-15 03:55:38 +040068 wsr a0, ps
Chris Zankel5a0015d2005-06-23 22:01:16 -070069
70 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
71
Max Filippovbc5378f2012-10-15 03:55:38 +040072 wsr a2, excsave1
Chris Zankel5a0015d2005-06-23 22:01:16 -070073
74 /* Start with a fresh windowbase and windowstart. */
75
76 movi a1, 1
77 movi a0, 0
Max Filippovbc5378f2012-10-15 03:55:38 +040078 wsr a1, windowstart
79 wsr a0, windowbase
Chris Zankel5a0015d2005-06-23 22:01:16 -070080 rsync
81
82 /* Set a0 to 0 for the remaining initialization. */
83
84 movi a0, 0
85
86 /* Clear debugging registers. */
87
88#if XCHAL_HAVE_DEBUG
Max Filippovbc5378f2012-10-15 03:55:38 +040089 wsr a0, ibreakenable
90 wsr a0, icount
Chris Zankel5a0015d2005-06-23 22:01:16 -070091 movi a1, 15
Max Filippovbc5378f2012-10-15 03:55:38 +040092 wsr a0, icountlevel
Chris Zankel5a0015d2005-06-23 22:01:16 -070093
Chris Zankel173d6682006-12-10 02:18:48 -080094 .set _index, 0
95 .rept XCHAL_NUM_DBREAK - 1
Max Filippovbc5378f2012-10-15 03:55:38 +040096 wsr a0, SREG_DBREAKC + _index
Chris Zankel173d6682006-12-10 02:18:48 -080097 .set _index, _index + 1
98 .endr
Chris Zankel5a0015d2005-06-23 22:01:16 -070099#endif
100
101 /* Clear CCOUNT (not really necessary, but nice) */
102
Max Filippovbc5378f2012-10-15 03:55:38 +0400103 wsr a0, ccount # not really necessary, but nice
Chris Zankel5a0015d2005-06-23 22:01:16 -0700104
105 /* Disable zero-loops. */
106
107#if XCHAL_HAVE_LOOPS
Max Filippovbc5378f2012-10-15 03:55:38 +0400108 wsr a0, lcount
Chris Zankel5a0015d2005-06-23 22:01:16 -0700109#endif
110
111 /* Disable all timers. */
112
Chris Zankel173d6682006-12-10 02:18:48 -0800113 .set _index, 0
Max Filippov79fcf522012-12-11 01:26:22 +0400114 .rept XCHAL_NUM_TIMERS
Max Filippovbc5378f2012-10-15 03:55:38 +0400115 wsr a0, SREG_CCOMPARE + _index
Chris Zankel173d6682006-12-10 02:18:48 -0800116 .set _index, _index + 1
117 .endr
Chris Zankel5a0015d2005-06-23 22:01:16 -0700118
119 /* Interrupt initialization. */
120
121 movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
Max Filippovbc5378f2012-10-15 03:55:38 +0400122 wsr a0, intenable
123 wsr a2, intclear
Chris Zankel5a0015d2005-06-23 22:01:16 -0700124
125 /* Disable coprocessors. */
126
Max Filippoveab5e7a2012-12-11 01:26:23 +0400127#if XCHAL_HAVE_CP
Max Filippovbc5378f2012-10-15 03:55:38 +0400128 wsr a0, cpenable
Chris Zankel5a0015d2005-06-23 22:01:16 -0700129#endif
130
Marc Gauthier2d1c6452013-01-05 04:57:17 +0400131 /* Set PS.INTLEVEL=LOCKLEVEL, PS.WOE=0, kernel stack, PS.EXCM=0
Chris Zankel5a0015d2005-06-23 22:01:16 -0700132 *
133 * Note: PS.EXCM must be cleared before using any loop
134 * instructions; otherwise, they are silently disabled, and
135 * at most one iteration of the loop is executed.
136 */
137
Marc Gauthier2d1c6452013-01-05 04:57:17 +0400138 movi a1, LOCKLEVEL
Max Filippovbc5378f2012-10-15 03:55:38 +0400139 wsr a1, ps
Chris Zankel5a0015d2005-06-23 22:01:16 -0700140 rsync
141
142 /* Initialize the caches.
Chris Zankel173d6682006-12-10 02:18:48 -0800143 * a2, a3 are just working registers (clobbered).
Chris Zankel5a0015d2005-06-23 22:01:16 -0700144 */
145
Chris Zankel173d6682006-12-10 02:18:48 -0800146#if XCHAL_DCACHE_LINE_LOCKABLE
147 ___unlock_dcache_all a2 a3
148#endif
149
150#if XCHAL_ICACHE_LINE_LOCKABLE
151 ___unlock_icache_all a2 a3
152#endif
153
154 ___invalidate_dcache_all a2 a3
155 ___invalidate_icache_all a2 a3
156
157 isync
Chris Zankel5a0015d2005-06-23 22:01:16 -0700158
Max Filippovc622b292012-11-19 07:00:41 +0400159 initialize_mmu
160
Chris Zankel5a0015d2005-06-23 22:01:16 -0700161 /* Unpack data sections
162 *
163 * The linker script used to build the Linux kernel image
164 * creates a table located at __boot_reloc_table_start
165 * that contans the information what data needs to be unpacked.
166 *
167 * Uses a2-a7.
168 */
169
170 movi a2, __boot_reloc_table_start
171 movi a3, __boot_reloc_table_end
172
1731: beq a2, a3, 3f # no more entries?
174 l32i a4, a2, 0 # start destination (in RAM)
175 l32i a5, a2, 4 # end desination (in RAM)
176 l32i a6, a2, 8 # start source (in ROM)
177 addi a2, a2, 12 # next entry
178 beq a4, a5, 1b # skip, empty entry
179 beq a4, a6, 1b # skip, source and dest. are the same
180
1812: l32i a7, a6, 0 # load word
182 addi a6, a6, 4
183 s32i a7, a4, 0 # store word
184 addi a4, a4, 4
185 bltu a4, a5, 2b
186 j 1b
187
1883:
189 /* All code and initialized data segments have been copied.
190 * Now clear the BSS segment.
191 */
192
Chris Zankel8b307f92010-05-01 23:05:29 -0700193 movi a2, __bss_start # start of BSS
194 movi a3, __bss_stop # end of BSS
Chris Zankel5a0015d2005-06-23 22:01:16 -0700195
Chris Zankel173d6682006-12-10 02:18:48 -0800196 __loopt a2, a3, a4, 2
Chris Zankel5a0015d2005-06-23 22:01:16 -0700197 s32i a0, a2, 0
Chris Zankel173d6682006-12-10 02:18:48 -0800198 __endla a2, a4, 4
Chris Zankel5a0015d2005-06-23 22:01:16 -0700199
200#if XCHAL_DCACHE_IS_WRITEBACK
201
202 /* After unpacking, flush the writeback cache to memory so the
203 * instructions/data are available.
204 */
205
Chris Zankel173d6682006-12-10 02:18:48 -0800206 ___flush_dcache_all a2 a3
Chris Zankel5a0015d2005-06-23 22:01:16 -0700207#endif
208
209 /* Setup stack and enable window exceptions (keep irqs disabled) */
210
211 movi a1, init_thread_union
212 addi a1, a1, KERNEL_STACK_SIZE
213
Marc Gauthier2d1c6452013-01-05 04:57:17 +0400214 movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL
215 # WOE=1, INTLEVEL=LOCKLEVEL, UM=0
Max Filippovbc5378f2012-10-15 03:55:38 +0400216 wsr a2, ps # (enable reg-windows; progmode stack)
Chris Zankel5a0015d2005-06-23 22:01:16 -0700217 rsync
218
219 /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
220
221 movi a2, debug_exception
Max Filippovbc5378f2012-10-15 03:55:38 +0400222 wsr a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
Chris Zankel5a0015d2005-06-23 22:01:16 -0700223
224 /* Set up EXCSAVE[1] to point to the exc_table. */
225
226 movi a6, exc_table
Max Filippovbc5378f2012-10-15 03:55:38 +0400227 xsr a6, excsave1
Chris Zankel5a0015d2005-06-23 22:01:16 -0700228
229 /* init_arch kick-starts the linux kernel */
230
231 movi a4, init_arch
232 callx4 a4
233
234 movi a4, start_kernel
235 callx4 a4
236
237should_never_return:
238 j should_never_return
239
Chris Zankeld1538c42012-11-16 16:16:20 -0800240ENDPROC(_startup)
Chris Zankel5a0015d2005-06-23 22:01:16 -0700241
Chris Zankeladba09f2007-05-31 17:48:07 -0700242/*
243 * BSS section
244 */
245
Tim Abbott02b7da32009-09-20 18:14:14 -0400246__PAGE_ALIGNED_BSS
Johannes Weinere5083a62009-03-04 16:21:31 +0100247#ifdef CONFIG_MMU
Chris Zankeladba09f2007-05-31 17:48:07 -0700248ENTRY(swapper_pg_dir)
249 .fill PAGE_SIZE, 1, 0
Chris Zankeld1538c42012-11-16 16:16:20 -0800250END(swapper_pg_dir)
Johannes Weinere5083a62009-03-04 16:21:31 +0100251#endif
Chris Zankeladba09f2007-05-31 17:48:07 -0700252ENTRY(empty_zero_page)
253 .fill PAGE_SIZE, 1, 0
Chris Zankeld1538c42012-11-16 16:16:20 -0800254END(empty_zero_page)