]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Implement grub_machine_get_bootlocation for ARC.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 27 Apr 2013 17:12:11 +0000 (19:12 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 27 Apr 2013 17:12:11 +0000 (19:12 +0200)
ChangeLog
grub-core/Makefile.core.def
grub-core/boot/mips/startup_raw.S
grub-core/kern/mips/arc/init.c
grub-core/kern/mips/init.c
grub-core/kern/mips/loongson/init.c
grub-core/kern/mips/qemu_mips/init.c
util/grub-mkrescue.in

index 0d4329c9e358d1eb9a5c23a0f38b4cdfaaa09ae9..09a6c70afe6f6955868fc8314d44fa94f270f168 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Implement grub_machine_get_bootlocation for ARC.
+
 2013-04-27  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Improve AHCI detection and command issuing.
index 2a8ac6f5b5ce3095fb411d8e5ae923c938c20478..7f9372320bc6d5043873af9d65f0a025a43a34cd 100644 (file)
@@ -76,6 +76,7 @@ kernel = {
   mips_arc_ldflags    = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
   mips_qemu_mips_ldflags    = '-Wl,-Ttext,0x80200000';
 
+  mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
   mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK';
   i386_qemu_cppflags     = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
   emu_cflags = '$(CFLAGS_GNULIB)';
index bbbc1dbece5001aee386f8d89f5fd3265979b5d0..606197624f0dfdb18140ea884cd12b10189b08c7 100644 (file)
@@ -196,6 +196,21 @@ do_check:
 argfw:
        not $s7, $a2
 cmdlinedone:   
+#endif
+#ifdef GRUB_MACHINE_ARC
+       lui $t0, %hi(_start - 256)
+       addiu $t0, $t0, %lo(_start - 256)
+       addiu $t3, $t0, 255
+       lw $t1, 0($a1)
+1:     
+       bne $t0, $t3, 2f
+        lb $t2, 0($t1)
+       move $t2, $zero
+2:
+       sb $t2, 0($t0)
+       addiu $t0, $t0, 1
+       bnez $t2, 1b
+        addiu $t1, $t1, 1
 #endif
        /* Copy the decompressor. */
        lui $t1, %hi(base)
@@ -253,10 +268,15 @@ cmdlinedone:
        lui $t0, %hi(EXT_C(grub_decompress_core))
        addiu $t0, $t0, %lo(EXT_C(grub_decompress_core))
 
+#ifdef GRUB_MACHINE_ARC
+       lui $sp, %hi(_start - 512)
+       jalr $t0
+        addiu $sp, $sp, %lo(_start - 512)
+#else
        lui $sp, %hi(_start - 256)
        jalr $t0
         addiu $sp, $sp, %lo(_start - 256)
-       
+#endif 
        move $a0, $s1
        move $a1, $s6
 
index 92a2877545ac5efc5458f66f70af70c792f9b2fd..d279ada7c8a58105ddc73cc6fc60cc41394b40a3 100644 (file)
@@ -34,6 +34,8 @@
 #include <grub/arc/arc.h>
 #include <grub/offsets.h>
 #include <grub/i18n.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
 
 const char *type_names[] = {
 #ifdef GRUB_CPU_WORDS_BIGENDIAN
@@ -164,10 +166,42 @@ grub_arc_alt_name_to_norm (const char *name, const char *suffix)
   return ret;
 }
 
+static char *
+norm_name_to_alt (const char *name)
+{
+  char *optr;
+  const char *iptr;
+  int state = 0;
+  char * ret = grub_malloc (grub_strlen (name) + sizeof ("arc/"));
+
+  if (!ret)
+    return NULL;
+  optr = grub_stpcpy (ret, "arc/");
+  for (iptr = name; *iptr; iptr++)
+    {
+      if (state == 1)
+       {
+         *optr++ = '/';
+         state = 0;
+       }
+      if (*iptr == '(')
+       continue;
+      if (*iptr == ')')
+       {
+         state = 1;
+         continue;
+       }
+      *optr++ = *iptr;
+    }
+  *optr = '\0';
+  return ret;
+}
+
 extern grub_uint32_t grub_total_modules_size __attribute__ ((section(".text")));
 grub_addr_t grub_modbase;
 
 extern char _end[];
+static char boot_location[256];
 
 void
 grub_machine_init (void)
@@ -175,6 +209,9 @@ grub_machine_init (void)
   struct grub_arc_memory_descriptor *cur = NULL;
   grub_addr_t modend;
 
+  grub_memcpy (boot_location,
+              (char *) (GRUB_DECOMPRESSOR_LINK_ADDR - 256), 256);
+
   grub_modbase = ALIGN_UP ((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN);
   modend = grub_modbase + grub_total_modules_size;
   grub_console_init_early ();
@@ -239,3 +276,133 @@ grub_exit (void)
   while (1);
 }
 
+static char *
+get_part (char *dev)
+{
+  char *ptr;
+  if (!*dev)
+    return 0;
+  ptr = dev + grub_strlen (dev) - 1;
+  if (ptr == dev || *ptr != ')')
+    return 0;
+  ptr--;
+  while (grub_isdigit (*ptr) && ptr > dev)
+    ptr--;
+  if (*ptr != '(' || ptr == dev)
+    return 0;
+  ptr--;
+  if (ptr - dev < (int) sizeof ("partition") - 2)
+    return 0;
+  ptr -= sizeof ("partition") - 2;
+  if (grub_memcmp (ptr, "partition", sizeof ("partition") - 1) != 0)
+    return 0;
+  return ptr;
+}
+
+static grub_disk_addr_t
+get_partition_offset (char *part, grub_disk_addr_t *en)
+{
+  grub_arc_fileno_t handle;
+  grub_disk_addr_t ret = -1;
+  struct grub_arc_fileinfo info;
+  grub_arc_err_t r;
+
+  if (GRUB_ARC_FIRMWARE_VECTOR->open (part, GRUB_ARC_FILE_ACCESS_OPEN_RO,
+                                     &handle))
+    return -1;
+
+  r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (handle, &info);
+  if (!r)
+    {
+      ret = (info.start >> 9);
+      *en = (info.end >> 9);
+    }
+  GRUB_ARC_FIRMWARE_VECTOR->close (handle);
+  return ret;
+}
+
+struct get_device_name_ctx
+{
+  char *partition_name;
+  grub_disk_addr_t poff, pend;
+};
+
+static int
+get_device_name_iter (grub_disk_t disk __attribute__ ((unused)),
+                     const grub_partition_t part, void *data)
+{
+  struct get_device_name_ctx *ctx = data;
+
+  if (grub_partition_get_start (part) == ctx->poff
+      && grub_partition_get_len (part) == ctx->pend)
+    {
+      ctx->partition_name = grub_partition_get_name (part);
+      return 1;
+    }
+
+  return 0;
+}
+
+void
+grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
+                              char **path __attribute__ ((unused)))
+{
+  char *loaddev = boot_location;
+  char *pptr, *partptr;
+  char *dname;
+  grub_disk_addr_t poff = -1, pend;
+  struct get_device_name_ctx ctx;
+  grub_disk_t parent = 0;
+
+  pptr = grub_strchr (loaddev, '/');
+  if (pptr)
+    {
+      *path = grub_strdup (pptr);
+      *pptr = '\0';
+    }
+  partptr = get_part (loaddev);
+  if (partptr)
+    {
+      poff = get_partition_offset (loaddev, &pend);
+      *partptr = '\0';
+    }
+  dname = norm_name_to_alt (loaddev);
+  if (poff == (grub_addr_t) -1)
+    {
+      *device = dname;
+      return;
+    }
+
+  parent = grub_disk_open (dname);
+  if (!parent)
+    {
+      *device = dname;
+      return;
+    }
+
+  if (poff == 0
+      && pend == grub_disk_get_size (parent))
+    {
+      grub_disk_close (parent);
+      *device = dname;
+      return;
+    }
+
+  ctx.partition_name = NULL;
+  ctx.poff = poff;
+  ctx.pend = pend;
+
+  grub_partition_iterate (parent, get_device_name_iter, &ctx);
+  grub_disk_close (parent);
+
+  if (! ctx.partition_name)
+    {
+      *device = dname;
+      return;
+    }
+
+  *device = grub_xasprintf ("%s,%s", dname,
+                           ctx.partition_name);
+  grub_free (ctx.partition_name);
+  grub_free (dname);
+}
index 353f679e60c54902712f916327ca9397ecf0eada..14b8752ece2e91693ca7836a71a51b127db5c012 100644 (file)
@@ -36,9 +36,3 @@ grub_get_rtc (void)
 
   return (((grub_uint64_t) high) << 32) | low;
 }
-
-void
-grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
-                              char **path __attribute__ ((unused)))
-{
-}
index 756439b13d3d63d2b2f3eb7f376305923e5a3d60..1abcf1ab416b042f4feb9420d8a136b18f1a8ac0 100644 (file)
@@ -259,6 +259,12 @@ grub_exit (void)
   grub_halt ();
 }
 
+void
+grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
+                              char **path __attribute__ ((unused)))
+{
+}
+
 extern char _end[];
 grub_addr_t grub_modbase = (grub_addr_t) _end;
 
index aa414ebc7f071171e48434bf3f89aa099bb00b53..050f19f6a3533f97c8b6b83537e4017428fe1ab7 100644 (file)
@@ -98,6 +98,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
   return GRUB_ERR_NONE;
 }
 
+void
+grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
+                              char **path __attribute__ ((unused)))
+{
+}
+
 extern char _end[];
 grub_addr_t grub_modbase = (grub_addr_t) _end;
 
index cc072c2ae12ac4a368359d92d0e18c0e94f15bf9..f2b24b4d5baa9d3407dd3d10557df9ceeb01e82e 100644 (file)
@@ -489,7 +489,7 @@ if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_are
    grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img"
 fi
 
-make_image "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
+make_image_fwdisk "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" ""
 if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then
    grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img  /boot/grub/mips-arc/sash=${iso9660_dir}/boot/grub/mips-arc/core.img"
 fi
@@ -497,7 +497,7 @@ if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arc
    grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/sash -mips-boot /boot/grub/mips-arc/grub"
 fi
 
-make_image "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
+make_image_fwdisk "${arc_dir}" mipsel-arc "${iso9660_dir}/boot/grub/arc.exe" ""
 
 make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" "pata"
 if [ -e "${iso9660_dir}/boot/grub/roms/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then