From 47a602eab43fc2a3ce402efd5e7baee3a8a3fffb Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:49 +0200 Subject: [PATCH 01/10] board_r: ARM[64] do not set gd again For ARM / ARM64 the relocation routines already updated gd to the new value. Don't set it again. This allows compilation with clang as it cannot update gd directly. cc: Albert ARIBAUD Signed-off-by: Jeroen Hofstee --- common/board_r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/board_r.c b/common/board_r.c index f9647e1358..551429c843 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -912,7 +912,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) int i; #endif -#ifndef CONFIG_X86 +#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) gd = new_gd; #endif From f0c3a6c4ad09210d5d4aeafe87685ee75e5683d6 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:50 +0200 Subject: [PATCH 02/10] ARM: SPL: do not set gd again Just before calling board_init_f, crt0.S has already reserved space for the initial gd on the stack. There should be no need to allocate it again. cc: Albert ARIBAUD Signed-off-by: Jeroen Hofstee --- arch/arm/lib/spl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c index dfcc596815..75ab546923 100644 --- a/arch/arm/lib/spl.c +++ b/arch/arm/lib/spl.c @@ -28,9 +28,6 @@ void __weak board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* Set global data pointer. */ - gd = &gdata; - board_init_r(NULL, 0); } From 1401d87b444bf114528e997db552d22142918d33 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:51 +0200 Subject: [PATCH 03/10] cc-option: also detect unsupported warnings options By default clang will echo a warning if a warning option is unknown. Turning warnings into errors when polling for options also catches such cases and prevents passing arguments to the compiler which cause warnings. cc: Masahiro Yamada cc: Tom Rini Signed-off-by: Jeroen Hofstee --- scripts/Kbuild.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index c664e39be6..4c333599c1 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -113,12 +113,12 @@ as-instr = $(call try-run,\ # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) cc-option = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) # cc-option-align # Prefix align with either -falign or -malign From c65a2abb6c0a9ab1c70f5241716066c9480ce96a Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:52 +0200 Subject: [PATCH 04/10] ARM: make gd a function for clang "clang does not support global register variables; this is unlikely to be implemented soon because it requires additional LLVM backend support" [1] Workaround it by obtaining the value of gd/r9 by an inline asm routine. Note there is no set routine added for ARM at the moment, since most if not all updates of gd from c are actually not needed for ARM. [1] http://clang.llvm.org/docs/UsersManual.html cc: Albert ARIBAUD Signed-off-by: Jeroen Hofstee --- arch/arm/include/asm/global_data.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 63e4ad5a67..c69d0646f5 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -44,10 +44,35 @@ struct arch_global_data { #include +#ifdef __clang__ + +#define DECLARE_GLOBAL_DATA_PTR +#define gd get_gd() + +static inline gd_t *get_gd(void) +{ + gd_t *gd_ptr; + +#ifdef CONFIG_ARM64 + /* + * Make will already error that reserving x18 is not supported at the + * time of writing, clang: error: unknown argument: '-ffixed-x18' + */ + __asm__ volatile("mov %0, x18\n" : "=r" (gd_ptr)); +#else + __asm__ volatile("mov %0, r9\n" : "=r" (gd_ptr)); +#endif + + return gd_ptr; +} + +#else + #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 #endif /* __ASM_GBL_DATA_H */ From f2cbb037a73bd91e99bbb2717e532a88929b2e12 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:53 +0200 Subject: [PATCH 05/10] eabi_compat: add __aeabi_memcpy __aeabi_memset cc: Albert ARIBAUD Signed-off-by: Jeroen Hofstee --- arch/arm/lib/eabi_compat.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/lib/eabi_compat.c b/arch/arm/lib/eabi_compat.c index 10d19333fc..a2cb06e49a 100644 --- a/arch/arm/lib/eabi_compat.c +++ b/arch/arm/lib/eabi_compat.c @@ -20,8 +20,19 @@ int raise (int signum) /* Dummy function to avoid linker complaints */ void __aeabi_unwind_cpp_pr0(void) { -}; +} void __aeabi_unwind_cpp_pr1(void) { -}; +} + +/* Copy memory like memcpy, but no return value required. */ +void __aeabi_memcpy(void *dest, const void *src, size_t n) +{ + (void) memcpy(dest, src, n); +} + +void __aeabi_memset(void *dest, size_t n, int c) +{ + (void) memset(dest, c, n); +} From fe5d1abcf47b2419f69d722deea902c0d44842e7 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 30 Jul 2014 21:54:54 +0200 Subject: [PATCH 06/10] clang: workaround for generated constants KBuild abuses the asm statement to write to a file and clang chokes about these invalid asm statements. Hack it even more by fooling this is actual valid asm code. cc: Masahiro Yamada cc: Tom Rini Signed-off-by: Jeroen Hofstee --- Kbuild | 3 ++- include/linux/kbuild.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Kbuild b/Kbuild index 6e1698c5bf..ef97787bf4 100644 --- a/Kbuild +++ b/Kbuild @@ -53,7 +53,8 @@ targets += arch/$(ARCH)/lib/asm-offsets.s # Default sed regexp - multiline due to syntax constraints define sed-y - "/^->/{s:->#\(.*\):/* \1 */:; \ + "s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:; \ + /^->/{s:->#\(.*\):/* \1 */:; \ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:->::; p;}" diff --git a/include/linux/kbuild.h b/include/linux/kbuild.h index ab7805a3b4..8a9f645e42 100644 --- a/include/linux/kbuild.h +++ b/include/linux/kbuild.h @@ -7,14 +7,14 @@ #define __LINUX_KBUILD_H #define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + asm volatile("\n.ascii \"->" #sym " %0 " #val "\"" : : "i" (val)) -#define BLANK() asm volatile("\n->" : : ) +#define BLANK() asm volatile("\n.ascii \"->\"" : : ) #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)) #define COMMENT(x) \ - asm volatile("\n->#" x) + asm volatile("\n.ascii \"->#" x "\"") #endif From b477fe44ee0c4b5338b9eebca5eeca1040e45610 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 10 Sep 2014 20:08:51 +0200 Subject: [PATCH 07/10] Makefile: default to cc for host compiler Since the host compiler might not be gcc but e.g. clang default to cc/c++ to invoke it. cc: Masahiro Yamada cc: Tom Rini Signed-off-by: Jeroen Hofstee --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fdda3ec053..42263e4de2 100644 --- a/Makefile +++ b/Makefile @@ -197,8 +197,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ else echo sh; fi ; fi) -HOSTCC = gcc -HOSTCXX = g++ +HOSTCC = cc +HOSTCXX = c++ HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer HOSTCXXFLAGS = -O2 From 5bfdcebf73f843b4a0968e87cff9ad6546358c8d Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 10 Sep 2014 20:08:52 +0200 Subject: [PATCH 08/10] README.clang: build command with clang Cc: Albert ARIBAUD Signed-off-by: Jeroen Hofstee --- doc/README.clang | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/README.clang diff --git a/doc/README.clang b/doc/README.clang new file mode 100644 index 0000000000..9ad689f071 --- /dev/null +++ b/doc/README.clang @@ -0,0 +1,56 @@ +The biggest problem when trying to compile U-boot with clang is that +almost all archs rely on storing gd in a global register and clang user +manual states: "clang does not support global register variables; this +is unlikely to be implemented soon because it requires additional LLVM +backend support." + +Since version 3.4 the ARM backend can be instructed to leave r9 alone. +Global registers themselves are not supported so some inline assembly is +used to get its value. This does lead to larger code then strictly +necessary, but at least works. + +NOTE: target compilation only work for _some_ ARM boards at the moment. +Also Aarch64 is not supported: Most notably boards which aren't using +the generic board will fail to compile, but since those are expected +to be converted this will solve itself. Boards which reassign gd in c +will also fail to compile, but there is in no strict reason to do so +in the ARM world, since crt0.S takes care of this. These assignments +can be avoided by changing the init calls but this is not in mainline yet. + +NOTE: without the -mllvm -arm-use-movt=0 flags u-boot will compile +fine, but llvm might hardcode addresses in movw / movt pairs, which +cannot be relocated and u-boot will fail at runtime. + +Debian (based) +-------------- +Binary packages can be installed as usual, e.g.: +sudo apt-get install clang + +To compile U-Boot with clang on linux without IAS use e.g.: +export TRIPLET=arm-linux-gnueabi && export CROSS_COMPILE="$TRIPLET-" +make HOSTCC=clang CC="clang -target $TRIPLET -mllvm -arm-use-movt=0 -no-integrated-as" rpi_b_defconfig +make HOSTCC=clang CC="clang -target $TRIPLET -mllvm -arm-use-movt=0 -no-integrated-as" all V=1 -j8 + +FreeBSD 11 (Current): +-------------------- +Since llvm 3.4 is currently in the base system, the integrated as is +incapable of building U-Boot. Therefore gas from devel/arm-eabi-binutils +is used instead. It needs a symlinks to be picked up correctly though: + +ln -s /usr/local/bin/arm-eabi-as /usr/bin/arm-freebsd-eabi-as + +# The following commands compile U-Boot using the clang xdev toolchain. +# NOTE: CROSS_COMPILE and target differ on purpose! +export CROSS_COMPILE=arm-eabi- +gmake CC="clang -target arm-freebsd-eabi --sysroot /usr/arm-freebsd -no-integrated-as -mllvm -arm-use-movt=0" rpi_b_defconfig +gmake CC="clang -target arm-freebsd-eabi --sysroot /usr/arm-freebsd -no-integrated-as -mllvm -arm-use-movt=0" -j8 + +Given that u-boot will default to gcc, above commands can be +simplified with a simple wrapper script, listed below. + +/usr/local/bin/arm-eabi-gcc +--- +#!/bin/sh + +exec clang -target arm-freebsd-eabi --sysroot /usr/arm-freebsd -no-integrated-as -mllvm -arm-use-movt=0 "$@" + From 58f9e1ae6391a1fbb7ca024ae45e288aabb88807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 3 Sep 2014 23:32:33 +0200 Subject: [PATCH 09/10] arm: Make reset position-independent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some boards, like mx31pdk and tx25, require the beginning of the SPL code to be position-independent. For these two boards, this is because they use the i.MX external NAND boot, which starts by executing the first NAND Flash page from the NFC page buffer. The SPL then needs to copy itself to its actual link address in order to free the NFC page buffer and use it to load the non-SPL image from Flash before running it. This means that the SPL runtime address differs from its link address between the reset and the initial copy performed by board_init_f(), so this part of the SPL binary must be position-independent. This requirement was broken by commit 41623c9 'arm: move exception handling out of start.S files', which used an absolute address to branch to the reset routine. This new commit restores the original behavior, which just performed a relative branch. This fixes the boot of mx31pdk and tx25. Signed-off-by: Benoît Thébaudeau Reported-by: Helmut Raiger Cc: Albert Aribaud Cc: Magnus Lilja Cc: John Rigby Tested-by: Magnus Lilja --- arch/arm/lib/vectors.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S index 493f3373f3..843b18f920 100644 --- a/arch/arm/lib/vectors.S +++ b/arch/arm/lib/vectors.S @@ -50,7 +50,7 @@ #endif _start: - ldr pc, _reset + b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort @@ -77,7 +77,6 @@ _start: .globl _irq .globl _fiq -_reset: .word reset _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort From a7f99bf139b3aaa0d5494693fd0395084355e41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 3 Sep 2014 23:32:34 +0200 Subject: [PATCH 10/10] arm: Fix _start for CONFIG_SYS_DV_NOR_BOOT_CFG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The boards using CONFIG_SYS_DV_NOR_BOOT_CFG (i.e. calimain, da850evm_direct_nor and enbw_cmc) had the _start symbol defined after the CONFIG_SYS_DV_NOR_BOOT_CFG word rather than before it in arch/arm/lib/vectors.S. Because of that, if by lack of luck 'gd->mon_len = (ulong)&__bss_end - (ulong)_start' (see setup_mon_len()) was a multiple of 4 kiB (see reserve_uboot()), then the last BSS word overlapped the first word of the following reserved RAM area (or went beyond the top of RAM without such an area) after relocation because __image_copy_start did not match _start (see relocate_code()). This was broken by commit 41623c9 'arm: move exception handling out of start.S files', which defined _start twice (before and after the CONFIG_SYS_DV_NOR_BOOT_CFG word), then by commit 0a26e1d 'arm: fix a double-definition error of _start symbol', which kept the definition of the _start symbol after the CONFIG_SYS_DV_NOR_BOOT_CFG word. This new commit fixes this issue by restoring the original behavior, i.e. by defining the _start symbol before the CONFIG_SYS_DV_NOR_BOOT_CFG word. Signed-off-by: Benoît Thébaudeau Cc: Albert Aribaud Cc: Manfred Rudigier Cc: Christian Riesch Cc: Sudhakar Rajashekhara Cc: Heiko Schocher --- arch/arm/lib/vectors.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S index 843b18f920..0cb87cee7f 100644 --- a/arch/arm/lib/vectors.S +++ b/arch/arm/lib/vectors.S @@ -45,11 +45,12 @@ ************************************************************************* */ +_start: + #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG .word CONFIG_SYS_DV_NOR_BOOT_CFG #endif -_start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt