diff options
Diffstat (limited to 'arch/sh/kernel/head.S')
-rw-r--r-- | arch/sh/kernel/head.S | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 9b9e6ef..f5f53d1 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -11,6 +11,18 @@ * Head.S contains the SH exception handlers and startup code. */ #include <linux/linkage.h> +#include <asm/thread_info.h> + +#ifdef CONFIG_CPU_SH4A +#define SYNCO() synco + +#define PREFI(label, reg) \ + mov.l label, reg; \ + prefi @reg +#else +#define SYNCO() +#define PREFI(label, reg) +#endif .section .empty_zero_page, "aw" ENTRY(empty_zero_page) @@ -42,18 +54,25 @@ ENTRY(_stext) ! Initialize global interrupt mask mov #0, r0 ldc r0, r6_bank + + /* + * Prefetch if possible to reduce cache miss penalty. + * + * We do this early on for SH-4A as a micro-optimization, + * as later on we will have speculative execution enabled + * and this will become less of an issue. + */ + PREFI(5f, r0) + PREFI(6f, r0) + ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #0x20, r1 ! - shll8 r1 ! r1 = 8192 + mov #(THREAD_SIZE >> 8), r1 + shll8 r1 ! r1 = THREAD_SIZE sub r1, r0 ! ldc r0, r7_bank ! ... and initial thread_info - ! - ! Additional CPU initialization - mov.l 6f, r0 - jsr @r0 - nop + ! Clear BSS area mov.l 3f, r1 add #4, r1 @@ -62,6 +81,14 @@ ENTRY(_stext) 9: cmp/hs r2, r1 bf/s 9b ! while (r1 < r2) mov.l r0,@-r2 + + ! Additional CPU initialization + mov.l 6f, r0 + jsr @r0 + nop + + SYNCO() ! Wait for pending instructions.. + ! Start kernel mov.l 5f, r0 jmp @r0 @@ -69,7 +96,7 @@ ENTRY(_stext) .balign 4 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF -2: .long stack +2: .long init_thread_union+THREAD_SIZE 3: .long __bss_start 4: .long _end 5: .long start_kernel |