aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arc/Kconfig5
-rw-r--r--arch/arc/cpu/u-boot.lds19
-rw-r--r--arch/arc/dts/Makefile1
-rw-r--r--arch/arc/dts/emdk.dts33
-rw-r--r--arch/arc/lib/cache.c12
-rw-r--r--arch/arc/lib/relocate.c76
-rw-r--r--arch/arc/lib/reset.c14
-rw-r--r--board/synopsys/emdk/Kconfig12
-rw-r--r--board/synopsys/emdk/MAINTAINERS5
-rw-r--r--board/synopsys/emdk/Makefile7
-rw-r--r--board/synopsys/emdk/emdk.c92
-rw-r--r--configs/emdk_defconfig31
-rw-r--r--include/configs/emdk.h40
14 files changed, 308 insertions, 40 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0289d9d..f5ff57e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -60,6 +60,7 @@ S: Maintained
L: uboot-snps-arc@synopsys.com
T: git git://git.denx.de/u-boot-arc.git
F: arch/arc/
+F: board/synopsys/
ARC HSDK CGU CLOCK
M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index aee15d5..6f139d5 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 73c642e..e12145c 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 6eccec9..491a4f4 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 0000000..5e853e3
--- /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 6f52877..8c1cb6e 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 a3b7428..4ffba84 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 40fb0f1..02e08df 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;
}
diff --git a/board/synopsys/emdk/Kconfig b/board/synopsys/emdk/Kconfig
new file mode 100644
index 0000000..a9b834d
--- /dev/null
+++ b/board/synopsys/emdk/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_EMDK
+
+config SYS_BOARD
+ default "emdk"
+
+config SYS_VENDOR
+ default "synopsys"
+
+config SYS_CONFIG_NAME
+ default "emdk"
+
+endif
diff --git a/board/synopsys/emdk/MAINTAINERS b/board/synopsys/emdk/MAINTAINERS
new file mode 100644
index 0000000..605e338
--- /dev/null
+++ b/board/synopsys/emdk/MAINTAINERS
@@ -0,0 +1,5 @@
+EM DEVELOPMENT KIT BOARD
+M: Alexey Brodkin <abrodkin@synopsys.com>
+S: Maintained
+F: board/synopsys/emdk/
+F: configs/emdk_defconfig
diff --git a/board/synopsys/emdk/Makefile b/board/synopsys/emdk/Makefile
new file mode 100644
index 0000000..4926c4e
--- /dev/null
+++ b/board/synopsys/emdk/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += emdk.o
diff --git a/board/synopsys/emdk/emdk.c b/board/synopsys/emdk/emdk.c
new file mode 100644
index 0000000..bbb946a
--- /dev/null
+++ b/board/synopsys/emdk/emdk.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <dwmmc.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ARC_PERIPHERAL_BASE 0xF0000000
+#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0x10000)
+
+int board_mmc_init(bd_t *bis)
+{
+ struct dwmci_host *host = NULL;
+
+ host = malloc(sizeof(struct dwmci_host));
+ if (!host) {
+ printf("dwmci_host malloc fail!\n");
+ return 1;
+ }
+
+ memset(host, 0, sizeof(struct dwmci_host));
+ host->name = "Synopsys Mobile storage";
+ host->ioaddr = (void *)SDIO_BASE;
+ host->buswidth = 4;
+ host->dev_index = 0;
+ host->bus_hz = 50000000;
+
+ add_dwmci(host, host->bus_hz / 2, 400000);
+
+ return 0;
+}
+
+#define CREG_BASE 0xF0001000
+#define CREG_BOOT_OFFSET 0
+#define CREG_BOOT_WP_OFFSET 8
+
+#define CGU_BASE 0xF0000000
+#define CGU_IP_SW_RESET 0x0FF0
+
+void reset_cpu(ulong addr)
+{
+ writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET));
+ while (1)
+ ; /* loop forever till reset */
+}
+
+static int do_emdk_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+
+ if (!strcmp(argv[1], "unlock"))
+ creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET);
+ else if (!strcmp(argv[1], "lock"))
+ creg_boot |= BIT(CREG_BOOT_WP_OFFSET);
+ else
+ return CMD_RET_USAGE;
+
+ writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET));
+
+ return CMD_RET_SUCCESS;
+}
+
+cmd_tbl_t cmd_emdk[] = {
+ U_BOOT_CMD_MKENT(rom, 2, 0, do_emdk_rom, "", ""),
+};
+
+static int do_emdk(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ cmd_tbl_t *c;
+
+ c = find_cmd_tbl(argv[1], cmd_emdk, ARRAY_SIZE(cmd_emdk));
+
+ /* Strip off leading 'emdk' command */
+ argc--;
+ argv++;
+
+ if (c == NULL || argc > c->maxargs)
+ return CMD_RET_USAGE;
+
+ return c->cmd(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+ emdk, CONFIG_SYS_MAXARGS, 0, do_emdk,
+ "Synopsys EMDK specific commands",
+ "rom unlock - Unlock non-volatile memory for writing\n"
+ "emdk rom lock - Lock non-volatile memory to prevent writing\n"
+);
diff --git a/configs/emdk_defconfig b/configs/emdk_defconfig
new file mode 100644
index 0000000..e3bccd2
--- /dev/null
+++ b/configs/emdk_defconfig
@@ -0,0 +1,31 @@
+CONFIG_ARC=y
+CONFIG_ISA_ARCV2=y
+CONFIG_CPU_ARCEM6=y
+CONFIG_TARGET_EMDK=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_SYS_CLK_FREQ=40000000
+CONFIG_DEFAULT_DEVICE_TREE="emdk"
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_VERSION_VARIABLE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="emdk# "
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=4096
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_PANIC_HANG=y
diff --git a/include/configs/emdk.h b/include/configs/emdk.h
new file mode 100644
index 0000000..dca13e2
--- /dev/null
+++ b/include/configs/emdk.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#ifndef _CONFIG_EMDK_H_
+#define _CONFIG_EMDK_H_
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_SDRAM_BASE 0x10000000
+#define CONFIG_SYS_SDRAM_SIZE SZ_8M
+
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_1M)
+
+#define CONFIG_SYS_MALLOC_LEN SZ_64K
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE
+
+/* Required by DW MMC driver */
+#define CONFIG_BOUNCE_BUFFER
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_SIZE SZ_4K
+#define CONFIG_BOOTFILE "app.bin"
+#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "upgrade_image=u-boot.bin\0" \
+ "upgrade=emdk rom unlock && " \
+ "fatload mmc 0 ${loadaddr} ${upgrade_image} && " \
+ "cp.b ${loadaddr} 0 ${filesize} && " \
+ "dcache flush && " \
+ "emdk rom lock\0"
+
+#endif /* _CONFIG_EMDK_H_ */
+