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):

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to