From 8719095cc8942b5b8d23fc48ebf90e1bcda3d0a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Nov 2009 15:05:20 +0100 Subject: [PATCH] Hopefully fixed cache problems in relocator --- lib/mips/relocator.c | 5 +++++ lib/mips/relocator_asm.S | 29 +++++++++++++++++++++-------- lib/relocator.c | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 4a67418c4..61c93e39f 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -80,6 +81,8 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } @@ -98,6 +101,8 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index f901fbe89..f9cdf1470 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -17,29 +17,35 @@ */ #include - -#ifdef BACKWARD -#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) -#else -#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) -#endif .p2align 4 /* force 16-byte alignment */ VARIABLE (grub_relocator32_forward_start) + move $12, $9 + move $13, $10 + copycont1: lb $11,0($8) sb $11,0($9) - cache 1, 0($9) - cache 0, 0($9) addiu $8, $8, 0x1 addiu $9, $9, 0x1 addiu $10, $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont1 + +cachecont1: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont1 VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) + move $12, $9 + move $13, $10 + addu $9, $9, $10 addu $8, $8, $10 /* Backward movsl is implicitly off-by-one. compensate that. */ @@ -55,4 +61,11 @@ copycont2: addiu $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont2 +cachecont2: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont2 VARIABLE (grub_relocator32_backward_end) diff --git a/lib/relocator.c b/lib/relocator.c index e551f337f..bebf7ada9 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -69,12 +69,23 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, playground = (char *) relocator - RELOCATOR_SIZEOF (forward); size = *(grub_size_t *) playground; + grub_dprintf ("relocator", + "Relocator: source: %p, destination: 0x%x, size: 0x%x\n", + relocator, dest, size); + if (UINT_TO_PTR (dest) >= relocator) { int overhead; overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); + grub_dprintf ("relocator", + "Backward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator - overhead, + (char *) relocator - overhead, + dest - overhead, size + overhead); + write_call_relocator_bw ((char *) relocator - overhead, (char *) relocator - overhead, dest - overhead, size + overhead, state); @@ -85,6 +96,12 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + RELOCATOR_SIZEOF (forward) - (dest + size); + grub_dprintf ("relocator", + "Forward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead); write_call_relocator_fw ((char *) relocator + size + overhead - RELOCATOR_SIZEOF (forward),