diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/Kconfig | 5 | ||||
-rw-r--r-- | arch/arc/cpu/u-boot.lds | 19 | ||||
-rw-r--r-- | arch/arc/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arc/dts/emdk.dts | 33 | ||||
-rw-r--r-- | arch/arc/lib/cache.c | 12 | ||||
-rw-r--r-- | arch/arc/lib/relocate.c | 76 | ||||
-rw-r--r-- | arch/arc/lib/reset.c | 14 |
7 files changed, 120 insertions, 40 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index aee15d5353..6f139d5bdc 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -150,6 +150,10 @@ config TARGET_AXS101 config TARGET_AXS103 bool "Support Synopsys Designware SDP board AXS103" +config TARGET_EMDK + bool "Synopsys EM Development kit" + select CPU_ARCEM6 + config TARGET_HSDK bool "Support Synpsys HS DevelopmentKit board" @@ -158,6 +162,7 @@ endchoice source "board/abilis/tb100/Kconfig" source "board/synopsys/Kconfig" source "board/synopsys/axs10x/Kconfig" +source "board/synopsys/emdk/Kconfig" source "board/synopsys/hsdk/Kconfig" endmenu diff --git a/arch/arc/cpu/u-boot.lds b/arch/arc/cpu/u-boot.lds index 73c642ed6b..e12145c768 100644 --- a/arch/arc/cpu/u-boot.lds +++ b/arch/arc/cpu/u-boot.lds @@ -5,28 +5,29 @@ #include <config.h> -OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc") +OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") OUTPUT_ARCH(arc) ENTRY(_start) SECTIONS { . = CONFIG_SYS_TEXT_BASE; __image_copy_start = .; - __text_start = .; - .text : { - arch/arc/lib/start.o (.text*) - *(.text*) - } - __text_end = .; - . = ALIGN(1024); __ivt_start = .; .ivt : { - *(.ivt) + KEEP(*(.ivt)) } __ivt_end = .; + . = ALIGN(1024); + __text_start = .; + .text : { + arch/arc/lib/start.o (.text*) + *(.text*) + } + __text_end = .; + . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile index 6eccec97da..491a4f40bb 100644 --- a/arch/arc/dts/Makefile +++ b/arch/arc/dts/Makefile @@ -4,6 +4,7 @@ dtb-$(CONFIG_TARGET_AXS101) += axs101.dtb dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb +dtb-$(CONFIG_TARGET_EMDK) += emdk.dtb dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb targets += $(dtb-y) diff --git a/arch/arc/dts/emdk.dts b/arch/arc/dts/emdk.dts new file mode 100644 index 0000000000..5e853e3a72 --- /dev/null +++ b/arch/arc/dts/emdk.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Synopsys, Inc. All rights reserved. + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &uart0; + }; + + cpu_card { + core_clk: core_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <40000000>; + u-boot,dm-pre-reloc; + }; + }; + + uart0: serial0@f0004000 { + compatible = "snps,dw-apb-uart"; + clock-frequency = <100000000>; + reg = <0xf0004000 0x1000>; + reg-shift = <2>; + reg-io-width = <4>; + }; +}; diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 6f52877643..8c1cb6e800 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -432,9 +432,16 @@ void read_decode_cache_bcr(void) int dc_line_sz = 0, ic_line_sz = 0; union bcr_di_cache ibcr, dbcr; + /* + * We don't care much about I$ line length really as there're + * no per-line ops on I$ instead we only do full invalidation of it + * on occasion of relocation and right before jumping to the OS. + * Still we check insane config with zero-encoded line length in + * presense of version field in I$ BCR. Just in case. + */ ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD); if (ibcr.fields.ver) { - gd->arch.l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len; + ic_line_sz = 8 << ibcr.fields.line_len; if (!ic_line_sz) panic("Instruction exists but line length is 0\n"); } @@ -445,9 +452,6 @@ void read_decode_cache_bcr(void) if (!dc_line_sz) panic("Data cache exists but line length is 0\n"); } - - if (ic_line_sz && dc_line_sz && (ic_line_sz != dc_line_sz)) - panic("Instruction and data cache line lengths differ\n"); } void cache_init(void) diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c index a3b7428d85..4ffba84eeb 100644 --- a/arch/arc/lib/relocate.c +++ b/arch/arc/lib/relocate.c @@ -8,7 +8,9 @@ #include <asm-generic/sections.h> extern ulong __image_copy_start; +extern ulong __ivt_start; extern ulong __ivt_end; +extern ulong __text_end; DECLARE_GLOBAL_DATA_PTR; @@ -48,7 +50,7 @@ int do_elf_reloc_fixups(void) debug("Section .rela.dyn is located at %08x-%08x\n", (unsigned int)re_src, (unsigned int)re_end); - Elf32_Addr *offset_ptr_rom, *last_offset = NULL; + Elf32_Addr *offset_ptr_rom; Elf32_Addr *offset_ptr_ram; do { @@ -57,15 +59,28 @@ int do_elf_reloc_fixups(void) /* Check that the location of the relocation is in .text */ if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start && - offset_ptr_rom > last_offset) { - unsigned int val; + offset_ptr_rom < (Elf32_Addr *)&__image_copy_end) { + unsigned int val, do_swap = 0; /* Switch to the in-RAM version */ offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + gd->reloc_off); - debug("Patching value @ %08x (relocated to %08x)\n", +#ifdef __LITTLE_ENDIAN__ + /* If location in ".text" section swap value */ + if (((u32)offset_ptr_rom >= (u32)&__text_start && + (u32)offset_ptr_rom <= (u32)&__text_end) +#if defined(__ARC700__) || defined(__ARC600__) + || ((u32)offset_ptr_rom >= (u32)&__ivt_start && + (u32)offset_ptr_rom <= (u32)&__ivt_end) +#endif + ) + do_swap = 1; +#endif + + debug("Patching value @ %08x (relocated to %08x)%s\n", (unsigned int)offset_ptr_rom, - (unsigned int)offset_ptr_ram); + (unsigned int)offset_ptr_ram, + do_swap ? ", middle-endian encoded" : ""); /* * Use "memcpy" because target location might be @@ -75,28 +90,45 @@ int do_elf_reloc_fixups(void) */ memcpy(&val, offset_ptr_ram, sizeof(int)); -#ifdef __LITTLE_ENDIAN__ - /* If location in ".text" section swap value */ - if ((unsigned int)offset_ptr_rom < - (unsigned int)&__ivt_end) + if (do_swap) val = (val << 16) | (val >> 16); -#endif /* Check that the target points into executable */ - if (val >= (unsigned int)&__image_copy_start && val <= - (unsigned int)&__image_copy_end) { - val += gd->reloc_off; -#ifdef __LITTLE_ENDIAN__ - /* If location in ".text" section swap value */ - if ((unsigned int)offset_ptr_rom < - (unsigned int)&__ivt_end) - val = (val << 16) | (val >> 16); -#endif - memcpy(offset_ptr_ram, &val, sizeof(int)); + if (val < (unsigned int)&__image_copy_start || + val > (unsigned int)&__image_copy_end) { + /* TODO: Use panic() instead of debug() + * + * For some reason GCC might generate + * fake relocation even for LD/SC of constant + * inderectly. See an example below: + * ----------------------->8-------------------- + * static int setup_mon_len(void) + * { + * gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE; + * return 0; + * } + * ----------------------->8-------------------- + * + * And that's what we get in the binary: + * ----------------------->8-------------------- + * 10005cb4 <setup_mon_len>: + * 10005cb4: 193c 3f80 0003 2f80 st 0x32f80,[r25,60] + * 10005cb8: R_ARC_RELATIVE *ABS*-0x10000000 + * 10005cbc: 7fe0 j_s.d [blink] + * 10005cbe: 700c mov_s r0,0 + * ----------------------->8-------------------- + */ + debug("Relocation target %08x points outside of image\n", + val); } - } - last_offset = offset_ptr_rom; + val += gd->reloc_off; + + if (do_swap) + val = (val << 16) | (val >> 16); + + memcpy(offset_ptr_ram, &val, sizeof(int)); + } } while (++re_src < re_end); return 0; diff --git a/arch/arc/lib/reset.c b/arch/arc/lib/reset.c index 40fb0f1fbd..02e08df48d 100644 --- a/arch/arc/lib/reset.c +++ b/arch/arc/lib/reset.c @@ -6,13 +6,17 @@ #include <command.h> #include <common.h> +__weak void reset_cpu(ulong addr) +{ + /* Stop debug session here */ + __builtin_arc_brk(); +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - printf("Put your restart handler here\n"); + printf("Resetting the board...\n"); + + reset_cpu(0); -#ifdef DEBUG - /* Stop debug session here */ - __asm__("brk"); -#endif return 0; } |