blob: e955d4388276e8d5c7f3a7636382a4e07243e98b [file] [log] [blame]
wdenkdc7c9a12003-03-26 06:55:25 +00001/*
2 * armboot - Startup Code for ARM720 CPU-core
3 *
4 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
5 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26
wdenkdc7c9a12003-03-26 06:55:25 +000027#include "config.h"
28#include "version.h"
29
30
31/*
32 *************************************************************************
33 *
34 * Jump vector table as in table 3.1 in [1]
35 *
36 *************************************************************************
37 */
38
39
40.globl _start
41_start: b reset
42 ldr pc, _undefined_instruction
43 ldr pc, _software_interrupt
44 ldr pc, _prefetch_abort
45 ldr pc, _data_abort
46 ldr pc, _not_used
47 ldr pc, _irq
48 ldr pc, _fiq
49
50_undefined_instruction: .word undefined_instruction
51_software_interrupt: .word software_interrupt
52_prefetch_abort: .word prefetch_abort
53_data_abort: .word data_abort
54_not_used: .word not_used
55_irq: .word irq
56_fiq: .word fiq
57
58 .balignl 16,0xdeadbeef
59
60
61/*
62 *************************************************************************
63 *
64 * Startup Code (reset vector)
65 *
66 * do important init only if we don't start from memory!
67 * relocate armboot to ram
68 * setup stack
69 * jump to second stage
70 *
71 *************************************************************************
72 */
73
74/*
75 * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h)
76 */
77_TEXT_BASE:
78 .word TEXT_BASE
79
80.globl _armboot_start
81_armboot_start:
82 .word _start
83
84/*
85 * Note: _armboot_end_data and _armboot_end are defined
86 * by the (board-dependent) linker script.
87 * _armboot_end_data is the first usable FLASH address after armboot
88 */
89.globl _armboot_end_data
90_armboot_end_data:
91 .word armboot_end_data
92/*
93 * Note: armboot_end is defined by the (board-dependent) linker script
94 */
95.globl _armboot_end
96_armboot_end:
97 .word armboot_end
98
99/*
100 * _armboot_real_end is the first usable RAM address behind armboot
101 * and the various stacks
102 */
103.globl _armboot_real_end
104_armboot_real_end:
105 .word 0x0badc0de
106
107#ifdef CONFIG_USE_IRQ
108/* IRQ stack memory (calculated at run-time) */
109.globl IRQ_STACK_START
110IRQ_STACK_START:
111 .word 0x0badc0de
112
113/* IRQ stack memory (calculated at run-time) */
114.globl FIQ_STACK_START
115FIQ_STACK_START:
116 .word 0x0badc0de
117#endif
118
119
120/*
121 * the actual reset code
122 */
123
124reset:
125 /*
wdenk8bde7f72003-06-27 21:31:46 +0000126 * set the cpu to SVC32 mode
127 */
128 mrs r0,cpsr
129 bic r0,r0,#0x1f
130 orr r0,r0,#0x13
131 msr cpsr,r0
wdenkdc7c9a12003-03-26 06:55:25 +0000132
133 /*
134 * relocate exeception table
135 */
136 ldr r0, =_start
137 ldr r1, =0x0
138 mov r2, #16
139copyex:
140 subs r2, r2, #1
141 ldr r3, [r0], #4
142 str r3, [r1], #4
143 bne copyex
144
145 /*
wdenk8bde7f72003-06-27 21:31:46 +0000146 * we do sys-critical inits only at reboot,
147 * not when booting from ram!
148 */
wdenkdc7c9a12003-03-26 06:55:25 +0000149#ifdef CONFIG_INIT_CRITICAL
wdenk8bde7f72003-06-27 21:31:46 +0000150 bl cpu_init_crit
wdenkdc7c9a12003-03-26 06:55:25 +0000151#endif
152
wdenk8bde7f72003-06-27 21:31:46 +0000153 /* set up the stack */
154 ldr r0, _armboot_end
155 add r0, r0, #CONFIG_STACKSIZE
156 sub sp, r0, #12 /* leave 3 words for abort-stack */
157 ldr pc,_start_armboot
wdenkdc7c9a12003-03-26 06:55:25 +0000158
159_start_armboot: .word start_armboot
160
161/*
162 *************************************************************************
163 *
164 * CPU_init_critical registers
165 *
166 *************************************************************************
167 */
168
169cpu_init_crit:
170 # actually do nothing for now!
171 mov pc, lr
172
173
wdenkdc7c9a12003-03-26 06:55:25 +0000174/*
175 *************************************************************************
176 *
177 * Interrupt handling
178 *
179 *************************************************************************
180 */
181
182@
183@ IRQ stack frame.
184@
185#define S_FRAME_SIZE 72
186
187#define S_OLD_R0 68
188#define S_PSR 64
189#define S_PC 60
190#define S_LR 56
191#define S_SP 52
192
193#define S_IP 48
194#define S_FP 44
195#define S_R10 40
196#define S_R9 36
197#define S_R8 32
198#define S_R7 28
199#define S_R6 24
200#define S_R5 20
201#define S_R4 16
202#define S_R3 12
203#define S_R2 8
204#define S_R1 4
205#define S_R0 0
206
207#define MODE_SVC 0x13
208#define I_BIT 0x80
209
210/*
211 * use bad_save_user_regs for abort/prefetch/undef/swi ...
212 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
213 */
214
215 .macro bad_save_user_regs
216 sub sp, sp, #S_FRAME_SIZE
217 stmia sp, {r0 - r12} @ Calling r0-r12
218 add r8, sp, #S_PC
219
220 ldr r2, _armboot_end
221 add r2, r2, #CONFIG_STACKSIZE
222 sub r2, r2, #8
223 ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
224 add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
225
226 add r5, sp, #S_SP
227 mov r1, lr
228 stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
229 mov r0, sp
230 .endm
231
232 .macro irq_save_user_regs
233 sub sp, sp, #S_FRAME_SIZE
234 stmia sp, {r0 - r12} @ Calling r0-r12
235 add r8, sp, #S_PC
236 stmdb r8, {sp, lr}^ @ Calling SP, LR
237 str lr, [r8, #0] @ Save calling PC
238 mrs r6, spsr
239 str r6, [r8, #4] @ Save CPSR
240 str r0, [r8, #8] @ Save OLD_R0
241 mov r0, sp
242 .endm
243
244 .macro irq_restore_user_regs
245 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
246 mov r0, r0
247 ldr lr, [sp, #S_PC] @ Get PC
248 add sp, sp, #S_FRAME_SIZE
249 subs pc, lr, #4 @ return & move spsr_svc into cpsr
250 .endm
251
252 .macro get_bad_stack
253 ldr r13, _armboot_end @ setup our mode stack
254 add r13, r13, #CONFIG_STACKSIZE @ resides at top of normal stack
255 sub r13, r13, #8
256
257 str lr, [r13] @ save caller lr / spsr
258 mrs lr, spsr
259 str lr, [r13, #4]
260
261 mov r13, #MODE_SVC @ prepare SVC-Mode
262 msr spsr_c, r13
263 mov lr, pc
264 movs pc, lr
265 .endm
266
267 .macro get_irq_stack @ setup IRQ stack
268 ldr sp, IRQ_STACK_START
269 .endm
270
271 .macro get_fiq_stack @ setup FIQ stack
272 ldr sp, FIQ_STACK_START
273 .endm
274
275/*
276 * exception handlers
277 */
278 .align 5
279undefined_instruction:
280 get_bad_stack
281 bad_save_user_regs
282 bl do_undefined_instruction
283
284 .align 5
285software_interrupt:
286 get_bad_stack
287 bad_save_user_regs
288 bl do_software_interrupt
289
290 .align 5
291prefetch_abort:
292 get_bad_stack
293 bad_save_user_regs
294 bl do_prefetch_abort
295
296 .align 5
297data_abort:
298 get_bad_stack
299 bad_save_user_regs
300 bl do_data_abort
301
302 .align 5
303not_used:
304 get_bad_stack
305 bad_save_user_regs
306 bl do_not_used
307
308#ifdef CONFIG_USE_IRQ
309
310 .align 5
311irq:
312 get_irq_stack
313 irq_save_user_regs
314 bl do_irq
315 irq_restore_user_regs
316
317 .align 5
318fiq:
319 get_fiq_stack
320 /* someone ought to write a more effiction fiq_save_user_regs */
321 irq_save_user_regs
322 bl do_fiq
323 irq_restore_user_regs
324
325#else
326
327 .align 5
328irq:
329 get_bad_stack
330 bad_save_user_regs
331 bl do_irq
332
333 .align 5
334fiq:
335 get_bad_stack
336 bad_save_user_regs
337 bl do_fiq
338
339#endif
340
341 .align 5
342.globl reset_cpu
343reset_cpu:
344 mov pc, r0