[U-Boot] [PATCH v3 0/9] Add support for the ARC700 architecture

This patch series adds support for the Synopsys DesignWare ARC700 architecture.
DesignWare ARC700 is family of 32-bit CPUs developed by Synopsys, Inc.
Since version 3.9 ARC architecture is supported in mainline Linux developemnt. And now to get better support in commonly used boot-loader we are introducing port of U-Boot for ARC700 CPUs.
Patches included in this series are also available on GitHub in the 'for-upstream-v3' branch:
git@github.com:foss-for-synopsys-dwc-arc-processors/u-boot.git
Also browsable here:
https://github.com/foss-for-synopsys-dwc-arc-processors/u-boot/tree/for-upst...
NOTE: there's an acked by Tom Rini prerequisite for Arcangel4 board:
http://patchwork.ozlabs.org/patch/300901/
For those who are interested in building this port please download pre-built toolchains for x86_64 hosts.
For RedHat-based distros: https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases/d...
For Debian-based distros: https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases/d...
Major changes for v3:
* Clean-up of headers copied from Linux kernel and other architectures. * Fix checkpatch.pl errors and most of warnings (except really required "typedefs" in "posix_types.h" and "volatile" in data accessors implemented with assembly instuctions). * Arcangel4 board now has big-endian modificatoin so both endianesses could be used for testing and debugging. * Common board init functionality moved from boards to cpu sources.
Each patch that follows has detailed description of its changes.
Alexey Brodkin (9): arc: add architecture header files arc: add cpu files arc: add library functions arc: bdinfo, image and arc-specific init functions declarations support arc: add support for standalone programs arc: add Arcangel4 board support arc: add AXS101 board support arc: add architecture to MAKEALL arc: add README for architecture
MAKEALL | 6 + arch/arc/config.mk | 31 ++++ arch/arc/cpu/arc700/Makefile | 13 ++ arch/arc/cpu/arc700/cache.c | 138 ++++++++++++++++ arch/arc/cpu/arc700/config.mk | 7 + arch/arc/cpu/arc700/cpu.c | 47 ++++++ arch/arc/cpu/arc700/interrupts.c | 142 ++++++++++++++++ arch/arc/cpu/arc700/reset.c | 19 +++ arch/arc/cpu/arc700/start.S | 241 ++++++++++++++++++++++++++++ arch/arc/cpu/arc700/timer.c | 24 +++ arch/arc/cpu/arc700/u-boot.lds | 72 +++++++++ arch/arc/include/asm/arch-arc700/hardware.h | 10 ++ arch/arc/include/asm/arcregs.h | 55 +++++++ arch/arc/include/asm/bitops.h | 19 +++ arch/arc/include/asm/byteorder.h | 23 +++ arch/arc/include/asm/cache.h | 23 +++ arch/arc/include/asm/config.h | 12 ++ arch/arc/include/asm/errno.h | 1 + arch/arc/include/asm/global_data.h | 19 +++ arch/arc/include/asm/io.h | 218 +++++++++++++++++++++++++ arch/arc/include/asm/posix_types.h | 39 +++++ arch/arc/include/asm/ptrace.h | 50 ++++++ arch/arc/include/asm/sections.h | 14 ++ arch/arc/include/asm/string.h | 27 ++++ arch/arc/include/asm/types.h | 55 +++++++ arch/arc/include/asm/u-boot-arc.h | 12 ++ arch/arc/include/asm/u-boot.h | 15 ++ arch/arc/include/asm/unaligned.h | 1 + arch/arc/lib/Makefile | 16 ++ arch/arc/lib/bootm.c | 106 ++++++++++++ arch/arc/lib/memcmp.S | 121 ++++++++++++++ arch/arc/lib/memcpy-700.S | 63 ++++++++ arch/arc/lib/memset.S | 62 +++++++ arch/arc/lib/relocate.c | 72 +++++++++ arch/arc/lib/sections.c | 21 +++ arch/arc/lib/strchr-700.S | 141 ++++++++++++++++ arch/arc/lib/strcmp.S | 97 +++++++++++ arch/arc/lib/strcpy-700.S | 67 ++++++++ arch/arc/lib/strlen.S | 80 +++++++++ board/synopsys/arcangel4/Makefile | 11 ++ board/synopsys/axs101/Makefile | 8 + board/synopsys/axs101/axs101.c | 44 +++++ board/synopsys/axs101/nand.c | 226 ++++++++++++++++++++++++++ boards.cfg | 3 + common/cmd_bdinfo.c | 18 +++ common/image.c | 1 + doc/README.ARC | 27 ++++ examples/standalone/stubs.c | 13 ++ include/common.h | 3 + include/configs/arcangel4-be.h | 96 +++++++++++ include/configs/arcangel4.h | 95 +++++++++++ include/configs/axs101.h | 186 +++++++++++++++++++++ include/image.h | 1 + 53 files changed, 2911 insertions(+) create mode 100644 arch/arc/config.mk create mode 100644 arch/arc/cpu/arc700/Makefile create mode 100644 arch/arc/cpu/arc700/cache.c create mode 100644 arch/arc/cpu/arc700/config.mk create mode 100644 arch/arc/cpu/arc700/cpu.c create mode 100644 arch/arc/cpu/arc700/interrupts.c create mode 100644 arch/arc/cpu/arc700/reset.c create mode 100644 arch/arc/cpu/arc700/start.S create mode 100644 arch/arc/cpu/arc700/timer.c create mode 100644 arch/arc/cpu/arc700/u-boot.lds create mode 100644 arch/arc/include/asm/arch-arc700/hardware.h create mode 100644 arch/arc/include/asm/arcregs.h create mode 100644 arch/arc/include/asm/bitops.h create mode 100644 arch/arc/include/asm/byteorder.h create mode 100644 arch/arc/include/asm/cache.h create mode 100644 arch/arc/include/asm/config.h create mode 100644 arch/arc/include/asm/errno.h create mode 100644 arch/arc/include/asm/global_data.h create mode 100644 arch/arc/include/asm/io.h create mode 100644 arch/arc/include/asm/posix_types.h create mode 100644 arch/arc/include/asm/ptrace.h create mode 100644 arch/arc/include/asm/sections.h create mode 100644 arch/arc/include/asm/string.h create mode 100644 arch/arc/include/asm/types.h create mode 100644 arch/arc/include/asm/u-boot-arc.h create mode 100644 arch/arc/include/asm/u-boot.h create mode 100644 arch/arc/include/asm/unaligned.h create mode 100644 arch/arc/lib/Makefile create mode 100644 arch/arc/lib/bootm.c create mode 100644 arch/arc/lib/memcmp.S create mode 100644 arch/arc/lib/memcpy-700.S create mode 100644 arch/arc/lib/memset.S create mode 100644 arch/arc/lib/relocate.c create mode 100644 arch/arc/lib/sections.c create mode 100644 arch/arc/lib/strchr-700.S create mode 100644 arch/arc/lib/strcmp.S create mode 100644 arch/arc/lib/strcpy-700.S create mode 100644 arch/arc/lib/strlen.S create mode 100644 board/synopsys/arcangel4/Makefile create mode 100644 board/synopsys/axs101/Makefile create mode 100644 board/synopsys/axs101/axs101.c create mode 100644 board/synopsys/axs101/nand.c create mode 100644 doc/README.ARC create mode 100644 include/configs/arcangel4-be.h create mode 100644 include/configs/arcangel4.h create mode 100644 include/configs/axs101.h
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de

These are header files used by ARC700 architecture.
Also note that "arch-arc700/hardware.h" is only required for compilation of "designware_i2c" driver which refers to "asm/arch/hardware.h". It would be good to fix mentioned driver sometime soon but it will cause changes in ARM board configs that use "designware_i2c".
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Clean-up of headers copied form Linux kernel and other architectures. * Removed BCR registers as non-needed in u-Boot. * Removal of legacy chech for __KERNEL__ definition. * Added "u-boot-arc.h" with ARC-specific init functions. * Added comment on existence of "hardware.h". * Move all AUX regs into one header. * Use "__raw_{read|write}" accessors from Linux.
arch/arc/include/asm/arch-arc700/hardware.h | 10 ++ arch/arc/include/asm/arcregs.h | 55 +++++++ arch/arc/include/asm/bitops.h | 19 +++ arch/arc/include/asm/byteorder.h | 23 +++ arch/arc/include/asm/cache.h | 23 +++ arch/arc/include/asm/config.h | 12 ++ arch/arc/include/asm/errno.h | 1 + arch/arc/include/asm/global_data.h | 19 +++ arch/arc/include/asm/io.h | 218 ++++++++++++++++++++++++++++ arch/arc/include/asm/posix_types.h | 39 +++++ arch/arc/include/asm/ptrace.h | 50 +++++++ arch/arc/include/asm/sections.h | 14 ++ arch/arc/include/asm/string.h | 27 ++++ arch/arc/include/asm/types.h | 55 +++++++ arch/arc/include/asm/u-boot-arc.h | 12 ++ arch/arc/include/asm/u-boot.h | 15 ++ arch/arc/include/asm/unaligned.h | 1 + 17 files changed, 593 insertions(+) create mode 100644 arch/arc/include/asm/arch-arc700/hardware.h create mode 100644 arch/arc/include/asm/arcregs.h create mode 100644 arch/arc/include/asm/bitops.h create mode 100644 arch/arc/include/asm/byteorder.h create mode 100644 arch/arc/include/asm/cache.h create mode 100644 arch/arc/include/asm/config.h create mode 100644 arch/arc/include/asm/errno.h create mode 100644 arch/arc/include/asm/global_data.h create mode 100644 arch/arc/include/asm/io.h create mode 100644 arch/arc/include/asm/posix_types.h create mode 100644 arch/arc/include/asm/ptrace.h create mode 100644 arch/arc/include/asm/sections.h create mode 100644 arch/arc/include/asm/string.h create mode 100644 arch/arc/include/asm/types.h create mode 100644 arch/arc/include/asm/u-boot-arc.h create mode 100644 arch/arc/include/asm/u-boot.h create mode 100644 arch/arc/include/asm/unaligned.h
diff --git a/arch/arc/include/asm/arch-arc700/hardware.h b/arch/arc/include/asm/arch-arc700/hardware.h new file mode 100644 index 0000000..8ec13a8 --- /dev/null +++ b/arch/arc/include/asm/arch-arc700/hardware.h @@ -0,0 +1,10 @@ +/* + * Copyright (C) 2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This file is only required to allow compilation of "designware_i2c" driver. + * Which explicitly includes <asm/arch/hardware.h>. + */ diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..5d48d11 --- /dev/null +++ b/arch/arc/include/asm/arcregs.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARC_ARCREGS_H +#define _ASM_ARC_ARCREGS_H + +/* + * ARC architecture has additional address space - auxiliary registers. + * These registers are mostly used for configuration purposes. + * These registers are not memory mapped and special commands are used for + * access: "lr"/"sr". + */ + +#define ARC_AUX_IDENTITY 0x04 +#define ARC_AUX_STATUS32 0x0a + +/* Instruction cache related auxiliary registers */ +#define ARC_AUX_IC_IVIC 0x10 +#define ARC_AUX_IC_CTRL 0x11 +#define ARC_AUX_IC_IVIL 0x19 +#if (CONFIG_ARC_MMU_VER > 2) +#define ARC_AUX_IC_PTAG 0x1E +#endif + +/* Timer related auxiliary registers */ +#define ARC_AUX_TIMER0_CNT 0x21 /* Timer 0 count */ +#define ARC_AUX_TIMER0_CTRL 0x22 /* Timer 0 control */ +#define ARC_AUX_TIMER0_LIMIT 0x23 /* Timer 0 limit */ + +#define ARC_AUX_INTR_VEC_BASE 0x25 + +/* Data cache related auxiliary registers */ +#define ARC_AUX_DC_IVDC 0x47 +#define ARC_AUX_DC_CTRL 0x48 + +#define ARC_AUX_DC_IVDL 0x4A +#define ARC_AUX_DC_FLSH 0x4B +#define ARC_AUX_DC_FLDL 0x4C +#if (CONFIG_ARC_MMU_VER > 2) +#define ARC_AUX_DC_PTAG 0x5C +#endif + +#ifndef __ASSEMBLY__ +/* Accessors for auxiliary registers */ +#define read_aux_reg(reg) __builtin_arc_lr(reg) + +/* gcc builtin sr needs reg param to be long immediate */ +#define write_aux_reg(reg_immed, val) \ + __builtin_arc_sr((unsigned int)val, reg_immed) +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARC_ARCREGS_H */ diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h new file mode 100644 index 0000000..85721aa --- /dev/null +++ b/arch/arc/include/asm/bitops.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_BITOPS_H +#define __ASM_ARC_BITOPS_H + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __ASM_ARC_BITOPS_H */ diff --git a/arch/arc/include/asm/byteorder.h b/arch/arc/include/asm/byteorder.h new file mode 100644 index 0000000..2fa9776 --- /dev/null +++ b/arch/arc/include/asm/byteorder.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_BYTEORDER_H +#define __ASM_ARC_BYTEORDER_H + +#include <asm/types.h> + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + #define __BYTEORDER_HAS_U64__ + #define __SWAB_64_THRU_32__ +#endif + +#ifdef __LITTLE_ENDIAN__ + #include <linux/byteorder/little_endian.h> +#else + #include <linux/byteorder/big_endian.h> +#endif /* CONFIG_SYS_BIG_ENDIAN */ + +#endif /* ASM_ARC_BYTEORDER_H */ diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h new file mode 100644 index 0000000..16e7568 --- /dev/null +++ b/arch/arc/include/asm/cache.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_CACHE_H +#define __ASM_ARC_CACHE_H + +#include <config.h> + +/* + * The current upper bound for ARC L1 data cache line sizes is 128 bytes. + * We use that value for aligning DMA buffers unless the board config has + * specified an alternate cache line size. + */ +#ifdef CONFIG_SYS_CACHELINE_SIZE +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#else +#define ARCH_DMA_MINALIGN 128 +#endif + +#endif /* __ASM_ARC_CACHE_H */ diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h new file mode 100644 index 0000000..5761def --- /dev/null +++ b/arch/arc/include/asm/config.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_CONFIG_H_ +#define __ASM_ARC_CONFIG_H_ + +#define CONFIG_LMB + +#endif /*__ASM_ARC_CONFIG_H_ */ diff --git a/arch/arc/include/asm/errno.h b/arch/arc/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/arc/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/arc/include/asm/global_data.h b/arch/arc/include/asm/global_data.h new file mode 100644 index 0000000..d644e80 --- /dev/null +++ b/arch/arc/include/asm/global_data.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_GLOBAL_DATA_H +#define __ASM_ARC_GLOBAL_DATA_H + +/* Architecture-specific global data */ +struct arch_global_data { + int running_on_hw; +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r25") + +#endif /* __ASM_ARC_GLOBAL_DATA_H */ diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h new file mode 100644 index 0000000..24b7337 --- /dev/null +++ b/arch/arc/include/asm/io.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_IO_H +#define __ASM_ARC_IO_H + +#include <linux/types.h> +#include <asm/byteorder.h> + +static inline void sync(void) +{ + /* Not yet implemented */ +} + +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + u8 b; + + __asm__ __volatile__("ldb%U1 %0, %1\n" + : "=r" (b) + : "m" (*(volatile u8 __force *)addr) + : "memory"); + return b; +} + +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ + u16 s; + + __asm__ __volatile__("ldw%U1 %0, %1\n" + : "=r" (s) + : "m" (*(volatile u16 __force *)addr) + : "memory"); + return s; +} + +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + u32 w; + + __asm__ __volatile__("ld%U1 %0, %1\n" + : "=r" (w) + : "m" (*(volatile u32 __force *)addr) + : "memory"); + return w; +} + +#define readb __raw_readb + +static inline u16 readw(const volatile void __iomem *addr) +{ + return __le16_to_cpu(__raw_readw(addr)); +} + +static inline u32 readl(const volatile void __iomem *addr) +{ + return __le32_to_cpu(__raw_readl(addr)); +} + +static inline void __raw_writeb(u8 b, volatile void __iomem *addr) +{ + __asm__ __volatile__("stb%U1 %0, %1\n" + : + : "r" (b), "m" (*(volatile u8 __force *)addr) + : "memory"); +} + +static inline void __raw_writew(u16 s, volatile void __iomem *addr) +{ + __asm__ __volatile__("stw%U1 %0, %1\n" + : + : "r" (s), "m" (*(volatile u16 __force *)addr) + : "memory"); +} + +static inline void __raw_writel(u32 w, volatile void __iomem *addr) +{ + __asm__ __volatile__("st%U1 %0, %1\n" + : + : "r" (w), "m" (*(volatile u32 __force *)addr) + : "memory"); +} + +#define writeb __raw_writeb +#define writew(b, addr) __raw_writew(__cpu_to_le16(b), addr) +#define writel(b, addr) __raw_writel(__cpu_to_le32(b), addr) + +static inline int __raw_readsb(unsigned int addr, void *data, int bytelen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "stb.ab r8, [r1, 1]\n" + : + : "r" (addr), "r" (data), "r" (bytelen) + : "r8"); + return bytelen; +} + +static inline int __raw_readsw(unsigned int addr, void *data, int wordlen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "stw.ab r8, [r1, 2]\n" + : + : "r" (addr), "r" (data), "r" (wordlen) + : "r8"); + return wordlen; +} + +static inline int __raw_readsl(unsigned int addr, void *data, int longlen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab r8, [r1, 4]\n" + : + : "r" (addr), "r" (data), "r" (longlen) + : "r8"); + return longlen; +} + +static inline int __raw_writesb(unsigned int addr, void *data, int bytelen) +{ + __asm__ __volatile__ ("1:ldb.ab r8, [r1, 1]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (bytelen) + : "r8"); + return bytelen; +} + +static inline int __raw_writesw(unsigned int addr, void *data, int wordlen) +{ + __asm__ __volatile__ ("1:ldw.ab r8, [r1, 2]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (wordlen) + : "r8"); + return wordlen; +} + +static inline int __raw_writesl(unsigned int addr, void *data, int longlen) +{ + __asm__ __volatile__ ("1:ld.ab r8, [r1, 4]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (longlen) + : "r8"); + return longlen; +} + +#define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a) +#define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a, v) out_arch(l, le32, a, v) +#define out_le16(a, v) out_arch(w, le16, a, v) + +#define in_le32(a) in_arch(l, le32, a) +#define in_le16(a) in_arch(w, le16, a) + +#define out_be32(a, v) out_arch(l, be32, a, v) +#define out_be16(a, v) out_arch(w, be16, a, v) + +#define in_be32(a) in_arch(l, be32, a) +#define in_be16(a) in_arch(w, be16, a) + +#define out_8(a, v) __raw_writeb(v, a) +#define in_8(a) __raw_readb(a) + +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + +#endif /* __ASM_ARC_IO_H */ diff --git a/arch/arc/include/asm/posix_types.h b/arch/arc/include/asm/posix_types.h new file mode 100644 index 0000000..20415f0 --- /dev/null +++ b/arch/arc/include/asm/posix_types.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_POSIX_TYPES_H +#define __ASM_ARC_POSIX_TYPES_H + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..8f73b31 --- /dev/null +++ b/arch/arc/include/asm/ptrace.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_PTRACE_H +#define __ASM_ARC_PTRACE_H + +struct pt_regs { + long bta; + long lp_start; + long lp_end; + long lp_count; + long status32; + long ret; + long blink; + long fp; + long r26; /* gp */ + long r25; + long r24; + long r23; + long r22; + long r21; + long r20; + long r19; + long r18; + long r17; + long r16; + long r15; + long r14; + long r13; + long r12; + long r11; + long r10; + long r9; + long r8; + long r7; + long r6; + long r5; + long r4; + long r3; + long r2; + long r1; + long r0; + long sp; + long ecr; +}; + +#endif /* __ASM_ARC_PTRACE_H */ diff --git a/arch/arc/include/asm/sections.h b/arch/arc/include/asm/sections.h new file mode 100644 index 0000000..18484a1 --- /dev/null +++ b/arch/arc/include/asm/sections.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_SECTIONS_H +#define __ASM_ARC_SECTIONS_H + +#include <asm-generic/sections.h> + +extern ulong __text_end; + +#endif /* __ASM_ARC_SECTIONS_H */ diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h new file mode 100644 index 0000000..909129c --- /dev/null +++ b/arch/arc/include/asm/string.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_STRING_H +#define __ASM_ARC_STRING_H + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_STRCHR +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRLEN + +extern void *memset(void *ptr, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void memzero(void *ptr, __kernel_size_t n); +extern int memcmp(const void *, const void *, __kernel_size_t); +extern char *strchr(const char *s, int c); +extern char *strcpy(char *dest, const char *src); +extern int strcmp(const char *cs, const char *ct); +extern __kernel_size_t strlen(const char *); + +#endif /* __ASM_ARC_STRING_H */ diff --git a/arch/arc/include/asm/types.h b/arch/arc/include/asm/types.h new file mode 100644 index 0000000..24eeb76 --- /dev/null +++ b/arch/arc/include/asm/types.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_TYPES_H +#define __ASM_ARC_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +typedef unsigned long phys_addr_t; +typedef unsigned long phys_size_t; + +#endif /* __ASM_ARC_TYPES_H */ diff --git a/arch/arc/include/asm/u-boot-arc.h b/arch/arc/include/asm/u-boot-arc.h new file mode 100644 index 0000000..0c0e8e6 --- /dev/null +++ b/arch/arc/include/asm/u-boot-arc.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_U_BOOT_ARC_H__ +#define __ASM_ARC_U_BOOT_ARC_H__ + +int arch_early_init_r(void); + +#endif /* __ASM_ARC_U_BOOT_ARC_H__ */ diff --git a/arch/arc/include/asm/u-boot.h b/arch/arc/include/asm/u-boot.h new file mode 100644 index 0000000..e354edf --- /dev/null +++ b/arch/arc/include/asm/u-boot.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_U_BOOT_H__ +#define __ASM_ARC_U_BOOT_H__ + +#include <asm-generic/u-boot.h> + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_ARC + +#endif /* __ASM_ARC_U_BOOT_H__ */ diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h new file mode 100644 index 0000000..6cecbbb --- /dev/null +++ b/arch/arc/include/asm/unaligned.h @@ -0,0 +1 @@ +#include <asm-generic/unaligned.h>

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Fixed checkpatch.pl errors. * All AUX regs were moved into one header. * Removed BCR (Build configuration Register) checks as not needed in u-Boot. * Clean-up of context saving/otput in exceptions.
arch/arc/config.mk | 31 +++++ arch/arc/cpu/arc700/Makefile | 13 +++ arch/arc/cpu/arc700/cache.c | 138 ++++++++++++++++++++++ arch/arc/cpu/arc700/config.mk | 7 ++ arch/arc/cpu/arc700/cpu.c | 47 ++++++++ arch/arc/cpu/arc700/interrupts.c | 142 +++++++++++++++++++++++ arch/arc/cpu/arc700/reset.c | 19 +++ arch/arc/cpu/arc700/start.S | 241 +++++++++++++++++++++++++++++++++++++++ arch/arc/cpu/arc700/timer.c | 24 ++++ arch/arc/cpu/arc700/u-boot.lds | 72 ++++++++++++ 10 files changed, 734 insertions(+) create mode 100644 arch/arc/config.mk create mode 100644 arch/arc/cpu/arc700/Makefile create mode 100644 arch/arc/cpu/arc700/cache.c create mode 100644 arch/arc/cpu/arc700/config.mk create mode 100644 arch/arc/cpu/arc700/cpu.c create mode 100644 arch/arc/cpu/arc700/interrupts.c create mode 100644 arch/arc/cpu/arc700/reset.c create mode 100644 arch/arc/cpu/arc700/start.S create mode 100644 arch/arc/cpu/arc700/timer.c create mode 100644 arch/arc/cpu/arc700/u-boot.lds
diff --git a/arch/arc/config.mk b/arch/arc/config.mk new file mode 100644 index 0000000..76f4f7c --- /dev/null +++ b/arch/arc/config.mk @@ -0,0 +1,31 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifndef CONFIG_SYS_BIG_ENDIAN +CONFIG_SYS_LITTLE_ENDIAN = 1 +endif + +ifdef CONFIG_SYS_LITTLE_ENDIAN +CROSS_COMPILE ?= arc-buildroot-linux-uclibc- +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +CROSS_COMPILE ?= arceb-buildroot-linux-uclibc- +PLATFORM_LDFLAGS += -EB +endif + +PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -DCONFIG_ARC -gdwarf-2 + +LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds + +# Needed for relocation +LDFLAGS_FINAL += -pie + +# Load address for standalone apps +CONFIG_STANDALONE_LOAD_ADDR ?= 0x82000000 + +# Support generic board on ARC +__HAVE_ARCH_GENERIC_BOARD := y diff --git a/arch/arc/cpu/arc700/Makefile b/arch/arc/cpu/arc700/Makefile new file mode 100644 index 0000000..cdc5002 --- /dev/null +++ b/arch/arc/cpu/arc700/Makefile @@ -0,0 +1,13 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y += start.o + +obj-y += cache.o +obj-y += cpu.o +obj-y += interrupts.o +obj-y += reset.o +obj-y += timer.o diff --git a/arch/arc/cpu/arc700/cache.c b/arch/arc/cpu/arc700/cache.c new file mode 100644 index 0000000..39d522d --- /dev/null +++ b/arch/arc/cpu/arc700/cache.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arcregs.h> + +/* Bit values in IC_CTRL */ +#define IC_CTRL_CACHE_DISABLE (1 << 0) + +/* Bit values in DC_CTRL */ +#define DC_CTRL_CACHE_DISABLE (1 << 0) +#define DC_CTRL_INV_MODE_FLUSH (1 << 6) +#define DC_CTRL_FLUSH_STATUS (1 << 8) + +int icache_status(void) +{ + return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) != + IC_CTRL_CACHE_DISABLE; +} + +void icache_enable(void) +{ + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & + ~IC_CTRL_CACHE_DISABLE); +} + +void icache_disable(void) +{ + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | + IC_CTRL_CACHE_DISABLE); +} + +void invalidate_icache_all(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + /* 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) +{ + return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) != + DC_CTRL_CACHE_DISABLE; +} + +void dcache_enable(void) +{ + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & + ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE)); +} + +void dcache_disable(void) +{ + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) | + DC_CTRL_CACHE_DISABLE); +} + +void flush_dcache_all(void) +{ + /* Do flush of entire cache */ + write_aux_reg(ARC_AUX_DC_FLSH, 1); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) + ; +} + +#ifndef CONFIG_SYS_DCACHE_OFF +static void dcache_flush_line(unsigned addr) +{ +#if (CONFIG_ARC_MMU_VER > 2) + write_aux_reg(ARC_AUX_DC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_DC_FLDL, addr); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) + ; + +#ifndef CONFIG_SYS_ICACHE_OFF + /* + * Invalidate I$ for addresses range just flushed from D$. + * If we try to execute data flushed above it will be valid/correct + */ +#if (CONFIG_ARC_MMU_VER > 2) + write_aux_reg(ARC_AUX_IC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_IC_IVIL, addr); +#endif /* CONFIG_SYS_ICACHE_OFF */ +} +#endif /* CONFIG_SYS_DCACHE_OFF */ + +void flush_dcache_range(unsigned long start, unsigned long end) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned int addr; + + start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) + dcache_flush_line(addr); +#endif /* CONFIG_SYS_DCACHE_OFF */ +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned int addr; + + start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { +#if (CONFIG_ARC_MMU_VER > 2) + write_aux_reg(ARC_AUX_DC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_DC_IVDL, addr); + } +#endif /* CONFIG_SYS_DCACHE_OFF */ +} + +void invalidate_dcache_all(void) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + /* 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) +{ + flush_dcache_range(start, start + size); +} diff --git a/arch/arc/cpu/arc700/config.mk b/arch/arc/cpu/arc700/config.mk new file mode 100644 index 0000000..3206ff4 --- /dev/null +++ b/arch/arc/cpu/arc700/config.mk @@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -mA7 diff --git a/arch/arc/cpu/arc700/cpu.c b/arch/arc/cpu/arc700/cpu.c new file mode 100644 index 0000000..50634b8 --- /dev/null +++ b/arch/arc/cpu/arc700/cpu.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arcregs.h> +#include <asm/cache.h> + +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" */ + if ((read_aux_reg(ARC_AUX_IDENTITY) & 0xffffff00) == 0xffffff00) + gd->arch.running_on_hw = 0; + else + gd->arch.running_on_hw = 1; + + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +int arch_early_init_r(void) +{ + gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + return 0; +} diff --git a/arch/arc/cpu/arc700/interrupts.c b/arch/arc/cpu/arc700/interrupts.c new file mode 100644 index 0000000..d93a6eb --- /dev/null +++ b/arch/arc/cpu/arc700/interrupts.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arcregs.h> +#include <asm/ptrace.h> + +/* Bit values in STATUS32 */ +#define E1_MASK (1 << 1) /* Level 1 interrupts enable */ +#define E2_MASK (1 << 2) /* Level 2 interrupts enable */ + +int interrupt_init(void) +{ + return 0; +} + +/* + * returns true if interrupts had been enabled before we disabled them + */ +int disable_interrupts(void) +{ + int status = read_aux_reg(ARC_AUX_STATUS32); + int state = (status | E1_MASK | E2_MASK) ? 1 : 0; + + status &= ~(E1_MASK | E2_MASK); + /* STATUS32 register is updated indirectly with "FLAG" instruction */ + __asm__("flag %0" : : "r" (status)); + return state; +} + +void enable_interrupts(void) +{ + unsigned int status = read_aux_reg(ARC_AUX_STATUS32); + + status |= E1_MASK | E2_MASK; + /* STATUS32 register is updated indirectly with "FLAG" instruction */ + __asm__("flag %0" : : "r" (status)); +} + +static void print_reg_file(long *reg_rev, int start_num) +{ + unsigned int i; + + /* Print 3 registers per line */ + for (i = start_num; i < start_num + 25; i++) { + printf("r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev); + if (((i + 1) % 3) == 0) + printf("\n"); + + /* Because pt_regs has registers reversed */ + reg_rev--; + } + + /* Add new-line if none was inserted in the end of loop above */ + if (((i + 1) % 3) != 0) + printf("\n"); +} + +void show_regs(struct pt_regs *regs) +{ + printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n", + regs->ret, regs->blink, regs->status32); + printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25); + printf("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", regs->bta, + regs->sp, regs->fp); + printf("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start, + regs->lp_end, regs->lp_count); + + print_reg_file(&(regs->r0), 0); +} + +void bad_mode(struct pt_regs *regs) +{ + if (regs) + show_regs(regs); + + panic("Resetting CPU ...\n"); +} + +void do_memory_error(unsigned long address, struct pt_regs *regs) +{ + printf("Memory error exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_instruction_error(unsigned long address, struct pt_regs *regs) +{ + printf("Instruction error exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_machine_check_fault(unsigned long address, struct pt_regs *regs) +{ + printf("Machine check exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_interrupt_handler(void) +{ + printf("Interrupt fired\n"); + bad_mode(0); +} + +void do_itlb_miss(struct pt_regs *regs) +{ + printf("I TLB miss exception\n"); + bad_mode(regs); +} + +void do_dtlb_miss(struct pt_regs *regs) +{ + printf("D TLB miss exception\n"); + bad_mode(regs); +} + +void do_tlb_prot_violation(unsigned long address, struct pt_regs *regs) +{ + printf("TLB protection violation or misaligned access @ 0x%lx\n", + address); + bad_mode(regs); +} + +void do_privilege_violation(struct pt_regs *regs) +{ + printf("Privilege violation exception\n"); + bad_mode(regs); +} + +void do_trap(struct pt_regs *regs) +{ + printf("Trap exception\n"); + bad_mode(regs); +} + +void do_extension(struct pt_regs *regs) +{ + printf("Extension instruction exception\n"); + bad_mode(regs); +} diff --git a/arch/arc/cpu/arc700/reset.c b/arch/arc/cpu/arc700/reset.c new file mode 100644 index 0000000..98ebf1d --- /dev/null +++ b/arch/arc/cpu/arc700/reset.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <command.h> +#include <common.h> + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + printf("Put your restart handler here\n"); + +#ifdef DEBUG + /* Stop debug session here */ + __asm__("brk"); +#endif + return 0; +} diff --git a/arch/arc/cpu/arc700/start.S b/arch/arc/cpu/arc700/start.S new file mode 100644 index 0000000..563513b --- /dev/null +++ b/arch/arc/cpu/arc700/start.S @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/arcregs.h> + +/* + * Note on the LD/ST addressing modes with address register write-back + * + * LD.a same as LD.aw + * + * LD.a reg1, [reg2, x] => Pre Incr + * Eff Addr for load = [reg2 + x] + * + * LD.ab reg1, [reg2, x] => Post Incr + * Eff Addr for load = [reg2] + */ + +.macro PUSH reg + st.a \reg, [%sp, -4] +.endm + +.macro PUSHAX aux + lr %r9, [\aux] + PUSH %r9 +.endm + +.macro SAVE_R1_TO_R24 + PUSH %r1 + PUSH %r2 + PUSH %r3 + PUSH %r4 + PUSH %r5 + PUSH %r6 + PUSH %r7 + PUSH %r8 + PUSH %r9 + PUSH %r10 + PUSH %r11 + PUSH %r12 + PUSH %r13 + PUSH %r14 + PUSH %r15 + PUSH %r16 + PUSH %r17 + PUSH %r18 + PUSH %r19 + PUSH %r20 + PUSH %r21 + PUSH %r22 + PUSH %r23 + PUSH %r24 +.endm + +.macro SAVE_ALL_SYS + + st %r0, [%sp] + lr %r0, [%ecr] + st %r0, [%sp, 8] /* ECR */ + st %sp, [%sp, 4] + + 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 + +.align 4 +.globl _start +_start: + /* Critical system events */ + j reset /* 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) */ + +memory_error: + SAVE_ALL_SYS + lr %r0, [%efa] + mov %r1, %sp + j do_memory_error + +instruction_error: + SAVE_ALL_SYS + lr %r0, [%efa] + 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 + lr %r0, [%efa] + 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 + lr %r0, [%efa] + 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 + + +reset: + /* Setup interrupt vector base that matches "__text_start" */ + sr __text_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 + +/* + * 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/arc700/timer.c b/arch/arc/cpu/arc700/timer.c new file mode 100644 index 0000000..a0acbbc --- /dev/null +++ b/arch/arc/cpu/arc700/timer.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arcregs.h> + +#define NH_MODE (1 << 1) /* Disable timer if CPU is halted */ + +int timer_init(void) +{ + write_aux_reg(ARC_AUX_TIMER0_CTRL, NH_MODE); + /* Set max value for counter/timer */ + write_aux_reg(ARC_AUX_TIMER0_LIMIT, 0xffffffff); + /* Set initial count value and restart counter/timer */ + write_aux_reg(ARC_AUX_TIMER0_CNT, 0); + return 0; +} + +unsigned long timer_read_counter(void) +{ + return read_aux_reg(ARC_AUX_TIMER0_CNT); +} diff --git a/arch/arc/cpu/arc700/u-boot.lds b/arch/arc/cpu/arc700/u-boot.lds new file mode 100644 index 0000000..2d01b21 --- /dev/null +++ b/arch/arc/cpu/arc700/u-boot.lds @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc") +OUTPUT_ARCH(arc) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(4); + .text : { + *(.__text_start) + *(.__image_copy_start) + CPUDIR/start.o (.text*) + *(.text*) + } + + . = ALIGN(4); + .text_end : + { + *(.__text_end) + } + + . = ALIGN(4); + .rodata : { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(4); + .rel_dyn_start : { + *(.__rel_dyn_start) + } + + .rela.dyn : { + *(.rela.dyn) + } + + .rel_dyn_end : { + *(.__rel_dyn_end) + } + + . = ALIGN(4); + .bss_start : { + *(.__bss_start); + } + + .bss : { + *(.bss*) + } + + .bss_end : { + *(.__bss_end); + } + + . = ALIGN(4); + .image_copy_end : { + *(.__image_copy_end) + *(.__init_end) + } +}

These are library functions used by ARC700 architecture.
Following files were borrowed from Linux kernel sources, commit 5ee54f38171b9b3541c5e9cf9c3a9e53455fd8b4 (Linux 3.11.10):
* memcmp.S * memcpy-700.S * memset.S * strchr-700.S * strcmp.S * strcpy-700.S * strlen.S
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Mostly cosmetics in string routines. * Moved declaration of "__text_end" to "asm/sections.h".
arch/arc/lib/Makefile | 16 ++++++ arch/arc/lib/bootm.c | 106 ++++++++++++++++++++++++++++++++++ arch/arc/lib/memcmp.S | 121 +++++++++++++++++++++++++++++++++++++++ arch/arc/lib/memcpy-700.S | 63 +++++++++++++++++++++ arch/arc/lib/memset.S | 62 ++++++++++++++++++++ arch/arc/lib/relocate.c | 72 +++++++++++++++++++++++ arch/arc/lib/sections.c | 21 +++++++ arch/arc/lib/strchr-700.S | 141 ++++++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/strcmp.S | 97 +++++++++++++++++++++++++++++++ arch/arc/lib/strcpy-700.S | 67 ++++++++++++++++++++++ arch/arc/lib/strlen.S | 80 ++++++++++++++++++++++++++ 11 files changed, 846 insertions(+) create mode 100644 arch/arc/lib/Makefile create mode 100644 arch/arc/lib/bootm.c create mode 100644 arch/arc/lib/memcmp.S create mode 100644 arch/arc/lib/memcpy-700.S create mode 100644 arch/arc/lib/memset.S create mode 100644 arch/arc/lib/relocate.c create mode 100644 arch/arc/lib/sections.c create mode 100644 arch/arc/lib/strchr-700.S create mode 100644 arch/arc/lib/strcmp.S create mode 100644 arch/arc/lib/strcpy-700.S create mode 100644 arch/arc/lib/strlen.S
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile new file mode 100644 index 0000000..7675f85 --- /dev/null +++ b/arch/arc/lib/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += sections.o +obj-y += relocate.o +obj-y += strchr-700.o +obj-y += strcmp.o +obj-y += strcpy-700.o +obj-y += strlen.o +obj-y += memcmp.o +obj-y += memcpy-700.o +obj-y += memset.o +obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c new file mode 100644 index 0000000..d185a50 --- /dev/null +++ b/arch/arc/lib/bootm.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 4K to be safe */ + sp -= 4096; + lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp)); +} + +static int cleanup_before_linux(void) +{ + disable_interrupts(); + flush_dcache_all(); + invalidate_icache_all(); + + return 0; +} + +/* Subcommand: PREP */ +static void boot_prep_linux(bootm_headers_t *images) +{ + if (image_setup_linux(images)) + hang(); +} + +/* Subcommand: GO */ +static void boot_jump_linux(bootm_headers_t *images, int flag) +{ + void (*kernel_entry)(int zero, int arch, uint params); + unsigned int r0, r2; + int fake = (flag & BOOTM_STATE_OS_FAKE_GO); + + kernel_entry = (void (*)(int, int, uint))images->ep; + + debug("## Transferring control to Linux (at address %08lx)...\n", + (ulong) kernel_entry); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + printf("\nStarting kernel ...%s\n\n", fake ? + "(fake run for tracing)" : ""); + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); + + cleanup_before_linux(); + + if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + r0 = 2; + r2 = (unsigned int)images->ft_addr; + } else { + r0 = 1; + r2 = (unsigned int)getenv("bootargs"); + } + + if (!fake) + kernel_entry(r0, 0, r2); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + /* No need for those on ARC */ + if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + boot_jump_linux(images, flag); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images, flag); + return 0; +} diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S new file mode 100644 index 0000000..fa5aac5 --- /dev/null +++ b/arch/arc/lib/memcmp.S @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifdef __LITTLE_ENDIAN__ +#define WORD2 r2 +#define SHIFT r3 +#else /* __BIG_ENDIAN__ */ +#define WORD2 r3 +#define SHIFT r2 +#endif /* _ENDIAN__ */ + +.global memcmp +.align 4 +memcmp: + or %r12, %r0, %r1 + asl_s %r12, %r12, 30 + sub %r3, %r2, 1 + brls %r2, %r12, .Lbytewise + ld %r4, [%r0, 0] + ld %r5, [%r1, 0] + lsr.f %lp_count, %r3, 3 + lpne .Loop_end + ld_s WORD2, [%r0, 4] + ld_s %r12, [%r1, 4] + brne %r4, %r5, .Leven + ld.a %r4, [%r0, 8] + ld.a %r5, [%r1, 8] + brne WORD2, %r12, .Lodd +.Loop_end: + asl_s SHIFT, SHIFT, 3 + bhs_s .Last_cmp + brne %r4, %r5, .Leven + ld %r4, [%r0, 4] + ld %r5, [%r1, 4] +#ifdef __LITTLE_ENDIAN__ + nop_s + /* one more load latency cycle */ +.Last_cmp: + xor %r0, %r4, %r5 + bset %r0, %r0, SHIFT + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + b.d .Leven_cmp + and %r1, %r1, 24 +.Leven: + xor %r0, %r4, %r5 + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + /* slow track insn */ + and %r1, %r1, 24 +.Leven_cmp: + asl %r2, %r4, %r1 + asl %r12, %r5, %r1 + lsr_s %r2, %r2, 1 + lsr_s %r12, %r12, 1 + j_s.d [%blink] + sub %r0, %r2, %r12 + .balign 4 +.Lodd: + xor %r0, WORD2, %r12 + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + /* slow track insn */ + and %r1, %r1, 24 + asl_s %r2, %r2, %r1 + asl_s %r12, %r12, %r1 + lsr_s %r2, %r2, 1 + lsr_s %r12, %r12, 1 + j_s.d [%blink] + sub %r0, %r2, %r12 +#else /* __BIG_ENDIAN__ */ +.Last_cmp: + neg_s SHIFT, SHIFT + lsr %r4, %r4, SHIFT + lsr %r5, %r5, SHIFT + /* slow track insn */ +.Leven: + sub.f %r0, %r4, %r5 + mov.ne %r0, 1 + j_s.d [%blink] + bset.cs %r0, %r0, 31 +.Lodd: + cmp_s WORD2, %r12 + + mov_s %r0, 1 + j_s.d [%blink] + bset.cs %r0, %r0, 31 +#endif /* _ENDIAN__ */ + .balign 4 +.Lbytewise: + breq %r2, 0, .Lnil + ldb %r4, [%r0, 0] + ldb %r5, [%r1, 0] + lsr.f %lp_count, %r3 + lpne .Lbyte_end + ldb_s %r3, [%r0, 1] + ldb %r12, [%r1, 1] + brne %r4, %r5, .Lbyte_even + ldb.a %r4, [%r0, 2] + ldb.a %r5, [%r1, 2] + brne %r3, %r12, .Lbyte_odd +.Lbyte_end: + bcc .Lbyte_even + brne %r4, %r5, .Lbyte_even + ldb_s %r3, [%r0, 1] + ldb_s %r12, [%r1, 1] +.Lbyte_odd: + j_s.d [%blink] + sub %r0, %r3, %r12 +.Lbyte_even: + j_s.d [%blink] + sub %r0, %r4, %r5 +.Lnil: + j_s.d [%blink] + mov %r0, 0 diff --git a/arch/arc/lib/memcpy-700.S b/arch/arc/lib/memcpy-700.S new file mode 100644 index 0000000..51dd73a --- /dev/null +++ b/arch/arc/lib/memcpy-700.S @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.global memcpy +.align 4 +memcpy: + or %r3, %r0, %r1 + asl_s %r3, %r3, 30 + mov_s %r5, %r0 + brls.d %r2, %r3, .Lcopy_bytewise + sub.f %r3, %r2, 1 + ld_s %r12, [%r1, 0] + asr.f %lp_count, %r3, 3 + bbit0.d %r3, 2, .Lnox4 + bmsk_s %r2, %r2, 1 + st.ab %r12, [%r5, 4] + ld.a %r12, [%r1, 4] +.Lnox4: + lppnz .Lendloop + ld_s %r3, [%r1, 4] + st.ab %r12, [%r5, 4] + ld.a %r12, [%r1, 8] + st.ab %r3, [%r5, 4] +.Lendloop: + breq %r2, 0, .Last_store + ld %r3, [%r5, 0] +#ifdef __LITTLE_ENDIAN__ + add3 %r2, -1, %r2 + /* uses long immediate */ + xor_s %r12, %r12, %r3 + bmsk %r12, %r12, %r2 + xor_s %r12, %r12, %r3 +#else /* __BIG_ENDIAN__ */ + sub3 %r2, 31, %r2 + /* uses long immediate */ + xor_s %r3, %r3, %r12 + bmsk %r3, %r3, %r2 + xor_s %r12, %r12, %r3 +#endif /* _ENDIAN__ */ +.Last_store: + j_s.d [%blink] + st %r12, [%r5, 0] + + .balign 4 +.Lcopy_bytewise: + jcs [%blink] + ldb_s %r12, [%r1, 0] + lsr.f %lp_count, %r3 + bhs_s .Lnox1 + stb.ab %r12, [%r5, 1] + ldb.a %r12, [%r1, 1] +.Lnox1: + lppnz .Lendbloop + ldb_s %r3, [%r1, 1] + stb.ab %r12, [%r5, 1] + ldb.a %r12, [%r1, 2] + stb.ab %r3, [%r5, 1] +.Lendbloop: + j_s.d [%blink] + stb %r12, [%r5, 0] diff --git a/arch/arc/lib/memset.S b/arch/arc/lib/memset.S new file mode 100644 index 0000000..017e8af --- /dev/null +++ b/arch/arc/lib/memset.S @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define SMALL 7 /* Must be at least 6 to deal with alignment/loop issues. */ + +.global memset +.align 4 +memset: + mov_s %r4, %r0 + or %r12, %r0, %r2 + bmsk.f %r12, %r12, 1 + extb_s %r1, %r1 + asl %r3, %r1, 8 + beq.d .Laligned + or_s %r1, %r1, %r3 + brls %r2, SMALL, .Ltiny + add %r3, %r2, %r0 + stb %r1, [%r3, -1] + bclr_s %r3, %r3, 0 + stw %r1, [%r3, -2] + bmsk.f %r12, %r0, 1 + add_s %r2, %r2, %r12 + sub.ne %r2, %r2, 4 + stb.ab %r1, [%r4, 1] + and %r4, %r4, -2 + stw.ab %r1, [%r4, 2] + and %r4, %r4, -4 + + .balign 4 +.Laligned: + asl %r3, %r1, 16 + lsr.f %lp_count, %r2, 2 + or_s %r1, %r1, %r3 + lpne .Loop_end + st.ab %r1, [%r4, 4] +.Loop_end: + j_s [%blink] + + .balign 4 +.Ltiny: + mov.f %lp_count, %r2 + lpne .Ltiny_end + stb.ab %r1, [%r4, 1] +.Ltiny_end: + j_s [%blink] + +/* + * memzero: @r0 = mem, @r1 = size_t + * memset: @r0 = mem, @r1 = char, @r2 = size_t + */ + +.global memzero +.align 4 +memzero: + /* adjust bzero args to memset args */ + mov %r2, %r1 + mov %r1, 0 + /* tail call so need to tinker with blink */ + b memset diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c new file mode 100644 index 0000000..956aa14 --- /dev/null +++ b/arch/arc/lib/relocate.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <elf.h> +#include <asm/sections.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Base functionality is taken from x86 version with added ARC-specifics + */ +int do_elf_reloc_fixups(void) +{ + Elf32_Rela *re_src = (Elf32_Rela *)(&__rel_dyn_start); + Elf32_Rela *re_end = (Elf32_Rela *)(&__rel_dyn_end); + + Elf32_Addr *offset_ptr_rom, *last_offset = NULL; + Elf32_Addr *offset_ptr_ram; + + do { + /* Get the location from the relocation entry */ + offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; + + /* Check that the location of the relocation is in .text */ + if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE && + offset_ptr_rom > last_offset) { + unsigned int val; + /* Switch to the in-RAM version */ + offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + + gd->reloc_off); + + /* + * Use "memcpy" because target location might be + * 16-bit aligned on ARC so we may need to read + * byte-by-byte. On attempt to read entire word by + * CPU throws an exception + */ + memcpy(&val, offset_ptr_ram, sizeof(int)); + + /* If location in ".text" section swap value */ + if ((unsigned int)offset_ptr_rom < + (unsigned int)&__text_end) + val = (val << 16) | (val >> 16); + + /* Check that the target points into .text */ + if (val >= CONFIG_SYS_TEXT_BASE && val <= + (unsigned int)&__bss_end) { + val += gd->reloc_off; + /* If location in ".text" section swap value */ + if ((unsigned int)offset_ptr_rom < + (unsigned int)&__text_end) + val = (val << 16) | (val >> 16); + memcpy(offset_ptr_ram, &val, sizeof(int)); + } else { + debug(" %p: rom reloc %x, ram %p, value %x, limit %x\n", + re_src, re_src->r_offset, offset_ptr_ram, + val, (unsigned int)&__bss_end); + } + } else { + debug(" %p: rom reloc %x, last %p\n", re_src, + re_src->r_offset, last_offset); + } + last_offset = offset_ptr_rom; + + } while (++re_src < re_end); + + return 0; +} diff --git a/arch/arc/lib/sections.c b/arch/arc/lib/sections.c new file mode 100644 index 0000000..b0b46a4 --- /dev/null +++ b/arch/arc/lib/sections.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * For some reason linker sets linker-generated symbols to zero in PIE mode. + * A work-around is substitution of linker-generated symbols with + * compiler-generated symbols which are properly handled by linker in PAE mode. + */ + +char __bss_start[0] __attribute__((section(".__bss_start"))); +char __bss_end[0] __attribute__((section(".__bss_end"))); +char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); +char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); +char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); +char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); +char __text_start[0] __attribute__((section(".__text_start"))); +char __text_end[0] __attribute__((section(".__text_end"))); +char __init_end[0] __attribute__((section(".__init_end"))); diff --git a/arch/arc/lib/strchr-700.S b/arch/arc/lib/strchr-700.S new file mode 100644 index 0000000..55fcc9f --- /dev/null +++ b/arch/arc/lib/strchr-700.S @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * ARC700 has a relatively long pipeline and branch prediction, so we want + * to avoid branches that are hard to predict. On the other hand, the + * presence of the norm instruction makes it easier to operate on whole + * words branch-free. + */ + +.global strchr +.align 4 +strchr: + extb_s %r1, %r1 + asl %r5, %r1, 8 + bmsk %r2, %r0, 1 + or %r5, %r5, %r1 + mov_s %r3, 0x01010101 + breq.d %r2, %r0, .Laligned + asl %r4, %r5, 16 + sub_s %r0, %r0, %r2 + asl %r7, %r2, 3 + ld_s %r2, [%r0] +#ifdef __LITTLE_ENDIAN__ + asl %r7, %r3, %r7 +#else /* __BIG_ENDIAN__ */ + lsr %r7, %r3, %r7 +#endif /* _ENDIAN__ */ + or %r5, %r5, %r4 + ror %r4, %r3 + sub %r12, %r2, %r7 + bic_s %r12, %r12, %r2 + and %r12, %r12, %r4 + brne.d %r12, 0, .Lfound0_ua + xor %r6, %r2, %r5 + ld.a %r2, [%r0, 4] + sub %r12, %r6, %r7 + bic %r12, %r12, %r6 +#ifdef __LITTLE_ENDIAN__ + and %r7, %r12, %r4 + /* For speed, we want this branch to be unaligned. */ + breq %r7, 0, .Loop + /* Likewise this one */ + b .Lfound_char +#else /* __BIG_ENDIAN__ */ + and %r12, %r12, %r4 + /* For speed, we want this branch to be unaligned. */ + breq %r12, 0, .Loop + lsr_s %r12, %r12, 7 + bic %r2, %r7, %r6 + b.d .Lfound_char_b + and_s %r2, %r2, %r12 +#endif /* _ENDIAN__ */ + /* We require this code address to be unaligned for speed... */ +.Laligned: + ld_s %r2, [%r0] + or %r5, %r5, %r4 + ror %r4, %r3 + /* ... so that this code address is aligned, for itself and ... */ +.Loop: + sub %r12, %r2, %r3 + bic_s %r12, %r12, %r2 + and %r12, %r12, %r4 + brne.d %r12, 0, .Lfound0 + xor %r6, %r2, %r5 + ld.a %r2, [%r0, 4] + sub %r12, %r6, %r3 + bic %r12, %r12, %r6 + and %r7, %r12, %r4 + breq %r7, 0, .Loop + /* + *... so that this branch is unaligned. + * Found searched-for character. + * r0 has already advanced to next word. + */ +#ifdef __LITTLE_ENDIAN__ + /* + * We only need the information about the first matching byte + * (i.e. the least significant matching byte) to be exact, + * hence there is no problem with carry effects. + */ +.Lfound_char: + sub %r3, %r7, 1 + bic %r3, %r3, %r7 + norm %r2, %r3 + sub_s %r0, %r0, 1 + asr_s %r2, %r2, 3 + j.d [%blink] + sub_s %r0, %r0, %r2 + + .balign 4 +.Lfound0_ua: + mov %r3, %r7 +.Lfound0: + sub %r3, %r6, %r3 + bic %r3, %r3, %r6 + and %r2, %r3, %r4 + or_s %r12, %r12, %r2 + sub_s %r3, %r12, 1 + bic_s %r3, %r3, %r12 + norm %r3, %r3 + add_s %r0, %r0, 3 + asr_s %r12, %r3, 3 + asl.f 0, %r2, %r3 + sub_s %r0, %r0, %r12 + j_s.d [%blink] + mov.pl %r0, 0 +#else /* __BIG_ENDIAN__ */ +.Lfound_char: + lsr %r7, %r7, 7 + + bic %r2, %r7, %r6 +.Lfound_char_b: + norm %r2, %r2 + sub_s %r0, %r0, 4 + asr_s %r2, %r2, 3 + j.d [%blink] + add_s %r0, %r0, %r2 + +.Lfound0_ua: + mov_s %r3, %r7 +.Lfound0: + asl_s %r2, %r2, 7 + or %r7, %r6, %r4 + bic_s %r12, %r12, %r2 + sub %r2, %r7, %r3 + or %r2, %r2, %r6 + bic %r12, %r2, %r12 + bic.f %r3, %r4, %r12 + norm %r3, %r3 + + add.pl %r3, %r3, 1 + asr_s %r12, %r3, 3 + asl.f 0, %r2, %r3 + add_s %r0, %r0, %r12 + j_s.d [%blink] + mov.mi %r0, 0 +#endif /* _ENDIAN__ */ diff --git a/arch/arc/lib/strcmp.S b/arch/arc/lib/strcmp.S new file mode 100644 index 0000000..8cb7d2f --- /dev/null +++ b/arch/arc/lib/strcmp.S @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This is optimized primarily for the ARC700. + * It would be possible to speed up the loops by one cycle / word + * respective one cycle / byte by forcing double source 1 alignment, unrolling + * by a factor of two, and speculatively loading the second word / byte of + * source 1; however, that would increase the overhead for loop setup / finish, + * and strcmp might often terminate early. + */ + +.global strcmp +.align 4 +strcmp: + or %r2, %r0, %r1 + bmsk_s %r2, %r2, 1 + brne %r2, 0, .Lcharloop + mov_s %r12, 0x01010101 + ror %r5, %r12 +.Lwordloop: + ld.ab %r2, [%r0, 4] + ld.ab %r3, [%r1, 4] + nop_s + sub %r4, %r2, %r12 + bic %r4, %r4, %r2 + and %r4, %r4, %r5 + brne %r4, 0, .Lfound0 + breq %r2 ,%r3, .Lwordloop +#ifdef __LITTLE_ENDIAN__ + xor %r0, %r2, %r3 /* mask for difference */ + sub_s %r1, %r0, 1 + bic_s %r0, %r0, %r1 /* mask for least significant difference bit */ + sub %r1, %r5, %r0 + xor %r0, %r5, %r1 /* mask for least significant difference byte */ + and_s %r2, %r2, %r0 + and_s %r3, %r3, %r0 +#endif /* _ENDIAN__ */ + cmp_s %r2, %r3 + mov_s %r0, 1 + j_s.d [%blink] + bset.lo %r0, %r0, 31 + + .balign 4 +#ifdef __LITTLE_ENDIAN__ +.Lfound0: + xor %r0, %r2, %r3 /* mask for difference */ + or %r0, %r0, %r4 /* or in zero indicator */ + sub_s %r1, %r0, 1 + bic_s %r0, %r0, %r1 /* mask for least significant difference bit */ + sub %r1, %r5, %r0 + xor %r0, %r5, %r1 /* mask for least significant difference byte */ + and_s %r2, %r2, %r0 + and_s %r3, %r3, %r0 + sub.f %r0, %r2, %r3 + mov.hi %r0, 1 + j_s.d [%blink] + bset.lo %r0, %r0, 31 +#else /* __BIG_ENDIAN__ */ + /* + * The zero-detection above can mis-detect 0x01 bytes as zeroes + * because of carry-propagateion from a lower significant zero byte. + * We can compensate for this by checking that bit0 is zero. + * This compensation is not necessary in the step where we + * get a low estimate for r2, because in any affected bytes + * we already have 0x00 or 0x01, which will remain unchanged + * when bit 7 is cleared. + */ + .balign 4 +.Lfound0: + lsr %r0, %r4, 8 + lsr_s %r1, %r2 + bic_s %r2, %r2, %r0 /* get low estimate for r2 and get ... */ + bic_s %r0, %r0, %r1 /* <this is the adjusted mask for zeros> */ + or_s %r3, %r3, %r0 /* ... high estimate r3 so that r2 > r3 will */ + cmp_s %r3, %r2 /* ... be independent of trailing garbage */ + or_s %r2, %r2, %r0 /* likewise for r3 > r2 */ + bic_s %r3, %r3, %r0 + rlc %r0, 0 /* r0 := r2 > r3 ? 1 : 0 */ + cmp_s %r2, %r3 + j_s.d [%blink] + bset.lo %r0, %r0, 31 +#endif /* _ENDIAN__ */ + + .balign 4 +.Lcharloop: + ldb.ab %r2,[%r0,1] + ldb.ab %r3,[%r1,1] + nop_s + breq %r2, 0, .Lcmpend + breq %r2, %r3, .Lcharloop +.Lcmpend: + j_s.d [%blink] + sub %r0, %r2, %r3 diff --git a/arch/arc/lib/strcpy-700.S b/arch/arc/lib/strcpy-700.S new file mode 100644 index 0000000..41bb53e --- /dev/null +++ b/arch/arc/lib/strcpy-700.S @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * If dst and src are 4 byte aligned, copy 8 bytes at a time. + * If the src is 4, but not 8 byte aligned, we first read 4 bytes to get + * it 8 byte aligned. Thus, we can do a little read-ahead, without + * dereferencing a cache line that we should not touch. + * Note that short and long instructions have been scheduled to avoid + * branch stalls. + * The beq_s to r3z could be made unaligned & long to avoid a stall + * there, but it is not likely to be taken often, and it would also be likely + * to cost an unaligned mispredict at the next call. + */ + +.global strcpy +.align 4 +strcpy: + or %r2, %r0, %r1 + bmsk_s %r2, %r2, 1 + brne.d %r2, 0, charloop + mov_s %r10, %r0 + ld_s %r3, [%r1, 0] + mov %r8, 0x01010101 + bbit0.d %r1, 2, loop_start + ror %r12, %r8 + sub %r2, %r3, %r8 + bic_s %r2, %r2, %r3 + tst_s %r2,%r12 + bne r3z + mov_s %r4,%r3 + .balign 4 +loop: + ld.a %r3, [%r1, 4] + st.ab %r4, [%r10, 4] +loop_start: + ld.a %r4, [%r1, 4] + sub %r2, %r3, %r8 + bic_s %r2, %r2, %r3 + tst_s %r2, %r12 + bne_s r3z + st.ab %r3, [%r10, 4] + sub %r2, %r4, %r8 + bic %r2, %r2, %r4 + tst %r2, %r12 + beq loop + mov_s %r3, %r4 +#ifdef __LITTLE_ENDIAN__ +r3z: bmsk.f %r1, %r3, 7 + lsr_s %r3, %r3, 8 +#else /* __BIG_ENDIAN__ */ +r3z: lsr.f %r1, %r3, 24 + asl_s %r3, %r3, 8 +#endif /* _ENDIAN__ */ + bne.d r3z + stb.ab %r1, [%r10, 1] + j_s [%blink] + + .balign 4 +charloop: + ldb.ab %r3, [%r1, 1] + brne.d %r3, 0, charloop + stb.ab %r3, [%r10, 1] + j [%blink] diff --git a/arch/arc/lib/strlen.S b/arch/arc/lib/strlen.S new file mode 100644 index 0000000..666e22c --- /dev/null +++ b/arch/arc/lib/strlen.S @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.global strlen +.align 4 +strlen: + or %r3, %r0, 7 + ld %r2, [%r3, -7] + ld.a %r6, [%r3, -3] + mov %r4, 0x01010101 + /* uses long immediate */ +#ifdef __LITTLE_ENDIAN__ + asl_s %r1, %r0, 3 + btst_s %r0, 2 + asl %r7, %r4, %r1 + ror %r5, %r4 + sub %r1, %r2, %r7 + bic_s %r1, %r1, %r2 + mov.eq %r7, %r4 + sub %r12, %r6, %r7 + bic %r12, %r12, %r6 + or.eq %r12, %r12, %r1 + and %r12, %r12, %r5 + brne %r12, 0, .Learly_end +#else /* __BIG_ENDIAN__ */ + ror %r5, %r4 + btst_s %r0, 2 + mov_s %r1, 31 + sub3 %r7, %r1, %r0 + sub %r1, %r2, %r4 + bic_s %r1, %r1, %r2 + bmsk %r1, %r1, %r7 + sub %r12, %r6, %r4 + bic %r12, %r12, %r6 + bmsk.ne %r12, %r12, %r7 + or.eq %r12, %r12, %r1 + and %r12, %r12, %r5 + brne %r12, 0, .Learly_end +#endif /* _ENDIAN__ */ + +.Loop: + ld_s %r2, [%r3, 4] + ld.a %r6, [%r3, 8] + /* stall for load result */ + sub %r1, %r2, %r4 + bic_s %r1, %r1, %r2 + sub %r12, %r6, %r4 + bic %r12, %r12, %r6 + or %r12, %r12, %r1 + and %r12, %r12, %r5 + breq %r12, 0, .Loop +.Lend: + and.f %r1, %r1, %r5 + sub.ne %r3, %r3, 4 + mov.eq %r1, %r12 +#ifdef __LITTLE_ENDIAN__ + sub_s %r2, %r1, 1 + bic_s %r2, %r2, %r1 + norm %r1, %r2 + sub_s %r0, %r0, 3 + lsr_s %r1, %r1, 3 + sub %r0, %r3, %r0 + j_s.d [%blink] + sub %r0, %r0, %r1 +#else /* __BIG_ENDIAN__ */ + lsr_s %r1, %r1, 7 + mov.eq %r2, %r6 + bic_s %r1, %r1, %r2 + norm %r1, %r1 + sub %r0, %r3, %r0 + lsr_s %r1, %r1, 3 + j_s.d [%blink] + add %r0, %r0, %r1 +#endif /* _ENDIAN */ +.Learly_end: + b.d .Lend + sub_s.ne %r1, %r1, %r1

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Added inclusion of "u-boot-arc.h" in "common.h".
common/cmd_bdinfo.c | 18 ++++++++++++++++++ common/image.c | 1 + include/common.h | 3 +++ include/image.h | 1 + 4 files changed, 23 insertions(+)
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 713de14..15119a7 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -517,6 +517,24 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; }
+#elif defined(CONFIG_ARC700) + +int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + bd_t *bd = gd->bd; + + print_num("mem start", bd->bi_memstart); + print_lnum("mem size", bd->bi_memsize); + +#if defined(CONFIG_CMD_NET) + print_eth(0); + printf("ip_addr = %s\n", getenv("ipaddr")); +#endif + printf("baudrate = %d bps\n", bd->bi_baudrate); + + return 0; +} + #else #error "a case for this architecture does not exist!" #endif diff --git a/common/image.c b/common/image.c index ae95c3f..9c6bec5 100644 --- a/common/image.c +++ b/common/image.c @@ -82,6 +82,7 @@ static const table_entry_t uimage_arch[] = { { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, { IH_ARCH_ARM64, "arm64", "AArch64", }, + { IH_ARCH_ARC, "arc", "ARC", }, { -1, "", "", }, };
diff --git a/include/common.h b/include/common.h index d5ebb25..221b776 100644 --- a/include/common.h +++ b/include/common.h @@ -408,6 +408,9 @@ static inline int setenv_addr(const char *varname, const void *addr) #ifdef CONFIG_MIPS # include <asm/u-boot-mips.h> #endif /* CONFIG_MIPS */ +#ifdef CONFIG_ARC +# include <asm/u-boot-arc.h> +#endif /* CONFIG_ARC */
#ifdef CONFIG_AUTO_COMPLETE int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf); diff --git a/include/image.h b/include/image.h index 7de2bb2..3ba8c2e 100644 --- a/include/image.h +++ b/include/image.h @@ -157,6 +157,7 @@ struct lmb; #define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */ #define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ #define IH_ARCH_ARM64 22 /* ARM64 */ +#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */
/* * Image Types

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- No changes for v3.
examples/standalone/stubs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 32a19ce..9346bc2 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -210,6 +210,19 @@ gd_t *global_data; " l.jr r13\n" \ " l.nop\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13"); +#elif defined(CONFIG_ARC) +/* + * r25 holds the pointer to the global_data. r10 is call clobbered. + */ +#define EXPORT_FUNC(x) \ + asm volatile( \ +" .align 4\n" \ +" .globl " #x "\n" \ +#x ":\n" \ +" ld %%r10, [%%r25, %0]\n" \ +" ld %%r10, [%%r10, %1]\n" \ +" j [%%r10]\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r10"); #else /*" addi $sp, $sp, -24\n" \ " br $r16\n" */

Arcangel4 is a FPGA-based development board that is used for prototyping and verification of of both ARC hardware (CPUs) and software running upon CPU.
Prerequisite is http://patchwork.ozlabs.org/patch/300901/
This board avaialble in 2 flavours: * Little-endian (arcangel4) * Big-endian (arcangel4-be)
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Added big-endian flavour of the board. * Common board init code moved to cpu sources.
board/synopsys/arcangel4/Makefile | 11 +++++ boards.cfg | 2 + include/configs/arcangel4-be.h | 96 +++++++++++++++++++++++++++++++++++++++ include/configs/arcangel4.h | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 board/synopsys/arcangel4/Makefile create mode 100644 include/configs/arcangel4-be.h create mode 100644 include/configs/arcangel4.h
diff --git a/board/synopsys/arcangel4/Makefile b/board/synopsys/arcangel4/Makefile new file mode 100644 index 0000000..575e58f --- /dev/null +++ b/board/synopsys/arcangel4/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# This board is mostly used for debugging U-Boot in simulation (ISS). +# The only peripheral which is used on this board is a serial port which +# requires no initialization except those in "include/configs/arcangel4.h". +# And now there's no specific initializations for this board. +# So this Makefile is only required for satisfaction of U-Boot build system. diff --git a/boards.cfg b/boards.cfg index 2dfd2b4..a873aaa 100644 --- a/boards.cfg +++ b/boards.cfg @@ -1229,6 +1229,8 @@ Active sparc leon3 - gaisler - Active sparc leon3 - gaisler - gr_xc3s_1500 - - Active sparc leon3 - gaisler - grsim - - Active x86 x86 coreboot chromebook-x86 coreboot coreboot-x86 coreboot:SYS_TEXT_BASE=0x01110000 - +Active arc arc700 - synopsys - arcangel4 - Alexey Brodkin abrodkin@synopsys.com +Active arc arc700 - synopsys arcangel4 arcangel4-be - Alexey Brodkin abrodkin@synopsys.com Orphan arm arm1136 mx31 - imx31_phycore imx31_phycore_eet imx31_phycore:IMX31_PHYCORE_EET (resigned) Guennadi Liakhovetski g.liakhovetski@gmx.de Orphan arm arm1136 mx31 freescale - mx31ads - (resigned) Guennadi Liakhovetski g.liakhovetski@gmx.de Orphan arm pxa - - - lubbock - (dead address) Kyle Harris kharris@nexus-tech.net diff --git a/include/configs/arcangel4-be.h b/include/configs/arcangel4-be.h new file mode 100644 index 0000000..f026626 --- /dev/null +++ b/include/configs/arcangel4-be.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_ARCANGEL4_H_ +#define _CONFIG_ARCANGEL4_H_ + +/* + * CPU configuration + */ +#define CONFIG_SYS_BIG_ENDIAN +#define CONFIG_ARC700 +#define CONFIG_ARC_MMU_VER 3 +#define CONFIG_SYS_CACHELINE_SIZE 64 +#define CONFIG_SYS_CLK_FREQ 70000000 +#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ + +/* + * Board configuration + */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ + +#define CONFIG_ARCH_EARLY_INIT_R + +/* + * Memory configuration + */ +#define CONFIG_SYS_TEXT_BASE 0x81000000 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE 0x10000000 /* 256 Mb */ + +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234) + +#define CONFIG_SYS_MALLOC_LEN 0x200000 /* 2 MB */ +#define CONFIG_SYS_BOOTM_LEN 0x2000000 /* 32 MB */ +#define CONFIG_SYS_LOAD_ADDR 0x82000000 + +#define CONFIG_SYS_NO_FLASH + +/* + * UART configuration + * + */ +#define CONFIG_ARC_SERIAL +#define CONFIG_ARC_UART_BASE 0xC0FC1000 +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200} + +/* + * Command line configuration + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_ELF + +#define CONFIG_OF_LIBFDT + +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_MAXARGS 16 + +/* + * Environment settings + */ +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ +#define CONFIG_ENV_OFFSET 0 + +/* + * Environment configuration + */ +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_BOOTARGS "console=ttyARC0,115200n8" +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR + +/* + * Console configuration + */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "arcangel4# " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +#endif /* _CONFIG_ARCANGEL4_H_ */ diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h new file mode 100644 index 0000000..31f3a77 --- /dev/null +++ b/include/configs/arcangel4.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_ARCANGEL4_H_ +#define _CONFIG_ARCANGEL4_H_ + +/* + * CPU configuration + */ +#define CONFIG_ARC700 +#define CONFIG_ARC_MMU_VER 3 +#define CONFIG_SYS_CACHELINE_SIZE 64 +#define CONFIG_SYS_CLK_FREQ 70000000 +#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ + +/* + * Board configuration + */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ + +#define CONFIG_ARCH_EARLY_INIT_R + +/* + * Memory configuration + */ +#define CONFIG_SYS_TEXT_BASE 0x81000000 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE 0x10000000 /* 256 Mb */ + +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234) + +#define CONFIG_SYS_MALLOC_LEN 0x200000 /* 2 MB */ +#define CONFIG_SYS_BOOTM_LEN 0x2000000 /* 32 MB */ +#define CONFIG_SYS_LOAD_ADDR 0x82000000 + +#define CONFIG_SYS_NO_FLASH + +/* + * UART configuration + * + */ +#define CONFIG_ARC_SERIAL +#define CONFIG_ARC_UART_BASE 0xC0FC1000 +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200} + +/* + * Command line configuration + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_ELF + +#define CONFIG_OF_LIBFDT + +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_MAXARGS 16 + +/* + * Environment settings + */ +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ +#define CONFIG_ENV_OFFSET 0 + +/* + * Environment configuration + */ +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_BOOTARGS "console=ttyARC0,115200n8" +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR + +/* + * Console configuration + */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "arcangel4# " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +#endif /* _CONFIG_ARCANGEL4_H_ */

Dear Alexey Brodkin,
In message 1391445368-10545-7-git-send-email-abrodkin@synopsys.com you wrote:
Arcangel4 is a FPGA-based development board that is used for prototyping and verification of of both ARC hardware (CPUs) and software running upon CPU.
Prerequisite is http://patchwork.ozlabs.org/patch/300901/
Is this commentuseful in the commit message?
+#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234)
This definitely makes no sense at all. Please see bullet 2. in doc/README.memory-test
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
This is standard, isn't it? So you can omit it.
...
+#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234)
...
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
See above.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Mon, 2014-02-03 at 20:15 +0100, Wolfgang Denk wrote:
Dear Alexey Brodkin,
In message 1391445368-10545-7-git-send-email-abrodkin@synopsys.com you wrote:
Arcangel4 is a FPGA-based development board that is used for prototyping and verification of of both ARC hardware (CPUs) and software running upon CPU.
Prerequisite is http://patchwork.ozlabs.org/patch/300901/
Is this commentuseful in the commit message?
Do you mean comment regarding Arcangel4 board itself? I upstreamed a number of drivers in both u-Boot and Linux kernel and each time I put a brief description of device I'm submitting sources for in commit message.
If this is uncommon and/or redundant I may remove this message in the next re-spin.
+#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234)
This definitely makes no sense at all. Please see bullet 2. in doc/README.memory-test
Thanks, will re-visit this part.
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
This is standard, isn't it? So you can omit it.
Indeed this is standard. But as I wrote earlier - since there's no guidance (or at least I didn't manage to find it) on how to use stuff in u-boot I went grepping through existing u-Boot sources and I saw how it's done.
It might be once again my tough luck in selection of examples...
Regards, Alexey

Dear Alexey,
In message 1391457010.2357.41.camel@abrodkin-8560l.internal.synopsys.com you wrote:
On Mon, 2014-02-03 at 20:15 +0100, Wolfgang Denk wrote:
Dear Alexey Brodkin,
In message 1391445368-10545-7-git-send-email-abrodkin@synopsys.com you wrote:
Arcangel4 is a FPGA-based development board that is used for prototyping and verification of of both ARC hardware (CPUs) and software running upon CPU.
Prerequisite is http://patchwork.ozlabs.org/patch/300901/
Is this commentuseful in the commit message?
Do you mean comment regarding Arcangel4 board itself? I upstreamed a number of drivers in both u-Boot and Linux kernel and each time I put a brief description of device I'm submitting sources for in commit message.
NO, I mean the comment about any prerequisites for this patch. These are only interesting for those to handle the patch, but once it's applied (hopefully with all prerequisites in place), then this sentence is meaningless. So please move it to the comment section.
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
This is standard, isn't it? So you can omit it.
Indeed this is standard. But as I wrote earlier - since there's no guidance (or at least I didn't manage to find it) on how to use stuff in u-boot I went grepping through existing u-Boot sources and I saw how it's done.
You must have used old code as reference; please see
commit 26750c8aee2383a026e0cf89e9310628d3a5a6a0 Author: Tom Rini trini@ti.com Date: Tue Jun 19 12:54:34 2012 +0000
CONFIG_SYS_BAUDRATE_TABLE: Add <config_fallbacks.h>, place there
Best regards,
Wolfgang Denk

AXS101 is a new generation of devlopment boards from Synopsys that houses ASIC with ARC700 and lots of DesignWare peripherals:
* DW APB UART * DW Mobile Storage (MMC/SD) * DW I2C * DW GMAC
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- Changes for v3:
* Removed network parameters. * Common board init code moved to cpu sources.
board/synopsys/axs101/Makefile | 8 ++ board/synopsys/axs101/axs101.c | 44 ++++++++ board/synopsys/axs101/nand.c | 226 +++++++++++++++++++++++++++++++++++++++++ boards.cfg | 1 + include/configs/axs101.h | 186 +++++++++++++++++++++++++++++++++ 5 files changed, 465 insertions(+) create mode 100644 board/synopsys/axs101/Makefile create mode 100644 board/synopsys/axs101/axs101.c create mode 100644 board/synopsys/axs101/nand.c create mode 100644 include/configs/axs101.h
diff --git a/board/synopsys/axs101/Makefile b/board/synopsys/axs101/Makefile new file mode 100644 index 0000000..f0965f7 --- /dev/null +++ b/board/synopsys/axs101/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += axs101.o +obj-$(CONFIG_CMD_NAND) += nand.o diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c new file mode 100644 index 0000000..4dbeaea --- /dev/null +++ b/board/synopsys/axs101/axs101.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dwmmc.h> +#include <malloc.h> +#include <netdev.h> +#include <phy.h> + +DECLARE_GLOBAL_DATA_PTR; + +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 *)ARC_DWMMC_BASE; + host->buswidth = 4; + host->dev_index = 0; + host->bus_hz = 25000000; + + add_dwmci(host, 52000000, 400000); + + return 0; +} + +int board_eth_init(bd_t *bis) +{ + if (designware_initialize(0, ARC_DWGMAC_BASE, 0, + PHY_INTERFACE_MODE_RGMII) >= 0) + return 1; + + return 0; +} diff --git a/board/synopsys/axs101/nand.c b/board/synopsys/axs101/nand.c new file mode 100644 index 0000000..8672803 --- /dev/null +++ b/board/synopsys/axs101/nand.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <bouncebuf.h> +#include <common.h> +#include <malloc.h> +#include <nand.h> +#include <asm/io.h> + +#define BUS_WIDTH 8 /* AXI data bus width in bytes */ + +/* DMA buffer descriptor bits & masks */ +#define BD_STAT_OWN (1 << 31) +#define BD_STAT_BD_FIRST (1 << 3) +#define BD_STAT_BD_LAST (1 << 2) +#define BD_SIZES_BUFFER1_MASK 0xfff + +#define BD_STAT_BD_COMPLETE (BD_STAT_BD_FIRST | BD_STAT_BD_LAST) + +/* Controller command flags */ +#define B_WFR (1 << 19) /* 1b - Wait for ready */ +#define B_LC (1 << 18) /* 1b - Last cycle */ +#define B_IWC (1 << 13) /* 1b - Interrupt when complete */ + +/* NAND cycle types */ +#define B_CT_ADDRESS (0x0 << 16) /* Address operation */ +#define B_CT_COMMAND (0x1 << 16) /* Command operation */ +#define B_CT_WRITE (0x2 << 16) /* Write operation */ +#define B_CT_READ (0x3 << 16) /* Write operation */ + +enum nand_isr_t { + NAND_ISR_DATAREQUIRED = 0, + NAND_ISR_TXUNDERFLOW, + NAND_ISR_TXOVERFLOW, + NAND_ISR_DATAAVAILABLE, + NAND_ISR_RXUNDERFLOW, + NAND_ISR_RXOVERFLOW, + NAND_ISR_TXDMACOMPLETE, + NAND_ISR_RXDMACOMPLETE, + NAND_ISR_DESCRIPTORUNAVAILABLE, + NAND_ISR_CMDDONE, + NAND_ISR_CMDAVAILABLE, + NAND_ISR_CMDERROR, + NAND_ISR_DATATRANSFEROVER, + NAND_ISR_NONE +}; + +enum nand_regs_t { + AC_FIFO = 0, /* address and command fifo */ + IDMAC_BDADDR = 0x18, /* idmac descriptor list base address */ + INT_STATUS = 0x118, /* interrupt status register */ + INT_CLR_STATUS = 0x120, /* interrupt clear status register */ +}; + +struct nand_bd { + uint32_t status; /* DES0 */ + uint32_t sizes; /* DES1 */ + uint32_t buffer_ptr0; /* DES2 */ + uint32_t buffer_ptr1; /* DES3 */ +}; + +#define NAND_REG_WRITE(r, v) writel(v, CONFIG_SYS_NAND_BASE + r) +#define NAND_REG_READ(r) readl(CONFIG_SYS_NAND_BASE + r) + +static struct nand_bd *bd; /* DMA buffer descriptors */ + +/** + * axs101_nand_write_buf - write buffer to chip + * @mtd: MTD device structure + * @buf: data buffer + * @len: number of bytes to write + */ +static uint32_t nand_flag_is_set(uint32_t flag) +{ + uint32_t reg = NAND_REG_READ(INT_STATUS); + + if (reg & (1 << NAND_ISR_CMDERROR)) + return 0; + + if (reg & (1 << flag)) { + NAND_REG_WRITE(INT_CLR_STATUS, 1 << flag); + return 1; + } + + return 0; +} + +/** + * axs101_nand_write_buf - write buffer to chip + * @mtd: MTD device structure + * @buf: data buffer + * @len: number of bytes to write + */ +static void axs101_nand_write_buf(struct mtd_info *mtd, const u_char *buf, + int len) +{ + struct bounce_buffer bbstate; + + bounce_buffer_start(&bbstate, (void *)buf, len, GEN_BB_READ); + + /* Setup buffer descriptor */ + writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status); + writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes); + writel(bbstate.bounce_buffer, &bd->buffer_ptr0); + writel(0, &bd->buffer_ptr1); + + /* Issue "write" command */ + NAND_REG_WRITE(AC_FIFO, B_CT_WRITE | B_WFR | B_IWC | B_LC | (len-1)); + + /* Wait for NAND command and DMA to complete */ + while (!nand_flag_is_set(NAND_ISR_CMDDONE)) + ; + while (!nand_flag_is_set(NAND_ISR_TXDMACOMPLETE)) + ; + + bounce_buffer_stop(&bbstate); +} + +/** + * axs101_nand_read_buf - read chip data into buffer + * @mtd: MTD device structure + * @buf: buffer to store data + * @len: number of bytes to read + */ +static void axs101_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + struct bounce_buffer bbstate; + + bounce_buffer_start(&bbstate, buf, len, GEN_BB_WRITE); + + /* Setup buffer descriptor */ + writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status); + writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes); + writel(bbstate.bounce_buffer, &bd->buffer_ptr0); + writel(0, &bd->buffer_ptr1); + + /* Issue "read" command */ + NAND_REG_WRITE(AC_FIFO, B_CT_READ | B_WFR | B_IWC | B_LC | (len - 1)); + + /* Wait for NAND command and DMA to complete */ + while (!nand_flag_is_set(NAND_ISR_CMDDONE)) + ; + while (!nand_flag_is_set(NAND_ISR_RXDMACOMPLETE)) + ; + + bounce_buffer_stop(&bbstate); +} + +/** + * axs101_nand_read_byte - read one byte from the chip + * @mtd: MTD device structure + */ +static u_char axs101_nand_read_byte(struct mtd_info *mtd) +{ + u8 byte; + + axs101_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte)); + return byte; +} + +/** + * axs101_nand_read_word - read one word from the chip + * @mtd: MTD device structure + */ +static u16 axs101_nand_read_word(struct mtd_info *mtd) +{ + u16 word; + + axs101_nand_read_buf(mtd, (uchar *)&word, sizeof(word)); + return word; +} + +/** + * axs101_nand_hwcontrol - NAND control functions wrapper. + * @mtd: MTD device structure + * @cmd: Command + */ +static void axs101_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, + unsigned int ctrl) +{ + if (cmd == NAND_CMD_NONE) + return; + + cmd = cmd & 0xff; + + switch (ctrl & (NAND_ALE | NAND_CLE)) { + /* Address */ + case NAND_ALE: + cmd |= B_CT_ADDRESS; + break; + + /* Command */ + case NAND_CLE: + cmd |= B_CT_COMMAND | B_WFR; + + break; + + default: + debug("%s: unknown ctrl %#x\n", __func__, ctrl); + } + + NAND_REG_WRITE(AC_FIFO, cmd | B_LC); + while (!nand_flag_is_set(NAND_ISR_CMDDONE)) + ; +} + +int board_nand_init(struct nand_chip *nand) +{ + bd = (struct nand_bd *)memalign(ARCH_DMA_MINALIGN, + sizeof(struct nand_bd)); + + /* Set buffer descriptor address in IDMAC */ + NAND_REG_WRITE(IDMAC_BDADDR, bd); + + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = axs101_nand_hwcontrol; + nand->read_byte = axs101_nand_read_byte; + nand->read_word = axs101_nand_read_word; + nand->write_buf = axs101_nand_write_buf; + nand->read_buf = axs101_nand_read_buf; + + return 0; +} diff --git a/boards.cfg b/boards.cfg index a873aaa..6fbc6b0 100644 --- a/boards.cfg +++ b/boards.cfg @@ -1229,6 +1229,7 @@ Active sparc leon3 - gaisler - Active sparc leon3 - gaisler - gr_xc3s_1500 - - Active sparc leon3 - gaisler - grsim - - Active x86 x86 coreboot chromebook-x86 coreboot coreboot-x86 coreboot:SYS_TEXT_BASE=0x01110000 - +Active arc arc700 - synopsys - axs101 - Alexey Brodkin abrodkin@synopsys.com Active arc arc700 - synopsys - arcangel4 - Alexey Brodkin abrodkin@synopsys.com Active arc arc700 - synopsys arcangel4 arcangel4-be - Alexey Brodkin abrodkin@synopsys.com Orphan arm arm1136 mx31 - imx31_phycore imx31_phycore_eet imx31_phycore:IMX31_PHYCORE_EET (resigned) Guennadi Liakhovetski g.liakhovetski@gmx.de diff --git a/include/configs/axs101.h b/include/configs/axs101.h new file mode 100644 index 0000000..159d4cf --- /dev/null +++ b/include/configs/axs101.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_AXS101_H_ +#define _CONFIG_AXS101_H_ + +/* + * CPU configuration + */ +#define CONFIG_ARC700 +#define CONFIG_ARC_MMU_VER 3 +#define CONFIG_SYS_CACHELINE_SIZE 32 +#define CONFIG_SYS_CLK_FREQ 750000000 +#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ + +/* dwgmac doesn't work with D$ enabled now */ +#define CONFIG_SYS_DCACHE_OFF + +/* + * Board configuration + */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ + +#define CONFIG_ARCH_EARLY_INIT_R + +#define ARC_FPGA_PERIPHERAL_BASE 0xE0000000 +#define ARC_APB_PERIPHERAL_BASE 0xF0000000 +#define ARC_DWMMC_BASE (ARC_FPGA_PERIPHERAL_BASE + 0x15000) +#define ARC_DWGMAC_BASE (ARC_FPGA_PERIPHERAL_BASE + 0x18000) + +/* + * Memory configuration + */ +#define CONFIG_SYS_TEXT_BASE 0x81000000 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_SYS_SDRAM_SIZE 0x10000000 /* 256 Mb */ + +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234) + +#define CONFIG_SYS_MALLOC_LEN 0x200000 /* 2 MB */ +#define CONFIG_SYS_BOOTM_LEN 0x2000000 /* 32 MB */ +#define CONFIG_SYS_LOAD_ADDR 0x82000000 + +/* + * NAND Flash configuration + */ +#define CONFIG_SYS_NO_FLASH +#define CONFIG_SYS_NAND_BASE (ARC_FPGA_PERIPHERAL_BASE + 0x16000) +#define CONFIG_SYS_MAX_NAND_DEVICE 1 + +/* + * UART configuration + * + * CONFIG_CONS_INDEX = 1 - Debug UART + * CONFIG_CONS_INDEX = 4 - FPGA UART connected to FTDI/USB + */ +#define CONFIG_CONS_INDEX 4 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE -4 +#if (CONFIG_CONS_INDEX == 1) + /* Debug UART */ +# define CONFIG_SYS_NS16550_CLK 33333000 +#else + /* FPGA UARTs use different clock */ +# define CONFIG_SYS_NS16550_CLK 33333333 +#endif +#define CONFIG_SYS_NS16550_COM1 (ARC_APB_PERIPHERAL_BASE + 0x5000) +#define CONFIG_SYS_NS16550_COM2 (ARC_FPGA_PERIPHERAL_BASE + 0x20000) +#define CONFIG_SYS_NS16550_COM3 (ARC_FPGA_PERIPHERAL_BASE + 0x21000) +#define CONFIG_SYS_NS16550_COM4 (ARC_FPGA_PERIPHERAL_BASE + 0x22000) +#define CONFIG_SYS_NS16550_MEM32 + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200} + +/* + * I2C configuration + */ +#define CONFIG_HARD_I2C 1 +#define CONFIG_DW_I2C 1 +#define CONFIG_I2C_ENV_EEPROM_BUS 2 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0 +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_SYS_I2C_BASE 0xE001D000 +#define CONFIG_SYS_I2C_BASE1 0xE001E000 +#define CONFIG_SYS_I2C_BASE2 0xE001F000 +#define CONFIG_SYS_I2C_BUS_MAX 3 +#define IC_CLK 50 + +/* + * EEPROM configuration + */ +#define CONFIG_SYS_I2C_EEPROM_ADDR (0xA8 >> 1) +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW 1 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 32 +#define CONFIG_SYS_I2C_MULTI_EEPROMS 1 + +/* + * SD/MMC configuration + */ +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_DWMMC +#define CONFIG_DOS_PARTITION + +/* + * Ethernet PHY configuration + */ +#define CONFIG_PHYLIB +#define CONFIG_MII +#define CONFIG_PHY_GIGE + +/* + * Ethernet configuration + */ +#define CONFIG_DESIGNWARE_ETH +#define CONFIG_DW_AUTONEG +#define CONFIG_DW_SEARCH_PHY +#define CONFIG_NET_MULTI + +/* + * Command line configuration + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_ELF +#define CONFIG_CMD_FAT +#define CONFIG_CMD_I2C +#define CONFIG_CMD_MMC +#define CONFIG_CMD_NAND +#define CONFIG_CMD_PING +#define CONFIG_CMD_RARP + +#define CONFIG_OF_LIBFDT + +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_MAXARGS 16 + +/* + * Environment settings + */ +#define CONFIG_ENV_IS_IN_EEPROM +#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ +#define CONFIG_ENV_OFFSET 0 + +/* + * Environment configuration + */ +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_BOOTARGS "console=ttyS3,115200n8" +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR + +/* + * Console configuration + */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT "axs101# " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +/* + * Misc utility configuration + */ +#define CONFIG_BOUNCE_BUFFER + +#endif /* _CONFIG_AXS101_H_ */

Dear Alexey,
In message 1391445368-10545-8-git-send-email-abrodkin@synopsys.com you wrote:
AXS101 is a new generation of devlopment boards from Synopsys that houses ASIC with ARC700 and lots of DesignWare peripherals:
...
+#define CONFIG_SYS_MEMTEST_START (CONFIG_SYS_SDRAM_BASE + 0x200) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1234)
...
+#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
See before.
+/*
- I2C configuration
- */
+#define CONFIG_HARD_I2C 1 +#define CONFIG_DW_I2C 1
...
+#define CONFIG_I2C_MULTI_BUS 1
...
Please do not define values for logical variables [please check everywhere].
+#define CONFIG_SYS_MAXARGS 16
You define this pretty much inconsistentlyu across your boards. Is this intentionally?
+/*
- Environment settings
- */
+#define CONFIG_ENV_IS_IN_EEPROM +#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ +#define CONFIG_ENV_OFFSET 0
Uh, oh. Environment in EEPROM is about the worst thing you can do. You should reconsider this design decision.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Mon, 2014-02-03 at 20:19 +0100, Wolfgang Denk wrote:
+/*
- I2C configuration
- */
+#define CONFIG_HARD_I2C 1 +#define CONFIG_DW_I2C 1
...
+#define CONFIG_I2C_MULTI_BUS 1
...
Please do not define values for logical variables [please check everywhere].
Oops, those slipped from my attention. Thanks for pointing out.
+#define CONFIG_SYS_MAXARGS 16
You define this pretty much inconsistentlyu across your boards. Is this intentionally?
Not clear what do you mean. All 3 boards have CONFIG_SYS_MAXARGS = 16.
+/*
- Environment settings
- */
+#define CONFIG_ENV_IS_IN_EEPROM +#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ +#define CONFIG_ENV_OFFSET 0
Uh, oh. Environment in EEPROM is about the worst thing you can do. You should reconsider this design decision.
Well I may agree on this point. But due to the fact that Linux driver is still not ready for our custom NAND controller we don't rely on NAND for whatever storage. And then the only persistent storage that remains is I2C EEPROM.
Regards, Alexey

Dear Alexey,
In message 1391457382.2357.46.camel@abrodkin-8560l.internal.synopsys.com you wrote:
+#define CONFIG_SYS_MAXARGS 16
You define this pretty much inconsistentlyu across your boards. Is this intentionally?
Not clear what do you mean. All 3 boards have CONFIG_SYS_MAXARGS = 16.
Indeed. Sorry, it seems I mixed this up with a patch for a broadcom board which had 64.
Uh, oh. Environment in EEPROM is about the worst thing you can do. You should reconsider this design decision.
Well I may agree on this point. But due to the fact that Linux driver is still not ready for our custom NAND controller we don't rely on NAND for whatever storage. And then the only persistent storage that remains is I2C EEPROM.
I see. Except that I would hesitate to use "I2C EEPROM" and "persistent" in the same sentence ;-)
Best regards,
Wolfgang Denk

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- No changes for v3.
MAKEALL | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/MAKEALL b/MAKEALL index 562071a..54b0d89 100755 --- a/MAKEALL +++ b/MAKEALL @@ -529,6 +529,12 @@ LIST_sparc="$(targets_by_arch sparc)"
LIST_nds32="$(targets_by_arch nds32)"
+######################################################################### +## ARC Systems +######################################################################### + +LIST_arc="$(targets_by_arch arc)" + #-----------------------------------------------------------------------
get_target_location() {

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Vineet Gupta vgupta@synopsys.com Cc: Francois Bedard fbedard@synopsys.com Cc: Wolfgang Denk wd@denx.de Cc: Heiko Schocher hs@denx.de --- No changes for v3.
doc/README.ARC | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 doc/README.ARC
diff --git a/doc/README.ARC b/doc/README.ARC new file mode 100644 index 0000000..5f414fb --- /dev/null +++ b/doc/README.ARC @@ -0,0 +1,27 @@ +Synopsys' DesignWare(r) ARC(r) Processors are a family of 32-bit CPUs +that SoC designers can optimize for a wide range of uses, from deeply embedded +to high-performance host applications. + +More information on ARC cores avaialble here: +http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/Pages/default.aspx + +Designers can differentiate their products by using patented configuration +technology to tailor each ARC processor instance to meet specific performance, +power and area requirements. + +The DesignWare ARC processors are also extendable, allowing designers to add +their own custom instructions that dramatically increase performance. + +Synopsys' ARC processors have been used by over 170 customers worldwide who +collectively ship more than 1 billion ARC-based chips annually. + +All DesignWare ARC processors utilize a 16-/32-bit ISA that provides excellent +performance and code density for embedded and host SoC applications. + +The RISC microprocessors are synthesizable and can be implemented in any foundry +or process, and are supported by a complete suite of development tools. + +The ARC GNU toolchain with support for all ARC Processors can be downloaded +from here (available pre-built toolchains as well): + +https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases
participants (2)
-
Alexey Brodkin
-
Wolfgang Denk