]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Hopefully fixed cache problems in relocator
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 22 Nov 2009 14:05:20 +0000 (15:05 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 22 Nov 2009 14:05:20 +0000 (15:05 +0100)
lib/mips/relocator.c
lib/mips/relocator_asm.S
lib/relocator.c

index 4a67418c492938ccab0d9e3239700ce1c822e0fa..61c93e39f68466b08222468c07ec8047b351ed09 100644 (file)
@@ -22,6 +22,7 @@
 #include <grub/types.h>
 #include <grub/types.h>
 #include <grub/err.h>
+#include <grub/cache.h>
 
 #include <grub/mips/relocator.h>
 
@@ -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) ();
 }
 
index f901fbe8901aa3f71da2f0ab18099dbd47d7f860..f9cdf147084a5c2849d20956f278bd66ea1382f0 100644 (file)
  */
 
 #include <grub/symbol.h>
-
-#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)
index e551f337f33d2ec5140205c58f360edb2cda49f4..bebf7ada96c205a7dca31d269bd0c3ee82f4009c 100644 (file)
@@ -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),