* Re: ARM branch
2013-04-12 17:33 ARM branch Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-05-01 18:32 ` Leif Lindholm
2013-05-03 12:34 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-05-04 17:50 ` Francesco Lavra
0 siblings, 2 replies; 6+ messages in thread
From: Leif Lindholm @ 2013-05-01 18:32 UTC (permalink / raw)
To: The development of GNU GRUB; +Cc: phcoder
[-- Attachment #1: Type: text/plain, Size: 2140 bytes --]
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
[-- Attachment #2: build-fixes.patch --]
[-- Type: text/x-diff, Size: 12672 bytes --]
=== 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
^ permalink raw reply [flat|nested] 6+ messages in thread