]> git.sur5r.net Git - u-boot/blob - arch/avr32/cpu/start.S
avr32: disable branch folding
[u-boot] / arch / avr32 / cpu / start.S
1 /*
2  * Copyright (C) 2005-2008 Atmel Corporation
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 #include <config.h>
23 #include <asm/ptrace.h>
24 #include <asm/sysreg.h>
25
26 #define SYSREG_MMUCR_I_OFFSET   2
27 #define SYSREG_MMUCR_S_OFFSET   4
28
29 #define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
30 /* due to errata (unreliable branch folding) clear FE bit explicitly */
31 #define CPUCR_INIT ((SYSREG_BIT(BI) | SYSREG_BIT(BE)    \
32                     | SYSREG_BIT(RE)   |  SYSREG_BIT(IBE)               \
33                     | SYSREG_BIT(IEE)) & ~SYSREG_BIT(FE))
34
35         /*
36          * To save some space, we use the same entry point for
37          * exceptions and reset. This avoids lots of alignment padding
38          * since the reset vector is always suitably aligned.
39          */
40         .section .exception.text, "ax", @progbits
41         .global _start
42         .global _evba
43         .type   _start, @function
44         .type   _evba, @function
45 _start:
46         .size   _start, 0
47 _evba:
48         .org    0x00
49         rjmp    unknown_exception       /* Unrecoverable exception */
50         .org    0x04
51         rjmp    unknown_exception       /* TLB multiple hit */
52         .org    0x08
53         rjmp    unknown_exception       /* Bus error data fetch */
54         .org    0x0c
55         rjmp    unknown_exception       /* Bus error instruction fetch */
56         .org    0x10
57         rjmp    unknown_exception       /* NMI */
58         .org    0x14
59         rjmp    unknown_exception       /* Instruction address */
60         .org    0x18
61         rjmp    unknown_exception       /* ITLB protection */
62         .org    0x1c
63         rjmp    unknown_exception       /* Breakpoint */
64         .org    0x20
65         rjmp    unknown_exception       /* Illegal opcode */
66         .org    0x24
67         rjmp    unknown_exception       /* Unimplemented instruction */
68         .org    0x28
69         rjmp    unknown_exception       /* Privilege violation */
70         .org    0x2c
71         rjmp    unknown_exception       /* Floating-point */
72         .org    0x30
73         rjmp    unknown_exception       /* Coprocessor absent */
74         .org    0x34
75         rjmp    unknown_exception       /* Data Address (read) */
76         .org    0x38
77         rjmp    unknown_exception       /* Data Address (write) */
78         .org    0x3c
79         rjmp    unknown_exception       /* DTLB Protection (read) */
80         .org    0x40
81         rjmp    unknown_exception       /* DTLB Protection (write) */
82         .org    0x44
83         rjmp    unknown_exception       /* DTLB Modified */
84
85         .org    0x50
86         rjmp    unknown_exception       /* ITLB Miss */
87         .org    0x60
88         rjmp    unknown_exception       /* DTLB Miss (read) */
89         .org    0x70
90         rjmp    unknown_exception       /* DTLB Miss (write) */
91
92         .size   _evba, . - _evba
93
94         .align  2
95         .type   unknown_exception, @function
96 unknown_exception:
97         /* Figure out whether we're handling an exception (Exception
98          * mode) or just booting (Supervisor mode). */
99         csrfcz  SYSREG_M1_OFFSET
100         brcc    at32ap_cpu_bootstrap
101
102         /* This is an exception. Complain. */
103         pushm   r0-r12
104         sub     r8, sp, REG_R12 - REG_R0 - 4
105         mov     r9, lr
106         mfsr    r10, SYSREG_RAR_EX
107         mfsr    r11, SYSREG_RSR_EX
108         pushm   r8-r11
109         mfsr    r12, SYSREG_ECR
110         mov     r11, sp
111         rcall   do_unknown_exception
112 1:      rjmp    1b
113
114         /* The COUNT/COMPARE timer interrupt handler */
115         .global timer_interrupt_handler
116         .type   timer_interrupt_handler,@function
117         .align  2
118 timer_interrupt_handler:
119         /*
120          * Increment timer_overflow and re-write COMPARE with 0xffffffff.
121          *
122          * We're running at interrupt level 3, so we don't need to save
123          * r8-r12 or lr to the stack.
124          */
125         lda.w   r8, timer_overflow
126         ld.w    r9, r8[0]
127         mov     r10, -1
128         mtsr    SYSREG_COMPARE, r10
129         sub     r9, -1
130         st.w    r8[0], r9
131         rete
132
133         /*
134          * CPU bootstrap after reset is handled here. SoC code may
135          * override this in case they need to initialize oscillators,
136          * etc.
137          */
138         .section .text.at32ap_cpu_bootstrap, "ax", @progbits
139         .global at32ap_cpu_bootstrap
140         .weak   at32ap_cpu_bootstrap
141         .type   at32ap_cpu_bootstrap, @function
142         .align  2
143 at32ap_cpu_bootstrap:
144         /* Reset the Status Register */
145         mov     r0, lo(SR_INIT)
146         orh     r0, hi(SR_INIT)
147         mtsr    SYSREG_SR, r0
148
149         /* Reset CPUCR and invalidate the BTB */
150         mov     r2, CPUCR_INIT
151         mtsr    SYSREG_CPUCR, r2
152
153         /* Flush the caches */
154         mov     r1, 0
155         cache   r1[4], 8
156         cache   r1[0], 0
157         sync    0
158
159         /* Reset the MMU to default settings */
160         mov     r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
161         mtsr    SYSREG_MMUCR, r0
162
163         /* Internal RAM should not need any initialization.  We might
164            have to initialize external RAM here if the part doesn't
165            have internal RAM (or we may use the data cache) */
166
167         /* Jump to cacheable segment */
168         lddpc   pc, 1f
169
170         .align  2
171 1:      .long   at32ap_low_level_init
172         .size   _start, . - _start
173
174         /* Common CPU bootstrap code after oscillator/cache/etc. init */
175         .section .text.avr32ap_low_level_init, "ax", @progbits
176         .global at32ap_low_level_init
177         .type   at32ap_low_level_init, @function
178         .align  2
179 at32ap_low_level_init:
180         lddpc   sp, sp_init
181
182         /* Initialize the GOT pointer */
183         lddpc   r6, got_init
184 3:      rsub    r6, pc
185
186         /* Let's go */
187         rjmp    board_init_f
188
189         .align  2
190         .type   sp_init,@object
191 sp_init:
192         .long   CONFIG_SYS_INIT_SP_ADDR
193 got_init:
194         .long   3b - _GLOBAL_OFFSET_TABLE_
195
196         /*
197          * void relocate_code(new_sp, new_gd, monitor_addr)
198          *
199          * Relocate the u-boot image into RAM and continue from there.
200          * Does not return.
201          */
202         .section .text.relocate_code,"ax",@progbits
203         .global relocate_code
204         .type   relocate_code,@function
205 relocate_code:
206         mov     sp, r12         /* use new stack */
207         mov     r12, r11        /* save new_gd */
208         mov     r11, r10        /* save destination address */
209
210         /* copy .text section and flush the cache along the way */
211         lda.w   r8, _text
212         lda.w   r9, _etext
213         sub     lr, r10, r8     /* relocation offset */
214
215 1:      ldm     r8++, r0-r3
216         stm     r10, r0-r3
217         sub     r10, -16
218         ldm     r8++, r0-r3
219         stm     r10, r0-r3
220         sub     r10, -16
221         cp.w    r8, r9
222         cache   r10[-4], 0x0d   /* dcache clean/invalidate */
223         cache   r10[-4], 0x01   /* icache invalidate */
224         brlt    1b
225
226         /* flush write buffer */
227         sync    0
228
229         /* copy data sections */
230         lda.w   r9, _edata
231 1:      ld.d    r0, r8++
232         st.d    r10++, r0
233         cp.w    r8, r9
234         brlt    1b
235
236         /* zero out .bss */
237         mov     r0, 0
238         mov     r1, 0
239         lda.w   r9, _end
240         sub     r9, r8
241 1:      st.d    r10++, r0
242         sub     r9, 8
243         brgt    1b
244
245         /* jump to RAM */
246         sub     r0, pc, . - in_ram
247         add     pc, r0, lr
248
249         .align  2
250 in_ram:
251         /* find the new GOT and relocate it */
252         lddpc   r6, got_init_reloc
253 3:      rsub    r6, pc
254         mov     r8, r6
255         lda.w   r9, _egot
256         lda.w   r10, _got
257         sub     r9, r10
258 1:      ld.w    r0, r8[0]
259         add     r0, lr
260         st.w    r8++, r0
261         sub     r9, 4
262         brgt    1b
263
264         /* Move the exception handlers */
265         mfsr    r2, SYSREG_EVBA
266         add     r2, lr
267         mtsr    SYSREG_EVBA, r2
268
269         /* Do the rest of the initialization sequence */
270         call    board_init_r
271
272         .align  2
273 got_init_reloc:
274         .long   3b - _GLOBAL_OFFSET_TABLE_
275
276         .size   relocate_code, . - relocate_code