=== 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 -#include .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 - address@hidden __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 -#include .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