[U-Boot] [PATCH v2 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-v2' 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...
Changes for v2:
* Deleted unused empty file "asm/processor.h" * Added borrowed from Linux optimized string routines * Added commit messages for most of patches * Added explicit mention of files borrowed from Linux sources with reference to versoin/commit in Linux git repository
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/linkage.h | 63 ++++++ arch/arc/include/asm/posix_types.h | 73 +++++++ arch/arc/include/asm/ptrace.h | 101 +++++++++ arch/arc/include/asm/sections.h | 1 + arch/arc/include/asm/string.h | 27 +++ 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 | 16 ++ arch/arc/lib/bootm.c | 106 +++++++++ arch/arc/lib/memcmp.S | 122 +++++++++++ arch/arc/lib/memcpy-700.S | 64 ++++++ arch/arc/lib/memset.S | 59 +++++ arch/arc/lib/relocate.c | 74 +++++++ arch/arc/lib/sections.c | 21 ++ arch/arc/lib/strchr-700.S | 133 ++++++++++++ arch/arc/lib/strcmp.S | 96 +++++++++ arch/arc/lib/strcpy-700.S | 70 ++++++ arch/arc/lib/strlen.S | 83 +++++++ 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 + 52 files changed, 3412 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/linkage.h create mode 100644 arch/arc/include/asm/posix_types.h create mode 100644 arch/arc/include/asm/ptrace.h create mode 100644 arch/arc/include/asm/sections.h create mode 100644 arch/arc/include/asm/string.h create mode 100644 arch/arc/include/asm/types.h create mode 100644 arch/arc/include/asm/u-boot.h create mode 100644 arch/arc/include/asm/unaligned.h create mode 100644 arch/arc/lib/Makefile create mode 100644 arch/arc/lib/bootm.c create mode 100644 arch/arc/lib/memcmp.S create mode 100644 arch/arc/lib/memcpy-700.S create mode 100644 arch/arc/lib/memset.S create mode 100644 arch/arc/lib/relocate.c create mode 100644 arch/arc/lib/sections.c create mode 100644 arch/arc/lib/strchr-700.S create mode 100644 arch/arc/lib/strcmp.S create mode 100644 arch/arc/lib/strcpy-700.S create mode 100644 arch/arc/lib/strlen.S create mode 100644 board/synopsys/arcangel4/Makefile create mode 100644 board/synopsys/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

These are header files used by ARC700 architecture.
Following files were borrowed from Linux kernel sources, commit 5ee54f38171b9b3541c5e9cf9c3a9e53455fd8b4 (Linux 3.11.10):
* arcregs.h * linkage.h * ptrace.h * string.h
Also note that "arch-arc700/hardware.h" is only required for compilation of "designware_i2c" driver which refers to "asm/arch/hardware.h". It would be good to fix mentioned driver sometime soon but it will cause changes in ARM board configs that use "designware_i2c".
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
Changes for v2:
* Deleted unused empty file "asm/processor.h" * Added commit message * Added explicit mention of header files borrowed from Linux sources with reference to versoin/commit in Linux git repository --- 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/linkage.h | 63 ++++++ arch/arc/include/asm/posix_types.h | 73 +++++++ arch/arc/include/asm/ptrace.h | 101 +++++++++ arch/arc/include/asm/sections.h | 1 + arch/arc/include/asm/string.h | 27 +++ 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, 1044 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/linkage.h create mode 100644 arch/arc/include/asm/posix_types.h create mode 100644 arch/arc/include/asm/ptrace.h create mode 100644 arch/arc/include/asm/sections.h create mode 100644 arch/arc/include/asm/string.h create mode 100644 arch/arc/include/asm/types.h create mode 100644 arch/arc/include/asm/u-boot.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/linkage.h b/arch/arc/include/asm/linkage.h new file mode 100644 index 0000000..0283e9e --- /dev/null +++ b/arch/arc/include/asm/linkage.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#ifdef __ASSEMBLY__ + +/* Can't use the ENTRY macro in linux/linkage.h + * gas considers ';' as comment vs. newline + */ +.macro ARC_ENTRY name + .global \name + .align 4 + \name: +.endm + +.macro ARC_EXIT name +#define ASM_PREV_SYM_ADDR(name) .-##name + .size \ name, ASM_PREV_SYM_ADDR(\name) +.endm + +/* annotation for data we want in DCCM - if enabled in .config */ +.macro ARCFP_DATA nm +#ifdef CONFIG_ARC_HAS_DCCM + .section .data.arcfp +#else + .section .data +#endif + .global \nm +.endm + +/* annotation for data we want in DCCM - if enabled in .config */ +.macro ARCFP_CODE +#ifdef CONFIG_ARC_HAS_ICCM + .section .text.arcfp, "ax",@progbits +#else + .section .text, "ax",@progbits +#endif +.endm + +#else /* !__ASSEMBLY__ */ + +#ifdef CONFIG_ARC_HAS_ICCM +#define __arcfp_code __attribute__((__section__(".text.arcfp"))) +#else +#define __arcfp_code __attribute__((__section__(".text"))) +#endif + +#ifdef CONFIG_ARC_HAS_DCCM +#define __arcfp_data __attribute__((__section__(".data.arcfp"))) +#else +#define __arcfp_data __attribute__((__section__(".data"))) +#endif + +#endif /* __ASSEMBLY__ */ + +#endif 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/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..909129c --- /dev/null +++ b/arch/arc/include/asm/string.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_STRING_H +#define __ASM_ARC_STRING_H + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_STRCHR +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRLEN + +extern void *memset(void *ptr, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void memzero(void *ptr, __kernel_size_t n); +extern int memcmp(const void *, const void *, __kernel_size_t); +extern char *strchr(const char *s, int c); +extern char *strcpy(char *dest, const char *src); +extern int strcmp(const char *cs, const char *ct); +extern __kernel_size_t strlen(const char *); + +#endif /* __ASM_ARC_STRING_H */ diff --git a/arch/arc/include/asm/types.h b/arch/arc/include/asm/types.h new file mode 100644 index 0000000..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>

Dear Alexey Brodkin,
In message 1391011745-22239-2-git-send-email-abrodkin@synopsys.com you wrote:
These are header files used by ARC700 architecture.
...
+/* 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
Are you sure that this should not become a C struct declaration? This looks much like offsets, and we so not allow a base address + offset notation for device I/O ...
+/* 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 */
Please uses masks instead of bit numbers. Bitfields are inherently non-portable and dangerous.
+/* 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)
As the STATUS_??_BIT defiens should not be used anywhere else, you might drop them without loss of readability.
+/*
Inline ASM macros to read/write AUX Regs
Essentially invocation of lr/sr insns from "C"
- */
Can we drop this "*******************" line?
+#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) \
...
+#endif
This pretty long else branch is just dead code. Please get rid of all such "#if 1" or "#if 0" blocks in your code, globally.
+#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(); \
- } \
+}
Do we really need this? No other architecture does anything like that. Can you not just use standard I/O accessors?
+/* 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)
Please drop these. The just make the code harder to read.
+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 +};
Arghh... Please by all means try to avoid bitfields! They are pure evil and are strongly discouraged!
+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 +};
Do you really need your own definition CONFIG_CPU_BIG_ENDIAN here? Can you not use the existing standard defines instead? If you do, please keep inmind that all new CONFIG_ optins must be explained in the README.
+/* 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 +};
..
etc.
With all these tons of bitfields the code will be a mess to read and understand. Please really try and get rid of using bitfields!
+/*
- Generic structures to hold build configuration used at runtime
- */
Incorrect multiline comment style. Please fix globally.
+struct cpuinfo_arc_mmu {
- unsigned int ver, pg_sz, sets, ways, u_dtlb, u_itlb, num_tlb;
+};
Please declare structs one field per line, and comment the meaning of the fields. Please fix globally.
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
- #define __BYTEORDER_HAS_U64__
- #define __SWAB_64_THRU_32__
+#endif
We don't have __KERNEL__ much longer, I think...
+#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; })
Why would these IOREAD*/IO_WRITE* macros be needed in addition to the read*/write* accessors? Their definitions look pretty much identical to me.
+#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; })
As far as I can tell there is no type checking for the arguments passed here. Can this please be added, so the compiler can catch when you for example try to use a writel() on a address that points to char only?
+/*
- 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)
Do we actually need any of this in U-Boot?
Please clean up and remove unused stuff...
+/*
- 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)
Needed in U-Boot? Please fix globally.
+/* 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
I think you can drop that, too?
+/* Can't use the ENTRY macro in linux/linkage.h
- gas considers ';' as comment vs. newline
- */
+.macro ARC_ENTRY name
- .global \name
- .align 4
- \name:
+.endm
Is this really correct sytax for this architecture? I would expect that the "\n" means a newline character ;-)
+/*
- 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)
Is any of this actually relevant in U-Boot?
+#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \
(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
+#endif
Note that checkpatch throws warnings here:
WARNING: space prohibited between function name and open parenthesis '('
Please make sure to run all your patches through checkpatch and fix such errors and warnings!
+#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..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 */
Needed?
+/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32 & STATUS_U_MASK)
Certainly not needed, right?
etc. etc.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Wed, 2014-01-29 at 20:54 +0100, Wolfgang Denk wrote:
Dear Alexey Brodkin,
In message 1391011745-22239-2-git-send-email-abrodkin@synopsys.com you wrote:
These are header files used by ARC700 architecture.
...
+/* 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
Are you sure that this should not become a C struct declaration? This looks much like offsets, and we so not allow a base address + offset notation for device I/O ...
+/* 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 */
Please uses masks instead of bit numbers. Bitfields are inherently non-portable and dangerous.
+/* 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)
As the STATUS_??_BIT defiens should not be used anywhere else, you might drop them without loss of readability.
+/*
Inline ASM macros to read/write AUX Regs
Essentially invocation of lr/sr insns from "C"
- */
Can we drop this "*******************" line?
+#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) \
...
+#endif
This pretty long else branch is just dead code. Please get rid of all such "#if 1" or "#if 0" blocks in your code, globally.
+#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(); \
- } \
+}
Do we really need this? No other architecture does anything like that. Can you not just use standard I/O accessors?
+/* 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)
Please drop these. The just make the code harder to read.
+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 +};
As it is clearly mentioned in commit message "arcregs.h" came from Linux sources and that's why kept as it was. You may refer to it here - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/ar...
So I'm wondering if you insist on fixing all mentioned items in "arcregs.h" or I may keep it as it is still?
Arghh... Please by all means try to avoid bitfields! They are pure evil and are strongly discouraged!
+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 +};
Do you really need your own definition CONFIG_CPU_BIG_ENDIAN here? Can you not use the existing standard defines instead? If you do, please keep inmind that all new CONFIG_ optins must be explained in the README.
Makes perfect sense. I missed the fact that similar defines have a bit different names in Linux/U-boot.
It's CONFIG_CPU_BIG_ENDIAN in Linux while CONFIG_SYS_BIG_ENDIAN in U-Boot. So I'll substitute it here with proper CONFIG_SYS_BIG_ENDIAN.
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
- #define __BYTEORDER_HAS_U64__
- #define __SWAB_64_THRU_32__
+#endif
We don't have __KERNEL__ much longer, I think...
Ok, I copy-pasted it from "arch/arm/include/asm/byteorder.h". And it still has __KERNEL__ - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/byteorder.h;h...
Are we going to fix it for existing arches (note all arches except M68K, PowerPC and SPARC have it in "byteorder.h")?
So do I need to eliminate all checks for __KERNEL__ then?
+#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; })
Why would these IOREAD*/IO_WRITE* macros be needed in addition to the read*/write* accessors? Their definitions look pretty much identical to me.
Indeed they are obsolete and I'll remove them completely.
+#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; })
As far as I can tell there is no type checking for the arguments passed here. Can this please be added, so the compiler can catch when you for example try to use a writel() on a address that points to char only?
Good suggestion, but I'm wondering if this kind of checks are already implemented in other arches - may I have a reference?
+/*
- 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)
Do we actually need any of this in U-Boot?
Please clean up and remove unused stuff...
Well for example "inb"/"outb" is used in "drivers/serial/ns16550.c" and in many other places. So we need to clean drivers and common files first.
+/*
- 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)
Needed in U-Boot? Please fix globally.
MAP_WRCOMBINE is not used really. While MAP_NOCACHE and MAP_WRBACK are still in use in couple of places together with "map_physmem()".
+/* 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
I think you can drop that, too?
will do.
+/* Can't use the ENTRY macro in linux/linkage.h
- gas considers ';' as comment vs. newline
- */
+.macro ARC_ENTRY name
- .global \name
- .align 4
- \name:
+.endm
Is this really correct sytax for this architecture? I would expect that the "\n" means a newline character ;-)
This is GNU Assembler macro syntax - https://sourceware.org/binutils/docs/as/Macro.html#Macro That's how you use parameters passed to macro. So here parameter name is "name" and you use it as "\name" in macro's body.
And it works which is proven by built and executed both Linux kernel and U-boot on ARC CPUs.
+/*
- 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)
Is any of this actually relevant in U-Boot?
Once again - "posix_types.h" are very similar in all arches now and so I took ARM's one. If everything or some parts there are useless we may want to clean-up this globally.
But I see that in "include/linux/types.h" "__kernel_XXX_t" types are used.
+#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \
(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
+#endif
Note that checkpatch throws warnings here:
WARNING: space prohibited between function name and open parenthesis '('
Please make sure to run all your patches through checkpatch and fix such errors and warnings!
As I mentioned I took this one from ARM so I left it as it is. I might just add explicit mention that my file is a copy. Will it work?
+#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..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 */
Needed?
+/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32 & STATUS_U_MASK)
Certainly not needed, right?
etc. etc.
This is another file taken from Linux kernel source that's why I didn't touch it at all.
Regards, Alexey

Dear Alexey,
In message 1391088780.3518.33.camel@abrodkin-8560l.internal.synopsys.com you wrote:
As it is clearly mentioned in commit message "arcregs.h" came from Linux sources and that's why kept as it was. You may refer to it here - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/ar...
So I'm wondering if you insist on fixing all mentioned items in "arcregs.h" or I may keep it as it is still?
This is difficult to impossible for me to decide yet. MY general feeling is that there is an overwhelming amount of code that is completely unused in U-Boot. That should really be dropped.
Also, it would help if you could give reasons (I mean, other than "this comes form Linux, so it must be good") why this code should be written as it is.
Or, for example, if it is realistic to expect that both BE and LE configurations of your systems will be supported in U-Boot, etc.
Ok, I copy-pasted it from "arch/arm/include/asm/byteorder.h". And it still has __KERNEL__ - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/byteor%3E der.h;h=20cce7657e1059a170fd5ef32688cb96064fcd7f;hb=HEAD
Are we going to fix it for existing arches (note all arches except M68K, PowerPC and SPARC have it in "byteorder.h")?
IIRC it might go away in the context of the Kconfig changes.
+#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; })
As far as I can tell there is no type checking for the arguments passed here. Can this please be added, so the compiler can catch when you for example try to use a writel() on a address that points to char only?
Good suggestion, but I'm wondering if this kind of checks are already implemented in other arches - may I have a reference?
It should be sufficient to use inline functions instead of macros; for example something like
extern inline u8 readb(const volatile unsigned char __iomem *addr) { u8 val;
__asm__ __volatile__( "ldb.di %0,[%1]" : "=&r" ((val)) : "r" ((addr))); return val; }
+/*
- 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)
Do we actually need any of this in U-Boot?
Please clean up and remove unused stuff...
Well for example "inb"/"outb" is used in "drivers/serial/ns16550.c" and in many other places. So we need to clean drivers and common files first.
Are you sure all of these are actually used?
+/*
- 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)
Needed in U-Boot? Please fix globally.
MAP_WRCOMBINE is not used really. While MAP_NOCACHE and MAP_WRBACK are still in use in couple of places together with "map_physmem()".
So drop the unused, please...
+/* 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
I think you can drop that, too?
will do.
+/* Can't use the ENTRY macro in linux/linkage.h
- gas considers ';' as comment vs. newline
- */
+.macro ARC_ENTRY name
- .global \name
- .align 4
- \name:
+.endm
Is this really correct sytax for this architecture? I would expect that the "\n" means a newline character ;-)
This is GNU Assembler macro syntax - https://sourceware.org/binutils/docs/as/Macro.html#Macro That's how you use parameters passed to macro. So here parameter name is "name" and you use it as "\name" in macro's body.
And it works which is proven by built and executed both Linux kernel and U-boot on ARC CPUs.
+/*
- 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)
Is any of this actually relevant in U-Boot?
Once again - "posix_types.h" are very similar in all arches now and so I took ARM's one. If everything or some parts there are useless we may want to clean-up this globally.
It appears you avoid to answer my questions. Referring to existing sub-optimal code is not really an answer. But you are right, if othe rarchitectures include such stuff, they should be cleaned up, too.
Patches are always welcome.
Note that checkpatch throws warnings here:
WARNING: space prohibited between function name and open parenthesis '('
Please make sure to run all your patches through checkpatch and fix such errors and warnings!
As I mentioned I took this one from ARM so I left it as it is. I might just add explicit mention that my file is a copy. Will it work?
No. Everybody can make mistakes. But to knowingly copy poor code would be... well, no.
+#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrac> e.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 */
Needed?
+/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32 & STATUS_U_MASK)
Certainly not needed, right?
etc. etc.
This is another file taken from Linux kernel source that's why I didn't touch it at all.
Maybe we can take only the parts that are actually needed or useful?
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Fri, 2014-01-31 at 00:10 +0100, Wolfgang Denk wrote:
Dear Alexey,
In message 1391088780.3518.33.camel@abrodkin-8560l.internal.synopsys.com you wrote:
As it is clearly mentioned in commit message "arcregs.h" came from Linux sources and that's why kept as it was. You may refer to it here - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/ar...
So I'm wondering if you insist on fixing all mentioned items in "arcregs.h" or I may keep it as it is still?
This is difficult to impossible for me to decide yet. MY general feeling is that there is an overwhelming amount of code that is completely unused in U-Boot. That should really be dropped.
Also, it would help if you could give reasons (I mean, other than "this comes form Linux, so it must be good") why this code should be written as it is.
Or, for example, if it is realistic to expect that both BE and LE configurations of your systems will be supported in U-Boot, etc.
Your comments and reasons make perfect sense so I think I'll do a massive clean-up of those headers. It will definitely benefit U-Boot and hopefully then similar clean-up will be accepted in Linux - everybody will be happy.
And indeed I do expect to support both LE and BE flavors of ARC CPUs. Because right away one of the active users (I mean company here not individual) use BE ARC CPU.
Ok, I copy-pasted it from "arch/arm/include/asm/byteorder.h". And it still has __KERNEL__ - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/byteor%3E der.h;h=20cce7657e1059a170fd5ef32688cb96064fcd7f;hb=HEAD
Are we going to fix it for existing arches (note all arches except M68K, PowerPC and SPARC have it in "byteorder.h")?
IIRC it might go away in the context of the Kconfig changes.
Good. I fixed mine, hope others will follow.
+#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; })
As far as I can tell there is no type checking for the arguments passed here. Can this please be added, so the compiler can catch when you for example try to use a writel() on a address that points to char only?
Good suggestion, but I'm wondering if this kind of checks are already implemented in other arches - may I have a reference?
It should be sufficient to use inline functions instead of macros; for example something like
extern inline u8 readb(const volatile unsigned char __iomem *addr) { u8 val;
__asm__ __volatile__( "ldb.di %0,[%1]" : "=&r" ((val)) : "r" ((addr)));
return val; }
Good suggestion. Will definitely replace macros with in-lined functions. Still I don't quite understand how this implementation helps with data type checking. I may feed any address and compiler happily puts 1 byte aligned address as argument for word load/store instruction.
I'm not sure if this is a flaw of our GCC port or I'm doing something wrong here.
+/*
- 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)
Do we actually need any of this in U-Boot?
Please clean up and remove unused stuff...
Well for example "inb"/"outb" is used in "drivers/serial/ns16550.c" and in many other places. So we need to clean drivers and common files first.
Are you sure all of these are actually used?
Well, most of these are used here and there. And the problem I see is we have many very similar accessors in U-Boot. And people randomly (or based on their preference) use either of them.
Let's look at "outb". Different arches define it as an alias for "writeb", "__raw_writeb", "out_8" etc.
Now I see "outb" is used in "drivers/serial/ns16550.c" as I mentioned. And this is one of the most common serial port devices right?
"writeb" is used everywhere.
"__raw_writeb" is used in "drivers/mtd/cfi_flash.c"
And the same picture with other accessors. It would be good if we re-visit this topic and come up with some guide that explains which accessers could be used and in which cases.
In current situation it looks like every arch sort of emulates accessors of other platform.
For example this is a comment from "io.h" for "SH" architecture: ===== The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space =====
And indeed I may remove these "in/out" accessors from "ARC" port. But as a maintainer/submitter of ARC port I'd like my users to have access to all (or at least most of) already existing and working drivers and common things (like commands etc).
But IMHO it will be unfair. ARC users will complain on "buggy"/obsolete drivers while users of all other architectures will rest in pease and just use existing code-base.
That's why I would prefer to have an accessors clean-up as a separate movement among all arches at once - so everybody gets affected and many hands will start fixing stuff all together.
+/*
- 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)
Needed in U-Boot? Please fix globally.
MAP_WRCOMBINE is not used really. While MAP_NOCACHE and MAP_WRBACK are still in use in couple of places together with "map_physmem()".
So drop the unused, please...
Already did.
+/* 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
I think you can drop that, too?
will do.
+/* Can't use the ENTRY macro in linux/linkage.h
- gas considers ';' as comment vs. newline
- */
+.macro ARC_ENTRY name
- .global \name
- .align 4
- \name:
+.endm
Is this really correct sytax for this architecture? I would expect that the "\n" means a newline character ;-)
This is GNU Assembler macro syntax - https://sourceware.org/binutils/docs/as/Macro.html#Macro That's how you use parameters passed to macro. So here parameter name is "name" and you use it as "\name" in macro's body.
And it works which is proven by built and executed both Linux kernel and U-boot on ARC CPUs.
+/*
- 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)
Is any of this actually relevant in U-Boot?
Once again - "posix_types.h" are very similar in all arches now and so I took ARM's one. If everything or some parts there are useless we may want to clean-up this globally.
It appears you avoid to answer my questions. Referring to existing sub-optimal code is not really an answer. But you are right, if othe rarchitectures include such stuff, they should be cleaned up, too.
Patches are always welcome.
Sure there're questions I don't have a good technical answer for. I have to confess that I'm not an expert of each and every tiny bit of U-boot.
But I see that those types in Linux sources are defined in single one header "include/linux/types.h". And all arches use it.
From this I can make a conclusion that each working implementation rom
other architecture will work for ARC. So did I - copied and it worked.
I would say that in U-Boot we need to unify lots of things - for example unified init sequences is a good movement but even there I see tons of ifdefs for each and other corner case.
So if I want to fix every flaw of existing U-Boot that I met during implementation of my port I would spend many months on this work while ARC port still won't be in upstream.
That's why I decided to fix non-ARC sources that block ARC port form being useful (more than 10 patches were accepted) and then submit ARC part which looks as much as possible similarly to existing architectures. This similarity will allow even automatic batch fixing of things. Otherwise each time you'll need to figure out what happen here and there and why there're different implementations of similar or even same things.
Saying all this I'm not withdrawing from doing all these fixes anytime later. As an active user and contributor I'm interested in having U-boot sources in good shape - it benefits me in the end.
Note that checkpatch throws warnings here:
WARNING: space prohibited between function name and open parenthesis '('
Please make sure to run all your patches through checkpatch and fix such errors and warnings!
As I mentioned I took this one from ARM so I left it as it is. I might just add explicit mention that my file is a copy. Will it work?
No. Everybody can make mistakes. But to knowingly copy poor code would be... well, no.
Understood.
+#endif /* __ASM_ARC_POSIX_TYPES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrac> e.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 */
Needed?
+/* return 1 if user mode or 0 if kernel mode */ +#define user_mode(regs) (regs->status32 & STATUS_U_MASK)
Certainly not needed, right?
etc. etc.
This is another file taken from Linux kernel source that's why I didn't touch it at all.
Maybe we can take only the parts that are actually needed or useful?
As with "arcregs.h" I'll clean this one up heavily so it has only useful pieces.
Regard, Alexey

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
No changes for v2.
--- 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) + } +}

Dear Alexey Brodkin,
In message 1391011745-22239-3-git-send-email-abrodkin@synopsys.com you wrote:
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
No changes for v2.
This belongs into the comment section (below the "---" line), not into the commit message.
...
+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);
+}
I missed this in patch # 1 - why do you need these read_aux_reg() / write_aux_reg() macros? Why cannot you use standard I/O accessors instead?
+/* 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)
See before.
+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;
+}
Please insert blankk line between declarations and code. Please fix globally.
+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.
Comment and code disagree: You print "\n", not "\r" !
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Wed, 2014-01-29 at 21:06 +0100, Wolfgang Denk wrote:
Dear Alexey Brodkin,
In message 1391011745-22239-3-git-send-email-abrodkin@synopsys.com you wrote:
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
No changes for v2.
This belongs into the comment section (below the "---" line), not into the commit message.
Good point, will fix next time.
...
+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);
+}
I missed this in patch # 1 - why do you need these read_aux_reg() / write_aux_reg() macros? Why cannot you use standard I/O accessors instead?
This is already answered by Mischa.
+/* 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)
See before.
As I answered in comments for the first patch - most of STATUS_xx_BITs are defined in "arcregs.h" which is a copy of kernel's one.
In kernel sources for some reason A1, A2, E1 and E2 bits are defined in separate header "irqflags.h" which as a whole substance we don't need in U-Boot. So I defined these flags in "arch/arc/cpu/arc700/interrupts.c" and did it in the same manner as they are in "arcregs.h".
Moreover it is expected that these mask defines all look the same way STATUS_xx_MASK by handy macro: ==== #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : "" ==== So we may easily access each and every status bit.
Also IMHO it's good to keep the same defines in both Linux kernel and in U-Boot so reader familiar with Linux for ARC understands what happens in U-Boot and vise versa.
That's my motivation here.
+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;
+}
Please insert blankk line between declarations and code. Please fix globally.
+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.
Comment and code disagree: You print "\n", not "\r" !
Agree, so I'll remove entire comment before function and put small comments within function itself - IMHO will be easier to understand a logic.
Regards, Alexey

These are library functions used by ARC700 architecture.
Following files were borrowed from Linux kernel sources, commit 5ee54f38171b9b3541c5e9cf9c3a9e53455fd8b4 (Linux 3.11.10):
* memcmp.S * memcpy-700.S * memset.S * strchr-700.S * strcmp.S * strcpy-700.S * strlen.S
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
Changes for v2:
* Added commit message * Added borrowed from Linux optimized string routines * Added explicit mention of files borrowed from Linux sources with reference to versoin/commit in Linux git repository --- arch/arc/lib/Makefile | 16 ++++++ arch/arc/lib/bootm.c | 106 ++++++++++++++++++++++++++++++++++++ arch/arc/lib/memcmp.S | 122 ++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/memcpy-700.S | 64 ++++++++++++++++++++++ arch/arc/lib/memset.S | 59 ++++++++++++++++++++ arch/arc/lib/relocate.c | 74 ++++++++++++++++++++++++++ arch/arc/lib/sections.c | 21 ++++++++ arch/arc/lib/strchr-700.S | 133 ++++++++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/strcmp.S | 96 +++++++++++++++++++++++++++++++++ arch/arc/lib/strcpy-700.S | 70 ++++++++++++++++++++++++ arch/arc/lib/strlen.S | 83 +++++++++++++++++++++++++++++ 11 files changed, 844 insertions(+) create mode 100644 arch/arc/lib/Makefile create mode 100644 arch/arc/lib/bootm.c create mode 100644 arch/arc/lib/memcmp.S create mode 100644 arch/arc/lib/memcpy-700.S create mode 100644 arch/arc/lib/memset.S create mode 100644 arch/arc/lib/relocate.c create mode 100644 arch/arc/lib/sections.c create mode 100644 arch/arc/lib/strchr-700.S create mode 100644 arch/arc/lib/strcmp.S create mode 100644 arch/arc/lib/strcpy-700.S create mode 100644 arch/arc/lib/strlen.S
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile new file mode 100644 index 0000000..7675f85 --- /dev/null +++ b/arch/arc/lib/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += sections.o +obj-y += relocate.o +obj-y += strchr-700.o +obj-y += strcmp.o +obj-y += strcpy-700.o +obj-y += strlen.o +obj-y += memcmp.o +obj-y += memcpy-700.o +obj-y += memset.o +obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c new file mode 100644 index 0000000..d185a50 --- /dev/null +++ b/arch/arc/lib/bootm.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 4K to be safe */ + sp -= 4096; + lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp)); +} + +static int cleanup_before_linux(void) +{ + disable_interrupts(); + flush_dcache_all(); + invalidate_icache_all(); + + return 0; +} + +/* Subcommand: PREP */ +static void boot_prep_linux(bootm_headers_t *images) +{ + if (image_setup_linux(images)) + hang(); +} + +/* Subcommand: GO */ +static void boot_jump_linux(bootm_headers_t *images, int flag) +{ + void (*kernel_entry)(int zero, int arch, uint params); + unsigned int r0, r2; + int fake = (flag & BOOTM_STATE_OS_FAKE_GO); + + kernel_entry = (void (*)(int, int, uint))images->ep; + + debug("## Transferring control to Linux (at address %08lx)...\n", + (ulong) kernel_entry); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + printf("\nStarting kernel ...%s\n\n", fake ? + "(fake run for tracing)" : ""); + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); + + cleanup_before_linux(); + + if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + r0 = 2; + r2 = (unsigned int)images->ft_addr; + } else { + r0 = 1; + r2 = (unsigned int)getenv("bootargs"); + } + + if (!fake) + kernel_entry(r0, 0, r2); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + /* No need for those on ARC */ + if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + boot_jump_linux(images, flag); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images, flag); + return 0; +} diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S new file mode 100644 index 0000000..c47a271 --- /dev/null +++ b/arch/arc/lib/memcmp.S @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/linkage.h> + +#ifdef __LITTLE_ENDIAN__ +#define WORD2 r2 +#define SHIFT r3 +#else /* BIG ENDIAN */ +#define WORD2 r3 +#define SHIFT r2 +#endif + +ARC_ENTRY memcmp + or r12,r0,r1 + asl_s r12,r12,30 + sub r3,r2,1 + brls r2,r12,.Lbytewise + ld r4,[r0,0] + ld r5,[r1,0] + lsr.f lp_count,r3,3 + lpne .Loop_end + ld_s WORD2,[r0,4] + ld_s r12,[r1,4] + brne r4,r5,.Leven + ld.a r4,[r0,8] + ld.a r5,[r1,8] + brne WORD2,r12,.Lodd +.Loop_end: + asl_s SHIFT,SHIFT,3 + bhs_s .Last_cmp + brne r4,r5,.Leven + ld r4,[r0,4] + ld r5,[r1,4] +#ifdef __LITTLE_ENDIAN__ + nop_s + ; one more load latency cycle +.Last_cmp: + xor r0,r4,r5 + bset r0,r0,SHIFT + sub_s r1,r0,1 + bic_s r1,r1,r0 + norm r1,r1 + b.d .Leven_cmp + and r1,r1,24 +.Leven: + xor r0,r4,r5 + sub_s r1,r0,1 + bic_s r1,r1,r0 + norm r1,r1 + ; slow track insn + and r1,r1,24 +.Leven_cmp: + asl r2,r4,r1 + asl r12,r5,r1 + lsr_s r2,r2,1 + lsr_s r12,r12,1 + j_s.d [blink] + sub r0,r2,r12 + .balign 4 +.Lodd: + xor r0,WORD2,r12 + sub_s r1,r0,1 + bic_s r1,r1,r0 + norm r1,r1 + ; slow track insn + and r1,r1,24 + asl_s r2,r2,r1 + asl_s r12,r12,r1 + lsr_s r2,r2,1 + lsr_s r12,r12,1 + j_s.d [blink] + sub r0,r2,r12 +#else /* BIG ENDIAN */ +.Last_cmp: + neg_s SHIFT,SHIFT + lsr r4,r4,SHIFT + lsr r5,r5,SHIFT + ; slow track insn +.Leven: + sub.f r0,r4,r5 + mov.ne r0,1 + j_s.d [blink] + bset.cs r0,r0,31 +.Lodd: + cmp_s WORD2,r12 + + mov_s r0,1 + j_s.d [blink] + bset.cs r0,r0,31 +#endif /* ENDIAN */ + .balign 4 +.Lbytewise: + breq r2,0,.Lnil + ldb r4,[r0,0] + ldb r5,[r1,0] + lsr.f lp_count,r3 + lpne .Lbyte_end + ldb_s r3,[r0,1] + ldb r12,[r1,1] + brne r4,r5,.Lbyte_even + ldb.a r4,[r0,2] + ldb.a r5,[r1,2] + brne r3,r12,.Lbyte_odd +.Lbyte_end: + bcc .Lbyte_even + brne r4,r5,.Lbyte_even + ldb_s r3,[r0,1] + ldb_s r12,[r1,1] +.Lbyte_odd: + j_s.d [blink] + sub r0,r3,r12 +.Lbyte_even: + j_s.d [blink] + sub r0,r4,r5 +.Lnil: + j_s.d [blink] + mov r0,0 +ARC_EXIT memcmp diff --git a/arch/arc/lib/memcpy-700.S b/arch/arc/lib/memcpy-700.S new file mode 100644 index 0000000..b5f6151 --- /dev/null +++ b/arch/arc/lib/memcpy-700.S @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/linkage.h> + +ARC_ENTRY memcpy + or r3,r0,r1 + asl_s r3,r3,30 + mov_s r5,r0 + brls.d r2,r3,.Lcopy_bytewise + sub.f r3,r2,1 + ld_s r12,[r1,0] + asr.f lp_count,r3,3 + bbit0.d r3,2,.Lnox4 + bmsk_s r2,r2,1 + st.ab r12,[r5,4] + ld.a r12,[r1,4] +.Lnox4: + lppnz .Lendloop + ld_s r3,[r1,4] + st.ab r12,[r5,4] + ld.a r12,[r1,8] + st.ab r3,[r5,4] +.Lendloop: + breq r2,0,.Last_store + ld r3,[r5,0] +#ifdef __LITTLE_ENDIAN__ + add3 r2,-1,r2 + ; uses long immediate + xor_s r12,r12,r3 + bmsk r12,r12,r2 + xor_s r12,r12,r3 +#else /* BIG ENDIAN */ + sub3 r2,31,r2 + ; uses long immediate + xor_s r3,r3,r12 + bmsk r3,r3,r2 + xor_s r12,r12,r3 +#endif /* ENDIAN */ +.Last_store: + j_s.d [blink] + st r12,[r5,0] + + .balign 4 +.Lcopy_bytewise: + jcs [blink] + ldb_s r12,[r1,0] + lsr.f lp_count,r3 + bhs_s .Lnox1 + stb.ab r12,[r5,1] + ldb.a r12,[r1,1] +.Lnox1: + lppnz .Lendbloop + ldb_s r3,[r1,1] + stb.ab r12,[r5,1] + ldb.a r12,[r1,2] + stb.ab r3,[r5,1] +.Lendbloop: + j_s.d [blink] + stb r12,[r5,0] +ARC_EXIT memcpy diff --git a/arch/arc/lib/memset.S b/arch/arc/lib/memset.S new file mode 100644 index 0000000..9b2d88d --- /dev/null +++ b/arch/arc/lib/memset.S @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <asm/linkage.h> + +#define SMALL 7 /* Must be at least 6 to deal with alignment/loop issues. */ + +ARC_ENTRY memset + mov_s r4,r0 + or r12,r0,r2 + bmsk.f r12,r12,1 + extb_s r1,r1 + asl r3,r1,8 + beq.d .Laligned + or_s r1,r1,r3 + brls r2,SMALL,.Ltiny + add r3,r2,r0 + stb r1,[r3,-1] + bclr_s r3,r3,0 + stw r1,[r3,-2] + bmsk.f r12,r0,1 + add_s r2,r2,r12 + sub.ne r2,r2,4 + stb.ab r1,[r4,1] + and r4,r4,-2 + stw.ab r1,[r4,2] + and r4,r4,-4 +.Laligned: ; This code address should be aligned for speed. + asl r3,r1,16 + lsr.f lp_count,r2,2 + or_s r1,r1,r3 + lpne .Loop_end + st.ab r1,[r4,4] +.Loop_end: + j_s [blink] + + .balign 4 +.Ltiny: + mov.f lp_count,r2 + lpne .Ltiny_end + stb.ab r1,[r4,1] +.Ltiny_end: + j_s [blink] +ARC_EXIT memset + +; memzero: @r0 = mem, @r1 = size_t +; memset: @r0 = mem, @r1 = char, @r2 = size_t + +ARC_ENTRY memzero + ; adjust bzero args to memset args + mov r2, r1 + mov r1, 0 + b memset ;tail call so need to tinker with blink +ARC_EXIT memzero 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"))); diff --git a/arch/arc/lib/strchr-700.S b/arch/arc/lib/strchr-700.S new file mode 100644 index 0000000..9c548c7 --- /dev/null +++ b/arch/arc/lib/strchr-700.S @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* ARC700 has a relatively long pipeline and branch prediction, so we want + to avoid branches that are hard to predict. On the other hand, the + presence of the norm instruction makes it easier to operate on whole + words branch-free. */ + +#include <asm/linkage.h> + +ARC_ENTRY strchr + extb_s r1,r1 + asl r5,r1,8 + bmsk r2,r0,1 + or r5,r5,r1 + mov_s r3,0x01010101 + breq.d r2,r0,.Laligned + asl r4,r5,16 + sub_s r0,r0,r2 + asl r7,r2,3 + ld_s r2,[r0] +#ifdef __LITTLE_ENDIAN__ + asl r7,r3,r7 +#else + lsr r7,r3,r7 +#endif + or r5,r5,r4 + ror r4,r3 + sub r12,r2,r7 + bic_s r12,r12,r2 + and r12,r12,r4 + brne.d r12,0,.Lfound0_ua + xor r6,r2,r5 + ld.a r2,[r0,4] + sub r12,r6,r7 + bic r12,r12,r6 +#ifdef __LITTLE_ENDIAN__ + and r7,r12,r4 + breq r7,0,.Loop ; For speed, we want this branch to be unaligned. + b .Lfound_char ; Likewise this one. +#else + and r12,r12,r4 + breq r12,0,.Loop ; For speed, we want this branch to be unaligned. + lsr_s r12,r12,7 + bic r2,r7,r6 + b.d .Lfound_char_b + and_s r2,r2,r12 +#endif +; /* We require this code address to be unaligned for speed... */ +.Laligned: + ld_s r2,[r0] + or r5,r5,r4 + ror r4,r3 +; /* ... so that this code address is aligned, for itself and ... */ +.Loop: + sub r12,r2,r3 + bic_s r12,r12,r2 + and r12,r12,r4 + brne.d r12,0,.Lfound0 + xor r6,r2,r5 + ld.a r2,[r0,4] + sub r12,r6,r3 + bic r12,r12,r6 + and r7,r12,r4 + breq r7,0,.Loop /* ... so that this branch is unaligned. */ + ; Found searched-for character. r0 has already advanced to next word. +#ifdef __LITTLE_ENDIAN__ +/* We only need the information about the first matching byte + (i.e. the least significant matching byte) to be exact, + hence there is no problem with carry effects. */ +.Lfound_char: + sub r3,r7,1 + bic r3,r3,r7 + norm r2,r3 + sub_s r0,r0,1 + asr_s r2,r2,3 + j.d [blink] + sub_s r0,r0,r2 + + .balign 4 +.Lfound0_ua: + mov r3,r7 +.Lfound0: + sub r3,r6,r3 + bic r3,r3,r6 + and r2,r3,r4 + or_s r12,r12,r2 + sub_s r3,r12,1 + bic_s r3,r3,r12 + norm r3,r3 + add_s r0,r0,3 + asr_s r12,r3,3 + asl.f 0,r2,r3 + sub_s r0,r0,r12 + j_s.d [blink] + mov.pl r0,0 +#else /* BIG ENDIAN */ +.Lfound_char: + lsr r7,r7,7 + + bic r2,r7,r6 +.Lfound_char_b: + norm r2,r2 + sub_s r0,r0,4 + asr_s r2,r2,3 + j.d [blink] + add_s r0,r0,r2 + +.Lfound0_ua: + mov_s r3,r7 +.Lfound0: + asl_s r2,r2,7 + or r7,r6,r4 + bic_s r12,r12,r2 + sub r2,r7,r3 + or r2,r2,r6 + bic r12,r2,r12 + bic.f r3,r4,r12 + norm r3,r3 + + add.pl r3,r3,1 + asr_s r12,r3,3 + asl.f 0,r2,r3 + add_s r0,r0,r12 + j_s.d [blink] + mov.mi r0,0 +#endif /* ENDIAN */ +ARC_EXIT strchr diff --git a/arch/arc/lib/strcmp.S b/arch/arc/lib/strcmp.S new file mode 100644 index 0000000..5dc802b --- /dev/null +++ b/arch/arc/lib/strcmp.S @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* This is optimized primarily for the ARC700. + It would be possible to speed up the loops by one cycle / word + respective one cycle / byte by forcing double source 1 alignment, unrolling + by a factor of two, and speculatively loading the second word / byte of + source 1; however, that would increase the overhead for loop setup / finish, + and strcmp might often terminate early. */ + +#include <asm/linkage.h> + +ARC_ENTRY strcmp + or r2,r0,r1 + bmsk_s r2,r2,1 + brne r2,0,.Lcharloop + mov_s r12,0x01010101 + ror r5,r12 +.Lwordloop: + ld.ab r2,[r0,4] + ld.ab r3,[r1,4] + nop_s + sub r4,r2,r12 + bic r4,r4,r2 + and r4,r4,r5 + brne r4,0,.Lfound0 + breq r2,r3,.Lwordloop +#ifdef __LITTLE_ENDIAN__ + xor r0,r2,r3 ; mask for difference + sub_s r1,r0,1 + bic_s r0,r0,r1 ; mask for least significant difference bit + sub r1,r5,r0 + xor r0,r5,r1 ; mask for least significant difference byte + and_s r2,r2,r0 + and_s r3,r3,r0 +#endif /* LITTLE ENDIAN */ + cmp_s r2,r3 + mov_s r0,1 + j_s.d [blink] + bset.lo r0,r0,31 + + .balign 4 +#ifdef __LITTLE_ENDIAN__ +.Lfound0: + xor r0,r2,r3 ; mask for difference + or r0,r0,r4 ; or in zero indicator + sub_s r1,r0,1 + bic_s r0,r0,r1 ; mask for least significant difference bit + sub r1,r5,r0 + xor r0,r5,r1 ; mask for least significant difference byte + and_s r2,r2,r0 + and_s r3,r3,r0 + sub.f r0,r2,r3 + mov.hi r0,1 + j_s.d [blink] + bset.lo r0,r0,31 +#else /* BIG ENDIAN */ + /* The zero-detection above can mis-detect 0x01 bytes as zeroes + because of carry-propagateion from a lower significant zero byte. + We can compensate for this by checking that bit0 is zero. + This compensation is not necessary in the step where we + get a low estimate for r2, because in any affected bytes + we already have 0x00 or 0x01, which will remain unchanged + when bit 7 is cleared. */ + .balign 4 +.Lfound0: + lsr r0,r4,8 + lsr_s r1,r2 + bic_s r2,r2,r0 ; get low estimate for r2 and get ... + bic_s r0,r0,r1 ; <this is the adjusted mask for zeros> + or_s r3,r3,r0 ; ... high estimate r3 so that r2 > r3 will ... + cmp_s r3,r2 ; ... be independent of trailing garbage + or_s r2,r2,r0 ; likewise for r3 > r2 + bic_s r3,r3,r0 + rlc r0,0 ; r0 := r2 > r3 ? 1 : 0 + cmp_s r2,r3 + j_s.d [blink] + bset.lo r0,r0,31 +#endif /* ENDIAN */ + + .balign 4 +.Lcharloop: + ldb.ab r2,[r0,1] + ldb.ab r3,[r1,1] + nop_s + breq r2,0,.Lcmpend + breq r2,r3,.Lcharloop +.Lcmpend: + j_s.d [blink] + sub r0,r2,r3 +ARC_EXIT strcmp diff --git a/arch/arc/lib/strcpy-700.S b/arch/arc/lib/strcpy-700.S new file mode 100644 index 0000000..b7ca4ae --- /dev/null +++ b/arch/arc/lib/strcpy-700.S @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* If dst and src are 4 byte aligned, copy 8 bytes at a time. + If the src is 4, but not 8 byte aligned, we first read 4 bytes to get + it 8 byte aligned. Thus, we can do a little read-ahead, without + dereferencing a cache line that we should not touch. + Note that short and long instructions have been scheduled to avoid + branch stalls. + The beq_s to r3z could be made unaligned & long to avoid a stall + there, but the it is not likely to be taken often, and it + would also be likey to cost an unaligned mispredict at the next call. */ + +#include <asm/linkage.h> + +ARC_ENTRY strcpy + or r2,r0,r1 + bmsk_s r2,r2,1 + brne.d r2,0,charloop + mov_s r10,r0 + ld_s r3,[r1,0] + mov r8,0x01010101 + bbit0.d r1,2,loop_start + ror r12,r8 + sub r2,r3,r8 + bic_s r2,r2,r3 + tst_s r2,r12 + bne r3z + mov_s r4,r3 + .balign 4 +loop: + ld.a r3,[r1,4] + st.ab r4,[r10,4] +loop_start: + ld.a r4,[r1,4] + sub r2,r3,r8 + bic_s r2,r2,r3 + tst_s r2,r12 + bne_s r3z + st.ab r3,[r10,4] + sub r2,r4,r8 + bic r2,r2,r4 + tst r2,r12 + beq loop + mov_s r3,r4 +#ifdef __LITTLE_ENDIAN__ +r3z: bmsk.f r1,r3,7 + lsr_s r3,r3,8 +#else +r3z: lsr.f r1,r3,24 + asl_s r3,r3,8 +#endif + bne.d r3z + stb.ab r1,[r10,1] + j_s [blink] + + .balign 4 +charloop: + ldb.ab r3,[r1,1] + + + brne.d r3,0,charloop + stb.ab r3,[r10,1] + j [blink] +ARC_EXIT strcpy diff --git a/arch/arc/lib/strlen.S b/arch/arc/lib/strlen.S new file mode 100644 index 0000000..39759e0 --- /dev/null +++ b/arch/arc/lib/strlen.S @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <asm/linkage.h> + +ARC_ENTRY strlen + or r3,r0,7 + ld r2,[r3,-7] + ld.a r6,[r3,-3] + mov r4,0x01010101 + ; uses long immediate +#ifdef __LITTLE_ENDIAN__ + asl_s r1,r0,3 + btst_s r0,2 + asl r7,r4,r1 + ror r5,r4 + sub r1,r2,r7 + bic_s r1,r1,r2 + mov.eq r7,r4 + sub r12,r6,r7 + bic r12,r12,r6 + or.eq r12,r12,r1 + and r12,r12,r5 + brne r12,0,.Learly_end +#else /* BIG ENDIAN */ + ror r5,r4 + btst_s r0,2 + mov_s r1,31 + sub3 r7,r1,r0 + sub r1,r2,r4 + bic_s r1,r1,r2 + bmsk r1,r1,r7 + sub r12,r6,r4 + bic r12,r12,r6 + bmsk.ne r12,r12,r7 + or.eq r12,r12,r1 + and r12,r12,r5 + brne r12,0,.Learly_end +#endif /* ENDIAN */ + +.Loop: + ld_s r2,[r3,4] + ld.a r6,[r3,8] + ; stall for load result + sub r1,r2,r4 + bic_s r1,r1,r2 + sub r12,r6,r4 + bic r12,r12,r6 + or r12,r12,r1 + and r12,r12,r5 + breq r12,0,.Loop +.Lend: + and.f r1,r1,r5 + sub.ne r3,r3,4 + mov.eq r1,r12 +#ifdef __LITTLE_ENDIAN__ + sub_s r2,r1,1 + bic_s r2,r2,r1 + norm r1,r2 + sub_s r0,r0,3 + lsr_s r1,r1,3 + sub r0,r3,r0 + j_s.d [blink] + sub r0,r0,r1 +#else /* BIG ENDIAN */ + lsr_s r1,r1,7 + mov.eq r2,r6 + bic_s r1,r1,r2 + norm r1,r1 + sub r0,r3,r0 + lsr_s r1,r1,3 + j_s.d [blink] + add r0,r0,r1 +#endif /* ENDIAN */ +.Learly_end: + b.d .Lend + sub_s.ne r1,r1,r1 +ARC_EXIT strlen

Dear Alexey Brodkin,
In message 1391011745-22239-4-git-send-email-abrodkin@synopsys.com you wrote:
These are library functions used by ARC700 architecture.
checkpatch says:
WARNING: line over 80 characters #610: FILE: arch/arc/lib/relocate.c:61: + debug(" %p: rom reloc %x, ram %p, value %x, limit %x\n",
Best regards,
Wolfgang Denk

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

Arcangel4 is a FPGA-based development board that is used for prototyping and verificationof of both ARC hardware (CPUs) and software running upon CPU.
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
Changes for v2:
* Added commit message --- 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_ */

AXS101 is a new generation of devlopment boards from Synopsys that houses ASIC with ARC700 and lots of DesignWare peripherals:
* DW APB UART * DW Mobile Storage (MMC/SD) * DW I2C * DW GMAC
Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
Changes for v2:
* Added commit message --- 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_ */

Dear Alexey Brodkin,
In message 1391011745-22239-8-git-send-email-abrodkin@synopsys.com you wrote:
AXS101 is a new generation of devlopment boards from Synopsys that houses ASIC with ARC700 and lots of DesignWare peripherals:
....
+#define CONFIG_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
We do not allow any such fixed network parameters in the board config headers.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Wed, 2014-01-29 at 21:09 +0100, Wolfgang Denk wrote:
Dear Alexey Brodkin,
In message 1391011745-22239-8-git-send-email-abrodkin@synopsys.com you wrote:
AXS101 is a new generation of devlopment boards from Synopsys that houses ASIC with ARC700 and lots of DesignWare peripherals:
....
+#define CONFIG_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
We do not allow any such fixed network parameters in the board config headers.
I see tons of boards do have these parameters set in "include/configs/xxx".
I may indeed remove them in from my board but why keep it in others? So people won't be confused any longer.
Regards, Alexey

Dear Alexey,
In message 1391088984.3518.35.camel@abrodkin-8560l.internal.synopsys.com you wrote:
+#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
We do not allow any such fixed network parameters in the board config headers.
I see tons of boards do have these parameters set in "include/configs/xxx".
Pre-historic sins. You happen to have a bit of tough luck when chosing your examples to copy from.
I may indeed remove them in from my board but why keep it in others? So people won't be confused any longer.
Cleanup patches are welcome.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Fri, 2014-01-31 at 00:13 +0100, Wolfgang Denk wrote:
Dear Alexey,
In message 1391088984.3518.35.camel@abrodkin-8560l.internal.synopsys.com you wrote:
+#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
We do not allow any such fixed network parameters in the board config headers.
I see tons of boards do have these parameters set in "include/configs/xxx".
Pre-historic sins. You happen to have a bit of tough luck when chosing your examples to copy from.
I may indeed remove them in from my board but why keep it in others? So people won't be confused any longer.
Cleanup patches are welcome.
Understood. I removed all my network parameters and will take a duty of cleaning up other configs.
The question then if CONFIG_HOSTNAME could be left? I see people rely on host name for selection (through name) of boot files (uImage, fdt etc.)
For example "include/configs/amcc-common.h", "include/configs/manroland/common.h" and others.
Regards, Alexey

Dear Alexey,
In message 1391179745.4721.36.camel@abrodkin-8560l you wrote:
Understood. I removed all my network parameters and will take a duty of cleaning up other configs.
thanks in advance.
The question then if CONFIG_HOSTNAME could be left? I see people rely on host name for selection (through name) of boot files (uImage, fdt etc.)
Yes, hostname is harmless - also in real life: it will not cause any issues on the network, if several hosts set (locally) the same hostname. Several boards with the same IP address or (even worse) the same MAC addresse are much more "interesting" ;-)
Best regards,
Wolfgang Denk

Hello Wolfgang,
On Fri, 2014-01-31 at 18:49 +0100, Wolfgang Denk wrote:
Dear Alexey,
In message 1391179745.4721.36.camel@abrodkin-8560l you wrote:
Understood. I removed all my network parameters and will take a duty of cleaning up other configs.
thanks in advance.
The question then if CONFIG_HOSTNAME could be left? I see people rely on host name for selection (through name) of boot files (uImage, fdt etc.)
Yes, hostname is harmless - also in real life: it will not cause any issues on the network, if several hosts set (locally) the same hostname. Several boards with the same IP address or (even worse) the same MAC addresse are much more "interesting" ;-)
I'm sorry for another continuation away from original patch discussion.
If actually not all network properties are really that harmful could you please comment on others as well - this will save a number of iterations on clean-up submission.
CONFIG_ETHADDR & CONFIG_IPADDR - it's simple - we don't want to have duplicates of the same MAC or/and IP address within one network. So definitely these ones must go away.
But others doesn't affect other devices in the network so why don't we leave them as well?
-Alexey

Dear Alexey,
In message 1391193816.4721.100.camel@abrodkin-8560l you wrote:
CONFIG_ETHADDR & CONFIG_IPADDR - it's simple - we don't want to have duplicates of the same MAC or/and IP address within one network. So definitely these ones must go away.
But others doesn't affect other devices in the network so why don't we leave them as well?
It seems only consequent to omit all settings specific to the network interface: addresses, netmask, etc. And if you do not set an IP address, it does not make sense to set a netmask, right?
Hostname (set to generic board name) is in so far somewhat of an exception as quite a lot of people appear to use this to organize their TFTP download directories.
It is difficult to give simple rules for these things. There is a lot of habits and decade old traditions involved, so please don't ask me for some formally defined rule sets.
Best regards,
Wolfgang Denk

Signed-off-by: Alexey Brodkin abrodkin@synopsys.com
Cc: Mischa Jonker mjonker@synopsys.com Cc: Francois Bedard fbedard@synopsys.com
No changes for v2. --- 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
No changes for v2. --- 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 (3)
-
Alexey Brodkin
-
Alexey Brodkin
-
Wolfgang Denk