]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/avr32/cpu/start.S
avr32: Add simple paging support
[karo-tx-uboot.git] / arch / avr32 / cpu / 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 /* 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))
34
35         /*
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
41         .global _start
42         .global _evba
43         .type   _start, @function
44         .type   _evba, @function
45 _start:
46         .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 */
84
85         .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
93 1:      mov     r12, sp
94         rcall   mmu_handle_tlb_miss
95         popm    r8-r12,lr
96         brne    unknown_exception
97         rete
98
99         .size   _evba, . - _evba
100
101         .align  2
102         .type   unknown_exception, @function
103 unknown_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
119 1:      rjmp    1b
120
121         /* The COUNT/COMPARE timer interrupt handler */
122         .global timer_interrupt_handler
123         .type   timer_interrupt_handler,@function
124         .align  2
125 timer_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
150 at32ap_cpu_bootstrap:
151         /* 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
178 1:      .long   at32ap_low_level_init
179         .size   _start, . - _start
180
181         /* 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
186 at32ap_low_level_init:
187         lddpc   sp, sp_init
188
189         /* Initialize the GOT pointer */
190         lddpc   r6, got_init
191 3:      rsub    r6, pc
192
193         /* Let's go */
194         rjmp    board_init_f
195
196         .align  2
197         .type   sp_init,@object
198 sp_init:
199         .long   CONFIG_SYS_INIT_SP_ADDR
200 got_init:
201         .long   3b - _GLOBAL_OFFSET_TABLE_
202
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          */
209         .section .text.relocate_code,"ax",@progbits
210         .global relocate_code
211         .type   relocate_code,@function
212 relocate_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
222 1:      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
238 1:      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
248 1:      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
257 in_ram:
258         /* find the new GOT and relocate it */
259         lddpc   r6, got_init_reloc
260 3:      rsub    r6, pc
261         mov     r8, r6
262         lda.w   r9, _egot
263         lda.w   r10, _got
264         sub     r9, r10
265 1:      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
280 got_init_reloc:
281         .long   3b - _GLOBAL_OFFSET_TABLE_
282
283         .size   relocate_code, . - relocate_code