The only place where we mix arm and thumb is hand-written asm parts. Attached patch adds explicit interworkers to asm and let's compile the rest without interworking.
diff --git a/conf/Makefile.common b/conf/Makefile.common
index 0dc26db..d0d52f0 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -19,7 +19,7 @@ if COND_sparc64_ieee1275
LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax
endif
if COND_arm
- CFLAGS_PLATFORM += -mthumb-interwork -mlong-calls
+ CFLAGS_PLATFORM += -mlong-calls
LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
endif
diff --git a/configure.ac b/configure.ac
index e599377..f2064d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -494,6 +494,25 @@ if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 || t
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as"
fi
+if test "x$target_cpu" = xarm ; then
+
+ AC_CACHE_CHECK([if compiling for thumb], [grub_cv_cc_target_thumb]
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([], [[
+#ifdef __thumb__
+#error "is thumb"
+#endif
+]])],
+ [grub_cv_cc_target_thumb=no], [grub_cv_cc_target_thumb=yes])])
+
+ if test "x$grub_cv_cc_target_thumb" = xyes ; then
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mthumb"
+ else
+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-thumb"
+ fi
+
+fi
+
if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then
TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
fi
diff --git a/grub-core/kern/arm/cache.S b/grub-core/kern/arm/cache.S
index 8522d24..3d2503e 100644
--- a/grub-core/kern/arm/cache.S
+++ b/grub-core/kern/arm/cache.S
@@ -84,19 +84,22 @@ FUNCTION(grub_arch_sync_caches_armv6)
#else
FUNCTION(grub_arch_sync_caches_armv7)
#endif
+ ARM_PROLOGUE
DSB
add r1, r0, r1
push {r0-r2, lr}
bl clean_dcache_range
pop {r0, r1}
bl invalidate_icache_range
- pop {r2, pc}
+ pop {r2, lr}
+ bx lr
#ifdef ARMV6
FUNCTION(grub_arm_disable_caches_mmu_armv6)
#else
FUNCTION(grub_arm_disable_caches_mmu_armv7)
#endif
+ ARM_PROLOGUE
push {r4, lr}
@@ -132,5 +135,6 @@ FUNCTION(grub_arm_disable_caches_mmu_armv7)
DSB
ISB
- pop {r4, pc}
+ pop {r4, lr}
+ bx lr
diff --git a/grub-core/kern/arm/cache_armv6.S b/grub-core/kern/arm/cache_armv6.S
index 52b8157..d6371eb 100644
--- a/grub-core/kern/arm/cache_armv6.S
+++ b/grub-core/kern/arm/cache_armv6.S
@@ -37,9 +37,11 @@ clean_invalidate_dcache:
#include "cache.S"
FUNCTION(grub_arm_main_id)
+ ARM_PROLOGUE
mrc p15, 0, r0, c0, c0, 0
bx lr
FUNCTION(grub_arm_cache_type)
+ ARM_PROLOGUE
mrc p15, 0, r0, c0, c0, 1
bx lr
\ No newline at end of file
diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S
index 0c16b10..454bad3 100644
--- a/grub-core/kern/arm/cache_armv7.S
+++ b/grub-core/kern/arm/cache_armv7.S
@@ -22,10 +22,16 @@
.text
.syntax unified
.arm
+#ifdef __clang__
+# define DMB .long 0xf57ff05f
+# define DSB .long 0xf57ff04f
+# define ISB .long 0xf57ff06f
+#else
.arch armv7a
# define DMB dmb
# define DSB dsb
# define ISB isb
+#endif
#define ARMV7 1
@ r0 - CLIDR
@@ -58,11 +64,17 @@ clean_invalidate_dcache:
@ read current cache information
mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR
lsr r3, r8, #13 @ Number of sets -1
- ldr r9, =0x3fff
- and r3, r3, r9
+
+ @ Keep only 14 bits of r3
+ lsl r3, r3, #18
+ lsr r3, r3, #18
+
lsr r4, r8, #3 @ Number of ways -1
- ldr r9, =0x1ff
- and r4, r4, r9
+
+ @ Keep only 9 bits of r4
+ lsl r4, r4, #23
+ lsr r4, r4, #23
+
and r7, r8, #7 @ log2(line size in words) - 2
add r7, r7, #2 @ adjust
mov r8, #1
diff --git a/grub-core/kern/arm/misc.S b/grub-core/kern/arm/misc.S
index 8420a2a..f5513c0 100644
--- a/grub-core/kern/arm/misc.S
+++ b/grub-core/kern/arm/misc.S
@@ -22,16 +22,13 @@
.file "misc.S"
.text
.syntax unified
-#if !defined (__thumb2__)
.arm
-#else
- .thumb
-#endif
.align 2
FUNCTION(__muldi3)
FUNCTION(__aeabi_lmul)
+ ARM_PROLOGUE
stmfd sp!, {r4, fp}
add fp, sp, #4
sub sp, sp, #16
@@ -74,14 +71,15 @@ FUNCTION(__aeabi_lmul)
.endm
FUNCTION(__aeabi_uidivmod)
+ ARM_PROLOGUE
division grub_divmod64
-
/*
* Null divide-by-zero handler
*/
FUNCTION(__aeabi_unwind_cpp_pr0)
FUNCTION(raise)
+ ARM_PROLOGUE
mov r0, #0
bx lr
diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/uboot/startup.S
index f54b14b..25c978a 100644
--- a/grub-core/kern/arm/uboot/startup.S
+++ b/grub-core/kern/arm/uboot/startup.S
@@ -47,7 +47,10 @@
.text
.arm
-FUNCTION(_start)
+ /* Don't use FUNCTION as this entry point is always ARM. */
+ .globl EXT_C(_start)
+ .type EXT_C(_start), %function
+EXT_C(_start):
b codestart
@ Size of final image integrated module blob - set by grub-mkimage
@@ -66,7 +69,7 @@ bss_start_ptr:
end_ptr:
.long EXT_C(_end)
-FUNCTION(codestart)
+codestart:
@ Store context: Machine ID, atags/dtb, ...
@ U-Boot API signature is stored on the U-Boot heap
@ Stack pointer used as start address for signature probing
@@ -117,8 +120,19 @@ FUNCTION(codestart)
1: str r2, [r0], #4
cmp r0, r1
bne 1b
-
- b EXT_C(grub_main)
+
+ ldr r0, main_addr
+#ifdef __thumb__
+ orr r0, r0, #1
+#endif
+ bx r0
+ .p2align 2
+#ifdef __thumb__
+ .thumb
+#endif
+main_addr:
+ .long EXT_C(grub_main)
+ .arm
/*
* uboot_syscall():
@@ -128,6 +142,7 @@ FUNCTION(codestart)
* U-Boot (Global Data Pointer) and preserve it for Grub.
*/
FUNCTION(grub_uboot_syscall)
+ ARM_PROLOGUE
str r8, transition_space
str lr, transition_space + 4
str r9, transition_space + 8
@@ -152,6 +167,7 @@ FUNCTION(grub_uboot_syscall)
bx lr
FUNCTION(grub_uboot_return)
+ ARM_PROLOGUE
adr sp, entry_state_end
pop {r4-r12, lr}
mov sp, r12
diff --git a/grub-core/lib/arm/setjmp.S b/grub-core/lib/arm/setjmp.S
index 4f15679..b731975 100644
--- a/grub-core/lib/arm/setjmp.S
+++ b/grub-core/lib/arm/setjmp.S
@@ -32,6 +32,7 @@ GRUB_MOD_LICENSE "GPLv3+"
* int grub_setjmp (grub_jmp_buf env)
*/
FUNCTION(grub_setjmp)
+ ARM_PROLOGUE
stm r0, { r4-r11, sp, lr }
mov r0, #0
bx lr
@@ -40,6 +41,7 @@ FUNCTION(grub_setjmp)
* int grub_longjmp (grub_jmp_buf env, int val)
*/
FUNCTION(grub_longjmp)
+ ARM_PROLOGUE
ldm r0, { r4-r11, sp, lr }
movs r0, r1
moveq r0, #1
diff --git a/include/grub/symbol.h b/include/grub/symbol.h
index 62d3cb1..6de9be2 100644
--- a/include/grub/symbol.h
+++ b/include/grub/symbol.h
@@ -52,9 +52,25 @@
/* .type not supported for non-ELF targets. XXX: Check this in configure? */
#define FUNCTION(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x):
#define VARIABLE(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x):
+#elif defined (__thumb__)
+#define FUNCTION(x) .p2align 2 ; .thumb ; .globl EXT_C(x) ; .type EXT_C(x), %function ; .thumb_func ; EXT_C(x):
+#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), %object ; EXT_C(x):
+#ifdef ASM_FILE
+ .macro ARM_PROLOGUE
+ bx pc
+ nop
+ .arm
+ orr lr, lr, #1
+ .endm
+#endif
#elif defined (__arm__)
#define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), %function ; EXT_C(x):
#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), %object ; EXT_C(x):
+#ifdef ASM_FILE
+ .macro ARM_PROLOGUE
+ .arm
+ .endm
+#endif
#else
#define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), @function ; EXT_C(x):
#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), @object ; EXT_C(x):
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Grub-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/grub-devel
