arc: clean-up init procedure

Intention behind this work was elimination of as much assembly-written
code as it is possible.

In case of ARC we already have relocation fix-up implemented in C so why
don't we use C for U-Boot copying, .bss zeroing etc.

It turned out x86 uses pretty similar approach so we re-used parts of
code in "board_f.c" initially implemented for x86.

Now assembly usage during init is limited to stack- and frame-pointer
setup before and after relocation.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Simon Glass <sjg@chromium.org>
master
Alexey Brodkin 10 years ago
parent 8ee28251d9
commit 3fb8016360
  1. 12
      arch/arc/include/asm/init_helpers.h
  2. 16
      arch/arc/include/asm/relocate.h
  3. 3
      arch/arc/include/asm/u-boot-arc.h
  4. 1
      arch/arc/lib/Makefile
  5. 13
      arch/arc/lib/cpu.c
  6. 25
      arch/arc/lib/init_helpers.c
  7. 19
      arch/arc/lib/relocate.c
  8. 82
      arch/arc/lib/start.S
  9. 8
      common/board_f.c

@ -0,0 +1,12 @@
/*
* Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARC_INIT_HELPERS_H
#define _ASM_ARC_INIT_HELPERS_H
int init_cache_f_r(void);
#endif /* _ASM_ARC_INIT_HELPERS_H */

@ -0,0 +1,16 @@
/*
* Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARC_RELOCATE_H
#define _ASM_ARC_RELOCATE_H
#include <common.h>
int copy_uboot_to_ram(void);
int clear_bss(void);
int do_elf_reloc_fixups(void);
#endif /* _ASM_ARC_RELOCATE_H */

@ -9,4 +9,7 @@
int arch_early_init_r(void); int arch_early_init_r(void);
void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
void board_init_f_r(void) __attribute__ ((noreturn));
#endif /* __ASM_ARC_U_BOOT_ARC_H__ */ #endif /* __ASM_ARC_U_BOOT_ARC_H__ */

@ -20,6 +20,7 @@ obj-y += reset.o
obj-y += timer.o obj-y += timer.o
obj-y += start.o obj-y += start.o
obj-y += ints_low.o obj-y += ints_low.o
obj-y += init_helpers.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTM) += bootm.o

@ -12,19 +12,6 @@ DECLARE_GLOBAL_DATA_PTR;
int arch_cpu_init(void) int arch_cpu_init(void)
{ {
#ifdef CONFIG_SYS_ICACHE_OFF
icache_disable();
#else
icache_enable();
invalidate_icache_all();
#endif
flush_dcache_all();
#ifdef CONFIG_SYS_DCACHE_OFF
dcache_disable();
#else
dcache_enable();
#endif
timer_init(); timer_init();
/* In simulation (ISS) "CHIPID" and "ARCNUM" are all "ff" */ /* In simulation (ISS) "CHIPID" and "ARCNUM" are all "ff" */

@ -0,0 +1,25 @@
/*
* Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
int init_cache_f_r(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
icache_enable();
/* Make sure no stale entries persist from before we disabled cache */
invalidate_icache_all();
#endif
#ifndef CONFIG_SYS_DCACHE_OFF
dcache_enable();
/* Make sure no stale entries persist from before we disabled cache */
invalidate_dcache_all();
#endif
return 0;
}

@ -10,6 +10,25 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
int copy_uboot_to_ram(void)
{
size_t len = (size_t)&__image_copy_end - (size_t)&__image_copy_start;
memcpy((void *)gd->relocaddr, (void *)&__image_copy_start, len);
return 0;
}
int clear_bss(void)
{
ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
memset((void *)dst_addr, 0x00, len);
return 0;
}
/* /*
* Base functionality is taken from x86 version with added ARC-specifics * Base functionality is taken from x86 version with added ARC-specifics
*/ */

@ -13,17 +13,14 @@ ENTRY(_start)
/* Setup interrupt vector base that matches "__text_start" */ /* Setup interrupt vector base that matches "__text_start" */
sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] sr __ivt_start, [ARC_AUX_INTR_VEC_BASE]
/* Setup stack pointer */ /* Setup stack- and frame-pointers */
mov %sp, CONFIG_SYS_INIT_SP_ADDR mov %sp, CONFIG_SYS_INIT_SP_ADDR
mov %fp, %sp mov %fp, %sp
/* Clear bss */ /* Unconditionally disable caches */
mov %r0, __bss_start bl flush_dcache_all
mov %r1, __bss_end bl dcache_disable
bl icache_disable
clear_bss:
st.ab 0, [%r0, 4]
brlt %r0, %r1, clear_bss
/* Zero the one and only argument of "board_init_f" */ /* Zero the one and only argument of "board_init_f" */
mov_s %r0, 0 mov_s %r0, 0
@ -31,67 +28,24 @@ clear_bss:
ENDPROC(_start) ENDPROC(_start)
/* /*
* void relocate_code (addr_sp, gd, addr_moni) * void board_init_f_r_trampoline(stack-pointer address)
* *
* This "function" does not return, instead it continues in RAM * This "function" does not return, instead it continues in RAM
* after relocating the monitor code. * after relocating the monitor code.
* *
* r0 = start_addr_sp * r0 = new stack-pointer
* r1 = new__gd
* r2 = relocaddr
*/
ENTRY(relocate_code)
/*
* r0-r12 might be clobbered by C functions
* so we use r13-r16 for storage here
*/ */
mov %r13, %r0 /* save addr_sp */ ENTRY(board_init_f_r_trampoline)
mov %r14, %r1 /* save addr of gd */ /* Set up the stack- and frame-pointers */
mov %r15, %r2 /* save addr of destination */ mov %sp, %r0
mov %r16, %r2 /* %r9 - relocation offset */
sub %r16, %r16, __image_copy_start
/* Set up the stack */
stack_setup:
mov %sp, %r13
mov %fp, %sp mov %fp, %sp
/* Check if monitor is loaded right in place for relocation */
mov %r0, __image_copy_start
cmp %r0, %r15 /* skip relocation if code loaded */
bz do_board_init_r /* in target location already */
/* Copy data (__image_copy_start - __image_copy_end) to new location */
mov %r1, %r15
mov %r2, __image_copy_end
sub %r2, %r2, %r0 /* r3 <- amount of bytes to copy */
asr %r2, %r2, 2 /* r3 <- amount of words to copy */
mov %lp_count, %r2
lp copy_end
ld.ab %r2,[%r0,4]
st.ab %r2,[%r1,4]
copy_end:
/* Fix relocations related issues */
bl do_elf_reloc_fixups
#ifndef CONFIG_SYS_ICACHE_OFF
bl invalidate_icache_all
#endif
#ifndef CONFIG_SYS_DCACHE_OFF
bl flush_dcache_all
#endif
/* Update position of intterupt vector table */ /* Update position of intterupt vector table */
lr %r0, [ARC_AUX_INTR_VEC_BASE] /* Read current position */ lr %r0, [ARC_AUX_INTR_VEC_BASE]
add %r0, %r0, %r16 /* Update address */ ld %r1, [%r25, GD_RELOC_OFF]
sr %r0, [ARC_AUX_INTR_VEC_BASE] /* Write new position */ add %r0, %r0, %r1
sr %r0, [ARC_AUX_INTR_VEC_BASE]
do_board_init_r:
/* Prepare for exection of "board_init_r" in relocated monitor */ /* Re-enter U-Boot by calling board_init_f_r */
mov %r2, board_init_r /* old address of "board_init_r()" */ j board_init_f_r
add %r2, %r2, %r16 /* new address of "board_init_r()" */ ENDPROC(board_init_f_r_trampoline)
mov %r0, %r14 /* 1-st parameter: gd_t */
mov %r1, %r15 /* 2-nd parameter: dest_addr */
j [%r2]
ENDPROC(relocate_code)

@ -47,7 +47,7 @@
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sections.h> #include <asm/sections.h>
#ifdef CONFIG_X86 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
#include <asm/init_helpers.h> #include <asm/init_helpers.h>
#include <asm/relocate.h> #include <asm/relocate.h>
#endif #endif
@ -761,7 +761,7 @@ static int jump_to_copy(void)
* similarly for all archs. When we do generic relocation, hopefully * similarly for all archs. When we do generic relocation, hopefully
* we can make all archs enable the dcache prior to relocation. * we can make all archs enable the dcache prior to relocation.
*/ */
#ifdef CONFIG_X86 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
/* /*
* SDRAM and console are now initialised. The final stack can now * SDRAM and console are now initialised. The final stack can now
* be setup in SDRAM. Code execution will continue in Flash, but * be setup in SDRAM. Code execution will continue in Flash, but
@ -997,7 +997,7 @@ static init_fnc_t init_sequence_f[] = {
INIT_FUNC_WATCHDOG_RESET INIT_FUNC_WATCHDOG_RESET
reloc_fdt, reloc_fdt,
setup_reloc, setup_reloc,
#ifdef CONFIG_X86 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
copy_uboot_to_ram, copy_uboot_to_ram,
clear_bss, clear_bss,
do_elf_reloc_fixups, do_elf_reloc_fixups,
@ -1041,7 +1041,7 @@ void board_init_f(ulong boot_flags)
#endif #endif
} }
#ifdef CONFIG_X86 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
/* /*
* For now this code is only used on x86. * For now this code is only used on x86.
* *

Loading…
Cancel
Save