[U-Boot] [PATCH 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-v1' 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...
Alexey Brodkin (9): arc: add architecture header files arc: add cpu files arc: add library functions arc: bdinfo and image 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 | 161 ++++++++++++++ arch/arc/cpu/arc700/config.mk | 7 + arch/arc/cpu/arc700/cpu.c | 37 ++++ arch/arc/cpu/arc700/interrupts.c | 211 ++++++++++++++++++ arch/arc/cpu/arc700/reset.c | 19 ++ arch/arc/cpu/arc700/start.S | 262 ++++++++++++++++++++++ arch/arc/cpu/arc700/timer.c | 28 +++ arch/arc/cpu/arc700/u-boot.lds | 72 +++++++ arch/arc/include/asm/arch-arc700/hardware.h | 0 arch/arc/include/asm/arcregs.h | 324 ++++++++++++++++++++++++++++ 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 | 287 ++++++++++++++++++++++++ arch/arc/include/asm/posix_types.h | 73 +++++++ arch/arc/include/asm/processor.h | 0 arch/arc/include/asm/ptrace.h | 101 +++++++++ arch/arc/include/asm/sections.h | 1 + arch/arc/include/asm/string.h | 0 arch/arc/include/asm/types.h | 55 +++++ arch/arc/include/asm/u-boot.h | 15 ++ arch/arc/include/asm/unaligned.h | 1 + arch/arc/lib/Makefile | 9 + arch/arc/lib/bootm.c | 106 +++++++++ arch/arc/lib/relocate.c | 74 +++++++ arch/arc/lib/sections.c | 21 ++ board/synopsys/arcangel4/Makefile | 7 + board/synopsys/arcangel4/arcangel4.c | 25 +++ board/synopsys/axs101/Makefile | 8 + board/synopsys/axs101/axs101.c | 61 ++++++ board/synopsys/axs101/nand.c | 224 +++++++++++++++++++ boards.cfg | 2 + common/cmd_bdinfo.c | 18 ++ common/image.c | 1 + doc/README.ARC | 27 +++ examples/standalone/stubs.c | 13 ++ include/configs/arcangel4.h | 96 +++++++++ include/configs/axs101.h | 194 +++++++++++++++++ include/image.h | 1 + 45 files changed, 2688 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/processor.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.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/relocate.c create mode 100644 arch/arc/lib/sections.c create mode 100644 board/synopsys/arcangel4/Makefile create mode 100644 board/synopsys/arcangel4/arcangel4.c 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.h create mode 100644 include/configs/axs101.h

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- arch/arc/include/asm/arch-arc700/hardware.h | 0 arch/arc/include/asm/arcregs.h | 324 ++++++++++++++++++++++++++++ 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 | 287 ++++++++++++++++++++++++ arch/arc/include/asm/posix_types.h | 73 +++++++ arch/arc/include/asm/processor.h | 0 arch/arc/include/asm/ptrace.h | 101 +++++++++ arch/arc/include/asm/sections.h | 1 + arch/arc/include/asm/string.h | 0 arch/arc/include/asm/types.h | 55 +++++ arch/arc/include/asm/u-boot.h | 15 ++ arch/arc/include/asm/unaligned.h | 1 + 17 files changed, 954 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/processor.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.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..e69de29 diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..87b0a60 --- /dev/null +++ b/arch/arc/include/asm/arcregs.h @@ -0,0 +1,324 @@ +/* + * 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 + +#ifdef __KERNEL__ + +/* Build Configuration Registers */ +#define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ +#define ARC_REG_CRC_BCR 0x62 +#define ARC_REG_DVFB_BCR 0x64 +#define ARC_REG_EXTARITH_BCR 0x65 +#define ARC_REG_VECBASE_BCR 0x68 +#define ARC_REG_PERIBASE_BCR 0x69 +#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ +#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ +#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ +#define ARC_REG_TIMERS_BCR 0x75 +#define ARC_REG_ICCM_BCR 0x78 +#define ARC_REG_XY_MEM_BCR 0x79 +#define ARC_REG_MAC_BCR 0x7a +#define ARC_REG_MUL_BCR 0x7b +#define ARC_REG_SWAP_BCR 0x7c +#define ARC_REG_NORM_BCR 0x7d +#define ARC_REG_MIXMAX_BCR 0x7e +#define ARC_REG_BARREL_BCR 0x7f +#define ARC_REG_D_UNCACH_BCR 0x6A + +/* status32 Bits Positions */ +#define STATUS_AE_BIT 5 /* Exception active */ +#define STATUS_DE_BIT 6 /* PC is in delay slot */ +#define STATUS_U_BIT 7 /* User/Kernel mode */ +#define STATUS_L_BIT 12 /* Loop inhibit */ + +/* These masks correspond to the status word(STATUS_32) bits */ +#define STATUS_AE_MASK (1<<STATUS_AE_BIT) +#define STATUS_DE_MASK (1<<STATUS_DE_BIT) +#define STATUS_U_MASK (1<<STATUS_U_BIT) +#define STATUS_L_MASK (1<<STATUS_L_BIT) + +/* + * ECR: Exception Cause Reg bits-n-pieces + * [23:16] = Exception Vector + * [15: 8] = Exception Cause Code + * [ 7: 0] = Exception Parameters (for certain types only) + */ +#define ECR_VEC_MASK 0xff0000 +#define ECR_CODE_MASK 0x00ff00 +#define ECR_PARAM_MASK 0x0000ff + +/* Exception Cause Vector Values */ +#define ECR_V_INSN_ERR 0x02 +#define ECR_V_MACH_CHK 0x20 +#define ECR_V_ITLB_MISS 0x21 +#define ECR_V_DTLB_MISS 0x22 +#define ECR_V_PROTV 0x23 +#define ECR_V_TRAP 0x25 + +/* Protection Violation Exception Cause Code Values */ +#define ECR_C_PROTV_INST_FETCH 0x00 +#define ECR_C_PROTV_LOAD 0x01 +#define ECR_C_PROTV_STORE 0x02 +#define ECR_C_PROTV_XCHG 0x03 +#define ECR_C_PROTV_MISALIG_DATA 0x04 + +#define ECR_C_BIT_PROTV_MISALIG_DATA 10 + +/* Machine Check Cause Code Values */ +#define ECR_C_MCHK_DUP_TLB 0x01 + +/* DTLB Miss Exception Cause Code Values */ +#define ECR_C_BIT_DTLB_LD_MISS 8 +#define ECR_C_BIT_DTLB_ST_MISS 9 + +/* Dummy ECR values for Interrupts */ +#define event_IRQ1 0x0031abcd +#define event_IRQ2 0x0032abcd + +/* Auxiliary registers */ +#define AUX_IDENTITY 4 +#define AUX_INTR_VEC_BASE 0x25 + + +/* + * Floating Pt Registers + * Status regs are read-only (build-time) so need not be saved/restored + */ +#define ARC_AUX_FP_STAT 0x300 +#define ARC_AUX_DPFP_1L 0x301 +#define ARC_AUX_DPFP_1H 0x302 +#define ARC_AUX_DPFP_2L 0x303 +#define ARC_AUX_DPFP_2H 0x304 +#define ARC_AUX_DPFP_STAT 0x305 + +#ifndef __ASSEMBLY__ + +/* + ****************************************************************** + * Inline ASM macros to read/write AUX Regs + * Essentially invocation of lr/sr insns from "C" + */ + +#if 1 + +#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) + +#else + +#define read_aux_reg(reg) \ +({ \ + unsigned int __ret; \ + __asm__ __volatile__( \ + " lr %0, [%1]" \ + : "=r"(__ret) \ + : "i"(reg)); \ + __ret; \ +}) + +/* + * Aux Reg address is specified as long immediate by caller + * e.g. + * write_aux_reg(0x69, some_val); + * This generates tightest code. + */ +#define write_aux_reg(reg_imm, val) \ +({ \ + __asm__ __volatile__( \ + " sr %0, [%1]\n" \ + : \ + : "ir"(val), "i"(reg_imm)); \ +}) + +/* + * Aux Reg address is specified in a variable + * * e.g. + * reg_num = 0x69 + * write_aux_reg2(reg_num, some_val); + * This has to generate glue code to load the reg num from + * memory to a reg hence not recommended. + */ +#define write_aux_reg2(reg_in_var, val) \ +({ \ + unsigned int tmp; \ + \ + __asm__ __volatile__( \ + " ld %0, [%2]\n\t" \ + " sr %1, [%0]\n\t" \ + : "=&r"(tmp) \ + : "r"(val), "memory"(®_in_var)); \ +}) + +#endif + +#define READ_BCR(reg, into) \ +{ \ + unsigned int tmp; \ + tmp = read_aux_reg(reg); \ + if (sizeof(tmp) == sizeof(into)) { \ + into = *((typeof(into) *)&tmp); \ + } else { \ + extern void bogus_undefined(void); \ + bogus_undefined(); \ + } \ +} + +#define WRITE_BCR(reg, into) \ +{ \ + unsigned int tmp; \ + if (sizeof(tmp) == sizeof(into)) { \ + tmp = (*(unsigned int *)(into)); \ + write_aux_reg(reg, tmp); \ + } else { \ + extern void bogus_undefined(void); \ + bogus_undefined(); \ + } \ +} + +/* Helpers */ +#define TO_KB(bytes) ((bytes) >> 10) +#define TO_MB(bytes) (TO_KB(bytes) >> 10) +#define PAGES_TO_KB(n_pages) ((n_pages) << (PAGE_SHIFT - 10)) +#define PAGES_TO_MB(n_pages) (PAGES_TO_KB(n_pages) >> 10) + +#ifdef CONFIG_ARC_FPU_SAVE_RESTORE +/* These DPFP regs need to be saved/restored across ctx-sw */ +struct arc_fpu { + struct { + unsigned int l, h; + } aux_dpfp[2]; +}; +#endif + +/* + *************************************************************** + * Build Configuration Registers, with encoded hardware config + */ +struct bcr_identity { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int chip_id:16, cpu_id:8, family:8; +#else + unsigned int family:8, cpu_id:8, chip_id:16; +#endif +}; + +#define EXTN_SWAP_VALID 0x1 +#define EXTN_NORM_VALID 0x2 +#define EXTN_MINMAX_VALID 0x2 +#define EXTN_BARREL_VALID 0x2 + +struct bcr_extn { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2, + norm:2, swap:1; +#else + unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2, + crc:1, pad:20; +#endif +}; + +/* DSP Options Ref Manual */ +struct bcr_extn_mac_mul { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int pad:16, type:8, ver:8; +#else + unsigned int ver:8, type:8, pad:16; +#endif +}; + +struct bcr_extn_xymem { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int ram_org:2, num_banks:4, bank_sz:4, ver:8; +#else + unsigned int ver:8, bank_sz:4, num_banks:4, ram_org:2; +#endif +}; + +struct bcr_perip { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int start:8, pad2:8, sz:8, pad:8; +#else + unsigned int pad:8, sz:8, pad2:8, start:8; +#endif +}; +struct bcr_iccm { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int base:16, pad:5, sz:3, ver:8; +#else + unsigned int ver:8, sz:3, pad:5, base:16; +#endif +}; + +/* DCCM Base Address Register: ARC_REG_DCCMBASE_BCR */ +struct bcr_dccm_base { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int addr:24, ver:8; +#else + unsigned int ver:8, addr:24; +#endif +}; + +/* DCCM RAM Configuration Register: ARC_REG_DCCM_BCR */ +struct bcr_dccm { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int res:21, sz:3, ver:8; +#else + unsigned int ver:8, sz:3, res:21; +#endif +}; + +/* Both SP and DP FPU BCRs have same format */ +struct bcr_fp { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned int fast:1, ver:8; +#else + unsigned int ver:8, fast:1; +#endif +}; + +/* + ******************************************************************* + * Generic structures to hold build configuration used at runtime + */ + +struct cpuinfo_arc_mmu { + unsigned int ver, pg_sz, sets, ways, u_dtlb, u_itlb, num_tlb; +}; + +struct cpuinfo_arc_cache { + unsigned int sz, line_len, assoc, ver; +}; + +struct cpuinfo_arc_ccm { + unsigned int base_addr, sz; +}; + +struct cpuinfo_arc { + struct cpuinfo_arc_cache icache, dcache; + struct cpuinfo_arc_mmu mmu; + struct bcr_identity core; + unsigned int timers; + unsigned int vec_base; + unsigned int uncached_base; + struct cpuinfo_arc_ccm iccm, dccm; + struct bcr_extn extn; + struct bcr_extn_xymem extn_xymem; + struct bcr_extn_mac_mul extn_mac_mul; + struct bcr_fp fp, dpfp; +}; + +extern struct cpuinfo_arc cpuinfo_arc700[]; + +#endif /* __ASEMBLY__ */ + +#endif /* __KERNEL__ */ + +#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..9057624 --- /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(__STRICT_ANSI__) || defined(__KERNEL__) + #define __BYTEORDER_HAS_U64__ + #define __SWAB_64_THRU_32__ +#endif + +#ifndef CONFIG_SYS_BIG_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..b7facc1 --- /dev/null +++ b/arch/arc/include/asm/io.h @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/types.h> + +#ifndef __ASM_ARC_IO_H +#define __ASM_ARC_IO_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/byteorder.h> + +static inline void sync(void) +{ + /* Not yet implemented */ +} + +#define IO_WRITE32(val, addr) ({__asm__ __volatile__ ("st.di %0,[%1]" : : \ + "r" ((val)) , "r" ((addr))); }) + +#define IO_READ32(addr) ({unsigned int val = 0; __asm__ __volatile__ \ + ("ld.di %0,[%1]" : "=&r" ((val)) : "r" ((addr))); val; }) + +#define IO_WRITE8(val, addr) ({__asm__ __volatile__ ("stb.di %0,[%1]" : : \ + "r" ((val)), "r" ((addr))); }) + +#define IO_READ8(addr) ({unsigned int val = 0; __asm__ __volatile__ \ + ("ldb.di %0,[%1]" : "=&r" ((val)) : "r" ((addr))); val; }) + +#define writeb(val, addr) ({ __asm__ __volatile__ ("stb.di %0,[%1]" : :\ + "r" ((val)), "r" ((addr))); }) + +#define writew(val, addr) ({ __asm__ __volatile__ ("stw.di %0,[%1]" : :\ + "r" ((val)), "r" ((addr))); }) + +#define writel(val, addr) ({ __asm__ __volatile__ ("st.di %0,[%1]" : :\ + "r" ((val)), "r" ((addr))); }) + +#define readb(addr) ({unsigned int val = 0; __asm__ __volatile__ \ + ("ldb.di %0,[%1]" : "=&r" ((val)) : "r" ((addr))); val; }) + +#define readw(addr) ({unsigned int val = 0; __asm__ __volatile__ \ + ("ldw.di %0,[%1]" : "=&r" ((val)) : "r" ((addr))); val; }) + +#define readl(addr) ({unsigned int val = 0; __asm__ __volatile__ \ + ("ld.di %0,[%1]" : "=&r" ((val)) : "r"((addr))); val; }) + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +/* These can't be used, because they don't make any sense like this - PS */ +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) + +#define __io(a) (a) +#define __mem_pci(a) ((unsigned long)(a)) +#define __mem_isa(a) ((unsigned long)(a)) + +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; +} + +/* + * Generic virtual read/write + */ +#define iomem_valid_addr(iomem, sz) (1) +#define iomem_to_phys(iomem) (iomem) + +#ifdef __io +#define outb(v, p) __raw_writeb(v, __io(p)) +#define outw(v, p) __raw_writew(cpu_to_le16(v), __io(p)) +#define outl(v, p) __raw_writel(cpu_to_le32(v), __io(p)) + +#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) +#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) +#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) + +#define outsb(p, d, l) __raw_writesb(__io(p), d, l) +#define outsw(p, d, l) __raw_writesw(__io(p), d, l) +#define outsl(p, d, l) __raw_writesl(__io(p), d, l) + +#define insb(p, d, l) __raw_readsb(__io(p), d, l) +#define insw(p, d, l) __raw_readsw(__io(p), d, l) +#define insl(p, d, l) __raw_readsl(__io(p), d, l) +#endif + +#define outb_p(val, port) outb((val), (port)) +#define outw_p(val, port) outw((val), (port)) +#define outl_p(val, port) outl((val), (port)) + +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) + +#define outsb_p(port, from, len) outsb(port, from, len) +#define outsw_p(port, from, len) outsw(port, from, len) +#define outsl_p(port, from, len) outsl(port, from, len) + +#define insb_p(port, to, len) insb(port, to, len) +#define insw_p(port, to, len) insw(port, to, len) +#define insl_p(port, to, len) insl(port, to, len) + +/* + * 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 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) + +#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) + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ +} + +extern void *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag); +extern void *ioremap(unsigned long physaddr, unsigned long size); +extern void *ioremap_nocache(unsigned long physaddr, unsigned long size); +extern void __iounmap(void *addr, unsigned long size); +extern void iounmap(void *addr); + +/* + * IO bus memory addresses are also 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + + +/* Written to pacify arch indepeandant code. + * Not used by ARC I/O + */ +#define _inb inb +#define _outb outb + +#define IO_SPACE_LIMIT 0xffff + +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +#endif /* __KERNEL__ */ +#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..9c5667b --- /dev/null +++ b/arch/arc/include/asm/posix_types.h @@ -0,0 +1,73 @@ +/* + * 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 + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +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 + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp))) + +#endif + +#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h new file mode 100644 index 0000000..e69de29 diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..3b2df87 --- /dev/null +++ b/arch/arc/include/asm/ptrace.h @@ -0,0 +1,101 @@ +/* + * 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 + +#ifndef __ASSEMBLY__ + +/* THE pt_regs: Defines how regs are saved during entry into kernel */ + +struct pt_regs { + /* Real registers */ + long bta; /* bta_l1, bta_l2, erbta */ + + long lp_start, lp_end, lp_count; + + long status32; /* status32_l1, status32_l2, erstatus */ + long ret; /* ilink1, ilink2 or eret */ + long blink; + long fp; + long r26; /* gp */ + + long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; + + long sp; /* user/kernel sp depending on where we came from */ + long orig_r0; + + /* + * To distinguish bet excp, syscall, irq + * For traps and exceptions, Exception Cause Register. + * ECR: <00> <VV> <CC> <PP> + * Last word used by Linux for extra state mgmt (syscall-restart) + * For interrupts, use artificial ECR values to note current prio-level + */ + union { + struct { +#ifdef CONFIG_CPU_BIG_ENDIAN + unsigned long state:8, ecr_vec:8, + ecr_cause:8, ecr_param:8; +#else + unsigned long ecr_param:8, ecr_cause:8, + ecr_vec:8, state:8; +#endif + }; + unsigned long event; + }; + + long user_r25; +}; + +/* Callee saved registers - need to be saved only when you are scheduled out */ + +struct callee_regs { + long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13; +}; + +#define instruction_pointer(regs) ((regs)->ret) +#define profile_pc(regs) instruction_pointer(regs) + +/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32 & STATUS_U_MASK) + +#define user_stack_pointer(regs)\ +({ unsigned int sp; \ + if (user_mode(regs)) \ + sp = (regs)->sp;\ + else \ + sp = -1; \ + sp; \ +}) + +/* return 1 if PC in delay slot */ +#define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK) + +#define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param) +#define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param) + +#define STATE_SCALL_RESTARTED 0x01 + +#define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED) +#define syscall_restartable(reg) !(reg->state & STATE_SCALL_RESTARTED) + +#define current_pt_regs() \ +({ \ + /* open-coded current_thread_info() */ \ + register unsigned long sp asm ("sp"); \ + unsigned long pg_start = (sp & ~(THREAD_SIZE - 1)); \ + (struct pt_regs *)(pg_start + THREAD_SIZE) - 1; \ +}) + +static inline long regs_return_value(struct pt_regs *regs) +{ + return regs->r0; +} + +#endif /* !__ASSEMBLY__ */ + +#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..2b8c516 --- /dev/null +++ b/arch/arc/include/asm/sections.h @@ -0,0 +1 @@ +#include <asm-generic/sections.h> diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h new file mode 100644 index 0000000..e69de29 diff --git a/arch/arc/include/asm/types.h b/arch/arc/include/asm/types.h new file mode 100644 index 0000000..7475db1 --- /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.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>

Hello Alexey,
Thanks for your patches, more or less just nitpicking comments ...
Am 29.01.2014 00:09, schrieb Alexey Brodkin:
Signed-off-by: Alexey Brodkinabrodkin@synopsys.com
No commit message, please add one. (Are this files from the Linux kernel? If so please add a comment in the commit message + add a hint which linux commit you used, thanks!)
Cc: Mischa Jonkermjonker@synopsys.com Cc: Francois Bedardfbedard@synopsys.com
arch/arc/include/asm/arch-arc700/hardware.h | 0 arch/arc/include/asm/arcregs.h | 324 ++++++++++++++++++++++++++++ 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 | 287 ++++++++++++++++++++++++ arch/arc/include/asm/posix_types.h | 73 +++++++ arch/arc/include/asm/processor.h | 0 arch/arc/include/asm/ptrace.h | 101 +++++++++ arch/arc/include/asm/sections.h | 1 + arch/arc/include/asm/string.h | 0 arch/arc/include/asm/types.h | 55 +++++ arch/arc/include/asm/u-boot.h | 15 ++ arch/arc/include/asm/unaligned.h | 1 + 17 files changed, 954 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/processor.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.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..e69de29
Empty file ?
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..87b0a60 --- /dev/null +++ b/arch/arc/include/asm/arcregs.h @@ -0,0 +1,324 @@ +/*
- 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
+#ifdef __KERNEL__
+/* Build Configuration Registers */ +#define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ +#define ARC_REG_CRC_BCR 0x62 +#define ARC_REG_DVFB_BCR 0x64 +#define ARC_REG_EXTARITH_BCR 0x65 +#define ARC_REG_VECBASE_BCR 0x68 +#define ARC_REG_PERIBASE_BCR 0x69 +#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ +#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ +#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ +#define ARC_REG_TIMERS_BCR 0x75 +#define ARC_REG_ICCM_BCR 0x78 +#define ARC_REG_XY_MEM_BCR 0x79 +#define ARC_REG_MAC_BCR 0x7a +#define ARC_REG_MUL_BCR 0x7b +#define ARC_REG_SWAP_BCR 0x7c +#define ARC_REG_NORM_BCR 0x7d +#define ARC_REG_MIXMAX_BCR 0x7e +#define ARC_REG_BARREL_BCR 0x7f +#define ARC_REG_D_UNCACH_BCR 0x6A
+/* status32 Bits Positions */ +#define STATUS_AE_BIT 5 /* Exception active */ +#define STATUS_DE_BIT 6 /* PC is in delay slot */ +#define STATUS_U_BIT 7 /* User/Kernel mode */ +#define STATUS_L_BIT 12 /* Loop inhibit */
+/* These masks correspond to the status word(STATUS_32) bits */ +#define STATUS_AE_MASK (1<<STATUS_AE_BIT) +#define STATUS_DE_MASK (1<<STATUS_DE_BIT) +#define STATUS_U_MASK (1<<STATUS_U_BIT) +#define STATUS_L_MASK (1<<STATUS_L_BIT)
+/*
- ECR: Exception Cause Reg bits-n-pieces
- [23:16] = Exception Vector
- [15: 8] = Exception Cause Code
- [ 7: 0] = Exception Parameters (for certain types only)
- */
+#define ECR_VEC_MASK 0xff0000 +#define ECR_CODE_MASK 0x00ff00 +#define ECR_PARAM_MASK 0x0000ff
+/* Exception Cause Vector Values */ +#define ECR_V_INSN_ERR 0x02 +#define ECR_V_MACH_CHK 0x20 +#define ECR_V_ITLB_MISS 0x21 +#define ECR_V_DTLB_MISS 0x22 +#define ECR_V_PROTV 0x23 +#define ECR_V_TRAP 0x25
+/* Protection Violation Exception Cause Code Values */ +#define ECR_C_PROTV_INST_FETCH 0x00 +#define ECR_C_PROTV_LOAD 0x01 +#define ECR_C_PROTV_STORE 0x02 +#define ECR_C_PROTV_XCHG 0x03 +#define ECR_C_PROTV_MISALIG_DATA 0x04
+#define ECR_C_BIT_PROTV_MISALIG_DATA 10
+/* Machine Check Cause Code Values */ +#define ECR_C_MCHK_DUP_TLB 0x01
+/* DTLB Miss Exception Cause Code Values */ +#define ECR_C_BIT_DTLB_LD_MISS 8 +#define ECR_C_BIT_DTLB_ST_MISS 9
+/* Dummy ECR values for Interrupts */ +#define event_IRQ1 0x0031abcd +#define event_IRQ2 0x0032abcd
+/* Auxiliary registers */ +#define AUX_IDENTITY 4 +#define AUX_INTR_VEC_BASE 0x25
+/*
- Floating Pt Registers
- Status regs are read-only (build-time) so need not be saved/restored
- */
+#define ARC_AUX_FP_STAT 0x300 +#define ARC_AUX_DPFP_1L 0x301 +#define ARC_AUX_DPFP_1H 0x302 +#define ARC_AUX_DPFP_2L 0x303 +#define ARC_AUX_DPFP_2H 0x304 +#define ARC_AUX_DPFP_STAT 0x305
+#ifndef __ASSEMBLY__
+/*
Bad comment style
Inline ASM macros to read/write AUX Regs
Essentially invocation of lr/sr insns from "C"
- */
+#if 1
+#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)
+#else
Please remove dead code ...
+#define read_aux_reg(reg) \ +({ \
- unsigned int __ret; \
- __asm__ __volatile__( \
- " lr %0, [%1]" \
- : "=r"(__ret) \
- : "i"(reg)); \
- __ret; \
+})
+/*
- Aux Reg address is specified as long immediate by caller
- e.g.
- write_aux_reg(0x69, some_val);
- This generates tightest code.
- */
+#define write_aux_reg(reg_imm, val) \ +({ \
- __asm__ __volatile__( \
- " sr %0, [%1]\n" \
- : \
- : "ir"(val), "i"(reg_imm)); \
+})
+/*
- Aux Reg address is specified in a variable
- e.g.
reg_num = 0x69
write_aux_reg2(reg_num, some_val);
- This has to generate glue code to load the reg num from
- memory to a reg hence not recommended.
- */
+#define write_aux_reg2(reg_in_var, val) \ +({ \
- unsigned int tmp; \
\
- __asm__ __volatile__( \
- " ld %0, [%2]\n\t" \
- " sr %1, [%0]\n\t" \
- : "=&r"(tmp) \
- : "r"(val), "memory"(®_in_var)); \
+})
+#endif
+#define READ_BCR(reg, into) \ +{ \
- unsigned int tmp; \
- tmp = read_aux_reg(reg); \
- if (sizeof(tmp) == sizeof(into)) { \
into = *((typeof(into) *)&tmp); \
- } else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
- } \
+}
Why do you use defines here instead of real functions?
+#define WRITE_BCR(reg, into) \ +{ \
- unsigned int tmp; \
- if (sizeof(tmp) == sizeof(into)) { \
tmp = (*(unsigned int *)(into)); \
write_aux_reg(reg, tmp); \
- } else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
- } \
+}
and here?
+/* Helpers */ +#define TO_KB(bytes) ((bytes)>> 10) +#define TO_MB(bytes) (TO_KB(bytes)>> 10) +#define PAGES_TO_KB(n_pages) ((n_pages)<< (PAGE_SHIFT - 10)) +#define PAGES_TO_MB(n_pages) (PAGES_TO_KB(n_pages)>> 10)
[...]
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h new file mode 100644 index 0000000..e69de29
Hups, one more empty file ...
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..3b2df87 --- /dev/null +++ b/arch/arc/include/asm/ptrace.h @@ -0,0 +1,101 @@ +/*
- 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
+#ifndef __ASSEMBLY__
+/* THE pt_regs: Defines how regs are saved during entry into kernel */
Is the "THE" a shortcut?
+struct pt_regs {
- /* Real registers */
- long bta; /* bta_l1, bta_l2, erbta */
- long lp_start, lp_end, lp_count;
- long status32; /* status32_l1, status32_l2, erstatus */
- long ret; /* ilink1, ilink2 or eret */
- long blink;
- long fp;
- long r26; /* gp */
- long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
- long sp; /* user/kernel sp depending on where we came from */
- long orig_r0;
- /*
* To distinguish bet excp, syscall, irq
* For traps and exceptions, Exception Cause Register.
* ECR:<00> <VV> <CC> <PP>
* Last word used by Linux for extra state mgmt (syscall-restart)
* For interrupts, use artificial ECR values to note current prio-level
*/
- union {
struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned long state:8, ecr_vec:8,
ecr_cause:8, ecr_param:8;
+#else
unsigned long ecr_param:8, ecr_cause:8,
ecr_vec:8, state:8;
+#endif
};
unsigned long event;
- };
- long user_r25;
+};
+/* Callee saved registers - need to be saved only when you are scheduled out */
+struct callee_regs {
- long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13;
+};
+#define instruction_pointer(regs) ((regs)->ret) +#define profile_pc(regs) instruction_pointer(regs)
+/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32& STATUS_U_MASK)
+#define user_stack_pointer(regs)\ +({ unsigned int sp; \
- if (user_mode(regs)) \
sp = (regs)->sp;\
- else \
sp = -1; \
- sp; \
+})
+/* return 1 if PC in delay slot */ +#define delay_mode(regs) ((regs->status32& STATUS_DE_MASK) == STATUS_DE_MASK)
+#define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP)&& !regs->ecr_param) +#define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP)&& regs->ecr_param)
+#define STATE_SCALL_RESTARTED 0x01
+#define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED) +#define syscall_restartable(reg) !(reg->state& STATE_SCALL_RESTARTED)
+#define current_pt_regs() \ +({ \
- /* open-coded current_thread_info() */ \
- register unsigned long sp asm ("sp"); \
- unsigned long pg_start = (sp& ~(THREAD_SIZE - 1)); \
- (struct pt_regs *)(pg_start + THREAD_SIZE) - 1; \
+})
+static inline long regs_return_value(struct pt_regs *regs) +{
- return regs->r0;
+}
+#endif /* !__ASSEMBLY__ */
+#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..2b8c516 --- /dev/null +++ b/arch/arc/include/asm/sections.h @@ -0,0 +1 @@ +#include<asm-generic/sections.h> diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h new file mode 100644 index 0000000..e69de29
empty file
diff --git a/arch/arc/include/asm/types.h b/arch/arc/include/asm/types.h new file mode 100644 index 0000000..7475db1 --- /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.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>
bye, Heiko

Hello Heiko,
On Wed, 2014-01-29 at 06:44 +0100, Heiko Schocher wrote:
Hello Alexey,
Thanks for your patches, more or less just nitpicking comments ...
Thanks for prompt review.
Am 29.01.2014 00:09, schrieb Alexey Brodkin:
Signed-off-by: Alexey Brodkinabrodkin@synopsys.com
No commit message, please add one. (Are this files from the Linux kernel? If so please add a comment in the commit message + add a hint which linux commit you used, thanks!)
I thought from commit subject it's already clear what's presented in each particular patch so I left commit messages empty. Frankly I'm not sure still what info may I put in commit messages except mention of headers borrowed from Linux - or this is exactly what is needed?
Agree I forgot to mention which header files came from Linux kernel. Will add mentions.
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..e69de29
Empty file ?
Right, it looks weird, but I had to add this empty file just because of "designware_i2c" driver which refers to "asm/arch/hardware.h".
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/i2c/designware_i2c.c;h=9ed...
And to remove "asm/arch/hardware.h" I would need to modify "arch/hardware.h" and "include/configs/..." files for platform/boards I don't own.
Basically this is just a work-around that allows me to use "designware_i2c" driver as it is.
There was a similar dependency ("asm/arch/clk.h") in "dw_mmc" but in that case it was possible to just remove it - what I did - http://git.denx.de/?p=u-boot.git;a=commit;h=ca6d4d0f8f0fb8ae09a7ba271177367b...
So if you insist on removal of this file we would need to fix "designware_i2c" first.
Please let me know what do you think about this item.
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..87b0a60
...
+#ifndef __ASSEMBLY__
+/*
Bad comment style
Inline ASM macros to read/write AUX Regs
Essentially invocation of lr/sr insns from "C"
- */
+#if 1
+#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)
+#else
Please remove dead code ...
+#define read_aux_reg(reg) \
...
bogus_undefined(); \
- } \
+}
Why do you use defines here instead of real functions?
+#define WRITE_BCR(reg, into) \ +{ \
- unsigned int tmp; \
- if (sizeof(tmp) == sizeof(into)) { \
tmp = (*(unsigned int *)(into)); \
write_aux_reg(reg, tmp); \
- } else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
- } \
+}
and here?
Ok, so this header is borrowed from Linux sources. That's why I didn't do any modifications and took it as it is on kernel.org.
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h new file mode 100644 index 0000000..e69de29
Hups, one more empty file ...
I thought it was required by some common file. Double-checked and now see that it could be safely removed.
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..3b2df87 --- /dev/null +++ b/arch/arc/include/asm/ptrace.h @@ -0,0 +1,101 @@ +/*
- 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
+#ifndef __ASSEMBLY__
+/* THE pt_regs: Defines how regs are saved during entry into kernel */
Is the "THE" a shortcut?
Another copy from Linux sources - thus taken as it is.
diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h new file mode 100644 index 0000000..e69de29
empty file
Somehow I missed a fact that ARC already has optimized "string" routines. Will add them in re-spin.
Will send a v2 series soon.
-Alexey

Hello Alexey,
Am 29.01.2014 09:57, schrieb Alexey Brodkin:
Hello Heiko,
On Wed, 2014-01-29 at 06:44 +0100, Heiko Schocher wrote:
Hello Alexey,
Thanks for your patches, more or less just nitpicking comments ...
Thanks for prompt review.
Am 29.01.2014 00:09, schrieb Alexey Brodkin:
Signed-off-by: Alexey Brodkinabrodkin@synopsys.com
No commit message, please add one. (Are this files from the Linux kernel? If so please add a comment in the commit message + add a hint which linux commit you used, thanks!)
I thought from commit subject it's already clear what's presented in each particular patch so I left commit messages empty. Frankly I'm not sure still what info may I put in commit messages except mention of headers borrowed from Linux - or this is exactly what is needed?
Maybe this site helps you:
http://www.denx.de/wiki/view/U-Boot/Patches#Attributing_Code_Copyrights_Sign
Agree I forgot to mention which header files came from Linux kernel. Will add mentions.
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..e69de29
Empty file ?
Right, it looks weird, but I had to add this empty file just because of "designware_i2c" driver which refers to "asm/arch/hardware.h".
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/i2c/designware_i2c.c;h=9ed...
And to remove "asm/arch/hardware.h" I would need to modify "arch/hardware.h" and "include/configs/..." files for platform/boards I don't own.
Basically this is just a work-around that allows me to use "designware_i2c" driver as it is.
There was a similar dependency ("asm/arch/clk.h") in "dw_mmc" but in that case it was possible to just remove it - what I did - http://git.denx.de/?p=u-boot.git;a=commit;h=ca6d4d0f8f0fb8ae09a7ba271177367b...
So if you insist on removal of this file we would need to fix "designware_i2c" first.
Please let me know what do you think about this item.
Hmm.. at least you should an comment in this file, why it is necessary.
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..87b0a60
...
+#ifndef __ASSEMBLY__
+/*
Bad comment style
Inline ASM macros to read/write AUX Regs
Essentially invocation of lr/sr insns from "C"
- */
+#if 1
+#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)
+#else
Please remove dead code ...
+#define read_aux_reg(reg) \
...
bogus_undefined(); \
- } \
+}
Why do you use defines here instead of real functions?
+#define WRITE_BCR(reg, into) \ +{ \
- unsigned int tmp; \
- if (sizeof(tmp) == sizeof(into)) { \
tmp = (*(unsigned int *)(into)); \
write_aux_reg(reg, tmp); \
- } else { \
extern void bogus_undefined(void); \
bogus_undefined(); \
- } \
+}
and here?
Ok, so this header is borrowed from Linux sources. That's why I didn't do any modifications and took it as it is on kernel.org.
Ah, ok, so this is ok I think.
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h new file mode 100644 index 0000000..e69de29
Hups, one more empty file ...
I thought it was required by some common file. Double-checked and now see that it could be safely removed.
Great!
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..3b2df87 --- /dev/null +++ b/arch/arc/include/asm/ptrace.h @@ -0,0 +1,101 @@ +/*
- 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
+#ifndef __ASSEMBLY__
+/* THE pt_regs: Defines how regs are saved during entry into kernel */
Is the "THE" a shortcut?
Another copy from Linux sources - thus taken as it is.
diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h new file mode 100644 index 0000000..e69de29
empty file
Somehow I missed a fact that ARC already has optimized "string" routines. Will add them in re-spin.
Will send a v2 series soon.
Ok, hope to find time for your other patches ...
bye, Heiko

Hello Heiko,
On Wed, 2014-01-29 at 10:04 +0100, Heiko Schocher wrote:
Maybe this site helps you:
http://www.denx.de/wiki/view/U-Boot/Patches#Attributing_Code_Copyrights_Sign
Indeed I even went through this readme a while ago but didn't pay enough attention to it on submission.
The question is - if only some files in "arch/arc/include" are copies from Linux sources may I still have a cumulative patch with all arc headers and just list borrowed files in commit message or I need to put borrowed files in a separate patch?
Agree I forgot to mention which header files came from Linux kernel. Will add mentions.
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..e69de29
Empty file ?
Right, it looks weird, but I had to add this empty file just because of "designware_i2c" driver which refers to "asm/arch/hardware.h".
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/i2c/designware_i2c.c;h=9ed...
And to remove "asm/arch/hardware.h" I would need to modify "arch/hardware.h" and "include/configs/..." files for platform/boards I don't own.
Basically this is just a work-around that allows me to use "designware_i2c" driver as it is.
There was a similar dependency ("asm/arch/clk.h") in "dw_mmc" but in that case it was possible to just remove it - what I did - http://git.denx.de/?p=u-boot.git;a=commit;h=ca6d4d0f8f0fb8ae09a7ba271177367b...
So if you insist on removal of this file we would need to fix "designware_i2c" first.
Please let me know what do you think about this item.
Hmm.. at least you should an comment in this file, why it is necessary.
Once again may I just mention it in commit message? Otherwise because of this mention in file itself I would need to add licensing (copyright) info in the file and then we have a file which only needs to exist to satisfy pre-processor but with contents of about 10 lines (which doesn't have any technical purpose).
Ok, hope to find time for your other patches ...
Much appreciated!
Thanks a lot, Alexey

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- arch/arc/config.mk | 31 +++++ arch/arc/cpu/arc700/Makefile | 13 ++ arch/arc/cpu/arc700/cache.c | 161 ++++++++++++++++++++++++ arch/arc/cpu/arc700/config.mk | 7 ++ arch/arc/cpu/arc700/cpu.c | 37 ++++++ arch/arc/cpu/arc700/interrupts.c | 211 +++++++++++++++++++++++++++++++ arch/arc/cpu/arc700/reset.c | 19 +++ arch/arc/cpu/arc700/start.S | 262 +++++++++++++++++++++++++++++++++++++++ arch/arc/cpu/arc700/timer.c | 28 +++++ arch/arc/cpu/arc700/u-boot.lds | 72 +++++++++++ 10 files changed, 841 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..2e6dc18 --- /dev/null +++ b/arch/arc/cpu/arc700/cache.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arcregs.h> + +/* Instruction cache related Auxiliary registers */ +#define ARC_REG_IC_BCR 0x77 +#define ARC_REG_IC_IVIC 0x10 +#define ARC_REG_IC_CTRL 0x11 +#define ARC_REG_IC_IVIL 0x19 +#if (CONFIG_ARC_MMU_VER > 2) +#define ARC_REG_IC_PTAG 0x1E +#endif + +/* Bit values in IC_CTRL */ +#define IC_CTRL_CACHE_DISABLE (1 << 0) + +/* Data cache related Auxiliary registers */ +#define ARC_REG_DC_BCR 0x72 +#define ARC_REG_DC_IVDC 0x47 +#define ARC_REG_DC_CTRL 0x48 +#define ARC_REG_DC_IVDL 0x4A +#define ARC_REG_DC_FLSH 0x4B +#define ARC_REG_DC_FLDL 0x4C +#if (CONFIG_ARC_MMU_VER > 2) +#define ARC_REG_DC_PTAG 0x5C +#endif + +/* 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) + +#define CACHE_LINE_SIZE CONFIG_SYS_CACHELINE_SIZE + +int icache_status(void) +{ + return (read_aux_reg(ARC_REG_IC_CTRL) & IC_CTRL_CACHE_DISABLE) != + IC_CTRL_CACHE_DISABLE; +} + +void icache_enable(void) +{ + write_aux_reg(ARC_REG_IC_CTRL, read_aux_reg(ARC_REG_IC_CTRL) & + ~IC_CTRL_CACHE_DISABLE); +} + +void icache_disable(void) +{ + write_aux_reg(ARC_REG_IC_CTRL, read_aux_reg(ARC_REG_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_REG_IC_IVIC, 1); +#endif /* CONFIG_SYS_ICACHE_OFF */ +} + +int dcache_status(void) +{ + return (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_CACHE_DISABLE) != + DC_CTRL_CACHE_DISABLE; +} + +void dcache_enable(void) +{ + unsigned int temp = read_aux_reg(ARC_REG_DC_CTRL); + temp &= ~DC_CTRL_INV_MODE_FLUSH; + write_aux_reg(ARC_REG_DC_CTRL, temp & ~DC_CTRL_CACHE_DISABLE); +} + +void dcache_disable(void) +{ + write_aux_reg(ARC_REG_DC_CTRL, read_aux_reg(ARC_REG_DC_CTRL) | + DC_CTRL_CACHE_DISABLE); +} + +void flush_dcache_all(void) +{ + /* Do flush of entire cache */ + write_aux_reg(ARC_REG_DC_FLSH, 1); + + /* Wait flush end */ + while (read_aux_reg(ARC_REG_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_REG_DC_PTAG, addr); +#endif + write_aux_reg(ARC_REG_DC_FLDL, addr); + + /* Wait flush end */ + while (read_aux_reg(ARC_REG_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_REG_IC_PTAG, addr); +#endif + write_aux_reg(ARC_REG_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 & (~(CACHE_LINE_SIZE - 1)); + end = end & (~(CACHE_LINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CACHE_LINE_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 & (~(CACHE_LINE_SIZE - 1)); + end = end & (~(CACHE_LINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CACHE_LINE_SIZE) { +#if (CONFIG_ARC_MMU_VER > 2) + write_aux_reg(ARC_REG_DC_PTAG, addr); +#endif + write_aux_reg(ARC_REG_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_REG_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..ec9d2cb --- /dev/null +++ b/arch/arc/cpu/arc700/cpu.c @@ -0,0 +1,37 @@ +/* + * 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 + + /* In simulation (ISS) "CHIPID" and "ARCNUM" are all "ff" */ + if ((read_aux_reg(AUX_IDENTITY) & 0xffffff00) == 0xffffff00) + gd->arch.running_on_hw = 0; + else + gd->arch.running_on_hw = 1; + + timer_init(); + return 0; +} diff --git a/arch/arc/cpu/arc700/interrupts.c b/arch/arc/cpu/arc700/interrupts.c new file mode 100644 index 0000000..7f5d663d --- /dev/null +++ b/arch/arc/cpu/arc700/interrupts.c @@ -0,0 +1,211 @@ +/* + * 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> + +#define ARC_REG_STATUS32 0x0A /* STATUS32 register */ + +/* STATUS32 register bits related to Interrupt Handling */ +#define STATUS_E1_BIT 1 /* Int 1 enable */ +#define STATUS_E2_BIT 2 /* Int 2 enable */ +#define STATUS_A1_BIT 3 /* Int 1 active */ +#define STATUS_A2_BIT 4 /* Int 2 active */ + +#define STATUS_E1_MASK (1<<STATUS_E1_BIT) +#define STATUS_E2_MASK (1<<STATUS_E2_BIT) +#define STATUS_A1_MASK (1<<STATUS_A1_BIT) +#define STATUS_A2_MASK (1<<STATUS_A2_BIT) + +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_REG_STATUS32); + int state = (status | STATUS_E1_MASK | STATUS_E2_MASK) ? 1 : 0; + status &= ~(STATUS_E1_MASK | STATUS_E2_MASK); + __asm__("flag %0" : : "r" (status)); + return state; +} + +void enable_interrupts(void) +{ + unsigned int status = read_aux_reg(ARC_REG_STATUS32); + status |= STATUS_E1_MASK | STATUS_E2_MASK; + __asm__("flag %0" : : "r" (status)); +} + +/* + * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) + * -Prints 3 regs per line and a CR. + * -To continue, callee regs right after scratch, special handling of CR + */ +static void print_reg_file(long *reg_rev, int start_num) +{ + unsigned int i; + char buf[512]; + int n = 0; + + for (i = start_num; i < start_num + 13; i++) { + n += sprintf(buf + n, "r%02u: 0x%08lx\t", + i, (unsigned long)*reg_rev); + + if (((i + 1) % 3) == 0) + n += sprintf(buf + n, "\n"); + + /* because pt_regs has regs reversed: r12..r0, r25..r13 */ + reg_rev--; + } + + if (start_num != 0) + n += sprintf(buf + n, "\n\n"); + + /* To continue printing callee regs on same line as scratch regs */ + if (start_num == 0) + printf("%s", buf); + else + printf("%s\n", buf); +} + +static void show_ecr_verbose(struct pt_regs *regs) +{ + unsigned int vec, cause_code; + unsigned long address; + + printf("\n[ECR ]: 0x%08lx =>\n", regs->event); + + /* For Data fault, this is data address not instruction addr */ + address = instruction_pointer(regs); + + vec = regs->ecr_vec; + cause_code = regs->ecr_cause; + + /* For DTLB Miss or ProtV, display the memory involved too */ + if (vec == ECR_V_DTLB_MISS) { + printf("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n", + (cause_code == 0x01) ? "Read" : + ((cause_code == 0x02) ? "Write" : "EX"), + address, regs->ret); + } else if (vec == ECR_V_ITLB_MISS) { + printf("Insn could not be fetched\n"); + } else if (vec == ECR_V_MACH_CHK) { + printf("%s\n", (cause_code == 0x0) ? + "Double Fault" : "Other Fatal Err"); + + } else if (vec == ECR_V_PROTV) { + if (cause_code == ECR_C_PROTV_INST_FETCH) + printf("Execute from Non-exec Page\n"); + else if (cause_code == ECR_C_PROTV_MISALIG_DATA) + printf("Misaligned r/w from 0x%08lx\n", address); + else + printf("%s access not allowed on page\n", + (cause_code == 0x01) ? "Read" : + ((cause_code == 0x02) ? "Write" : "EX")); + } else if (vec == ECR_V_INSN_ERR) { + printf("Illegal Insn\n"); + } else { + printf("Check Programmer's Manual\n"); + } +} + +void show_regs(struct pt_regs *regs) +{ + show_ecr_verbose(regs); + + printf("[RET ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", + instruction_pointer(regs), + (void *)regs->blink, (void *)regs->ret); + + printf("[STAT32]: 0x%08lx", regs->status32); + +#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : "" + printf(" : %2s %2s %2s %2s %2s\n", + STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1), + STS_BIT(regs, E2), STS_BIT(regs, E1)); + + 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..d4c4ae5 --- /dev/null +++ b/arch/arc/cpu/arc700/start.S @@ -0,0 +1,262 @@ +/* + * 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 addr modes with addr reg wback + * + * 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 POP reg + ld.ab \reg, [sp, 4] +.endm + +.macro POPAX aux + POP r9 + sr r9, [\aux] +.endm + +/*-------------------------------------------------------------- + * Helpers to save/restore Scratch Regs: + * used by Interrupt/Exception Prologue/Epilogue + *-------------------------------------------------------------*/ +.macro SAVE_R0_TO_R12 + PUSH r0 + PUSH r1 + PUSH r2 + PUSH r3 + PUSH r4 + PUSH r5 + PUSH r6 + PUSH r7 + PUSH r8 + PUSH r9 + PUSH r10 + PUSH r11 + PUSH r12 +.endm + +.macro RESTORE_R12_TO_R0 + POP r12 + POP r11 + POP r10 + POP r9 + POP r8 + POP r7 + POP r6 + POP r5 + POP r4 + POP r3 + POP r2 + POP r1 + POP r0 +.endm + +/*-------------------------------------------------------------- + * Save all registers used by Exceptions (TLB Miss, Prot-V, Mem err etc) + * Requires SP to be already switched to kernel mode Stack + * sp points to the next free element on the stack at exit of this macro. + * Registers are pushed / popped in the order defined in struct ptregs + * in asm/ptrace.h + * Note that syscalls are implemented via TRAP which is also a exception + * from CPU's point of view + *-------------------------------------------------------------*/ +.macro SAVE_ALL_SYS + + lr r0, [ecr] + st r0, [sp, 8] /* ECR */ + + SAVE_R0_TO_R12 + 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, [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, [AUX_INTR_VEC_BASE] /* Read current position */ + add %r0, %r0, %r16 /* Update address */ + sr %r0, [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..02ba319 --- /dev/null +++ b/arch/arc/cpu/arc700/timer.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arcregs.h> + +/* Timer related Aux registers */ +#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */ +#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */ +#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */ + +#define TIMER0_LIMIT -1 /* Maximum limit for timer */ + +int timer_init(void) +{ + write_aux_reg(ARC_REG_TIMER0_CTRL, 0); + write_aux_reg(ARC_REG_TIMER0_LIMIT, TIMER0_LIMIT); + write_aux_reg(ARC_REG_TIMER0_CTRL, 2); + write_aux_reg(ARC_REG_TIMER0_CNT, 0); + return 0; +} + +unsigned long timer_read_counter(void) +{ + return read_aux_reg(ARC_REG_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) + } +}

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- arch/arc/lib/Makefile | 9 ++++ arch/arc/lib/bootm.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/relocate.c | 74 +++++++++++++++++++++++++++++++++ arch/arc/lib/sections.c | 21 ++++++++++ 4 files changed, 210 insertions(+) create mode 100644 arch/arc/lib/Makefile create mode 100644 arch/arc/lib/bootm.c create mode 100644 arch/arc/lib/relocate.c create mode 100644 arch/arc/lib/sections.c
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile new file mode 100644 index 0000000..6420cf2 --- /dev/null +++ b/arch/arc/lib/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += sections.o +obj-y += relocate.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/relocate.c b/arch/arc/lib/relocate.c new file mode 100644 index 0000000..710b792 --- /dev/null +++ b/arch/arc/lib/relocate.c @@ -0,0 +1,74 @@ +/* + * 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; + +extern char __text_end[]; + +/* + * 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")));

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- common/cmd_bdinfo.c | 18 ++++++++++++++++++ common/image.c | 1 + include/image.h | 1 + 3 files changed, 20 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/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: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- 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" */

Prerequisite is http://patchwork.ozlabs.org/patch/300901/
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- board/synopsys/arcangel4/Makefile | 7 +++ board/synopsys/arcangel4/arcangel4.c | 25 ++++++++++ boards.cfg | 1 + include/configs/arcangel4.h | 96 ++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 board/synopsys/arcangel4/Makefile create mode 100644 board/synopsys/arcangel4/arcangel4.c 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..f849750 --- /dev/null +++ b/board/synopsys/arcangel4/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += arcangel4.o diff --git a/board/synopsys/arcangel4/arcangel4.c b/board/synopsys/arcangel4/arcangel4.c new file mode 100644 index 0000000..e2ffcd0 --- /dev/null +++ b/board/synopsys/arcangel4/arcangel4.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +int board_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/boards.cfg b/boards.cfg index 2dfd2b4..41269fe 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 arcangel4 arcangel4 - 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.h b/include/configs/arcangel4.h new file mode 100644 index 0000000..3d415a0 --- /dev/null +++ b/include/configs/arcangel4.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_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_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_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_ */

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- board/synopsys/axs101/Makefile | 8 ++ board/synopsys/axs101/axs101.c | 61 +++++++++++ board/synopsys/axs101/nand.c | 224 +++++++++++++++++++++++++++++++++++++++++ boards.cfg | 1 + include/configs/axs101.h | 194 +++++++++++++++++++++++++++++++++++ 5 files changed, 488 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..93e44dd --- /dev/null +++ b/board/synopsys/axs101/axs101.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dwmmc.h> +#include <i2c.h> +#include <malloc.h> +#include <netdev.h> +#include <phy.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +int board_early_init_r(void) +{ + gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +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..9667080 --- /dev/null +++ b/board/synopsys/axs101/nand.c @@ -0,0 +1,224 @@ +/* + * 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 41269fe..cb6bc37 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 axs101 - Alexey Brodkin abrodkin@synopsys.com Active arc arc700 - synopsys arcangel4 arcangel4 - 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 diff --git a/include/configs/axs101.h b/include/configs/axs101.h new file mode 100644 index 0000000..8e0f67e --- /dev/null +++ b/include/configs/axs101.h @@ -0,0 +1,194 @@ +/* + * 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_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_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 + +#define CONFIG_HOSTNAME axs101 +#define CONFIG_ETHADDR 4a:56:49:22:3e:43 +#define CONFIG_IPADDR 10.121.8.200 +#define CONFIG_SERVERIP 10.121.8.31 +#define CONFIG_GATEWAYIP 10.121.8.1 +#define CONFIG_NETMASK 255.255.255.0 + +/* + * 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_ */

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- 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: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com --- 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
-
Heiko Schocher