summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-03-06 09:39:59 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-03-06 09:39:59 +0100
commitbeb36c510bd6abf80a20148bf165a990c69fed8a (patch)
tree95e7a242ee9c264bc35f2aedddacae74e93d7ad9
parente0d674735b26c279d4cb6c73c140f1e0866a7953 (diff)
parent276252a5598a9596970cc02f186c3847b932dcc1 (diff)
downloadbarebox-beb36c510bd6abf80a20148bf165a990c69fed8a.tar.gz
barebox-beb36c510bd6abf80a20148bf165a990c69fed8a.tar.xz
Merge branch 'work/thumb2' into next
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/Makefile11
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c3
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/flash_header.c3
-rw-r--r--arch/arm/boards/eukrea_cpuimx51/flash_header.c3
-rw-r--r--arch/arm/boards/freescale-mx25-3-stack/3stack.c3
-rw-r--r--arch/arm/boards/freescale-mx35-3-stack/flash_header.c3
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/flash_header.c3
-rw-r--r--arch/arm/boards/freescale-mx53-loco/flash_header.c3
-rw-r--r--arch/arm/boards/freescale-mx53-smd/flash_header.c3
-rw-r--r--arch/arm/cpu/cpu.c27
-rw-r--r--arch/arm/cpu/exceptions.S1
-rw-r--r--arch/arm/cpu/mmu.c4
-rw-r--r--arch/arm/cpu/start.c35
-rw-r--r--arch/arm/include/asm/barebox-arm-head.h36
-rw-r--r--arch/arm/include/asm/barebox-arm.h3
-rw-r--r--arch/arm/include/asm/unified.h8
-rw-r--r--arch/arm/lib/armlinux.c17
-rw-r--r--arch/arm/lib/barebox.lds.S7
-rw-r--r--commands/go.c6
-rw-r--r--common/misc.c3
-rw-r--r--include/common.h6
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);