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