Browse Source

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>
Alexey Brodkin 9 years ago
parent
commit
3fb8016360

+ 12 - 0
arch/arc/include/asm/init_helpers.h

@@ -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 */

+ 16 - 0
arch/arc/include/asm/relocate.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 */

+ 3 - 0
arch/arc/include/asm/u-boot-arc.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__ */

+ 1 - 0
arch/arc/lib/Makefile

@@ -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
 

+ 0 - 13
arch/arc/lib/cpu.c

@@ -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" */

+ 25 - 0
arch/arc/lib/init_helpers.c

@@ -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;
+}

+ 19 - 0
arch/arc/lib/relocate.c

@@ -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
  */

+ 18 - 64
arch/arc/lib/start.S

@@ -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
+ * r0 = new stack-pointer
  */
-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 */
-	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 */
+	/* Update position of intterupt vector table */
+	lr	%r0, [ARC_AUX_INTR_VEC_BASE]
+	ld	%r1, [%r25, GD_RELOC_OFF]
+	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 */
-	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)
+	/* Re-enter U-Boot by calling board_init_f_r */
+	j	board_init_f_r
+ENDPROC(board_init_f_r_trampoline)

+ 4 - 4
common/board_f.c

@@ -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.
  *