On Fri, Apr 12, 2013 at 07:33:21PM +0200, Vladimir 'φ-coder/phcoder' Serbinenko 
wrote:
> Hello, all. I've uploaded Leif's and my ARM code to
> http://bzr.savannah.gnu.org/lh/grub/branches/arm/changes. Francesco's
> code will be added as well once his papers are done. The only dirty part
> for Raspberry pi that I didn't upload is:

I have attached a patch (against this branch) that contains build
system fixes and changes to the assembly files in order to permit the 
same target-platform combination to build correctly on both ARMv6 and
ARMv7, with no special options required.

It does also revert the removal of uboot_get_real_bss_start, since
this causes GRUB to fail even reaching "Welcome to GRUB!" on my
Trimslice. It may not be the best solution, but it is in there for a
reason.

There are also some "collateral" changes in this patch, holding other
fixes I have in my launchpad branch. Sorry about those.

This _should_ make your out-of-tree patch unnecessary.

> === modified file 'conf/Makefile.common'
> --- conf/Makefile.common      2013-04-07 00:41:07 +0000
> +++ conf/Makefile.common      2013-04-12 14:55:49 +0000
> @@ -40,8 +40,7 @@
>  if COND_arm
>  # Image entry point always in ARM (A32) state - ensure proper
> functionality if
>  # the rest is built for the Thumb (T32) state.
> -  CFLAGS_PLATFORM += -mthumb-interwork -mno-unaligned-access -mlong-calls
> -  CCASFLAGS_PLATFORM = -Wa,-mimplicit-it=thumb
> +  CFLAGS_PLATFORM += -mthumb-interwork -march=armv6 -mlong-calls
>    LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
>  endif
> 
> 
> === modified file 'grub-core/kern/dl.c'
> --- grub-core/kern/dl.c       2013-03-19 19:25:09 +0000
> +++ grub-core/kern/dl.c       2013-04-12 14:55:49 +0000
> @@ -588,7 +588,7 @@
>  {
>    grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
>               (unsigned long) mod->sz, mod->base);
> -  grub_arch_sync_caches (mod->base, mod->sz);
> +  //  grub_arch_sync_caches (mod->base, mod->sz);
>  }
> 
>  /* Load a module from core memory.  */
> 
> 



> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel

=== modified file 'acinclude.m4'
--- acinclude.m4	2012-12-28 06:57:17 +0000
+++ acinclude.m4	2013-04-28 14:02:08 +0000
@@ -458,3 +458,23 @@
 AC_DEFUN([grub_TRANSFORM],[dnl
 AC_SUBST(AS_TR_SH([$1]), [`AS_ECHO([$1]) | sed "$program_transform_name"`])dnl
 ])
+
+dnl Check if the C compiler supports `-mno-unaligned-access'.
+AC_DEFUN([grub_CHECK_NO_UNALIGNED_ACCESS],[
+[# foobar
+nua_possible=yes]
+AC_MSG_CHECKING([whether `$CC' supports `-mno-unaligned-access'])
+AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+int main() {
+	return 0;
+}
+]])])
+
+[if eval "$ac_compile -S -mno-unaligned-access -o conftest.s" 2> /dev/null; then]
+  AC_MSG_RESULT([yes])
+  [rm -f conftest.s
+else
+  nua_possible=no]
+  AC_MSG_RESULT([no])
+[fi]
+])

=== modified file 'conf/Makefile.common'
--- conf/Makefile.common	2013-04-07 00:41:07 +0000
+++ conf/Makefile.common	2013-04-28 14:07:59 +0000
@@ -38,10 +38,7 @@
   LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax
 endif
 if COND_arm
-# Image entry point always in ARM (A32) state - ensure proper functionality if
-# the rest is built for the Thumb (T32) state.
-  CFLAGS_PLATFORM += -mthumb-interwork -mno-unaligned-access -mlong-calls
-  CCASFLAGS_PLATFORM = -Wa,-mimplicit-it=thumb
+  CFLAGS_PLATFORM += -mthumb-interwork -mlong-calls
   LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
 endif
 

=== modified file 'configure.ac'
--- configure.ac	2013-04-07 00:41:07 +0000
+++ configure.ac	2013-04-28 14:11:26 +0000
@@ -656,6 +656,14 @@
   TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
 fi
 
+# -mno-unaligned-access
+if test "$platform" = uboot; then
+  grub_CHECK_NO_UNALIGNED_ACCESS
+  if test x"$nua_possible" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -mno-unaligned-access"
+  fi
+fi
+
 AC_ARG_ENABLE([werror],
 	      [AS_HELP_STRING([--disable-werror],
                              [do not use -Werror when building GRUB])])

=== modified file 'grub-core/kern/arm/cache.S'
--- grub-core/kern/arm/cache.S	2013-04-07 00:41:07 +0000
+++ grub-core/kern/arm/cache.S	2013-04-28 12:48:56 +0000
@@ -17,19 +17,22 @@
  */
 
 #include <grub/symbol.h>
-#include <grub/dl.h>
 
 	.file	"cache.S"
 	.text
 	.syntax	unified
-#if !defined (__thumb2__)
 	.arm
-#define ARM(x...)	x
-#define THUMB(x...)
+#if (__ARM_ARCH_6__ == 1)
+	.arch	armv6
+# define DMB	mcr	p15, 0, r0, c7, c10, 5
+# define DSB	mcr	p15, 0, r0, c7, c10, 4
+# define ISB	mcr	p15, 0, r0, c7, c5, 4
+#elif (__ARM_ARCH_7A__ == 1)
+# define DMB	dmb
+# define DSB	dsb
+# define ISB	isb
 #else
-	.thumb
-#define THUMB(x...)	x
-#define ARM(x...)
+# error Unsupported architecture version!
 #endif
 
 	.align	2
@@ -39,54 +42,43 @@
  */
 
 @ r0 - *beg (inclusive)
-@ r1 - *end (exclusive)	
+@ r1 - *end (exclusive)
 clean_dcache_range:
-	@ Clean data cache range for range to point-of-unification
+	@ Clean data cache for range to point-of-unification
 	ldr	r2, dlinesz
+	sub	r3, r2, #1		@ align "beg" to start of line
+	mvn	r3, r3
+	and	r0, r0, r3
 1:	cmp	r0, r1
 	bge	2f
-#ifdef DEBUG
-	push	{r0-r2, lr}
-	mov	r1, r2
-	mov	r2, r0
-	ldr	r0, =dcstr
-	bl	EXT_C(grub_printf)
-	pop	{r0-r2, lr}
-#endif
 	mcr	p15, 0, r0, c7, c11, 1	@ DCCMVAU
 	add	r0, r0, r2		@ Next line
 	b	1b
-2:	dsb
+2:	DSB
 	bx	lr
 
 @ r0 - *beg (inclusive)
-@ r1 - *end (exclusive)	
+@ r1 - *end (exclusive)
 invalidate_icache_range:
 	@ Invalidate instruction cache for range to point-of-unification
 	ldr	r2, ilinesz
+	sub	r3, r2, #1		@ align "beg" to start of line
+	mvn	r3, r3
+	and	r0, r0, r3
 1:	cmp	r0, r1
 	bge	2f
-#ifdef DEBUG
-	push	{r0-r2, lr}
-	mov	r1, r2
-	mov	r2, r0
-	ldr	r0, =icstr
-	bl	EXT_C(grub_printf)
-	pop	{r0-r2, lr}
-#endif
 	mcr	p15, 0, r0, c7, c5, 1	@ ICIMVAU
 	add	r0, r0, r2		@ Next line
 	b	1b
 	@ Branch predictor invalidate all
 2:	mcr	p15, 0, r0, c7,	c5, 6	@ BPIALL
-	dsb
-	isb
+	DSB
+	ISB
 	bx	lr
-	
-@void __wrap___clear_cache(char *beg, char *end);
-FUNCTION(__wrap___clear_cache)
-	dmb
-	dsb
+
+sync_caches:
+	DMB
+	DSB
 	push	{r4-r6, lr}
 	ldr	r2, probed	@ If first call, probe cache sizes
 	cmp	r2, #0
@@ -103,7 +95,8 @@
 	push	{r4-r6, lr}
 	mrc 	p15, 0, r4, c0, c0, 1	@ Read Cache Type Register
 	mov	r5, #1
-	ubfx	r6, r4, #16, #4		@ Extract min D-cache num word log2
+	lsr	r6, r4, #16		@ Extract min D-cache num word log2
+	and	r6, r6, #0xf
 	add	r6, r6, #2		@ words->bytes
 	lsl	r6, r5, r6		@ Convert to num bytes
 	ldr	r3, =dlinesz
@@ -117,11 +110,6 @@
 	str	r5, [r3]
 	pop	{r4-r6, pc}
 
-#ifdef DEBUG
-dcstr:	.asciz	"cleaning %d bytes of D cache @ 0x%08x\n"
-icstr:	.asciz	"invalidating %d bytes of I cache @ 0x%08x\n"
-#endif
-	
 	.align	3
 probed:	.long	0
 dlinesz:
@@ -132,7 +120,7 @@
 @void grub_arch_sync_caches (void *address, grub_size_t len)
 FUNCTION(grub_arch_sync_caches)
 	add	r1, r0, r1
-	b	__wrap___clear_cache
+	b	sync_caches
 
 	@ r0  - CLIDR
 	@ r1  - LoC
@@ -149,21 +137,26 @@
 clean_invalidate_dcache:
 	push	{r4-r12, lr}
 	mrc 	p15, 1, r0, c0, c0, 1	@ Read CLIDR
-	ubfx	r1, r0, #24, #3		@ Extract LoC
-	
+	lsr	r1, r0, #24		@ Extract LoC
+	and	r1, r1, #0x7
+
 	mov	r2, #0			@ First level, L1
 2:	and	r8, r0, #7		@ cache type at current level
 	cmp	r8, #2
 	blt	5f			@ instruction only, or none, skip level
 
-	@ set current cache level/type (for CSSIDR read)
+	@ set current cache level/type (for CCSIDR read)
 	lsl	r8, r2, #1
 	mcr	p15, 2, r8, c0, c0, 0	@ Write CSSELR (level, type: data/uni)
 
 	@ read current cache information
-	mrc	p15, 1, r8, c0, c0, 0	@ Read CSSIDR
-	ubfx	r3, r8, #13, #14	@ Number of sets -1
-	ubfx	r4, r8, #3, #9		@ Number of ways -1
+	mrc	p15, 1, r8, c0, c0, 0	@ Read CCSIDR
+	lsr	r3, r8, #13		@ Number of sets -1
+	ldr	r9, =0x3fff
+	and	r3, r3, r9
+	lsr	r4, r8, #3		@ Number of ways -1
+	ldr	r9, =0x1ff
+	and	r4, r4, r9
 	and	r7, r8, #7		@ log2(line size in words) - 2
 	add	r7, r7, #2		@  adjust
 	mov	r8, #1
@@ -186,11 +179,11 @@
 	clz	r9, r10			@ r9 = way field offset
 	add	r9, r9, #1
 4:	lsl	r10, r6, r9
-	orr	r11, r8, r10		@ insert way field	
-	
-	@ clean line by set/way
+	orr	r11, r8, r10		@ insert way field
+
+	@ clean and invalidate line by set/way
 	mcr	p15, 0, r11, c7, c14, 2	@ DCCISW
-	
+
 	@ next way
 	add	r6, r6, #1
 	cmp	r6, r4
@@ -200,7 +193,7 @@
 	add	r5, r5, #1
 	cmp	r5, r3
 	ble	3b
-	
+
 	@ next level
 5:	lsr	r0, r0, #3		@ align next level CLIDR 'type' field
 	add	r2, r2, #1		@ increment cache level counter
@@ -208,8 +201,8 @@
 	blt	2b			@ outer loop
 
 	@ return
-6:	dsb
-	isb
+6:	DSB
+	ISB
 	pop	{r4-r12, pc}
 
 FUNCTION(grub_arm_disable_caches_mmu)
@@ -219,8 +212,8 @@
 	mrc	p15, 0, r0, c1, c0, 0
 	bic	r0, r0, #(1 << 2)
 	mcr	p15, 0, r0, c1, c0, 0
-	dsb
-	isb
+	DSB
+	ISB
 
 	@ clean/invalidate D-cache
 	bl	clean_invalidate_dcache
@@ -229,14 +222,14 @@
 	mrc	p15, 0, r0, c1, c0, 0
 	bic	r0, r0, #(1 << 12)
 	mcr	p15, 0, r0, c1, c0, 0
-	dsb
-	isb
+	DSB
+	ISB
 
 	@ invalidate I-cache (also invalidates branch predictors)
 	mcr	p15, 0, r0, c7, c5, 0
-	dsb
-	isb
-	
+	DSB
+	ISB
+
 	@ clear SCTLR M bit
 	mrc	p15, 0, r0, c1, c0, 0
 	bic	r0, r0, #(1 << 0)
@@ -244,8 +237,8 @@
 
 	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLB
 	mcr	p15, 0, r0, c7, c5, 6	@ invalidate branch predictor
-	dsb
-	isb
+	DSB
+	ISB
 
 	pop	{r4, pc}
 

=== modified file 'grub-core/kern/arm/uboot/startup.S'
--- grub-core/kern/arm/uboot/startup.S	2013-04-12 14:50:58 +0000
+++ grub-core/kern/arm/uboot/startup.S	2013-04-28 14:37:40 +0000
@@ -73,20 +73,13 @@
 	@ Modules have been stored as a blob in BSS,
 	@ they need to be manually relocated to _end or
 	@ (__bss_start + grub_total_module_size), whichever greater.
-	ldr	r0, =EXT_C(__bss_start)		@ src
-	add	r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
-	mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
-	and	r0, r0, r1
-
+	bl	uboot_get_real_bss_start	@ r0 = src
 	ldr	r1, =EXT_C(_end)		@ dst = End of BSS
 	ldr	r2, grub_total_module_size	@ blob size
 	add	r3, r0, r2			@ blob end
 	cmp	r1, r3				@ _end < blob end?
 	movlt	r1, r3				@ dst = blob end + blob size
-
-	ldr     r12, =EXT_C(grub_modbase)
-	str     r1, [r12]
-
+	
 1:	ldr	r3, [r0], #4 			@ r3 = *src++ 
 	str	r3, [r1], #4			@ *dst++ = r3 
 	subs	r2, #4				@ remaining -= 4
@@ -99,16 +92,29 @@
 
 	@ Since we _are_ the C run-time, we need to manually zero the BSS
 	@ region before continuing
-	ldr	r0, =EXT_C(__bss_start)	@ zero from here
+	bl	uboot_get_real_bss_start	@ zero from here
 	ldr	r1, =EXT_C(_end)		@ to here
 	mov	r2, #0
 1:	str	r2, [r0], #4
 	cmp	r0, r1
 	bne	1b
-	
+
 	b	EXT_C(grub_main)
 
 	/*
+	 * __bss_start does not actually point to the start of the runtime
+	 * BSS, but rather to the next byte following the preceding data.
+	 */
+FUNCTION (uboot_get_real_bss_start)
+	ldr	r0, =EXT_C(__bss_start)		@ src
+	tst	r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	beq	1f
+	mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	and	r0, r0, r1
+	add	r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN)
+1:	bx	lr
+
+	/*
 	 * uboot_syscall():
 	 *   This function is effectively a veneer, so it cannot
 	 *   modify the stack or corrupt any registers other than

=== modified file 'grub-core/kern/uboot/init.c'
--- grub-core/kern/uboot/init.c	2013-04-12 14:51:33 +0000
+++ grub-core/kern/uboot/init.c	2013-04-28 14:36:35 +0000
@@ -69,6 +69,7 @@
 void
 grub_machine_init (void)
 {
+  grub_addr_t end, real_bss_start;
   int ver;
 
   /* First of all - establish connection with U-Boot */
@@ -84,14 +85,26 @@
       uboot_puts ("invalid U-Boot API version\n");
     }
 
+  /*
+   * Modules were relocated to _end, or __bss_start + grub_total_module_size,
+   * whichever greater. (And __bss_start may not point to actual BSS start...)
+   */
+  real_bss_start = uboot_get_real_bss_start ();
+  end = real_bss_start + grub_total_module_size;
+  if (end < (grub_addr_t) _end)
+    end = (grub_addr_t) _end;
+  grub_modbase = end;
+
   /* Initialize the console so that GRUB can display messages.  */
   grub_console_init_early ();
 
   /* Enumerate memory and initialize the memory management system. */
   grub_uboot_mm_init ();
 
-  grub_dprintf ("init", "__bss_start: %p\n", __bss_start);
-  grub_dprintf ("init", "_end: %p\n", _end);
+  grub_dprintf ("init", "__bss_start: 0x%08x, real_bss_start: 0x%08x\n",
+		(grub_addr_t) __bss_start, real_bss_start);
+  grub_dprintf ("init", "end: 0x%08x, _end: 0x%08x\n",
+		(grub_addr_t) end, (grub_addr_t) _end);
   grub_dprintf ("init", "grub_modbase: %p\n", (void *) grub_modbase);
   grub_dprintf ("init", "grub_modules_get_end(): %p\n",
 		(void *) grub_modules_get_end ());
@@ -130,10 +143,9 @@
   tmp = uboot_env_get ("grub_bootdev");
   if (tmp)
     {
-      *device = grub_malloc (grub_strlen (tmp) + 1);
+      *device = grub_strdup (tmp);
       if (*device == NULL)
 	return;
-      grub_strncpy (*device, tmp, grub_strlen (tmp) + 1);
     }
   else
     *device = NULL;
@@ -141,10 +153,9 @@
   tmp = uboot_env_get ("grub_bootpath");
   if (tmp)
     {
-      *path = grub_malloc (grub_strlen (tmp) + 1);
+      *path = grub_strdup (tmp);
       if (*path == NULL)
 	return;
-      grub_strncpy (*path, tmp, grub_strlen (tmp) + 1);
     }
   else
     *path = NULL;

=== modified file 'grub-core/lib/arm/setjmp.S'
--- grub-core/lib/arm/setjmp.S	2013-04-07 00:41:07 +0000
+++ grub-core/lib/arm/setjmp.S	2013-04-28 14:16:24 +0000
@@ -17,19 +17,10 @@
  */
 
 #include <grub/symbol.h>
-#include <grub/dl.h>
 
 	.file	"setjmp.S"
 	.syntax	unified
-#if !defined (__thumb2__)
 	.arm
-#define ARM(x...)	x
-#define THUMB(x...)
-#else
-	.thumb
-#define THUMB(x...)	x
-#define ARM(x...)
-#endif
 
 	.text
 
@@ -37,9 +28,7 @@
  * int grub_setjmp (grub_jmp_buf env)
  */
 FUNCTION(grub_setjmp)
- THUMB(	mov	ip, sp			)
- THUMB(	stm	r0, { r4-r11, ip, lr }	)
- ARM(	stm	r0, { r4-r11, sp, lr }	)
+	stm	r0, { r4-r11, sp, lr }
 	mov	r0, #0
 	bx	lr
 
@@ -47,9 +36,7 @@
  * int grub_longjmp (grub_jmp_buf env, int val)
  */
 FUNCTION(grub_longjmp)
- THUMB(	ldm	r0, { r4-r11, ip, lr }	)
- THUMB(	mov	sp, ip			)
- ARM(	ldm	r0, { r4-r11, sp, lr }	)
+ 	ldm	r0, { r4-r11, sp, lr }
 	movs	r0, r1
 	moveq	r0, #1
 	bx	lr

=== modified file 'include/grub/libgcc.h'
--- include/grub/libgcc.h	2013-04-12 14:47:15 +0000
+++ include/grub/libgcc.h	2013-04-28 12:53:45 +0000
@@ -121,6 +121,5 @@
 void EXPORT_FUNC (__aeabi_llsr) (void);
 void EXPORT_FUNC (__aeabi_uidiv) (void);
 void EXPORT_FUNC (__aeabi_uidivmod) (void);
-void EXPORT_FUNC (__wrap___clear_cache) (void *, void *);
 void EXPORT_FUNC (__aeabi_ulcmp) (void);
 #endif

=== modified file 'include/grub/symbol.h'
--- include/grub/symbol.h	2013-04-07 00:41:07 +0000
+++ include/grub/symbol.h	2013-04-28 13:45:11 +0000
@@ -29,11 +29,7 @@
 
 #if HAVE_ASM_USCORE
 #ifdef ASM_FILE
-# ifndef (__arm__)
-#  define EXT_C(sym)	_ ## sym
-# else
-#  define EXT_C(sym)	% ## sym
-# endif
+# define EXT_C(sym)	_ ## sym
 #else
 # define EXT_C(sym)	"_" sym
 #endif

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to