From mboxrd@z Thu Jan 1 00:00:00 1970 From: Albert ARIBAUD Date: Mon, 6 Jul 2015 13:48:25 +0200 Subject: [U-Boot] [PATCH v4 2/4] arm: support Thumb-1 with CONFIG_SYS_THUMB_BUILD In-Reply-To: <1436109227-10790-3-git-send-email-albert.u.boot@aribaud.net> References: <1436109227-10790-1-git-send-email-albert.u.boot@aribaud.net> <1436109227-10790-3-git-send-email-albert.u.boot@aribaud.net> Message-ID: <20150706134825.3f14fa79@lilith> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Sun, 5 Jul 2015 17:13:45 +0200, Albert ARIBAUD wrote: > When building a Thumb-1-only target with CONFIG_SYS_THUMB_BUILD, > some files fail to build, most of the time because they include > mcr instructions, which only exist for Thumb-2. > > Thos patch introduces a Kconfig option CONFIG_THUMB2 and uses > it to select between Thumb-2 and ARM mode for the aforementioned > files. > > Signed-off-by: Albert ARIBAUD > --- > This patch has been build-tested and run-tested on ED Mini V2, > above the "edmini: switch to SPL" patch, and found to reduce > U-Boot size by 25% and SPL size by 14%... and to run fine. :) > > This patch has also been tested against side effects on the > non-Thumb wireless_space target. The binaries produced with > and without ths patch were found to differ only by their > version string. > > Changes in v4: None > Changes in v3: > - added arch/arm/lib/mem{set,cpy}.S to the list of modules > which should always be built in ARM state. > - Selected HAS_THUMB2 for CPU_V7M. > - Fixed invalidate_l2_cache() when building for Thumb-1. > > Changes in v2: > - fixed a typo in the commit message > - added file arch/arm/thumb1/include/asm/proc-armv/system.h, > which overrides arch/arm/include/asm/proc-armv/system.h > when building for Thumb-1 and provides non-functional but > Thumb-compilable IRQ and FIQ related macros and functions. > > Makefile | 2 + > arch/arm/Kconfig | 5 ++ > arch/arm/cpu/arm926ejs/Makefile | 11 ++++ > arch/arm/cpu/arm926ejs/cache.c | 5 ++ > arch/arm/include/asm/cache.h | 4 ++ > arch/arm/lib/Makefile | 24 +++++++++ > arch/arm/lib/cache.c | 11 ++++ > arch/arm/lib/memcpy.S | 4 +- > arch/arm/lib/memset.S | 2 +- > arch/arm/mach-orion5x/Makefile | 10 ++++ > arch/arm/thumb1/include/asm/proc-armv/system.h | 69 ++++++++++++++++++++++++++ > examples/standalone/Makefile | 10 ++++ > scripts/Makefile.lib | 3 +- > 13 files changed, 156 insertions(+), 4 deletions(-) > create mode 100644 arch/arm/thumb1/include/asm/proc-armv/system.h > > diff --git a/Makefile b/Makefile > index 37cc4c3..dc881fa 100644 > --- a/Makefile > +++ b/Makefile > @@ -606,6 +606,8 @@ KBUILD_CFLAGS += $(KCFLAGS) > UBOOTINCLUDE := \ > -Iinclude \ > $(if $(KBUILD_SRC), -I$(srctree)/include) \ > + $(if $(CONFIG_SYS_THUMB_BUILD), $(if $(CONFIG_HAS_THUMB2),, \ > + -I$(srctree)/arch/$(ARCH)/thumb1/include),) \ > -I$(srctree)/arch/$(ARCH)/include \ > -include $(srctree)/include/linux/kconfig.h > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 0829235..906afd0 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -10,6 +10,9 @@ config ARM64 > config HAS_VBAR > bool > > +config HAS_THUMB2 > + bool > + > config CPU_ARM720T > bool > > @@ -32,9 +35,11 @@ config CPU_ARM1176 > config CPU_V7 > bool > select HAS_VBAR > + select HAS_THUMB2 > > config CPU_V7M > bool > + select HAS_THUMB2 > > config CPU_PXA > bool > diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile > index 63fa159..fe78922 100644 > --- a/arch/arm/cpu/arm926ejs/Makefile > +++ b/arch/arm/cpu/arm926ejs/Makefile > @@ -20,3 +20,14 @@ obj-$(CONFIG_MX25) += mx25/ > obj-$(CONFIG_MX27) += mx27/ > obj-$(if $(filter mxs,$(SOC)),y) += mxs/ > obj-$(if $(filter spear,$(SOC)),y) += spear/ > + > +# some files can only build in ARM or THUMB2, not THUMB1 > + > +ifdef CONFIG_SYS_THUMB_BUILD > +ifndef CONFIG_HAS_THUMB2 > + > +CFLAGS_cpu.o := -marm > +CFLAGS_cache.o := -marm > + > +endif > +endif > diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c > index 8d7873c..f12e365 100644 > --- a/arch/arm/cpu/arm926ejs/cache.c > +++ b/arch/arm/cpu/arm926ejs/cache.c > @@ -99,4 +99,9 @@ void flush_cache(unsigned long start, unsigned long size) > /* > * Stub implementations for l2 cache operations > */ > + > __weak void l2_cache_disable(void) {} > + > +#if defined CONFIG_SYS_THUMB_BUILD > +__weak void invalidate_l2_cache(void) {} > +#endif > diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h > index a836e9f..1f63127 100644 > --- a/arch/arm/include/asm/cache.h > +++ b/arch/arm/include/asm/cache.h > @@ -16,6 +16,9 @@ > /* > * Invalidate L2 Cache using co-proc instruction > */ > +#ifdef CONFIG_SYS_THUMB_BUILD > +void invalidate_l2_cache(void); > +#else > static inline void invalidate_l2_cache(void) > { > unsigned int val=0; > @@ -24,6 +27,7 @@ static inline void invalidate_l2_cache(void) > : : "r" (val) : "cc"); > isb(); > } > +#endif > > void l2_cache_enable(void); > void l2_cache_disable(void); > diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile > index 9a631d1..4272d2f 100644 > --- a/arch/arm/lib/Makefile > +++ b/arch/arm/lib/Makefile > @@ -60,3 +60,27 @@ obj-$(CONFIG_DEBUG_LL) += debug.o > ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) > extra-y += eabi_compat.o > endif > + > +# some files can only build in ARM or THUMB2, not THUMB1 > + > +ifdef CONFIG_SYS_THUMB_BUILD > +ifndef CONFIG_HAS_THUMB2 > + > +# for C files, just apend -marm, which will override previous -mthumb* > + > +CFLAGS_cache.o := -marm > +CFLAGS_cache-cp15.o := -marm > + > +# For .S, drop -mthumb* and other thumb-related options. > +# CFLAGS_REMOVE_* would not have an effet, so AFLAGS_REMOVE_* > +# was implemented and is used here. > +# Also, define ${target}_NO_THUMB_BUILD for these two targets > +# so that the code knows it should not use Thumb. > + > +AFLAGS_REMOVE_memset.o := -mthumb -mthumb-interwork > +AFLAGS_REMOVE_memcpy.o := -mthumb -mthumb-interwork > +AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD > +AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD > + > +endif > +endif > diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c > index 74cfde6..7c8878d 100644 > --- a/arch/arm/lib/cache.c > +++ b/arch/arm/lib/cache.c > @@ -95,3 +95,14 @@ phys_addr_t noncached_alloc(size_t size, size_t align) > return next; > } > #endif /* CONFIG_SYS_NONCACHED_MEMORY */ > + > +#if defined(CONFIG_SYS_THUMB_BUILD) > +void invalidate_l2_cache(void) > +{ > + unsigned int val = 0; > + > + asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache" > + : : "r" (val) : "cc"); > + isb(); > +} > +#endif > diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S > index ffaee74..409d5f7 100644 > --- a/arch/arm/lib/memcpy.S > +++ b/arch/arm/lib/memcpy.S > @@ -13,7 +13,7 @@ > #include > #include > > -#ifdef CONFIG_SYS_THUMB_BUILD > +#if defined(CONFIG_SYS_THUMB_BUILD) && !defined(MEMCPY_NO_THUMB_BUILD) > #define W(instr) instr.w > #else > #define W(instr) instr > @@ -62,7 +62,7 @@ > > /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */ > .syntax unified > -#ifdef CONFIG_SYS_THUMB_BUILD > +#if defined(CONFIG_SYS_THUMB_BUILD) && !defined(MEMCPY_NO_THUMB_BUILD) > .thumb > .thumb_func > #endif > diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S > index 49bdff7..b586055 100644 > --- a/arch/arm/lib/memset.S > +++ b/arch/arm/lib/memset.S > @@ -16,7 +16,7 @@ > .align 5 > > .syntax unified > -#ifdef CONFIG_SYS_THUMB_BUILD > +#if defined(CONFIG_SYS_THUMB_BUILD) && !defined(MEMSET_NO_THUMB_BUILD) > .thumb > .thumb_func > #endif > diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile > index 546ebcb..33dcad4 100644 > --- a/arch/arm/mach-orion5x/Makefile > +++ b/arch/arm/mach-orion5x/Makefile > @@ -16,3 +16,13 @@ obj-y += timer.o > ifndef CONFIG_SKIP_LOWLEVEL_INIT > obj-y += lowlevel_init.o > endif > + > +# some files can only build in ARM or THUMB2, not THUMB1 > + > +ifdef CONFIG_SYS_THUMB_BUILD > +ifndef CONFIG_HAS_THUMB2 > + > +CFLAGS_cpu.o := -marm > + > +endif > +endif > diff --git a/arch/arm/thumb1/include/asm/proc-armv/system.h b/arch/arm/thumb1/include/asm/proc-armv/system.h > new file mode 100644 > index 0000000..7dfbf3d > --- /dev/null > +++ b/arch/arm/thumb1/include/asm/proc-armv/system.h > @@ -0,0 +1,69 @@ > +/* > + * Thumb-1 drop-in for the linux/include/asm-arm/proc-armv/system.h > + * > + * (C) Copyright 2015 > + * Albert ARIBAUD > + * > + * The original file does not build in Thumb mode. However, in U-Boot > + * we don't use interrupt context, so we can redefine these as empty > + * memory barriers, which makes Thumb-1 compiler happy. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +/* > + * Use the same macro name as linux/include/asm-arm/proc-armv/system.h > + * here, so that if the original ever gets included after us, it won't > + * try to re-redefine anything. > + */ > + > +#ifndef __ASM_PROC_SYSTEM_H > +#define __ASM_PROC_SYSTEM_H > + > +/* > + * Redefine all original macros with static inline functions containing > + * a simple memory barrier, so that they produce the same instruction > + * ordering constraints as their original counterparts. > + * We use static inline functions rather than macros so that we can tell > + * the compiler to not complain about unused arguments. > + */ > + > +static inline void local_irq_save( > + unsigned long flags __attribute__((unused))) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void local_irq_enable(void) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void local_irq_disable(void) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void __stf(void) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void __clf(void) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void local_save_flags( > + unsigned long flags __attribute__((unused))) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +static inline void local_irq_restore( > + unsigned long flags __attribute__((unused))) > +{ > + __asm__ __volatile__ ("" : : : "memory"); > +} > + > +#endif /* __ASM_PROC_SYSTEM_H */ > diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile > index 0863a8c..5a6ae00 100644 > --- a/examples/standalone/Makefile > +++ b/examples/standalone/Makefile > @@ -73,3 +73,13 @@ $(obj)/%.srec: $(obj)/% FORCE > $(obj)/%.bin: OBJCOPYFLAGS := -O binary > $(obj)/%.bin: $(obj)/% FORCE > $(call if_changed,objcopy) > + > +# some files can only build in ARM or THUMB2, not THUMB1 > + > +ifdef CONFIG_SYS_THUMB_BUILD > +ifndef CONFIG_HAS_THUMB2 > + > +CFLAGS_stubs.o := -marm > + > +endif > +endif > diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib > index 8731fc6..3d5c872 100644 > --- a/scripts/Makefile.lib > +++ b/scripts/Makefile.lib > @@ -104,8 +104,9 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ > orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ > $(ccflags-y) $(CFLAGS_$(basetarget).o) > _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) > -_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ > +orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ > $(asflags-y) $(AFLAGS_$(basetarget).o) > +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) > _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) > > # > -- > 2.1.0 > Applied to u-boot-arm/master. Amicalement, -- Albert.