blob: 14a0269a548880566673c8886d75fd99bbaf0bb1 [file] [log] [blame]
Wolfgang Denk64702552006-10-24 14:27:35 +02001/*
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +02002 * Copyright (C) 2005-2008 Atmel Corporation
Wolfgang Denk64702552006-10-24 14:27:35 +02003 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Wolfgang Denk64702552006-10-24 14:27:35 +02005 */
Wolfgang Denk0191e472010-10-26 14:34:52 +02006#include <asm-offsets.h>
Wolfgang Denk64702552006-10-24 14:27:35 +02007#include <config.h>
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +02008#include <asm/ptrace.h>
Wolfgang Denk64702552006-10-24 14:27:35 +02009#include <asm/sysreg.h>
10
Wolfgang Denk64702552006-10-24 14:27:35 +020011#define SYSREG_MMUCR_I_OFFSET 2
12#define SYSREG_MMUCR_S_OFFSET 4
13
14#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
Andreas Bießmannd6082d32010-06-09 14:13:45 +020015/* due to errata (unreliable branch folding) clear FE bit explicitly */
16#define CPUCR_INIT ((SYSREG_BIT(BI) | SYSREG_BIT(BE) \
17 | SYSREG_BIT(RE) | SYSREG_BIT(IBE) \
18 | SYSREG_BIT(IEE)) & ~SYSREG_BIT(FE))
Wolfgang Denk64702552006-10-24 14:27:35 +020019
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +020020 /*
21 * To save some space, we use the same entry point for
22 * exceptions and reset. This avoids lots of alignment padding
23 * since the reset vector is always suitably aligned.
24 */
25 .section .exception.text, "ax", @progbits
Wolfgang Denk64702552006-10-24 14:27:35 +020026 .global _start
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +020027 .global _evba
28 .type _start, @function
29 .type _evba, @function
Wolfgang Denk64702552006-10-24 14:27:35 +020030_start:
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +020031 .size _start, 0
32_evba:
33 .org 0x00
34 rjmp unknown_exception /* Unrecoverable exception */
35 .org 0x04
36 rjmp unknown_exception /* TLB multiple hit */
37 .org 0x08
38 rjmp unknown_exception /* Bus error data fetch */
39 .org 0x0c
40 rjmp unknown_exception /* Bus error instruction fetch */
41 .org 0x10
42 rjmp unknown_exception /* NMI */
43 .org 0x14
44 rjmp unknown_exception /* Instruction address */
45 .org 0x18
46 rjmp unknown_exception /* ITLB protection */
47 .org 0x1c
48 rjmp unknown_exception /* Breakpoint */
49 .org 0x20
50 rjmp unknown_exception /* Illegal opcode */
51 .org 0x24
52 rjmp unknown_exception /* Unimplemented instruction */
53 .org 0x28
54 rjmp unknown_exception /* Privilege violation */
55 .org 0x2c
56 rjmp unknown_exception /* Floating-point */
57 .org 0x30
58 rjmp unknown_exception /* Coprocessor absent */
59 .org 0x34
60 rjmp unknown_exception /* Data Address (read) */
61 .org 0x38
62 rjmp unknown_exception /* Data Address (write) */
63 .org 0x3c
64 rjmp unknown_exception /* DTLB Protection (read) */
65 .org 0x40
66 rjmp unknown_exception /* DTLB Protection (write) */
67 .org 0x44
68 rjmp unknown_exception /* DTLB Modified */
69
Haavard Skinnemoenc6f292f2010-08-12 13:52:54 +070070 .org 0x50 /* ITLB Miss */
71 pushm r8-r12,lr
72 rjmp 1f
73 .org 0x60 /* DTLB Miss (read) */
74 pushm r8-r12,lr
75 rjmp 1f
76 .org 0x70 /* DTLB Miss (write) */
77 pushm r8-r12,lr
781: mov r12, sp
79 rcall mmu_handle_tlb_miss
80 popm r8-r12,lr
81 brne unknown_exception
82 rete
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +020083
84 .size _evba, . - _evba
85
86 .align 2
87 .type unknown_exception, @function
88unknown_exception:
89 /* Figure out whether we're handling an exception (Exception
90 * mode) or just booting (Supervisor mode). */
91 csrfcz SYSREG_M1_OFFSET
92 brcc at32ap_cpu_bootstrap
93
94 /* This is an exception. Complain. */
95 pushm r0-r12
96 sub r8, sp, REG_R12 - REG_R0 - 4
97 mov r9, lr
98 mfsr r10, SYSREG_RAR_EX
99 mfsr r11, SYSREG_RSR_EX
100 pushm r8-r11
101 mfsr r12, SYSREG_ECR
102 mov r11, sp
103 rcall do_unknown_exception
1041: rjmp 1b
105
106 /* The COUNT/COMPARE timer interrupt handler */
107 .global timer_interrupt_handler
108 .type timer_interrupt_handler,@function
109 .align 2
110timer_interrupt_handler:
111 /*
112 * Increment timer_overflow and re-write COMPARE with 0xffffffff.
113 *
114 * We're running at interrupt level 3, so we don't need to save
115 * r8-r12 or lr to the stack.
116 */
117 lda.w r8, timer_overflow
118 ld.w r9, r8[0]
119 mov r10, -1
120 mtsr SYSREG_COMPARE, r10
121 sub r9, -1
122 st.w r8[0], r9
123 rete
Wolfgang Denk64702552006-10-24 14:27:35 +0200124
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +0200125 /*
126 * CPU bootstrap after reset is handled here. SoC code may
127 * override this in case they need to initialize oscillators,
128 * etc.
129 */
130 .section .text.at32ap_cpu_bootstrap, "ax", @progbits
131 .global at32ap_cpu_bootstrap
132 .weak at32ap_cpu_bootstrap
133 .type at32ap_cpu_bootstrap, @function
134 .align 2
135at32ap_cpu_bootstrap:
Wolfgang Denk64702552006-10-24 14:27:35 +0200136 /* Reset the Status Register */
137 mov r0, lo(SR_INIT)
138 orh r0, hi(SR_INIT)
139 mtsr SYSREG_SR, r0
140
141 /* Reset CPUCR and invalidate the BTB */
142 mov r2, CPUCR_INIT
143 mtsr SYSREG_CPUCR, r2
144
145 /* Flush the caches */
146 mov r1, 0
147 cache r1[4], 8
148 cache r1[0], 0
149 sync 0
150
151 /* Reset the MMU to default settings */
152 mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
153 mtsr SYSREG_MMUCR, r0
154
155 /* Internal RAM should not need any initialization. We might
156 have to initialize external RAM here if the part doesn't
157 have internal RAM (or we may use the data cache) */
158
159 /* Jump to cacheable segment */
160 lddpc pc, 1f
161
162 .align 2
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +02001631: .long at32ap_low_level_init
164 .size _start, . - _start
Wolfgang Denk64702552006-10-24 14:27:35 +0200165
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +0200166 /* Common CPU bootstrap code after oscillator/cache/etc. init */
167 .section .text.avr32ap_low_level_init, "ax", @progbits
168 .global at32ap_low_level_init
169 .type at32ap_low_level_init, @function
170 .align 2
171at32ap_low_level_init:
172 lddpc sp, sp_init
Wolfgang Denk64702552006-10-24 14:27:35 +0200173
Wolfgang Denk64702552006-10-24 14:27:35 +0200174 /* Initialize the GOT pointer */
175 lddpc r6, got_init
1763: rsub r6, pc
Haavard Skinnemoenabf19bf2006-11-20 15:53:10 +0100177
178 /* Let's go */
179 rjmp board_init_f
Wolfgang Denk64702552006-10-24 14:27:35 +0200180
181 .align 2
182 .type sp_init,@object
183sp_init:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200184 .long CONFIG_SYS_INIT_SP_ADDR
Wolfgang Denk64702552006-10-24 14:27:35 +0200185got_init:
186 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoenabf19bf2006-11-20 15:53:10 +0100187
188 /*
189 * void relocate_code(new_sp, new_gd, monitor_addr)
190 *
191 * Relocate the u-boot image into RAM and continue from there.
192 * Does not return.
193 */
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +0200194 .section .text.relocate_code,"ax",@progbits
Haavard Skinnemoenabf19bf2006-11-20 15:53:10 +0100195 .global relocate_code
196 .type relocate_code,@function
197relocate_code:
198 mov sp, r12 /* use new stack */
199 mov r12, r11 /* save new_gd */
200 mov r11, r10 /* save destination address */
201
202 /* copy .text section and flush the cache along the way */
203 lda.w r8, _text
204 lda.w r9, _etext
205 sub lr, r10, r8 /* relocation offset */
206
2071: ldm r8++, r0-r3
208 stm r10, r0-r3
209 sub r10, -16
210 ldm r8++, r0-r3
211 stm r10, r0-r3
212 sub r10, -16
213 cp.w r8, r9
214 cache r10[-4], 0x0d /* dcache clean/invalidate */
215 cache r10[-4], 0x01 /* icache invalidate */
216 brlt 1b
217
218 /* flush write buffer */
219 sync 0
220
221 /* copy data sections */
222 lda.w r9, _edata
2231: ld.d r0, r8++
224 st.d r10++, r0
225 cp.w r8, r9
226 brlt 1b
227
228 /* zero out .bss */
229 mov r0, 0
230 mov r1, 0
Simon Glassed70c8f2013-03-14 06:54:53 +0000231 lda.w r9, __bss_end
Haavard Skinnemoenabf19bf2006-11-20 15:53:10 +0100232 sub r9, r8
2331: st.d r10++, r0
234 sub r9, 8
235 brgt 1b
236
237 /* jump to RAM */
238 sub r0, pc, . - in_ram
239 add pc, r0, lr
240
241 .align 2
242in_ram:
243 /* find the new GOT and relocate it */
244 lddpc r6, got_init_reloc
2453: rsub r6, pc
246 mov r8, r6
247 lda.w r9, _egot
248 lda.w r10, _got
249 sub r9, r10
2501: ld.w r0, r8[0]
251 add r0, lr
252 st.w r8++, r0
253 sub r9, 4
254 brgt 1b
255
256 /* Move the exception handlers */
257 mfsr r2, SYSREG_EVBA
258 add r2, lr
259 mtsr SYSREG_EVBA, r2
260
261 /* Do the rest of the initialization sequence */
262 call board_init_r
263
264 .align 2
265got_init_reloc:
266 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoen2b56a4b2008-05-02 15:32:57 +0200267
268 .size relocate_code, . - relocate_code