blob: 7f32db787423d05d381be3b95020cf7f184b5aa9 [file] [log] [blame]
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +02001/*
Cyril Chemparathy678e0082010-06-07 14:13:27 -04002 * armboot - Startup Code for ARM1176 CPU-core
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +02003 *
4 * Copyright (c) 2007 Samsung Electronics
5 *
6 * Copyright (C) 2008
7 * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
8 *
9 * See file CREDITS for list of people who contributed to this
10 * project.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 *
27 * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)
28 * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
29 * jsgood (jsgood.yang@samsung.com)
30 * Base codes by scsuh (sc.suh)
31 */
32
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +020033#include <asm-offsets.h>
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +020034#include <config.h>
35#include <version.h>
36#ifdef CONFIG_ENABLE_MMU
37#include <asm/proc/domain.h>
38#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +020039
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020040#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
41#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +020042#endif
43
44/*
45 *************************************************************************
46 *
47 * Jump vector table as in table 3.1 in [1]
48 *
49 *************************************************************************
50 */
51
52.globl _start
53_start: b reset
54#ifndef CONFIG_NAND_SPL
55 ldr pc, _undefined_instruction
56 ldr pc, _software_interrupt
57 ldr pc, _prefetch_abort
58 ldr pc, _data_abort
59 ldr pc, _not_used
60 ldr pc, _irq
61 ldr pc, _fiq
62
63_undefined_instruction:
64 .word undefined_instruction
65_software_interrupt:
66 .word software_interrupt
67_prefetch_abort:
68 .word prefetch_abort
69_data_abort:
70 .word data_abort
71_not_used:
72 .word not_used
73_irq:
74 .word irq
75_fiq:
76 .word fiq
77_pad:
78 .word 0x12345678 /* now 16*4=64 */
79#else
80 . = _start + 64
81#endif
82
83.global _end_vect
84_end_vect:
85 .balignl 16,0xdeadbeef
86/*
87 *************************************************************************
88 *
89 * Startup Code (reset vector)
90 *
91 * do important init only if we don't start from memory!
92 * setup Memory and board specific bits prior to relocation.
93 * relocate armboot to ram
94 * setup stack
95 *
96 *************************************************************************
97 */
98
Heiko Schochera51dd672010-09-17 13:10:53 +020099.globl _TEXT_BASE
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200100_TEXT_BASE:
Wolfgang Denk14d0a022010-10-07 21:51:12 +0200101 .word CONFIG_SYS_TEXT_BASE
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200102
103/*
104 * Below variable is very important because we use MMU in U-Boot.
105 * Without it, we cannot run code correctly before MMU is ON.
106 * by scsuh.
107 */
108_TEXT_PHY_BASE:
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200109 .word CONFIG_SYS_PHY_UBOOT_BASE
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200110
Heiko Schochera51dd672010-09-17 13:10:53 +0200111#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200112.globl _armboot_start
113_armboot_start:
114 .word _start
Heiko Schochera51dd672010-09-17 13:10:53 +0200115#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200116
117/*
118 * These are defined in the board-specific linker script.
Darius Augulisea34c9d2010-10-25 13:48:03 +0300119 * Subtracting _start from them lets the linker put their
120 * relative position in the executable instead of leaving
121 * them null.
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200122 */
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200123
Darius Augulisea34c9d2010-10-25 13:48:03 +0300124.globl _bss_start_ofs
125_bss_start_ofs:
126 .word __bss_start - _start
127
128.globl _bss_end_ofs
129_bss_end_ofs:
130 .word _end - _start
131
132.globl _datarel_start_ofs
133_datarel_start_ofs:
134 .word __datarel_start - _start
135
136.globl _datarelrolocal_start_ofs
137_datarelrolocal_start_ofs:
138 .word __datarelrolocal_start - _start
139
140.globl _datarellocal_start_ofs
141_datarellocal_start_ofs:
142 .word __datarellocal_start - _start
143
144.globl _datarelro_start_ofs
145_datarelro_start_ofs:
146 .word __datarelro_start - _start
147
148.globl _rel_dyn_start_ofs
149_rel_dyn_start_ofs:
150 .word __rel_dyn_start - _start
151
152.globl _rel_dyn_end_ofs
153_rel_dyn_end_ofs:
154 .word __rel_dyn_end - _start
155
156.globl _dynsym_start_ofs
157_dynsym_start_ofs:
158 .word __dynsym_start - _start
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200159
Heiko Schochera51dd672010-09-17 13:10:53 +0200160#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
161/* IRQ stack memory (calculated at run-time) + 8 bytes */
162.globl IRQ_STACK_START_IN
163IRQ_STACK_START_IN:
164 .word 0x0badc0de
165
Heiko Schochera51dd672010-09-17 13:10:53 +0200166/*
167 * the actual reset code
168 */
169
170reset:
171 /*
172 * set the cpu to SVC32 mode
173 */
174 mrs r0, cpsr
175 bic r0, r0, #0x3f
176 orr r0, r0, #0xd3
177 msr cpsr, r0
178
179/*
180 *************************************************************************
181 *
182 * CPU_init_critical registers
183 *
184 * setup important registers
185 * setup memory timing
186 *
187 *************************************************************************
188 */
189 /*
190 * we do sys-critical inits only at reboot,
191 * not when booting from ram!
192 */
193cpu_init_crit:
194 /*
195 * When booting from NAND - it has definitely been a reset, so, no need
196 * to flush caches and disable the MMU
197 */
198#ifndef CONFIG_NAND_SPL
199 /*
200 * flush v4 I/D caches
201 */
202 mov r0, #0
203 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
204 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
205
206 /*
207 * disable MMU stuff and caches
208 */
209 mrc p15, 0, r0, c1, c0, 0
210 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
211 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
212 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
213 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
214
215 /* Prepare to disable the MMU */
216 adr r2, mmu_disable_phys
Wolfgang Denk14d0a022010-10-07 21:51:12 +0200217 sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
Heiko Schochera51dd672010-09-17 13:10:53 +0200218 b mmu_disable
219
220 .align 5
221 /* Run in a single cache-line */
222mmu_disable:
223 mcr p15, 0, r0, c1, c0, 0
224 nop
225 nop
226 mov pc, r2
227mmu_disable_phys:
228
229#ifdef CONFIG_DISABLE_TCM
230 /*
231 * Disable the TCMs
232 */
233 mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */
234 cmp r0, #0
235 beq skip_tcmdisable
236 mov r1, #0
237 mov r2, #1
238 tst r0, r2
239 mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/
240 tst r0, r2, LSL #16
241 mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/
242skip_tcmdisable:
243#endif
244#endif
245
246#ifdef CONFIG_PERIPORT_REMAP
247 /* Peri port setup */
248 ldr r0, =CONFIG_PERIPORT_BASE
249 orr r0, r0, #CONFIG_PERIPORT_SIZE
250 mcr p15,0,r0,c15,c2,4
251#endif
252
253 /*
254 * Go setup Memory and board specific bits prior to relocation.
255 */
256 bl lowlevel_init /* go setup pll,mux,memory */
257
258/* Set stackpointer in internal RAM to call board_init_f */
259call_board_init_f:
260 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
261 ldr r0,=0x00000000
262 bl board_init_f
263
264/*------------------------------------------------------------------------------*/
265
266/*
267 * void relocate_code (addr_sp, gd, addr_moni)
268 *
269 * This "function" does not return, instead it continues in RAM
270 * after relocating the monitor code.
271 *
272 */
273 .globl relocate_code
274relocate_code:
275 mov r4, r0 /* save addr_sp */
276 mov r5, r1 /* save addr of gd */
277 mov r6, r2 /* save addr of destination */
278 mov r7, r2 /* save addr of destination */
279
280 /* Set up the stack */
281stack_setup:
282 mov sp, r4
283
284 adr r0, _start
285 ldr r2, _TEXT_BASE
Darius Augulisea34c9d2010-10-25 13:48:03 +0300286 ldr r3, _bss_start_ofs
287 add r2, r0, r3 /* r2 <- source end address */
Heiko Schochera51dd672010-09-17 13:10:53 +0200288 cmp r0, r6
289 beq clear_bss
290
291#ifndef CONFIG_SKIP_RELOCATE_UBOOT
292copy_loop:
293 ldmia r0!, {r9-r10} /* copy from source address [r0] */
294 stmia r6!, {r9-r10} /* copy to target address [r1] */
Albert Aribaudda90d4c2010-10-05 16:06:39 +0200295 cmp r0, r2 /* until source end address [r2] */
296 blo copy_loop
Heiko Schochera51dd672010-09-17 13:10:53 +0200297
298#ifndef CONFIG_PRELOADER
Darius Augulisea34c9d2010-10-25 13:48:03 +0300299 /*
300 * fix .rel.dyn relocations
301 */
302 ldr r0, _TEXT_BASE /* r0 <- Text base */
303 sub r9, r7, r0 /* r9 <- relocation offset */
304 ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
305 add r10, r10, r0 /* r10 <- sym table in FLASH */
306 ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
307 add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
308 ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
309 add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
Heiko Schochera51dd672010-09-17 13:10:53 +0200310fixloop:
Darius Augulisea34c9d2010-10-25 13:48:03 +0300311 ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
312 add r0, r0, r9 /* r0 <- location to fix up in RAM */
313 ldr r1, [r2, #4]
314 and r8, r1, #0xff
315 cmp r8, #23 /* relative fixup? */
316 beq fixrel
317 cmp r8, #2 /* absolute fixup? */
318 beq fixabs
319 /* ignore unknown type of fixup */
320 b fixnext
321fixabs:
322 /* absolute fix: set location to (offset) symbol value */
323 mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
324 add r1, r10, r1 /* r1 <- address of symbol in table */
325 ldr r1, [r1, #4] /* r1 <- symbol value */
326 add r1, r1, r9 /* r1 <- relocated sym addr */
327 b fixnext
328fixrel:
329 /* relative fix: increase location by offset */
330 ldr r1, [r0]
331 add r1, r1, r9
332fixnext:
333 str r1, [r0]
334 add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
Heiko Schochera51dd672010-09-17 13:10:53 +0200335 cmp r2, r3
Darius Augulisea34c9d2010-10-25 13:48:03 +0300336 blo fixloop
Heiko Schochera51dd672010-09-17 13:10:53 +0200337#endif
338#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
339
340#ifdef CONFIG_ENABLE_MMU
341enable_mmu:
342 /* enable domain access */
343 ldr r5, =0x0000ffff
344 mcr p15, 0, r5, c3, c0, 0 /* load domain access register */
345
346 /* Set the TTB register */
347 ldr r0, _mmu_table_base
348 ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE
349 ldr r2, =0xfff00000
350 bic r0, r0, r2
351 orr r1, r0, r1
352 mcr p15, 0, r1, c2, c0, 0
353
354 /* Enable the MMU */
355 mrc p15, 0, r0, c1, c0, 0
356 orr r0, r0, #1 /* Set CR_M to enable MMU */
357
358 /* Prepare to enable the MMU */
359 adr r1, skip_hw_init
360 and r1, r1, #0x3fc
361 ldr r2, _TEXT_BASE
362 ldr r3, =0xfff00000
363 and r2, r2, r3
364 orr r2, r2, r1
365 b mmu_enable
366
367 .align 5
368 /* Run in a single cache-line */
369mmu_enable:
370
371 mcr p15, 0, r0, c1, c0, 0
372 nop
373 nop
374 mov pc, r2
375skip_hw_init:
376#endif
377
378clear_bss:
379#ifndef CONFIG_PRELOADER
Darius Augulisea34c9d2010-10-25 13:48:03 +0300380 ldr r0, _bss_start_ofs
381 ldr r1, _bss_end_ofs
Heiko Schochera51dd672010-09-17 13:10:53 +0200382 ldr r3, _TEXT_BASE /* Text base */
383 mov r4, r7 /* reloc addr */
Heiko Schochera51dd672010-09-17 13:10:53 +0200384 add r0, r0, r4
Heiko Schochera51dd672010-09-17 13:10:53 +0200385 add r1, r1, r4
386 mov r2, #0x00000000 /* clear */
387
388clbss_l:str r2, [r0] /* clear loop... */
389 add r0, r0, #4
390 cmp r0, r1
391 bne clbss_l
392
393 bl coloured_LED_init
394 bl red_LED_on
395#endif
396
397/*
398 * We are done. Do not return, instead branch to second part of board
399 * initialization, now running from RAM.
400 */
401#ifdef CONFIG_NAND_SPL
402 ldr pc, _nand_boot
403
404_nand_boot: .word nand_boot
405#else
Darius Augulisea34c9d2010-10-25 13:48:03 +0300406 ldr r0, _board_init_r_ofs
407 adr r1, _start
408 add lr, r0, r1
409#ifndef CONFIG_SKIP_RELOCATE_UBOOT
410 add lr, lr, r9
411#endif
Heiko Schochera51dd672010-09-17 13:10:53 +0200412 /* setup parameters for board_init_r */
413 mov r0, r5 /* gd_t */
414 mov r1, r7 /* dest_addr */
415 /* jump to it ... */
Heiko Schochera51dd672010-09-17 13:10:53 +0200416 mov pc, lr
417
Darius Augulisea34c9d2010-10-25 13:48:03 +0300418_board_init_r_ofs:
419 .word board_init_r - _start
Heiko Schochera51dd672010-09-17 13:10:53 +0200420#endif
421
422#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
423
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200424/*
425 * the actual reset code
426 */
427
428reset:
429 /*
430 * set the cpu to SVC32 mode
431 */
432 mrs r0, cpsr
433 bic r0, r0, #0x3f
434 orr r0, r0, #0xd3
435 msr cpsr, r0
436
437/*
438 *************************************************************************
439 *
440 * CPU_init_critical registers
441 *
442 * setup important registers
443 * setup memory timing
444 *
445 *************************************************************************
446 */
447 /*
448 * we do sys-critical inits only at reboot,
449 * not when booting from ram!
450 */
451cpu_init_crit:
452 /*
453 * When booting from NAND - it has definitely been a reset, so, no need
454 * to flush caches and disable the MMU
455 */
456#ifndef CONFIG_NAND_SPL
457 /*
458 * flush v4 I/D caches
459 */
460 mov r0, #0
461 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
462 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
463
464 /*
465 * disable MMU stuff and caches
466 */
467 mrc p15, 0, r0, c1, c0, 0
468 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
469 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
470 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
471 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400472
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200473 /* Prepare to disable the MMU */
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400474 adr r2, mmu_disable_phys
Wolfgang Denk14d0a022010-10-07 21:51:12 +0200475 sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200476 b mmu_disable
477
478 .align 5
479 /* Run in a single cache-line */
480mmu_disable:
481 mcr p15, 0, r0, c1, c0, 0
482 nop
483 nop
484 mov pc, r2
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400485mmu_disable_phys:
486
487#ifdef CONFIG_DISABLE_TCM
488 /*
489 * Disable the TCMs
490 */
491 mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */
492 cmp r0, #0
493 beq skip_tcmdisable
494 mov r1, #0
495 mov r2, #1
496 tst r0, r2
497 mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/
498 tst r0, r2, LSL #16
499 mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/
500skip_tcmdisable:
501#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200502#endif
503
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400504#ifdef CONFIG_PERIPORT_REMAP
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200505 /* Peri port setup */
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400506 ldr r0, =CONFIG_PERIPORT_BASE
507 orr r0, r0, #CONFIG_PERIPORT_SIZE
508 mcr p15,0,r0,c15,c2,4
Joonyoung Shim7b921592010-02-08 22:00:52 +0900509#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200510
511 /*
512 * Go setup Memory and board specific bits prior to relocation.
513 */
514 bl lowlevel_init /* go setup pll,mux,memory */
515
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400516#ifndef CONFIG_SKIP_RELOCATE_UBOOT
517relocate: /* relocate U-Boot to RAM */
518 adr r0, _start /* r0 <- current position of code */
519 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
520 cmp r0, r1 /* don't reloc during debug */
521 beq stack_setup
522
523 ldr r2, _armboot_start
524 ldr r3, _bss_start
525 sub r2, r3, r2 /* r2 <- size of armboot */
526 add r2, r0, r2 /* r2 <- source end address */
527
528copy_loop:
529 ldmia r0!, {r3-r10} /* copy from source address [r0] */
530 stmia r1!, {r3-r10} /* copy to target address [r1] */
Albert Aribaudda90d4c2010-10-05 16:06:39 +0200531 cmp r0, r2 /* until source end address [r2] */
532 blo copy_loop
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400533#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
534
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200535#ifdef CONFIG_ENABLE_MMU
536enable_mmu:
537 /* enable domain access */
538 ldr r5, =0x0000ffff
539 mcr p15, 0, r5, c3, c0, 0 /* load domain access register */
540
541 /* Set the TTB register */
542 ldr r0, _mmu_table_base
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200543 ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200544 ldr r2, =0xfff00000
545 bic r0, r0, r2
546 orr r1, r0, r1
547 mcr p15, 0, r1, c2, c0, 0
548
549 /* Enable the MMU */
550 mrc p15, 0, r0, c1, c0, 0
551 orr r0, r0, #1 /* Set CR_M to enable MMU */
552
553 /* Prepare to enable the MMU */
554 adr r1, skip_hw_init
555 and r1, r1, #0x3fc
556 ldr r2, _TEXT_BASE
557 ldr r3, =0xfff00000
558 and r2, r2, r3
559 orr r2, r2, r1
560 b mmu_enable
561
562 .align 5
563 /* Run in a single cache-line */
564mmu_enable:
565
566 mcr p15, 0, r0, c1, c0, 0
567 nop
568 nop
569 mov pc, r2
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400570skip_hw_init:
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200571#endif
572
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200573 /* Set up the stack */
574stack_setup:
Seunghyeon Rheea59a23d2009-11-13 16:49:41 +0900575 ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200576 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +0200577 sub r0, r0, #GENERATED_GBL_DATA_SIZE /* bdinfo */
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200578 sub sp, r0, #12 /* leave 3 words for abort-stack */
Vitaly Kuzmichev1a27f7d2010-06-15 22:18:11 +0400579 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200580
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200581clear_bss:
582 ldr r0, _bss_start /* find start of bss segment */
583 ldr r1, _bss_end /* stop here */
584 mov r2, #0 /* clear */
585
586clbss_l:
587 str r2, [r0] /* clear loop... */
588 add r0, r0, #4
589 cmp r0, r1
Albert Aribaudda90d4c2010-10-05 16:06:39 +0200590 blo clbss_l
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200591
592#ifndef CONFIG_NAND_SPL
593 ldr pc, _start_armboot
594
595_start_armboot:
596 .word start_armboot
597#else
598 b nand_boot
599/* .word nand_boot*/
600#endif
601
Heiko Schochera51dd672010-09-17 13:10:53 +0200602#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
603
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200604#ifdef CONFIG_ENABLE_MMU
605_mmu_table_base:
606 .word mmu_table
607#endif
608
609#ifndef CONFIG_NAND_SPL
610/*
611 * we assume that cache operation is done before. (eg. cleanup_before_linux())
612 * actually, we don't need to do anything about cache if not use d-cache in
613 * U-Boot. So, in this function we clean only MMU. by scsuh
614 *
615 * void theLastJump(void *kernel, int arch_num, uint boot_params);
616 */
617#ifdef CONFIG_ENABLE_MMU
618 .globl theLastJump
619theLastJump:
620 mov r9, r0
621 ldr r3, =0xfff00000
622 ldr r4, _TEXT_PHY_BASE
623 adr r5, phy_last_jump
624 bic r5, r5, r3
625 orr r5, r5, r4
626 mov pc, r5
627phy_last_jump:
628 /*
629 * disable MMU stuff
630 */
631 mrc p15, 0, r0, c1, c0, 0
632 bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
633 bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
634 orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
635 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
636 mcr p15, 0, r0, c1, c0, 0
637
638 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
639
640 mov r0, #0
641 mov pc, r9
642#endif
Cyril Chemparathy678e0082010-06-07 14:13:27 -0400643
644
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200645/*
646 *************************************************************************
647 *
648 * Interrupt handling
649 *
650 *************************************************************************
651 */
652@
653@ IRQ stack frame.
654@
655#define S_FRAME_SIZE 72
656
657#define S_OLD_R0 68
658#define S_PSR 64
659#define S_PC 60
660#define S_LR 56
661#define S_SP 52
662
663#define S_IP 48
664#define S_FP 44
665#define S_R10 40
666#define S_R9 36
667#define S_R8 32
668#define S_R7 28
669#define S_R6 24
670#define S_R5 20
671#define S_R4 16
672#define S_R3 12
673#define S_R2 8
674#define S_R1 4
675#define S_R0 0
676
677#define MODE_SVC 0x13
678#define I_BIT 0x80
679
680/*
681 * use bad_save_user_regs for abort/prefetch/undef/swi ...
682 */
683
684 .macro bad_save_user_regs
685 /* carve out a frame on current user stack */
686 sub sp, sp, #S_FRAME_SIZE
687 /* Save user registers (now in svc mode) r0-r12 */
688 stmia sp, {r0 - r12}
689
Heiko Schochera51dd672010-09-17 13:10:53 +0200690#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200691 ldr r2, _armboot_start
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200692 sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200693 /* set base 2 words into abort stack */
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +0200694 sub r2, r2, #(GENERATED_GBL_DATA_SIZE+8)
Heiko Schochera51dd672010-09-17 13:10:53 +0200695#else
696 ldr r2, IRQ_STACK_START_IN
697#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200698 /* get values for "aborted" pc and cpsr (into parm regs) */
699 ldmia r2, {r2 - r3}
700 /* grab pointer to old stack */
701 add r0, sp, #S_FRAME_SIZE
702
703 add r5, sp, #S_SP
704 mov r1, lr
705 /* save sp_SVC, lr_SVC, pc, cpsr */
706 stmia r5, {r0 - r3}
707 /* save current stack into r0 (param register) */
708 mov r0, sp
709 .endm
710
711 .macro get_bad_stack
Heiko Schochera51dd672010-09-17 13:10:53 +0200712#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200713 /* setup our mode stack (enter in banked mode) */
714 ldr r13, _armboot_start
715 /* move past malloc pool */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200716 sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200717 /* move to reserved a couple spots for abort stack */
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +0200718 sub r13, r13, #(GENERATED_GBL_DATA_SIZE + 8)
Heiko Schochera51dd672010-09-17 13:10:53 +0200719#else
720 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
721#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200722
723 /* save caller lr in position 0 of saved stack */
724 str lr, [r13]
725 /* get the spsr */
726 mrs lr, spsr
727 /* save spsr in position 1 of saved stack */
728 str lr, [r13, #4]
729
730 /* prepare SVC-Mode */
731 mov r13, #MODE_SVC
732 @ msr spsr_c, r13
733 /* switch modes, make sure moves will execute */
734 msr spsr, r13
735 /* capture return pc */
736 mov lr, pc
737 /* jump to next instruction & switch modes. */
738 movs pc, lr
739 .endm
740
741 .macro get_bad_stack_swi
742 /* space on current stack for scratch reg. */
743 sub r13, r13, #4
744 /* save R0's value. */
745 str r0, [r13]
Heiko Schochera51dd672010-09-17 13:10:53 +0200746#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200747 /* get data regions start */
748 ldr r0, _armboot_start
749 /* move past malloc pool */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200750 sub r0, r0, #(CONFIG_SYS_MALLOC_LEN)
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200751 /* move past gbl and a couple spots for abort stack */
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +0200752 sub r0, r0, #(GENERATED_GBL_DATA_SIZE + 8)
Heiko Schochera51dd672010-09-17 13:10:53 +0200753#else
754 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
755#endif
Guennadi Liakhovetski9b077732008-08-31 00:39:46 +0200756 /* save caller lr in position 0 of saved stack */
757 str lr, [r0]
758 /* get the spsr */
759 mrs r0, spsr
760 /* save spsr in position 1 of saved stack */
761 str lr, [r0, #4]
762 /* restore r0 */
763 ldr r0, [r13]
764 /* pop stack entry */
765 add r13, r13, #4
766 .endm
767
768/*
769 * exception handlers
770 */
771 .align 5
772undefined_instruction:
773 get_bad_stack
774 bad_save_user_regs
775 bl do_undefined_instruction
776
777 .align 5
778software_interrupt:
779 get_bad_stack_swi
780 bad_save_user_regs
781 bl do_software_interrupt
782
783 .align 5
784prefetch_abort:
785 get_bad_stack
786 bad_save_user_regs
787 bl do_prefetch_abort
788
789 .align 5
790data_abort:
791 get_bad_stack
792 bad_save_user_regs
793 bl do_data_abort
794
795 .align 5
796not_used:
797 get_bad_stack
798 bad_save_user_regs
799 bl do_not_used
800
801 .align 5
802irq:
803 get_bad_stack
804 bad_save_user_regs
805 bl do_irq
806
807 .align 5
808fiq:
809 get_bad_stack
810 bad_save_user_regs
811 bl do_fiq
812#endif /* CONFIG_NAND_SPL */