Merge tag 'arc-updates-for-2018.07-rc1' of git://git.denx.de/u-boot-arc

Here we do a couple of minor fixes like:
 - Move .ivt section to the very beginning of the image
   by default which allows us to use that image put right
   at reset vector (usually 0x0)

 - Improve relocation fix-up which became required once
   we moved .ivt and understood a problem with existing implementation
   where we relied on a particular placement of sections.
   Now we don't care about placement because we just explicitly
   check for .text and in case of ARCompact .ivt sections

 - Re-implemnt do_reset() such that it calls reset_cpu() which
   could implmented for a particular board

And hte most important part we introduce support for yet another
devboard from Synopsys - EMDK.
This commit is contained in:
Tom Rini 2018-05-31 14:17:36 -04:00
commit c90c43cda8
14 changed files with 308 additions and 40 deletions

View File

@ -60,6 +60,7 @@ S: Maintained
L: uboot-snps-arc@synopsys.com L: uboot-snps-arc@synopsys.com
T: git git://git.denx.de/u-boot-arc.git T: git git://git.denx.de/u-boot-arc.git
F: arch/arc/ F: arch/arc/
F: board/synopsys/
ARC HSDK CGU CLOCK ARC HSDK CGU CLOCK
M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>

View File

@ -150,6 +150,10 @@ config TARGET_AXS101
config TARGET_AXS103 config TARGET_AXS103
bool "Support Synopsys Designware SDP board AXS103" bool "Support Synopsys Designware SDP board AXS103"
config TARGET_EMDK
bool "Synopsys EM Development kit"
select CPU_ARCEM6
config TARGET_HSDK config TARGET_HSDK
bool "Support Synpsys HS DevelopmentKit board" bool "Support Synpsys HS DevelopmentKit board"
@ -158,6 +162,7 @@ endchoice
source "board/abilis/tb100/Kconfig" source "board/abilis/tb100/Kconfig"
source "board/synopsys/Kconfig" source "board/synopsys/Kconfig"
source "board/synopsys/axs10x/Kconfig" source "board/synopsys/axs10x/Kconfig"
source "board/synopsys/emdk/Kconfig"
source "board/synopsys/hsdk/Kconfig" source "board/synopsys/hsdk/Kconfig"
endmenu endmenu

View File

@ -5,13 +5,22 @@
#include <config.h> #include <config.h>
OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc") OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc")
OUTPUT_ARCH(arc) OUTPUT_ARCH(arc)
ENTRY(_start) ENTRY(_start)
SECTIONS SECTIONS
{ {
. = CONFIG_SYS_TEXT_BASE; . = CONFIG_SYS_TEXT_BASE;
__image_copy_start = .; __image_copy_start = .;
. = ALIGN(1024);
__ivt_start = .;
.ivt :
{
KEEP(*(.ivt))
}
__ivt_end = .;
. = ALIGN(1024);
__text_start = .; __text_start = .;
.text : { .text : {
arch/arc/lib/start.o (.text*) arch/arc/lib/start.o (.text*)
@ -19,14 +28,6 @@ SECTIONS
} }
__text_end = .; __text_end = .;
. = ALIGN(1024);
__ivt_start = .;
.ivt :
{
*(.ivt)
}
__ivt_end = .;
. = ALIGN(4); . = ALIGN(4);
.rodata : { .rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))

View File

@ -4,6 +4,7 @@ dtb-$(CONFIG_TARGET_AXS101) += axs101.dtb
dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb
dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb
dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb
dtb-$(CONFIG_TARGET_EMDK) += emdk.dtb
dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb
targets += $(dtb-y) targets += $(dtb-y)

33
arch/arc/dts/emdk.dts Normal file
View File

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

View File

@ -432,9 +432,16 @@ void read_decode_cache_bcr(void)
int dc_line_sz = 0, ic_line_sz = 0; int dc_line_sz = 0, ic_line_sz = 0;
union bcr_di_cache ibcr, dbcr; 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); ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
if (ibcr.fields.ver) { 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) if (!ic_line_sz)
panic("Instruction exists but line length is 0\n"); panic("Instruction exists but line length is 0\n");
} }
@ -445,9 +452,6 @@ void read_decode_cache_bcr(void)
if (!dc_line_sz) if (!dc_line_sz)
panic("Data cache exists but line length is 0\n"); 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) void cache_init(void)

View File

@ -8,7 +8,9 @@
#include <asm-generic/sections.h> #include <asm-generic/sections.h>
extern ulong __image_copy_start; extern ulong __image_copy_start;
extern ulong __ivt_start;
extern ulong __ivt_end; extern ulong __ivt_end;
extern ulong __text_end;
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -48,7 +50,7 @@ int do_elf_reloc_fixups(void)
debug("Section .rela.dyn is located at %08x-%08x\n", debug("Section .rela.dyn is located at %08x-%08x\n",
(unsigned int)re_src, (unsigned int)re_end); (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; Elf32_Addr *offset_ptr_ram;
do { do {
@ -57,15 +59,28 @@ int do_elf_reloc_fixups(void)
/* Check that the location of the relocation is in .text */ /* Check that the location of the relocation is in .text */
if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start && if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start &&
offset_ptr_rom > last_offset) { offset_ptr_rom < (Elf32_Addr *)&__image_copy_end) {
unsigned int val; unsigned int val, do_swap = 0;
/* Switch to the in-RAM version */ /* Switch to the in-RAM version */
offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
gd->reloc_off); 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_rom,
(unsigned int)offset_ptr_ram); (unsigned int)offset_ptr_ram,
do_swap ? ", middle-endian encoded" : "");
/* /*
* Use "memcpy" because target location might be * Use "memcpy" because target location might be
@ -75,28 +90,45 @@ int do_elf_reloc_fixups(void)
*/ */
memcpy(&val, offset_ptr_ram, sizeof(int)); memcpy(&val, offset_ptr_ram, sizeof(int));
#ifdef __LITTLE_ENDIAN__ if (do_swap)
/* If location in ".text" section swap value */
if ((unsigned int)offset_ptr_rom <
(unsigned int)&__ivt_end)
val = (val << 16) | (val >> 16); val = (val << 16) | (val >> 16);
#endif
/* Check that the target points into executable */ /* Check that the target points into executable */
if (val >= (unsigned int)&__image_copy_start && val <= if (val < (unsigned int)&__image_copy_start ||
(unsigned int)&__image_copy_end) { val > (unsigned int)&__image_copy_end) {
val += gd->reloc_off; /* TODO: Use panic() instead of debug()
#ifdef __LITTLE_ENDIAN__ *
/* If location in ".text" section swap value */ * For some reason GCC might generate
if ((unsigned int)offset_ptr_rom < * fake relocation even for LD/SC of constant
(unsigned int)&__ivt_end) * inderectly. See an example below:
val = (val << 16) | (val >> 16); * ----------------------->8--------------------
#endif * static int setup_mon_len(void)
memcpy(offset_ptr_ram, &val, sizeof(int)); * {
* 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); } while (++re_src < re_end);
return 0; return 0;

View File

@ -6,13 +6,17 @@
#include <command.h> #include <command.h>
#include <common.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[]) 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; return 0;
} }

View File

@ -0,0 +1,12 @@
if TARGET_EMDK
config SYS_BOARD
default "emdk"
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "emdk"
endif

View File

@ -0,0 +1,5 @@
EM DEVELOPMENT KIT BOARD
M: Alexey Brodkin <abrodkin@synopsys.com>
S: Maintained
F: board/synopsys/emdk/
F: configs/emdk_defconfig

View File

@ -0,0 +1,7 @@
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += emdk.o

View File

@ -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"
);

31
configs/emdk_defconfig Normal file
View File

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

40
include/configs/emdk.h Normal file
View File

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