9
0
Fork 0

ARM: Allow to compile in thumb-2 mode

This shrinks the resulting binary size by ~25%. Exceptions
are still handled in arm mode, so we have to explicitely
put .arm directives into the exception code. Thumb-2 mode
has been tested on i.MX51 Babbage board.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2011-12-10 16:41:07 +01:00
parent cb1bd905dc
commit 104a6a7ccf
11 changed files with 96 additions and 8 deletions

View File

@ -101,6 +101,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 "

View File

@ -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.

View File

@ -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

View File

@ -106,6 +106,7 @@ _STACK_START:
* exception handlers
*/
.section ".text","ax"
.arm
.align 5
.globl undefined_instruction

View File

@ -36,6 +36,7 @@ void __naked __section(.text_entry) start(void)
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 */

View File

@ -4,6 +4,17 @@
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"
@ -12,6 +23,7 @@ static inline void barebox_arm_head(void)
"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,

View File

@ -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

View File

@ -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
}

View File

@ -62,7 +62,11 @@ static int do_go(struct command *cmdtp, 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

View File

@ -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);

View File

@ -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);