blob: 99c9e06cb83682c56c7d3f9b59001bac6c33ce22 [file] [log] [blame]
Wolfgang Denk72a087e2006-10-24 14:27:35 +02001/*
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +02002 * Copyright (C) 2005-2008 Atmel Corporation
Wolfgang Denk72a087e2006-10-24 14:27:35 +02003 *
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>
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020023#include <asm/ptrace.h>
Wolfgang Denk72a087e2006-10-24 14:27:35 +020024#include <asm/sysreg.h>
25
Wolfgang Denk72a087e2006-10-24 14:27:35 +020026#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))
Andreas Bießmanneb70d052010-06-09 14:13:45 +020030/* 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))
Wolfgang Denk72a087e2006-10-24 14:27:35 +020034
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020035 /*
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
Wolfgang Denk72a087e2006-10-24 14:27:35 +020041 .global _start
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020042 .global _evba
43 .type _start, @function
44 .type _evba, @function
Wolfgang Denk72a087e2006-10-24 14:27:35 +020045_start:
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020046 .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 */
Wolfgang Denk72a087e2006-10-24 14:27:35 +020084
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020085 .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
96unknown_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
1121: rjmp 1b
113
114 /* The COUNT/COMPARE timer interrupt handler */
115 .global timer_interrupt_handler
116 .type timer_interrupt_handler,@function
117 .align 2
118timer_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
143at32ap_cpu_bootstrap:
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200144 /* 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
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +02001711: .long at32ap_low_level_init
172 .size _start, . - _start
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200173
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200174 /* 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
179at32ap_low_level_init:
180 lddpc sp, sp_init
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200181
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200182 /* Initialize the GOT pointer */
183 lddpc r6, got_init
1843: rsub r6, pc
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100185
186 /* Let's go */
187 rjmp board_init_f
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200188
189 .align 2
190 .type sp_init,@object
191sp_init:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200192 .long CONFIG_SYS_INIT_SP_ADDR
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200193got_init:
194 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100195
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 */
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200202 .section .text.relocate_code,"ax",@progbits
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100203 .global relocate_code
204 .type relocate_code,@function
205relocate_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
2151: 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
2311: 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
2411: 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
250in_ram:
251 /* find the new GOT and relocate it */
252 lddpc r6, got_init_reloc
2533: rsub r6, pc
254 mov r8, r6
255 lda.w r9, _egot
256 lda.w r10, _got
257 sub r9, r10
2581: 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
273got_init_reloc:
274 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200275
276 .size relocate_code, . - relocate_code