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);
void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
void board_init_f_r(void) __attribute__ ((noreturn));
#endif /* __ASM_ARC_U_BOOT_ARC_H__ */

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

@ -12,19 +12,6 @@ DECLARE_GLOBAL_DATA_PTR;
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();
/* 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;
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
*/

@ -13,17 +13,14 @@ ENTRY(_start)
/* Setup interrupt vector base that matches "__text_start" */
sr __ivt_start, [ARC_AUX_INTR_VEC_BASE]
/* Setup stack pointer */
/* Setup stack- and frame-pointers */
mov %sp, CONFIG_SYS_INIT_SP_ADDR
mov %fp, %sp
/* Clear bss */
mov %r0, __bss_start
mov %r1, __bss_end
clear_bss:
st.ab 0, [%r0, 4]
brlt %r0, %r1, clear_bss
/* Unconditionally disable caches */
bl flush_dcache_all
bl dcache_disable
bl icache_disable
/* Zero the one and only argument of "board_init_f" */
mov_s %r0, 0
@ -31,67 +28,24 @@ clear_bss:
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
* after relocating the monitor code.
*
* r0 = start_addr_sp
* r1 = new__gd
* r2 = relocaddr
*/
ENTRY(relocate_code)
/*
* r0-r12 might be clobbered by C functions
* so we use r13-r16 for storage here
* r0 = new stack-pointer
*/
mov %r13, %r0 /* save addr_sp */
mov %r14, %r1 /* save addr of gd */
mov %r15, %r2 /* save addr of destination */
mov %r16, %r2 /* %r9 - relocation offset */
sub %r16, %r16, __image_copy_start
/* Set up the stack */
stack_setup:
mov %sp, %r13
ENTRY(board_init_f_r_trampoline)
/* Set up the stack- and frame-pointers */
mov %sp, %r0
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 */
lr %r0, [ARC_AUX_INTR_VEC_BASE] /* Read current position */
add %r0, %r0, %r16 /* Update address */
sr %r0, [ARC_AUX_INTR_VEC_BASE] /* Write new position */
do_board_init_r:
/* Prepare for exection of "board_init_r" in relocated monitor */
mov %r2, board_init_r /* old address of "board_init_r()" */
add %r2, %r2, %r16 /* new address of "board_init_r()" */
mov %r0, %r14 /* 1-st parameter: gd_t */
mov %r1, %r15 /* 2-nd parameter: dest_addr */
j [%r2]
ENDPROC(relocate_code)
lr %r0, [ARC_AUX_INTR_VEC_BASE]
ld %r1, [%r25, GD_RELOC_OFF]
add %r0, %r0, %r1
sr %r0, [ARC_AUX_INTR_VEC_BASE]
/* Re-enter U-Boot by calling board_init_f_r */
j board_init_f_r
ENDPROC(board_init_f_r_trampoline)

@ -47,7 +47,7 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/sections.h>
#ifdef CONFIG_X86
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
#include <asm/init_helpers.h>
#include <asm/relocate.h>
#endif
@ -761,7 +761,7 @@ static int jump_to_copy(void)
* similarly for all archs. When we do generic relocation, hopefully
* 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
* 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
reloc_fdt,
setup_reloc,
#ifdef CONFIG_X86
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
copy_uboot_to_ram,
clear_bss,
do_elf_reloc_fixups,
@ -1041,7 +1041,7 @@ void board_init_f(ulong boot_flags)
#endif
}
#ifdef CONFIG_X86
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
/*
* For now this code is only used on x86.
*

Loading…
Cancel
Save