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