From 36d68668e33191d55b2a23c9f0ec0c1ffecd6897 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 24 Feb 2015 19:31:51 +0300 Subject: serial/serial_arc: set registers address during compilation Being global variable with 0 value it falls into .bss area which we may only use after relocation to RAM. And right afetr relocation we zero .bss - effectively cleaing register address set for early console. Now with pre-set value "regs" variable is no longer in .bss and this way safely survives relocation. Signed-off-by: Alexey Brodkin --- drivers/serial/serial_arc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c index 2ddbf32a50..0ee8ce5e7d 100644 --- a/drivers/serial/serial_arc.c +++ b/drivers/serial/serial_arc.c @@ -28,7 +28,7 @@ struct arc_serial_regs { #define UART_OVERFLOW_ERR (1 << 1) #define UART_TXEMPTY (1 << 7) -struct arc_serial_regs *regs; +struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE; static void arc_serial_setbrg(void) { @@ -60,7 +60,6 @@ static void arc_serial_setbrg(void) static int arc_serial_init(void) { - regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE; serial_setbrg(); return 0; } -- cgit v1.2.3 From ae4a351ad9e3b800e8eb55b27c302d8be256540e Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Fri, 27 Mar 2015 12:47:29 +0300 Subject: arc: cache - build invalidate_icache_all() and invalidate_dcache_all() always Make both invalidate_icache_all() and invalidate_dcache_all() available even if U-Boot is configured with CONFIG_SYS_DCACHE_OFF and/or CONFIG_SYS_ICACHE_OFF. This is useful because configuration of U-Boot may not match actual hardware features. Real board may have cache(s) but for some reason we may want to run U-Boot with cache(s) disabled (for example if some peripherals work improperly with existing drivers if data cache is enabled). So board may start with cache(s) enabled (that's the case for ARC cores with built-in caches) but early in U-Boot we disable cache(s) and make sure all contents of data cache gets flushed in RAM. Signed-off-by: Alexey Brodkin --- arch/arc/lib/cache.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index a2277231ba..30f045a864 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -49,10 +49,12 @@ void icache_disable(void) void invalidate_icache_all(void) { -#ifndef CONFIG_SYS_ICACHE_OFF + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + /* Any write to IC_IVIC register triggers invalidation of entire I$ */ write_aux_reg(ARC_AUX_IC_IVIC, 1); -#endif /* CONFIG_SYS_ICACHE_OFF */ } int dcache_status(void) @@ -156,10 +158,12 @@ void invalidate_dcache_range(unsigned long start, unsigned long end) void invalidate_dcache_all(void) { -#ifndef CONFIG_SYS_DCACHE_OFF + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + /* Write 1 to DC_IVDC register triggers invalidation of entire D$ */ write_aux_reg(ARC_AUX_DC_IVDC, 1); -#endif /* CONFIG_SYS_DCACHE_OFF */ } void flush_cache(unsigned long start, unsigned long size) -- cgit v1.2.3 From 4d93617d87285f01f450a30584520369ff3585d2 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 19 Feb 2015 18:40:58 +0300 Subject: arc: merge common start-up code between ARC and ARCv2 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 --- 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/lib/Makefile | 1 + arch/arc/lib/start.S | 241 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 298 insertions(+), 510 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/lib/start.S diff --git a/arch/arc/cpu/arcv1/Makefile b/arch/arc/cpu/arcv1/Makefile index 3704ebeeae..6d17ab2886 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 0000000000..7df47a2127 --- /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/arcv1/start.S b/arch/arc/cpu/arcv1/start.S deleted file mode 100644 index 01cfba4933..0000000000 --- a/arch/arc/cpu/arcv1/start.S +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -/* - * 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 - -.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: - /* 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/cpu/arcv2/Makefile b/arch/arc/cpu/arcv2/Makefile index cc69e5a17e..e338a0ae56 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 0000000000..d110b5bba5 --- /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 3ce689675f..0000000000 --- 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 -#include -#include - -/* - * 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 b8028c91e1..ad66ac21e6 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/lib/start.S b/arch/arc/lib/start.S new file mode 100644 index 0000000000..39eace36a9 --- /dev/null +++ b/arch/arc/lib/start.S @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* + * 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] + + /* 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 + 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) + * + * 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) -- cgit v1.2.3 From 8ee28251d95e237302c7c44929e59a813e147622 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 24 Feb 2015 17:08:44 +0300 Subject: arc: move low-level interrupt and exception handlers in a separate file 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 --- arch/arc/lib/Makefile | 1 + arch/arc/lib/ints_low.S | 151 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/start.S | 144 --------------------------------------------- 3 files changed, 152 insertions(+), 144 deletions(-) create mode 100644 arch/arc/lib/ints_low.S diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index ad66ac21e6..b1f1fbe4a1 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/ints_low.S b/arch/arc/lib/ints_low.S new file mode 100644 index 0000000000..161cf37dc4 --- /dev/null +++ b/arch/arc/lib/ints_low.S @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +/* + * 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(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) diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 39eace36a9..3408f45d2c 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -9,86 +9,6 @@ #include #include -/* - * 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) * -- cgit v1.2.3 From 3fb8016360d5433f3c4da51f8dd57550e7ef9018 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 24 Feb 2015 19:40:36 +0300 Subject: 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 Cc: Simon Glass --- 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 | 25 +++++++++++ arch/arc/lib/relocate.c | 19 +++++++++ arch/arc/lib/start.S | 82 ++++++++----------------------------- common/board_f.c | 8 ++-- 9 files changed, 98 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 0000000000..7607e19561 --- /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 0000000000..4c5f923416 --- /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 + +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 0c0e8e661d..a56ccf1b5d 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 b1f1fbe4a1..b88790492d 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 50634b860f..3c930bcbeb 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 0000000000..25690ee16e --- /dev/null +++ b/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 + +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; +} diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c index 7797782563..5c2c2d1930 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 3408f45d2c..82045aeb6d 100644 --- a/arch/arc/lib/start.S +++ b/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) diff --git a/common/board_f.c b/common/board_f.c index f7ffa54052..cb956b853c 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -47,7 +47,7 @@ #include #include #include -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) || defined(CONFIG_ARC) #include #include #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. * -- cgit v1.2.3 From 97ee47bdaba7421261d8568cd517f89275a42319 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 17 Mar 2015 14:30:59 +0300 Subject: arc: re-generate defconfigs Before that moment our defconfigs were manually modified with addition of new options. That means once anybody wants to add 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 --- 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 979f26e6dc..990c74a726 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 797595f2c3..fbc0ffe0a8 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 34ed9633a1..e5e1d8769a 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 c63dd4ab2e..7d662add41 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 b0e8c9f602..c964272d0d 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 -- cgit v1.2.3 From f56d625ee07a1ffb424e6c9278dd84b534e0bc1e Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 25 Feb 2015 18:10:18 +0300 Subject: arc: get rid of CONFIG_SYS_GENERIC_GLOBAL_DATA 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 --- arch/arc/include/asm/config.h | 1 - arch/arc/lib/start.S | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h index 8936f5cdf7..d2d791988e 100644 --- a/arch/arc/include/asm/config.h +++ b/arch/arc/include/asm/config.h @@ -7,7 +7,6 @@ #ifndef __ASM_ARC_CONFIG_H_ #define __ASM_ARC_CONFIG_H_ -#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 82045aeb6d..48ee86e54a 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -22,6 +22,14 @@ ENTRY(_start) bl dcache_disable bl icache_disable + /* Allocate and zero GD, update 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 j board_init_f -- cgit v1.2.3 From b903792e4492a710d6a58ccd136c9b3a2f684180 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 17 Mar 2015 14:26:43 +0300 Subject: arc: minor fixes in Kconfig [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 --- arch/arc/Kconfig | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 24f5c02c76..c044ad4de6 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" -- cgit v1.2.3 From 01496c4fac227221e67d93cb9cc14f48fb98a2b6 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 17 Mar 2015 14:55:14 +0300 Subject: serial-arc: switch to DM Now when all infrastructure in ARC is ready for it let's switch ARC UART to driver model. Signed-off-by: Alexey Brodkin Cc: Masahiro Yamada Cc: Simon Glass --- arch/Kconfig | 1 + arch/arc/dts/Makefile | 11 +++++ arch/arc/dts/arcangel4.dts | 24 ++++++++++ arch/arc/dts/skeleton.dtsi | 13 ++++++ configs/arcangel4-be_defconfig | 5 ++ configs/arcangel4_defconfig | 5 ++ drivers/serial/serial_arc.c | 102 ++++++++++++++++++++++++++++------------- 7 files changed, 129 insertions(+), 32 deletions(-) create mode 100644 arch/arc/dts/Makefile create mode 100644 arch/arc/dts/arcangel4.dts create mode 100644 arch/arc/dts/skeleton.dtsi diff --git a/arch/Kconfig b/arch/Kconfig index ca617e75ab..2ca530525e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -14,6 +14,7 @@ config ARC select HAVE_PRIVATE_LIBGCC select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL config ARM bool "ARM architecture" diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile new file mode 100644 index 0000000000..a155311f32 --- /dev/null +++ b/arch/arc/dts/Makefile @@ -0,0 +1,11 @@ +dtb-$(CONFIG_TARGET_ARCANGEL4) += arcangel4.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/arc/dts/arcangel4.dts b/arch/arc/dts/arcangel4.dts new file mode 100644 index 0000000000..bfcb9d8369 --- /dev/null +++ b/arch/arc/dts/arcangel4.dts @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &arcuart0; + }; + + arcuart0: serial@0xc0fc1000 { + compatible = "snps,arc-uart"; + reg = <0xc0fc1000 0x100>; + clock-frequency = <80000000>; + }; + +}; diff --git a/arch/arc/dts/skeleton.dtsi b/arch/arc/dts/skeleton.dtsi new file mode 100644 index 0000000000..b41d241de2 --- /dev/null +++ b/arch/arc/dts/skeleton.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig index 990c74a726..36ea6be09a 100644 --- a/configs/arcangel4-be_defconfig +++ b/configs/arcangel4-be_defconfig @@ -1,5 +1,10 @@ CONFIG_ARC=y CONFIG_CPU_BIG_ENDIAN=y CONFIG_TARGET_ARCANGEL4=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig index fbc0ffe0a8..75a91c850f 100644 --- a/configs/arcangel4_defconfig +++ b/configs/arcangel4_defconfig @@ -1,4 +1,9 @@ CONFIG_ARC=y CONFIG_TARGET_ARCANGEL4=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c index 0ee8ce5e7d..54e596c4ed 100644 --- a/drivers/serial/serial_arc.c +++ b/drivers/serial/serial_arc.c @@ -8,6 +8,7 @@ */ #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -23,21 +24,23 @@ struct arc_serial_regs { unsigned int baudh; }; + +struct arc_serial_platdata { + struct arc_serial_regs *reg; + unsigned int uartclk; +}; + /* Bit definitions of STATUS register */ #define UART_RXEMPTY (1 << 5) #define UART_OVERFLOW_ERR (1 << 1) #define UART_TXEMPTY (1 << 7) -struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE; - -static void arc_serial_setbrg(void) +static int arc_serial_setbrg(struct udevice *dev, int baudrate) { - int arc_console_baud; + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1; - if (!gd->baudrate) - gd->baudrate = CONFIG_BAUDRATE; - - arc_console_baud = gd->cpu_clk / (gd->baudrate * 4) - 1; writeb(arc_console_baud & 0xff, ®s->baudl); #ifdef CONFIG_ARC @@ -56,33 +59,49 @@ static void arc_serial_setbrg(void) #else writeb((arc_console_baud & 0xff00) >> 8, ®s->baudh); #endif -} -static int arc_serial_init(void) -{ - serial_setbrg(); return 0; } -static void arc_serial_putc(const char c) +static int arc_serial_putc(struct udevice *dev, const char c) { + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + if (c == '\n') - arc_serial_putc('\r'); + arc_serial_putc(dev, '\r'); while (!(readb(®s->status) & UART_TXEMPTY)) ; writeb(c, ®s->data); + + return 0; } -static int arc_serial_tstc(void) +static int arc_serial_tstc(struct arc_serial_regs *const regs) { return !(readb(®s->status) & UART_RXEMPTY); } -static int arc_serial_getc(void) +static int arc_serial_pending(struct udevice *dev, bool input) +{ + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + uint32_t status = readb(®s->status); + + if (input) + return status & UART_RXEMPTY ? 0 : 1; + else + return status & UART_TXEMPTY ? 0 : 1; +} + +static int arc_serial_getc(struct udevice *dev) { - while (!arc_serial_tstc()) + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + + while (!arc_serial_tstc(regs)) ; /* Check for overflow errors */ @@ -92,23 +111,42 @@ static int arc_serial_getc(void) return readb(®s->data) & 0xFF; } -static struct serial_device arc_serial_drv = { - .name = "arc_serial", - .start = arc_serial_init, - .stop = NULL, - .setbrg = arc_serial_setbrg, - .putc = arc_serial_putc, - .puts = default_serial_puts, - .getc = arc_serial_getc, - .tstc = arc_serial_tstc, -}; - -void arc_serial_initialize(void) +static int arc_serial_probe(struct udevice *dev) { - serial_register(&arc_serial_drv); + return 0; } -__weak struct serial_device *default_serial_console(void) +static const struct dm_serial_ops arc_serial_ops = { + .putc = arc_serial_putc, + .pending = arc_serial_pending, + .getc = arc_serial_getc, + .setbrg = arc_serial_setbrg, +}; + +static const struct udevice_id arc_serial_ids[] = { + { .compatible = "snps,arc-uart" }, + { } +}; + +static int arc_serial_ofdata_to_platdata(struct udevice *dev) { - return &arc_serial_drv; + struct arc_serial_platdata *plat = dev_get_platdata(dev); + DECLARE_GLOBAL_DATA_PTR; + + plat->reg = (struct arc_serial_regs *)fdtdec_get_addr(gd->fdt_blob, + dev->of_offset, "reg"); + plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", 0); + + return 0; } + +U_BOOT_DRIVER(serial_arc) = { + .name = "serial_arc", + .id = UCLASS_SERIAL, + .of_match = arc_serial_ids, + .ofdata_to_platdata = arc_serial_ofdata_to_platdata, + .probe = arc_serial_probe, + .ops = &arc_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit v1.2.3 From 09424d11192cffd4793b7bc922c5b47d4fe88a4d Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Fri, 27 Mar 2015 13:24:35 +0300 Subject: board: Switch Abilis TB-100 board to Driver Model for serial port Signed-off-by: Alexey Brodkin Cc: Masahiro Yamada Cc: Simon Glass --- arch/arc/dts/Makefile | 1 + arch/arc/dts/abilis_tb100.dts | 24 ++++++++++++++++++++++++ configs/tb100_defconfig | 5 +++++ include/configs/tb100.h | 6 +----- 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 arch/arc/dts/abilis_tb100.dts diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile index a155311f32..5bc6f44c1a 100644 --- a/arch/arc/dts/Makefile +++ b/arch/arc/dts/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_TARGET_ARCANGEL4) += arcangel4.dtb +dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb targets += $(dtb-y) diff --git a/arch/arc/dts/abilis_tb100.dts b/arch/arc/dts/abilis_tb100.dts new file mode 100644 index 0000000000..cf395c4011 --- /dev/null +++ b/arch/arc/dts/abilis_tb100.dts @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &uart0; + }; + + uart0: serial@ff100000 { + compatible = "snps,dw-apb-uart"; + reg = <0xff100000 0x1000>; + reg-shift = <2>; + reg-io-width = <4>; + }; +}; diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig index c964272d0d..59f09d9f64 100644 --- a/configs/tb100_defconfig +++ b/configs/tb100_defconfig @@ -1,5 +1,10 @@ CONFIG_ARC=y CONFIG_ARC_CACHE_LINE_SHIFT=5 CONFIG_TARGET_TB100=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="abilis_tb100" CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_SYS_CLK_FREQ=500000000 +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y diff --git a/include/configs/tb100.h b/include/configs/tb100.h index 46df40661d..501449a581 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -35,14 +35,10 @@ /* * UART configuration */ -#define CONFIG_CONS_INDEX 1 +#define CONFIG_DW_SERIAL #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE -4 #define CONFIG_SYS_NS16550_CLK 166666666 -#define CONFIG_SYS_NS16550_COM1 0xFF100000 -#define CONFIG_SYS_NS16550_MEM32 - #define CONFIG_BAUDRATE 115200 /* -- cgit v1.2.3 From 6eb15e50f48927c65a67371555b5afc24b3c7d21 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 30 Mar 2015 13:36:04 +0300 Subject: arc: add support for SLC (System Level Cache, AKA L2-cache) ARCv2 cores may have built-in SLC (System Level Cache, AKA L2-cache). This change adds functions required for controlling SLC: * slc_enable/disable * slc_flush/invalidate For now we just disable SLC to escape DMA coherency issues until either: * SLC flush/invalidate is supported in DMA APIin U-Boot * hardware DMA coherency is implemented (that might be board specific so probably we'll need to have a separate Kconfig option for controlling SLC explicitly) Signed-off-by: Alexey Brodkin --- arch/arc/include/asm/arcregs.h | 4 ++++ arch/arc/include/asm/cache.h | 11 ++++++++++ arch/arc/lib/cache.c | 46 ++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/start.S | 4 ++++ 4 files changed, 65 insertions(+) diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 6a36a81c0f..0e11dcced5 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -46,6 +46,10 @@ #define ARC_AUX_DC_PTAG 0x5C #endif #define ARC_BCR_DC_BUILD 0x72 +#define ARC_BCR_SLC 0xce +#define ARC_AUX_SLC_CONTROL 0x903 +#define ARC_AUX_SLC_FLUSH 0x904 +#define ARC_AUX_SLC_INVALIDATE 0x905 #ifndef __ASSEMBLY__ /* Accessors for auxiliary registers */ diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 8a77cd93af..0b3ebd9f58 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -27,4 +27,15 @@ #define CONFIG_ARC_MMU_VER 4 #endif +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ISA_ARCV2 +void slc_enable(void); +void slc_disable(void); +void slc_flush(void); +void slc_invalidate(void); +#endif + +#endif /* __ASSEMBLY__ */ + #endif /* __ASM_ARC_CACHE_H */ diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 30f045a864..e369e5a856 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -16,6 +16,7 @@ #define DC_CTRL_INV_MODE_FLUSH (1 << 6) #define DC_CTRL_FLUSH_STATUS (1 << 8) #define CACHE_VER_NUM_MASK 0xF +#define SLC_CTRL_SB (1 << 2) int icache_status(void) { @@ -170,3 +171,48 @@ void flush_cache(unsigned long start, unsigned long size) { flush_dcache_range(start, start + size); } + +#ifdef CONFIG_ISA_ARCV2 +void slc_enable(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_CONTROL, + read_aux_reg(ARC_AUX_SLC_CONTROL) & ~1); +} + +void slc_disable(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_CONTROL, + read_aux_reg(ARC_AUX_SLC_CONTROL) | 1); +} + +void slc_flush(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_FLUSH, 1); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_SLC_CONTROL) & SLC_CTRL_SB) + ; +} + +void slc_invalidate(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_INVALIDATE, 1); +} + +#endif /* CONFIG_ISA_ARCV2 */ diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 48ee86e54a..e1ef19cb88 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -18,6 +18,10 @@ ENTRY(_start) mov %fp, %sp /* Unconditionally disable caches */ +#ifdef CONFIG_ISA_ARCV2 + bl slc_flush + bl slc_disable +#endif bl flush_dcache_all bl dcache_disable bl icache_disable -- cgit v1.2.3 From d5717e894497124fd44289a37f818ee301640c70 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 2 Apr 2015 10:19:12 +0300 Subject: board: AXS10x - update SDIO clock value With the most recent board firmware correct SDIO clock is 50MHz as opposed to 25 MHz before. Also set max frequency of MMC data exchange equal to SDIO clock - because there's no way to transfer data faster than interface clock. Signed-off-by: Alexey Brodkin --- board/synopsys/axs101/axs101.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c index d1271ffcca..774204976e 100644 --- a/board/synopsys/axs101/axs101.c +++ b/board/synopsys/axs101/axs101.c @@ -27,9 +27,9 @@ int board_mmc_init(bd_t *bis) host->ioaddr = (void *)ARC_DWMMC_BASE; host->buswidth = 4; host->dev_index = 0; - host->bus_hz = 25000000; + host->bus_hz = 50000000; - add_dwmci(host, 52000000, 400000); + add_dwmci(host, host->bus_hz, 400000); return 0; } -- cgit v1.2.3