sync hh.org
[hh.org.git] / arch / xtensa / kernel / head.S
blobc07cb25229931b1198895c291947c59c8ce3e4e9
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  *
10  * Copyright (C) 2001 - 2005 Tensilica Inc.
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  */
18 #include <xtensa/cacheasm.h>
19 #include <asm/processor.h>
20 #include <asm/page.h>
23  * This module contains the entry code for kernel images. It performs the
24  * minimal setup needed to call the generic C routines.
25  *
26  * Prerequisites:
27  *
28  * - The kernel image has been loaded to the actual address where it was
29  *   compiled to.
30  * - a2 contains either 0 or a pointer to a list of boot parameters.
31  *   (see setup.c for more details)
32  *
33  */
35         .macro  iterate from, to , cmd
36                 .ifeq   ((\to - \from) & ~0xfff)
37                         \cmd    \from
38                         iterate "(\from+1)", \to, \cmd
39                 .endif
40         .endm
43  *  _start
44  *
45  *  The bootloader passes a pointer to a list of boot parameters in a2.
46  */
48         /* The first bytes of the kernel image must be an instruction, so we
49          * manually allocate and define the literal constant we need for a jx
50          * instruction.
51          */
53         .section .head.text, "ax"
54         .globl _start
55 _start: _j      2f
56         .align  4
57 1:      .word   _startup
58 2:      l32r    a0, 1b
59         jx      a0
61         .text
62         .align 4
63 _startup:
65         /* Disable interrupts and exceptions. */
67         movi    a0, XCHAL_PS_EXCM_MASK
68         wsr     a0, PS
70         /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
72         wsr     a2, EXCSAVE_1
74         /* Start with a fresh windowbase and windowstart.  */
76         movi    a1, 1
77         movi    a0, 0
78         wsr     a1, WINDOWSTART
79         wsr     a0, WINDOWBASE
80         rsync
82         /* Set a0 to 0 for the remaining initialization. */
84         movi    a0, 0
86         /* Clear debugging registers. */
88 #if XCHAL_HAVE_DEBUG
89         wsr     a0, IBREAKENABLE
90         wsr     a0, ICOUNT
91         movi    a1, 15
92         wsr     a0, ICOUNTLEVEL
94         .macro reset_dbreak num
95         wsr     a0, DBREAKC + \num
96         .endm
98         iterate 0, XCHAL_NUM_IBREAK-1, reset_dbreak
99 #endif
101         /* Clear CCOUNT (not really necessary, but nice) */
103         wsr     a0, CCOUNT      # not really necessary, but nice
105         /* Disable zero-loops. */
107 #if XCHAL_HAVE_LOOPS
108         wsr     a0, LCOUNT
109 #endif
111         /* Disable all timers. */
113         .macro  reset_timer     num
114         wsr     a0, CCOMPARE_0 + \num
115         .endm
116         iterate 0, XCHAL_NUM_TIMERS-1, reset_timer
118         /* Interrupt initialization. */
120         movi    a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
121         wsr     a0, INTENABLE
122         wsr     a2, INTCLEAR
124         /* Disable coprocessors. */
126 #if XCHAL_CP_NUM > 0
127         wsr     a0, CPENABLE
128 #endif
130         /* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0
131          *
132          * Note: PS.EXCM must be cleared before using any loop
133          *       instructions; otherwise, they are silently disabled, and
134          *       at most one iteration of the loop is executed.
135          */
137         movi    a1, 1
138         wsr     a1, PS
139         rsync
141         /*  Initialize the caches.
142          *  Does not include flushing writeback d-cache.
143          *  a6, a7 are just working registers (clobbered).
144          */
146         icache_reset  a2, a3
147         dcache_reset  a2, a3
149         /* Unpack data sections
150          *
151          * The linker script used to build the Linux kernel image
152          * creates a table located at __boot_reloc_table_start
153          * that contans the information what data needs to be unpacked.
154          *
155          * Uses a2-a7.
156          */
158         movi    a2, __boot_reloc_table_start
159         movi    a3, __boot_reloc_table_end
161 1:      beq     a2, a3, 3f      # no more entries?
162         l32i    a4, a2, 0       # start destination (in RAM)
163         l32i    a5, a2, 4       # end desination (in RAM)
164         l32i    a6, a2, 8       # start source (in ROM)
165         addi    a2, a2, 12      # next entry
166         beq     a4, a5, 1b      # skip, empty entry
167         beq     a4, a6, 1b      # skip, source and dest. are the same
169 2:      l32i    a7, a6, 0       # load word
170         addi    a6, a6, 4
171         s32i    a7, a4, 0       # store word
172         addi    a4, a4, 4
173         bltu    a4, a5, 2b
174         j       1b
177         /* All code and initialized data segments have been copied.
178          * Now clear the BSS segment.
179          */
181         movi    a2, _bss_start  # start of BSS
182         movi    a3, _bss_end    # end of BSS
184 1:      addi    a2, a2, 4
185         s32i    a0, a2, 0
186         blt     a2, a3, 1b
188 #if XCHAL_DCACHE_IS_WRITEBACK
190         /* After unpacking, flush the writeback cache to memory so the
191          * instructions/data are available.
192          */
194         dcache_writeback_all    a2, a3
195 #endif
197         /* Setup stack and enable window exceptions (keep irqs disabled) */
199         movi    a1, init_thread_union
200         addi    a1, a1, KERNEL_STACK_SIZE
202         movi    a2, 0x00040001          # WOE=1, INTLEVEL=1, UM=0
203         wsr     a2, PS                  # (enable reg-windows; progmode stack)
204         rsync
206         /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
208         movi    a2, debug_exception
209         wsr     a2, EXCSAVE + XCHAL_DEBUGLEVEL
211         /* Set up EXCSAVE[1] to point to the exc_table. */
213         movi    a6, exc_table
214         xsr     a6, EXCSAVE_1
216         /* init_arch kick-starts the linux kernel */
218         movi    a4, init_arch
219         callx4  a4
221         movi    a4, start_kernel
222         callx4  a4
224 should_never_return:
225         j       should_never_return
227         /* Define some common data structures here.  We define them
228          * here in this assembly file due to their unusual alignment
229          * requirements.
230          */
232         .comm   swapper_pg_dir,PAGE_SIZE,PAGE_SIZE
233         .comm   empty_bad_page_table,PAGE_SIZE,PAGE_SIZE
234         .comm   empty_bad_page,PAGE_SIZE,PAGE_SIZE
235         .comm   empty_zero_page,PAGE_SIZE,PAGE_SIZE