From c1015c67f4cb01bdd59642c912263cf62e70e8d1 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Thu, 28 Nov 2013 13:52:51 +0800 Subject: powerpc/t4240: Add a frequency setting case for fman1 A new valid setting case added for fman1, it uses platform frequency. Signed-off-by: Shaohui Xie Acked-by: York Sun --- arch/powerpc/cpu/mpc85xx/speed.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 46ae80c4d81..7c7467f7bfc 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -229,6 +229,9 @@ void get_sys_info(sys_info_t *sys_info) case 4: sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4; break; + case 5: + sys_info->freq_fman[1] = sys_info->freq_systembus; + break; case 6: sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2; break; -- cgit v1.3.1 From e03c76c30342797a25ef9350e51c8daa0b56f1df Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 11 Dec 2013 12:49:13 +0530 Subject: powerpc/mpc85xx: Update CONFIG_SYS_FSL_TBCLK_DIV for T1040 The default value of CONFIG_SYS_FSL_TBCLK_DIV is 16. So, update its value as default. Signed-off-by: Prabhakar Kushwaha Acked-by: York Sun --- arch/powerpc/include/asm/config_mpc85xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 99e16bdf631..244ccbf24fc 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -711,7 +711,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define CONFIG_FM_PLAT_CLK_DIV 1 #define CONFIG_SYS_FM1_CLK CONFIG_FM_PLAT_CLK_DIV #define CONFIG_SYS_FM_MURAM_SIZE 0x30000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 +#define CONFIG_SYS_FSL_TBCLK_DIV 16 #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4" #define CONFIG_SYS_FSL_USB1_PHY_ENABLE #define CONFIG_SYS_FSL_USB2_PHY_ENABLE -- cgit v1.3.1 From a8c075414a48663b0604c22b90883e651c1a053d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Dec 2013 15:08:31 +0900 Subject: Makefile: use two double-quotations as a pair Some editors such as Emacs can highlight source files. But their parser algorithm is not perfect. If you use one double-quotation alone, some editor cannot handle it nicely and mark source lines as a string by mistake. It is preferable to use two double-quotations as a pair. Signed-off-by: Masahiro Yamada --- Makefile | 4 ++-- arch/blackfin/config.mk | 4 ++-- dts/Makefile | 2 +- spl/Makefile | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/Makefile b/Makefile index 6401fc933c0..452d0701928 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug ifdef CONFIG_SYS_LDSCRIPT # need to strip off double quotes - LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT)) + LDSCRIPT := $(CONFIG_SYS_LDSCRIPT:"%"=%) endif endif @@ -345,7 +345,7 @@ ALL-$(CONFIG_SPL_FRAMEWORK) += $(obj)u-boot.img ALL-$(CONFIG_TPL) += $(obj)tpl/u-boot-tpl.bin ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin ifneq ($(CONFIG_SPL_TARGET),) -ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET)) +ALL-$(CONFIG_SPL) += $(obj)$(CONFIG_SPL_TARGET:"%"=%) endif # enable combined SPL/u-boot/dtb rules for tegra diff --git a/arch/blackfin/config.mk b/arch/blackfin/config.mk index 35f871662df..73fa79855f5 100644 --- a/arch/blackfin/config.mk +++ b/arch/blackfin/config.mk @@ -14,9 +14,9 @@ CONFIG_BFIN_CPU := \ $(shell awk '$$2 == "CONFIG_BFIN_CPU" { print $$3 }' \ $(src)include/configs/$(BOARD).h) else -CONFIG_BFIN_CPU := $(strip $(subst ",,$(CONFIG_BFIN_CPU))) +CONFIG_BFIN_CPU := $(strip $(CONFIG_BFIN_CPU:"%"=%)) endif -CONFIG_BFIN_BOOT_MODE := $(strip $(subst ",,$(CONFIG_BFIN_BOOT_MODE))) +CONFIG_BFIN_BOOT_MODE := $(strip $(CONFIG_BFIN_BOOT_MODE:"%"=%)) PLATFORM_RELFLAGS += -ffixed-P3 -fomit-frame-pointer -mno-fdpic PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN diff --git a/dts/Makefile b/dts/Makefile index 140c8bc5e76..6c7198f65ff 100644 --- a/dts/Makefile +++ b/dts/Makefile @@ -10,7 +10,7 @@ ifeq ($(DEVICE_TREE),) $(if $(CONFIG_DEFAULT_DEVICE_TREE),,\ $(error Please define CONFIG_DEFAULT_DEVICE_TREE in your board header file)) -DEVICE_TREE = $(subst ",,$(CONFIG_DEFAULT_DEVICE_TREE)) +DEVICE_TREE = $(CONFIG_DEFAULT_DEVICE_TREE:"%"=%) endif DTS_INCDIRS = $(SRCTREE)/board/$(VENDOR)/$(BOARD)/dts diff --git a/spl/Makefile b/spl/Makefile index 2a787afa4f9..b816e20efc9 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -37,7 +37,7 @@ endif HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(SRCTREE)/board/$(VENDOR)/common/Makefile),y,n) ifdef CONFIG_SPL_START_S_PATH -START_PATH := $(subst ",,$(CONFIG_SPL_START_S_PATH)) +START_PATH := $(CONFIG_SPL_START_S_PATH:"%"=%) else START_PATH := $(CPUDIR) endif @@ -118,7 +118,7 @@ __LIBS := $(subst $(obj),,$(LIBS)) # Linker Script ifdef CONFIG_SPL_LDSCRIPT # need to strip off double quotes -LDSCRIPT := $(addprefix $(SRCTREE)/,$(subst ",,$(CONFIG_SPL_LDSCRIPT))) +LDSCRIPT := $(addprefix $(SRCTREE)/,$(CONFIG_SPL_LDSCRIPT:"%"=%)) endif ifeq ($(wildcard $(LDSCRIPT)),) -- cgit v1.3.1 From e83bab8403bf5c1cb81b5c0a749c50b917bc9fc3 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 5 Dec 2013 14:48:36 -0500 Subject: ARM:zynq: Correct __udelay to use lldiv Cc: Michal Simek Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/zynq/timer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c index 636322a8e57..2be253c2c3d 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -107,8 +107,7 @@ void __udelay(unsigned long usec) if (usec == 0) return; - countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) / - 1000000); + countticks = lldiv(TIMER_TICK_HZ * usec, 1000000); /* decrementing timer */ timeend = readl(&timer_base->counter) - countticks; -- cgit v1.3.1 From 49a90e29754bf4dc231e882375378996ca570cbf Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 5 Dec 2013 14:48:37 -0500 Subject: ARM:PXA: Correct tick_to_time / us_to_tick to use lldiv Cc: Marek Vasut Signed-off-by: Tom Rini Acked-by: Marek Vasut --- arch/arm/cpu/pxa/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index 78d9f327452..c4717de6a9c 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -28,12 +28,12 @@ DECLARE_GLOBAL_DATA_PTR; static unsigned long long tick_to_time(unsigned long long tick) { - return tick * CONFIG_SYS_HZ / TIMER_FREQ_HZ; + return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); } static unsigned long long us_to_tick(unsigned long long us) { - return (us * TIMER_FREQ_HZ) / 1000000; + return lldiv(us * TIMER_FREQ_HZ, 1000000); } int timer_init(void) -- cgit v1.3.1 From de04d64eda42490f94d638e8ee2e12e494e80417 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 26 Nov 2013 10:53:58 +0900 Subject: PowerPC: merge commonly-defined flags PLATFORM_RELFLAGS += -meabi PLATFORM_CPPFLAGS += -ffixed-r2 were defined in all arch/powerpc/${CPU}/config.mk. This commit moves them to arch/powerpc/config.mk. Signed-off-by: Masahiro Yamada --- arch/powerpc/config.mk | 5 +++-- arch/powerpc/cpu/74xx_7xx/config.mk | 4 +--- arch/powerpc/cpu/mpc512x/config.mk | 5 +---- arch/powerpc/cpu/mpc5xx/config.mk | 4 +--- arch/powerpc/cpu/mpc5xxx/config.mk | 4 +--- arch/powerpc/cpu/mpc824x/config.mk | 4 +--- arch/powerpc/cpu/mpc8260/config.mk | 4 +--- arch/powerpc/cpu/mpc83xx/config.mk | 5 +---- arch/powerpc/cpu/mpc85xx/config.mk | 7 ++----- arch/powerpc/cpu/mpc86xx/config.mk | 5 +---- arch/powerpc/cpu/mpc8xx/config.mk | 4 +--- arch/powerpc/cpu/ppc4xx/config.mk | 3 +-- 12 files changed, 15 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk index e6bb9357292..f75c3bf187c 100644 --- a/arch/powerpc/config.mk +++ b/arch/powerpc/config.mk @@ -9,8 +9,9 @@ CROSS_COMPILE ?= ppc_8xx- CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000 LDFLAGS_FINAL += --gc-sections -PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections -PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ +PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections \ + -meabi +PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ -ffixed-r2 PLATFORM_LDFLAGS += -n # Support generic board on PPC diff --git a/arch/powerpc/cpu/74xx_7xx/config.mk b/arch/powerpc/cpu/74xx_7xx/config.mk index 9053191602e..96812a02d82 100644 --- a/arch/powerpc/cpu/74xx_7xx/config.mk +++ b/arch/powerpc/cpu/74xx_7xx/config.mk @@ -5,6 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -ffixed-r2 -mstring +PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -mstring diff --git a/arch/powerpc/cpu/mpc512x/config.mk b/arch/powerpc/cpu/mpc512x/config.mk index 04717a485e8..03759e66250 100644 --- a/arch/powerpc/cpu/mpc512x/config.mk +++ b/arch/powerpc/cpu/mpc512x/config.mk @@ -4,7 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \ - -ffixed-r2 -msoft-float -mcpu=603e +PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 -msoft-float -mcpu=603e diff --git a/arch/powerpc/cpu/mpc5xx/config.mk b/arch/powerpc/cpu/mpc5xx/config.mk index b33f17a1ba6..31e2dc98731 100644 --- a/arch/powerpc/cpu/mpc5xx/config.mk +++ b/arch/powerpc/cpu/mpc5xx/config.mk @@ -5,6 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_5xx -ffixed-r2 -mpowerpc -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_5xx -mpowerpc -msoft-float diff --git a/arch/powerpc/cpu/mpc5xxx/config.mk b/arch/powerpc/cpu/mpc5xxx/config.mk index 57bdd2d252d..3384f6ffccc 100644 --- a/arch/powerpc/cpu/mpc5xxx/config.mk +++ b/arch/powerpc/cpu/mpc5xxx/config.mk @@ -5,7 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 \ +PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx \ -mstring -mcpu=603e -mmultiple diff --git a/arch/powerpc/cpu/mpc824x/config.mk b/arch/powerpc/cpu/mpc824x/config.mk index ef605f07975..a224bc8e73e 100644 --- a/arch/powerpc/cpu/mpc824x/config.mk +++ b/arch/powerpc/cpu/mpc824x/config.mk @@ -5,6 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -mstring -mcpu=603e -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -mstring -mcpu=603e -msoft-float diff --git a/arch/powerpc/cpu/mpc8260/config.mk b/arch/powerpc/cpu/mpc8260/config.mk index 91b0497ccbc..dfac710e630 100644 --- a/arch/powerpc/cpu/mpc8260/config.mk +++ b/arch/powerpc/cpu/mpc8260/config.mk @@ -5,7 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 -ffixed-r2 \ +PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 \ -mstring -mcpu=603e -mmultiple diff --git a/arch/powerpc/cpu/mpc83xx/config.mk b/arch/powerpc/cpu/mpc83xx/config.mk index c16a00376f2..dfce4d53b4a 100644 --- a/arch/powerpc/cpu/mpc83xx/config.mk +++ b/arch/powerpc/cpu/mpc83xx/config.mk @@ -4,7 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 \ - -ffixed-r2 -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 -msoft-float diff --git a/arch/powerpc/cpu/mpc85xx/config.mk b/arch/powerpc/cpu/mpc85xx/config.mk index 9eef539e5e1..72c964cd151 100644 --- a/arch/powerpc/cpu/mpc85xx/config.mk +++ b/arch/powerpc/cpu/mpc85xx/config.mk @@ -5,13 +5,10 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -ffixed-r2 -Wa,-me500 -msoft-float -mno-string +PLATFORM_CPPFLAGS += -Wa,-me500 -msoft-float -mno-string # -mspe=yes is needed to have -mno-spe accepted by a buggy GCC; # see "[PATCH,rs6000] make -mno-spe work as expected" on # http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00311.html -PF_CPPFLAGS_SPE := $(call cc-option,-mspe=yes) \ +PLATFORM_CPPFLAGS += $(call cc-option,-mspe=yes) \ $(call cc-option,-mno-spe) -PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_SPE) diff --git a/arch/powerpc/cpu/mpc86xx/config.mk b/arch/powerpc/cpu/mpc86xx/config.mk index 5dbf6a8472e..69a0b96eadb 100644 --- a/arch/powerpc/cpu/mpc86xx/config.mk +++ b/arch/powerpc/cpu/mpc86xx/config.mk @@ -5,7 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -ffixed-r2 -mstring -PLATFORM_CPPFLAGS += -maltivec -mabi=altivec -msoft-float +PLATFORM_CPPFLAGS += -mstring -maltivec -mabi=altivec -msoft-float diff --git a/arch/powerpc/cpu/mpc8xx/config.mk b/arch/powerpc/cpu/mpc8xx/config.mk index c04e7338c84..ee2c883665c 100644 --- a/arch/powerpc/cpu/mpc8xx/config.mk +++ b/arch/powerpc/cpu/mpc8xx/config.mk @@ -5,6 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi - -PLATFORM_CPPFLAGS += -DCONFIG_8xx -ffixed-r2 -mstring -mcpu=860 -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_8xx -mstring -mcpu=860 -msoft-float diff --git a/arch/powerpc/cpu/ppc4xx/config.mk b/arch/powerpc/cpu/ppc4xx/config.mk index c2b0f9aab60..71c2a6c729f 100644 --- a/arch/powerpc/cpu/ppc4xx/config.mk +++ b/arch/powerpc/cpu/ppc4xx/config.mk @@ -5,8 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_RELFLAGS += -meabi -PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -mstring -msoft-float +PLATFORM_CPPFLAGS += -DCONFIG_4xx -mstring -msoft-float cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') is440:=$(shell grep CONFIG_440 $(TOPDIR)/include/$(cfg)) -- cgit v1.3.1 From 31d5d4e056622ae655b8f37f09d643d2a4affbcb Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 9 Dec 2013 12:56:27 +0800 Subject: blackfin: fixing warning by including proper headers Signed-off-by: Sonic Zhang --- arch/blackfin/lib/board.c | 1 + arch/blackfin/lib/clocks.c | 5 ++++- board/bf609-ezkit/bf609-ezkit.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 17d1f468dd3..392d72d2321 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/blackfin/lib/clocks.c b/arch/blackfin/lib/clocks.c index 97795e11ac9..7ed56a72742 100644 --- a/arch/blackfin/lib/clocks.c +++ b/arch/blackfin/lib/clocks.c @@ -36,7 +36,10 @@ u_long get_vco(void) u_long get_cclk(void) { static u_long cached_cclk_pll_div, cached_cclk; - u_long div, csel, ssel; + u_long div, csel; +#ifndef CGU_DIV + u_long ssel; +#endif if (pll_is_bypassed()) return CONFIG_CLKIN_HZ; diff --git a/board/bf609-ezkit/bf609-ezkit.c b/board/bf609-ezkit/bf609-ezkit.c index 0388226db48..cfc64fe51d6 100644 --- a/board/bf609-ezkit/bf609-ezkit.c +++ b/board/bf609-ezkit/bf609-ezkit.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "soft_switch.h" -- cgit v1.3.1 From ecf9ce2149bdb884ac294e9b39c673046bb9b572 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 9 Dec 2013 14:55:21 +0800 Subject: blackfin: remove build warning Signed-off-by: Sonic Zhang --- arch/blackfin/cpu/initcode.c | 18 ++++++++++-------- arch/blackfin/include/asm/blackfin_local.h | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index ffaf1017d7b..2e640afc453 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -18,8 +18,6 @@ #include #include -#define BUG() while (1) asm volatile("emuexcpt;"); - #ifndef __ADSPBF60x__ #include #include @@ -147,8 +145,6 @@ static struct ddr_config ddr_config_table[] = { __attribute__((always_inline)) static inline void serial_init(void) { - uint32_t uart_base = UART_BASE; - #if defined(__ADSPBF54x__) || defined(__ADSPBF60x__) # ifdef BFIN_BOOT_UART_USE_RTS # define BFIN_UART_USE_RTS 1 @@ -156,6 +152,7 @@ static inline void serial_init(void) # define BFIN_UART_USE_RTS 0 # endif if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { + uint32_t uart_base = UART_BASE; size_t i; /* force RTS rather than relying on auto RTS */ @@ -195,8 +192,8 @@ static inline void serial_init(void) #if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS if (BFIN_DEBUG_EARLY_SERIAL) { - serial_early_init(uart_base); - serial_early_set_baud(uart_base, CONFIG_BAUDRATE); + serial_early_init(UART_BASE); + serial_early_set_baud(UART_BASE, CONFIG_BAUDRATE); } #endif } @@ -547,7 +544,7 @@ maybe_self_refresh(ADI_BOOT_DATA *bs) __attribute__((always_inline)) static inline u16 program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs) { - u16 vr_ctl; + u16 vr_ctl = 0; serial_putc('a'); @@ -731,6 +728,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB) serial_putc('a'); + if (BFIN_DEBUG_EARLY_SERIAL || + CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { #ifdef __ADSPBF60x__ sdivR = bfin_read_CGU_DIV(); sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7); @@ -744,6 +743,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB) divisor = vcoB * sdivR; quotient = early_division(dividend, divisor); serial_early_put_div(quotient - ANOMALY_05000230); + } + serial_putc('c'); } @@ -913,7 +914,8 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs) continue; serial_putc('z'); - uint32_t *hibernate_magic = bfin_read32(DPM0_RESTORE4); + uint32_t *hibernate_magic = + (uint32_t *)bfin_read32(DPM0_RESTORE4); SSYNC(); /* make sure memory controller is done */ if (hibernate_magic[0] == 0xDEADBEEF) { serial_putc('c'); diff --git a/arch/blackfin/include/asm/blackfin_local.h b/arch/blackfin/include/asm/blackfin_local.h index 8ea8cde691a..4d6eeab0ec1 100644 --- a/arch/blackfin/include/asm/blackfin_local.h +++ b/arch/blackfin/include/asm/blackfin_local.h @@ -81,6 +81,8 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *); # define NOP_PAD_ANOMALY_05000198 #endif +#define BFIN_BUG() while (1) asm volatile("emuexcpt;"); + #define _bfin_readX(addr, size, asm_size, asm_ext) ({ \ u32 __v; \ __asm__ __volatile__( \ @@ -111,7 +113,7 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *); sizeof(*(addr)) == 1 ? bfin_read8(addr) : \ sizeof(*(addr)) == 2 ? bfin_read16(addr) : \ sizeof(*(addr)) == 4 ? bfin_read32(addr) : \ - ({ BUG(); 0; }); \ + ({ BFIN_BUG(); 0; }); \ }) #define bfin_write(addr, val) \ do { \ @@ -119,7 +121,8 @@ do { \ case 1: bfin_write8(addr, val); break; \ case 2: bfin_write16(addr, val); break; \ case 4: bfin_write32(addr, val); break; \ - default: BUG(); \ + default: \ + BFIN_BUG(); \ } \ } while (0) -- cgit v1.3.1 From 871a57bb817a7f4129d924d72f308228180c49ef Mon Sep 17 00:00:00 2001 From: Miao Yan Date: Thu, 28 Nov 2013 17:51:38 +0800 Subject: common/cmd_bootm: extend do_bootm_vxworks to support the new VxWorks boot interface. The next version VxWorks adopts device tree (for PowerPC and ARM) as its hardware description mechanism. For PowerPC, the boot interface conforms to the ePAPR standard, which is: void (*kernel_entry)(ulong fdt_addr, ulong r4 /* 0 */, ulong r5 /* 0 */, ulong r6 /* EPAPR_MAGIC */, ulong r7 /* IMA size */, ulong r8 /* 0 */, ulong r9 /* 0 */) For ARM, the boot interface is: void (*kernel_entry)(void *fdt_addr) Signed-off-by: Miao Yan [trini: Fix build error when !CONFIG_OF_FDT is set, typo on PowerPC, missing extern ft_fixup_num_cores] Signed-off-by: Tom Rini --- arch/arm/lib/bootm.c | 23 ++++++++++++++ arch/powerpc/lib/bootm.c | 56 +++++++++++++++++++++++++++++++++ common/cmd_bootm.c | 81 +++++++++++++++++++++++++++++++++++++++++------- include/common.h | 4 +++ include/vxworks.h | 3 ++ 5 files changed, 155 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index f476a897022..dff10ba3acf 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -326,3 +326,26 @@ int bootz_setup(ulong image, ulong *start, ulong *end) } #endif /* CONFIG_CMD_BOOTZ */ + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) + int off; + + if (images->ft_addr) { + off = fdt_path_offset(images->ft_addr, "/memory"); + if (off < 0) { + if (arch_fixup_memory_node(images->ft_addr)) + puts("## WARNING: fixup memory failed!\n"); + } + } +#endif + cleanup_before_linux(); +} +void boot_jump_vxworks(bootm_headers_t *images) +{ + /* ARM VxWorks requires device tree physical address to be passed */ + ((void (*)(void *))images->ep)(images->ft_addr); +} +#endif diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e7153b04800..41fc8f7ff7a 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR; extern ulong get_effective_memsize(void); static ulong get_sp (void); +extern void ft_fixup_num_cores(void *blob); static void set_clocks_in_mhz (bd_t *kbd); #ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE @@ -277,3 +278,58 @@ static void set_clocks_in_mhz (bd_t *kbd) #endif /* CONFIG_MPC5xxx */ } } + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) + int off; + u64 base, size; + + if (!images->ft_addr) + return; + + base = (u64)gd->bd->bi_memstart; + size = (u64)gd->bd->bi_memsize; + + off = fdt_path_offset(images->ft_addr, "/memory"); + if (off < 0) + fdt_fixup_memory(images->ft_addr, base, size); + +#if defined(CONFIG_MP) +#if defined(CONFIG_MPC85xx) + ft_fixup_cpu(images->ft_addr, base + size); + ft_fixup_num_cores(images->ft_addr); +#elif defined(CONFIG_MPC86xx) + off = fdt_add_mem_rsv(images->ft_addr, + determine_mp_bootpg(NULL), (u64)4096); + if (off < 0) + printf("## WARNING %s: %s\n", __func__, fdt_strerror(off)); + ft_fixup_num_cores(images->ft_addr); +#endif + flush_cache((unsigned long)images->ft_addr, images->ft_len); +#endif +#endif +} + +void boot_jump_vxworks(bootm_headers_t *images) +{ + /* PowerPC VxWorks boot interface conforms to the ePAPR standard + * general purpuse registers: + * + * r3: Effective address of the device tree image + * r4: 0 + * r5: 0 + * r6: ePAPR magic value + * r7: shall be the size of the boot IMA in bytes + * r8: 0 + * r9: 0 + * TCR: WRC = 0, no watchdog timer reset will occur + */ + WATCHDOG_RESET(); + + ((void (*)(void *, ulong, ulong, ulong, + ulong, ulong, ulong))images->ep)(images->ft_addr, + 0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0); +} +#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 56d53b15c05..3f576594d17 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -23,6 +23,11 @@ #include #include +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) +#include +#endif + #if defined(CONFIG_CMD_USB) #include #endif @@ -120,7 +125,8 @@ static boot_os_fn do_bootm_ose; #if defined(CONFIG_BOOTM_PLAN9) static boot_os_fn do_bootm_plan9; #endif -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) static boot_os_fn do_bootm_vxworks; #endif #if defined(CONFIG_CMD_ELF) @@ -151,7 +157,8 @@ static boot_os_fn *boot_os[] = { #if defined(CONFIG_BOOTM_PLAN9) [IH_OS_PLAN9] = do_bootm_plan9, #endif -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) [IH_OS_VXWORKS] = do_bootm_vxworks, #endif #if defined(CONFIG_CMD_ELF) @@ -337,7 +344,8 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, if (((images.os.type == IH_TYPE_KERNEL) || (images.os.type == IH_TYPE_KERNEL_NOLOAD) || (images.os.type == IH_TYPE_MULTI)) && - (images.os.os == IH_OS_LINUX)) { + (images.os.os == IH_OS_LINUX || + images.os.os == IH_OS_VXWORKS)) { if (bootm_find_ramdisk(flag, argc, argv)) return 1; @@ -1682,12 +1690,66 @@ static int do_bootm_plan9(int flag, int argc, char * const argv[], } #endif /* CONFIG_BOOTM_PLAN9 */ -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) + +void do_bootvx_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) + int ret; + char *bootline; + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + struct lmb *lmb = &images->lmb; + + if (*of_flat_tree) { + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return; + + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); + if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { + bootline = getenv("bootargs"); + if (bootline) { + ret = fdt_find_and_setprop(*of_flat_tree, + "/chosen", "bootargs", + bootline, + strlen(bootline) + 1, 1); + if (ret < 0) { + printf("## ERROR: %s : %s\n", __func__, + fdt_strerror(ret)); + return; + } + } + } else { + printf("## ERROR: %s : %s\n", __func__, + fdt_strerror(ret)); + return; + } + } +#endif + + boot_prep_vxworks(images); + + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + +#if defined(CONFIG_OF_LIBFDT) + printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n", + (ulong)images->ep, (ulong)*of_flat_tree); +#else + printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); +#endif + + boot_jump_vxworks(images); + + puts("## vxWorks terminated\n"); +} + static int do_bootm_vxworks(int flag, int argc, char * const argv[], bootm_headers_t *images) { - char str[80]; - if (flag != BOOTM_STATE_OS_GO) return 0; @@ -1698,12 +1760,7 @@ static int do_bootm_vxworks(int flag, int argc, char * const argv[], } #endif - sprintf(str, "%lx", images->ep); /* write entry-point into string */ - setenv("loadaddr", str); - -#if defined(CONFIG_CMD_ELF) - do_bootvx(NULL, 0, 0, NULL); -#endif + do_bootvx_fdt(images); return 1; } diff --git a/include/common.h b/include/common.h index 8ca67f64fac..d49c51464da 100644 --- a/include/common.h +++ b/include/common.h @@ -698,6 +698,10 @@ ulong get_ddr_freq(ulong); #if defined(CONFIG_MPC85xx) typedef MPC85xx_SYS_INFO sys_info_t; void get_sys_info ( sys_info_t * ); +# if defined(CONFIG_OF_LIBFDT) + void ft_fixup_cpu(void *, u64); + void ft_fixup_num_cores(void *); +# endif #endif #if defined(CONFIG_MPC86xx) typedef MPC86xx_SYS_INFO sys_info_t; diff --git a/include/vxworks.h b/include/vxworks.h index c5d1577f9cb..122043c941e 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -9,6 +9,9 @@ #define _VXWORKS_H_ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +void boot_prep_vxworks(bootm_headers_t *images); +void boot_jump_vxworks(bootm_headers_t *images); +void do_bootvx_fdt(bootm_headers_t *images); /* * Use bootaddr to find the location in memory that VxWorks -- cgit v1.3.1 From e8a8b8246a5e7dee9db19b14b31039389ccf99af Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 28 Nov 2013 12:09:59 +0900 Subject: Makefile: Select objects by CONFIG_ rather than $(ARCH) or $(CPU) Convert like follows: CPU mpc83xx -> CONFIG_MPC83xx CPU mpc85xx -> CONFIG_MPC85xx CPU mpc86xx -> CONFIG_MPC86xx CPU mpc5xxx -> CONFIG_MPC5xxx CPU mpc8xx -> CONFIG_8xx CPU mpc8260 -> CONFIG_8260 CPU ppc4xx -> CONFIG_4xx CPU x86 -> CONFIG_X86 ARCH x86 -> CONFIG_X86 ARCH powerpc -> CONFIG_PPC Signed-off-by: Masahiro Yamada --- Makefile | 12 ++++-------- arch/powerpc/cpu/Makefile | 6 +++--- arch/powerpc/cpu/mpc8xxx/Makefile | 6 ++---- examples/standalone/Makefile | 26 +++++++++++++------------- post/Makefile | 6 +++--- spl/Makefile | 17 +++++------------ 6 files changed, 30 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/Makefile b/Makefile index a0e59737a83..ca3c5c3c5da 100644 --- a/Makefile +++ b/Makefile @@ -213,15 +213,11 @@ endif ######################################################################### # U-Boot objects....order is important (i.e. start must be first) -OBJS = $(CPUDIR)/start.o -ifeq ($(CPU),ppc4xx) -OBJS += $(CPUDIR)/resetvec.o -endif -ifeq ($(CPU),mpc85xx) -OBJS += $(CPUDIR)/resetvec.o -endif +head-y := $(CPUDIR)/start.o +head-$(CONFIG_4xx) += arch/powerpc/cpu/ppc4xx/resetvec.o +head-$(CONFIG_MPC85xx) += arch/powerpc/cpu/mpc85xx/resetvec.o -OBJS := $(addprefix $(obj),$(OBJS)) +OBJS := $(addprefix $(obj),$(head-y)) HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n) diff --git a/arch/powerpc/cpu/Makefile b/arch/powerpc/cpu/Makefile index d630abe1da5..88b5298be0c 100644 --- a/arch/powerpc/cpu/Makefile +++ b/arch/powerpc/cpu/Makefile @@ -1,3 +1,3 @@ -ifneq ($(filter mpc83xx mpc85xx mpc86xx,$(CPU)),) -obj-y += mpc8xxx/ -endif +obj-$(CONFIG_MPC83xx) += mpc8xxx/ +obj-$(CONFIG_MPC85xx) += mpc8xxx/ +obj-$(CONFIG_MPC86xx) += mpc8xxx/ diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile index f66ee2e4239..e95539e0a3e 100644 --- a/arch/powerpc/cpu/mpc8xxx/Makefile +++ b/arch/powerpc/cpu/mpc8xxx/Makefile @@ -19,10 +19,8 @@ ifdef MINIMAL obj-$(CONFIG_FSL_LAW) += law.o else - -ifneq ($(CPU),mpc83xx) -obj-y += cpu.o -endif +obj-$(CONFIG_MPC85xx) += cpu.o +obj-$(CONFIG_MPC86xx) += cpu.o obj-$(CONFIG_OF_LIBFDT) += fdt.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index f4f102b3e1c..6e7500dc75d 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -7,25 +7,27 @@ include $(TOPDIR)/config.mk -ELF-$(ARCH) := -ELF-$(CPU) := ELF-y := hello_world ELF-$(CONFIG_SMC91111) += smc91111_eeprom ELF-$(CONFIG_SMC911X) += smc911x_eeprom ELF-$(CONFIG_SPI_FLASH_ATMEL) += atmel_df_pow2 -ELF-i386 += 82559_eeprom -ELF-mpc5xxx += interrupt -ELF-mpc8xx += test_burst timer -ELF-mpc8260 += mem_to_mem_idma2intr -ELF-ppc += sched +# TODO: +# - Fix the warning of 82559_eeprom.c and uncomment the following +# or +# - Delete 82559_eeprom.c and the following line +#ELF-$(CONFIG_X86) += 82559_eeprom +ELF-$(CONFIG_MPC5xxx) += interrupt +ELF-$(CONFIG_8xx) += test_burst timer +ELF-$(CONFIG_8260) += mem_to_mem_idma2intr +ELF-$(CONFIG_PPC) += sched # # Some versions of make do not handle trailing white spaces properly; # leading to build failures. The problem was found with GNU Make 3.80. # Using 'strip' as a workaround for the problem. # -ELF := $(strip $(ELF-y) $(ELF-$(ARCH)) $(ELF-$(CPU))) +ELF := $(strip $(ELF-y)) SREC := $(addsuffix .srec,$(ELF)) BIN := $(addsuffix .bin,$(ELF)) @@ -34,11 +36,9 @@ COBJS := $(ELF:=.o) LIB = $(obj)libstubs.o -LIBAOBJS-$(ARCH) := -LIBAOBJS-$(CPU) := -LIBAOBJS-ppc += $(ARCH)_longjmp.o $(ARCH)_setjmp.o -LIBAOBJS-mpc8xx += test_burst_lib.o -LIBAOBJS := $(LIBAOBJS-$(ARCH)) $(LIBAOBJS-$(CPU)) +LIBAOBJS-$(CONFIG_PPC) += ppc_longjmp.o ppc_setjmp.o +LIBAOBJS-$(CONFIG_8xx) += test_burst_lib.o +LIBAOBJS := $(LIBAOBJS-y) LIBCOBJS = stubs.o diff --git a/post/Makefile b/post/Makefile index 20a463a3453..2fa6f8a295a 100644 --- a/post/Makefile +++ b/post/Makefile @@ -10,9 +10,9 @@ obj-$(CONFIG_POST_STD_LIST) += tests.o obj-y += drivers/ obj-$(CONFIG_PPC) += lib_powerpc/ -ifneq ($(filter mpc83xx mpc8xx ppc4xx,$(CPU)),) -obj-y += cpu/$(CPU)/ -endif +obj-$(CONFIG_MPC83xx) += cpu/mpc83xx/ +obj-$(CONFIG_8xx) += cpu/mpc8xx/ +obj-$(CONFIG_4xx) += cpu/ppc4xx/ ifneq ($(filter lwmon lwmon5 netta pdm360ng,$(BOARD)),) obj-y += board/$(BOARD)/ endif diff --git a/spl/Makefile b/spl/Makefile index ec0983170a0..1e88d7469f4 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -42,17 +42,10 @@ else START_PATH := $(CPUDIR) endif -START := $(START_PATH)/start.o -ifeq ($(CPU),x86) -START += $(START_PATH)/start16.o -START += $(START_PATH)/resetvec.o -endif -ifeq ($(CPU),ppc4xx) -START += $(START_PATH)/resetvec.o -endif -ifeq ($(CPU),mpc85xx) -START += $(START_PATH)/resetvec.o -endif +head-y := $(START_PATH)/start.o +head-$(CONFIG_X86) += $(START_PATH)/start16.o $(START_PATH)/resetvec.o +head-$(CONFIG_4xx) += $(START_PATH)/resetvec.o +head-$(CONFIG_MPC85xx) += $(START_PATH)/resetvec.o LIBS-y += arch/$(ARCH)/lib/ @@ -105,7 +98,7 @@ PLATFORM_LIBGCC = $(SPLTREE)/arch/$(ARCH)/lib/libgcc.o PLATFORM_LIBS := $(filter-out %/libgcc.o, $(filter-out -lgcc, $(PLATFORM_LIBS))) $(PLATFORM_LIBGCC) endif -START := $(addprefix $(SPLTREE)/,$(START)) +START := $(addprefix $(SPLTREE)/,$(head-y)) LIBS := $(addprefix $(SPLTREE)/,$(sort $(LIBS-y))) __START := $(subst $(obj),,$(START)) -- cgit v1.3.1 From 320cf350801f30875fe5749eee74aed242573031 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Dec 2013 16:03:44 +0900 Subject: sh: add support for sh7753evb board The SH7753 EVB board has SH7753, 512MB DDR3-SDRAM, SPI ROM, Gigabit Ethernet, and eMMC. This patch support the following functions: - 512MB DDR3-SDRAM, SCIF4, SPI ROM, Gigabit Ethernet, eMMC Signed-off-by: Yoshihiro Shimoda Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/include/asm/cpu_sh4.h | 2 + arch/sh/include/asm/cpu_sh7753.h | 197 +++++++++++++++ board/renesas/sh7753evb/Makefile | 7 + board/renesas/sh7753evb/lowlevel_init.S | 416 ++++++++++++++++++++++++++++++++ board/renesas/sh7753evb/sh7753evb.c | 326 +++++++++++++++++++++++++ board/renesas/sh7753evb/spi-boot.c | 134 ++++++++++ board/renesas/sh7753evb/u-boot.lds | 81 +++++++ boards.cfg | 1 + doc/README.sh7753evb | 67 +++++ include/configs/sh7753evb.h | 137 +++++++++++ 10 files changed, 1368 insertions(+) create mode 100644 arch/sh/include/asm/cpu_sh7753.h create mode 100644 board/renesas/sh7753evb/Makefile create mode 100644 board/renesas/sh7753evb/lowlevel_init.S create mode 100644 board/renesas/sh7753evb/sh7753evb.c create mode 100644 board/renesas/sh7753evb/spi-boot.c create mode 100644 board/renesas/sh7753evb/u-boot.lds create mode 100644 doc/README.sh7753evb create mode 100644 include/configs/sh7753evb.h (limited to 'arch') diff --git a/arch/sh/include/asm/cpu_sh4.h b/arch/sh/include/asm/cpu_sh4.h index 9181d59a947..9f48e4fe048 100644 --- a/arch/sh/include/asm/cpu_sh4.h +++ b/arch/sh/include/asm/cpu_sh4.h @@ -37,6 +37,8 @@ # include #elif defined (CONFIG_CPU_SH7752) # include +#elif defined (CONFIG_CPU_SH7753) +# include #elif defined (CONFIG_CPU_SH7757) # include #elif defined (CONFIG_CPU_SH7763) diff --git a/arch/sh/include/asm/cpu_sh7753.h b/arch/sh/include/asm/cpu_sh7753.h new file mode 100644 index 00000000000..cd0e0bba6c2 --- /dev/null +++ b/arch/sh/include/asm/cpu_sh7753.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_CPU_SH7753_H_ +#define _ASM_CPU_SH7753_H_ + +#define CCR 0xFF00001C +#define WTCNT 0xFFCC0000 +#define CCR_CACHE_INIT 0x0000090b +#define CACHE_OC_NUM_WAYS 1 + +#ifndef __ASSEMBLY__ /* put C only stuff in this section */ +/* MMU */ +struct mmu_regs { + unsigned int reserved[4]; + unsigned int mmucr; +}; +#define MMU_BASE ((struct mmu_regs *)0xff000000) + +/* Watchdog */ +#define WTCSR0 0xffcc0002 +#define WRSTCSR_R 0xffcc0003 +#define WRSTCSR_W 0xffcc0002 +#define WTCSR_PREFIX 0xa500 +#define WRSTCSR_PREFIX 0x6900 +#define WRSTCSR_WOVF_PREFIX 0x9600 + +/* SCIF */ +#define SCIF0_BASE 0xfe4b0000 /* The real name is SCIF2 */ +#define SCIF1_BASE 0xfe4c0000 /* The real name is SCIF3 */ +#define SCIF2_BASE 0xfe4d0000 /* The real name is SCIF4 */ + +/* TMU0 */ +#define TMU_BASE 0xFE430000 + +/* ETHER, GETHER MAC address */ +struct ether_mac_regs { + unsigned int reserved[114]; + unsigned int mahr; + unsigned int reserved2; + unsigned int malr; +}; +#define GETHER0_MAC_BASE ((struct ether_mac_regs *)0xfee0400) +#define GETHER1_MAC_BASE ((struct ether_mac_regs *)0xfee0c00) +#define ETHER0_MAC_BASE ((struct ether_mac_regs *)0xfef0000) +#define ETHER1_MAC_BASE ((struct ether_mac_regs *)0xfef0800) + +/* GETHER */ +struct gether_control_regs { + unsigned int gbecont; +}; +#define GETHER_CONTROL_BASE ((struct gether_control_regs *)0xffc10100) +#define GBECONT_RMII1 0x00020000 +#define GBECONT_RMII0 0x00010000 + +/* SerMux */ +struct sermux_regs { + unsigned char smr0; + unsigned char smr1; + unsigned char smr2; + unsigned char smr3; + unsigned char smr4; + unsigned char smr5; +}; +#define SERMUX_BASE ((struct sermux_regs *)0xfe470000) + + +/* USB0/1 */ +struct usb_common_regs { + unsigned short reserved[129]; + unsigned short suspmode; +}; +#define USB0_COMMON_BASE ((struct usb_common_regs *)0xfe450000) +#define USB1_COMMON_BASE ((struct usb_common_regs *)0xfe4f0000) + +struct usb0_phy_regs { + unsigned short reset; + unsigned short reserved[4]; + unsigned short portsel; +}; +#define USB0_PHY_BASE ((struct usb0_phy_regs *)0xfe5f0000) + +struct usb1_port_regs { + unsigned int port1sel; + unsigned int reserved; + unsigned int usb1intsts; +}; +#define USB1_PORT_BASE ((struct usb1_port_regs *)0xfe4f2000) + +struct usb1_alignment_regs { + unsigned int ehcidatac; /* 0xfe4fe018 */ + unsigned int reserved[63]; + unsigned int ohcidatac; +}; +#define USB1_ALIGNMENT_BASE ((struct usb1_alignment_regs *)0xfe4fe018) + +/* GPIO */ +struct gpio_regs { + unsigned short pacr; + unsigned short pbcr; + unsigned short pccr; + unsigned short pdcr; + unsigned short pecr; + unsigned short pfcr; + unsigned short pgcr; + unsigned short phcr; + unsigned short picr; + unsigned short pjcr; + unsigned short pkcr; + unsigned short plcr; + unsigned short pmcr; + unsigned short pncr; + unsigned short pocr; + unsigned short reserved; + unsigned short pqcr; + unsigned short prcr; + unsigned short pscr; + unsigned short ptcr; + unsigned short pucr; + unsigned short pvcr; + unsigned short pwcr; + unsigned short pxcr; + unsigned short pycr; + unsigned short pzcr; + unsigned char padr; + unsigned char reserved_a; + unsigned char pbdr; + unsigned char reserved_b; + unsigned char pcdr; + unsigned char reserved_c; + unsigned char pddr; + unsigned char reserved_d; + unsigned char pedr; + unsigned char reserved_e; + unsigned char pfdr; + unsigned char reserved_f; + unsigned char pgdr; + unsigned char reserved_g; + unsigned char phdr; + unsigned char reserved_h; + unsigned char pidr; + unsigned char reserved_i; + unsigned char pjdr; + unsigned char reserved_j; + unsigned char pkdr; + unsigned char reserved_k; + unsigned char pldr; + unsigned char reserved_l; + unsigned char pmdr; + unsigned char reserved_m; + unsigned char pndr; + unsigned char reserved_n; + unsigned char podr; + unsigned char reserved_o; + unsigned char ppdr; + unsigned char reserved_p; + unsigned char pqdr; + unsigned char reserved_q; + unsigned char prdr; + unsigned char reserved_r; + unsigned char psdr; + unsigned char reserved_s; + unsigned char ptdr; + unsigned char reserved_t; + unsigned char pudr; + unsigned char reserved_u; + unsigned char pvdr; + unsigned char reserved_v; + unsigned char pwdr; + unsigned char reserved_w; + unsigned char pxdr; + unsigned char reserved_x; + unsigned char pydr; + unsigned char reserved_y; + unsigned char pzdr; + unsigned char reserved_z; + unsigned short ncer; + unsigned short ncmcr; + unsigned short nccsr; + unsigned char reserved2[2]; + unsigned short psel0; /* +0x70 */ + unsigned short psel1; + unsigned short psel2; + unsigned short psel3; + unsigned short psel4; + unsigned short psel5; + unsigned short psel6; + unsigned short reserved3[2]; + unsigned short psel7; +}; +#define GPIO_BASE ((struct gpio_regs *)0xffec0000) + +#endif /* ifndef __ASSEMBLY__ */ +#endif /* _ASM_CPU_SH7753_H_ */ diff --git a/board/renesas/sh7753evb/Makefile b/board/renesas/sh7753evb/Makefile new file mode 100644 index 00000000000..f7c8e949f9f --- /dev/null +++ b/board/renesas/sh7753evb/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2012 Yoshihiro Shimoda +# +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := sh7753evb.o spi-boot.o +obj-y += lowlevel_init.o diff --git a/board/renesas/sh7753evb/lowlevel_init.S b/board/renesas/sh7753evb/lowlevel_init.S new file mode 100644 index 00000000000..21987a51e89 --- /dev/null +++ b/board/renesas/sh7753evb/lowlevel_init.S @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2013 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +.macro or32, addr, data + mov.l \addr, r1 + mov.l \data, r0 + mov.l @r1, r2 + or r2, r0 + mov.l r0, @r1 +.endm + +.macro wait_DBCMD + mov.l DBWAIT_A, r0 + mov.l @r0, r1 +.endm + + .global lowlevel_init + .section .spiboot1.text + .align 2 + +lowlevel_init: + mov #0, r14 + mova 2f, r0 + mov.l PC_MASK, r1 + tst r0, r1 + bf 2f + + bra exit_pmb + nop + + .align 2 + +/* If CPU runs on SDRAM (PC=0x5???????) or not. */ +PC_MASK: .long 0x20000000 + +2: + mov #1, r14 + + mov.l EXPEVT_A, r0 + mov.l @r0, r0 + mov.l EXPEVT_POWER_ON_RESET, r1 + cmp/eq r0, r1 + bt 1f + + /* + * If EXPEVT value is manual reset or tlb multipul-hit, + * initialization of DBSC3 is not necessary. + */ + bra exit_ddr + nop + +1: + /*------- Reset -------*/ + write32 MRSTCR0_A, MRSTCR0_D + write32 MRSTCR1_A, MRSTCR1_D + + /* For Core Reset */ + mov.l DBACEN_A, r0 + mov.l @r0, r0 + cmp/eq #0, r0 + bt 3f + + /* + * If DBACEN == 1(DBSC was already enabled), we have to avoid the + * initialization of DDR3-SDRAM. + */ + bra exit_ddr + nop + +3: + /*------- DBSC3 -------*/ + /* oscillation stabilization time */ + wait_timer WAIT_OSC_TIME + + /* step 3 */ + write32 DBKIND_A, DBKIND_D + + /* step 4 */ + write32 DBCONF_A, DBCONF_D + write32 DBTR0_A, DBTR0_D + write32 DBTR1_A, DBTR1_D + write32 DBTR2_A, DBTR2_D + write32 DBTR3_A, DBTR3_D + write32 DBTR4_A, DBTR4_D + write32 DBTR5_A, DBTR5_D + write32 DBTR6_A, DBTR6_D + write32 DBTR7_A, DBTR7_D + write32 DBTR8_A, DBTR8_D + write32 DBTR9_A, DBTR9_D + write32 DBTR10_A, DBTR10_D + write32 DBTR11_A, DBTR11_D + write32 DBTR12_A, DBTR12_D + write32 DBTR13_A, DBTR13_D + write32 DBTR14_A, DBTR14_D + write32 DBTR15_A, DBTR15_D + write32 DBTR16_A, DBTR16_D + write32 DBTR17_A, DBTR17_D + write32 DBTR18_A, DBTR18_D + write32 DBTR19_A, DBTR19_D + write32 DBRNK0_A, DBRNK0_D + write32 DBADJ0_A, DBADJ0_D + write32 DBADJ2_A, DBADJ2_D + + /* step 5 */ + write32 DBCMD_A, DBCMD_RSTL_VAL + wait_timer WAIT_30US + + /* step 6 */ + write32 DBCMD_A, DBCMD_PDEN_VAL + + /* step 7 */ + write32 DBPDCNT3_A, DBPDCNT3_D + + /* step 8 */ + write32 DBPDCNT1_A, DBPDCNT1_D + write32 DBPDCNT2_A, DBPDCNT2_D + write32 DBPDLCK_A, DBPDLCK_D + write32 DBPDRGA_A, DBPDRGA_D + write32 DBPDRGD_A, DBPDRGD_D + + /* step 9 */ + wait_timer WAIT_30US + + /* step 10 */ + write32 DBPDCNT0_A, DBPDCNT0_D + + /* step 11 */ + wait_timer WAIT_30US + wait_timer WAIT_30US + + /* step 12 */ + write32 DBCMD_A, DBCMD_WAIT_VAL + wait_DBCMD + + /* step 13 */ + write32 DBCMD_A, DBCMD_RSTH_VAL + wait_DBCMD + + /* step 14 */ + write32 DBCMD_A, DBCMD_WAIT_VAL + write32 DBCMD_A, DBCMD_WAIT_VAL + write32 DBCMD_A, DBCMD_WAIT_VAL + write32 DBCMD_A, DBCMD_WAIT_VAL + + /* step 15 */ + write32 DBCMD_A, DBCMD_PDXT_VAL + + /* step 16 */ + write32 DBCMD_A, DBCMD_MRS2_VAL + + /* step 17 */ + write32 DBCMD_A, DBCMD_MRS3_VAL + + /* step 18 */ + write32 DBCMD_A, DBCMD_MRS1_VAL + + /* step 19 */ + write32 DBCMD_A, DBCMD_MRS0_VAL + write32 DBPDNCNF_A, DBPDNCNF_D + + /* step 20 */ + write32 DBCMD_A, DBCMD_ZQCL_VAL + + write32 DBCMD_A, DBCMD_REF_VAL + write32 DBCMD_A, DBCMD_REF_VAL + wait_DBCMD + + /* step 21 */ + write32 DBCALTR_A, DBCALTR_D + + /* step 22 */ + write32 DBRFCNF0_A, DBRFCNF0_D + write32 DBRFCNF1_A, DBRFCNF1_D + write32 DBRFCNF2_A, DBRFCNF2_D + + /* step 23 */ + write32 DBCALCNF_A, DBCALCNF_D + + /* step 24 */ + write32 DBRFEN_A, DBRFEN_D + write32 DBCMD_A, DBCMD_SRXT_VAL + + /* step 25 */ + write32 DBACEN_A, DBACEN_D + + /* step 26 */ + wait_DBCMD + + bra exit_ddr + nop + + .align 2 + +EXPEVT_A: .long 0xff000024 +EXPEVT_POWER_ON_RESET: .long 0x00000000 + +/*------- Reset -------*/ +MRSTCR0_A: .long 0xffd50030 +MRSTCR0_D: .long 0xfe1ffe7f +MRSTCR1_A: .long 0xffd50034 +MRSTCR1_D: .long 0xfff3ffff + +/*------- DBSC3 -------*/ +DBCMD_A: .long 0xfe800018 +DBKIND_A: .long 0xfe800020 +DBCONF_A: .long 0xfe800024 +DBTR0_A: .long 0xfe800040 +DBTR1_A: .long 0xfe800044 +DBTR2_A: .long 0xfe800048 +DBTR3_A: .long 0xfe800050 +DBTR4_A: .long 0xfe800054 +DBTR5_A: .long 0xfe800058 +DBTR6_A: .long 0xfe80005c +DBTR7_A: .long 0xfe800060 +DBTR8_A: .long 0xfe800064 +DBTR9_A: .long 0xfe800068 +DBTR10_A: .long 0xfe80006c +DBTR11_A: .long 0xfe800070 +DBTR12_A: .long 0xfe800074 +DBTR13_A: .long 0xfe800078 +DBTR14_A: .long 0xfe80007c +DBTR15_A: .long 0xfe800080 +DBTR16_A: .long 0xfe800084 +DBTR17_A: .long 0xfe800088 +DBTR18_A: .long 0xfe80008c +DBTR19_A: .long 0xfe800090 +DBRNK0_A: .long 0xfe800100 +DBPDCNT0_A: .long 0xfe800200 +DBPDCNT1_A: .long 0xfe800204 +DBPDCNT2_A: .long 0xfe800208 +DBPDCNT3_A: .long 0xfe80020c +DBPDLCK_A: .long 0xfe800280 +DBPDRGA_A: .long 0xfe800290 +DBPDRGD_A: .long 0xfe8002a0 +DBADJ0_A: .long 0xfe8000c0 +DBADJ2_A: .long 0xfe8000c8 +DBRFCNF0_A: .long 0xfe8000e0 +DBRFCNF1_A: .long 0xfe8000e4 +DBRFCNF2_A: .long 0xfe8000e8 +DBCALCNF_A: .long 0xfe8000f4 +DBRFEN_A: .long 0xfe800014 +DBACEN_A: .long 0xfe800010 +DBWAIT_A: .long 0xfe80001c +DBCALTR_A: .long 0xfe8000f8 +DBPDNCNF_A: .long 0xfe800180 + +WAIT_OSC_TIME: .long 6000 +WAIT_30US: .long 13333 + +DBCMD_RSTL_VAL: .long 0x20000000 +DBCMD_PDEN_VAL: .long 0x1000d73c +DBCMD_WAIT_VAL: .long 0x0000d73c +DBCMD_RSTH_VAL: .long 0x2100d73c +DBCMD_PDXT_VAL: .long 0x110000c8 +DBCMD_MRS0_VAL: .long 0x28000930 +DBCMD_MRS1_VAL: .long 0x29000004 +DBCMD_MRS2_VAL: .long 0x2a000008 +DBCMD_MRS3_VAL: .long 0x2b000000 +DBCMD_ZQCL_VAL: .long 0x03000200 +DBCMD_REF_VAL: .long 0x0c000000 +DBCMD_SRXT_VAL: .long 0x19000000 +DBKIND_D: .long 0x00000007 +DBCONF_D: .long 0x0f030a01 +DBTR0_D: .long 0x00000007 +DBTR1_D: .long 0x00000006 +DBTR2_D: .long 0x00000000 +DBTR3_D: .long 0x00000007 +DBTR4_D: .long 0x00070007 +DBTR5_D: .long 0x0000001b +DBTR6_D: .long 0x00000014 +DBTR7_D: .long 0x00000004 +DBTR8_D: .long 0x00000014 +DBTR9_D: .long 0x00000004 +DBTR10_D: .long 0x00000008 +DBTR11_D: .long 0x00000007 +DBTR12_D: .long 0x0000000e +DBTR13_D: .long 0x000000a0 +DBTR14_D: .long 0x00060006 +DBTR15_D: .long 0x00000003 +DBTR16_D: .long 0x00160002 +DBTR17_D: .long 0x000c0000 +DBTR18_D: .long 0x00000200 +DBTR19_D: .long 0x00000040 +DBRNK0_D: .long 0x00000001 +DBPDCNT0_D: .long 0x00000001 +DBPDCNT1_D: .long 0x00000001 +DBPDCNT2_D: .long 0x00000000 +DBPDCNT3_D: .long 0x00004010 +DBPDLCK_D: .long 0x0000a55a +DBPDRGA_D: .long 0x00000028 +DBPDRGD_D: .long 0x00017100 + +DBADJ0_D: .long 0x00010000 +DBADJ2_D: .long 0x18061806 +DBRFCNF0_D: .long 0x000001ff +DBRFCNF1_D: .long 0x00081040 +DBRFCNF2_D: .long 0x00000000 +DBCALCNF_D: .long 0x0000ffff +DBRFEN_D: .long 0x00000001 +DBACEN_D: .long 0x00000001 +DBCALTR_D: .long 0x08200820 +DBPDNCNF_D: .long 0x00000001 + + .align 2 +exit_ddr: +#if defined(CONFIG_SH_32BIT) + /*------- set PMB -------*/ + write32 PASCR_A, PASCR_29BIT_D + write32 MMUCR_A, MMUCR_D + + /***************************************************************** + * ent virt phys v sz c wt + * 0 0xa0000000 0x00000000 1 128M 0 1 + * 1 0xa8000000 0x48000000 1 128M 0 1 + * 5 0x88000000 0x48000000 1 128M 1 1 + */ + write32 PMB_ADDR_SPIBOOT_A, PMB_ADDR_SPIBOOT_D + write32 PMB_DATA_SPIBOOT_A, PMB_DATA_SPIBOOT_D + write32 PMB_ADDR_DDR_C1_A, PMB_ADDR_DDR_C1_D + write32 PMB_DATA_DDR_C1_A, PMB_DATA_DDR_C1_D + write32 PMB_ADDR_DDR_N1_A, PMB_ADDR_DDR_N1_D + write32 PMB_DATA_DDR_N1_A, PMB_DATA_DDR_N1_D + + write32 PMB_ADDR_ENTRY2, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY3, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY4, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY6, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY7, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY8, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY9, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY10, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY11, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY12, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY13, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY14, PMB_ADDR_NOT_USE_D + write32 PMB_ADDR_ENTRY15, PMB_ADDR_NOT_USE_D + + write32 PASCR_A, PASCR_INIT + mov.l DUMMY_ADDR, r0 + icbi @r0 +#endif /* if defined(CONFIG_SH_32BIT) */ + +exit_pmb: + /* CPU is running on ILRAM? */ + mov r14, r0 + tst #1, r0 + bt 1f + + mov.l _stack_ilram, r15 + mov.l _spiboot_main, r0 +100: bsrf r0 + nop + + .align 2 +_spiboot_main: .long (spiboot_main - (100b + 4)) +_stack_ilram: .long 0xe5204000 + +1: + write32 CCR_A, CCR_D + + rts + nop + + .align 2 + +#if defined(CONFIG_SH_32BIT) +/*------- set PMB -------*/ +PMB_ADDR_SPIBOOT_A: .long PMB_ADDR_BASE(0) +PMB_ADDR_DDR_N1_A: .long PMB_ADDR_BASE(1) +PMB_ADDR_DDR_C1_A: .long PMB_ADDR_BASE(5) +PMB_ADDR_ENTRY2: .long PMB_ADDR_BASE(2) +PMB_ADDR_ENTRY3: .long PMB_ADDR_BASE(3) +PMB_ADDR_ENTRY4: .long PMB_ADDR_BASE(4) +PMB_ADDR_ENTRY6: .long PMB_ADDR_BASE(6) +PMB_ADDR_ENTRY7: .long PMB_ADDR_BASE(7) +PMB_ADDR_ENTRY8: .long PMB_ADDR_BASE(8) +PMB_ADDR_ENTRY9: .long PMB_ADDR_BASE(9) +PMB_ADDR_ENTRY10: .long PMB_ADDR_BASE(10) +PMB_ADDR_ENTRY11: .long PMB_ADDR_BASE(11) +PMB_ADDR_ENTRY12: .long PMB_ADDR_BASE(12) +PMB_ADDR_ENTRY13: .long PMB_ADDR_BASE(13) +PMB_ADDR_ENTRY14: .long PMB_ADDR_BASE(14) +PMB_ADDR_ENTRY15: .long PMB_ADDR_BASE(15) + +PMB_ADDR_SPIBOOT_D: .long mk_pmb_addr_val(0xa0) +PMB_ADDR_DDR_C1_D: .long mk_pmb_addr_val(0x88) +PMB_ADDR_DDR_N1_D: .long mk_pmb_addr_val(0xa8) +PMB_ADDR_NOT_USE_D: .long 0x00000000 + +PMB_DATA_SPIBOOT_A: .long PMB_DATA_BASE(0) +PMB_DATA_DDR_N1_A: .long PMB_DATA_BASE(1) +PMB_DATA_DDR_C1_A: .long PMB_DATA_BASE(5) + +/* ppn ub v s1 s0 c wt */ +PMB_DATA_SPIBOOT_D: .long mk_pmb_data_val(0x00, 0, 1, 1, 0, 0, 1) +PMB_DATA_DDR_C1_D: .long mk_pmb_data_val(0x48, 0, 1, 1, 0, 1, 1) +PMB_DATA_DDR_N1_D: .long mk_pmb_data_val(0x48, 1, 1, 1, 0, 0, 1) + +PASCR_A: .long 0xff000070 +DUMMY_ADDR: .long 0xa0000000 +PASCR_29BIT_D: .long 0x00000000 +PASCR_INIT: .long 0x80000080 +MMUCR_A: .long 0xff000010 +MMUCR_D: .long 0x00000004 /* clear ITLB */ +#endif /* CONFIG_SH_32BIT */ + +CCR_A: .long CCR +CCR_D: .long CCR_CACHE_INIT diff --git a/board/renesas/sh7753evb/sh7753evb.c b/board/renesas/sh7753evb/sh7753evb.c new file mode 100644 index 00000000000..42b920fb333 --- /dev/null +++ b/board/renesas/sh7753evb/sh7753evb.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +int checkboard(void) +{ + puts("BOARD: SH7753 EVB\n"); + + return 0; +} + +static void init_gpio(void) +{ + struct gpio_regs *gpio = GPIO_BASE; + struct sermux_regs *sermux = SERMUX_BASE; + + /* GPIO */ + writew(0x0000, &gpio->pacr); /* GETHER */ + writew(0x0001, &gpio->pbcr); /* INTC */ + writew(0x0000, &gpio->pccr); /* PWMU, INTC */ + writew(0x0000, &gpio->pdcr); /* SPI0 */ + writew(0xeaff, &gpio->pecr); /* GPIO */ + writew(0x0000, &gpio->pfcr); /* WDT */ + writew(0x0004, &gpio->pgcr); /* SPI0, GETHER MDIO gate(PTG1) */ + writew(0x0000, &gpio->phcr); /* SPI1 */ + writew(0x0000, &gpio->picr); /* SDHI */ + writew(0x0000, &gpio->pjcr); /* SCIF4 */ + writew(0x0003, &gpio->pkcr); /* SerMux */ + writew(0x0000, &gpio->plcr); /* SerMux */ + writew(0x0000, &gpio->pmcr); /* RIIC */ + writew(0x0000, &gpio->pncr); /* USB, SGPIO */ + writew(0x0000, &gpio->pocr); /* SGPIO */ + writew(0xd555, &gpio->pqcr); /* GPIO */ + writew(0x0000, &gpio->prcr); /* RIIC */ + writew(0x0000, &gpio->pscr); /* RIIC */ + writew(0x0000, &gpio->ptcr); /* STATUS */ + writeb(0x00, &gpio->pudr); + writew(0x5555, &gpio->pucr); /* Debug LED */ + writew(0x0000, &gpio->pvcr); /* RSPI */ + writew(0x0000, &gpio->pwcr); /* EVC */ + writew(0x0000, &gpio->pxcr); /* LBSC */ + writew(0x0000, &gpio->pycr); /* LBSC */ + writew(0x0000, &gpio->pzcr); /* eMMC */ + writew(0xfe00, &gpio->psel0); + writew(0x0000, &gpio->psel1); + writew(0x3000, &gpio->psel2); + writew(0xff00, &gpio->psel3); + writew(0x771f, &gpio->psel4); + writew(0x0ffc, &gpio->psel5); + writew(0x00ff, &gpio->psel6); + writew(0xfc00, &gpio->psel7); + + writeb(0x10, &sermux->smr0); /* SMR0: SerMux mode 0 */ +} + +static void init_usb_phy(void) +{ + struct usb_common_regs *common0 = USB0_COMMON_BASE; + struct usb_common_regs *common1 = USB1_COMMON_BASE; + struct usb0_phy_regs *phy = USB0_PHY_BASE; + struct usb1_port_regs *port = USB1_PORT_BASE; + struct usb1_alignment_regs *align = USB1_ALIGNMENT_BASE; + + writew(0x0100, &phy->reset); /* set reset */ + /* port0 = USB0, port1 = USB1 */ + writew(0x0002, &phy->portsel); + writel(0x0001, &port->port1sel); /* port1 = Host */ + writew(0x0111, &phy->reset); /* clear reset */ + + writew(0x4000, &common0->suspmode); + writew(0x4000, &common1->suspmode); + +#if defined(__LITTLE_ENDIAN) + writel(0x00000000, &align->ehcidatac); + writel(0x00000000, &align->ohcidatac); +#endif +} + +static void init_gether_mdio(void) +{ + struct gpio_regs *gpio = GPIO_BASE; + + writew(readw(&gpio->pgcr) | 0x0004, &gpio->pgcr); + writeb(readb(&gpio->pgdr) | 0x02, &gpio->pgdr); /* Use ET0-MDIO */ +} + +static void set_mac_to_sh_giga_eth_register(int channel, char *mac_string) +{ + struct ether_mac_regs *ether; + unsigned char mac[6]; + unsigned long val; + + eth_parse_enetaddr(mac_string, mac); + + if (!channel) + ether = GETHER0_MAC_BASE; + else + ether = GETHER1_MAC_BASE; + + val = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]; + writel(val, ðer->mahr); + val = (mac[4] << 8) | mac[5]; + writel(val, ðer->malr); +} + +/***************************************************************** + * This PMB must be set on this timing. The lowlevel_init is run on + * Area 0(phys 0x00000000), so we have to map it. + * + * The new PMB table is following: + * ent virt phys v sz c wt + * 0 0xa0000000 0x40000000 1 128M 0 1 + * 1 0xa8000000 0x48000000 1 128M 0 1 + * 2 0xb0000000 0x50000000 1 128M 0 1 + * 3 0xb8000000 0x58000000 1 128M 0 1 + * 4 0x80000000 0x40000000 1 128M 1 1 + * 5 0x88000000 0x48000000 1 128M 1 1 + * 6 0x90000000 0x50000000 1 128M 1 1 + * 7 0x98000000 0x58000000 1 128M 1 1 + */ +static void set_pmb_on_board_init(void) +{ + struct mmu_regs *mmu = MMU_BASE; + + /* clear ITLB */ + writel(0x00000004, &mmu->mmucr); + + /* delete PMB for SPIBOOT */ + writel(0, PMB_ADDR_BASE(0)); + writel(0, PMB_DATA_BASE(0)); + + /* add PMB for SDRAM(0x40000000 - 0x47ffffff) */ + /* ppn ub v s1 s0 c wt */ + writel(mk_pmb_addr_val(0xa0), PMB_ADDR_BASE(0)); + writel(mk_pmb_data_val(0x40, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(0)); + writel(mk_pmb_addr_val(0xb0), PMB_ADDR_BASE(2)); + writel(mk_pmb_data_val(0x50, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(2)); + writel(mk_pmb_addr_val(0xb8), PMB_ADDR_BASE(3)); + writel(mk_pmb_data_val(0x58, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(3)); + writel(mk_pmb_addr_val(0x80), PMB_ADDR_BASE(4)); + writel(mk_pmb_data_val(0x40, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(4)); + writel(mk_pmb_addr_val(0x90), PMB_ADDR_BASE(6)); + writel(mk_pmb_data_val(0x50, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(6)); + writel(mk_pmb_addr_val(0x98), PMB_ADDR_BASE(7)); + writel(mk_pmb_data_val(0x58, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(7)); +} + +int board_init(void) +{ + struct gether_control_regs *gether = GETHER_CONTROL_BASE; + + init_gpio(); + set_pmb_on_board_init(); + + /* Sets TXnDLY to B'010 */ + writel(0x00000202, &gether->gbecont); + + init_usb_phy(); + init_gether_mdio(); + + return 0; +} + +int dram_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + printf("DRAM: %dMB\n", CONFIG_SYS_SDRAM_SIZE / (1024 * 1024)); + + return 0; +} + +int board_mmc_init(bd_t *bis) +{ + struct gpio_regs *gpio = GPIO_BASE; + + writew(readw(&gpio->pgcr) | 0x0040, &gpio->pgcr); + writeb(readb(&gpio->pgdr) & ~0x08, &gpio->pgdr); /* Reset */ + udelay(1); + writeb(readb(&gpio->pgdr) | 0x08, &gpio->pgdr); /* Release reset */ + udelay(200); + + return mmcif_mmc_init(); +} + +static int get_sh_eth_mac_raw(unsigned char *buf, int size) +{ + struct spi_flash *spi; + int ret; + + spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); + if (spi == NULL) { + printf("%s: spi_flash probe failed.\n", __func__); + return 1; + } + + ret = spi_flash_read(spi, SH7753EVB_ETHERNET_MAC_BASE, size, buf); + if (ret) { + printf("%s: spi_flash read failed.\n", __func__); + spi_flash_free(spi); + return 1; + } + spi_flash_free(spi); + + return 0; +} + +static int get_sh_eth_mac(int channel, char *mac_string, unsigned char *buf) +{ + memcpy(mac_string, &buf[channel * (SH7753EVB_ETHERNET_MAC_SIZE + 1)], + SH7753EVB_ETHERNET_MAC_SIZE); + mac_string[SH7753EVB_ETHERNET_MAC_SIZE] = 0x00; /* terminate */ + + return 0; +} + +static void init_ethernet_mac(void) +{ + char mac_string[64]; + char env_string[64]; + int i; + unsigned char *buf; + + buf = malloc(256); + if (!buf) { + printf("%s: malloc failed.\n", __func__); + return; + } + get_sh_eth_mac_raw(buf, 256); + + /* Gigabit Ethernet */ + for (i = 0; i < SH7753EVB_ETHERNET_NUM_CH; i++) { + get_sh_eth_mac(i, mac_string, buf); + if (i == 0) + setenv("ethaddr", mac_string); + else { + sprintf(env_string, "eth%daddr", i); + setenv(env_string, mac_string); + } + set_mac_to_sh_giga_eth_register(i, mac_string); + } + + free(buf); +} + +int board_late_init(void) +{ + init_ethernet_mac(); + + return 0; +} + +int do_write_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int i, ret; + char mac_string[256]; + struct spi_flash *spi; + unsigned char *buf; + + if (argc != 3) { + buf = malloc(256); + if (!buf) { + printf("%s: malloc failed.\n", __func__); + return 1; + } + + get_sh_eth_mac_raw(buf, 256); + + /* print current MAC address */ + for (i = 0; i < SH7753EVB_ETHERNET_NUM_CH; i++) { + get_sh_eth_mac(i, mac_string, buf); + printf("GETHERC ch%d = %s\n", i, mac_string); + } + free(buf); + return 0; + } + + /* new setting */ + memset(mac_string, 0xff, sizeof(mac_string)); + sprintf(mac_string, "%s\t%s", + argv[1], argv[2]); + + /* write MAC data to SPI rom */ + spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); + if (!spi) { + printf("%s: spi_flash probe failed.\n", __func__); + return 1; + } + + ret = spi_flash_erase(spi, SH7753EVB_ETHERNET_MAC_BASE_SPI, + SH7753EVB_SPI_SECTOR_SIZE); + if (ret) { + printf("%s: spi_flash erase failed.\n", __func__); + return 1; + } + + ret = spi_flash_write(spi, SH7753EVB_ETHERNET_MAC_BASE_SPI, + sizeof(mac_string), mac_string); + if (ret) { + printf("%s: spi_flash write failed.\n", __func__); + spi_flash_free(spi); + return 1; + } + spi_flash_free(spi); + + puts("The writing of the MAC address to SPI ROM was completed.\n"); + + return 0; +} + +U_BOOT_CMD( + write_mac, 3, 1, do_write_mac, + "write MAC address for GETHERC", + "[GETHERC ch0] [GETHERC ch1]\n" +); diff --git a/board/renesas/sh7753evb/spi-boot.c b/board/renesas/sh7753evb/spi-boot.c new file mode 100644 index 00000000000..21903d9c7bd --- /dev/null +++ b/board/renesas/sh7753evb/spi-boot.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define CONFIG_SPI_ADDR 0x00000000 +#define PHYADDR(_addr) ((_addr & 0x1fffffff) | 0x40000000) +#define CONFIG_RAM_BOOT_PHYS PHYADDR(CONFIG_SYS_TEXT_BASE) + +#define SPIWDMADR 0xFE001018 +#define SPIWDMCNTR 0xFE001020 +#define SPIDMCOR 0xFE001028 +#define SPIDMINTSR 0xFE001188 +#define SPIDMINTMR 0xFE001190 + +#define SPIDMINTSR_DMEND 0x00000004 + +#define TBR 0xFE002000 +#define RBR 0xFE002000 + +#define CR1 0xFE002008 +#define CR2 0xFE002010 +#define CR3 0xFE002018 +#define CR4 0xFE002020 +#define CR7 0xFE002038 +#define CR8 0xFE002040 + +/* CR1 */ +#define SPI_TBE 0x80 +#define SPI_TBF 0x40 +#define SPI_RBE 0x20 +#define SPI_RBF 0x10 +#define SPI_PFONRD 0x08 +#define SPI_SSDB 0x04 +#define SPI_SSD 0x02 +#define SPI_SSA 0x01 + +/* CR2 */ +#define SPI_RSTF 0x80 +#define SPI_LOOPBK 0x40 +#define SPI_CPOL 0x20 +#define SPI_CPHA 0x10 +#define SPI_L1M0 0x08 + +/* CR4 */ +#define SPI_TBEI 0x80 +#define SPI_TBFI 0x40 +#define SPI_RBEI 0x20 +#define SPI_RBFI 0x10 +#define SPI_SpiS0 0x02 +#define SPI_SSS 0x01 + +/* CR7 */ +#define CR7_IDX_OR12 0x12 +#define OR12_ADDR32 0x00000001 + +#define spi_write(val, addr) (*(volatile unsigned long *)(addr)) = val +#define spi_read(addr) (*(volatile unsigned long *)(addr)) + +/* M25P80 */ +#define M25_READ 0x03 +#define M25_READ_4BYTE 0x13 + +extern void bss_start(void); + +#define __uses_spiboot2 __attribute__((section(".spiboot2.text"))) +static void __uses_spiboot2 spi_reset(void) +{ + int timeout = 0x00100000; + + /* Make sure the last transaction is finalized */ + spi_write(0x00, CR3); + spi_write(0x02, CR1); + while (!(spi_read(CR4) & SPI_SpiS0)) { + if (timeout-- < 0) + break; + } + spi_write(0x00, CR1); + + spi_write(spi_read(CR2) | SPI_RSTF, CR2); /* fifo reset */ + spi_write(spi_read(CR2) & ~SPI_RSTF, CR2); + + spi_write(0, SPIDMCOR); +} + +static void __uses_spiboot2 spi_read_flash(void *buf, unsigned long addr, + unsigned long len) +{ + spi_write(CR7_IDX_OR12, CR7); + if (spi_read(CR8) & OR12_ADDR32) { + /* 4-bytes address mode */ + spi_write(M25_READ_4BYTE, TBR); + spi_write((addr >> 24) & 0xFF, TBR); /* ADDR31-24 */ + } else { + /* 3-bytes address mode */ + spi_write(M25_READ, TBR); + } + spi_write((addr >> 16) & 0xFF, TBR); /* ADDR23-16 */ + spi_write((addr >> 8) & 0xFF, TBR); /* ADDR15-8 */ + spi_write(addr & 0xFF, TBR); /* ADDR7-0 */ + + spi_write(SPIDMINTSR_DMEND, SPIDMINTSR); + spi_write((unsigned long)buf, SPIWDMADR); + spi_write(len & 0xFFFFFFE0, SPIWDMCNTR); + spi_write(1, SPIDMCOR); + + spi_write(0xff, CR3); + spi_write(spi_read(CR1) | SPI_SSDB, CR1); + spi_write(spi_read(CR1) | SPI_SSA, CR1); + + while (!(spi_read(SPIDMINTSR) & SPIDMINTSR_DMEND)) + ; + + /* Nagate SP0-SS0 */ + spi_write(0, CR1); +} + +void __uses_spiboot2 spiboot_main(void) +{ + /* + * This code rounds len up for SPIWDMCNTR. We should set it to 0 in + * lower 5-bits. + */ + void (*_start)(void) = (void *)CONFIG_SYS_TEXT_BASE; + volatile unsigned long len = (bss_start - _start + 31) & 0xffffffe0; + + spi_reset(); + spi_read_flash((void *)CONFIG_RAM_BOOT_PHYS, CONFIG_SPI_ADDR, len); + + _start(); +} diff --git a/board/renesas/sh7753evb/u-boot.lds b/board/renesas/sh7753evb/u-boot.lds new file mode 100644 index 00000000000..053df642ea9 --- /dev/null +++ b/board/renesas/sh7753evb/u-boot.lds @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2007 + * Nobuhiro Iwamatsu + * + * Copyright (C) 2012 + * Yoshihiro Shimoda + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") +OUTPUT_ARCH(sh) +ENTRY(_start) + +SECTIONS +{ + /* + * entry and reloct_dst will be provided via ldflags + */ + . = .; + + PROVIDE (_ftext = .); + PROVIDE (_fcode = .); + PROVIDE (_start = .); + + .text : + { + KEEP(arch/sh/cpu/sh4/start.o (.text)) + *(.spiboot1.text) + *(.spiboot2.text) + . = ALIGN(8192); + common/env_embedded.o (.ppcenv) + . = ALIGN(8192); + common/env_embedded.o (.ppcenvr) + . = ALIGN(8192); + *(.text) + . = ALIGN(4); + } =0xFF + PROVIDE (_ecode = .); + .rodata : + { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + . = ALIGN(4); + } + PROVIDE (_etext = .); + + + PROVIDE (_fdata = .); + .data : + { + *(.data) + . = ALIGN(4); + } + PROVIDE (_edata = .); + + PROVIDE (_fgot = .); + .got : + { + *(.got) + . = ALIGN(4); + } + PROVIDE (_egot = .); + + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + PROVIDE (reloc_dst_end = .); + /* _reloc_dst_end = .; */ + + PROVIDE (bss_start = .); + PROVIDE (__bss_start = .); + .bss (NOLOAD) : + { + *(.bss) + . = ALIGN(4); + } + PROVIDE (bss_end = .); + + PROVIDE (__bss_end = .); +} diff --git a/boards.cfg b/boards.cfg index 2128996a1e6..93c3fd1b8b2 100644 --- a/boards.cfg +++ b/boards.cfg @@ -1209,6 +1209,7 @@ Active sh sh4 - renesas r0p7734 Active sh sh4 - renesas r2dplus r2dplus - Nobuhiro Iwamatsu :Nobuhiro Iwamatsu Active sh sh4 - renesas r7780mp r7780mp - Nobuhiro Iwamatsu :Nobuhiro Iwamatsu Active sh sh4 - renesas sh7752evb sh7752evb - - +Active sh sh4 - renesas sh7753evb sh7753evb - - Active sh sh4 - renesas sh7757lcr sh7757lcr - - Active sh sh4 - renesas sh7763rdp sh7763rdp - Nobuhiro Iwamatsu :Nobuhiro Iwamatsu Active sh sh4 - renesas sh7785lcr sh7785lcr - - diff --git a/doc/README.sh7753evb b/doc/README.sh7753evb new file mode 100644 index 00000000000..5fe178c53f0 --- /dev/null +++ b/doc/README.sh7753evb @@ -0,0 +1,67 @@ +======================================== +Renesas SH7753 EVB board +======================================== + +This board specification: +========================= + +The SH7753 EVB (board config name:sh7753evb) has the following device: + + - SH7753 (SH-4A) + - DDR3-SDRAM 512MB + - SPI ROM 8MB + - Gigabit Ethernet controllers + - eMMC 4GB + + +Configuration for This board: +============================= + +You can select the configuration as follows: + + - make sh7753evb_config + + +This board specific command: +============================ + +This board has the following its specific command: + + - write_mac + + +1. write_mac + +You can write MAC address to SPI ROM. + + Usage 1) Write MAC address + + write_mac [GETHERC ch0] [GETHERC ch1] + + For example) + => write_mac 74:90:50:00:33:9e 74:90:50:00:33:9f + *) We have to input the command as a single line + (without carriage return) + *) We have to reset after input the command. + + Usage 2) Show current data + + write_mac + + For example) + => write_mac + GETHERC ch0 = 74:90:50:00:33:9e + GETHERC ch1 = 74:90:50:00:33:9f + + +Update SPI ROM: +============================ + +1. Copy u-boot image to RAM area. +2. Probe SPI device. + => sf probe 0 + SF: Detected MX25L6405D with page size 64KiB, total 8 MiB +3. Erase SPI ROM. + => sf erase 0 80000 +4. Write u-boot image to SPI ROM. + => sf write 0x48000000 0 80000 diff --git a/include/configs/sh7753evb.h b/include/configs/sh7753evb.h new file mode 100644 index 00000000000..f7eb86d1d6a --- /dev/null +++ b/include/configs/sh7753evb.h @@ -0,0 +1,137 @@ +/* + * Configuation settings for the sh7753evb board + * + * Copyright (C) 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SH7753EVB_H +#define __SH7753EVB_H + +#undef DEBUG +#define CONFIG_SH 1 +#define CONFIG_SH4A 1 +#define CONFIG_SH_32BIT 1 +#define CONFIG_CPU_SH7753 1 +#define CONFIG_SH7753EVB 1 + +#define CONFIG_SYS_TEXT_BASE 0x5ff80000 +#define CONFIG_SYS_LDSCRIPT "board/renesas/sh7753evb/u-boot.lds" + +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_NET +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_NFS +#define CONFIG_CMD_DFL +#define CONFIG_CMD_SDRAM +#define CONFIG_CMD_SF +#define CONFIG_CMD_RUN +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_MD5SUM +#define CONFIG_MD5 +#define CONFIG_CMD_LOADS +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_DOS_PARTITION +#define CONFIG_MAC_PARTITION + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTARGS "console=ttySC2,115200 root=/dev/nfs ip=dhcp" + +#define CONFIG_VERSION_VARIABLE +#undef CONFIG_SHOW_BOOT_PROGRESS +#define CONFIG_CMDLINE_EDITING +#define CONFIG_AUTO_COMPLETE + +/* MEMORY */ +#define SH7753EVB_SDRAM_BASE (0x40000000) +#define SH7753EVB_SDRAM_SIZE (512 * 1024 * 1024) + +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_PBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE 512 +#define CONFIG_SYS_BAUDRATE_TABLE { 115200 } + +/* SCIF */ +#define CONFIG_SCIF_CONSOLE 1 +#define CONFIG_CONS_SCIF2 1 +#undef CONFIG_SYS_CONSOLE_INFO_QUIET +#undef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE +#undef CONFIG_SYS_CONSOLE_ENV_OVERWRITE + +#define CONFIG_SYS_MEMTEST_START (SH7753EVB_SDRAM_BASE) +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ + 480 * 1024 * 1024) +#undef CONFIG_SYS_ALT_MEMTEST +#undef CONFIG_SYS_MEMTEST_SCRATCH +#undef CONFIG_SYS_LOADS_BAUD_CHANGE + +#define CONFIG_SYS_SDRAM_BASE (SH7753EVB_SDRAM_BASE) +#define CONFIG_SYS_SDRAM_SIZE (SH7753EVB_SDRAM_SIZE) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + \ + 128 * 1024 * 1024) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) +#define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024) + +/* FLASH */ +#define CONFIG_SYS_NO_FLASH + +/* Ether */ +#define CONFIG_SH_ETHER 1 +#define CONFIG_SH_ETHER_USE_PORT 0 +#define CONFIG_SH_ETHER_PHY_ADDR 18 +#define CONFIG_SH_ETHER_CACHE_WRITEBACK 1 +#define CONFIG_SH_ETHER_USE_GETHER 1 +#define CONFIG_PHYLIB +#define CONFIG_BITBANGMII +#define CONFIG_BITBANGMII_MULTI +#define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RGMII +#define CONFIG_PHY_VITESSE + +#define SH7753EVB_ETHERNET_MAC_BASE_SPI 0x00090000 +#define SH7753EVB_SPI_SECTOR_SIZE (64 * 1024) +#define SH7753EVB_ETHERNET_MAC_BASE SH7753EVB_ETHERNET_MAC_BASE_SPI +#define SH7753EVB_ETHERNET_MAC_SIZE 17 +#define SH7753EVB_ETHERNET_NUM_CH 2 +#define CONFIG_BOARD_LATE_INIT + +/* SPI */ +#define CONFIG_SH_SPI 1 +#define CONFIG_SH_SPI_BASE 0xfe002000 +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO 1 +#define CONFIG_SPI_FLASH_MACRONIX 1 + +/* MMCIF */ +#define CONFIG_MMC 1 +#define CONFIG_GENERIC_MMC 1 +#define CONFIG_SH_MMCIF 1 +#define CONFIG_SH_MMCIF_ADDR 0xffcb0000 +#define CONFIG_SH_MMCIF_CLK 48000000 + +/* ENV setting */ +#define CONFIG_ENV_IS_EMBEDDED +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SECT_SIZE (64 * 1024) +#define CONFIG_ENV_ADDR (0x00080000) +#define CONFIG_ENV_OFFSET (CONFIG_ENV_ADDR) +#define CONFIG_ENV_OVERWRITE 1 +#define CONFIG_ENV_SIZE (CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SECT_SIZE) +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netboot=bootp; bootm\0" + +/* Board Clock */ +#define CONFIG_SYS_CLK_FREQ 48000000 +#define CONFIG_SH_TMU_CLK_FREQ CONFIG_SYS_CLK_FREQ +#define CONFIG_SH_SCIF_CLK_FREQ CONFIG_SYS_CLK_FREQ +#define CONFIG_SYS_TMU_CLK_DIV 4 +#endif /* __SH7753EVB_H */ -- cgit v1.3.1 From b135991a3cddd1a266c5fbd64e25eaaa61bde2d8 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Tue, 17 Dec 2013 14:25:52 +0530 Subject: powerpc/mpc85xx: Add support for single source clocking Single-source clocking is new feature introduced in T1040. In this mode, a single differential clock is supplied to the DIFF_SYSCLK_P/N inputs to the processor, which in turn is used to supply clocks to the sysclock, ddrclock and usbclock. So, both ddrclock and syclock are driven by same differential sysclock in single-source clocking mode whereas in normal clocking mode, generally separate DDRCLK and SYSCLK pins provides reference clock for sysclock and ddrclock DDR_REFCLK_SEL rcw bit is used to determine DDR clock source -If DDR_REFCLK_SEL rcw bit is 0, then DDR PLLs are driven in normal clocking mode by DDR_Reference clock -If DDR_REFCLK_SEL rcw bit is 1, then DDR PLLs are driven in single source clocking mode by DIFF_SYSCLK Add code to determine ddrclock based on DDR_REFCLK_SEL rcw bit. Signed-off-by: Poonam Aggrwal Signed-off-by: Priyanka Jain --- README | 5 +++++ arch/powerpc/cpu/mpc85xx/speed.c | 25 +++++++++++++++++++++++-- arch/powerpc/include/asm/config_mpc85xx.h | 1 + arch/powerpc/include/asm/immap_85xx.h | 3 +++ 4 files changed, 32 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/README b/README index e58e9c0e1c1..a0646c36657 100644 --- a/README +++ b/README @@ -423,6 +423,11 @@ The following options need to be configured: CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT This value denotes start offset of DSP CCSR space. + CONFIG_SYS_FSL_SINGLE_SOURCE_CLK + Single Source Clock is clocking mode present in some of FSL SoC's. + In this mode, a single differential clock is used to supply + clocks to the sysclock, ddrclock and usbclock. + - Generic CPU options: CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index 7c7467f7bfc..35867dffdd7 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -74,12 +74,33 @@ void get_sys_info(sys_info_t *sys_info) uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; unsigned long sysclk = CONFIG_SYS_CLK_FREQ; uint mem_pll_rat; +#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK + uint single_src; +#endif sys_info->freq_systembus = sysclk; +#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK + /* + * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS + * are driven by separate DDR Refclock or single source + * differential clock. + */ + single_src = (in_be32(&gur->rcwsr[5]) >> + FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) & + FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK; + /* + * For single source clocking, both ddrclock and syclock + * are driven by differential sysclock. + */ + if (single_src == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK) { + printf("Single Source Clock Configuration\n"); + sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ; + } else +#endif #ifdef CONFIG_DDR_CLK_FREQ - sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; + sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; #else - sys_info->freq_ddrbus = sysclk; + sys_info->freq_ddrbus = sysclk; #endif sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f; diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 244ccbf24fc..3d8bd9a819b 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -711,6 +711,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define CONFIG_FM_PLAT_CLK_DIV 1 #define CONFIG_SYS_FM1_CLK CONFIG_FM_PLAT_CLK_DIV #define CONFIG_SYS_FM_MURAM_SIZE 0x30000 +#define CONFIG_SYS_FSL_SINGLE_SOURCE_CLK #define CONFIG_SYS_FSL_TBCLK_DIV 16 #define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4" #define CONFIG_SYS_FSL_USB1_PHY_ENABLE diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 672e8c6650c..68c3c824533 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1774,6 +1774,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S3_PLL2 0x00040000 #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL1 0x00020000 #define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL2 0x00010000 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT 4 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK 0x00000011 +#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK 1 #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ #define FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT 17 -- cgit v1.3.1 From 2ffa96d815c947ba09286e1a20ae832882707eba Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Wed, 18 Dec 2013 10:27:55 +0800 Subject: powerpc/t208x: fix macro CONFIG_SYS_FSL_NUM_USB_CTRLS CONFIG_SYS_FSL_NUM_USB_CTRLS is no longer used, update it to new CONFIG_USB_MAX_CONTROLLER_COUNT. Signed-off-by: Shengzhou Liu --- arch/powerpc/include/asm/config_mpc85xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 3d8bd9a819b..54ce2f053cc 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -746,7 +746,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define CONFIG_SYS_NUM_FM1_DTSEC 6 #define CONFIG_SYS_NUM_FM1_10GEC 2 #endif -#define CONFIG_SYS_FSL_NUM_USB_CTRLS 2 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #define CONFIG_NUM_DDR_CONTROLLERS 1 #define CONFIG_PME_PLAT_CLK_DIV 1 #define CONFIG_SYS_PME_CLK CONFIG_PME_PLAT_CLK_DIV -- cgit v1.3.1 From 14eeb926bb1fc7fbfa0e8767136540ed10aff81a Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 13:46:06 +0900 Subject: sh: sh2: Add CONFIG_SH2 definition to config.mk of SH2 Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/cpu/sh2/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/cpu/sh2/config.mk b/arch/sh/cpu/sh2/config.mk index 8a0de967146..69273b4f382 100644 --- a/arch/sh/cpu/sh2/config.mk +++ b/arch/sh/cpu/sh2/config.mk @@ -12,7 +12,7 @@ PLATFORM_CPPFLAGS += -m2a -m2a-nofpu -mb -ffreestanding else # SH2 PLATFORM_CPPFLAGS += -m3e -mb endif -PLATFORM_CPPFLAGS += $(call cc-option,-mno-fdpic) +PLATFORM_CPPFLAGS += -DCONFIG_SH2 $(call cc-option,-mno-fdpic) PLATFORM_RELFLAGS += -ffixed-r13 PLATFORM_LDFLAGS += $(ENDIANNESS) -- cgit v1.3.1 From 22e7d66181aa64e1fbca1132049ab4fe0ed44bc5 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 13:46:11 +0900 Subject: sh: sh3: Add CONFIG_SH3 definition to config.mk of SH3 Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/cpu/sh3/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/cpu/sh3/config.mk b/arch/sh/cpu/sh3/config.mk index 5c77e5c32d9..abd4b8d2bd9 100644 --- a/arch/sh/cpu/sh3/config.mk +++ b/arch/sh/cpu/sh3/config.mk @@ -11,5 +11,5 @@ # SPDX-License-Identifier: GPL-2.0+ # # -PLATFORM_CPPFLAGS += -m3 +PLATFORM_CPPFLAGS += -DCONFIG_SH3 -m3 PLATFORM_RELFLAGS += -ffixed-r13 -- cgit v1.3.1 From b1165adfd5cd6bcf59657436086fc98d9d2b214d Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 14:09:32 +0900 Subject: sh: sh4: Add CONFIG_SH4 definition to config.mk of SH4 Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/cpu/sh4/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/cpu/sh4/config.mk b/arch/sh/cpu/sh4/config.mk index c3575570e75..753580beb1c 100644 --- a/arch/sh/cpu/sh4/config.mk +++ b/arch/sh/cpu/sh4/config.mk @@ -8,5 +8,5 @@ # SPDX-License-Identifier: GPL-2.0+ # # -PLATFORM_CPPFLAGS += -m4-nofpu +PLATFORM_CPPFLAGS += -DCONFIG_SH4 -m4-nofpu PLATFORM_RELFLAGS += -ffixed-r13 -- cgit v1.3.1 From 8f0960e8378e0fc14d6216f60910994c217d3d57 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 14:57:30 +0900 Subject: sh: sh2: Change CONFIG_SYS_HZ to CONFIG_SH_CMT_CLK_FREQ CONFIG_SYS_HZ of SH2 is not used as frequency of base timer. This is the correct clock of CMT. This changes from CONFIG_SYS_HZ to CONFIG_SH_CMT_CLK_FREQ, in order to use CONFIG_SYS_HZ as clock of CMT. Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/lib/time_sh2.c | 2 +- include/configs/rsk7203.h | 2 +- include/configs/rsk7264.h | 2 +- include/configs/rsk7269.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/lib/time_sh2.c b/arch/sh/lib/time_sh2.c index be3896c3ed7..4b1f47b6adf 100644 --- a/arch/sh/lib/time_sh2.c +++ b/arch/sh/lib/time_sh2.c @@ -84,5 +84,5 @@ void __udelay(unsigned long usec) unsigned long get_tbclk(void) { - return CONFIG_SYS_HZ; + return CONFIG_SH_CMT_CLK_FREQ; } diff --git a/include/configs/rsk7203.h b/include/configs/rsk7203.h index 5920a2630c2..54363245803 100644 --- a/include/configs/rsk7203.h +++ b/include/configs/rsk7203.h @@ -85,7 +85,7 @@ #define CONFIG_SH_TMU_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CMT_CLK_DIVIDER 32 /* 8 (default), 32, 128 or 512 */ -#define CONFIG_SYS_HZ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) +#define CONFIG_SH_CMT_CLK_FREQ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) /* Network interface */ #define CONFIG_SMC911X diff --git a/include/configs/rsk7264.h b/include/configs/rsk7264.h index 5338cf23b6d..4aaa3ef74b7 100644 --- a/include/configs/rsk7264.h +++ b/include/configs/rsk7264.h @@ -65,7 +65,7 @@ #define CONFIG_SH_TMU_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CMT_CLK_DIVIDER 32 /* 8 (default), 32, 128 or 512 */ -#define CONFIG_SYS_HZ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) +#define CONFIG_SH_CMT_CLK_FREQ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) /* Network interface */ #define CONFIG_SMC911X diff --git a/include/configs/rsk7269.h b/include/configs/rsk7269.h index 4796039f1ad..11fc231fa67 100644 --- a/include/configs/rsk7269.h +++ b/include/configs/rsk7269.h @@ -64,7 +64,7 @@ #define CONFIG_SH_TMU_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_SYS_CLK_FREQ #define CMT_CLK_DIVIDER 32 /* 8 (default), 32, 128 or 512 */ -#define CONFIG_SYS_HZ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) +#define CONFIG_SH_CMT_CLK_FREQ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER) /* Network interface */ #define CONFIG_SMC911X -- cgit v1.3.1 From 77595c6d9e2c1af9c3b143f496c4c47d0e95a458 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:26:57 -0700 Subject: sandbox: Improve/augment memory allocation functions Implement realloc() and free() for sandbox, by adding a header to each block which contains the block size. Signed-off-by: Simon Glass Signed-off-by: Simon Glass Reviewed-by: Che-Liang Chiou Reviewed-by: Hung-ying Tyan --- arch/sandbox/cpu/os.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- include/os.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 26f44cb597e..88dd371760b 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -27,6 +27,10 @@ /* Operating System Interface */ +struct os_mem_hdr { + size_t length; /* number of bytes in the block */ +}; + ssize_t os_read(int fd, void *buf, size_t count) { return read(fd, buf, count); @@ -128,8 +132,45 @@ void os_tty_raw(int fd) void *os_malloc(size_t length) { - return mmap(NULL, length, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + struct os_mem_hdr *hdr; + + hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (hdr == MAP_FAILED) + return NULL; + hdr->length = length; + + return hdr + 1; +} + +void *os_free(void *ptr) +{ + struct os_mem_hdr *hdr = ptr; + + hdr--; + if (ptr) + munmap(hdr, hdr->length + sizeof(*hdr)); +} + +void *os_realloc(void *ptr, size_t length) +{ + struct os_mem_hdr *hdr = ptr; + void *buf = NULL; + + hdr--; + if (length != 0) { + buf = os_malloc(length); + if (!buf) + return buf; + if (ptr) { + if (length > hdr->length) + length = hdr->length; + memcpy(buf, ptr, length); + } + } + os_free(ptr); + + return buf; } void os_usleep(unsigned long usec) diff --git a/include/os.h b/include/os.h index 950433daa32..1575a969222 100644 --- a/include/os.h +++ b/include/os.h @@ -106,6 +106,35 @@ void os_tty_raw(int fd); */ void *os_malloc(size_t length); +/** + * Free memory previous allocated with os_malloc()/os_realloc() + * + * This returns the memory to the OS. + * + * \param ptr Pointer to memory block to free + */ +void *os_free(void *ptr); + +/** + * Reallocate previously-allocated memory to increase/decrease space + * + * This works in a similar way to the C library realloc() function. If + * length is 0, then ptr is freed. Otherwise the space used by ptr is + * expanded or reduced depending on whether length is larger or smaller + * than before. + * + * If ptr is NULL, then this is similar to calling os_malloc(). + * + * This function may need to move the memory block to make room for any + * extra space, in which case the new pointer is returned. + * + * \param ptr Pointer to memory block to reallocate + * \param length New length for memory block + * \return pointer to new memory block, or NULL on failure or if length + * is 0. + */ +void *os_realloc(void *ptr, size_t length); + /** * Access to the usleep function of the os * -- cgit v1.3.1 From 6ebcab8de7c38ca0b2cc5215c5b3e7ccf5f9d0d7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:26:58 -0700 Subject: sandbox: Correct help message garbling The is displayed for options with no argument, and omitted for those with an argument. Swap this around. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/start.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 1b154547847..951ac63f3a1 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -50,9 +50,9 @@ int sandbox_early_getopt_check(void) /* then the long flag */ if (opt->has_arg) - printf("--%-*s", max_noarg_len, opt->flag); - else printf("--%-*s ", max_arg_len, opt->flag); + else + printf("--%-*s", max_noarg_len, opt->flag); /* finally the help text */ printf(" %s\n", opt->help); -- cgit v1.3.1 From 808434cdbd70b6633c99fe2974af7d25316cc593 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:26:59 -0700 Subject: sandbox: Allow return from board_init_f() The execution flow becomes easier if we can return from board_init_f() as ARM does. We can control things from start.c instead of having to call back into that file from other places. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/start.c | 11 ++++++----- common/board_f.c | 8 +++----- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 951ac63f3a1..895c4d82b0d 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -10,6 +10,8 @@ #include +DECLARE_GLOBAL_DATA_PTR; + int sandbox_early_getopt_check(void) { struct sandbox_state *state = state_get_current(); @@ -109,12 +111,11 @@ int main(int argc, char *argv[]) if (os_parse_args(state, argc, argv)) return 1; - /* - * Do pre- and post-relocation init, then start up U-Boot. This will - * never return. - */ + /* Do pre- and post-relocation init */ board_init_f(0); - /* NOTREACHED - board_init_f() does not return */ + board_init_r(gd->new_gd, 0); + + /* NOTREACHED - board_init_r() does not return */ return 0; } diff --git a/common/board_f.c b/common/board_f.c index fcfd713b076..6f77e1d1295 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -772,7 +772,7 @@ static int setup_reloc(void) } /* ARM calls relocate_code from its crt0.S */ -#if !defined(CONFIG_ARM) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) static int jump_to_copy(void) { @@ -792,8 +792,6 @@ static int jump_to_copy(void) * (CPU cache) */ board_init_f_r_trampoline(gd->start_addr_sp); -#elif defined(CONFIG_SANDBOX) - board_init_r(gd->new_gd, 0); #else relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr); #endif @@ -995,7 +993,7 @@ static init_fnc_t init_sequence_f[] = { INIT_FUNC_WATCHDOG_RESET reloc_fdt, setup_reloc, -#ifndef CONFIG_ARM +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) jump_to_copy, #endif NULL, @@ -1015,7 +1013,7 @@ void board_init_f(ulong boot_flags) if (initcall_run_list(init_sequence_f)) hang(); -#ifndef CONFIG_ARM +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) /* NOTREACHED - jump_to_copy() does not return */ hang(); #endif -- cgit v1.3.1 From 88bd0e9d15d2f7e8c040931b06497878f9ed0550 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:00 -0700 Subject: sandbox: Implement the bootm command for sandbox When sandbox does a 'bootm' to run a kernel we cannot actually execute it. So just exit sandbox, which is essentially what U-Boot does on other archs. Also, allow sandbox to use bootm on any kernel, so that it can be used to test booting of kernels from any architecture. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/cpu.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index cfc1fda1e15..bc7641a8081 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -8,10 +8,16 @@ DECLARE_GLOBAL_DATA_PTR; -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +void reset_cpu(ulong ignored) { /* This is considered normal termination for now */ os_exit(0); +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + reset_cpu(0); + return 0; } @@ -28,7 +34,14 @@ unsigned long __attribute__((no_instrument_function)) timer_get_us(void) int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { - return -1; + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + printf("## Transferring control to Linux (at address %08lx)...\n", + images->ep); + reset_cpu(0); + } + + return 0; } int cleanup_before_linux(void) -- cgit v1.3.1 From 91b136c7989e763b01632ca3de6fca8ead0b847b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:01 -0700 Subject: sandbox: Allow the console to work earlier With sandbox, errors and problems may be reported before console_init_f() is executed. For example, an argument may not parse correctly or U-Boot may panic(). At present this output is swallowed so there is no indication what is going wrong. Adjust the console to deal with a very early sandbox setup, by detecting that there is no global_data yet, and calling os functions in that case. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/os.c | 11 +++++++++++ common/console.c | 16 +++++++++++++++- include/os.h | 20 ++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 88dd371760b..ef6a651a603 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -388,3 +388,14 @@ ssize_t os_get_filesize(const char *fname) return ret; return buf.st_size; } + +void os_putc(int ch) +{ + putchar(ch); +} + +void os_puts(const char *str) +{ + while (*str) + os_putc(*str++); +} diff --git a/common/console.c b/common/console.c index cc55068c7cd..2dfb788885b 100644 --- a/common/console.c +++ b/common/console.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -415,6 +416,12 @@ static inline void print_pre_console_buffer(void) {} void putc(const char c) { +#ifdef CONFIG_SANDBOX + if (!gd) { + os_putc(c); + return; + } +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -439,6 +446,13 @@ void putc(const char c) void puts(const char *s) { +#ifdef CONFIG_SANDBOX + if (!gd) { + os_puts(s); + return; + } +#endif + #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -467,7 +481,7 @@ int printf(const char *fmt, ...) uint i; char printbuffer[CONFIG_SYS_PBSIZE]; -#ifndef CONFIG_PRE_CONSOLE_BUFFER +#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER) if (!gd->have_console) return 0; #endif diff --git a/include/os.h b/include/os.h index 1575a969222..d302b3685bb 100644 --- a/include/os.h +++ b/include/os.h @@ -209,4 +209,24 @@ const char *os_dirent_get_typename(enum os_dirent_t type); */ ssize_t os_get_filesize(const char *fname); +/** + * Write a character to the controlling OS terminal + * + * This bypasses the U-Boot console support and writes directly to the OS + * stdout file descriptor. + * + * @param ch Character to write + */ +void os_putc(int ch); + +/** + * Write a string to the controlling OS terminal + * + * This bypasses the U-Boot console support and writes directly to the OS + * stdout file descriptor. + * + * @param str String to write (note that \n is not appended) + */ +void os_puts(const char *str); + #endif -- cgit v1.3.1 From c5a62d4a7b4a971a1fb17d595f7c1e98a936a974 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:02 -0700 Subject: sandbox: Add -i option to enter interactive mode Normally when U-Boot starts with a command (-c option) it quits when the command completes. Normally this is what is requires, since the test is likely complete. Provide an option to jump into the console instead, so that debugging or other tasks may be performed before quitting. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/start.c | 12 +++++++++++- arch/sandbox/include/asm/state.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 895c4d82b0d..579ece44711 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -77,7 +77,8 @@ int sandbox_main_loop_init(void) /* Execute command if required */ if (state->cmd) { run_command_list(state->cmd, -1, 0); - os_exit(state->exit_type); + if (!state->interactive) + os_exit(state->exit_type); } return 0; @@ -98,6 +99,15 @@ static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) } SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); +static int sandbox_cmdline_cb_interactive(struct sandbox_state *state, + const char *arg) +{ + state->interactive = true; + return 0; +} + +SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode"); + int main(int argc, char *argv[]) { struct sandbox_state *state; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index a38820bdeeb..df196b79f6d 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -7,6 +7,7 @@ #define __SANDBOX_STATE_H #include +#include /* How we exited U-Boot */ enum exit_type_id { @@ -23,6 +24,7 @@ struct sandbox_spi_info { /* The complete state of the test system */ struct sandbox_state { const char *cmd; /* Command to execute */ + bool interactive; /* Enable cmdline after execute */ const char *fdt_fname; /* Filename of FDT binary */ enum exit_type_id exit_type; /* How we exited U-Boot */ const char *parse_err; /* Error to report from parsing */ -- cgit v1.3.1 From 5c2859cdc30287b3593d9df88f48c31eecb0bbed Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:03 -0700 Subject: sandbox: Allow reading/writing of RAM buffer It is useful to be able to save and restore the RAM contents of sandbox U-Boot either for setting up tests, for later analysys, or for chaining together multiple tests which need to keep the same memory contents. Add a function to provide a memory file for U-Boot. This is read on start-up and written when shutting down. If the file does not exist on start-up, it will be created when shutting down. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/cpu/cpu.c | 4 ++++ arch/sandbox/cpu/os.c | 39 ++++++++++++++++++++++++++++++++++ arch/sandbox/cpu/start.c | 22 +++++++++++++++++-- arch/sandbox/cpu/state.c | 22 +++++++++++++++++++ arch/sandbox/include/asm/global_data.h | 2 +- arch/sandbox/include/asm/state.h | 12 +++++++++++ common/board_f.c | 7 +++--- include/os.h | 16 ++++++++++++++ 8 files changed, 118 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index bc7641a8081..38019e0b48e 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -5,11 +5,15 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; void reset_cpu(ulong ignored) { + if (state_uninit()) + os_exit(2); + /* This is considered normal termination for now */ os_exit(0); } diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index ef6a651a603..725b505177d 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -399,3 +399,42 @@ void os_puts(const char *str) while (*str) os_putc(*str++); } + +int os_write_ram_buf(const char *fname) +{ + struct sandbox_state *state = state_get_current(); + int fd, ret; + + fd = open(fname, O_CREAT | O_WRONLY, 0777); + if (fd < 0) + return -ENOENT; + ret = write(fd, state->ram_buf, state->ram_size); + close(fd); + if (ret != state->ram_size) + return -EIO; + + return 0; +} + +int os_read_ram_buf(const char *fname) +{ + struct sandbox_state *state = state_get_current(); + int fd, ret; + int size; + + size = os_get_filesize(fname); + if (size < 0) + return -ENOENT; + if (size != state->ram_size) + return -ENOSPC; + fd = open(fname, O_RDONLY); + if (fd < 0) + return -ENOENT; + + ret = read(fd, state->ram_buf, state->ram_size); + close(fd); + if (ret != state->ram_size) + return -EIO; + + return 0; +} diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 579ece44711..452f2a98f36 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -4,12 +4,11 @@ */ #include +#include #include #include #include -#include - DECLARE_GLOBAL_DATA_PTR; int sandbox_early_getopt_check(void) @@ -108,6 +107,25 @@ static int sandbox_cmdline_cb_interactive(struct sandbox_state *state, SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode"); +static int sandbox_cmdline_cb_memory(struct sandbox_state *state, + const char *arg) +{ + int err; + + /* For now assume we always want to write it */ + state->write_ram_buf = true; + state->ram_buf_fname = arg; + + if (os_read_ram_buf(arg)) { + printf("Failed to read RAM buffer\n"); + return err; + } + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1, + "Read/write ram_buf memory contents from file"); + int main(int argc, char *argv[]) { struct sandbox_state *state; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 56d5041411c..0380fe27918 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -4,6 +4,7 @@ */ #include +#include #include /* Main state record for the sandbox */ @@ -25,6 +26,10 @@ int state_init(void) { state = &main_state; + state->ram_size = CONFIG_SYS_SDRAM_SIZE; + state->ram_buf = os_malloc(state->ram_size); + assert(state->ram_buf); + /* * Example of how to use GPIOs: * @@ -33,3 +38,20 @@ int state_init(void) */ return 0; } + +int state_uninit(void) +{ + int err; + + state = &main_state; + + if (state->write_ram_buf) { + err = os_write_ram_buf(state->ram_buf_fname); + if (err) { + printf("Failed to write RAM buffer\n"); + return err; + } + } + + return 0; +} diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index d70532aa4d7..b2e9b488f13 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -12,7 +12,7 @@ /* Architecture-specific global data */ struct arch_global_data { - u8 *ram_buf; /* emulated RAM buffer */ + uint8_t *ram_buf; /* emulated RAM buffer */ }; #include diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index df196b79f6d..e4b4c724632 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -30,6 +30,10 @@ struct sandbox_state { const char *parse_err; /* Error to report from parsing */ int argc; /* Program arguments */ char **argv; + uint8_t *ram_buf; /* Emulated RAM buffer */ + unsigned int ram_size; /* Size of RAM buffer */ + const char *ram_buf_fname; /* Filename to use for RAM buffer */ + bool write_ram_buf; /* Write RAM buffer on exit */ /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] @@ -55,4 +59,12 @@ struct sandbox_state *state_get_current(void); */ int state_init(void); +/** + * Uninitialize the test system state, writing out state if configured to + * do so. + * + * @return 0 if OK, -ve on error + */ +int state_uninit(void); + #endif diff --git a/common/board_f.c b/common/board_f.c index 6f77e1d1295..c2f47bc1889 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -347,9 +347,10 @@ done: #ifdef CONFIG_SANDBOX static int setup_ram_buf(void) { - gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE); - assert(gd->arch.ram_buf); - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + struct sandbox_state *state = state_get_current(); + + gd->arch.ram_buf = state->ram_buf; + gd->ram_size = state->ram_size; return 0; } diff --git a/include/os.h b/include/os.h index d302b3685bb..b65fba43014 100644 --- a/include/os.h +++ b/include/os.h @@ -229,4 +229,20 @@ void os_putc(int ch); */ void os_puts(const char *str); +/** + * Write the sandbox RAM buffer to a existing file + * + * @param fname Filename to write memory to (simple binary format) + * @return 0 if OK, -ve on error + */ +int os_write_ram_buf(const char *fname); + +/** + * Read the sandbox RAM buffer from an existing file + * + * @param fname Filename containing memory (simple binary format) + * @return 0 if OK, -ve on error + */ +int os_read_ram_buf(const char *fname); + #endif -- cgit v1.3.1 From 1209e2727c60d052ce875aa39bb8b9ba2edbfbdf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:04 -0700 Subject: sandbox: Add facility to save/restore sandbox state It is often useful to be able to save out the state from a sandbox test run, for analysis or to restore it later to continue a test. Add generic infrastructure for doing this using a device tree binary file. This is a flexible tagged file format which is already supported by U-Boot, and it supports hierarchy if needed. Signed-off-by: Simon Glass Signed-off-by: Simon Glass Reviewed-by: Hung-ying Tyan --- arch/sandbox/cpu/start.c | 49 +++++- arch/sandbox/cpu/state.c | 331 +++++++++++++++++++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 114 ++++++++++++++ 3 files changed, 490 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 452f2a98f36..1df21d49fa5 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -126,19 +126,56 @@ static int sandbox_cmdline_cb_memory(struct sandbox_state *state, SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1, "Read/write ram_buf memory contents from file"); +static int sandbox_cmdline_cb_state(struct sandbox_state *state, + const char *arg) +{ + state->state_fname = arg; + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT"); + +static int sandbox_cmdline_cb_read(struct sandbox_state *state, + const char *arg) +{ + state->read_state = true; + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup"); + +static int sandbox_cmdline_cb_write(struct sandbox_state *state, + const char *arg) +{ + state->write_state = true; + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit"); + +static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state, + const char *arg) +{ + state->ignore_missing_state_on_read = true; + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0, + "Ignore missing state on read"); + int main(int argc, char *argv[]) { struct sandbox_state *state; - int err; + int ret; - err = state_init(); - if (err) - return err; + ret = state_init(); + if (ret) + goto err; state = state_get_current(); if (os_parse_args(state, argc, argv)) return 1; + ret = sandbox_read_state(state, state->state_fname); + if (ret) + goto err; + /* Do pre- and post-relocation init */ board_init_f(0); @@ -146,4 +183,8 @@ int main(int argc, char *argv[]) /* NOTREACHED - board_init_r() does not return */ return 0; + +err: + printf("Error %d\n", ret); + return 1; } diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 0380fe27918..a145808a52d 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include #include @@ -16,6 +18,324 @@ void state_record_exit(enum exit_type_id exit_type) state->exit_type = exit_type; } +static int state_ensure_space(int extra_size) +{ + void *blob = state->state_fdt; + int used, size, free; + void *buf; + int ret; + + used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob); + size = fdt_totalsize(blob); + free = size - used; + if (free > extra_size) + return 0; + + size = used + extra_size; + buf = os_malloc(size); + if (!buf) + return -ENOMEM; + + ret = fdt_open_into(blob, buf, size); + if (ret) { + os_free(buf); + return -EIO; + } + + os_free(blob); + state->state_fdt = buf; + return 0; +} + +static int state_read_file(struct sandbox_state *state, const char *fname) +{ + int size; + int ret; + int fd; + + size = os_get_filesize(fname); + if (size < 0) { + printf("Cannot find sandbox state file '%s'\n", fname); + return -ENOENT; + } + state->state_fdt = os_malloc(size); + if (!state->state_fdt) { + puts("No memory to read sandbox state\n"); + return -ENOMEM; + } + fd = os_open(fname, OS_O_RDONLY); + if (fd < 0) { + printf("Cannot open sandbox state file '%s'\n", fname); + ret = -EPERM; + goto err_open; + } + if (os_read(fd, state->state_fdt, size) != size) { + printf("Cannot read sandbox state file '%s'\n", fname); + ret = -EIO; + goto err_read; + } + os_close(fd); + + return 0; +err_read: + os_close(fd); +err_open: + os_free(state->state_fdt); + state->state_fdt = NULL; + + return ret; +} + +/*** + * sandbox_read_state_nodes() - Read state associated with a driver + * + * This looks through all compatible nodes and calls the read function on + * each one, to read in the state. + * + * If nothing is found, it still calls the read function once, to set up a + * single global state for that driver. + * + * @state: Sandbox state + * @io: Method to use for reading state + * @blob: FDT containing state + * @return 0 if OK, -EINVAL if the read function returned failure + */ +int sandbox_read_state_nodes(struct sandbox_state *state, + struct sandbox_state_io *io, const void *blob) +{ + int count; + int node; + int ret; + + debug(" - read %s\n", io->name); + if (!io->read) + return 0; + + node = -1; + count = 0; + while (blob) { + node = fdt_node_offset_by_compatible(blob, node, io->compat); + if (node < 0) + return 0; /* No more */ + debug(" - read node '%s'\n", fdt_get_name(blob, node, NULL)); + ret = io->read(blob, node); + if (ret) { + printf("Unable to read state for '%s'\n", io->compat); + return -EINVAL; + } + count++; + } + + /* + * If we got no saved state, call the read function once without a + * node, to set up the global state. + */ + if (count == 0) { + debug(" - read global\n"); + ret = io->read(NULL, -1); + if (ret) { + printf("Unable to read global state for '%s'\n", + io->name); + return -EINVAL; + } + } + + return 0; +} + +int sandbox_read_state(struct sandbox_state *state, const char *fname) +{ + struct sandbox_state_io *io; + const void *blob; + bool got_err; + int ret; + + if (state->read_state && fname) { + ret = state_read_file(state, fname); + if (ret == -ENOENT && state->ignore_missing_state_on_read) + ret = 0; + if (ret) + return ret; + } + + /* Call all the state read funtcions */ + got_err = false; + blob = state->state_fdt; + io = ll_entry_start(struct sandbox_state_io, state_io); + for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { + ret = sandbox_read_state_nodes(state, io, blob); + if (ret < 0) + got_err = true; + } + + if (state->read_state && fname) { + debug("Read sandbox state from '%s'%s\n", fname, + got_err ? " (with errors)" : ""); + } + + return got_err ? -1 : 0; +} + +/*** + * sandbox_write_state_node() - Write state associated with a driver + * + * This calls the write function to write out global state for that driver. + * + * TODO(sjg@chromium.org): Support writing out state from multiple drivers + * of the same time. We don't need this yet,and it will be much easier to + * do when driver model is available. + * + * @state: Sandbox state + * @io: Method to use for writing state + * @return 0 if OK, -EIO if there is a fatal error (such as out of space + * for adding the data), -EINVAL if the write function failed. + */ +int sandbox_write_state_node(struct sandbox_state *state, + struct sandbox_state_io *io) +{ + void *blob; + int node; + int ret; + + if (!io->write) + return 0; + + ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE); + if (ret) { + printf("Failed to add more space for state\n"); + return -EIO; + } + + /* The blob location can change when the size increases */ + blob = state->state_fdt; + node = fdt_node_offset_by_compatible(blob, -1, io->compat); + if (node == -FDT_ERR_NOTFOUND) { + node = fdt_add_subnode(blob, 0, io->name); + if (node < 0) { + printf("Cannot create node '%s': %s\n", io->name, + fdt_strerror(node)); + return -EIO; + } + + if (fdt_setprop_string(blob, node, "compatible", io->compat)) { + puts("Cannot set compatible\n"); + return -EIO; + } + } else if (node < 0) { + printf("Cannot access node '%s': %s\n", io->name, + fdt_strerror(node)); + return -EIO; + } + debug("Write state for '%s' to node %d\n", io->compat, node); + ret = io->write(blob, node); + if (ret) { + printf("Unable to write state for '%s'\n", io->compat); + return -EINVAL; + } + + return 0; +} + +int sandbox_write_state(struct sandbox_state *state, const char *fname) +{ + struct sandbox_state_io *io; + bool got_err; + int size; + int ret; + int fd; + + /* Create a state FDT if we don't have one */ + if (!state->state_fdt) { + size = 0x4000; + state->state_fdt = os_malloc(size); + if (!state->state_fdt) { + puts("No memory to create FDT\n"); + return -ENOMEM; + } + ret = fdt_create_empty_tree(state->state_fdt, size); + if (ret < 0) { + printf("Cannot create empty state FDT: %s\n", + fdt_strerror(ret)); + ret = -EIO; + goto err_create; + } + } + + /* Call all the state write funtcions */ + got_err = false; + io = ll_entry_start(struct sandbox_state_io, state_io); + ret = 0; + for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) { + ret = sandbox_write_state_node(state, io); + if (ret == -EIO) + break; + else if (ret) + got_err = true; + } + + if (ret == -EIO) { + printf("Could not write sandbox state\n"); + goto err_create; + } + + ret = fdt_pack(state->state_fdt); + if (ret < 0) { + printf("Cannot pack state FDT: %s\n", fdt_strerror(ret)); + ret = -EINVAL; + goto err_create; + } + size = fdt_totalsize(state->state_fdt); + fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT); + if (fd < 0) { + printf("Cannot open sandbox state file '%s'\n", fname); + ret = -EIO; + goto err_create; + } + if (os_write(fd, state->state_fdt, size) != size) { + printf("Cannot write sandbox state file '%s'\n", fname); + ret = -EIO; + goto err_write; + } + os_close(fd); + + debug("Wrote sandbox state to '%s'%s\n", fname, + got_err ? " (with errors)" : ""); + + return 0; +err_write: + os_close(fd); +err_create: + os_free(state->state_fdt); + + return ret; +} + +int state_setprop(int node, const char *prop_name, const void *data, int size) +{ + void *blob; + int len; + int ret; + + fdt_getprop(state->state_fdt, node, prop_name, &len); + + /* Add space for the new property, its name and some overhead */ + ret = state_ensure_space(size - len + strlen(prop_name) + 32); + if (ret) + return ret; + + /* This should succeed, barring a mutiny */ + blob = state->state_fdt; + ret = fdt_setprop(blob, node, prop_name, data, size); + if (ret) { + printf("%s: Unable to set property '%s' in node '%s': %s\n", + __func__, prop_name, fdt_get_name(blob, node, NULL), + fdt_strerror(ret)); + return -ENOSPC; + } + + return 0; +} + struct sandbox_state *state_get_current(void) { assert(state); @@ -53,5 +373,16 @@ int state_uninit(void) } } + if (state->write_state) { + if (sandbox_write_state(state, state->state_fname)) { + printf("Failed to write sandbox state\n"); + return -1; + } + } + + if (state->state_fdt) + os_free(state->state_fdt); + memset(state, '\0', sizeof(*state)); + return 0; } diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index e4b4c724632..e8e4fea1b57 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -8,6 +8,7 @@ #include #include +#include /* How we exited U-Boot */ enum exit_type_id { @@ -34,12 +35,82 @@ struct sandbox_state { unsigned int ram_size; /* Size of RAM buffer */ const char *ram_buf_fname; /* Filename to use for RAM buffer */ bool write_ram_buf; /* Write RAM buffer on exit */ + const char *state_fname; /* File containing sandbox state */ + void *state_fdt; /* Holds saved state for sandbox */ + bool read_state; /* Read sandbox state on startup */ + bool write_state; /* Write sandbox state on exit */ + bool ignore_missing_state_on_read; /* No error if state missing */ /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] [CONFIG_SANDBOX_SPI_MAX_CS]; }; +/* Minimum space we guarantee in the state FDT when calling read/write*/ +#define SANDBOX_STATE_MIN_SPACE 0x1000 + +/** + * struct sandbox_state_io - methods to saved/restore sandbox state + * @name: Name of of the device tree node, also the name of the variable + * holding this data so it should be an identifier (use underscore + * instead of minus) + * @compat: Compatible string for the node containing this state + * + * @read: Function to read state from FDT + * If data is available, then blob and node will provide access to it. If + * not (blob == NULL and node == -1) this function should set up an empty + * data set for start-of-day. + * @param blob: Pointer to device tree blob, or NULL if no data to read + * @param node: Node offset to read from + * @return 0 if OK, -ve on error + * + * @write: Function to write state to FDT + * The caller will ensure that there is a node ready for the state. The + * node may already contain the old state, in which case it should be + * overridden. There is guaranteed to be SANDBOX_STATE_MIN_SPACE bytes + * of free space, so error checking is not required for fdt_setprop...() + * calls which add up to less than this much space. + * + * For adding larger properties, use state_setprop(). + * + * @param blob: Device tree blob holding state + * @param node: Node to write our state into + * + * Note that it is possible to save data as large blobs or as individual + * hierarchical properties. However, unless you intend to keep state files + * around for a long time and be able to run an old state file on a new + * sandbox, it might not be worth using individual properties for everything. + * This is certainly supported, it is just a matter of the effort you wish + * to put into the state read/write feature. + */ +struct sandbox_state_io { + const char *name; + const char *compat; + int (*write)(void *blob, int node); + int (*read)(const void *blob, int node); +}; + +/** + * SANDBOX_STATE_IO - Declare sandbox state to read/write + * + * Sandbox permits saving state from one run and restoring it in another. This + * allows the test system to retain state between runs and thus better + * emulate a real system. Examples of state that might be useful to save are + * the emulated GPIOs pin settings, flash memory contents and TPM private + * data. U-Boot memory contents is dealth with separately since it is large + * and it is not normally useful to save it (since a normal system does not + * preserve DRAM between runs). See the '-m' option for this. + * + * See struct sandbox_state_io above for member documentation. + */ +#define SANDBOX_STATE_IO(_name, _compat, _read, _write) \ + ll_entry_declare(struct sandbox_state_io, _name, state_io) = { \ + .name = __stringify(_name), \ + .read = _read, \ + .write = _write, \ + .compat = _compat, \ + } + /** * Record the exit type to be reported by the test program. * @@ -54,6 +125,49 @@ void state_record_exit(enum exit_type_id exit_type); */ struct sandbox_state *state_get_current(void); +/** + * Read the sandbox state from the supplied device tree file + * + * This calls all registered state handlers to read in the sandbox state + * from a previous test run. + * + * @param state Sandbox state to update + * @param fname Filename of device tree file to read from + * @return 0 if OK, -ve on error + */ +int sandbox_read_state(struct sandbox_state *state, const char *fname); + +/** + * Write the sandbox state to the supplied device tree file + * + * This calls all registered state handlers to write out the sandbox state + * so that it can be preserved for a future test run. + * + * If the file exists it is overwritten. + * + * @param state Sandbox state to update + * @param fname Filename of device tree file to write to + * @return 0 if OK, -ve on error + */ +int sandbox_write_state(struct sandbox_state *state, const char *fname); + +/** + * Add a property to a sandbox state node + * + * This is equivalent to fdt_setprop except that it automatically enlarges + * the device tree if necessary. That means it is safe to write any amount + * of data here. + * + * This function can only be called from within struct sandbox_state_io's + * ->write method, i.e. within state I/O drivers. + * + * @param node Device tree node to write to + * @param prop_name Property to write + * @param data Data to write into property + * @param size Size of data to write into property + */ +int state_setprop(int node, const char *prop_name, const void *data, int size); + /** * Initialize the test system state */ -- cgit v1.3.1 From b88eb329ce45c0c0f5471c8624f47bac35dd466e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:07 -0700 Subject: sandbox: Add a prototype for cleanup_before_linux() This function is defined but has no prototype declaration. Add it. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- arch/sandbox/include/asm/u-boot-sandbox.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index bed720cf81b..5707c2710d9 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -23,4 +23,6 @@ int dram_init(void); int sandbox_early_getopt_check(void); int sandbox_main_loop_init(void); +int cleanup_before_linux(void); + #endif /* _U_BOOT_SANDBOX_H_ */ -- cgit v1.3.1 From 6b87abe3ac357649a990c05a6a5f9fd232cca21c Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 9 Jan 2014 12:22:12 +0900 Subject: sh: sh4: Remove CONFIG_SH4A definition from source code SH4 and SH4A are compatible. But some instructions are different from these. In Linux kernel, It is treated as a separate CPU, but for now, I think that there is no need to divide especially in the U-Boot. This removes CONFIG_SH4A definition from source code, SH4A is treated as SH4. And this fix white space. Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/cpu/sh2/cpu.c | 4 ---- arch/sh/cpu/sh4/cpu.c | 4 ---- arch/sh/include/asm/cache.h | 4 ++-- arch/sh/include/asm/processor.h | 5 ++--- include/configs/ap_sh4a_4a.h | 1 - include/configs/ecovec.h | 1 - include/configs/r0p7734.h | 1 - include/configs/r7780mp.h | 1 - include/configs/sh7752evb.h | 1 - include/configs/sh7753evb.h | 1 - include/configs/sh7757lcr.h | 1 - include/configs/sh7785lcr.h | 1 - include/sh_tmu.h | 2 +- 13 files changed, 5 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/sh/cpu/sh2/cpu.c b/arch/sh/cpu/sh2/cpu.c index 18479a4c40f..a2f856f4594 100644 --- a/arch/sh/cpu/sh2/cpu.c +++ b/arch/sh/cpu/sh2/cpu.c @@ -23,11 +23,7 @@ int checkcpu(void) { -#if defined(CONFIG_SH2A) - puts("CPU: SH2A\n"); -#else puts("CPU: SH2\n"); -#endif return 0; } diff --git a/arch/sh/cpu/sh4/cpu.c b/arch/sh/cpu/sh4/cpu.c index 91133a38aee..e8ee0a45ab9 100644 --- a/arch/sh/cpu/sh4/cpu.c +++ b/arch/sh/cpu/sh4/cpu.c @@ -13,11 +13,7 @@ int checkcpu(void) { -#ifdef CONFIG_SH4A - puts("CPU: SH-4A\n"); -#else puts("CPU: SH4\n"); -#endif return 0; } diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h index b21dc4422ed..0698a377595 100644 --- a/arch/sh/include/asm/cache.h +++ b/arch/sh/include/asm/cache.h @@ -1,7 +1,7 @@ #ifndef __ASM_SH_CACHE_H #define __ASM_SH_CACHE_H -#if defined(CONFIG_SH4) || defined(CONFIG_SH4A) +#if defined(CONFIG_SH4) int cache_control(unsigned int cmd); @@ -18,7 +18,7 @@ struct __large_struct { unsigned long buf[100]; }; */ #define ARCH_DMA_MINALIGN 32 -#endif /* CONFIG_SH4 || CONFIG_SH4A */ +#endif /* CONFIG_SH4 */ /* * Use the L1 data cache line size value for the minimum DMA buffer alignment diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 938a89cff50..c3441ff5585 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -3,10 +3,9 @@ #if defined(CONFIG_SH2) || \ defined (CONFIG_SH2A) # include -#elif defined (CONFIG_SH3) +#elif defined(CONFIG_SH3) # include -#elif defined (CONFIG_SH4) || \ - defined (CONFIG_SH4A) +#elif defined(CONFIG_SH4) # include #endif #endif diff --git a/include/configs/ap_sh4a_4a.h b/include/configs/ap_sh4a_4a.h index 0162c3b04eb..bb39491f8b6 100644 --- a/include/configs/ap_sh4a_4a.h +++ b/include/configs/ap_sh4a_4a.h @@ -10,7 +10,6 @@ #define __AP_SH4A_4A_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_CPU_SH7734 1 #define CONFIG_AP_SH4A_4A 1 #define CONFIG_400MHZ_MODE 1 diff --git a/include/configs/ecovec.h b/include/configs/ecovec.h index ee9bd0731fb..3a5cc74829c 100644 --- a/include/configs/ecovec.h +++ b/include/configs/ecovec.h @@ -23,7 +23,6 @@ */ #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_CPU_SH7724 1 #define CONFIG_BOARD_LATE_INIT 1 #define CONFIG_ECOVEC 1 diff --git a/include/configs/r0p7734.h b/include/configs/r0p7734.h index 0bb7cc54bd2..53128ecc120 100644 --- a/include/configs/r0p7734.h +++ b/include/configs/r0p7734.h @@ -10,7 +10,6 @@ #define __R0P7734_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_CPU_SH7734 1 #define CONFIG_R0P7734 1 #define CONFIG_400MHZ_MODE 1 diff --git a/include/configs/r7780mp.h b/include/configs/r7780mp.h index 3574c52cc13..8156724f7f6 100644 --- a/include/configs/r7780mp.h +++ b/include/configs/r7780mp.h @@ -11,7 +11,6 @@ #define __R7780RP_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_CPU_SH7780 1 #define CONFIG_R7780MP 1 #define CONFIG_SYS_R7780MP_OLD_FLASH 1 diff --git a/include/configs/sh7752evb.h b/include/configs/sh7752evb.h index d4d45b4c569..f06abbca0c2 100644 --- a/include/configs/sh7752evb.h +++ b/include/configs/sh7752evb.h @@ -10,7 +10,6 @@ #define __SH7752EVB_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_SH_32BIT 1 #define CONFIG_CPU_SH7752 1 #define CONFIG_SH7752EVB 1 diff --git a/include/configs/sh7753evb.h b/include/configs/sh7753evb.h index fa6e74a3928..e400db08ad9 100644 --- a/include/configs/sh7753evb.h +++ b/include/configs/sh7753evb.h @@ -10,7 +10,6 @@ #define __SH7753EVB_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_SH_32BIT 1 #define CONFIG_CPU_SH7753 1 #define CONFIG_SH7753EVB 1 diff --git a/include/configs/sh7757lcr.h b/include/configs/sh7757lcr.h index 5752dbb3b28..08bff1da3fa 100644 --- a/include/configs/sh7757lcr.h +++ b/include/configs/sh7757lcr.h @@ -10,7 +10,6 @@ #define __SH7757LCR_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_SH_32BIT 1 #define CONFIG_CPU_SH7757 1 #define CONFIG_SH7757LCR 1 diff --git a/include/configs/sh7785lcr.h b/include/configs/sh7785lcr.h index 95f5a284022..2723eaf2d3d 100644 --- a/include/configs/sh7785lcr.h +++ b/include/configs/sh7785lcr.h @@ -10,7 +10,6 @@ #define __SH7785LCR_H #undef DEBUG -#define CONFIG_SH4A 1 #define CONFIG_CPU_SH7785 1 #define CONFIG_SH7785LCR 1 diff --git a/include/sh_tmu.h b/include/sh_tmu.h index f5b42faea41..61afc7136d7 100644 --- a/include/sh_tmu.h +++ b/include/sh_tmu.h @@ -47,7 +47,7 @@ struct tmu_regs { }; #endif /* CONFIG_SH3 */ -#if defined(CONFIG_SH4) || defined(CONFIG_SH4A) || defined(CONFIG_RMOBILE) +#if defined(CONFIG_SH4) || defined(CONFIG_RMOBILE) struct tmu_regs { u32 reserved; u8 tstr; -- cgit v1.3.1 From 5fe3aefd3dd0845ed4f69ba34b9790d3961d7ea8 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 9 Jan 2014 12:31:35 +0900 Subject: sh: sh2: Remove CONFIG_SH2A definition from asm/processor.h SH2 and SH2A use a common header. Both checks are not necessary. This removes CONFIG_SH2A definition from asm/processor.h. Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/include/asm/processor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index c3441ff5585..b8677da9593 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -1,7 +1,6 @@ #ifndef _ASM_SH_PROCESSOR_H_ #define _ASM_SH_PROCESSOR_H_ -#if defined(CONFIG_SH2) || \ - defined (CONFIG_SH2A) +#if defined(CONFIG_SH2) # include #elif defined(CONFIG_SH3) # include -- cgit v1.3.1 From c5c1af21764d9423b45c1d03e835c4547a8bc5cb Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Mon, 30 Dec 2013 18:26:14 -0600 Subject: socfpga/dwmmc: Adding DesignWare MMC driver support for SOCFPGA To add the DesignWare MMC driver support for Altera SOCFPGA. It required information such as clocks and bus width from platform specific files (SOCFPGA handoff files) Signed-off-by: Chin Liang See Cc: Rajeshwari Shinde Cc: Jaehoon Chung Cc: Pantelis Antoniou Cc: Wolfgang Denk Acked-by: Pantelis Antoniou --- arch/arm/include/asm/arch-socfpga/dwmmc.h | 12 ++++ arch/arm/include/asm/arch-socfpga/system_manager.h | 65 +++++++++++++++++++++ doc/README.socfpga | 53 +++++++++++++++++ drivers/mmc/Makefile | 1 + drivers/mmc/socfpga_dw_mmc.c | 68 ++++++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 arch/arm/include/asm/arch-socfpga/dwmmc.h create mode 100644 doc/README.socfpga create mode 100644 drivers/mmc/socfpga_dw_mmc.c (limited to 'arch') diff --git a/arch/arm/include/asm/arch-socfpga/dwmmc.h b/arch/arm/include/asm/arch-socfpga/dwmmc.h new file mode 100644 index 00000000000..945eb646ce8 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/dwmmc.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SOCFPGA_DWMMC_H_ +#define _SOCFPGA_DWMMC_H_ + +extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index); + +#endif /* _SOCFPGA_SDMMC_H_ */ diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index d965d25effc..838d21053ef 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -19,4 +19,69 @@ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM]; #define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400) +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ + ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) + +struct socfpga_system_manager { + u32 siliconid1; + u32 siliconid2; + u32 _pad_0x8_0xf[2]; + u32 wddbg; + u32 bootinfo; + u32 hpsinfo; + u32 parityinj; + u32 fpgaintfgrp_gbl; + u32 fpgaintfgrp_indiv; + u32 fpgaintfgrp_module; + u32 _pad_0x2c_0x2f; + u32 scanmgrgrp_ctrl; + u32 _pad_0x34_0x3f[3]; + u32 frzctrl_vioctrl; + u32 _pad_0x44_0x4f[3]; + u32 frzctrl_hioctrl; + u32 frzctrl_src; + u32 frzctrl_hwctrl; + u32 _pad_0x5c_0x5f; + u32 emacgrp_ctrl; + u32 emacgrp_l3master; + u32 _pad_0x68_0x6f[2]; + u32 dmagrp_ctrl; + u32 dmagrp_persecurity; + u32 _pad_0x78_0x7f[2]; + u32 iswgrp_handoff[8]; + u32 _pad_0xa0_0xbf[8]; + u32 romcodegrp_ctrl; + u32 romcodegrp_cpu1startaddr; + u32 romcodegrp_initswstate; + u32 romcodegrp_initswlastld; + u32 romcodegrp_bootromswstate; + u32 __pad_0xd4_0xdf[3]; + u32 romcodegrp_warmramgrp_enable; + u32 romcodegrp_warmramgrp_datastart; + u32 romcodegrp_warmramgrp_length; + u32 romcodegrp_warmramgrp_execution; + u32 romcodegrp_warmramgrp_crc; + u32 __pad_0xf4_0xff[3]; + u32 romhwgrp_ctrl; + u32 _pad_0x104_0x107; + u32 sdmmcgrp_ctrl; + u32 sdmmcgrp_l3master; + u32 nandgrp_bootstrap; + u32 nandgrp_l3master; + u32 usbgrp_l3master; + u32 _pad_0x11c_0x13f[9]; + u32 eccgrp_l2; + u32 eccgrp_ocram; + u32 eccgrp_usb0; + u32 eccgrp_usb1; + u32 eccgrp_emac0; + u32 eccgrp_emac1; + u32 eccgrp_dma; + u32 eccgrp_can0; + u32 eccgrp_can1; + u32 eccgrp_nand; + u32 eccgrp_qspi; + u32 eccgrp_sdmmc; +}; + #endif /* _SYSTEM_MANAGER_H_ */ diff --git a/doc/README.socfpga b/doc/README.socfpga new file mode 100644 index 00000000000..cfcbbfe3798 --- /dev/null +++ b/doc/README.socfpga @@ -0,0 +1,53 @@ + +-------------------------------------------- +SOCFPGA Documentation for U-Boot and SPL +-------------------------------------------- + +This README is about U-Boot and SPL support for Altera's ARM Cortex-A9MPCore +based SOCFPGA. To know more about the hardware itself, please refer to +www.altera.com. + + +-------------------------------------------- +socfpga_dw_mmc +-------------------------------------------- +Here are macro and detailed configuration required to enable DesignWare SDMMC +controller support within SOCFPGA + +#define CONFIG_MMC +-> To enable the SD MMC framework support + +#define CONFIG_SDMMC_BASE (SOCFPGA_SDMMC_ADDRESS) +-> The base address of CSR register for DesignWare SDMMC controller + +#define CONFIG_GENERIC_MMC +-> Enable the generic MMC driver + +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 256 +-> Using smaller max blk cnt to avoid flooding the limited stack in OCRAM + +#define CONFIG_DWMMC +-> Enable the common DesignWare SDMMC controller framework + +#define CONFIG_SOCFPGA_DWMMC +-> Enable the SOCFPGA specific driver for DesignWare SDMMC controller + +#define CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH 1024 +-> The FIFO depth for SOCFPGA DesignWare SDMMC controller + +#define CONFIG_SOCFPGA_DWMMC_DRVSEL 3 +-> Phase-shifted clock of sdmmc_clk for controller to drive command and data to +the card to meet hold time requirements. SD clock is running at 50MHz and +drvsel is set to shift 135 degrees (3 * 45 degrees). With that, the hold time +is 135 / 360 * 20ns = 7.5ns. + +#define CONFIG_SOCFPGA_DWMMC_SMPSEL 0 +-> Phase-shifted clock of sdmmc_clk used to sample the command and data from +the card + +#define CONFIG_SOCFPGA_DWMMC_BUS_WIDTH 4 +-> Bus width of data line which either 1, 4 or 8 and based on board routing. + +#define CONFIG_SOCFPGA_DWMMC_BUS_HZ 50000000 +-> The clock rate to controller. Do note the controller have a wrapper which +divide the clock from PLL by 4. diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1ed26cab34f..e793ed994e4 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o obj-$(CONFIG_DWMMC) += dw_mmc.o obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o +obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o else diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c new file mode 100644 index 00000000000..bc53a5da272 --- /dev/null +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +static const struct socfpga_clock_manager *clock_manager_base = + (void *)SOCFPGA_CLKMGR_ADDRESS; +static const struct socfpga_system_manager *system_manager_base = + (void *)SOCFPGA_SYSMGR_ADDRESS; + +static char *SOCFPGA_NAME = "SOCFPGA DWMMC"; + +static void socfpga_dwmci_clksel(struct dwmci_host *host) +{ + unsigned int drvsel; + unsigned int smplsel; + + /* Disable SDMMC clock. */ + clrbits_le32(&clock_manager_base->per_pll_en, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); + + /* Configures drv_sel and smpl_sel */ + drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; + smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; + + debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); + writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), + &system_manager_base->sdmmcgrp_ctrl); + + debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, + readl(&system_manager_base->sdmmcgrp_ctrl)); + + /* Enable SDMMC clock */ + setbits_le32(&clock_manager_base->per_pll_en, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); +} + +int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) +{ + struct dwmci_host *host = NULL; + host = calloc(sizeof(struct dwmci_host), 1); + if (!host) { + printf("dwmci_host calloc fail!\n"); + return -1; + } + + host->name = SOCFPGA_NAME; + host->ioaddr = (void *)regbase; + host->buswidth = bus_width; + host->clksel = socfpga_dwmci_clksel; + host->dev_index = index; + /* fixed clock divide by 4 which due to the SDMMC wrapper */ + host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ; + host->fifoth_val = MSIZE(0x2) | + RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | + TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); + + return add_dwmci(host, host->bus_hz, 400000); +} + -- cgit v1.3.1 From 0ae7653128c80a4f2920cbe9b124792c2fd9d9e0 Mon Sep 17 00:00:00 2001 From: David Feng Date: Sat, 14 Dec 2013 11:47:35 +0800 Subject: arm64: core support Relocation code based on a patch by Scott Wood, which is: Signed-off-by: Scott Wood Signed-off-by: David Feng --- arch/arm/config.mk | 7 +- arch/arm/cpu/armv8/Makefile | 17 +++ arch/arm/cpu/armv8/cache.S | 136 ++++++++++++++++++++ arch/arm/cpu/armv8/cache_v8.c | 219 ++++++++++++++++++++++++++++++++ arch/arm/cpu/armv8/config.mk | 15 +++ arch/arm/cpu/armv8/cpu.c | 43 +++++++ arch/arm/cpu/armv8/exceptions.S | 113 ++++++++++++++++ arch/arm/cpu/armv8/generic_timer.c | 31 +++++ arch/arm/cpu/armv8/gic.S | 106 ++++++++++++++++ arch/arm/cpu/armv8/start.S | 164 ++++++++++++++++++++++++ arch/arm/cpu/armv8/tlb.S | 34 +++++ arch/arm/cpu/armv8/transition.S | 83 ++++++++++++ arch/arm/cpu/armv8/u-boot.lds | 89 +++++++++++++ arch/arm/include/asm/armv8/mmu.h | 111 ++++++++++++++++ arch/arm/include/asm/byteorder.h | 12 ++ arch/arm/include/asm/cache.h | 5 + arch/arm/include/asm/config.h | 6 + arch/arm/include/asm/gic.h | 49 ++++++- arch/arm/include/asm/global_data.h | 6 +- arch/arm/include/asm/io.h | 15 ++- arch/arm/include/asm/macro.h | 53 ++++++++ arch/arm/include/asm/posix_types.h | 10 ++ arch/arm/include/asm/proc-armv/ptrace.h | 21 +++ arch/arm/include/asm/proc-armv/system.h | 59 ++++++++- arch/arm/include/asm/system.h | 84 ++++++++++++ arch/arm/include/asm/types.h | 4 + arch/arm/include/asm/u-boot.h | 4 + arch/arm/include/asm/unaligned.h | 2 +- arch/arm/lib/Makefile | 20 ++- arch/arm/lib/board.c | 7 +- arch/arm/lib/bootm.c | 24 ++++ arch/arm/lib/crt0_64.S | 113 ++++++++++++++++ arch/arm/lib/interrupts_64.c | 120 +++++++++++++++++ arch/arm/lib/relocate_64.S | 58 +++++++++ common/image.c | 1 + doc/README.arm64 | 46 +++++++ examples/standalone/stubs.c | 15 +++ include/image.h | 1 + 38 files changed, 1882 insertions(+), 21 deletions(-) create mode 100644 arch/arm/cpu/armv8/Makefile create mode 100644 arch/arm/cpu/armv8/cache.S create mode 100644 arch/arm/cpu/armv8/cache_v8.c create mode 100644 arch/arm/cpu/armv8/config.mk create mode 100644 arch/arm/cpu/armv8/cpu.c create mode 100644 arch/arm/cpu/armv8/exceptions.S create mode 100644 arch/arm/cpu/armv8/generic_timer.c create mode 100644 arch/arm/cpu/armv8/gic.S create mode 100644 arch/arm/cpu/armv8/start.S create mode 100644 arch/arm/cpu/armv8/tlb.S create mode 100644 arch/arm/cpu/armv8/transition.S create mode 100644 arch/arm/cpu/armv8/u-boot.lds create mode 100644 arch/arm/include/asm/armv8/mmu.h create mode 100644 arch/arm/lib/crt0_64.S create mode 100644 arch/arm/lib/interrupts_64.c create mode 100644 arch/arm/lib/relocate_64.S create mode 100644 doc/README.arm64 (limited to 'arch') diff --git a/arch/arm/config.mk b/arch/arm/config.mk index fd3e5fb661d..329c7a7f01d 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -17,7 +17,8 @@ endif LDFLAGS_FINAL += --gc-sections PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ - -fno-common -ffixed-r9 -msoft-float + -fno-common -ffixed-r9 +PLATFORM_RELFLAGS += $(call cc-option, -msoft-float) # Support generic board on ARM __HAVE_ARCH_GENERIC_BOARD := y @@ -105,4 +106,8 @@ PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations) endif # limit ourselves to the sections we want in the .bin. +ifdef CONFIG_ARM64 +OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn +else OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rel.dyn +endif diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile new file mode 100644 index 00000000000..b6eb6de5e35 --- /dev/null +++ b/arch/arm/cpu/armv8/Makefile @@ -0,0 +1,17 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y := start.o + +obj-y += cpu.o +obj-y += generic_timer.o +obj-y += cache_v8.o +obj-y += exceptions.o +obj-y += cache.o +obj-y += tlb.o +obj-y += gic.o +obj-y += transition.o diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S new file mode 100644 index 00000000000..546a83e8f8b --- /dev/null +++ b/arch/arm/cpu/armv8/cache.S @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * This file is based on sample code from ARMv8 ARM. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * void __asm_flush_dcache_level(level) + * + * clean and invalidate one level cache. + * + * x0: cache level + * x1~x9: clobbered + */ +ENTRY(__asm_flush_dcache_level) + lsl x1, x0, #1 + msr csselr_el1, x1 /* select cache level */ + isb /* sync change of cssidr_el1 */ + mrs x6, ccsidr_el1 /* read the new cssidr_el1 */ + and x2, x6, #7 /* x2 <- log2(cache line size)-4 */ + add x2, x2, #4 /* x2 <- log2(cache line size) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */ + add w4, w3, w3 + sub w4, w4, 1 /* round up log2(#ways + 1) */ + clz w5, w4 /* bit position of #ways */ + mov x4, #0x7fff + and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */ + /* x1 <- cache level << 1 */ + /* x2 <- line length offset */ + /* x3 <- number of cache ways - 1 */ + /* x4 <- number of cache sets - 1 */ + /* x5 <- bit position of #ways */ + +loop_set: + mov x6, x3 /* x6 <- working copy of #ways */ +loop_way: + lsl x7, x6, x5 + orr x9, x1, x7 /* map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + dc cisw, x9 /* clean & invalidate by set/way */ + subs x6, x6, #1 /* decrement the way */ + b.ge loop_way + subs x4, x4, #1 /* decrement the set */ + b.ge loop_set + + ret +ENDPROC(__asm_flush_dcache_level) + +/* + * void __asm_flush_dcache_all(void) + * + * clean and invalidate all data cache by SET/WAY. + */ +ENTRY(__asm_flush_dcache_all) + dsb sy + mrs x10, clidr_el1 /* read clidr_el1 */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 <- loc */ + cbz x11, finished /* if loc is 0, exit */ + mov x15, lr + mov x0, #0 /* start flush at cache level 0 */ + /* x0 <- cache level */ + /* x10 <- clidr_el1 */ + /* x11 <- loc */ + /* x15 <- return address */ + +loop_level: + lsl x1, x0, #1 + add x1, x1, x0 /* x0 <- tripled cache level */ + lsr x1, x10, x1 + and x1, x1, #7 /* x1 <- cache type */ + cmp x1, #2 + b.lt skip /* skip if no cache or icache */ + bl __asm_flush_dcache_level +skip: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt loop_level + + mov x0, #0 + msr csselr_el1, x0 /* resotre csselr_el1 */ + dsb sy + isb + mov lr, x15 + +finished: + ret +ENDPROC(__asm_flush_dcache_all) + +/* + * void __asm_flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +ENTRY(__asm_flush_dcache_range) + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 /* clean & invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__asm_flush_dcache_range) + +/* + * void __asm_invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__asm_invalidate_icache_all) + ic ialluis + isb sy + ret +ENDPROC(__asm_invalidate_icache_all) diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c new file mode 100644 index 00000000000..131fdaba3f3 --- /dev/null +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -0,0 +1,219 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_DCACHE_OFF + +static void set_pgtable_section(u64 section, u64 memory_type) +{ + u64 *page_table = (u64 *)gd->arch.tlb_addr; + u64 value; + + value = (section << SECTION_SHIFT) | PMD_TYPE_SECT | PMD_SECT_AF; + value |= PMD_ATTRINDX(memory_type); + page_table[section] = value; +} + +/* to activate the MMU we need to set up virtual memory */ +static void mmu_setup(void) +{ + int i, j, el; + bd_t *bd = gd->bd; + + /* Setup an identity-mapping for all spaces */ + for (i = 0; i < (PGTABLE_SIZE >> 3); i++) + set_pgtable_section(i, MT_DEVICE_NGNRNE); + + /* Setup an identity-mapping for all RAM space */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + ulong start = bd->bi_dram[i].start; + ulong end = bd->bi_dram[i].start + bd->bi_dram[i].size; + for (j = start >> SECTION_SHIFT; + j < end >> SECTION_SHIFT; j++) { + set_pgtable_section(j, MT_NORMAL); + } + } + + /* load TTBR0 */ + el = current_el(); + if (el == 1) + asm volatile("msr ttbr0_el1, %0" + : : "r" (gd->arch.tlb_addr) : "memory"); + else if (el == 2) + asm volatile("msr ttbr0_el2, %0" + : : "r" (gd->arch.tlb_addr) : "memory"); + else + asm volatile("msr ttbr0_el3, %0" + : : "r" (gd->arch.tlb_addr) : "memory"); + + /* enable the mmu */ + set_sctlr(get_sctlr() | CR_M); +} + +/* + * Performs a invalidation of the entire data cache at all levels + */ +void invalidate_dcache_all(void) +{ + __asm_flush_dcache_all(); +} + +/* + * Performs a clean & invalidation of the entire data cache at all levels + */ +void flush_dcache_all(void) +{ + __asm_flush_dcache_all(); +} + +/* + * Invalidates range in all levels of D-cache/unified cache + */ +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ + __asm_flush_dcache_range(start, stop); +} + +/* + * Flush range(clean & invalidate) from all levels of D-cache/unified cache + */ +void flush_dcache_range(unsigned long start, unsigned long stop) +{ + __asm_flush_dcache_range(start, stop); +} + +void dcache_enable(void) +{ + /* The data cache is not active unless the mmu is enabled */ + if (!(get_sctlr() & CR_M)) { + invalidate_dcache_all(); + __asm_invalidate_tlb_all(); + mmu_setup(); + } + + set_sctlr(get_sctlr() | CR_C); +} + +void dcache_disable(void) +{ + uint32_t sctlr; + + sctlr = get_sctlr(); + + /* if cache isn't enabled no need to disable */ + if (!(sctlr & CR_C)) + return; + + set_sctlr(sctlr & ~(CR_C|CR_M)); + + flush_dcache_all(); + __asm_invalidate_tlb_all(); +} + +int dcache_status(void) +{ + return (get_sctlr() & CR_C) != 0; +} + +#else /* CONFIG_SYS_DCACHE_OFF */ + +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void dcache_enable(void) +{ +} + +void dcache_disable(void) +{ +} + +int dcache_status(void) +{ + return 0; +} + +#endif /* CONFIG_SYS_DCACHE_OFF */ + +#ifndef CONFIG_SYS_ICACHE_OFF + +void icache_enable(void) +{ + set_sctlr(get_sctlr() | CR_I); +} + +void icache_disable(void) +{ + set_sctlr(get_sctlr() & ~CR_I); +} + +int icache_status(void) +{ + return (get_sctlr() & CR_I) != 0; +} + +void invalidate_icache_all(void) +{ + __asm_invalidate_icache_all(); +} + +#else /* CONFIG_SYS_ICACHE_OFF */ + +void icache_enable(void) +{ +} + +void icache_disable(void) +{ +} + +int icache_status(void) +{ + return 0; +} + +void invalidate_icache_all(void) +{ +} + +#endif /* CONFIG_SYS_ICACHE_OFF */ + +/* + * Enable dCache & iCache, whether cache is actually enabled + * depend on CONFIG_SYS_DCACHE_OFF and CONFIG_SYS_ICACHE_OFF + */ +void enable_caches(void) +{ + icache_enable(); + dcache_enable(); +} + +/* + * Flush range from all levels of d-cache/unified-cache + */ +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk new file mode 100644 index 00000000000..027a68ca577 --- /dev/null +++ b/arch/arm/cpu/armv8/config.mk @@ -0,0 +1,15 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, +# +# SPDX-License-Identifier: GPL-2.0+ +# +PLATFORM_RELFLAGS += -fno-common -ffixed-x18 + +# SEE README.arm-unaligned-accesses +PF_NO_UNALIGNED := $(call cc-option, -mstrict-align) +PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED) + +PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8) +PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED) diff --git a/arch/arm/cpu/armv8/cpu.c b/arch/arm/cpu/armv8/cpu.c new file mode 100644 index 00000000000..e06c3cc04de --- /dev/null +++ b/arch/arm/cpu/armv8/cpu.c @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +int cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * disable interrupt and turn off caches etc ... + */ + disable_interrupts(); + + /* + * Turn off I-cache and invalidate it + */ + icache_disable(); + invalidate_icache_all(); + + /* + * turn off D-cache + * dcache_disable() in turn flushes the d-cache and disables MMU + */ + dcache_disable(); + invalidate_dcache_all(); + + return 0; +} diff --git a/arch/arm/cpu/armv8/exceptions.S b/arch/arm/cpu/armv8/exceptions.S new file mode 100644 index 00000000000..b91a1b662f4 --- /dev/null +++ b/arch/arm/cpu/armv8/exceptions.S @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +/* + * Enter Exception. + * This will save the processor state that is ELR/X0~X30 + * to the stack frame. + */ +.macro exception_entry + stp x29, x30, [sp, #-16]! + stp x27, x28, [sp, #-16]! + stp x25, x26, [sp, #-16]! + stp x23, x24, [sp, #-16]! + stp x21, x22, [sp, #-16]! + stp x19, x20, [sp, #-16]! + stp x17, x18, [sp, #-16]! + stp x15, x16, [sp, #-16]! + stp x13, x14, [sp, #-16]! + stp x11, x12, [sp, #-16]! + stp x9, x10, [sp, #-16]! + stp x7, x8, [sp, #-16]! + stp x5, x6, [sp, #-16]! + stp x3, x4, [sp, #-16]! + stp x1, x2, [sp, #-16]! + + /* Could be running at EL3/EL2/EL1 */ + switch_el x11, 3f, 2f, 1f +3: mrs x1, esr_el3 + mrs x2, elr_el3 + b 0f +2: mrs x1, esr_el2 + mrs x2, elr_el2 + b 0f +1: mrs x1, esr_el1 + mrs x2, elr_el1 +0: + stp x2, x0, [sp, #-16]! + mov x0, sp +.endm + +/* + * Exception vectors. + */ + .align 11 + .globl vectors +vectors: + .align 7 + b _do_bad_sync /* Current EL Synchronous Thread */ + + .align 7 + b _do_bad_irq /* Current EL IRQ Thread */ + + .align 7 + b _do_bad_fiq /* Current EL FIQ Thread */ + + .align 7 + b _do_bad_error /* Current EL Error Thread */ + + .align 7 + b _do_sync /* Current EL Synchronous Handler */ + + .align 7 + b _do_irq /* Current EL IRQ Handler */ + + .align 7 + b _do_fiq /* Current EL FIQ Handler */ + + .align 7 + b _do_error /* Current EL Error Handler */ + + +_do_bad_sync: + exception_entry + bl do_bad_sync + +_do_bad_irq: + exception_entry + bl do_bad_irq + +_do_bad_fiq: + exception_entry + bl do_bad_fiq + +_do_bad_error: + exception_entry + bl do_bad_error + +_do_sync: + exception_entry + bl do_sync + +_do_irq: + exception_entry + bl do_irq + +_do_fiq: + exception_entry + bl do_fiq + +_do_error: + exception_entry + bl do_error diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c new file mode 100644 index 00000000000..223b95e210e --- /dev/null +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * Generic timer implementation of get_tbclk() + */ +unsigned long get_tbclk(void) +{ + unsigned long cntfrq; + asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq)); + return cntfrq; +} + +/* + * Generic timer implementation of timer_read_counter() + */ +unsigned long timer_read_counter(void) +{ + unsigned long cntpct; + isb(); + asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); + return cntpct; +} diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S new file mode 100644 index 00000000000..599aa8f2ba1 --- /dev/null +++ b/arch/arm/cpu/armv8/gic.S @@ -0,0 +1,106 @@ +/* + * GIC Initialization Routines. + * + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + + +/************************************************************************* + * + * void gic_init(void) __attribute__((weak)); + * + * Currently, this routine only initialize secure copy of GIC + * with Security Extensions at EL3. + * + *************************************************************************/ +WEAK(gic_init) + branch_if_slave x0, 2f + + /* Initialize Distributor and SPIs */ + ldr x1, =GICD_BASE + mov w0, #0x3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1, GICD_CTLR] /* Secure GICD_CTLR */ + ldr w0, [x1, GICD_TYPER] + and w2, w0, #0x1f /* ITLinesNumber */ + cbz w2, 2f /* No SPIs */ + add x1, x1, (GICD_IGROUPRn + 4) + mov w0, #~0 /* Config SPIs as Grp1 */ +1: str w0, [x1], #0x4 + sub w2, w2, #0x1 + cbnz w2, 1b + + /* Initialize SGIs and PPIs */ +2: ldr x1, =GICD_BASE + mov w0, #~0 /* Config SGIs and PPIs as Grp1 */ + str w0, [x1, GICD_IGROUPRn] /* GICD_IGROUPR0 */ + mov w0, #0x1 /* Enable SGI 0 */ + str w0, [x1, GICD_ISENABLERn] + + /* Initialize Cpu Interface */ + ldr x1, =GICC_BASE + mov w0, #0x1e7 /* Disable IRQ/FIQ Bypass & */ + /* Enable Ack Group1 Interrupt & */ + /* EnableGrp0 & EnableGrp1 */ + str w0, [x1, GICC_CTLR] /* Secure GICC_CTLR */ + + mov w0, #0x1 << 7 /* Non-Secure access to GICC_PMR */ + str w0, [x1, GICC_PMR] + + ret +ENDPROC(gic_init) + + +/************************************************************************* + * + * void gic_send_sgi(u64 sgi) __attribute__((weak)); + * + *************************************************************************/ +WEAK(gic_send_sgi) + ldr x1, =GICD_BASE + mov w2, #0x8000 + movk w2, #0x100, lsl #16 + orr w2, w2, w0 + str w2, [x1, GICD_SGIR] + ret +ENDPROC(gic_send_sgi) + + +/************************************************************************* + * + * void wait_for_wakeup(void) __attribute__((weak)); + * + * Wait for SGI 0 from master. + * + *************************************************************************/ +WEAK(wait_for_wakeup) + ldr x1, =GICC_BASE +0: wfi + ldr w0, [x1, GICC_AIAR] + str w0, [x1, GICC_AEOIR] + cbnz w0, 0b + ret +ENDPROC(wait_for_wakeup) + + +/************************************************************************* + * + * void smp_kick_all_cpus(void) __attribute__((weak)); + * + *************************************************************************/ +WEAK(smp_kick_all_cpus) + /* Kick secondary cpus up by SGI 0 interrupt */ + mov x0, xzr /* SGI 0 */ + mov x29, lr /* Save LR */ + bl gic_send_sgi + mov lr, x29 /* Restore LR */ + ret +ENDPROC(smp_kick_all_cpus) diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S new file mode 100644 index 00000000000..bcc26030983 --- /dev/null +++ b/arch/arm/cpu/armv8/start.S @@ -0,0 +1,164 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +/************************************************************************* + * + * Startup Code (reset vector) + * + *************************************************************************/ + +.globl _start +_start: + b reset + + .align 3 + +.globl _TEXT_BASE +_TEXT_BASE: + .quad CONFIG_SYS_TEXT_BASE + +/* + * These are defined in the linker script. + */ +.globl _end_ofs +_end_ofs: + .quad _end - _start + +.globl _bss_start_ofs +_bss_start_ofs: + .quad __bss_start - _start + +.globl _bss_end_ofs +_bss_end_ofs: + .quad __bss_end - _start + +reset: + /* + * Could be EL3/EL2/EL1, Initial State: + * Little Endian, MMU Disabled, i/dCache Disabled + */ + adr x0, vectors + switch_el x1, 3f, 2f, 1f +3: msr vbar_el3, x0 + msr cptr_el3, xzr /* Enable FP/SIMD */ + ldr x0, =COUNTER_FREQUENCY + msr cntfrq_el0, x0 /* Initialize CNTFRQ */ + b 0f +2: msr vbar_el2, x0 + mov x0, #0x33ff + msr cptr_el2, x0 /* Enable FP/SIMD */ + b 0f +1: msr vbar_el1, x0 + mov x0, #3 << 20 + msr cpacr_el1, x0 /* Enable FP/SIMD */ +0: + + /* Cache/BPB/TLB Invalidate */ + bl __asm_flush_dcache_all /* dCache clean&invalidate */ + bl __asm_invalidate_icache_all /* iCache invalidate */ + bl __asm_invalidate_tlb_all /* invalidate TLBs */ + + /* Processor specific initialization */ + bl lowlevel_init + + branch_if_master x0, x1, master_cpu + + /* + * Slave CPUs + */ +slave_cpu: + wfe + ldr x1, =CPU_RELEASE_ADDR + ldr x0, [x1] + cbz x0, slave_cpu + br x0 /* branch to the given address */ + + /* + * Master CPU + */ +master_cpu: + bl _main + +/*-----------------------------------------------------------------------*/ + +WEAK(lowlevel_init) + /* Initialize GIC Secure Bank Status */ + mov x29, lr /* Save LR */ + bl gic_init + + branch_if_master x0, x1, 1f + + /* + * Slave should wait for master clearing spin table. + * This sync prevent salves observing incorrect + * value of spin table and jumping to wrong place. + */ + bl wait_for_wakeup + + /* + * All processors will enter EL2 and optionally EL1. + */ + bl armv8_switch_to_el2 +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + bl armv8_switch_to_el1 +#endif + +1: + mov lr, x29 /* Restore LR */ + ret +ENDPROC(lowlevel_init) + +/*-----------------------------------------------------------------------*/ + +ENTRY(c_runtime_cpu_setup) + /* If I-cache is enabled invalidate it */ +#ifndef CONFIG_SYS_ICACHE_OFF + ic iallu /* I+BTB cache invalidate */ + isb sy +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF + /* + * Setup MAIR and TCR. + */ + ldr x0, =MEMORY_ATTRIBUTES + ldr x1, =TCR_FLAGS + + switch_el x2, 3f, 2f, 1f +3: orr x1, x1, TCR_EL3_IPS_BITS + msr mair_el3, x0 + msr tcr_el3, x1 + b 0f +2: orr x1, x1, TCR_EL2_IPS_BITS + msr mair_el2, x0 + msr tcr_el2, x1 + b 0f +1: orr x1, x1, TCR_EL1_IPS_BITS + msr mair_el1, x0 + msr tcr_el1, x1 +0: +#endif + + /* Relocate vBAR */ + adr x0, vectors + switch_el x1, 3f, 2f, 1f +3: msr vbar_el3, x0 + b 0f +2: msr vbar_el2, x0 + b 0f +1: msr vbar_el1, x0 +0: + + ret +ENDPROC(c_runtime_cpu_setup) diff --git a/arch/arm/cpu/armv8/tlb.S b/arch/arm/cpu/armv8/tlb.S new file mode 100644 index 00000000000..f840b04df50 --- /dev/null +++ b/arch/arm/cpu/armv8/tlb.S @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * void __asm_invalidate_tlb_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__asm_invalidate_tlb_all) + switch_el x9, 3f, 2f, 1f +3: tlbi alle3 + dsb sy + isb + b 0f +2: tlbi alle2 + dsb sy + isb + b 0f +1: tlbi vmalle1 + dsb sy + isb +0: + ret +ENDPROC(__asm_invalidate_tlb_all) diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S new file mode 100644 index 00000000000..e0a59460091 --- /dev/null +++ b/arch/arm/cpu/armv8/transition.S @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +ENTRY(armv8_switch_to_el2) + switch_el x0, 1f, 0f, 0f +0: ret +1: + mov x0, #0x5b1 /* Non-secure EL0/EL1 | HVC | 64bit EL2 */ + msr scr_el3, x0 + msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */ + mov x0, #0x33ff + msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */ + + /* Initialize SCTLR_EL2 */ + msr sctlr_el2, xzr + + /* Return to the EL2_SP2 mode from EL3 */ + mov x0, sp + msr sp_el2, x0 /* Migrate SP */ + mrs x0, vbar_el3 + msr vbar_el2, x0 /* Migrate VBAR */ + mov x0, #0x3c9 + msr spsr_el3, x0 /* EL2_SP2 | D | A | I | F */ + msr elr_el3, lr + eret +ENDPROC(armv8_switch_to_el2) + +ENTRY(armv8_switch_to_el1) + switch_el x0, 0f, 1f, 0f +0: ret +1: + /* Initialize Generic Timers */ + mrs x0, cnthctl_el2 + orr x0, x0, #0x3 /* Enable EL1 access to timers */ + msr cnthctl_el2, x0 + msr cntvoff_el2, x0 + mrs x0, cntkctl_el1 + orr x0, x0, #0x3 /* Enable EL0 access to timers */ + msr cntkctl_el1, x0 + + /* Initilize MPID/MPIDR registers */ + mrs x0, midr_el1 + mrs x1, mpidr_el1 + msr vpidr_el2, x0 + msr vmpidr_el2, x1 + + /* Disable coprocessor traps */ + mov x0, #0x33ff + msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */ + msr hstr_el2, xzr /* Disable coprocessor traps to EL2 */ + mov x0, #3 << 20 + msr cpacr_el1, x0 /* Enable FP/SIMD at EL1 */ + + /* Initialize HCR_EL2 */ + mov x0, #(1 << 31) /* 64bit EL1 */ + orr x0, x0, #(1 << 29) /* Disable HVC */ + msr hcr_el2, x0 + + /* SCTLR_EL1 initialization */ + mov x0, #0x0800 + movk x0, #0x30d0, lsl #16 + msr sctlr_el1, x0 + + /* Return to the EL1_SP1 mode from EL2 */ + mov x0, sp + msr sp_el1, x0 /* Migrate SP */ + mrs x0, vbar_el2 + msr vbar_el1, x0 /* Migrate VBAR */ + mov x0, #0x3c5 + msr spsr_el2, x0 /* EL1_SP1 | D | A | I | F */ + msr elr_el2, lr + eret +ENDPROC(armv8_switch_to_el1) diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds new file mode 100644 index 00000000000..4c122223705 --- /dev/null +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(8); + .text : + { + *(.__image_copy_start) + CPUDIR/start.o (.text*) + *(.text*) + } + + . = ALIGN(8); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(8); + .data : { + *(.data*) + } + + . = ALIGN(8); + + . = .; + + . = ALIGN(8); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(8); + + .image_copy_end : + { + *(.__image_copy_end) + } + + . = ALIGN(8); + + .rel_dyn_start : + { + *(.__rel_dyn_start) + } + + .rela.dyn : { + *(.rela*) + } + + .rel_dyn_end : + { + *(.__rel_dyn_end) + } + + _end = .; + + . = ALIGN(8); + + .bss_start : { + KEEP(*(.__bss_start)); + } + + .bss : { + *(.bss*) + . = ALIGN(8); + } + + .bss_end : { + KEEP(*(.__bss_end)); + } + + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h new file mode 100644 index 00000000000..1193e76a82a --- /dev/null +++ b/arch/arm/include/asm/armv8/mmu.h @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARMV8_MMU_H_ +#define _ASM_ARMV8_MMU_H_ + +#ifdef __ASSEMBLY__ +#define _AC(X, Y) X +#else +#define _AC(X, Y) (X##Y) +#endif + +#define UL(x) _AC(x, UL) + +/***************************************************************/ +/* + * The following definitions are related each other, shoud be + * calculated specifically. + */ +#define VA_BITS (42) /* 42 bits virtual address */ + +/* PAGE_SHIFT determines the page size */ +#undef PAGE_SIZE +#define PAGE_SHIFT 16 +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 29 +#define SECTION_SIZE (UL(1) << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) +/***************************************************************/ + +/* + * Memory types + */ +#define MT_DEVICE_NGNRNE 0 +#define MT_DEVICE_NGNRE 1 +#define MT_DEVICE_GRE 2 +#define MT_NORMAL_NC 3 +#define MT_NORMAL 4 + +#define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE*8)) | \ + (0x04 << (MT_DEVICE_NGNRE*8)) | \ + (0x0c << (MT_DEVICE_GRE*8)) | \ + (0x44 << (MT_NORMAL_NC*8)) | \ + (UL(0xff) << (MT_NORMAL*8))) + +/* + * Hardware page table definitions. + * + * Level 2 descriptor (PMD). + */ +#define PMD_TYPE_MASK (3 << 0) +#define PMD_TYPE_FAULT (0 << 0) +#define PMD_TYPE_TABLE (3 << 0) +#define PMD_TYPE_SECT (1 << 0) + +/* + * Section + */ +#define PMD_SECT_S (3 << 8) +#define PMD_SECT_AF (1 << 10) +#define PMD_SECT_NG (1 << 11) +#define PMD_SECT_PXN (UL(1) << 53) +#define PMD_SECT_UXN (UL(1) << 54) + +/* + * AttrIndx[2:0] + */ +#define PMD_ATTRINDX(t) ((t) << 2) +#define PMD_ATTRINDX_MASK (7 << 2) + +/* + * TCR flags. + */ +#define TCR_T0SZ(x) ((64 - (x)) << 0) +#define TCR_IRGN_NC (0 << 8) +#define TCR_IRGN_WBWA (1 << 8) +#define TCR_IRGN_WT (2 << 8) +#define TCR_IRGN_WBNWA (3 << 8) +#define TCR_IRGN_MASK (3 << 8) +#define TCR_ORGN_NC (0 << 10) +#define TCR_ORGN_WBWA (1 << 10) +#define TCR_ORGN_WT (2 << 10) +#define TCR_ORGN_WBNWA (3 << 10) +#define TCR_ORGN_MASK (3 << 10) +#define TCR_SHARED_NON (0 << 12) +#define TCR_SHARED_OUTER (1 << 12) +#define TCR_SHARED_INNER (2 << 12) +#define TCR_TG0_4K (0 << 14) +#define TCR_TG0_64K (1 << 14) +#define TCR_TG0_16K (2 << 14) +#define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */ +#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ +#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */ + +/* PTWs cacheable, inner/outer WBWA and non-shareable */ +#define TCR_FLAGS (TCR_TG0_64K | \ + TCR_SHARED_NON | \ + TCR_ORGN_WBWA | \ + TCR_IRGN_WBWA | \ + TCR_T0SZ(VA_BITS)) + +#endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h index c3489f1e1fc..71a9966301d 100644 --- a/arch/arm/include/asm/byteorder.h +++ b/arch/arm/include/asm/byteorder.h @@ -23,10 +23,22 @@ # define __SWAB_64_THRU_32__ #endif +#ifdef CONFIG_ARM64 + +#ifdef __AARCH64EB__ +#include +#else +#include +#endif + +#else /* CONFIG_ARM64 */ + #ifdef __ARMEB__ #include #else #include #endif +#endif /* CONFIG_ARM64 */ + #endif diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 6d60a4a6d95..ddebbc8fcdc 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -11,6 +11,8 @@ #include +#ifndef CONFIG_ARM64 + /* * Invalidate L2 Cache using co-proc instruction */ @@ -28,6 +30,9 @@ void l2_cache_disable(void); void set_section_dcache(int section, enum dcache_option option); void dram_bank_mmu_setup(int bank); + +#endif + /* * The current upper bound for ARM L1 data cache line sizes is 64 bytes. We * use that value for aligning DMA buffers unless the board config has specified diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 99b703e1e4c..abf79e5c9ed 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -9,4 +9,10 @@ #define CONFIG_LMB #define CONFIG_SYS_BOOT_RAMDISK_HIGH + +#ifdef CONFIG_ARM64 +#define CONFIG_PHYS_64BIT +#define CONFIG_STATIC_RELA +#endif + #endif diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h index a0891cc09c9..ac2b2bfbed2 100644 --- a/arch/arm/include/asm/gic.h +++ b/arch/arm/include/asm/gic.h @@ -1,19 +1,54 @@ -#ifndef __GIC_V2_H__ -#define __GIC_V2_H__ +#ifndef __GIC_H__ +#define __GIC_H__ -/* register offsets for the ARM generic interrupt controller (GIC) */ +/* Register offsets for the ARM generic interrupt controller (GIC) */ #define GIC_DIST_OFFSET 0x1000 +#define GIC_CPU_OFFSET_A9 0x0100 +#define GIC_CPU_OFFSET_A15 0x2000 + +/* Distributor Registers */ #define GICD_CTLR 0x0000 #define GICD_TYPER 0x0004 +#define GICD_IIDR 0x0008 +#define GICD_STATUSR 0x0010 +#define GICD_SETSPI_NSR 0x0040 +#define GICD_CLRSPI_NSR 0x0048 +#define GICD_SETSPI_SR 0x0050 +#define GICD_CLRSPI_SR 0x0058 +#define GICD_SEIR 0x0068 #define GICD_IGROUPRn 0x0080 -#define GICD_SGIR 0x0F00 +#define GICD_ISENABLERn 0x0100 +#define GICD_ICENABLERn 0x0180 +#define GICD_ISPENDRn 0x0200 +#define GICD_ICPENDRn 0x0280 +#define GICD_ISACTIVERn 0x0300 +#define GICD_ICACTIVERn 0x0380 +#define GICD_IPRIORITYRn 0x0400 +#define GICD_ITARGETSRn 0x0800 +#define GICD_ICFGR 0x0c00 +#define GICD_IGROUPMODRn 0x0d00 +#define GICD_NSACRn 0x0e00 +#define GICD_SGIR 0x0f00 +#define GICD_CPENDSGIRn 0x0f10 +#define GICD_SPENDSGIRn 0x0f20 +#define GICD_IROUTERn 0x6000 -#define GIC_CPU_OFFSET_A9 0x0100 -#define GIC_CPU_OFFSET_A15 0x2000 +/* Cpu Interface Memory Mapped Registers */ #define GICC_CTLR 0x0000 #define GICC_PMR 0x0004 +#define GICC_BPR 0x0008 #define GICC_IAR 0x000C #define GICC_EOIR 0x0010 +#define GICC_RPR 0x0014 +#define GICC_HPPIR 0x0018 +#define GICC_ABPR 0x001c +#define GICC_AIAR 0x0020 +#define GICC_AEOIR 0x0024 +#define GICC_AHPPIR 0x0028 +#define GICC_APRn 0x00d0 +#define GICC_NSAPRn 0x00e0 +#define GICC_IIDR 0x00fc +#define GICC_DIR 0x1000 -#endif +#endif /* __GIC_H__ */ diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index e126436093d..60e872637fc 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -47,6 +47,10 @@ struct arch_global_data { #include -#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") +#ifdef CONFIG_ARM64 +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("x18") +#else +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") +#endif #endif /* __ASM_GBL_DATA_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 1fbc531a084..6a1f05ac3ef 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -75,42 +75,45 @@ static inline phys_addr_t virt_to_phys(void * vaddr) #define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) #define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) -extern inline void __raw_writesb(unsigned int addr, const void *data, int bytelen) +extern inline void __raw_writesb(unsigned long addr, const void *data, + int bytelen) { uint8_t *buf = (uint8_t *)data; while(bytelen--) __arch_putb(*buf++, addr); } -extern inline void __raw_writesw(unsigned int addr, const void *data, int wordlen) +extern inline void __raw_writesw(unsigned long addr, const void *data, + int wordlen) { uint16_t *buf = (uint16_t *)data; while(wordlen--) __arch_putw(*buf++, addr); } -extern inline void __raw_writesl(unsigned int addr, const void *data, int longlen) +extern inline void __raw_writesl(unsigned long addr, const void *data, + int longlen) { uint32_t *buf = (uint32_t *)data; while(longlen--) __arch_putl(*buf++, addr); } -extern inline void __raw_readsb(unsigned int addr, void *data, int bytelen) +extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen) { uint8_t *buf = (uint8_t *)data; while(bytelen--) *buf++ = __arch_getb(addr); } -extern inline void __raw_readsw(unsigned int addr, void *data, int wordlen) +extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen) { uint16_t *buf = (uint16_t *)data; while(wordlen--) *buf++ = __arch_getw(addr); } -extern inline void __raw_readsl(unsigned int addr, void *data, int longlen) +extern inline void __raw_readsl(unsigned long addr, void *data, int longlen) { uint32_t *buf = (uint32_t *)data; while(longlen--) diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index ff13f36ba00..f77e4b880e4 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -54,5 +54,58 @@ bcs 1b .endm +#ifdef CONFIG_ARM64 +/* + * Register aliases. + */ +lr .req x30 + +/* + * Branch according to exception level + */ +.macro switch_el, xreg, el3_label, el2_label, el1_label + mrs \xreg, CurrentEL + cmp \xreg, 0xc + b.eq \el3_label + cmp \xreg, 0x8 + b.eq \el2_label + cmp \xreg, 0x4 + b.eq \el1_label +.endm + +/* + * Branch if current processor is a slave, + * choose processor with all zero affinity value as the master. + */ +.macro branch_if_slave, xreg, slave_label + mrs \xreg, mpidr_el1 + tst \xreg, #0xff /* Test Affinity 0 */ + b.ne \slave_label + lsr \xreg, \xreg, #8 + tst \xreg, #0xff /* Test Affinity 1 */ + b.ne \slave_label + lsr \xreg, \xreg, #8 + tst \xreg, #0xff /* Test Affinity 2 */ + b.ne \slave_label + lsr \xreg, \xreg, #16 + tst \xreg, #0xff /* Test Affinity 3 */ + b.ne \slave_label +.endm + +/* + * Branch if current processor is a master, + * choose processor with all zero affinity value as the master. + */ +.macro branch_if_master, xreg1, xreg2, master_label + mrs \xreg1, mpidr_el1 + lsr \xreg2, \xreg1, #32 + lsl \xreg1, \xreg1, #40 + lsr \xreg1, \xreg1, #40 + orr \xreg1, \xreg1, \xreg2 + cbz \xreg1, \master_label +.endm + +#endif /* CONFIG_ARM64 */ + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARM_MACRO_H__ */ diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h index c412486db50..9ba9add4f7d 100644 --- a/arch/arm/include/asm/posix_types.h +++ b/arch/arm/include/asm/posix_types.h @@ -13,6 +13,8 @@ #ifndef __ARCH_ARM_POSIX_TYPES_H #define __ARCH_ARM_POSIX_TYPES_H +#include + /* * This file is generally used by user-level software, so you need to * be a little careful about namespace pollution etc. Also, we cannot @@ -28,9 +30,17 @@ typedef int __kernel_pid_t; typedef unsigned short __kernel_ipc_pid_t; typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; + +#ifdef CONFIG_ARM64 +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +#else /* CONFIG_ARM64 */ typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; +#endif /* CONFIG_ARM64 */ + typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h index a060ee67e34..21aef58b7b1 100644 --- a/arch/arm/include/asm/proc-armv/ptrace.h +++ b/arch/arm/include/asm/proc-armv/ptrace.h @@ -10,6 +10,25 @@ #ifndef __ASM_PROC_PTRACE_H #define __ASM_PROC_PTRACE_H +#ifdef CONFIG_ARM64 + +#define PCMASK 0 + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored + * on the stack during an exception. + */ +struct pt_regs { + unsigned long elr; + unsigned long regs[31]; +}; + +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_ARM64 */ + #define USR26_MODE 0x00 #define FIQ26_MODE 0x01 #define IRQ26_MODE 0x02 @@ -104,4 +123,6 @@ static inline int valid_user_regs(struct pt_regs *regs) #endif /* __ASSEMBLY__ */ +#endif /* CONFIG_ARM64 */ + #endif diff --git a/arch/arm/include/asm/proc-armv/system.h b/arch/arm/include/asm/proc-armv/system.h index cda8976b6a2..693d1f4921d 100644 --- a/arch/arm/include/asm/proc-armv/system.h +++ b/arch/arm/include/asm/proc-armv/system.h @@ -13,6 +13,60 @@ /* * Save the current interrupt enable state & disable IRQs */ +#ifdef CONFIG_ARM64 + +/* + * Save the current interrupt enable state + * and disable IRQs/FIQs + */ +#define local_irq_save(flags) \ + ({ \ + asm volatile( \ + "mrs %0, daif" \ + "msr daifset, #3" \ + : "=r" (flags) \ + : \ + : "memory"); \ + }) + +/* + * restore saved IRQ & FIQ state + */ +#define local_irq_restore(flags) \ + ({ \ + asm volatile( \ + "msr daif, %0" \ + : \ + : "r" (flags) \ + : "memory"); \ + }) + +/* + * Enable IRQs/FIQs + */ +#define local_irq_enable() \ + ({ \ + asm volatile( \ + "msr daifclr, #3" \ + : \ + : \ + : "memory"); \ + }) + +/* + * Disable IRQs/FIQs + */ +#define local_irq_disable() \ + ({ \ + asm volatile( \ + "msr daifset, #3" \ + : \ + : \ + : "memory"); \ + }) + +#else /* CONFIG_ARM64 */ + #define local_irq_save(x) \ ({ \ unsigned long temp; \ @@ -107,7 +161,10 @@ : "r" (x) \ : "memory") -#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +#endif /* CONFIG_ARM64 */ + +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) || \ + defined(CONFIG_ARM64) /* * On the StrongARM, "swp" is terminally broken since it bypasses the * cache totally. This means that the cache becomes inconsistent, and, diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 760345f847f..4178f8cf7e3 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -1,6 +1,86 @@ #ifndef __ASM_ARM_SYSTEM_H #define __ASM_ARM_SYSTEM_H +#ifdef CONFIG_ARM64 + +/* + * SCTLR_EL1/SCTLR_EL2/SCTLR_EL3 bits definitions + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_SA (1 << 3) /* Stack Alignment Check Enable */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_WXN (1 << 19) /* Write Permision Imply XN */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ + +#define PGTABLE_SIZE (0x10000) + +#ifndef __ASSEMBLY__ + +#define isb() \ + ({asm volatile( \ + "isb" : : : "memory"); \ + }) + +#define wfi() \ + ({asm volatile( \ + "wfi" : : : "memory"); \ + }) + +static inline unsigned int current_el(void) +{ + unsigned int el; + asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc"); + return el >> 2; +} + +static inline unsigned int get_sctlr(void) +{ + unsigned int el, val; + + el = current_el(); + if (el == 1) + asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc"); + else if (el == 2) + asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); + else + asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc"); + + return val; +} + +static inline void set_sctlr(unsigned int val) +{ + unsigned int el; + + el = current_el(); + if (el == 1) + asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc"); + else if (el == 2) + asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc"); + else + asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc"); + + asm volatile("isb"); +} + +void __asm_flush_dcache_all(void); +void __asm_flush_dcache_range(u64 start, u64 end); +void __asm_invalidate_tlb_all(void); +void __asm_invalidate_icache_all(void); + +void armv8_switch_to_el2(void); +void armv8_switch_to_el1(void); +void gic_init(void); +void gic_send_sgi(unsigned long sgino); +void wait_for_wakeup(void); +void smp_kick_all_cpus(void); + +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_ARM64 */ + #ifdef __KERNEL__ #define CPU_ARCH_UNKNOWN 0 @@ -45,6 +125,8 @@ #define CR_AFE (1 << 29) /* Access flag enable */ #define CR_TE (1 << 30) /* Thumb exception enable */ +#define PGTABLE_SIZE (4096 * 4) + /* * This is used to ensure the compiler did actually allocate the register we * asked it for some inline assembly sequences. Apparently we can't trust @@ -132,4 +214,6 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop); #endif /* __KERNEL__ */ +#endif /* CONFIG_ARM64 */ + #endif diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h index 71dc049da62..2326420a7f7 100644 --- a/arch/arm/include/asm/types.h +++ b/arch/arm/include/asm/types.h @@ -39,7 +39,11 @@ typedef unsigned int u32; typedef signed long long s64; typedef unsigned long long u64; +#ifdef CONFIG_ARM64 +#define BITS_PER_LONG 64 +#else /* CONFIG_ARM64 */ #define BITS_PER_LONG 32 +#endif /* CONFIG_ARM64 */ /* Dma addresses are 32-bits wide. */ diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h index 2b5fce86ab6..cb81232b832 100644 --- a/arch/arm/include/asm/u-boot.h +++ b/arch/arm/include/asm/u-boot.h @@ -44,6 +44,10 @@ typedef struct bd_info { #endif /* !CONFIG_SYS_GENERIC_BOARD */ /* For image.h:image_check_target_arch() */ +#ifndef CONFIG_ARM64 #define IH_ARCH_DEFAULT IH_ARCH_ARM +#else +#define IH_ARCH_DEFAULT IH_ARCH_ARM64 +#endif #endif /* _U_BOOT_H_ */ diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h index 44593a89490..0a228fb8eea 100644 --- a/arch/arm/include/asm/unaligned.h +++ b/arch/arm/include/asm/unaligned.h @@ -8,7 +8,7 @@ /* * Select endianness */ -#ifndef __ARMEB__ +#if __BYTE_ORDER == __LITTLE_ENDIAN #define get_unaligned __get_unaligned_le #define put_unaligned __put_unaligned_le #else diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 679f19a233d..321997c332c 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -17,14 +17,22 @@ lib-y += _umodsi3.o lib-y += div0.o endif -obj-y += crt0.o +ifdef CONFIG_ARM64 +obj-y += crt0_64.o +else +obj-y += crt0.o +endif ifndef CONFIG_SPL_BUILD -obj-y += relocate.o +ifdef CONFIG_ARM64 +obj-y += relocate_64.o +else +obj-y += relocate.o +endif ifndef CONFIG_SYS_GENERIC_BOARD obj-y += board.o endif -obj-y += sections.o +obj-y += sections.o obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTM) += bootm.o @@ -35,11 +43,17 @@ else obj-$(CONFIG_SPL_FRAMEWORK) += spl.o endif +ifdef CONFIG_ARM64 +obj-y += interrupts_64.o +else obj-y += interrupts.o +endif obj-y += reset.o obj-y += cache.o +ifndef CONFIG_ARM64 obj-y += cache-cp15.o +endif # For EABI conformant tool chains, provide eabi_compat() ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 9c72a5353fe..b770e25d87b 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -344,7 +344,7 @@ void board_init_f(ulong bootflag) #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) /* reserve TLB table */ - gd->arch.tlb_size = 4096 * 4; + gd->arch.tlb_size = PGTABLE_SIZE; addr -= gd->arch.tlb_size; /* round down to next 64 kB limit */ @@ -419,6 +419,7 @@ void board_init_f(ulong bootflag) } #endif +#ifndef CONFIG_ARM64 /* setup stackpointer for exeptions */ gd->irq_sp = addr_sp; #ifdef CONFIG_USE_IRQ @@ -431,6 +432,10 @@ void board_init_f(ulong bootflag) /* 8-byte alignment for ABI compliance */ addr_sp &= ~0x07; +#else /* CONFIG_ARM64 */ + /* 16-byte alignment for ABI compliance */ + addr_sp &= ~0x0f; +#endif /* CONFIG_ARM64 */ #else addr_sp += 128; /* leave 32 words for abort-stack */ gd->irq_sp = addr_sp; diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index f476a897022..77f1a5c9736 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -196,6 +196,14 @@ static void do_nonsec_virt_switch(void) debug("entered non-secure state\n"); #endif #endif + +#ifdef CONFIG_ARM64 + smp_kick_all_cpus(); + armv8_switch_to_el2(); +#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + armv8_switch_to_el1(); +#endif +#endif } /* Subcommand: PREP */ @@ -240,6 +248,21 @@ static void boot_prep_linux(bootm_headers_t *images) /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { +#ifdef CONFIG_ARM64 + void (*kernel_entry)(void *fdt_addr); + int fake = (flag & BOOTM_STATE_OS_FAKE_GO); + + kernel_entry = (void (*)(void *fdt_addr))images->ep; + + debug("## Transferring control to Linux (at address %lx)...\n", + (ulong) kernel_entry); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + announce_and_cleanup(fake); + + if (!fake) + kernel_entry(images->ft_addr); +#else unsigned long machid = gd->bd->bi_arch_number; char *s; void (*kernel_entry)(int zero, int arch, uint params); @@ -266,6 +289,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) kernel_entry(0, machid, r2); +#endif } /* Main Entry point for arm bootm implementation diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S new file mode 100644 index 00000000000..77563967e51 --- /dev/null +++ b/arch/arm/lib/crt0_64.S @@ -0,0 +1,113 @@ +/* + * crt0 - C-runtime startup Code for AArch64 U-Boot + * + * (C) Copyright 2013 + * David Feng + * + * (C) Copyright 2012 + * Albert ARIBAUD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* + * This file handles the target-independent stages of the U-Boot + * start-up where a C runtime environment is needed. Its entry point + * is _main and is branched into from the target's start.S file. + * + * _main execution sequence is: + * + * 1. Set up initial environment for calling board_init_f(). + * This environment only provides a stack and a place to store + * the GD ('global data') structure, both located in some readily + * available RAM (SRAM, locked cache...). In this context, VARIABLE + * global data, initialized or not (BSS), are UNAVAILABLE; only + * CONSTANT initialized data are available. + * + * 2. Call board_init_f(). This function prepares the hardware for + * execution from system RAM (DRAM, DDR...) As system RAM may not + * be available yet, , board_init_f() must use the current GD to + * store any data which must be passed on to later stages. These + * data include the relocation destination, the future stack, and + * the future GD location. + * + * (the following applies only to non-SPL builds) + * + * 3. Set up intermediate environment where the stack and GD are the + * ones allocated by board_init_f() in system RAM, but BSS and + * initialized non-const data are still not available. + * + * 4. Call relocate_code(). This function relocates U-Boot from its + * current location into the relocation destination computed by + * board_init_f(). + * + * 5. Set up final environment for calling board_init_r(). This + * environment has BSS (initialized to 0), initialized non-const + * data (initialized to their intended value), and stack in system + * RAM. GD has retained values set by board_init_f(). Some CPUs + * have some work left to do at this point regarding memory, so + * call c_runtime_cpu_setup. + * + * 6. Branch to board_init_r(). + */ + +ENTRY(_main) + +/* + * Set up initial C runtime environment and call board_init_f(0). + */ + ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) + sub x0, x0, #GD_SIZE /* allocate one GD above SP */ + bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ + mov x18, sp /* GD is above SP */ + mov x0, #0 + bl board_init_f + +/* + * Set up intermediate environment (new sp and gd) and call + * relocate_code(addr_moni). Trick here is that we'll return + * 'here' but relocated. + */ + ldr x0, [x18, #GD_START_ADDR_SP] /* x0 <- gd->start_addr_sp */ + bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ + ldr x18, [x18, #GD_BD] /* x18 <- gd->bd */ + sub x18, x18, #GD_SIZE /* new GD is below bd */ + + adr lr, relocation_return + ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */ + add lr, lr, x9 /* new return address after relocation */ + ldr x0, [x18, #GD_RELOCADDR] /* x0 <- gd->relocaddr */ + b relocate_code + +relocation_return: + +/* + * Set up final (full) environment + */ + bl c_runtime_cpu_setup /* still call old routine */ + +/* + * Clear BSS section + */ + ldr x0, =__bss_start /* this is auto-relocated! */ + ldr x1, =__bss_end /* this is auto-relocated! */ + mov x2, #0 +clear_loop: + str x2, [x0] + add x0, x0, #8 + cmp x0, x1 + b.lo clear_loop + + /* call board_init_r(gd_t *id, ulong dest_addr) */ + mov x0, x18 /* gd_t */ + ldr x1, [x18, #GD_RELOCADDR] /* dest_addr */ + b board_init_r /* PC relative jump */ + + /* NOTREACHED - board_init_r() does not return */ + +ENDPROC(_main) diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c new file mode 100644 index 00000000000..b4767225564 --- /dev/null +++ b/arch/arm/lib/interrupts_64.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2013 + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + + +int interrupt_init(void) +{ + return 0; +} + +void enable_interrupts(void) +{ + return; +} + +int disable_interrupts(void) +{ + return 0; +} + +void show_regs(struct pt_regs *regs) +{ + int i; + + printf("ELR: %lx\n", regs->elr); + printf("LR: %lx\n", regs->regs[30]); + for (i = 0; i < 29; i += 2) + printf("x%-2d: %016lx x%-2d: %016lx\n", + i, regs->regs[i], i+1, regs->regs[i+1]); + printf("\n"); +} + +/* + * do_bad_sync handles the impossible case in the Synchronous Abort vector. + */ +void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_bad_irq handles the impossible case in the Irq vector. + */ +void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_bad_fiq handles the impossible case in the Fiq vector. + */ +void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_bad_error handles the impossible case in the Error vector. + */ +void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_sync handles the Synchronous Abort exception. + */ +void do_sync(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_irq handles the Irq exception. + */ +void do_irq(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("\"Irq\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_fiq handles the Fiq exception. + */ +void do_fiq(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("\"Fiq\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} + +/* + * do_error handles the Error exception. + * Errors are more likely to be processor specific, + * it is defined with weak attribute and can be redefined + * in processor specific code. + */ +void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) +{ + printf("\"Error\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S new file mode 100644 index 00000000000..7fba9e27809 --- /dev/null +++ b/arch/arm/lib/relocate_64.S @@ -0,0 +1,58 @@ +/* + * relocate - common relocation function for AArch64 U-Boot + * + * (C) Copyright 2013 + * Albert ARIBAUD + * David Feng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * void relocate_code (addr_moni) + * + * This function relocates the monitor code. + * x0 holds the destination address. + */ +ENTRY(relocate_code) + /* + * Copy u-boot from flash to RAM + */ + ldr x1, =__image_copy_start /* x1 <- SRC &__image_copy_start */ + subs x9, x0, x1 /* x9 <- relocation offset */ + b.eq relocate_done /* skip relocation */ + ldr x2, =__image_copy_end /* x2 <- SRC &__image_copy_end */ + +copy_loop: + ldp x10, x11, [x1], #16 /* copy from source address [x1] */ + stp x10, x11, [x0], #16 /* copy to target address [x0] */ + cmp x1, x2 /* until source end address [x2] */ + b.lo copy_loop + + /* + * Fix .rela.dyn relocations + */ + ldr x2, =__rel_dyn_start /* x2 <- SRC &__rel_dyn_start */ + ldr x3, =__rel_dyn_end /* x3 <- SRC &__rel_dyn_end */ +fixloop: + ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */ + ldr x4, [x2], #8 /* x4 <- addend */ + and x1, x1, #0xffffffff + cmp x1, #1027 /* relative fixup? */ + bne fixnext + + /* relative fix: store addend plus offset at dest location */ + add x0, x0, x9 + add x4, x4, x9 + str x4, [x0] +fixnext: + cmp x2, x3 + b.lo fixloop + +relocate_done: + ret +ENDPROC(relocate_code) diff --git a/common/image.c b/common/image.c index b0ae58ff3e8..41453540f26 100644 --- a/common/image.c +++ b/common/image.c @@ -81,6 +81,7 @@ static const table_entry_t uimage_arch[] = { { IH_ARCH_NDS32, "nds32", "NDS32", }, { IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",}, { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, + { IH_ARCH_ARM64, "arm64", "AArch64", }, { -1, "", "", }, }; diff --git a/doc/README.arm64 b/doc/README.arm64 new file mode 100644 index 00000000000..75586dbaa70 --- /dev/null +++ b/doc/README.arm64 @@ -0,0 +1,46 @@ +U-boot for arm64 + +Summary +======= +No hardware platform of arm64 is available now. The u-boot is +simulated on Foundation Model and Fast Model for ARMv8. + +Notes +===== + +1. Currenly, u-boot run at the highest exception level processor + supported and jump to EL2 or optionally EL1 before enter OS. + +2. U-boot for arm64 is compiled with AArch64-gcc. AArch64-gcc + use rela relocation format, a tool(tools/relocate-rela) by Scott Wood + is used to encode the initial addend of rela to u-boot.bin. After running, + the u-boot will be relocated to destination again. + +3. Fdt should be placed at a 2-megabyte boundary and within the first 512 + megabytes from the start of the kernel image. So, fdt_high should be + defined specially. + Please reference linux/Documentation/arm64/booting.txt for detail. + +4. Spin-table is used to wake up secondary processors. One location + (or per processor location) is defined to hold the kernel entry point + for secondary processors. It must be ensured that the location is + accessible and zero immediately after secondary processor + enter slave_cpu branch execution in start.S. The location address + is encoded in cpu node of DTS. Linux kernel store the entry point + of secondary processors to it and send event to wakeup secondary + processors. + Please reference linux/Documentation/arm64/booting.txt for detail. + +5. Generic board is supported. + +6. CONFIG_ARM64 instead of CONFIG_ARMV8 is used to distinguish aarch64 and + aarch32 specific codes. + +Contributor +=========== + Tom Rini + Scott Wood + York Sun + Simon Glass + Sharma Bhupesh + Rob Herring diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 5d2ab569958..32a19ce3549 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -39,6 +39,20 @@ gd_t *global_data; " bctr\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11"); #elif defined(CONFIG_ARM) +#ifdef CONFIG_ARM64 +/* + * x18 holds the pointer to the global_data, x9 is a call-clobbered + * register + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" ldr x9, [x18, %0]\n" \ +" ldr x9, [x9, %1]\n" \ +" br x9\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x9"); +#else /* * r9 holds the pointer to the global_data, ip is a call-clobbered * register @@ -50,6 +64,7 @@ gd_t *global_data; " ldr ip, [r9, %0]\n" \ " ldr pc, [ip, %1]\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip"); +#endif #elif defined(CONFIG_MIPS) /* * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call- diff --git a/include/image.h b/include/image.h index ee6eb8d2464..7de2bb2f81e 100644 --- a/include/image.h +++ b/include/image.h @@ -156,6 +156,7 @@ struct lmb; #define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */ #define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */ #define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ +#define IH_ARCH_ARM64 22 /* ARM64 */ /* * Image Types -- cgit v1.3.1 From 795611e6ffb7d95c2a4529f365953bead0ccd13f Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 9 Jan 2014 15:11:27 -0500 Subject: armv8: Use __aarch64__ rather than CONFIG_ARM64 in some cases The toolchain sets __aarch64__ for both LE and BE. In the case of posix_types.h we cannot reliably use config.h as that will lead to problems. In the case of byteorder.h it's clearer to check the EB flag being set in either case instead. Cc: David Feng Signed-off-by: Tom Rini Amended by Albert ARIBAUD to actually remove the config.h include from the posix_types.h files, with permission from Tom Rini. --- arch/arm/include/asm/byteorder.h | 14 +------------- arch/arm/include/asm/posix_types.h | 8 +++----- 2 files changed, 4 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h index 71a9966301d..20cce7657e1 100644 --- a/arch/arm/include/asm/byteorder.h +++ b/arch/arm/include/asm/byteorder.h @@ -23,22 +23,10 @@ # define __SWAB_64_THRU_32__ #endif -#ifdef CONFIG_ARM64 - -#ifdef __AARCH64EB__ -#include -#else -#include -#endif - -#else /* CONFIG_ARM64 */ - -#ifdef __ARMEB__ +#if defined(__ARMEB__) || defined(__AARCH64EB__) #include #else #include #endif -#endif /* CONFIG_ARM64 */ - #endif diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h index 9ba9add4f7d..d254b95b2ab 100644 --- a/arch/arm/include/asm/posix_types.h +++ b/arch/arm/include/asm/posix_types.h @@ -13,8 +13,6 @@ #ifndef __ARCH_ARM_POSIX_TYPES_H #define __ARCH_ARM_POSIX_TYPES_H -#include - /* * This file is generally used by user-level software, so you need to * be a little careful about namespace pollution etc. Also, we cannot @@ -31,15 +29,15 @@ typedef unsigned short __kernel_ipc_pid_t; typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; -#ifdef CONFIG_ARM64 +#ifdef __aarch64__ typedef unsigned long __kernel_size_t; typedef long __kernel_ssize_t; typedef long __kernel_ptrdiff_t; -#else /* CONFIG_ARM64 */ +#else typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; -#endif /* CONFIG_ARM64 */ +#endif typedef long __kernel_time_t; typedef long __kernel_suseconds_t; -- cgit v1.3.1 From b3de92495f23db58a2643fb9328edacbf9a17f1c Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Thu, 9 Jan 2014 01:48:21 +0530 Subject: zynq: Add support to find bootmode Added support to find the bootmodes by reading slcr bootmode register. this can be helpful to autoboot the configurations w.r.t a specified bootmode. Added this functionality on board_late_init as it's not needed for normal initializtion part. Signed-off-by: Jagannadha Sutradharudu Teki --- arch/arm/cpu/armv7/zynq/slcr.c | 6 ++++++ arch/arm/include/asm/arch-zynq/sys_proto.h | 1 + board/xilinx/zynq/board.c | 25 +++++++++++++++++++++++++ doc/README.zynq | 25 +++++++++++++++++++++++-- include/configs/zynq-common.h | 1 + 5 files changed, 56 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index 717ec65aeee..b4c11c324c0 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -101,6 +101,12 @@ void zynq_slcr_devcfg_enable(void) zynq_slcr_lock(); } +u32 zynq_slcr_get_boot_mode(void) +{ + /* Get the bootmode register value */ + return readl(&slcr_base->boot_mode); +} + u32 zynq_slcr_get_idcode(void) { return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 110de909221..8f925af8a41 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -13,6 +13,7 @@ extern void zynq_slcr_cpu_reset(void); extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk); extern void zynq_slcr_devcfg_disable(void); extern void zynq_slcr_devcfg_enable(void); +extern u32 zynq_slcr_get_boot_mode(void); extern u32 zynq_slcr_get_idcode(void); extern void zynq_ddrc_init(void); diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 5119c09037e..a5b9bdef46a 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -12,6 +12,12 @@ DECLARE_GLOBAL_DATA_PTR; +/* Bootmode setting values */ +#define ZYNQ_BM_MASK 0x0F +#define ZYNQ_BM_NOR 0x02 +#define ZYNQ_BM_SD 0x05 +#define ZYNQ_BM_JTAG 0x0 + #ifdef CONFIG_FPGA Xilinx_desc fpga; @@ -59,6 +65,25 @@ int board_init(void) return 0; } +int board_late_init(void) +{ + switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) { + case ZYNQ_BM_NOR: + setenv("modeboot", "norboot"); + break; + case ZYNQ_BM_SD: + setenv("modeboot", "sdboot"); + break; + case ZYNQ_BM_JTAG: + setenv("modeboot", "jtagboot"); + break; + default: + setenv("modeboot", ""); + break; + } + + return 0; +} #ifdef CONFIG_CMD_NET int board_eth_init(bd_t *bis) diff --git a/doc/README.zynq b/doc/README.zynq index 56a74b4f1f0..ea1c8c14124 100644 --- a/doc/README.zynq +++ b/doc/README.zynq @@ -28,7 +28,27 @@ and I/O programmability. - zc770-xm012 (nor) - zc770-xm013 (dual parallel qspi, gem1) -3. Mainline status +3. Bootmode + +Zynq has a facility to read the bootmode from the slcr bootmode register +once user is setting through jumpers on the board - see page no:1546 on [5] + +All possible bootmode values are defined in Table 6-2:Boot_Mode MIO Pins +on [5]. + +board_late_init() will read the bootmode values using slcr bootmode register +at runtime and assign the modeboot variable to specific bootmode string which +is intern used in autoboot. + +SLCR bootmode register Bit[3:0] values +#define ZYNQ_BM_NOR 0x02 +#define ZYNQ_BM_SD 0x05 +#define ZYNQ_BM_JTAG 0x0 + +"modeboot" variable can assign any of "norboot", "sdboot" or "jtagboot" +bootmode strings at runtime. + +4. Mainline status - Added basic board configurations support. - Added zynq u-boot bsp code - arch/arm/cpu/armv7/zynq @@ -41,7 +61,7 @@ and I/O programmability. spi- drivers/spi/zynq_spi.c i2c - drivers/i2c/zynq_i2c.c -4. TODO +5. TODO - Add zynq boards support - zc70x, zed, microzed, zc770 - Add zynq qspi controller driver @@ -54,6 +74,7 @@ and I/O programmability. [2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm [3] http://zedboard.org/product/zedboard [4] http://zedboard.org/product/microzed +[5] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf -- Jagannadha Sutradharudu Teki diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index db47c421740..b1fa0cb8ea8 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -140,6 +140,7 @@ #define CONFIG_CMDLINE_EDITING #define CONFIG_AUTO_COMPLETE +#define CONFIG_BOARD_LATE_INIT #define CONFIG_SYS_LONGHELP #define CONFIG_SYS_MAXARGS 15 /* max number of command args */ #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ -- cgit v1.3.1 From f8f36c5dda67c53c471d1fe65215b9124ef62d71 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Thu, 9 Jan 2014 01:48:26 +0530 Subject: dts: zynq: Add basic fdt support This patch provides a basic fdt support for zynq u-boot. zynq-7000.dtsi-> initial arch dts file zynq-zed.dts -> initial zed board dts file more devices should be added in subsequent patches. u-boot build: once configuring of a board done for building dtb with zynq-zed.dts as an input zynq-uboot> make DEVICE_TREE=zynq-zed Enabled CONFIG_OF_SEPARATE for building dtb separately. There is a new binary called u-boot-dtb.bin which is a u-boot with devicetree supported. Signed-off-by: Jagannadha Sutradharudu Teki --- arch/arm/dts/zynq-7000.dtsi | 13 +++++++++++++ board/xilinx/dts/zynq-zed.dts | 14 ++++++++++++++ include/configs/zynq-common.h | 5 +++++ 3 files changed, 32 insertions(+) create mode 100644 arch/arm/dts/zynq-7000.dtsi create mode 100644 board/xilinx/dts/zynq-zed.dts (limited to 'arch') diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi new file mode 100644 index 00000000000..f20b8bd604d --- /dev/null +++ b/arch/arm/dts/zynq-7000.dtsi @@ -0,0 +1,13 @@ +/* + * Xilinx Zynq 7000 DTSI + * Describes the hardware common to all Zynq 7000-based boards. + * + * Copyright (C) 2013 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/include/ "skeleton.dtsi" + +/ { + compatible = "xlnx,zynq-7000"; +}; diff --git a/board/xilinx/dts/zynq-zed.dts b/board/xilinx/dts/zynq-zed.dts new file mode 100644 index 00000000000..91a5deba4a9 --- /dev/null +++ b/board/xilinx/dts/zynq-zed.dts @@ -0,0 +1,14 @@ +/* + * Xilinx ZED board DTS + * + * Copyright (C) 2013 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq ZED Board"; + compatible = "xlnx,zynq-zed", "xlnx,zynq-7000"; +}; diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 184d4ba820b..8707bc00c01 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -212,6 +212,11 @@ #define CONFIG_FIT #define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ +/* FDT support */ +#define CONFIG_OF_CONTROL +#define CONFIG_OF_SEPARATE +#define CONFIG_DISPLAY_BOARDINFO_LATE + /* Boot FreeBSD/vxWorks from an ELF image */ #if defined(CONFIG_ZYNQ_BOOT_FREEBSD) # define CONFIG_API -- cgit v1.3.1 From 84515165da1dd21171b7d6042f07b2af210849b5 Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki Date: Thu, 9 Jan 2014 01:48:27 +0530 Subject: gpio: zynq: Add dummy gpio routines GPIO dummy routines are required for fdt build, may be removed these dependencies once the u-boot fdt is fully optimized. Signed-off-by: Jagannadha Sutradharudu Teki --- arch/arm/include/asm/arch-zynq/gpio.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 arch/arm/include/asm/arch-zynq/gpio.h (limited to 'arch') diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h new file mode 100644 index 00000000000..2dbba756d73 --- /dev/null +++ b/arch/arm/include/asm/arch-zynq/gpio.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ZYNQ_GPIO_H +#define _ZYNQ_GPIO_H + +inline int gpio_get_value(unsigned gpio) +{ + return 0; +} + +inline int gpio_set_value(unsigned gpio, int val) +{ + return 0; +} + +inline int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +#endif /* _ZYNQ_GPIO_H */ -- cgit v1.3.1 From 67decc71ed887d91fd17a1731533ff7a277e6fb5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 26 Dec 2013 00:46:49 +0100 Subject: ARM: pxa: Fix OneNAND SPL builds The OneNAND SPL used on PXA is slightly obscure. Due to the OneNAND limitation, where we have only the first 1KiB of the OneNAND available upon power-up as a memory-mapped area, from which the CPU starts executing, we place only the most essential code into this first 1KiB . This code copies the rest of the SPL into SRAM and jumps to it. This code is stored in section .text.0 . The rest of the SPL is stored in section .text.1 . When running the OBJCOPY on the SPL, it will preserve only .text section, but the .text.0 and .text.1 are stripped away from the result, thus making the SPL binary empty. The patch adds additional -j parameters to the OBJCOPY for PXA during the SPL build, which will preserve the .text.0 and .text.1 sections. Moreover, this patch also adds missing functions into the .text.0 section, since otherwise the PXA270 with 1KiB-window OneNAND won't be able to boot. Signed-off-by: Marek Vasut Cc: Albert Aribaud Cc: Tom Rini --- arch/arm/cpu/pxa/config.mk | 13 +++++++++++++ board/vpac270/u-boot-spl.lds | 1 + 2 files changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/arm/cpu/pxa/config.mk b/arch/arm/cpu/pxa/config.mk index d8d263d404d..f2befbe5155 100644 --- a/arch/arm/cpu/pxa/config.mk +++ b/arch/arm/cpu/pxa/config.mk @@ -14,3 +14,16 @@ PLATFORM_CPPFLAGS += -mcpu=xscale # ======================================================================== PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT) + +# +# !WARNING! +# The PXA's OneNAND SPL uses .text.0 and .text.1 segments to allow booting from +# really small OneNAND memories where the mmap'd window is only 1KiB big. The +# .text.0 contains only the bare minimum needed to load the real SPL into SRAM. +# Add .text.0 and .text.1 into OBJFLAGS, so when the SPL is being objcopy'd, +# they are not discarded. +# + +#ifdef CONFIG_SPL_BUILD +OBJCFLAGS += -j .text.0 -j .text.1 +#endif diff --git a/board/vpac270/u-boot-spl.lds b/board/vpac270/u-boot-spl.lds index 02d107c4b9b..b6fdde4d1b0 100644 --- a/board/vpac270/u-boot-spl.lds +++ b/board/vpac270/u-boot-spl.lds @@ -20,6 +20,7 @@ SECTIONS .text.0 : { arch/arm/cpu/pxa/start.o (.text*) + arch/arm/lib/built-in.o (.text*) board/vpac270/built-in.o (.text*) drivers/mtd/onenand/built-in.o (.text*) } -- cgit v1.3.1 From b02bfc4dfcef3be8276521e1933573e97a5cf203 Mon Sep 17 00:00:00 2001 From: Albert ARIBAUD Date: Mon, 13 Jan 2014 14:57:05 +0100 Subject: arm: put .hash, .got.plt and .machine_param back in binaries Some targets will build fine but not boot if sections .hash and .got.plt are not present in the binary. Add them back. Also, Exynos machines require .machine_param section in SPL. Add it. Signed-off-by: Albert ARIBAUD Tested-by: Rajeshwari S Shinde --- arch/arm/config.mk | 2 +- arch/arm/cpu/armv7/exynos/config.mk | 7 +++++++ arch/arm/cpu/u-boot.lds | 3 +-- spl/Makefile | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/exynos/config.mk (limited to 'arch') diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 329c7a7f01d..cfa42094ca7 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -109,5 +109,5 @@ endif ifdef CONFIG_ARM64 OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn else -OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rel.dyn +OBJCFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn endif diff --git a/arch/arm/cpu/armv7/exynos/config.mk b/arch/arm/cpu/armv7/exynos/config.mk new file mode 100644 index 00000000000..ee0d2dab7b8 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/config.mk @@ -0,0 +1,7 @@ +# +# Copyright (C) Albert ARIBAUD +# +# SPDX-License-Identifier: GPL-2.0+ +# + +SPL_OBJCFLAGS += -j .machine_param diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 9463a33dcb3..4da5d246e0e 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -92,8 +92,6 @@ SECTIONS } .dynsym _end : { *(.dynsym) } - .hash : { *(.hash) } - .got.plt : { *(.got.plt) } .dynbss : { *(.dynbss) } .dynstr : { *(.dynstr*) } .dynamic : { *(.dynamic*) } @@ -101,4 +99,5 @@ SECTIONS .interp : { *(.interp*) } .gnu : { *(.gnu*) } .ARM.exidx : { *(.ARM.exidx*) } + .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) } } diff --git a/spl/Makefile b/spl/Makefile index 003956ebb34..5e5472d97ce 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -165,7 +165,7 @@ $(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin endif $(obj)$(SPL_BIN).bin: $(obj)$(SPL_BIN) - $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ + $(OBJCOPY) $(OBJCFLAGS) $(SPL_OBJCFLAGS) -O binary $< $@ GEN_UBOOT = \ cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $(__START) \ -- cgit v1.3.1 From 6ba2bc8fa9be4bd09ec43e39cb8e666480ef010c Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Wed, 27 Nov 2013 16:09:29 +0100 Subject: arm: use canonical sub mnemonic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building some arm boards with older binutils may produce errors like this: ---8<--- crt0.S: Assembler messages: crt0.S:70: Error: register expected, not '#(184)' -- `sub sp,#(184)' --->8--- Use canonical version of the subtract mnemonic to avoid those issues. Reported-by: Alexey Smishlayev Signed-off-by: Andreas Bießmann --- arch/arm/cpu/armv7/lowlevel_init.S | 2 +- arch/arm/lib/crt0.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv7/lowlevel_init.S b/arch/arm/cpu/armv7/lowlevel_init.S index 69e3053a426..f1aea05c909 100644 --- a/arch/arm/cpu/armv7/lowlevel_init.S +++ b/arch/arm/cpu/armv7/lowlevel_init.S @@ -24,7 +24,7 @@ ENTRY(lowlevel_init) #ifdef CONFIG_SPL_BUILD ldr r9, =gdata #else - sub sp, #GD_SIZE + sub sp, sp, #GD_SIZE bic sp, sp, #7 mov r9, sp #endif diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index ac54b9359ae..dfc2de9a618 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -67,7 +67,7 @@ ENTRY(_main) ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ - sub sp, #GD_SIZE /* allocate one GD above SP */ + sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ mov r0, #0 -- cgit v1.3.1 From 82852762ced9e08db3062394020f87bf0b1812b8 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 10:14:26 +0900 Subject: arm: rmobile: Add SH QSPI base register address This adds base register address of SH QSPI. Currently, SH QSPI is used only from R8A7790 and R8A7791. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- arch/arm/include/asm/arch-rmobile/r8a7790.h | 1 + arch/arm/include/asm/arch-rmobile/r8a7791.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/include/asm/arch-rmobile/r8a7790.h b/arch/arm/include/asm/arch-rmobile/r8a7790.h index 42d65d356da..d9ea71fa14f 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7790.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7790.h @@ -19,6 +19,7 @@ #define DBSC3_1_BASE 0xE67A0000 #define TMU_BASE 0xE61E0000 #define GPIO5_BASE 0xE6055000 +#define SH_QSPI_BASE 0xE6B10000 #define S3C_BASE 0xE6784000 #define S3C_INT_BASE 0xE6784A00 diff --git a/arch/arm/include/asm/arch-rmobile/r8a7791.h b/arch/arm/include/asm/arch-rmobile/r8a7791.h index 2afda0a62f7..ff301805914 100644 --- a/arch/arm/include/asm/arch-rmobile/r8a7791.h +++ b/arch/arm/include/asm/arch-rmobile/r8a7791.h @@ -19,6 +19,7 @@ #define DBSC3_1_BASE 0xE67A0000 #define TMU_BASE 0xE61E0000 #define GPIO5_BASE 0xE6055000 +#define SH_QSPI_BASE 0xE6B10000 #define S3C_BASE 0xE6784000 #define S3C_INT_BASE 0xE6784A00 -- cgit v1.3.1