/*
- * armboot - Startup Code for S3C6400/ARM1176 CPU-core
+ * armboot - Startup Code for ARM1176 CPU-core
*
* Copyright (c) 2007 Samsung Electronics
*
* Base codes by scsuh (sc.suh)
*/
+#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#ifdef CONFIG_ENABLE_MMU
#include <asm/proc/domain.h>
#endif
-#ifdef CONFIG_S3C64XX
-#include <asm/arch/s3c6400.h>
-#endif
#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
*************************************************************************
*/
+.globl _TEXT_BASE
_TEXT_BASE:
- .word TEXT_BASE
+ .word CONFIG_SYS_TEXT_BASE
/*
* Below variable is very important because we use MMU in U-Boot.
_TEXT_PHY_BASE:
.word CONFIG_SYS_PHY_UBOOT_BASE
-.globl _armboot_start
-_armboot_start:
- .word _start
-
/*
* These are defined in the board-specific linker script.
+ * Subtracting _start from them lets the linker put their
+ * relative position in the executable instead of leaving
+ * them null.
*/
-.globl _bss_start
-_bss_start:
- .word __bss_start
-.globl _bss_end
-_bss_end:
- .word _end
+.globl _bss_start_ofs
+_bss_start_ofs:
+ .word __bss_start - _start
+
+.globl _bss_end_ofs
+_bss_end_ofs:
+ .word __bss_end - _start
+
+.globl _end_ofs
+_end_ofs:
+ .word _end - _start
+
+/* IRQ stack memory (calculated at run-time) + 8 bytes */
+.globl IRQ_STACK_START_IN
+IRQ_STACK_START_IN:
+ .word 0x0badc0de
/*
* the actual reset code
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+
/* Prepare to disable the MMU */
- adr r1, mmu_disable_phys
- /* We presume we're within the first 1024 bytes */
- and r1, r1, #0x3fc
- ldr r2, _TEXT_PHY_BASE
- ldr r3, =0xfff00000
- and r2, r2, r3
- orr r2, r2, r1
+ adr r2, mmu_disable_phys
+ sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
b mmu_disable
.align 5
nop
nop
mov pc, r2
+mmu_disable_phys:
+
+#ifdef CONFIG_DISABLE_TCM
+ /*
+ * Disable the TCMs
+ */
+ mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */
+ cmp r0, #0
+ beq skip_tcmdisable
+ mov r1, #0
+ mov r2, #1
+ tst r0, r2
+ mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/
+ tst r0, r2, LSL #16
+ mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/
+skip_tcmdisable:
+#endif
#endif
-mmu_disable_phys:
-#ifdef CONFIG_S3C64XX
+#ifdef CONFIG_PERIPORT_REMAP
/* Peri port setup */
- ldr r0, =0x70000000
- orr r0, r0, #0x13
- mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff)
+ ldr r0, =CONFIG_PERIPORT_BASE
+ orr r0, r0, #CONFIG_PERIPORT_SIZE
+ mcr p15,0,r0,c15,c2,4
#endif
/*
*/
bl lowlevel_init /* go setup pll,mux,memory */
-after_copy:
+ bl _main
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ */
+ .globl relocate_code
+relocate_code:
+ mov r4, r0 /* save addr_sp */
+ mov r5, r1 /* save addr of gd */
+ mov r6, r2 /* save addr of destination */
+
+ adr r0, _start
+ cmp r0, r6
+ moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */
+ beq relocate_done /* skip relocation */
+ mov r1, r6 /* r1 <- scratch for copy_loop */
+ ldr r3, _bss_start_ofs
+ add r2, r0, r3 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r9-r10} /* copy from source address [r0] */
+ stmia r1!, {r9-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end address [r2] */
+ blo copy_loop
+
+#ifndef CONFIG_SPL_BUILD
+ /*
+ * fix .rel.dyn relocations
+ */
+ ldr r0, _TEXT_BASE /* r0 <- Text base */
+ sub r9, r6, r0 /* r9 <- relocation offset */
+ ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
+ add r10, r10, r0 /* r10 <- sym table in FLASH */
+ ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
+ add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
+ ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
+ add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
+fixloop:
+ ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
+ add r0, r0, r9 /* r0 <- location to fix up in RAM */
+ ldr r1, [r2, #4]
+ and r7, r1, #0xff
+ cmp r7, #23 /* relative fixup? */
+ beq fixrel
+ cmp r7, #2 /* absolute fixup? */
+ beq fixabs
+ /* ignore unknown type of fixup */
+ b fixnext
+fixabs:
+ /* absolute fix: set location to (offset) symbol value */
+ mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
+ add r1, r10, r1 /* r1 <- address of symbol in table */
+ ldr r1, [r1, #4] /* r1 <- symbol value */
+ add r1, r1, r9 /* r1 <- relocated sym addr */
+ b fixnext
+fixrel:
+ /* relative fix: increase location by offset */
+ ldr r1, [r0]
+ add r1, r1, r9
+fixnext:
+ str r1, [r0]
+ add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
+ cmp r2, r3
+ blo fixloop
+#endif
+
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
nop
nop
mov pc, r2
+skip_hw_init:
#endif
-skip_hw_init:
- /* Set up the stack */
-stack_setup:
- ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */
- sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
- sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
- sub sp, r0, #12 /* leave 3 words for abort-stack */
-
-clear_bss:
- ldr r0, _bss_start /* find start of bss segment */
- ldr r1, _bss_end /* stop here */
- mov r2, #0 /* clear */
-
-clbss_l:
- str r2, [r0] /* clear loop... */
- add r0, r0, #4
- cmp r0, r1
- ble clbss_l
+relocate_done:
-#ifndef CONFIG_NAND_SPL
- ldr pc, _start_armboot
+ bx lr
-_start_armboot:
- .word start_armboot
-#else
- b nand_boot
-/* .word nand_boot*/
-#endif
+_rel_dyn_start_ofs:
+ .word __rel_dyn_start - _start
+_rel_dyn_end_ofs:
+ .word __rel_dyn_end - _start
+_dynsym_start_ofs:
+ .word __dynsym_start - _start
#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word mmu_table
#endif
+ .globl c_runtime_cpu_setup
+c_runtime_cpu_setup:
+
+ mov pc, lr
+
#ifndef CONFIG_NAND_SPL
/*
* we assume that cache operation is done before. (eg. cleanup_before_linux())
mov r0, #0
mov pc, r9
#endif
+
+
/*
*************************************************************************
*
/* Save user registers (now in svc mode) r0-r12 */
stmia sp, {r0 - r12}
- ldr r2, _armboot_start
- sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
- /* set base 2 words into abort stack */
- sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
+ ldr r2, IRQ_STACK_START_IN
/* get values for "aborted" pc and cpsr (into parm regs) */
ldmia r2, {r2 - r3}
/* grab pointer to old stack */
.endm
.macro get_bad_stack
- /* setup our mode stack (enter in banked mode) */
- ldr r13, _armboot_start
- /* move past malloc pool */
- sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
- /* move to reserved a couple spots for abort stack */
- sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
+ ldr r13, IRQ_STACK_START_IN @ setup our mode stack
/* save caller lr in position 0 of saved stack */
str lr, [r13]
sub r13, r13, #4
/* save R0's value. */
str r0, [r13]
- /* get data regions start */
- ldr r0, _armboot_start
- /* move past malloc pool */
- sub r0, r0, #(CONFIG_SYS_MALLOC_LEN)
- /* move past gbl and a couple spots for abort stack */
- sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
+ ldr r13, IRQ_STACK_START_IN @ setup our mode stack
/* save caller lr in position 0 of saved stack */
str lr, [r0]
/* get the spsr */