]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
x86_64 support for relocator
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 12 Jan 2010 22:30:52 +0000 (23:30 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 12 Jan 2010 22:30:52 +0000 (23:30 +0100)
conf/i386.rmk
conf/x86_64-efi.rmk
lib/i386/relocator.c
lib/i386/relocator16.S
lib/i386/relocator32.S
lib/i386/relocator64.S
lib/relocator.c

index 2efd9895aeb692e79ea02a9d63cf3036d2aea5ae..d7417f444a24bc10409e5636c65b9a41019aa471 100644 (file)
@@ -18,7 +18,7 @@ vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
 pkglib_MODULES += relocator.mod
 relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \
        lib/i386/relocator64.S lib/i386/relocator16.S \
-       lib/i386/relocator_asm.S lib/i386/relocator.c
+       lib/$(target_cpu)/relocator_asm.S lib/i386/relocator.c
 relocator_mod_CFLAGS = $(COMMON_CFLAGS)
 relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
 relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
index 19220610dda9d0b073faace99189aa41dead0b88..36d6579deba3c7153b833162d84fac8431729969 100644 (file)
@@ -167,7 +167,9 @@ xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
 xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
 pkglib_MODULES += relocator.mod
-relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
+relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \
+       lib/i386/relocator64.S lib/i386/relocator16.S \
+       lib/$(target_cpu)/relocator_asm.S lib/i386/relocator.c
 relocator_mod_CFLAGS = $(COMMON_CFLAGS)
 relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
 relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
index 5757bb6df25c830027fdc4755e00821123bc3180..d040c80abd669c32dc0f2ba0f56a0edc4625afcb 100644 (file)
@@ -77,7 +77,11 @@ extern grub_addr_t grub_relocator64_cr3;
 grub_size_t grub_relocator_align = 1;
 grub_size_t grub_relocator_forward_size;
 grub_size_t grub_relocator_backward_size;
-grub_size_t grub_relocator_jumper_size = 10;
+#ifdef __x86_64__
+grub_size_t grub_relocator_jumper_size = 12;
+#else
+grub_size_t grub_relocator_jumper_size = 7;
+#endif
 
 void
 grub_cpu_relocator_init (void)
@@ -91,16 +95,26 @@ grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
 {
   grub_uint8_t *ptr;
   ptr = rels;
-  /* movl $addr, %eax (for relocator) */
+#ifdef __x86_64__
+  /* movq imm64, %rax (for relocator) */
+  *(grub_uint8_t *) ptr = 0x48;
+  ptr++;
+  *(grub_uint8_t *) ptr = 0xb8;
+  ptr++;
+  *(grub_uint64_t *) ptr = addr;
+  ptr += sizeof (grub_uint64_t);
+#else
+  /* movl imm32, %eax (for relocator) */
   *(grub_uint8_t *) ptr = 0xb8;
   ptr++;
   *(grub_uint32_t *) ptr = addr;
-  ptr += 4;
-  /* jmp $addr */
-  *(grub_uint8_t *) ptr = 0xe9;
+  ptr += sizeof (grub_uint32_t);
+#endif
+  /* jmp $eax/$rax */
+  *(grub_uint8_t *) ptr = 0xff;
+  ptr++;
+  *(grub_uint8_t *) ptr = 0xe0;
   ptr++;
-  *(grub_uint32_t *) ptr = addr - (grub_uint32_t) (ptr + 4);
-  ptr += 4;
 }
 
 void
index d35adecd854a9bd4de52b93b5523f2404bdabe66..7d65e4dbeac69e1f79900deb3c8fe422d278fc9b 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifdef __x86_64__
 #define RAX %rax
-#define RSI %rdi
+#define RSI %rsi
 #else
 #define RAX %eax
 #define RSI %esi
@@ -93,7 +93,7 @@ LOCAL(cont1):
 
        movl    %esi, %eax
        shrl    $4, %eax
-       movw    %ax, (LOCAL (segment) - LOCAL (base)) (RSI, 1)
+       movw    %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1)
        
        /* jump to a 16 bit segment */
        ljmp    $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base))
index 4e0553c0325e7e6e7ffc618ae6a4c31c83e78383..4f79151e23290c1ea41855ed74ca16ff4ee54ef4 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifdef __x86_64__
 #define RAX %rax
-#define RSI %rdi
+#define RSI %rsi
 #else
 #define RAX %eax
 #define RSI %esi
index 42f61e32e5e1aa55a62b77f3cd7a2714fa9959e4..05627fb90614e6bddcd3eefa42a67314c7757b6b 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifdef __x86_64__
 #define RAX %rax
-#define RSI %rdi
+#define RSI %rsi
 #else
 #define RAX %eax
 #define RSI %esi
@@ -82,7 +82,7 @@ VARIABLE(grub_relocator64_cr3)
        .byte   0xb8
 VARIABLE(grub_relocator64_cr3)
        .quad   0
-       movl    %rax, %cr3
+       movq    %rax, %cr3
 #endif
        /* Load GDT. */
        lgdt    (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)
index a5b3c6daf8de4ed8d5f9150aa07fe2cfbad6d0a6..84ead99b1a21bac88f4f5958ab606cef53d59f04 100644 (file)
@@ -40,7 +40,7 @@ grub_relocator_new (void)
     
   ret->postchunks = ~(grub_addr_t) 0;
   ret->relocators_size = grub_relocator_jumper_size;
-  grub_dprintf ("relocator", "relocators_size=%d\n", ret->relocators_size);
+  grub_dprintf ("relocator", "relocators_size=%ld\n", ret->relocators_size);
   return ret;
 }
 
@@ -103,7 +103,7 @@ get_best_header (struct grub_relocator *rel,
            hb = h;
            hbp = hp;
            *best_addr = addr;
-           grub_dprintf ("relocator", "picked %p/%x\n", hb, addr);
+           grub_dprintf ("relocator", "picked %p/%lx\n", hb, addr);
          }
       }
     else
@@ -146,7 +146,7 @@ get_best_header (struct grub_relocator *rel,
            hb = h;
            hbp = hp;
            *best_addr = addr;
-           grub_dprintf ("relocator", "picked %p/%x\n", hb, addr);
+           grub_dprintf ("relocator", "picked %p/%lx\n", hb, addr);
          }
       }
   }
@@ -221,7 +221,7 @@ malloc_in_range (struct grub_relocator *rel,
   hb = get_best_header (rel, start, end, align, size, rb, &hbp, &best_addr,
                        from_low_priv, collisioncheck);
 
-  grub_dprintf ("relocator", "best header %p/%x\n", hb, best_addr);
+  grub_dprintf ("relocator", "best header %p/%lx\n", hb, best_addr);
 
   if (!hb)
     {
@@ -421,14 +421,14 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
        rel->highestnonpostaddr = start + size;  
     }
 
-  grub_dprintf ("relocator", "relocators_size=%d\n", rel->relocators_size);
+  grub_dprintf ("relocator", "relocators_size=%ld\n", rel->relocators_size);
 
   if (start < target)
     rel->relocators_size += grub_relocator_backward_size;
   if (start > target)
     rel->relocators_size += grub_relocator_forward_size;
 
-  grub_dprintf ("relocator", "relocators_size=%d\n", rel->relocators_size);
+  grub_dprintf ("relocator", "relocators_size=%ld\n", rel->relocators_size);
 
   chunk->src = start;
   chunk->target = target;
@@ -485,7 +485,7 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
     }
 
   adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr);
-  grub_dprintf ("relocator", "Adjusted limits from %x-%x to %x-%x\n",
+  grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n",
                min_addr, max_addr, min_addr2, max_addr2);
 
   do
@@ -572,7 +572,7 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
   grub_addr_t rels;
   grub_addr_t rels0;
 
-  grub_dprintf ("relocator", "Preparing relocs (size=%d)\n",
+  grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n",
                rel->relocators_size);
 
   if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1,