blob: 5008ac6e9e2f1a139d306e75122f3c8a91a021e6 [file] [log] [blame]
wdenkf8062712005-01-09 23:16:25 +00001/*
2 * armboot - Startup Code for OMP2420/ARM1136 CPU-core
3 *
wdenk2e405bf2005-01-10 00:01:04 +00004 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
wdenkf8062712005-01-09 23:16:25 +00005 *
6 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
7 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
Detlev Zundelf1b3f2b2009-05-13 10:54:10 +02008 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
wdenkf8062712005-01-09 23:16:25 +00009 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
10 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
11 *
12 * See file CREDITS for list of people who contributed to this
13 * project.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wdenk2e405bf2005-01-10 00:01:04 +000022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wdenkf8062712005-01-09 23:16:25 +000023 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 */
30
31#include <config.h>
32#include <version.h>
wdenkf8062712005-01-09 23:16:25 +000033.globl _start
wdenk2e405bf2005-01-10 00:01:04 +000034_start: b reset
Magnus Lilja1ec96d82009-06-13 20:50:00 +020035#ifdef CONFIG_PRELOADER
Kyungmin Park33174212008-01-17 16:43:25 +090036 ldr pc, _hang
37 ldr pc, _hang
38 ldr pc, _hang
39 ldr pc, _hang
40 ldr pc, _hang
41 ldr pc, _hang
42 ldr pc, _hang
43
44_hang:
45 .word do_hang
46 .word 0x12345678
47 .word 0x12345678
48 .word 0x12345678
49 .word 0x12345678
50 .word 0x12345678
51 .word 0x12345678
52 .word 0x12345678 /* now 16*4=64 */
53#else
wdenkf8062712005-01-09 23:16:25 +000054 ldr pc, _undefined_instruction
55 ldr pc, _software_interrupt
56 ldr pc, _prefetch_abort
57 ldr pc, _data_abort
58 ldr pc, _not_used
59 ldr pc, _irq
60 ldr pc, _fiq
61
wdenk2e405bf2005-01-10 00:01:04 +000062_undefined_instruction: .word undefined_instruction
wdenkf8062712005-01-09 23:16:25 +000063_software_interrupt: .word software_interrupt
64_prefetch_abort: .word prefetch_abort
65_data_abort: .word data_abort
66_not_used: .word not_used
67_irq: .word irq
68_fiq: .word fiq
wdenk2e405bf2005-01-10 00:01:04 +000069_pad: .word 0x12345678 /* now 16*4=64 */
Magnus Lilja1ec96d82009-06-13 20:50:00 +020070#endif /* CONFIG_PRELOADER */
wdenkf8062712005-01-09 23:16:25 +000071.global _end_vect
72_end_vect:
73
74 .balignl 16,0xdeadbeef
75/*
76 *************************************************************************
77 *
78 * Startup Code (reset vector)
79 *
80 * do important init only if we don't start from memory!
81 * setup Memory and board specific bits prior to relocation.
82 * relocate armboot to ram
83 * setup stack
84 *
85 *************************************************************************
86 */
87
Heiko Schocher504f87c2010-09-17 13:10:40 +020088.globl _TEXT_BASE
wdenkf8062712005-01-09 23:16:25 +000089_TEXT_BASE:
Wolfgang Denk0708bc62010-10-07 21:51:12 +020090 .word CONFIG_SYS_TEXT_BASE
wdenkf8062712005-01-09 23:16:25 +000091
Heiko Schocher504f87c2010-09-17 13:10:40 +020092#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
wdenkf8062712005-01-09 23:16:25 +000093.globl _armboot_start
94_armboot_start:
95 .word _start
Heiko Schocher504f87c2010-09-17 13:10:40 +020096#endif
wdenkf8062712005-01-09 23:16:25 +000097
98/*
99 * These are defined in the board-specific linker script.
100 */
101.globl _bss_start
102_bss_start:
103 .word __bss_start
104
105.globl _bss_end
106_bss_end:
107 .word _end
108
Heiko Schocher504f87c2010-09-17 13:10:40 +0200109#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
110.globl _datarel_start
111_datarel_start:
112 .word __datarel_start
113
114.globl _datarelrolocal_start
115_datarelrolocal_start:
116 .word __datarelrolocal_start
117
118.globl _datarellocal_start
119_datarellocal_start:
120 .word __datarellocal_start
121
122.globl _datarelro_start
123_datarelro_start:
124 .word __datarelro_start
125
126.globl _got_start
127_got_start:
128 .word __got_start
129
130.globl _got_end
131_got_end:
132 .word __got_end
133#endif
134
wdenkf8062712005-01-09 23:16:25 +0000135#ifdef CONFIG_USE_IRQ
136/* IRQ stack memory (calculated at run-time) */
137.globl IRQ_STACK_START
138IRQ_STACK_START:
139 .word 0x0badc0de
140
141/* IRQ stack memory (calculated at run-time) */
142.globl FIQ_STACK_START
143FIQ_STACK_START:
144 .word 0x0badc0de
145#endif
Heiko Schocher504f87c2010-09-17 13:10:40 +0200146
147#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
148/* IRQ stack memory (calculated at run-time) + 8 bytes */
149.globl IRQ_STACK_START_IN
150IRQ_STACK_START_IN:
151 .word 0x0badc0de
152#endif
153
154#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
155/*
156 * the actual reset code
157 */
158
159reset:
160 /*
161 * set the cpu to SVC32 mode
162 */
163 mrs r0,cpsr
164 bic r0,r0,#0x1f
165 orr r0,r0,#0xd3
166 msr cpsr,r0
167
168#ifdef CONFIG_OMAP2420H4
169 /* Copy vectors to mask ROM indirect addr */
170 adr r0, _start /* r0 <- current position of code */
171 add r0, r0, #4 /* skip reset vector */
172 mov r2, #64 /* r2 <- size to copy */
173 add r2, r0, r2 /* r2 <- source end address */
174 mov r1, #SRAM_OFFSET0 /* build vect addr */
175 mov r3, #SRAM_OFFSET1
176 add r1, r1, r3
177 mov r3, #SRAM_OFFSET2
178 add r1, r1, r3
179next:
180 ldmia r0!, {r3-r10} /* copy from source address [r0] */
181 stmia r1!, {r3-r10} /* copy to target address [r1] */
182 cmp r0, r2 /* until source end address [r2] */
183 bne next /* loop until equal */
184 bl cpy_clk_code /* put dpll adjust code behind vectors */
185#endif
186 /* the mask ROM code should have PLL and others stable */
187#ifndef CONFIG_SKIP_LOWLEVEL_INIT
188 bl cpu_init_crit
189#endif
190
191/* Set stackpointer in internal RAM to call board_init_f */
192call_board_init_f:
193 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
194 ldr r0,=0x00000000
195
196#ifdef CONFIG_NAND_SPL
197 bl nand_boot
198#else
199#ifdef CONFIG_ONENAND_IPL
200 bl start_oneboot
201#else
202 bl board_init_f
203#endif /* CONFIG_ONENAND_IPL */
204#endif /* CONFIG_NAND_SPL */
205
206/*------------------------------------------------------------------------------*/
207
208/*
209 * void relocate_code (addr_sp, gd, addr_moni)
210 *
211 * This "function" does not return, instead it continues in RAM
212 * after relocating the monitor code.
213 *
214 */
215 .globl relocate_code
216relocate_code:
217 mov r4, r0 /* save addr_sp */
218 mov r5, r1 /* save addr of gd */
219 mov r6, r2 /* save addr of destination */
220 mov r7, r2 /* save addr of destination */
221
222 /* Set up the stack */
223stack_setup:
224 mov sp, r4
225
226 adr r0, _start
227 ldr r2, _TEXT_BASE
228 ldr r3, _bss_start
229 sub r2, r3, r2 /* r2 <- size of armboot */
230 add r2, r0, r2 /* r2 <- source end address */
231 cmp r0, r6
232 beq clear_bss
233
234#ifndef CONFIG_SKIP_RELOCATE_UBOOT
235copy_loop:
236 ldmia r0!, {r9-r10} /* copy from source address [r0] */
237 stmia r6!, {r9-r10} /* copy to target address [r1] */
Albert Aribaud0668d162010-10-05 16:06:39 +0200238 cmp r0, r2 /* until source end address [r2] */
239 blo copy_loop
Heiko Schocher504f87c2010-09-17 13:10:40 +0200240
241#ifndef CONFIG_PRELOADER
242 /* fix got entries */
243 ldr r1, _TEXT_BASE
244 mov r0, r7 /* reloc addr */
245 ldr r2, _got_start /* addr in Flash */
246 ldr r3, _got_end /* addr in Flash */
247 sub r3, r3, r1
248 add r3, r3, r0
249 sub r2, r2, r1
250 add r2, r2, r0
251
252fixloop:
253 ldr r4, [r2]
254 sub r4, r4, r1
255 add r4, r4, r0
256 str r4, [r2]
257 add r2, r2, #4
258 cmp r2, r3
259 bne fixloop
260#endif
261#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
262
263clear_bss:
264#ifndef CONFIG_PRELOADER
265 ldr r0, _bss_start
266 ldr r1, _bss_end
267 ldr r3, _TEXT_BASE /* Text base */
268 mov r4, r7 /* reloc addr */
269 sub r0, r0, r3
270 add r0, r0, r4
271 sub r1, r1, r3
272 add r1, r1, r4
273 mov r2, #0x00000000 /* clear */
274
275clbss_l:str r2, [r0] /* clear loop... */
276 add r0, r0, #4
277 cmp r0, r1
278 bne clbss_l
279#endif /* #ifndef CONFIG_PRELOADER */
wdenkf8062712005-01-09 23:16:25 +0000280
281/*
Heiko Schocher504f87c2010-09-17 13:10:40 +0200282 * We are done. Do not return, instead branch to second part of board
283 * initialization, now running from RAM.
284 */
285#ifdef CONFIG_NAND_SPL
286 ldr pc, _nand_boot
287
288_nand_boot: .word nand_boot
289#else
290jump_2_ram:
291 ldr r0, _TEXT_BASE
292 ldr r2, _board_init_r
293 sub r2, r2, r0
294 add r2, r2, r7 /* position from board_init_r in RAM */
295 /* setup parameters for board_init_r */
296 mov r0, r5 /* gd_t */
297 mov r1, r7 /* dest_addr */
298 /* jump to it ... */
299 mov lr, r2
300 mov pc, lr
301
302_board_init_r: .word board_init_r
303#endif
304#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
305/*
wdenkf8062712005-01-09 23:16:25 +0000306 * the actual reset code
307 */
308
309reset:
310 /*
311 * set the cpu to SVC32 mode
312 */
313 mrs r0,cpsr
314 bic r0,r0,#0x1f
315 orr r0,r0,#0xd3
316 msr cpsr,r0
317
318#ifdef CONFIG_OMAP2420H4
wdenk2e405bf2005-01-10 00:01:04 +0000319 /* Copy vectors to mask ROM indirect addr */
320 adr r0, _start /* r0 <- current position of code */
Wolfgang Denka1be4762008-05-20 16:00:29 +0200321 add r0, r0, #4 /* skip reset vector */
wdenk2e405bf2005-01-10 00:01:04 +0000322 mov r2, #64 /* r2 <- size to copy */
323 add r2, r0, r2 /* r2 <- source end address */
324 mov r1, #SRAM_OFFSET0 /* build vect addr */
325 mov r3, #SRAM_OFFSET1
326 add r1, r1, r3
327 mov r3, #SRAM_OFFSET2
328 add r1, r1, r3
wdenkf8062712005-01-09 23:16:25 +0000329next:
wdenk2e405bf2005-01-10 00:01:04 +0000330 ldmia r0!, {r3-r10} /* copy from source address [r0] */
331 stmia r1!, {r3-r10} /* copy to target address [r1] */
332 cmp r0, r2 /* until source end address [r2] */
333 bne next /* loop until equal */
wdenk2e405bf2005-01-10 00:01:04 +0000334 bl cpy_clk_code /* put dpll adjust code behind vectors */
wdenkf8062712005-01-09 23:16:25 +0000335#endif
wdenkf8062712005-01-09 23:16:25 +0000336 /* the mask ROM code should have PLL and others stable */
wdenk3d3d99f2005-04-04 12:44:11 +0000337#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenkf8062712005-01-09 23:16:25 +0000338 bl cpu_init_crit
wdenk3d3d99f2005-04-04 12:44:11 +0000339#endif
wdenkf8062712005-01-09 23:16:25 +0000340
wdenk3d3d99f2005-04-04 12:44:11 +0000341#ifndef CONFIG_SKIP_RELOCATE_UBOOT
wdenkf8062712005-01-09 23:16:25 +0000342relocate: /* relocate U-Boot to RAM */
343 adr r0, _start /* r0 <- current position of code */
344 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
wdenk2e405bf2005-01-10 00:01:04 +0000345 cmp r0, r1 /* don't reloc during debug */
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200346#ifndef CONFIG_PRELOADER
wdenk2e405bf2005-01-10 00:01:04 +0000347 beq stack_setup
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200348#endif /* CONFIG_PRELOADER */
wdenkf8062712005-01-09 23:16:25 +0000349
350 ldr r2, _armboot_start
351 ldr r3, _bss_start
wdenk2e405bf2005-01-10 00:01:04 +0000352 sub r2, r3, r2 /* r2 <- size of armboot */
353 add r2, r0, r2 /* r2 <- source end address */
wdenkf8062712005-01-09 23:16:25 +0000354
355copy_loop:
356 ldmia r0!, {r3-r10} /* copy from source address [r0] */
357 stmia r1!, {r3-r10} /* copy to target address [r1] */
Albert Aribaud0668d162010-10-05 16:06:39 +0200358 cmp r0, r2 /* until source end address [r2] */
359 blo copy_loop
wdenk3d3d99f2005-04-04 12:44:11 +0000360#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
wdenkf8062712005-01-09 23:16:25 +0000361
362 /* Set up the stack */
363stack_setup:
364 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200365#ifdef CONFIG_PRELOADER
Kyungmin Park33174212008-01-17 16:43:25 +0900366 sub sp, r0, #128 /* leave 32 words for abort-stack */
367#else
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200368 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
369 sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
wdenkf8062712005-01-09 23:16:25 +0000370#ifdef CONFIG_USE_IRQ
371 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
372#endif
373 sub sp, r0, #12 /* leave 3 words for abort-stack */
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200374#endif /* CONFIG_PRELOADER */
Vitaly Kuzmichev9c2cec42010-06-15 22:18:11 +0400375 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
wdenkf8062712005-01-09 23:16:25 +0000376
377clear_bss:
wdenk2e405bf2005-01-10 00:01:04 +0000378 ldr r0, _bss_start /* find start of bss segment */
379 ldr r1, _bss_end /* stop here */
380 mov r2, #0x00000000 /* clear */
wdenkf8062712005-01-09 23:16:25 +0000381
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200382#ifndef CONFIG_PRELOADER
wdenk2e405bf2005-01-10 00:01:04 +0000383clbss_l:str r2, [r0] /* clear loop... */
wdenkf8062712005-01-09 23:16:25 +0000384 add r0, r0, #4
385 cmp r0, r1
386 bne clbss_l
Kyungmin Park33174212008-01-17 16:43:25 +0900387#endif
wdenkf8062712005-01-09 23:16:25 +0000388
389 ldr pc, _start_armboot
390
Magnus Lilja4133f652009-06-13 20:50:01 +0200391#ifdef CONFIG_NAND_SPL
392_start_armboot: .word nand_boot
393#else
Kyungmin Park33174212008-01-17 16:43:25 +0900394#ifdef CONFIG_ONENAND_IPL
395_start_armboot: .word start_oneboot
396#else
wdenk2e405bf2005-01-10 00:01:04 +0000397_start_armboot: .word start_armboot
Magnus Lilja4133f652009-06-13 20:50:01 +0200398#endif /* CONFIG_ONENAND_IPL */
399#endif /* CONFIG_NAND_SPL */
wdenkf8062712005-01-09 23:16:25 +0000400
Heiko Schocher504f87c2010-09-17 13:10:40 +0200401#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
402
wdenkf8062712005-01-09 23:16:25 +0000403/*
404 *************************************************************************
405 *
406 * CPU_init_critical registers
407 *
408 * setup important registers
409 * setup memory timing
410 *
411 *************************************************************************
412 */
Magnus Lilja4133f652009-06-13 20:50:01 +0200413#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenkf8062712005-01-09 23:16:25 +0000414cpu_init_crit:
415 /*
416 * flush v4 I/D caches
417 */
418 mov r0, #0
George G. Davis15967892010-05-11 10:15:36 -0400419 mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
420 mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */
wdenkf8062712005-01-09 23:16:25 +0000421
422 /*
423 * disable MMU stuff and caches
424 */
425 mrc p15, 0, r0, c1, c0, 0
426 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
427 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
428 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
wdenkf8062712005-01-09 23:16:25 +0000429 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
wdenkf8062712005-01-09 23:16:25 +0000430 mcr p15, 0, r0, c1, c0, 0
431
432 /*
wdenk2e405bf2005-01-10 00:01:04 +0000433 * Jump to board specific initialization... The Mask ROM will have already initialized
434 * basic memory. Go here to bump up clock rate and handle wake up conditions.
wdenkf8062712005-01-09 23:16:25 +0000435 */
wdenk2e405bf2005-01-10 00:01:04 +0000436 mov ip, lr /* persevere link reg across call */
Wolfgang Denk7f88a5e2005-10-06 17:08:18 +0200437 bl lowlevel_init /* go setup pll,mux,memory */
wdenk2e405bf2005-01-10 00:01:04 +0000438 mov lr, ip /* restore link */
439 mov pc, lr /* back to my caller */
Magnus Lilja4133f652009-06-13 20:50:01 +0200440#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
Kyungmin Park33174212008-01-17 16:43:25 +0900441
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200442#ifndef CONFIG_PRELOADER
wdenkf8062712005-01-09 23:16:25 +0000443/*
444 *************************************************************************
445 *
446 * Interrupt handling
447 *
448 *************************************************************************
449 */
450@
451@ IRQ stack frame.
452@
453#define S_FRAME_SIZE 72
454
455#define S_OLD_R0 68
456#define S_PSR 64
457#define S_PC 60
458#define S_LR 56
459#define S_SP 52
460
461#define S_IP 48
462#define S_FP 44
463#define S_R10 40
464#define S_R9 36
465#define S_R8 32
466#define S_R7 28
467#define S_R6 24
468#define S_R5 20
469#define S_R4 16
470#define S_R3 12
471#define S_R2 8
472#define S_R1 4
473#define S_R0 0
474
475#define MODE_SVC 0x13
476#define I_BIT 0x80
477
478/*
479 * use bad_save_user_regs for abort/prefetch/undef/swi ...
480 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
481 */
482
483 .macro bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000484 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
wdenkf8062712005-01-09 23:16:25 +0000485 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
486
Heiko Schocher504f87c2010-09-17 13:10:40 +0200487#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
488 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack
489#else
wdenkf8062712005-01-09 23:16:25 +0000490 ldr r2, _armboot_start
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200491 sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
492 sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
Heiko Schocher504f87c2010-09-17 13:10:40 +0200493#endif
wdenk2e405bf2005-01-10 00:01:04 +0000494 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
wdenkf8062712005-01-09 23:16:25 +0000495 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
496
497 add r5, sp, #S_SP
498 mov r1, lr
wdenk2e405bf2005-01-10 00:01:04 +0000499 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
500 mov r0, sp @ save current stack into r0 (param register)
wdenkf8062712005-01-09 23:16:25 +0000501 .endm
502
503 .macro irq_save_user_regs
504 sub sp, sp, #S_FRAME_SIZE
505 stmia sp, {r0 - r12} @ Calling r0-r12
wdenk2e405bf2005-01-10 00:01:04 +0000506 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
507 stmdb r8, {sp, lr}^ @ Calling SP, LR
508 str lr, [r8, #0] @ Save calling PC
509 mrs r6, spsr
510 str r6, [r8, #4] @ Save CPSR
511 str r0, [r8, #8] @ Save OLD_R0
wdenkf8062712005-01-09 23:16:25 +0000512 mov r0, sp
513 .endm
514
515 .macro irq_restore_user_regs
516 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
517 mov r0, r0
518 ldr lr, [sp, #S_PC] @ Get PC
519 add sp, sp, #S_FRAME_SIZE
520 subs pc, lr, #4 @ return & move spsr_svc into cpsr
521 .endm
522
523 .macro get_bad_stack
Heiko Schocher504f87c2010-09-17 13:10:40 +0200524#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
525 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode)
526#else
wdenkf8062712005-01-09 23:16:25 +0000527 ldr r13, _armboot_start @ setup our mode stack (enter in banked mode)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200528 sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
529 sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
Heiko Schocher504f87c2010-09-17 13:10:40 +0200530#endif
wdenkf8062712005-01-09 23:16:25 +0000531
532 str lr, [r13] @ save caller lr in position 0 of saved stack
wdenk2e405bf2005-01-10 00:01:04 +0000533 mrs lr, spsr @ get the spsr
534 str lr, [r13, #4] @ save spsr in position 1 of saved stack
wdenkf8062712005-01-09 23:16:25 +0000535
536 mov r13, #MODE_SVC @ prepare SVC-Mode
537 @ msr spsr_c, r13
wdenk2e405bf2005-01-10 00:01:04 +0000538 msr spsr, r13 @ switch modes, make sure moves will execute
539 mov lr, pc @ capture return pc
540 movs pc, lr @ jump to next instruction & switch modes.
wdenkf8062712005-01-09 23:16:25 +0000541 .endm
542
543 .macro get_bad_stack_swi
wdenk2e405bf2005-01-10 00:01:04 +0000544 sub r13, r13, #4 @ space on current stack for scratch reg.
545 str r0, [r13] @ save R0's value.
Heiko Schocher504f87c2010-09-17 13:10:40 +0200546#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
547 ldr r0, IRQ_STACK_START_IN @ get data regions start
548#else
wdenkf8062712005-01-09 23:16:25 +0000549 ldr r0, _armboot_start @ get data regions start
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200550 sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
551 sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
Heiko Schocher504f87c2010-09-17 13:10:40 +0200552#endif
wdenkf8062712005-01-09 23:16:25 +0000553 str lr, [r0] @ save caller lr in position 0 of saved stack
wdenk2e405bf2005-01-10 00:01:04 +0000554 mrs r0, spsr @ get the spsr
555 str lr, [r0, #4] @ save spsr in position 1 of saved stack
556 ldr r0, [r13] @ restore r0
557 add r13, r13, #4 @ pop stack entry
wdenkf8062712005-01-09 23:16:25 +0000558 .endm
559
560 .macro get_irq_stack @ setup IRQ stack
561 ldr sp, IRQ_STACK_START
562 .endm
563
564 .macro get_fiq_stack @ setup FIQ stack
565 ldr sp, FIQ_STACK_START
566 .endm
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200567#endif /* CONFIG_PRELOADER */
wdenkf8062712005-01-09 23:16:25 +0000568
569/*
570 * exception handlers
571 */
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200572#ifdef CONFIG_PRELOADER
Kyungmin Park33174212008-01-17 16:43:25 +0900573 .align 5
574do_hang:
575 ldr sp, _TEXT_BASE /* use 32 words about stack */
576 bl hang /* hang and never return */
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200577#else /* !CONFIG_PRELOADER */
wdenk2e405bf2005-01-10 00:01:04 +0000578 .align 5
wdenkf8062712005-01-09 23:16:25 +0000579undefined_instruction:
580 get_bad_stack
581 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000582 bl do_undefined_instruction
wdenkf8062712005-01-09 23:16:25 +0000583
584 .align 5
585software_interrupt:
586 get_bad_stack_swi
587 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000588 bl do_software_interrupt
wdenkf8062712005-01-09 23:16:25 +0000589
590 .align 5
591prefetch_abort:
592 get_bad_stack
593 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000594 bl do_prefetch_abort
wdenkf8062712005-01-09 23:16:25 +0000595
596 .align 5
597data_abort:
598 get_bad_stack
599 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000600 bl do_data_abort
wdenkf8062712005-01-09 23:16:25 +0000601
602 .align 5
603not_used:
604 get_bad_stack
605 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000606 bl do_not_used
wdenkf8062712005-01-09 23:16:25 +0000607
608#ifdef CONFIG_USE_IRQ
609
610 .align 5
611irq:
612 get_irq_stack
613 irq_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000614 bl do_irq
wdenkf8062712005-01-09 23:16:25 +0000615 irq_restore_user_regs
616
617 .align 5
618fiq:
619 get_fiq_stack
620 /* someone ought to write a more effiction fiq_save_user_regs */
621 irq_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000622 bl do_fiq
wdenkf8062712005-01-09 23:16:25 +0000623 irq_restore_user_regs
624
625#else
626
627 .align 5
628irq:
629 get_bad_stack
630 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000631 bl do_irq
wdenkf8062712005-01-09 23:16:25 +0000632
633 .align 5
634fiq:
635 get_bad_stack
636 bad_save_user_regs
wdenk2e405bf2005-01-10 00:01:04 +0000637 bl do_fiq
wdenkf8062712005-01-09 23:16:25 +0000638
639#endif
640 .align 5
641.global arm1136_cache_flush
642arm1136_cache_flush:
Heiko Schocher95965b92010-09-17 13:10:32 +0200643#if !defined(CONFIG_SYS_NO_ICACHE)
wdenkf8062712005-01-09 23:16:25 +0000644 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
Heiko Schocher95965b92010-09-17 13:10:32 +0200645#endif
646#if !defined(CONFIG_SYS_NO_DCACHE)
647 mcr p15, 0, r1, c7, c14, 0 @ invalidate D cache
648#endif
wdenkf8062712005-01-09 23:16:25 +0000649 mov pc, lr @ back to caller
Magnus Lilja1ec96d82009-06-13 20:50:00 +0200650#endif /* CONFIG_PRELOADER */