blob: 06bf4c692d8e4d848d93d06689bd67a446091242 [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 Skinnemoen1f36f732010-08-12 13:52:54 +070085 .org 0x50 /* ITLB Miss */
86 pushm r8-r12,lr
87 rjmp 1f
88 .org 0x60 /* DTLB Miss (read) */
89 pushm r8-r12,lr
90 rjmp 1f
91 .org 0x70 /* DTLB Miss (write) */
92 pushm r8-r12,lr
931: mov r12, sp
94 rcall mmu_handle_tlb_miss
95 popm r8-r12,lr
96 brne unknown_exception
97 rete
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +020098
99 .size _evba, . - _evba
100
101 .align 2
102 .type unknown_exception, @function
103unknown_exception:
104 /* Figure out whether we're handling an exception (Exception
105 * mode) or just booting (Supervisor mode). */
106 csrfcz SYSREG_M1_OFFSET
107 brcc at32ap_cpu_bootstrap
108
109 /* This is an exception. Complain. */
110 pushm r0-r12
111 sub r8, sp, REG_R12 - REG_R0 - 4
112 mov r9, lr
113 mfsr r10, SYSREG_RAR_EX
114 mfsr r11, SYSREG_RSR_EX
115 pushm r8-r11
116 mfsr r12, SYSREG_ECR
117 mov r11, sp
118 rcall do_unknown_exception
1191: rjmp 1b
120
121 /* The COUNT/COMPARE timer interrupt handler */
122 .global timer_interrupt_handler
123 .type timer_interrupt_handler,@function
124 .align 2
125timer_interrupt_handler:
126 /*
127 * Increment timer_overflow and re-write COMPARE with 0xffffffff.
128 *
129 * We're running at interrupt level 3, so we don't need to save
130 * r8-r12 or lr to the stack.
131 */
132 lda.w r8, timer_overflow
133 ld.w r9, r8[0]
134 mov r10, -1
135 mtsr SYSREG_COMPARE, r10
136 sub r9, -1
137 st.w r8[0], r9
138 rete
139
140 /*
141 * CPU bootstrap after reset is handled here. SoC code may
142 * override this in case they need to initialize oscillators,
143 * etc.
144 */
145 .section .text.at32ap_cpu_bootstrap, "ax", @progbits
146 .global at32ap_cpu_bootstrap
147 .weak at32ap_cpu_bootstrap
148 .type at32ap_cpu_bootstrap, @function
149 .align 2
150at32ap_cpu_bootstrap:
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200151 /* Reset the Status Register */
152 mov r0, lo(SR_INIT)
153 orh r0, hi(SR_INIT)
154 mtsr SYSREG_SR, r0
155
156 /* Reset CPUCR and invalidate the BTB */
157 mov r2, CPUCR_INIT
158 mtsr SYSREG_CPUCR, r2
159
160 /* Flush the caches */
161 mov r1, 0
162 cache r1[4], 8
163 cache r1[0], 0
164 sync 0
165
166 /* Reset the MMU to default settings */
167 mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
168 mtsr SYSREG_MMUCR, r0
169
170 /* Internal RAM should not need any initialization. We might
171 have to initialize external RAM here if the part doesn't
172 have internal RAM (or we may use the data cache) */
173
174 /* Jump to cacheable segment */
175 lddpc pc, 1f
176
177 .align 2
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +02001781: .long at32ap_low_level_init
179 .size _start, . - _start
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200180
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200181 /* Common CPU bootstrap code after oscillator/cache/etc. init */
182 .section .text.avr32ap_low_level_init, "ax", @progbits
183 .global at32ap_low_level_init
184 .type at32ap_low_level_init, @function
185 .align 2
186at32ap_low_level_init:
187 lddpc sp, sp_init
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200188
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200189 /* Initialize the GOT pointer */
190 lddpc r6, got_init
1913: rsub r6, pc
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100192
193 /* Let's go */
194 rjmp board_init_f
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200195
196 .align 2
197 .type sp_init,@object
198sp_init:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200199 .long CONFIG_SYS_INIT_SP_ADDR
Wolfgang Denk72a087e2006-10-24 14:27:35 +0200200got_init:
201 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100202
203 /*
204 * void relocate_code(new_sp, new_gd, monitor_addr)
205 *
206 * Relocate the u-boot image into RAM and continue from there.
207 * Does not return.
208 */
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200209 .section .text.relocate_code,"ax",@progbits
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +0100210 .global relocate_code
211 .type relocate_code,@function
212relocate_code:
213 mov sp, r12 /* use new stack */
214 mov r12, r11 /* save new_gd */
215 mov r11, r10 /* save destination address */
216
217 /* copy .text section and flush the cache along the way */
218 lda.w r8, _text
219 lda.w r9, _etext
220 sub lr, r10, r8 /* relocation offset */
221
2221: ldm r8++, r0-r3
223 stm r10, r0-r3
224 sub r10, -16
225 ldm r8++, r0-r3
226 stm r10, r0-r3
227 sub r10, -16
228 cp.w r8, r9
229 cache r10[-4], 0x0d /* dcache clean/invalidate */
230 cache r10[-4], 0x01 /* icache invalidate */
231 brlt 1b
232
233 /* flush write buffer */
234 sync 0
235
236 /* copy data sections */
237 lda.w r9, _edata
2381: ld.d r0, r8++
239 st.d r10++, r0
240 cp.w r8, r9
241 brlt 1b
242
243 /* zero out .bss */
244 mov r0, 0
245 mov r1, 0
246 lda.w r9, _end
247 sub r9, r8
2481: st.d r10++, r0
249 sub r9, 8
250 brgt 1b
251
252 /* jump to RAM */
253 sub r0, pc, . - in_ram
254 add pc, r0, lr
255
256 .align 2
257in_ram:
258 /* find the new GOT and relocate it */
259 lddpc r6, got_init_reloc
2603: rsub r6, pc
261 mov r8, r6
262 lda.w r9, _egot
263 lda.w r10, _got
264 sub r9, r10
2651: ld.w r0, r8[0]
266 add r0, lr
267 st.w r8++, r0
268 sub r9, 4
269 brgt 1b
270
271 /* Move the exception handlers */
272 mfsr r2, SYSREG_EVBA
273 add r2, lr
274 mtsr SYSREG_EVBA, r2
275
276 /* Do the rest of the initialization sequence */
277 call board_init_r
278
279 .align 2
280got_init_reloc:
281 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoencaf83ea2008-05-02 15:32:57 +0200282
283 .size relocate_code, . - relocate_code