diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-03-06 09:39:59 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-03-06 09:39:59 +0100 |
commit | beb36c510bd6abf80a20148bf165a990c69fed8a (patch) | |
tree | 95e7a242ee9c264bc35f2aedddacae74e93d7ad9 | |
parent | e0d674735b26c279d4cb6c73c140f1e0866a7953 (diff) | |
parent | 276252a5598a9596970cc02f186c3847b932dcc1 (diff) | |
download | barebox-beb36c510bd6abf80a20148bf165a990c69fed8a.tar.gz barebox-beb36c510bd6abf80a20148bf165a990c69fed8a.tar.xz |
Merge branch 'work/thumb2' into next
-rw-r--r-- | arch/arm/Kconfig | 12 | ||||
-rw-r--r-- | arch/arm/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/eukrea_cpuimx35/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/eukrea_cpuimx51/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/freescale-mx25-3-stack/3stack.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/freescale-mx35-3-stack/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/freescale-mx51-pdk/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/freescale-mx53-loco/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/boards/freescale-mx53-smd/flash_header.c | 3 | ||||
-rw-r--r-- | arch/arm/cpu/cpu.c | 27 | ||||
-rw-r--r-- | arch/arm/cpu/exceptions.S | 1 | ||||
-rw-r--r-- | arch/arm/cpu/mmu.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/start.c | 35 | ||||
-rw-r--r-- | arch/arm/include/asm/barebox-arm-head.h | 36 | ||||
-rw-r--r-- | arch/arm/include/asm/barebox-arm.h | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/unified.h | 8 | ||||
-rw-r--r-- | arch/arm/lib/armlinux.c | 17 | ||||
-rw-r--r-- | arch/arm/lib/barebox.lds.S | 7 | ||||
-rw-r--r-- | commands/go.c | 6 | ||||
-rw-r--r-- | common/misc.c | 3 | ||||
-rw-r--r-- | include/common.h | 6 |
22 files changed, 164 insertions, 36 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67a1009777..8a4e1a2b41 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -102,6 +102,18 @@ config AEABI To use this you need GCC version 4.0.0 or later. +config THUMB2_BAREBOX + select ARM_ASM_UNIFIED + depends on CPU_V7 + bool "Compile barebox in thumb-2 mode (read help)" + help + This enables compilation of barebox in thumb-2 mode which generates + ~25% smaller binaries. Arm Assembly code needs some fixups to be able + to work correctly in thumb-2 mode. the barebox core should have these + fixups since most assembly code is derived from the Kernel. However, + your board lowlevel init code may break in thumb-2 mode. You have been + warned. + endmenu menu "Arm specific settings " diff --git a/arch/arm/Makefile b/arch/arm/Makefile index b28a5b2263..4c6a566ff2 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -39,8 +39,15 @@ ifeq ($(CONFIG_ARM_UNWIND),y) CFLAGS_ABI +=-funwind-tables endif -CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float -AFLAGS += -include asm/unified.h -msoft-float +ifeq ($(CONFIG_THUMB2_BAREBOX),y) +AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it) +AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) +CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) +AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb +endif + +CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float $(CFLAGS_THUMB2) +AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2) # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c index 73e54f2f54..695e75f288 100644 --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c @@ -46,13 +46,14 @@ #include <usb/fsl_usb2.h> #include <mach/usb.h> #include <mach/devices-imx25.h> +#include <asm/barebox-arm-head.h> extern unsigned long _stext; extern void exception_vectors(void); void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c index 93c8348209..f8ed5d483e 100644 --- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c +++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c @@ -1,12 +1,13 @@ #include <common.h> #include <mach/imx-flash-header.h> #include <mach/imx-regs.h> +#include <asm/barebox-arm-head.h> extern void exception_vectors(void); void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/eukrea_cpuimx51/flash_header.c b/arch/arm/boards/eukrea_cpuimx51/flash_header.c index f953b09bde..ac6bbdcc0f 100644 --- a/arch/arm/boards/eukrea_cpuimx51/flash_header.c +++ b/arch/arm/boards/eukrea_cpuimx51/flash_header.c @@ -1,11 +1,12 @@ #include <common.h> #include <mach/imx-flash-header.h> +#include <asm/barebox-arm-head.h> extern unsigned long _stext; void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c index 5aa54e43ff..d7e24cf3e7 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c @@ -42,13 +42,14 @@ #include <i2c/i2c.h> #include <mfd/mc34704.h> #include <mach/devices-imx25.h> +#include <asm/barebox-arm-head.h> extern unsigned long _stext; extern void exception_vectors(void); void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/freescale-mx35-3-stack/flash_header.c b/arch/arm/boards/freescale-mx35-3-stack/flash_header.c index 92f214202e..85b52a25ca 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/flash_header.c +++ b/arch/arm/boards/freescale-mx35-3-stack/flash_header.c @@ -1,12 +1,13 @@ #include <common.h> #include <mach/imx-flash-header.h> #include <mach/imx-regs.h> +#include <asm/barebox-arm-head.h> extern void exception_vectors(void); void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/freescale-mx51-pdk/flash_header.c b/arch/arm/boards/freescale-mx51-pdk/flash_header.c index 5f94506b69..297dca1c29 100644 --- a/arch/arm/boards/freescale-mx51-pdk/flash_header.c +++ b/arch/arm/boards/freescale-mx51-pdk/flash_header.c @@ -1,11 +1,12 @@ #include <common.h> #include <mach/imx-flash-header.h> +#include <asm/barebox-arm-head.h> extern unsigned long _stext; void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/freescale-mx53-loco/flash_header.c b/arch/arm/boards/freescale-mx53-loco/flash_header.c index 490e223f0e..b45964059a 100644 --- a/arch/arm/boards/freescale-mx53-loco/flash_header.c +++ b/arch/arm/boards/freescale-mx53-loco/flash_header.c @@ -16,10 +16,11 @@ #include <common.h> #include <asm/byteorder.h> #include <mach/imx-flash-header.h> +#include <asm/barebox-arm-head.h> void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/boards/freescale-mx53-smd/flash_header.c b/arch/arm/boards/freescale-mx53-smd/flash_header.c index 490e223f0e..b45964059a 100644 --- a/arch/arm/boards/freescale-mx53-smd/flash_header.c +++ b/arch/arm/boards/freescale-mx53-smd/flash_header.c @@ -16,10 +16,11 @@ #include <common.h> #include <asm/byteorder.h> #include <mach/imx-flash-header.h> +#include <asm/barebox-arm-head.h> void __naked __flash_header_start go(void) { - __asm__ __volatile__("b exception_vectors\n"); + barebox_arm_head(); } struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = { diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c index cf31e8bb2e..71ef8c06d6 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -26,6 +26,7 @@ */ #include <common.h> +#include <init.h> #include <command.h> #include <cache.h> #include <asm/mmu.h> @@ -89,3 +90,29 @@ void arch_shutdown(void) ); #endif } + +#ifdef CONFIG_THUMB2_BAREBOX +static void thumb2_execute(void *func, int argc, char *argv[]) +{ + /* + * Switch back to arm mode before executing external + * programs. + */ + __asm__ __volatile__ ( + "mov r0, #0\n" + "mov r1, %0\n" + "mov r2, %1\n" + "bx %2\n" + : + : "r" (argc - 1), "r" (&argv[1]), "r" (func) + : "r0", "r1", "r2" + ); +} + +static int execute_init(void) +{ + do_execute = thumb2_execute; + return 0; +} +postcore_initcall(execute_init); +#endif diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S index 6f35d408f4..c08537a405 100644 --- a/arch/arm/cpu/exceptions.S +++ b/arch/arm/cpu/exceptions.S @@ -106,6 +106,7 @@ _STACK_START: * exception handlers */ .section ".text","ax" + .arm .align 5 .globl undefined_instruction diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 6d9b1e0231..c19f9311cd 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -4,6 +4,7 @@ #include <errno.h> #include <sizes.h> #include <asm/memory.h> +#include <asm/barebox-arm.h> #include <asm/system.h> #include <memory.h> @@ -182,7 +183,6 @@ static void vectors_init(void) { u32 *exc, *zero = NULL; void *vectors; - extern unsigned long exception_vectors; u32 cr; cr = get_cr(); @@ -210,7 +210,7 @@ static void vectors_init(void) vectors = xmemalign(PAGE_SIZE, PAGE_SIZE); memset(vectors, 0, PAGE_SIZE); - memcpy(vectors, &exception_vectors, ARM_VECTORS_SIZE); + memcpy(vectors, __exceptions_start, __exceptions_stop - __exceptions_start); if (cr & CR_V) exc[256 - 16] = (u32)vectors | PTE_TYPE_SMALL | PTE_FLAGS_CACHED; diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index 61d7e3e5d5..ede8fd1f09 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -23,37 +23,38 @@ #include <common.h> #include <init.h> #include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> #include <asm/system.h> #include <asm-generic/memory_layout.h> #include <asm/sections.h> -void __naked __section(.text_entry) exception_vectors(void) +void __naked __section(.text_entry) start(void) +{ + barebox_arm_head(); +} + +void __naked __section(.text_exceptions) exception_vectors(void) { __asm__ __volatile__ ( + ".arm\n" "b reset\n" /* reset */ #ifdef CONFIG_ARM_EXCEPTIONS "ldr pc, =undefined_instruction\n" /* undefined instruction */ "ldr pc, =software_interrupt\n" /* software interrupt (SWI) */ "ldr pc, =prefetch_abort\n" /* prefetch abort */ "ldr pc, =data_abort\n" /* data abort */ - "1: bne 1b\n" /* (reserved) */ + "1: b 1b\n" /* (reserved) */ "ldr pc, =irq\n" /* irq (interrupt) */ "ldr pc, =fiq\n" /* fiq (fast interrupt) */ #else - "1: bne 1b\n" /* undefined instruction */ - "1: bne 1b\n" /* software interrupt (SWI) */ - "1: bne 1b\n" /* prefetch abort */ - "1: bne 1b\n" /* data abort */ - "1: bne 1b\n" /* (reserved) */ - "1: bne 1b\n" /* irq (interrupt) */ - "1: bne 1b\n" /* fiq (fast interrupt) */ + "1: b 1b\n" /* undefined instruction */ + "1: b 1b\n" /* software interrupt (SWI) */ + "1: b 1b\n" /* prefetch abort */ + "1: b 1b\n" /* data abort */ + "1: b 1b\n" /* (reserved) */ + "1: b 1b\n" /* irq (interrupt) */ + "1: b 1b\n" /* fiq (fast interrupt) */ #endif - ".word 0x65726162\n" /* 'bare' */ - ".word 0x00786f62\n" /* 'box' */ - ".word _text\n" /* text base. If copied there, - * barebox can skip relocation - */ - ".word _barebox_image_size\n" /* image size to copy */ ); } @@ -109,7 +110,7 @@ void __naked __bare_init reset(void) * Board code can jump here by either returning from board_init_lowlevel * or by calling this funtion directly. */ -void __naked __bare_init board_init_lowlevel_return(void) +void __naked __section(.text_ll_return) board_init_lowlevel_return(void) { uint32_t r, addr; @@ -124,7 +125,7 @@ void __naked __bare_init board_init_lowlevel_return(void) __asm__ __volatile__("mov sp, %0" : : "r"(r)); /* Get start of binary image */ - addr -= (uint32_t)&board_init_lowlevel_return - TEXT_BASE; + addr -= (uint32_t)&__ll_return - TEXT_BASE; /* relocate to link address if necessary */ if (addr != TEXT_BASE) diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h new file mode 100644 index 0000000000..0dc3074a27 --- /dev/null +++ b/arch/arm/include/asm/barebox-arm-head.h @@ -0,0 +1,36 @@ +#ifndef __ASM_ARM_HEAD_H +#define __ASM_ARM_HEAD_H + +static inline void barebox_arm_head(void) +{ + __asm__ __volatile__ ( +#ifdef CONFIG_THUMB2_BAREBOX + ".arm\n" + "adr r9, 1f + 1\n" + "bx r9\n" + ".thumb\n" + "1:\n" + "bl reset\n" + ".rept 10\n" + "1: b 1b\n" + ".endr\n" +#else + "b reset\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" + "1: b 1b\n" +#endif + ".word 0x65726162\n" /* 'bare' */ + ".word 0x00786f62\n" /* 'box' */ + ".word _text\n" /* text base. If copied there, + * barebox can skip relocation + */ + ".word _barebox_image_size\n" /* image size to copy */ + ); +} + +#endif /* __ASM_ARM_HEAD_H */ diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 7bb1af1606..b880dd49b3 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -36,6 +36,9 @@ int cleanup_before_linux(void); int board_init(void); int dram_init (void); +extern char __exceptions_start[], __exceptions_stop[]; +extern char __ll_return[]; + void board_init_lowlevel(void); void board_init_lowlevel_return(void); void arch_init_lowlevel(void); diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h index bc631161e9..4d855c8352 100644 --- a/arch/arm/include/asm/unified.h +++ b/arch/arm/include/asm/unified.h @@ -24,10 +24,10 @@ .syntax unified #endif -#ifdef CONFIG_THUMB2_KERNEL +#ifdef CONFIG_THUMB2_BAREBOX #if __GNUC__ < 4 -#error Thumb-2 kernel requires gcc >= 4 +#error Thumb-2 barebox requires gcc >= 4 #endif /* The CPSR bit describing the instruction set (Thumb) */ @@ -40,7 +40,7 @@ #endif #define BSYM(sym) sym + 1 -#else /* !CONFIG_THUMB2_KERNEL */ +#else /* !CONFIG_THUMB2_BAREBOX */ /* The CPSR bit describing the instruction set (ARM) */ #define PSR_ISETSTATE 0 @@ -52,7 +52,7 @@ #endif #define BSYM(sym) sym -#endif /* CONFIG_THUMB2_KERNEL */ +#endif /* CONFIG_THUMB2_BAREBOX */ #ifndef CONFIG_ARM_ASM_UNIFIED diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index 85fe2b9f66..a167036db5 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -255,6 +255,7 @@ void start_linux(void *adr, int swap, unsigned long initrd_address, { void (*kernel)(int zero, int arch, void *params) = adr; void *params = NULL; + int architecture; if (oftree) { printf("booting Linux kernel with devicetree\n"); @@ -272,5 +273,19 @@ void start_linux(void *adr, int swap, unsigned long initrd_address, __asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg)); } - kernel(0, armlinux_get_architecture(), params); + architecture = armlinux_get_architecture(); + +#ifdef CONFIG_THUMB2_BAREBOX + __asm__ __volatile__ ( + "mov r0, #0\n" + "mov r1, %0\n" + "mov r2, %1\n" + "bx %2\n" + : + : "r" (architecture), "r" (params), "r" (kernel) + : "r0", "r1", "r2" + ); +#else + kernel(0, architecture, params); +#endif } diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S index e9f62107f9..bc20694945 100644 --- a/arch/arm/lib/barebox.lds.S +++ b/arch/arm/lib/barebox.lds.S @@ -26,7 +26,7 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) -ENTRY(exception_vectors) +ENTRY(start) SECTIONS { . = TEXT_BASE; @@ -39,6 +39,8 @@ SECTIONS _stext = .; _text = .; *(.text_entry*) + __ll_return = .; + *(.text_ll_return*) #ifdef CONFIG_ARCH_EP93XX /* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */ . = 0x1000; @@ -47,6 +49,9 @@ SECTIONS __bare_init_start = .; *(.text_bare_init*) __bare_init_end = .; + __exceptions_start = .; + KEEP(*(.text_exceptions*)) + __exceptions_stop = .; *(.text*) } BAREBOX_BARE_INIT_SIZE diff --git a/commands/go.c b/commands/go.c index b97fcef32a..c821207a6f 100644 --- a/commands/go.c +++ b/commands/go.c @@ -62,7 +62,11 @@ static int do_go(int argc, char *argv[]) func = addr; shutdown_barebox(); - func(argc - 1, &argv[1]); + + if (do_execute) + do_execute(func, argc - 1, &argv[1]); + else + func(argc - 1, &argv[1]); /* * The application returned. Since we have shutdown barebox and diff --git a/common/misc.c b/common/misc.c index a0059c1b79..b31a45c1a4 100644 --- a/common/misc.c +++ b/common/misc.c @@ -125,3 +125,6 @@ void perror(const char *s) #endif } EXPORT_SYMBOL(perror); + +void (*do_execute)(void *func, int argc, char *argv[]); +EXPORT_SYMBOL(do_execute); diff --git a/include/common.h b/include/common.h index d22787542e..d2347f8629 100644 --- a/include/common.h +++ b/include/common.h @@ -146,6 +146,12 @@ unsigned long strtoul_suffix(const char *str, char **endp, int base); void start_barebox(void); void shutdown_barebox(void); +/* + * architectures which have special calling conventions for + * executing programs should set this. Used by the 'go' command + */ +extern void (*do_execute)(void *func, int argc, char *argv[]); + void arch_shutdown(void); int run_shell(void); |