[U-Boot] [PATCH 0/6] ARC updates

This patchset is meant to prepare ARC for device model utilization. The most important things done:
[1] Separation of interrupt vectore tables from start.S [2] Merge of low-level start-up code (written in assembly) for ARCompat and ARCv2 architectures [3] Separation of interrupt and exception handling code in a separate source file (ints_low.S) [4] Major clean-up of start-up code and switch to heavy use of routines written in C (re-use implementations for x86 in board_f.c)
Alexey Brodkin (6): arc: merge common start-up code between ARC and ARCv2 arc: move low-level interrupt and exception handlers in a separate file arc: clean-up init procedure arc: get rid of CONFIG_SYS_GENERIC_GLOBAL_DATA arc: minor fixes in Kconfig arc: re-generate defconfigs
arch/arc/Kconfig | 10 +- arch/arc/cpu/arcv1/Makefile | 2 +- arch/arc/cpu/arcv1/ivt.S | 27 ++++ arch/arc/cpu/arcv1/start.S | 254 ------------------------------------ arch/arc/cpu/arcv2/Makefile | 2 +- arch/arc/cpu/arcv2/ivt.S | 27 ++++ arch/arc/cpu/arcv2/start.S | 254 ------------------------------------ arch/arc/include/asm/config.h | 1 - arch/arc/include/asm/init_helpers.h | 12 ++ arch/arc/include/asm/relocate.h | 16 +++ arch/arc/include/asm/u-boot-arc.h | 3 + arch/arc/lib/Makefile | 3 + arch/arc/lib/cpu.c | 13 -- arch/arc/lib/init_helpers.c | 27 ++++ arch/arc/lib/ints_low.S | 151 +++++++++++++++++++++ arch/arc/lib/relocate.c | 19 +++ arch/arc/lib/start.S | 51 ++++++++ common/board_f.c | 8 +- configs/arcangel4-be_defconfig | 4 +- configs/arcangel4_defconfig | 2 +- configs/axs101_defconfig | 6 +- configs/axs103_defconfig | 4 +- configs/tb100_defconfig | 4 +- 23 files changed, 361 insertions(+), 539 deletions(-) create mode 100644 arch/arc/cpu/arcv1/ivt.S delete mode 100644 arch/arc/cpu/arcv1/start.S create mode 100644 arch/arc/cpu/arcv2/ivt.S delete mode 100644 arch/arc/cpu/arcv2/start.S create mode 100644 arch/arc/include/asm/init_helpers.h create mode 100644 arch/arc/include/asm/relocate.h create mode 100644 arch/arc/lib/init_helpers.c create mode 100644 arch/arc/lib/ints_low.S create mode 100644 arch/arc/lib/start.S

Even though ARCompact and ARCv2 are not binary compatible most of assembly instructions are used in both. With this change we'll get rid of duplicate code.
Still IVTs are implemented differently so we're keeping them in separate files.
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com --- arch/arc/cpu/arcv1/Makefile | 2 +- arch/arc/cpu/arcv1/ivt.S | 27 ++++ arch/arc/cpu/arcv2/Makefile | 2 +- arch/arc/cpu/arcv2/ivt.S | 27 ++++ arch/arc/cpu/arcv2/start.S | 254 ------------------------------------ arch/arc/lib/Makefile | 1 + arch/arc/{cpu/arcv1 => lib}/start.S | 63 ++++----- 7 files changed, 82 insertions(+), 294 deletions(-) create mode 100644 arch/arc/cpu/arcv1/ivt.S create mode 100644 arch/arc/cpu/arcv2/ivt.S delete mode 100644 arch/arc/cpu/arcv2/start.S rename arch/arc/{cpu/arcv1 => lib}/start.S (82%)
diff --git a/arch/arc/cpu/arcv1/Makefile b/arch/arc/cpu/arcv1/Makefile index 3704ebe..6d17ab2 100644 --- a/arch/arc/cpu/arcv1/Makefile +++ b/arch/arc/cpu/arcv1/Makefile @@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += start.o +obj-y += ivt.o diff --git a/arch/arc/cpu/arcv1/ivt.S b/arch/arc/cpu/arcv1/ivt.S new file mode 100644 index 0000000..7df47a2 --- /dev/null +++ b/arch/arc/cpu/arcv1/ivt.S @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.section .ivt, "ax",@progbits +.align 4 +_ivt: + /* Critical system events */ + j _start /* 0 - 0x000 */ + j memory_error /* 1 - 0x008 */ + j instruction_error /* 2 - 0x010 */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr + /* Exceptions */ + j EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ + j EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ + j EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ + j EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ + j EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ + j EV_Trap /* 0x128, Trap exception (0x25) */ + j EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ diff --git a/arch/arc/cpu/arcv2/Makefile b/arch/arc/cpu/arcv2/Makefile index cc69e5a..e338a0a 100644 --- a/arch/arc/cpu/arcv2/Makefile +++ b/arch/arc/cpu/arcv2/Makefile @@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += start.o +obj-y += ivt.o diff --git a/arch/arc/cpu/arcv2/ivt.S b/arch/arc/cpu/arcv2/ivt.S new file mode 100644 index 0000000..d110b5b --- /dev/null +++ b/arch/arc/cpu/arcv2/ivt.S @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.section .ivt, "a",@progbits +.align 4 + /* Critical system events */ +.word _start /* 0 - 0x000 */ +.word memory_error /* 1 - 0x008 */ +.word instruction_error /* 2 - 0x010 */ + + /* Exceptions */ +.word EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ +.word EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ +.word EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ +.word EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ +.word EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ +.word EV_Trap /* 0x128, Trap exception (0x25) */ +.word EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr diff --git a/arch/arc/cpu/arcv2/start.S b/arch/arc/cpu/arcv2/start.S deleted file mode 100644 index 3ce6896..0000000 --- a/arch/arc/cpu/arcv2/start.S +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm-offsets.h> -#include <config.h> -#include <asm/arcregs.h> - -/* - * Note on the LD/ST addressing modes with address register write-back - * - * LD.a same as LD.aw - * - * LD.a reg1, [reg2, x] => Pre Incr - * Eff Addr for load = [reg2 + x] - * - * LD.ab reg1, [reg2, x] => Post Incr - * Eff Addr for load = [reg2] - */ - -.macro PUSH reg - st.a \reg, [%sp, -4] -.endm - -.macro PUSHAX aux - lr %r9, [\aux] - PUSH %r9 -.endm - -.macro SAVE_R1_TO_R24 - PUSH %r1 - PUSH %r2 - PUSH %r3 - PUSH %r4 - PUSH %r5 - PUSH %r6 - PUSH %r7 - PUSH %r8 - PUSH %r9 - PUSH %r10 - PUSH %r11 - PUSH %r12 - PUSH %r13 - PUSH %r14 - PUSH %r15 - PUSH %r16 - PUSH %r17 - PUSH %r18 - PUSH %r19 - PUSH %r20 - PUSH %r21 - PUSH %r22 - PUSH %r23 - PUSH %r24 -.endm - -.macro SAVE_ALL_SYS - /* saving %r0 to reg->r0 in advance since weread %ecr into it */ - st %r0, [%sp, -8] - lr %r0, [%ecr] /* all stack addressing is manual so far */ - st %r0, [%sp] - st %sp, [%sp, -4] - /* now move %sp to reg->r0 position so we can do "push" automatically */ - sub %sp, %sp, 8 - - SAVE_R1_TO_R24 - PUSH %r25 - PUSH %gp - PUSH %fp - PUSH %blink - PUSHAX %eret - PUSHAX %erstatus - PUSH %lp_count - PUSHAX %lp_end - PUSHAX %lp_start - PUSHAX %erbta -.endm - -.macro SAVE_EXCEPTION_SOURCE -#ifdef CONFIG_MMU - /* If MMU exists exception faulting address is loaded in EFA reg */ - lr %r0, [%efa] -#else - /* Otherwise in ERET (exception return) reg */ - lr %r0, [%eret] -#endif -.endm - -.section .ivt, "a",@progbits -.align 4 - /* Critical system events */ -.word _start /* 0 - 0x000 */ -.word memory_error /* 1 - 0x008 */ -.word instruction_error /* 2 - 0x010 */ - - /* Exceptions */ -.word EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ -.word EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ -.word EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ -.word EV_TLBProtV /* 0x118, Protection Violation (0x23) - or Misaligned Access */ -.word EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ -.word EV_Trap /* 0x128, Trap exception (0x25) */ -.word EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ - - /* Device interrupts */ -.rept 29 - j interrupt_handler /* 3:31 - 0x018:0xF8 */ -.endr - -.text -.globl _start -_start: - /* Setup interrupt vector base that matches "__text_start" */ - sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] - - /* Setup stack pointer */ - 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 - - /* Zero the one and only argument of "board_init_f" */ - mov_s %r0, 0 - j board_init_f - -memory_error: - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_memory_error - -instruction_error: - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_instruction_error - -interrupt_handler: - /* Todo - save and restore CPU context when interrupts will be in use */ - bl do_interrupt_handler - rtie - -EV_MachineCheck: - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_machine_check_fault - -EV_TLBMissI: - SAVE_ALL_SYS - mov %r0, %sp - j do_itlb_miss - -EV_TLBMissD: - SAVE_ALL_SYS - mov %r0, %sp - j do_dtlb_miss - -EV_TLBProtV: - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_tlb_prot_violation - -EV_PrivilegeV: - SAVE_ALL_SYS - mov %r0, %sp - j do_privilege_violation - -EV_Trap: - SAVE_ALL_SYS - mov %r0, %sp - j do_trap - -EV_Extension: - SAVE_ALL_SYS - mov %r0, %sp - j do_extension - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * r0 = start_addr_sp - * r1 = new__gd - * r2 = relocaddr - */ -.align 4 -.globl relocate_code -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 - 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] diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index b8028c9..ad66ac2 100644 --- a/arch/arc/lib/Makefile +++ b/arch/arc/lib/Makefile @@ -18,6 +18,7 @@ obj-y += memcpy-700.o obj-y += memset.o obj-y += reset.o obj-y += timer.o +obj-y += start.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
diff --git a/arch/arc/cpu/arcv1/start.S b/arch/arc/lib/start.S similarity index 82% rename from arch/arc/cpu/arcv1/start.S rename to arch/arc/lib/start.S index 01cfba4..39eace3 100644 --- a/arch/arc/cpu/arcv1/start.S +++ b/arch/arc/lib/start.S @@ -6,6 +6,7 @@
#include <asm-offsets.h> #include <config.h> +#include <linux/linkage.h> #include <asm/arcregs.h>
/* @@ -88,31 +89,7 @@ #endif .endm
-.section .ivt, "ax",@progbits -.align 4 -_ivt: - /* Critical system events */ - j _start /* 0 - 0x000 */ - j memory_error /* 1 - 0x008 */ - j instruction_error /* 2 - 0x010 */ - - /* Device interrupts */ -.rept 29 - j interrupt_handler /* 3:31 - 0x018:0xF8 */ -.endr - /* Exceptions */ - j EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ - j EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ - j EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ - j EV_TLBProtV /* 0x118, Protection Violation (0x23) - or Misaligned Access */ - j EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ - j EV_Trap /* 0x128, Trap exception (0x25) */ - j EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ - -.text -.globl _start -_start: +ENTRY(_start) /* Setup interrupt vector base that matches "__text_start" */ sr __ivt_start, [ARC_AUX_INTR_VEC_BASE]
@@ -131,60 +108,71 @@ clear_bss: /* Zero the one and only argument of "board_init_f" */ mov_s %r0, 0 j board_init_f +ENDPROC(_start)
-memory_error: +ENTRY(memory_error) SAVE_ALL_SYS SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_memory_error +ENDPROC(memory_error)
-instruction_error: +ENTRY(instruction_error) SAVE_ALL_SYS SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_instruction_error +ENDPROC(instruction_error)
-interrupt_handler: +ENTRY(interrupt_handler) /* Todo - save and restore CPU context when interrupts will be in use */ bl do_interrupt_handler rtie +ENDPROC(interrupt_handler)
-EV_MachineCheck: +ENTRY(EV_MachineCheck) SAVE_ALL_SYS SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_machine_check_fault +ENDPROC(EV_MachineCheck)
-EV_TLBMissI: +ENTRY(EV_TLBMissI) SAVE_ALL_SYS mov %r0, %sp j do_itlb_miss +ENDPROC(EV_TLBMissI)
-EV_TLBMissD: +ENTRY(EV_TLBMissD) SAVE_ALL_SYS mov %r0, %sp j do_dtlb_miss +ENDPROC(EV_TLBMissD)
-EV_TLBProtV: +ENTRY(EV_TLBProtV) SAVE_ALL_SYS SAVE_EXCEPTION_SOURCE mov %r1, %sp j do_tlb_prot_violation +ENDPROC(EV_TLBProtV)
-EV_PrivilegeV: +ENTRY(EV_PrivilegeV) SAVE_ALL_SYS mov %r0, %sp j do_privilege_violation +ENDPROC(EV_PrivilegeV)
-EV_Trap: +ENTRY(EV_Trap) SAVE_ALL_SYS mov %r0, %sp j do_trap +ENDPROC(EV_Trap)
-EV_Extension: +ENTRY(EV_Extension) SAVE_ALL_SYS mov %r0, %sp j do_extension +ENDPROC(EV_Extension)
/* * void relocate_code (addr_sp, gd, addr_moni) @@ -196,9 +184,7 @@ EV_Extension: * r1 = new__gd * r2 = relocaddr */ -.align 4 -.globl relocate_code -relocate_code: +ENTRY(relocate_code) /* * r0-r12 might be clobbered by C functions * so we use r13-r16 for storage here @@ -252,3 +238,4 @@ do_board_init_r: mov %r0, %r14 /* 1-st parameter: gd_t */ mov %r1, %r15 /* 2-nd parameter: dest_addr */ j [%r2] +ENDPROC(relocate_code)

This separation makes maintenance of code easier because those low-level interrupt- or exception handling routines are pretty static and usually require not much care while start-up code is a subject of modifications and enhancements.
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com --- arch/arc/lib/Makefile | 1 + arch/arc/lib/{start.S => ints_low.S} | 92 +--------------------- arch/arc/lib/start.S | 144 ----------------------------------- 3 files changed, 2 insertions(+), 235 deletions(-) copy arch/arc/lib/{start.S => ints_low.S} (50%)
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index ad66ac2..b1f1fbe 100644 --- a/arch/arc/lib/Makefile +++ b/arch/arc/lib/Makefile @@ -19,6 +19,7 @@ obj-y += memset.o obj-y += reset.o obj-y += timer.o obj-y += start.o +obj-y += ints_low.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/ints_low.S similarity index 50% copy from arch/arc/lib/start.S copy to arch/arc/lib/ints_low.S index 39eace3..161cf37 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/ints_low.S @@ -1,13 +1,10 @@ /* - * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. * * SPDX-License-Identifier: GPL-2.0+ */
-#include <asm-offsets.h> -#include <config.h> #include <linux/linkage.h> -#include <asm/arcregs.h>
/* * Note on the LD/ST addressing modes with address register write-back @@ -89,27 +86,6 @@ #endif .endm
-ENTRY(_start) - /* Setup interrupt vector base that matches "__text_start" */ - sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] - - /* Setup stack pointer */ - 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 - - /* Zero the one and only argument of "board_init_f" */ - mov_s %r0, 0 - j board_init_f -ENDPROC(_start) - ENTRY(memory_error) SAVE_ALL_SYS SAVE_EXCEPTION_SOURCE @@ -173,69 +149,3 @@ ENTRY(EV_Extension) mov %r0, %sp j do_extension ENDPROC(EV_Extension) - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * 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 - */ - 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 - 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) diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 39eace3..3408f45 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -9,86 +9,6 @@ #include <linux/linkage.h> #include <asm/arcregs.h>
-/* - * Note on the LD/ST addressing modes with address register write-back - * - * LD.a same as LD.aw - * - * LD.a reg1, [reg2, x] => Pre Incr - * Eff Addr for load = [reg2 + x] - * - * LD.ab reg1, [reg2, x] => Post Incr - * Eff Addr for load = [reg2] - */ - -.macro PUSH reg - st.a \reg, [%sp, -4] -.endm - -.macro PUSHAX aux - lr %r9, [\aux] - PUSH %r9 -.endm - -.macro SAVE_R1_TO_R24 - PUSH %r1 - PUSH %r2 - PUSH %r3 - PUSH %r4 - PUSH %r5 - PUSH %r6 - PUSH %r7 - PUSH %r8 - PUSH %r9 - PUSH %r10 - PUSH %r11 - PUSH %r12 - PUSH %r13 - PUSH %r14 - PUSH %r15 - PUSH %r16 - PUSH %r17 - PUSH %r18 - PUSH %r19 - PUSH %r20 - PUSH %r21 - PUSH %r22 - PUSH %r23 - PUSH %r24 -.endm - -.macro SAVE_ALL_SYS - /* saving %r0 to reg->r0 in advance since we read %ecr into it */ - st %r0, [%sp, -8] - lr %r0, [%ecr] /* all stack addressing is manual so far */ - st %r0, [%sp] - st %sp, [%sp, -4] - /* now move %sp to reg->r0 position so we can do "push" automatically */ - sub %sp, %sp, 8 - - SAVE_R1_TO_R24 - PUSH %r25 - PUSH %gp - PUSH %fp - PUSH %blink - PUSHAX %eret - PUSHAX %erstatus - PUSH %lp_count - PUSHAX %lp_end - PUSHAX %lp_start - PUSHAX %erbta -.endm - -.macro SAVE_EXCEPTION_SOURCE -#ifdef CONFIG_MMU - /* If MMU exists exception faulting address is loaded in EFA reg */ - lr %r0, [%efa] -#else - /* Otherwise in ERET (exception return) reg */ - lr %r0, [%eret] -#endif -.endm - ENTRY(_start) /* Setup interrupt vector base that matches "__text_start" */ sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] @@ -110,70 +30,6 @@ clear_bss: j board_init_f ENDPROC(_start)
-ENTRY(memory_error) - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_memory_error -ENDPROC(memory_error) - -ENTRY(instruction_error) - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_instruction_error -ENDPROC(instruction_error) - -ENTRY(interrupt_handler) - /* Todo - save and restore CPU context when interrupts will be in use */ - bl do_interrupt_handler - rtie -ENDPROC(interrupt_handler) - -ENTRY(EV_MachineCheck) - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_machine_check_fault -ENDPROC(EV_MachineCheck) - -ENTRY(EV_TLBMissI) - SAVE_ALL_SYS - mov %r0, %sp - j do_itlb_miss -ENDPROC(EV_TLBMissI) - -ENTRY(EV_TLBMissD) - SAVE_ALL_SYS - mov %r0, %sp - j do_dtlb_miss -ENDPROC(EV_TLBMissD) - -ENTRY(EV_TLBProtV) - SAVE_ALL_SYS - SAVE_EXCEPTION_SOURCE - mov %r1, %sp - j do_tlb_prot_violation -ENDPROC(EV_TLBProtV) - -ENTRY(EV_PrivilegeV) - SAVE_ALL_SYS - mov %r0, %sp - j do_privilege_violation -ENDPROC(EV_PrivilegeV) - -ENTRY(EV_Trap) - SAVE_ALL_SYS - mov %r0, %sp - j do_trap -ENDPROC(EV_Trap) - -ENTRY(EV_Extension) - SAVE_ALL_SYS - mov %r0, %sp - j do_extension -ENDPROC(EV_Extension) - /* * void relocate_code (addr_sp, gd, addr_moni) *

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 --- arch/arc/include/asm/init_helpers.h | 12 ++++++ arch/arc/include/asm/relocate.h | 16 ++++++++ arch/arc/include/asm/u-boot-arc.h | 3 ++ arch/arc/lib/Makefile | 1 + arch/arc/lib/cpu.c | 13 ------- arch/arc/lib/init_helpers.c | 27 +++++++++++++ arch/arc/lib/relocate.c | 19 +++++++++ arch/arc/lib/start.S | 77 +++++++------------------------------ common/board_f.c | 8 ++-- 9 files changed, 95 insertions(+), 81 deletions(-) create mode 100644 arch/arc/include/asm/init_helpers.h create mode 100644 arch/arc/include/asm/relocate.h create mode 100644 arch/arc/lib/init_helpers.c
diff --git a/arch/arc/include/asm/init_helpers.h b/arch/arc/include/asm/init_helpers.h new file mode 100644 index 0000000..7607e19 --- /dev/null +++ b/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 */ diff --git a/arch/arc/include/asm/relocate.h b/arch/arc/include/asm/relocate.h new file mode 100644 index 0000000..4c5f923 --- /dev/null +++ b/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 */ diff --git a/arch/arc/include/asm/u-boot-arc.h b/arch/arc/include/asm/u-boot-arc.h index 0c0e8e6..a56ccf1 100644 --- a/arch/arc/include/asm/u-boot-arc.h +++ b/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__ */ diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index b1f1fbe..b887904 100644 --- a/arch/arc/lib/Makefile +++ b/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
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c index 50634b8..3c930bc 100644 --- a/arch/arc/lib/cpu.c +++ b/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" */ diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c new file mode 100644 index 0000000..ef9fac2 --- /dev/null +++ b/arch/arc/lib/init_helpers.c @@ -0,0 +1,27 @@ +/* + * 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) +{ +#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 + return 0; +} diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c index 7797782..5c2c2d1 100644 --- a/arch/arc/lib/relocate.c +++ b/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 */ diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 3408f45..a9aa2b5 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -17,81 +17,30 @@ ENTRY(_start) 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 - /* Zero the one and only argument of "board_init_f" */ mov_s %r0, 0 j board_init_f 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) diff --git a/common/board_f.c b/common/board_f.c index f55550c..bb4c32e 100644 --- a/common/board_f.c +++ b/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 @@ -760,7 +760,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 @@ -996,7 +996,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, @@ -1040,7 +1040,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. *

As discussed on mailing list we're drifting away from CONFIG_SYS_GENERIC_GLOBAL_DATA in favour to use of board_init_f_mem() for global data.
So do this for ARC architecture.
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com --- arch/arc/include/asm/config.h | 1 - arch/arc/lib/start.S | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h index b4e9099..450adda 100644 --- a/arch/arc/include/asm/config.h +++ b/arch/arc/include/asm/config.h @@ -8,7 +8,6 @@ #define __ASM_ARC_CONFIG_H_
#define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_SYS_GENERIC_GLOBAL_DATA #define CONFIG_SYS_BOOT_RAMDISK_HIGH #define CONFIG_ARCH_EARLY_INIT_R
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index a9aa2b5..8fcd896 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -13,9 +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 + mov %r0, %sp + bl board_init_f_mem + /* Update stack- and frame-pointers */ + mov %sp, %r0 + mov %fp, %sp
/* Zero the one and only argument of "board_init_f" */ mov_s %r0, 0

[1] Fix misspeling in ARC_CACHE_LINE_SHIFT dependency, now cache-line lenth selection is correctly enabled if either I$ or D$ are enabled.
[2] Add dummy entry to target list to make sure target type is always mentioned in defconfig. Otherwise defconfig for the first target in the list will not have target name and later on with addition of the new target on top of the list in Kconfig will lead to corrupted configuration expanded from defconfig.
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com --- arch/arc/Kconfig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 24f5c02..c044ad4 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -123,7 +123,7 @@ config ARC_CACHE_LINE_SHIFT int "Cache Line Length (as power of 2)" range 5 7 default "6" - depends on !SYS_DCACHE_OFF || !SYS_DCACHE_OFF + depends on !SYS_DCACHE_OFF || !SYS_ICACHE_OFF help Starting with ARC700 4.9, Cache line length is configurable, This option specifies "N", with Line-len = 2 power N @@ -133,6 +133,14 @@ config ARC_CACHE_LINE_SHIFT choice prompt "Target select"
+config TARGET_DUMMY + bool "Dummy target" + help + Please select one of real target boards below! + This target is only meant to force "makedefconfig" to put + TARGET_xxx in defconfig even this is the first target from the list + below. + config TARGET_TB100 bool "Support tb100"

Before that moment our defconfigs were manually modified with addition of new options. That means once anybody wants to addd another option and re-genarate defconfig with "make defconfig" there will be lots of differences. So to make future modifications more clean we'll do bulk re-generation right away.
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com --- configs/arcangel4-be_defconfig | 4 ++-- configs/arcangel4_defconfig | 2 +- configs/axs101_defconfig | 6 +++--- configs/axs103_defconfig | 4 ++-- configs/tb100_defconfig | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig index 979f26e..990c74a 100644 --- a/configs/arcangel4-be_defconfig +++ b/configs/arcangel4-be_defconfig @@ -1,5 +1,5 @@ CONFIG_ARC=y -CONFIG_TARGET_ARCANGEL4=y -CONFIG_SYS_CLK_FREQ=70000000 CONFIG_CPU_BIG_ENDIAN=y +CONFIG_TARGET_ARCANGEL4=y CONFIG_SYS_TEXT_BASE=0x81000000 +CONFIG_SYS_CLK_FREQ=70000000 diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig index 797595f..fbc0ffe 100644 --- a/configs/arcangel4_defconfig +++ b/configs/arcangel4_defconfig @@ -1,4 +1,4 @@ CONFIG_ARC=y CONFIG_TARGET_ARCANGEL4=y -CONFIG_SYS_CLK_FREQ=70000000 CONFIG_SYS_TEXT_BASE=0x81000000 +CONFIG_SYS_CLK_FREQ=70000000 diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index 34ed963..e5e1d87 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -1,6 +1,6 @@ CONFIG_ARC=y +CONFIG_SYS_DCACHE_OFF=y +CONFIG_ARC_CACHE_LINE_SHIFT=5 CONFIG_TARGET_AXS101=y +CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=750000000 -CONFIG_ARC_CACHE_LINE_SHIFT=5 -CONFIG_SYS_DCACHE_OFF=y -CONFIG_SYS_TEXT_BASE=0x81000000 \ No newline at end of file diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig index c63dd4a..7d662ad 100644 --- a/configs/axs103_defconfig +++ b/configs/axs103_defconfig @@ -1,5 +1,5 @@ -CONFIG_SYS_TEXT_BASE=0x81000000 -CONFIG_SYS_CLK_FREQ=50000000 CONFIG_ARC=y CONFIG_ISA_ARCV2=y CONFIG_TARGET_AXS101=y +CONFIG_SYS_TEXT_BASE=0x81000000 +CONFIG_SYS_CLK_FREQ=50000000 diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig index b0e8c9f..c964272 100644 --- a/configs/tb100_defconfig +++ b/configs/tb100_defconfig @@ -1,5 +1,5 @@ CONFIG_ARC=y -CONFIG_TARGET_TB100=y -CONFIG_SYS_CLK_FREQ=500000000 CONFIG_ARC_CACHE_LINE_SHIFT=5 +CONFIG_TARGET_TB100=y CONFIG_SYS_TEXT_BASE=0x84000000 +CONFIG_SYS_CLK_FREQ=500000000

Hi Alexey,
2015-03-17 21:13 GMT+09:00 Alexey Brodkin Alexey.Brodkin@synopsys.com:
Before that moment our defconfigs were manually modified with addition of new options. That means once anybody wants to addd another option and
I just noticed a typo. s/addd/add/
You need not to submit v2 for such a minor error. Please fix it when you apply this patch, if you remember.

Hello Masahiro-san,
On Sun, 2015-03-29 at 19:47 +0900, Masahiro Yamada wrote:
Hi Alexey,
2015-03-17 21:13 GMT+09:00 Alexey Brodkin Alexey.Brodkin@synopsys.com:
Before that moment our defconfigs were manually modified with addition of new options. That means once anybody wants to addd another option and
I just noticed a typo. s/addd/add/
You need not to submit v2 for such a minor error. Please fix it when you apply this patch, if you remember.
Thanks for catching this typo.
I was going to send v2 respin of entire series due to important fixes I've done recently and mentioned typo will be addressed there as well.
-Alexey
participants (2)
-
Alexey Brodkin
-
Masahiro Yamada