All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tristan Gingold <tgingold@free.fr>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: IA64 port
Date: Tue, 29 Jan 2008 06:49:31 +0100	[thread overview]
Message-ID: <20080129054931.GA12985@saphi> (raw)
In-Reply-To: <20080128165504.GB9715@thorin>

[-- Attachment #1: Type: text/plain, Size: 224 bytes --]

Hi,

here is my new version of the patch.  I think all the comments have been
addressed.
(There are still // comments in the .S files I copied from glibc.  I suppose
this is OK as the files come as-is from glibc).

Tristan.

[-- Attachment #2: grub.diffs2 --]
[-- Type: text/plain, Size: 132010 bytes --]

2008-01-28  Tristan Gingold  <gingold@free.fr>

	* geninit.sh: Call _init with a null argument.

	* configure.ac: Add ia64-efi target.

	* Makefile.in (STRIP_FLAGS): Declare (overriden on ia64).
	(RMKFILES): Use a wildcard.
	
	* genmk.rb: Use STRIP_FLAGS for strip.

	* util/ia64/efi/grub-install.in: New file.

	* util/ia64/efi/pe32.h: New file.

	* util/ia64/efi/elf2pe.c: New file.

	* normal/ia64/setjmp.S: New file (from glibc).

	* normal/ia64/longjmp.S: New file (from glibc).

	* loader/ia64/efi/linux_normal.c: New file.

	* loader/ia64/efi/linux.c: New file.

	* conf/ia64-efi.rmk: New file.

	* commands/efi/systab.c: New file.

	* commands/efi/memmap.c: New file.

	* commands/efi/acpi.c: New file.

	* fs/fat.c (grub_fat_find_dir): Use case insensitive string
	compare as filenames are not case sensitive.

	* include/grub/efi/efi.h: Declare grub_efi_allocate_boot_pages and
	grub_efi_free_boot_pages.

	* include/grub/misc.h: Declare grub_strcasecmp.

	* include/grub/kernel.h: Export grub_machine_fini.

	* include/grub/dl.h: Use attribute instead of raw asm statement.
	Use grub_module as prefix to make identification easier.

	* include/grub/ia64/efi/time.h: New file.

	* include/grub/ia64/efi/misc.h: New file.

	* include/grub/ia64/efi/loader.h: New file.

	* include/grub/ia64/efi/kernel.h: New file.

	* include/grub/ia64/time.h: New file.

	* include/grub/ia64/setjmp.h: New file.

	* include/grub/ia64/types.h: New file.

	* kern/efi/mm.c (BYTES_TO_PAGES): Round instead of truncating.
	(grub_efi_allocate_boot_pages): Low level interface to allocate_pages.
	(grub_efi_free_boot_pages): Low level interface to free_pages.
	(grub_efi_allocate_pages): Call grub_efi_allocate_boot_pages.
	(grub_efi_free_pages): Call grubèefi_free_boot_pages.
	(add_memory_regions): Add debug message in ifdef.
	(add_memory_regions): Add debug message in ifdef.
	(grub_efi_mm_init): Do not constraint memory map length, add space for
	a few more entries.

	* kern/misc.c (grub_strcasecmp): New function.

	* kern/dl.c (grub_init_module): New function.  Register an already
	linked module.

	* kern/ia64/efi/elf_ia64_efi.lds: New file.

	* kern/ia64/efi/startup.S: New file.

	* kern/ia64/efi/init.c: New file.

	* kern/ia64/trampoline.S: New file.

diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/Makefile.in grub2/Makefile.in
--- grub2.orig/Makefile.in	2008-01-08 11:00:42.000000000 +0100
+++ grub2/Makefile.in	2008-01-29 06:21:37.000000000 +0100
@@ -67,6 +67,7 @@ TARGET_CFLAGS = @TARGET_CFLAGS@
 TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I. -Iinclude -I$(srcdir)/include \
 	-Wall -W
 TARGET_LDFLAGS = @TARGET_LDFLAGS@
+STRIP_FLAGS=--strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment 
 OBJCOPY = @OBJCOPY@
 STRIP = @STRIP@
 NM = @NM@
@@ -82,8 +83,7 @@ enable_grub_emu = @enable_grub_emu@
 
 ### General variables.
 
-RMKFILES = $(addprefix conf/,common.rmk i386-pc.rmk powerpc-ieee1275.rmk \
-	sparc64-ieee1275.rmk i386-efi.rmk)
+RMKFILES = $(wildcard $(srcdir)/conf/*.rmk)
 MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
 
 PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \
@@ -97,13 +97,13 @@ MOSTLYCLEANFILES = 
 DISTCLEANFILES = config.status config.cache config.log config.h \
 	Makefile stamp-h include/grub/cpu include/grub/machine \
 	gensymlist.sh genkernsyms.sh
-MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES))
+MAINTAINER_CLEANFILES = $(srcdir)/configure $(MKFILES)
 
 # The default target.
 all: all-local
 
 ### Include an arch-specific Makefile.
-$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb
+$(MKFILES): %.mk: %.rmk genmk.rb
 	if test "x$(RUBY)" = x; then \
 	  touch $@; \
 	else \
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/acpi.c grub2/commands/efi/acpi.c
--- grub2.orig/commands/efi/acpi.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/acpi.c	2008-01-29 06:27:02.000000000 +0100
@@ -0,0 +1,190 @@
+/* acpi.c  - Display acpi tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+
+static grub_uint32_t read16 (grub_uint8_t *p)
+{
+  return grub_le_to_cpu16 (*(grub_uint16_t *)p);
+}
+
+static grub_uint32_t read32 (grub_uint8_t *p)
+{
+  return grub_le_to_cpu32 (*(grub_uint32_t *)p);
+}
+
+static grub_uint64_t read64 (grub_uint8_t *p)
+{
+  return grub_le_to_cpu64 (*(grub_uint64_t *)p);
+}
+
+static void
+disp_acpi_table (grub_uint8_t *t)
+{
+  int i;
+  grub_printf ("%c%c%c%c %4dB rev=%d OEM=", t[0], t[1], t[2], t[3],
+	       read32 (t + 4), t[8]);
+  for (i = 0; i < 6; i++)
+    grub_printf ("%c", t[10 + i]);
+  grub_printf (" ");
+  for (i = 0; i < 8; i++)
+    grub_printf ("%c", t[16 + i]);
+  grub_printf (" V=%08lx ", read32 (t + 24));
+  for (i = 0; i < 4; i++)
+    grub_printf ("%c", t[28 + i]);
+  grub_printf (" %08lx\n", read32 (t + 32));
+
+}
+
+static void
+disp_acpi_apic_table (grub_uint8_t *t)
+{
+  grub_uint8_t *d;
+  grub_uint32_t len;
+  grub_uint32_t flags;
+
+  disp_acpi_table (t);
+  grub_printf ("Local APIC=%08lx  Flags=%08lx\n",
+	       read32 (t + 36), read32 (t + 40));
+  len = read32 (t + 4);
+  len -= 44;
+  d = t + 44;
+  while (len > 0)
+    {
+      grub_uint32_t l = d[1];
+      grub_printf ("  type=%x l=%d ", d[0], l);
+
+      switch (d[0])
+	{
+	case 2:
+	  grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x",
+		       d[2], d[3], read32 (d + 4), read16 (d + 8));
+	  break;
+	case 6:
+	  grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016llx",
+		       d[2], read32 (d + 4), read64 (d + 8));
+	  break;
+	case 7:
+	  flags = read32 (d + 8);
+	  grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
+		       d[2], d[3], d[4], flags);
+	  if (flags & 1)
+	    grub_printf (" Enabled");
+	  else
+	    grub_printf (" Disabled");
+	  if (l >= 17)
+	    grub_printf ("\n"
+			 "    UID val=%08x, Str=%s", read32 (d + 12), d + 16);
+	  break;
+	case 8:
+	  grub_printf ("Platform INT flags=%04x type=%02x (",
+		       read16 (d + 2), d[4]);
+	  if (d[4] <= 3)
+	    {
+	      static const char * const platint_type[4] =
+		{"Nul", "PMI", "INIT", "CPEI"};
+	      grub_printf ("%s", platint_type[d[4]]);
+	    }
+	  else
+	    grub_printf ("??");
+	  grub_printf (") ID=%02x EID=%02x\n", d[5], d[6]);
+	  grub_printf ("      IOSAPIC Vec=%02x GSI=%08x source flags=%08x",
+		       d[7], read32 (d + 8), read32 (d + 12));
+	  break;
+	default:
+	  grub_printf (" ??");
+	}
+      grub_printf ("\n");
+      d += l;
+      len -= l;
+    }
+}
+
+static void
+disp_acpi_xsdt_table (grub_uint8_t *t)
+{
+  grub_uint32_t len;
+  grub_uint8_t *desc;
+
+  disp_acpi_table (t);
+  len = read32 (t + 4) - 36;
+  desc = t + 36;
+  while (len > 0)
+    {
+      t = read64 (desc);
+	  
+      if (t[0] == 'A' && t[1] == 'P' && t[2] == 'I' && t[3] == 'C')
+	disp_acpi_apic_table (t);
+      else
+	disp_acpi_table (t);
+      desc += 8;
+      len -= 8;
+    }
+}
+
+static void
+disp_acpi_rsdt_table (grub_uint8_t *t)
+{
+  grub_uint32_t len;
+  grub_uint8_t *desc;
+
+  disp_acpi_table (t);
+  len = read32 (t + 4) - 36;
+  desc = t + 36;
+  while (len > 0)
+    {
+      t = read32 (desc);
+	  
+      if (t != NULL)
+	disp_acpi_table (t);
+      desc += 4;
+      len -= 4;
+    }
+}
+
+void
+disp_acpi_rsdp_table (grub_uint8_t *rsdp)
+{
+  grub_uint8_t *t = rsdp;
+  int i;
+  grub_uint8_t *xsdt;
+
+  grub_printf ("RSDP signature:");
+  for (i = 0; i < 8; i++)
+    grub_printf ("%c", t[i]);
+  grub_printf (" chksum:%02x, OEM-ID: ", t[8]);
+  for (i = 0; i < 6; i++)
+    grub_printf ("%c", t[9 + i]);
+  grub_printf (" rev=%d\n", t[15]);
+  grub_printf ("RSDT=%08lx", read32 (t + 16));
+  if (t[15] == 2)
+    {
+      xsdt = read64 (t + 24);
+      grub_printf (" len=%d XSDT=%016llx\n", read32 (t + 20), xsdt);
+      grub_printf ("\n");
+      disp_acpi_xsdt_table (xsdt);
+    }
+  else
+    {
+      grub_printf ("\n");
+      disp_acpi_rsdt_table (read32 (t + 16));
+    }
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/memmap.c grub2/commands/efi/memmap.c
--- grub2.orig/commands/efi/memmap.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/memmap.c	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,143 @@
+/* memmap.c  - Display memory map.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#define ADD_MEMORY_DESCRIPTOR(desc, size)	\
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_err_t
+grub_cmd_memmap (struct grub_arg_list *state, int argc, char **args)
+{
+  grub_efi_uintn_t map_size;
+  grub_efi_memory_descriptor_t *memory_map;
+  grub_efi_memory_descriptor_t *memory_map_end;
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_uintn_t desc_size;
+
+  map_size = 0;
+  if (grub_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0)
+    return 0;
+
+  memory_map = grub_malloc (map_size);
+  if (memory_map == NULL)
+    return 0;
+  if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) < 0)
+    goto fail;
+
+  grub_set_more (1);
+
+  grub_printf
+    ("Type      Physical start  - end             #Pages   "
+     "  Size Attributes\n");
+  memory_map_end = ADD_MEMORY_DESCRIPTOR(memory_map, map_size);
+  for (desc = memory_map;
+       desc < memory_map_end;
+       desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_efi_uintn_t size;
+      grub_efi_uint64_t attr;
+      static const char types_str[][9] = 
+	{
+	  "reserved", 
+	  "ldr-code",
+	  "ldr-data",
+	  "BS-code ",
+	  "BS-data ",
+	  "RT-code ",
+	  "RT-data ",
+	  "conv-mem",
+	  "unusable",
+	  "ACPI-rec",
+	  "ACPI-nvs",
+	  "MMIO    ",
+	  "IO-ports",
+	  "PAL-code"
+	};
+      if (desc->type < sizeof (types_str) / sizeof (types_str[0]))
+	grub_printf ("%s ", types_str[desc->type]);
+      else
+	grub_printf ("Unk %02x   ", desc->type);
+      
+      grub_printf (" %016llx-%016llx %08lx",
+		   desc->physical_start,
+		   desc->physical_start + (desc->num_pages << 12) - 1,
+		   desc->num_pages);
+
+      size = desc->num_pages << (12 - 10);
+      if (size < 1024)
+	grub_printf (" %4uKB", size);
+      else
+	{
+	  size /= 1024;
+	  if (size < 1024)
+	    grub_printf (" %4uMB", size);
+	  else
+	    {
+	      size /= 1024;
+	      grub_printf (" %4uGB", size);
+	    }
+	}
+
+      attr = desc->attribute;
+      if (attr & GRUB_EFI_MEMORY_RUNTIME)
+	grub_printf (" RT");
+      if (attr & GRUB_EFI_MEMORY_UC)
+	grub_printf (" UC");
+      if (attr & GRUB_EFI_MEMORY_WC)
+	grub_printf (" WC");
+      if (attr & GRUB_EFI_MEMORY_WT)
+	grub_printf (" WT");
+      if (attr & GRUB_EFI_MEMORY_WB)
+	grub_printf (" WB");
+      if (attr & GRUB_EFI_MEMORY_UCE)
+	grub_printf (" UCE");
+      if (attr & GRUB_EFI_MEMORY_WP)
+	grub_printf (" WP");
+      if (attr & GRUB_EFI_MEMORY_RP)
+	grub_printf (" RP");
+      if (attr & GRUB_EFI_MEMORY_XP)
+	grub_printf (" XP");
+
+      grub_printf ("\n");
+    }
+
+  grub_set_more (0);
+
+ fail:
+  grub_free (memory_map);
+  return 0;
+}
+
+GRUB_MOD_INIT(memmap)
+{
+  (void)mod;			/* To stop warning. */
+  grub_register_command ("memmap", grub_cmd_memmap, GRUB_COMMAND_FLAG_BOTH,
+			 "memmap",
+			 "Display memory map.", NULL);
+}
+
+GRUB_MOD_FINI(memmap)
+{
+  grub_unregister_command ("memmap");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/commands/efi/systab.c grub2/commands/efi/systab.c
--- grub2.orig/commands/efi/systab.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/commands/efi/systab.c	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,258 @@
+/* systab.c  - Display EFI systab.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#define ACPI_20_TABLE_GUID \
+{0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x0,0x80,0xc7,0x3c,0x88,0x81}}
+#define ACPI_TABLE_GUID \
+{0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define SAL_SYSTEM_TABLE_GUID \
+{0xeb9d2d32,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define SMBIOS_TABLE_GUID \
+{0xeb9d2d31,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define MPS_TABLE_GUID \
+{0xeb9d2d2f,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define HCDP_TABLE_GUID \
+{0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
+
+struct guid_mapping
+{
+  grub_efi_guid_t guid;
+  const char *name;
+  void (*disp)(struct guid_mapping *map, void *table);
+};
+
+static void disp_sal (struct guid_mapping *map, void *table);
+static void disp_acpi (struct guid_mapping *map, void *table);
+
+static const struct guid_mapping guid_mappings[] =
+  {
+    { ACPI_20_TABLE_GUID, "ACPI-2.0", disp_acpi},
+    { ACPI_TABLE_GUID, "ACPI-1.0", disp_acpi},
+    { SAL_SYSTEM_TABLE_GUID, "SAL", disp_sal},
+    { SMBIOS_TABLE_GUID, "SMBIOS",NULL},
+    { MPS_TABLE_GUID, "MPS", NULL},
+    { HCDP_TABLE_GUID, "HCDP", NULL}
+  };
+
+struct sal_system_table
+{
+  grub_uint32_t signature;
+  grub_uint32_t total_table_len;
+  grub_uint16_t sal_rev;
+  grub_uint16_t entry_count;
+  grub_uint8_t checksum;
+  grub_uint8_t reserved1[7];
+  grub_uint16_t sal_a_version;
+  grub_uint16_t sal_b_version;
+  grub_uint8_t oem_id[32];
+  grub_uint8_t product_id[32];
+  grub_uint8_t reserved2[8];
+};
+
+static void
+disp_sal (struct guid_mapping *map, void *table)
+{
+  struct sal_system_table *t = table;
+  grub_uint8_t *desc = table;
+  grub_uint32_t len, l;
+
+  grub_printf ("SAL rev: %02x, signature: %x, len:%x\n",
+	       t->sal_rev, t->signature, t->total_table_len);
+  grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n",
+	       t->entry_count, t->checksum,
+	       t->sal_a_version, t->sal_b_version);
+  grub_printf ("OEM-ID: %-32s\n", t->oem_id);
+  grub_printf ("Product-ID: %-32s\n", t->product_id);
+
+  desc += sizeof (struct sal_system_table);
+  len = t->total_table_len - sizeof (struct sal_system_table);
+  while (len > 0)
+    {
+      switch (*desc)
+	{
+	case 0:
+	  l = 48;
+	  grub_printf (" Entry point: PAL=%016lx SAL=%016lx GP=%016lx\n",
+		       *(grub_uint64_t*)(desc + 8),
+		       *(grub_uint64_t*)(desc + 16),
+		       *(grub_uint64_t*)(desc + 24));
+	  break;
+	case 1:
+	  l = 32;
+	  grub_printf (" Memory descriptor entry addr=%016llx len=%uKB\n",
+		       *(grub_uint64_t*)(desc + 8),
+		       *(grub_uint32_t*)(desc + 16) * 4);
+	  grub_printf ("     sal_used=%d attr=%x AR=%x attr_mask=%x "
+		       "type=%x usage=%x\n",
+		       desc[1], desc[2], desc[3], desc[4], desc[5], desc[6]);
+	  break;
+	case 2:
+	  l = 16;
+	  grub_printf (" Platform features: %02x", desc[1]);
+	  if (desc[1] & 0x01)
+	    grub_printf (" BusLock");
+	  if (desc[1] & 0x02)
+	    grub_printf (" IrqRedirect");
+	  if (desc[1] & 0x04)
+	    grub_printf (" IPIRedirect");
+	  grub_printf ("\n");
+	  break;
+	case 3:
+	  l = 32;
+	  grub_printf (" TR type=%d num=%d va=%016llx pte=%016llx\n",
+		       desc[1], desc[2],
+		       *(grub_uint64_t *)(desc + 8),
+		       *(grub_uint64_t *)(desc + 16));
+	  break;
+	case 4:
+	  l = 16;
+	  grub_printf (" PTC coherence nbr=%d addr=%016llx\n",
+		       desc[1], *(grub_uint64_t *)(desc + 8));
+	  break;
+	case 5:
+	  l = 16;
+	  grub_printf (" AP wake-up: mec=%d vect=%x\n",
+		       desc[1], *(grub_uint64_t *)(desc + 8));
+	  break;
+	default:
+	  grub_printf (" unknown entry %d\n", *desc);
+	  return;
+	}
+      desc += l;
+      len -= l;
+    }
+}
+
+static void
+disp_acpi (struct guid_mapping *map, void *table)
+{
+  disp_acpi_rsdp_table (table);
+}
+
+static void
+disp_systab (void)
+{
+  grub_efi_char16_t *vendor;
+  const grub_efi_system_table_t *st = grub_efi_system_table;
+  grub_efi_configuration_table_t *t;
+  unsigned int i;
+
+  grub_printf ("Signature: %016llx revision: %08x\n",
+	       st->hdr.signature, st->hdr.revision);
+  grub_printf ("Vendor: ");
+  for (vendor = st->firmware_vendor; *vendor; vendor++)
+    grub_printf ("%c", *vendor);
+  grub_printf (", Version=%x\n", st->firmware_revision);
+
+  grub_printf ("%ld tables:\n", st->num_table_entries);
+  t = st->configuration_table;
+  for (i = 0; i < st->num_table_entries; i++)
+    {
+      unsigned int j;
+
+      grub_printf ("%016llx  ", (grub_uint64_t)t->vendor_table);
+
+      grub_printf ("%08x-%04x-%04x-",
+		   t->vendor_guid.data1, t->vendor_guid.data2,
+		   t->vendor_guid.data3);
+      for (j = 0; j < 8; j++)
+	grub_printf ("%02x", t->vendor_guid.data4[j]);
+      
+      for (j = 0; j < sizeof (guid_mappings)/sizeof(guid_mappings[0]); j++)
+	if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid,
+			 sizeof (grub_efi_guid_t)) == 0)
+	  grub_printf ("   %s", guid_mappings[j].name);
+
+      grub_printf ("\n");
+      t++;
+    }
+}
+
+static void
+disp_systab_entry (const char *name)
+{
+  const grub_efi_system_table_t *st = grub_efi_system_table;
+  grub_efi_configuration_table_t *t;
+  unsigned int i;
+  struct guid_mapping *map;
+
+  map = NULL;
+  for (i = 0; i < sizeof (guid_mappings)/sizeof(guid_mappings[0]); i++)
+    if (grub_strcmp (guid_mappings[i].name, name) == 0)
+      {
+	map = &guid_mappings[i];
+	break;
+      }
+  if (map == NULL)
+    {
+      grub_printf ("System table '%s' unknown\n", name);
+      return;
+    }
+  if (map->disp == NULL)
+    {
+      grub_printf ("Don't know how to display table '%s'\n", name);
+      return;
+    }
+  t = st->configuration_table;
+  for (i = 0; i < st->num_table_entries; i++)
+    {
+      if (grub_memcmp (&map->guid, &t->vendor_guid,
+		       sizeof (grub_efi_guid_t)) == 0)
+	{
+	  grub_set_more (1);
+	  (*map->disp)(map, t->vendor_table);
+	  grub_set_more (0);
+	  return;
+	}
+      t++;
+    }
+  grub_printf ("Systab '%s' not found\n", map->name);
+}
+
+static grub_err_t
+grub_cmd_systab (struct grub_arg_list *state, int argc, char **args)
+{
+  int i;
+
+  if (argc == 0)
+    disp_systab ();
+  else
+    for (i = 0; i < argc; i++)
+      disp_systab_entry (args[i]);
+  return 0;
+}
+
+GRUB_MOD_INIT(systab)
+{
+  (void)mod;			/* To stop warning. */
+  grub_register_command ("systab", grub_cmd_systab, GRUB_COMMAND_FLAG_BOTH,
+			 "systab [NAME]",
+			 "Display EFI system table.", NULL);
+}
+
+GRUB_MOD_FINI(systab)
+{
+  grub_unregister_command ("systab");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/conf/ia64-efi.rmk grub2/conf/ia64-efi.rmk
--- grub2.orig/conf/ia64-efi.rmk	1970-01-01 01:00:00.000000000 +0100
+++ grub2/conf/ia64-efi.rmk	2008-01-29 06:39:34.000000000 +0100
@@ -0,0 +1,127 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin
+COMMON_CFLAGS = -fno-builtin -fpic -minline-int-divide-max-throughput
+COMMON_LDFLAGS = -melf_64 -nostdlib 
+
+STRIP_FLAGS=-R .note -R .comment -X
+
+# Utilities.
+bin_UTILITIES = grub-elf2pe
+#sbin_UTILITIES = grub-emu
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/ia64/efi/grub-install.in
+
+pkgdata_DATA += kern/ia64/efi/elf_ia64_efi.lds
+
+# For grub-elf2pe
+grub_elf2pe_SOURCES = util/ia64/efi/elf2pe.c
+grub_elf2pe_CFLAGS = -DELF2PE_IA64
+
+# For grub-emu.
+grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/help.c				\
+	commands/terminal.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c				\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/jfs.c fs/minix.c			\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/xfs.c						\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c 	\
+	normal/execute.c kern/file.c kern/fs.c normal/lexer.c 		\
+	kern/loader.c kern/main.c kern/misc.c kern/parser.c		\
+	grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c	\
+	normal/arg.c normal/cmdline.c normal/command.c normal/function.c\
+	normal/completion.c normal/main.c				\
+	normal/menu.c normal/menu_entry.c normal/misc.c normal/script.c	\
+	partmap/amiga.c	partmap/apple.c partmap/pc.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/grub-emu.c util/misc.c			\
+	util/i386/pc/misc.c grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Modules.
+pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod \
+	_linux.mod linux.mod memmap.mod systab.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/ia64/efi/startup.S \
+	kern/ia64/trampoline.S \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
+	kern/i386/dl.c kern/ia64/efi/init.c kern/parser.c kern/partition.c \
+	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+	term/efi/console.c disk/efi/efidisk.c
+kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
+	file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
+	pc_partition.h rescue.h symbol.h term.h types.h cache.h \
+	i386/efi/time.h efi/efi.h efi/time.h efi/disk.h ia64/efi/misc.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For normal.mod.
+normal_mod_DEPENDENCIES = grub_script.tab.c grub_script.tab.h
+normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c	\
+	normal/completion.c normal/execute.c 		\
+	normal/function.c normal/lexer.c normal/main.c normal/menu.c	\
+	normal/menu_entry.c normal/misc.c grub_script.tab.c 		\
+	normal/script.c \
+	normal/ia64/setjmp.S normal/ia64/longjmp.S normal/color.c
+
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _chain.mod.
+_chain_mod_SOURCES = loader/efi/chainloader.c
+_chain_mod_CFLAGS = $(COMMON_CFLAGS)
+_chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader_normal.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _linux.mod.
+_linux_mod_SOURCES = loader/ia64/efi/linux.c
+_linux_mod_CFLAGS = $(COMMON_CFLAGS)
+_linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/ia64/efi/linux_normal.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memmap.mod.
+memmap_mod_SOURCES = commands/efi/memmap.c
+memmap_mod_CFLAGS = $(COMMON_CFLAGS)
+memmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For systab.mod.
+systab_mod_SOURCES = commands/efi/systab.c commands/efi/acpi.c
+systab_mod_CFLAGS = $(COMMON_CFLAGS)
+systab_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/config.h.in grub2/config.h.in
--- grub2.orig/config.h.in	2008-01-15 21:05:44.000000000 +0100
+++ grub2/config.h.in	2008-01-29 06:38:00.000000000 +0100
@@ -88,10 +88,10 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* The size of `long', as computed by sizeof. */
+/* The size of a `long', as computed by sizeof. */
 #undef SIZEOF_LONG
 
-/* The size of `void *', as computed by sizeof. */
+/* The size of a `void *', as computed by sizeof. */
 #undef SIZEOF_VOID_P
 
 /* Define it to either start or _start */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/configure.ac grub2/configure.ac
--- grub2.orig/configure.ac	2008-01-15 21:05:44.000000000 +0100
+++ grub2/configure.ac	2008-01-28 16:29:57.000000000 +0100
@@ -53,7 +53,8 @@ case "$target_cpu" in
   powerpc) ;;
   powerpc64) target_cpu=powerpc target_m32=1;;
   sparc64) ;;
-  *) AC_MSG_ERROR([unsupported CPU type]) ;;
+  ia64) ;;
+  *) AC_MSG_ERROR([unsupported CPU type $target_cpu]) ;;
 esac
 
 # Specify the platform (such as firmware).
@@ -68,6 +69,7 @@ if test "x$with_platform" = x; then
     i386-*) platform=pc ;;
     powerpc-*) platform=ieee1275 ;;
     sparc64-*) platform=ieee1275 ;;
+    ia64*) platform=efi ;;
     *) AC_MSG_ERROR([unsupported machine type]) ;;
   esac
 else
@@ -82,6 +84,7 @@ case "$target_cpu"-"$platform" in
   i386-ieee1275) ;;
   powerpc-ieee1275) ;;
   sparc64-ieee1275) ;;
+  ia64-efi) ;;
   *) AC_MSG_ERROR([unsupported machine type]) ;;
 esac
 
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/fs/fat.c grub2/fs/fat.c
--- grub2.orig/fs/fat.c	2007-08-02 20:40:36.000000000 +0200
+++ grub2/fs/fat.c	2008-01-28 16:29:57.000000000 +0100
@@ -568,7 +568,7 @@ grub_fat_find_dir (grub_disk_t disk, str
 		  continue;
 		}
 
-	      if (grub_strcmp (dirname, filename) == 0)
+	      if (grub_strcasecmp (dirname, filename) == 0)
 		{
 		  if (call_hook)
 		    hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
@@ -601,7 +601,7 @@ grub_fat_find_dir (grub_disk_t disk, str
 	  if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY))
 	    break;
 	}
-      else if (grub_strcmp (dirname, filename) == 0)
+      else if (grub_strcasecmp (dirname, filename) == 0)
 	{
 	  if (call_hook)
 	    hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/geninit.sh grub2/geninit.sh
--- grub2.orig/geninit.sh	2007-07-22 21:17:21.000000000 +0200
+++ grub2/geninit.sh	2008-01-28 16:29:57.000000000 +0100
@@ -49,7 +49,7 @@ EOF
 while read line; do
   file=`echo $line | cut -f1 -d:`
   if echo $@ | grep $file >/dev/null; then
-    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_init ();/'
+    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_init (0);/'
   fi
 done < ${lst}
 
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/genmk.rb grub2/genmk.rb
--- grub2.orig/genmk.rb	2008-01-25 23:33:56.000000000 +0100
+++ grub2/genmk.rb	2008-01-28 16:29:57.000000000 +0100
@@ -115,7 +115,7 @@ UNDSYMFILES += #{undsym}
 #{@name}: #{pre_obj} #{mod_obj}
 	-rm -f $@
 	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
-	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+	$(STRIP) $(STRIP_FLAGS) $@
 
 #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
 	-rm -f $@
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/dl.h grub2/include/grub/dl.h
--- grub2.orig/include/grub/dl.h	2007-07-22 01:32:21.000000000 +0200
+++ grub2/include/grub/dl.h	2008-01-28 16:29:57.000000000 +0100
@@ -26,25 +26,27 @@
 
 #define GRUB_MOD_INIT(name)	\
 static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
-void grub_##name##_init (void); \
+void grub_module_##name##_init (grub_dl_t); \
 void \
-grub_##name##_init (void) { grub_mod_init (0); } \
+grub_module_##name##_init (grub_dl_t mod) { grub_mod_init (mod); } \
 static void \
 grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
 
 #define GRUB_MOD_FINI(name)	\
 static void grub_mod_fini (void) __attribute__ ((used)); \
-void grub_##name##_fini (void); \
+void grub_module_##name##_fini (void); \
 void \
-grub_##name##_fini (void) { grub_mod_fini (); } \
+grub_module_##name##_fini (void) { grub_mod_fini (); } \
 static void \
 grub_mod_fini (void)
 
 #define GRUB_MOD_NAME(name)	\
-__asm__ (".section .modname,\"S\"\n.string \"" #name "\"\n.previous")
+static const char grub_module_name_##name[] \
+  __attribute__((section(".modname"), __used__)) = #name
 
 #define GRUB_MOD_DEP(name)	\
-__asm__ (".section .moddeps,\"S\"\n.string \"" #name "\"\n.previous")
+static const char grub_module_depend_##name[] \
+  __attribute__((section(".moddeps"), __used__)) = #name
 
 struct grub_dl_segment
 {
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/efi/efi.h grub2/include/grub/efi/efi.h
--- grub2.orig/include/grub/efi/efi.h	2007-07-22 01:32:23.000000000 +0200
+++ grub2/include/grub/efi/efi.h	2008-01-28 16:29:57.000000000 +0100
@@ -42,6 +42,13 @@ EXPORT_FUNC(grub_efi_allocate_pages) (gr
 				      grub_efi_uintn_t pages);
 void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
 				       grub_efi_uintn_t pages);
+void *
+EXPORT_FUNC(grub_efi_allocate_boot_pages) (grub_efi_physical_address_t address,
+					   grub_efi_uintn_t pages);
+void
+EXPORT_FUNC(grub_efi_free_boot_pages) (grub_efi_physical_address_t address,
+				       grub_efi_uintn_t pages);
+
 int
 EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
 				      grub_efi_memory_descriptor_t *memory_map,
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/kernel.h grub2/include/grub/ia64/efi/kernel.h
--- grub2.orig/include/grub/ia64/efi/kernel.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/kernel.h	2008-01-29 05:42:30.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER   1
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/loader.h grub2/include/grub/ia64/efi/loader.h
--- grub2.orig/include/grub/ia64/efi/loader.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/loader.h	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+/* It is necessary to export these functions, because normal mode commands
+   reuse rescue mode commands.  */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+void grub_rescue_cmd_module (int argc, char *argv[]);
+void grub_rescue_cmd_relocate (int argc, char *argv[]);
+void grub_rescue_cmd_fpswa (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/misc.h grub2/include/grub/ia64/efi/misc.h
--- grub2.orig/include/grub/ia64/efi/misc.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/misc.h	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void EXPORT_FUNC (memset) (void);
+void EXPORT_FUNC (__ia64_trampoline) (void);
+void EXPORT_FUNC (grub_init_modules) (void);
+
+extern unsigned long EXPORT_VAR (__gp);
+
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/efi/time.h grub2/include/grub/ia64/efi/time.h
--- grub2.orig/include/grub/ia64/efi/time.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/efi/time.h	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER	1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/setjmp.h grub2/include/grub/ia64/setjmp.h
--- grub2.orig/include/grub/ia64/setjmp.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/setjmp.h	2008-01-29 06:45:08.000000000 +0100
@@ -0,0 +1,31 @@
+/* Define the machine-dependent type `jmp_buf'.  Linux/IA-64 version.
+   Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc.
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* User code must not depend on the internal representation of jmp_buf. */
+
+#define _JBLEN	70
+
+/* the __jmp_buf element type should be __float80 per ABI... */
+typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */
+
+#define grub_setjmp setjmp
+#define grub_longjmp longjmp
+
+int grub_setjmp (grub_jmp_buf env);
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/time.h grub2/include/grub/ia64/time.h
--- grub2.orig/include/grub/ia64/time.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/time.h	2008-01-29 06:45:15.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/ia64/types.h grub2/include/grub/ia64/types.h
--- grub2.orig/include/grub/ia64/types.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/include/grub/ia64/types.h	2008-01-28 16:29:57.000000000 +0100
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		8
+
+/* ia64 is little-endian (usually).  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/kernel.h grub2/include/grub/kernel.h
--- grub2.orig/include/grub/kernel.h	2008-01-21 01:04:04.000000000 +0100
+++ grub2/include/grub/kernel.h	2008-01-28 16:29:57.000000000 +0100
@@ -53,7 +53,7 @@ void grub_main (void);
 void grub_machine_init (void);
 
 /* The machine-specific finalization.  */
-void grub_machine_fini (void);
+void EXPORT_FUNC (grub_machine_fini) (void);
 
 /* The machine-specific prefix initialization.  */
 void grub_machine_set_prefix (void);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/include/grub/misc.h grub2/include/grub/misc.h
--- grub2.orig/include/grub/misc.h	2007-11-05 15:54:00.000000000 +0100
+++ grub2/include/grub/misc.h	2008-01-28 16:29:57.000000000 +0100
@@ -46,6 +46,7 @@ int EXPORT_FUNC(grub_memcmp) (const void
 int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
 int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
 int EXPORT_FUNC(grub_strncasecmp) (const char *s1, const char *s2, int c);
+int EXPORT_FUNC(grub_strcasecmp) (const char *s1, const char *s2);
 char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
 char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
 int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/dl.c grub2/kern/dl.c
--- grub2.orig/kern/dl.c	2008-01-26 21:34:58.000000000 +0100
+++ grub2/kern/dl.c	2008-01-28 16:29:58.000000000 +0100
@@ -579,6 +579,29 @@ grub_dl_load_core (void *addr, grub_size
   return mod;
 }
 
+void
+grub_init_module (const char *name,
+		  void (*init)(grub_dl_t), void (*fini)(void))
+{
+  grub_dl_t mod;
+
+  mod = (grub_dl_t) grub_malloc (sizeof (*mod));
+  if (! mod)
+    return;
+
+  mod->name = name;
+  mod->ref_count = 1;
+  mod->dep = 0;
+  mod->segment = 0;
+  mod->init = init;
+  mod->fini = fini;
+
+  grub_dl_call_init (mod);
+
+  /* Can't fail.  */
+  grub_dl_add (mod);
+}
+
 /* Load a module from the file FILENAME.  */
 grub_dl_t
 grub_dl_load_file (const char *filename)
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/efi/mm.c grub2/kern/efi/mm.c
--- grub2.orig/kern/efi/mm.c	2007-07-22 01:32:26.000000000 +0200
+++ grub2/kern/efi/mm.c	2008-01-28 16:29:58.000000000 +0100
@@ -22,16 +22,14 @@
 #include <grub/efi/api.h>
 #include <grub/efi/efi.h>
 
+//#define DEBUG_MM
+
 #define NEXT_MEMORY_DESCRIPTOR(desc, size)	\
   ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
 
-#define BYTES_TO_PAGES(bytes)	((bytes) >> 12)
+#define BYTES_TO_PAGES(bytes)	((bytes + 0xfff) >> 12)
 #define PAGES_TO_BYTES(pages)	((pages) << 12)
 
-/* The size of a memory map obtained from the firmware. This must be
-   a multiplier of 4KB.  */
-#define MEMORY_MAP_SIZE	0x1000
-
 /* Maintain the list of allocated pages.  */
 struct allocated_page
 {
@@ -49,11 +47,10 @@ static struct allocated_page *allocated_
 #define MIN_HEAP_SIZE	0x100000
 #define MAX_HEAP_SIZE	(16 * 0x100000)
 
-
 /* Allocate pages. Return the pointer to the first of allocated pages.  */
 void *
-grub_efi_allocate_pages (grub_efi_physical_address_t address,
-			 grub_efi_uintn_t pages)
+grub_efi_allocate_boot_pages (grub_efi_physical_address_t address,
+			      grub_efi_uintn_t pages)
 {
   grub_efi_allocate_type_t type;
   grub_efi_status_t status;
@@ -87,14 +84,34 @@ grub_efi_allocate_pages (grub_efi_physic
     {
       /* Uggh, the address 0 was allocated... This is too annoying,
 	 so reallocate another one.  */
-      address = 0xffffffff;
       status = b->allocate_pages (type, GRUB_EFI_LOADER_DATA, pages, &address);
-      grub_efi_free_pages (0, pages);
+      grub_efi_free_boot_pages (0, pages);
       if (status != GRUB_EFI_SUCCESS)
 	return 0;
     }
       
-  if (allocated_pages)
+  return (void *)address;
+}
+
+/* Free pages starting from ADDRESS.  */
+void
+grub_efi_free_boot_pages (grub_efi_physical_address_t address,
+			  grub_efi_uintn_t pages)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  b->free_pages (address, pages);
+}
+
+/* Allocate pages. Return the pointer to the first of allocated pages.  */
+void *
+grub_efi_allocate_pages (grub_efi_physical_address_t address,
+			 grub_efi_uintn_t pages)
+{
+  address = grub_efi_allocate_boot_pages (address, pages);
+
+  if (address != 0 && allocated_pages)
     {
       unsigned i;
 
@@ -118,8 +135,6 @@ void
 grub_efi_free_pages (grub_efi_physical_address_t address,
 		     grub_efi_uintn_t pages)
 {
-  grub_efi_boot_services_t *b;
-
   if (allocated_pages
       && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
 	  != address))
@@ -133,9 +148,8 @@ grub_efi_free_pages (grub_efi_physical_a
 	    break;
 	  }
     }
-  
-  b = grub_efi_system_table->boot_services;
-  b->free_pages (address, pages);
+
+  grub_efi_free_boot_pages (address, pages);
 }
 
 /* Get the memory map as defined in the EFI spec. Return 1 if successful,
@@ -278,7 +292,11 @@ add_memory_regions (grub_efi_memory_desc
 		    grub_efi_uint64_t required_pages)
 {
   grub_efi_memory_descriptor_t *desc;
-  
+
+#ifdef DEBUG_MM
+  grub_printf ("mm: required_pages=%lu\n", required_pages);
+#endif
+
   for (desc = memory_map;
        desc < memory_map_end;
        desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
@@ -303,6 +321,10 @@ add_memory_regions (grub_efi_memory_desc
 
       grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
 
+#ifdef DEBUG_MM
+      grub_printf ("mm: add %lu pages from %p\n", pages, addr);
+#endif
+
       required_pages -= pages;
       if (required_pages == 0)
 	break;
@@ -344,6 +366,8 @@ grub_efi_mm_init (void)
   grub_efi_uintn_t desc_size;
   grub_efi_uint64_t total_pages;
   grub_efi_uint64_t required_pages;
+  grub_efi_uintn_t memory_map_size;
+  int res;
 
   /* First of all, allocate pages to maintain allocations.  */
   allocated_pages
@@ -352,26 +376,35 @@ grub_efi_mm_init (void)
     grub_fatal ("cannot allocate memory");
 
   grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
-  
+
   /* Prepare a memory region to store two memory maps.  */
-  memory_map = grub_efi_allocate_pages (0,
-					2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+  memory_map_size = 0;
+  res = grub_efi_get_memory_map (&memory_map_size, NULL, 0, &desc_size, 0);
+  if (res != 0)
+    grub_fatal ("cannot get memory map size");
+
+  /* Add space for a few more entries as allocating pages can increase
+     memory map size.  */
+  memory_map_size += 4 * desc_size;
+
+  memory_map = grub_efi_allocate_pages
+    (0, 2 * BYTES_TO_PAGES (memory_map_size));
   if (! memory_map)
     grub_fatal ("cannot allocate memory");
 
-  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, memory_map_size);
 
   /* Obtain descriptors for available memory.  */
-  map_size = MEMORY_MAP_SIZE;
+  map_size = memory_map_size;
 
-  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) <= 0)
     grub_fatal ("cannot get memory map");
 
   memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
   
   filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
 					       desc_size, memory_map_end);
-  
+
   /* By default, request a quarter of the available memory.  */
   total_pages = get_total_pages (filtered_memory_map, desc_size,
 				 filtered_memory_map_end);
@@ -391,7 +424,7 @@ grub_efi_mm_init (void)
 
 #if 0
   /* For debug.  */
-  map_size = MEMORY_MAP_SIZE;
+  map_size = memory_map_size;
 
   if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
     grub_fatal ("cannot get memory map");
@@ -404,7 +437,7 @@ grub_efi_mm_init (void)
   
   /* Release the memory maps.  */
   grub_efi_free_pages ((grub_addr_t) memory_map,
-		       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+		       2 * BYTES_TO_PAGES (memory_map_size));
 }
 
 void
@@ -420,10 +453,13 @@ grub_efi_mm_fini (void)
 
 	  p = allocated_pages + i;
 	  if (p->addr != 0)
-	    grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+	    {
+	      grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+	    }
 	}
 
       grub_efi_free_pages ((grub_addr_t) allocated_pages,
 			   BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+      allocated_pages = 0;
     }
 }
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/elf_ia64_efi.lds grub2/kern/ia64/efi/elf_ia64_efi.lds
--- grub2.orig/kern/ia64/efi/elf_ia64_efi.lds	1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/elf_ia64_efi.lds	2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+OUTPUT_FORMAT("elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x240;
+ .text :
+ {
+  *(.text)
+  *(.text.*)
+  *(.rodata)
+  *(.rodata.*)
+ /* Reserve space for the entry point descriptor.  */
+  . = ALIGN(16);
+  QUAD(0)
+  QUAD(0)
+ }
+ . = ALIGN(0x20);
+ .got :
+ {
+  *(.got.plt)
+  *(.got)
+  . = ALIGN(0x10);
+ }
+ .opd :
+ {
+   *(.opd)
+ }
+ .sdata :
+ {
+  *(.srodata)
+  *(.sdata)
+  *(.sbss)
+  *(.scommon)
+  . = ALIGN(0x10);
+ }
+ .data :
+ {
+  *(.data*)
+  *(.dynbss)
+  *(.bss)
+  *(COMMON)
+  . = ALIGN(0x10);
+ }
+ .dynamic : { *(.dynamic) }
+
+ . = ALIGN(4096);
+ .interp : { *(.interp) }
+ .plt : { *(.plt) }
+ .rela :
+ {
+  *(.rela.text*)
+  *(.rela.data*)
+  *(.rela.sdata)
+  *(.rela.got)
+ }
+ .hash : { *(.hash) } 
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ /DISCARD/ :
+ {
+  *(.IA_64.unwind*)
+  *(.IA64.unwind*)
+  *(.moddeps)
+  *(.modname)
+ }
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/init.c grub2/kern/ia64/efi/init.c
--- grub2.orig/kern/ia64/efi/init.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/init.c	2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,59 @@
+/* init.c - initialize an ia64-based EFI system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+
+void
+grub_machine_init (void)
+{
+  grub_efi_init ();
+  grub_init_modules ();
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_efi_fini ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_efi_set_prefix ();
+}
+
+void
+grub_arch_sync_caches (void *address, grub_size_t len)
+{
+  /* Cache line length is at least 32.  */
+  grub_uint64_t a = (grub_uint64_t)address & ~0x1f;
+
+  /* Flush data.  */
+  for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20)
+    asm volatile ("fc.i %0" : : "r" (a));
+  /* Sync and serialize.  Maybe extra.  */
+  asm volatile (";; sync.i;; srlz.i;;");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/efi/startup.S grub2/kern/ia64/efi/startup.S
--- grub2.orig/kern/ia64/efi/startup.S	1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/efi/startup.S	2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+	.text
+	.psr abi64
+	.psr lsb
+	.lsb
+
+	.global _start
+	.proc _start
+_start:
+	alloc loc0=ar.pfs,2,4,0,0
+	mov loc1=rp
+	addl loc2=@gprel(grub_efi_image_handle),gp
+	addl loc3=@gprel(grub_efi_system_table),gp
+	;;
+	st8 [loc2]=in0
+	st8 [loc3]=in1
+	br.call.sptk.few rp=grub_main
+	;;
+	mov ar.pfs=loc0
+	mov rp=loc1
+	;;
+	br.ret.sptk.few rp
+
+	.endp _start
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/ia64/trampoline.S grub2/kern/ia64/trampoline.S
--- grub2.orig/kern/ia64/trampoline.S	1970-01-01 01:00:00.000000000 +0100
+++ grub2/kern/ia64/trampoline.S	2008-01-29 05:43:17.000000000 +0100
@@ -0,0 +1,38 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+	.text
+	.psr abi64
+	.psr lsb
+	.lsb
+	
+	.proc __ia64_trampoline
+	.global __ia64_trampoline
+__ia64_trampoline:
+	/* Read address of the real descriptor.  */
+	ld8 r2=[r1],8
+	;;
+	/* Read chain.  */
+	ld8 r15=[r1]
+	/* Read pc.  */
+	ld8 r3=[r2],8
+	;;
+	/* Read gp.  */
+	ld8 r1=[r2]
+	mov b6=r3
+	br.many b6
+	.endp __ia64_trampoline
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/kern/misc.c grub2/kern/misc.c
--- grub2.orig/kern/misc.c	2008-01-15 18:22:09.000000000 +0100
+++ grub2/kern/misc.c	2008-01-28 16:29:58.000000000 +0100
@@ -193,6 +193,26 @@ grub_strcmp (const char *s1, const char 
 }
 
 int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+  char c1, c2;
+
+  while (*s1 && *s2)
+    {
+      c1 = grub_tolower (*s1);
+      c2 = grub_tolower (*s2);
+      if (c1 != c2)
+	return (int) c1 - (int) c2;
+      
+      s1++;
+      s2++;
+    }
+
+  /* One of these is 0!  */
+  return (int) *s1 - (int) *s2;
+}
+
+int
 grub_strncmp (const char *s1, const char *s2, grub_size_t n)
 {
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/loader/ia64/efi/linux.c grub2/loader/ia64/efi/linux.c
--- grub2.orig/loader/ia64/efi/linux.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/ia64/efi/linux.c	2008-01-29 05:44:15.000000000 +0100
@@ -0,0 +1,780 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/rescue.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/cache.h>
+/* #include <grub/cpu/linux.h> */
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/gzio.h>
+
+#define ALIGN_MIN (256*1024*1024)
+
+#define GRUB_ELF_SEARCH 1024
+
+#define BOOT_PARAM_SIZE	16384
+
+struct ia64_boot_param
+{
+  grub_uint64_t command_line;	/* physical address of command line. */
+  grub_uint64_t efi_systab;	/* physical address of EFI system table */
+  grub_uint64_t efi_memmap;	/* physical address of EFI memory map */
+  grub_uint64_t efi_memmap_size;	/* size of EFI memory map */
+  grub_uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */
+  grub_uint32_t efi_memdesc_version;	/* memory descriptor version */
+  struct
+  {
+    grub_uint16_t num_cols;	/* number of columns on console output dev */
+    grub_uint16_t num_rows;	/* number of rows on console output device */
+    grub_uint16_t orig_x;	/* cursor's x position */
+    grub_uint16_t orig_y;	/* cursor's y position */
+  } console_info;
+  grub_uint64_t fpswa;		/* physical address of the fpswa interface */
+  grub_uint64_t initrd_start;
+  grub_uint64_t initrd_size;
+  grub_uint64_t domain_start;   /* boot domain address.  */
+  grub_uint64_t domain_size;    /* how big is the boot domain */
+  grub_uint64_t modules_chain;
+  grub_uint64_t modules_nbr;
+};
+
+struct ia64_boot_module
+{
+  grub_uint64_t mod_start;
+  grub_uint64_t mod_end;
+  
+  /* Module command line */
+  grub_uint64_t cmdline;
+  
+  grub_uint64_t next;
+};
+
+typedef struct
+{
+  grub_uint32_t	revision;
+  grub_uint32_t	reserved;
+  void *fpswa;
+} fpswa_interface_t;
+static fpswa_interface_t *fpswa;
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+/* Kernel base and size.  */
+static void *kernel_mem;
+static grub_efi_uintn_t kernel_pages;
+static grub_uint64_t entry;
+
+/* Initrd base and size.  */
+static void *initrd_mem;
+static grub_efi_uintn_t initrd_pages;
+static grub_efi_uintn_t initrd_size;
+
+static struct ia64_boot_param *boot_param;
+static grub_efi_uintn_t boot_param_pages;
+static struct ia64_boot_module *last_module = NULL;
+
+/* Can linux kernel be relocated ?  */
+#define RELOCATE_OFF   0	/* No.  */
+#define RELOCATE_ON    1	/* Yes.  */
+#define RELOCATE_FORCE 2	/* Always - used to debug.  */
+static int relocate = RELOCATE_OFF;
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+static void
+query_fpswa (void)
+{
+  grub_efi_handle_t fpswa_image;
+  grub_efi_boot_services_t *bs;
+  grub_efi_status_t status;
+  grub_efi_uintn_t size;
+  static const grub_efi_guid_t fpswa_protocol = 
+    { 0xc41b6531, 0x97b9, 0x11d3,
+      {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} };
+
+  if (fpswa != NULL)
+    return;
+
+  size = sizeof(grub_efi_handle_t);
+  
+  bs = grub_efi_system_table->boot_services;
+  status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL,
+			      &fpswa_protocol,
+			      NULL, &size, &fpswa_image);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_printf("Could not locate FPSWA driver\n");
+      return;
+    }
+  status = bs->handle_protocol (fpswa_image, &fpswa_protocol, &fpswa);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_printf ("Fpswa protocol not able find the interface\n");
+      return;
+    } 
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+   move this code to efi/mm.c?  */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+  static grub_efi_uintn_t mmap_size = 0;
+
+  if (mmap_size != 0)
+    return mmap_size;
+  
+  mmap_size = (1 << 12);
+  while (1)
+    {
+      int ret;
+      grub_efi_memory_descriptor_t *mmap;
+      grub_efi_uintn_t desc_size;
+      
+      mmap = grub_malloc (mmap_size);
+      if (! mmap)
+	return 0;
+
+      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      grub_free (mmap);
+      
+      if (ret < 0)
+	grub_fatal ("cannot get memory map");
+      else if (ret > 0)
+	break;
+
+      mmap_size += (1 << 12);
+    }
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later, and EFI itself may allocate more.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+  if (kernel_mem)
+    {
+      grub_efi_free_boot_pages ((grub_addr_t) kernel_mem, kernel_pages);
+      kernel_mem = 0;
+    }
+
+  if (initrd_mem)
+    {
+      grub_efi_free_boot_pages ((grub_addr_t) initrd_mem, initrd_pages);
+      initrd_mem = 0;
+    }
+
+  if (boot_param)
+    {
+      struct ia64_boot_module *mod;
+      struct ia64_boot_module *next_mod;
+
+      /* Free modules.  */
+      mod = (struct ia64_boot_module *)boot_param->modules_chain;
+      while (mod != 0)
+	{
+	  next_mod = (struct ia64_boot_module *)mod->next;
+
+	  grub_efi_free_boot_pages
+	    (mod->mod_start, page_align (mod->mod_end - mod->mod_start) >> 12);
+	  grub_efi_free_boot_pages ((grub_efi_physical_address_t)mod, 1);
+
+	  mod = next_mod;
+	}
+
+      /* Free bootparam.  */
+      grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param,
+				boot_param_pages);
+      boot_param = 0;
+    }
+}
+
+static void *
+allocate_pages (grub_uint64_t align, grub_uint64_t size_pages,
+		grub_uint64_t nobase)
+{
+  grub_uint64_t size;
+  grub_efi_uintn_t desc_size;
+  grub_efi_memory_descriptor_t *mmap, *mmap_end;
+  grub_efi_uintn_t mmap_size, tmp_mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  void *mem = NULL;
+
+  size = size_pages << 12;
+
+  mmap_size = find_mmap_size ();
+
+    /* Read the memory map temporarily, to find free space.  */
+  mmap = grub_malloc (mmap_size);
+  if (! mmap)
+    return 0;
+
+  tmp_mmap_size = mmap_size;
+  if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
+  
+  /* First, find free pages for the real mode code
+     and the memory map buffer.  */
+  for (desc = mmap;
+       desc < mmap_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_uint64_t start, end;
+      grub_uint64_t aligned_start;
+
+      if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
+	continue;
+
+      start = desc->physical_start;
+      end = start + (desc->num_pages << 12);
+      /* Align is a power of 2.  */
+      aligned_start = (start + align - 1) & ~(align - 1);
+      if (aligned_start + size > end)
+	continue;
+      if (aligned_start == nobase)
+	aligned_start += align;
+      if (aligned_start + size > end)
+	continue;
+      mem = grub_efi_allocate_pages (aligned_start, size_pages);
+      if (! mem)
+	grub_fatal ("cannot allocate pages");
+      break;
+    }
+
+  if (! mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory");
+      goto fail;
+    }
+
+  grub_free (mmap);
+  return mem;
+
+ fail:
+  grub_free (mmap);
+  free_pages ();
+  return 0;
+}
+
+static void
+set_boot_param_console (void)
+{
+  grub_efi_simple_text_output_interface_t *conout;
+  grub_efi_uintn_t cols, rows;
+  
+  conout = grub_efi_system_table->con_out;
+  if (conout->query_mode (conout, conout->mode->mode, &cols, &rows)
+      != GRUB_EFI_SUCCESS)
+    return;
+
+  grub_dprintf("linux",
+	       "Console info: cols=%lu rows=%lu x=%u y=%u\n",
+	       cols, rows,
+	       conout->mode->cursor_column, conout->mode->cursor_row);
+  
+  boot_param->console_info.num_cols = cols;
+  boot_param->console_info.num_rows = rows;
+  boot_param->console_info.orig_x = conout->mode->cursor_column;
+  boot_param->console_info.orig_y = conout->mode->cursor_row;
+}
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  grub_efi_uintn_t mmap_size;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  grub_efi_memory_descriptor_t *mmap_buf;
+
+  /* FPSWA.  */
+  query_fpswa ();
+  boot_param->fpswa = (grub_uint64_t)fpswa;
+
+  /* Initrd.  */
+  boot_param->initrd_start = (grub_uint64_t)initrd_mem;
+  boot_param->initrd_size = (grub_uint64_t)initrd_size;
+
+  set_boot_param_console ();
+
+  grub_printf ("Jump to %016lx\n", entry);
+
+  grub_machine_fini ();
+
+  /* MDT.
+     Must be done after grub_machine_fini because map_key is used by
+     exit_boot_services.  */
+  mmap_size = find_mmap_size ();
+  mmap_buf = grub_efi_allocate_boot_pages (0, page_align (mmap_size) >> 12);
+  if (! mmap_buf)
+    grub_fatal ("cannot allocate memory map");
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  boot_param->efi_memmap = (grub_uint64_t)mmap_buf;
+  boot_param->efi_memmap_size = mmap_size;
+  boot_param->efi_memdesc_size = desc_size;
+  boot_param->efi_memdesc_version = desc_version;
+
+  if (! grub_efi_exit_boot_services (map_key))
+    grub_fatal ("cannot exit boot services");
+
+  /* See you next boot.  */
+  asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(entry),"r"(boot_param));
+  
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  free_pages ();
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_load_elf64 (grub_file_t file, void *buffer)
+{
+  Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer;
+  Elf64_Phdr *phdr;
+  int i;
+  grub_uint64_t low_addr;
+  grub_uint64_t high_addr;
+  grub_uint64_t align;
+  grub_uint64_t reloc_offset;
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+      || ehdr->e_ident[EI_MAG1] != ELFMAG1
+      || ehdr->e_ident[EI_MAG2] != ELFMAG2
+      || ehdr->e_ident[EI_MAG3] != ELFMAG3
+      || ehdr->e_version != EV_CURRENT
+      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+      || ehdr->e_machine != EM_IA_64)
+    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+  if (ehdr->e_type != ET_EXEC)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_ELF_SEARCH)
+    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+  entry = ehdr->e_entry;
+
+  /* Compute low, high and align addresses.  */
+  low_addr = ~0UL;
+  high_addr = 0;
+  align = 0;
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
+			     + i * ehdr->e_phentsize);
+      if (phdr->p_type == PT_LOAD)
+	{
+	  if (phdr->p_paddr < low_addr)
+	    low_addr = phdr->p_paddr;
+	  if (phdr->p_paddr + phdr->p_memsz > high_addr)
+	    high_addr = phdr->p_paddr + phdr->p_memsz;
+	  if (phdr->p_align > align)
+	    align = phdr->p_align;
+	}
+    }
+
+  if (align < ALIGN_MIN)
+    align = ALIGN_MIN;
+
+  if (high_addr == 0)
+    return grub_error (GRUB_ERR_BAD_OS, "no program entries");
+
+  kernel_pages = page_align (high_addr - low_addr) >> 12;
+
+  if (relocate != RELOCATE_FORCE)
+    {
+      kernel_mem = grub_efi_allocate_boot_pages (low_addr, kernel_pages);
+      reloc_offset = 0;
+    }
+  /* Try to relocate.  */
+  if (! kernel_mem && relocate != RELOCATE_OFF)
+    {
+      kernel_mem = allocate_pages (align, kernel_pages, low_addr);
+      if (kernel_mem)
+	{
+	  reloc_offset = kernel_mem - low_addr;
+	  grub_printf ("  Relocated at %p (offset=%016llx)\n",
+		       kernel_mem, reloc_offset);
+	  entry += reloc_offset;
+	}
+    }
+  if (! kernel_mem)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "cannot allocate memory for OS");
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff
+			     + i * ehdr->e_phentsize);
+      if (phdr->p_type == PT_LOAD)
+        {
+	  grub_printf ("  [paddr=%llx load=%llx memsz=%08llx "
+		       "off=%lx flags=%x]\n",
+		       phdr->p_paddr, phdr->p_paddr + reloc_offset,
+		       phdr->p_memsz, phdr->p_offset, phdr->p_flags);
+
+	  if (grub_file_seek (file, phdr->p_offset) == -1)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "invalid offset in program header");
+
+	  if (grub_file_read (file, (void *)(phdr->p_paddr + reloc_offset),
+			      phdr->p_filesz)
+              != (grub_ssize_t) phdr->p_filesz)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "couldn't read segment from file");
+	  
+          if (phdr->p_filesz < phdr->p_memsz)
+	    grub_memset
+	      ((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz),
+	       0, phdr->p_memsz - phdr->p_filesz);
+
+	  /* Sync caches if necessary.  */
+	  if (phdr->p_flags & PF_X)
+	    grub_arch_sync_caches
+	      ((void *)(phdr->p_paddr + reloc_offset), phdr->p_memsz);
+        }
+    }
+  loaded = 1;
+  return 0;
+}
+
+void
+grub_rescue_cmd_linux (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char buffer[GRUB_ELF_SEARCH];
+  char *cmdline, *p;
+  grub_ssize_t len;
+  int i;
+
+  grub_dl_ref (my_mod);
+
+  grub_loader_unset ();
+    
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  len = grub_file_read (file, buffer, sizeof (buffer));
+  if (len < (grub_ssize_t)sizeof (Elf64_Ehdr))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "File too small");
+      goto fail;
+    }
+
+  grub_printf ("Loading linux: %s\n", argv[0]);
+
+  if (grub_load_elf64 (file, buffer))
+    goto fail;
+
+  len = sizeof("BOOT_IMAGE=") + 8;
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+  len += sizeof (struct ia64_boot_param) + 256; /* Room for extensions.  */
+  boot_param_pages = page_align (len) >> 12;
+  boot_param = grub_efi_allocate_boot_pages (0, boot_param_pages);
+  if (boot_param == 0)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "cannot allocate memory for bootparams");
+      goto fail;
+    }
+
+  grub_memset (boot_param, 0, len);
+  cmdline = ((char *)(boot_param + 1)) + 256;
+
+  /* Build cmdline.  */
+  p = grub_stpcpy (cmdline, "BOOT_IMAGE");
+  for (i = 0; i < argc; i++)
+    {
+      *p++ = ' ';
+      p = grub_stpcpy (p, argv[i]);
+    }
+  cmdline[10] = '=';
+  
+  boot_param->command_line = (grub_uint64_t)cmdline;
+  boot_param->efi_systab = (grub_uint64_t)grub_efi_system_table;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_efi_free_boot_pages ((grub_efi_physical_address_t)boot_param,
+				boot_param_pages);
+      grub_dl_unref (my_mod);
+    }
+}
+
+void
+grub_rescue_cmd_initrd (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+  
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto fail;
+
+  grub_printf ("Loading initrd: %s\n",argv[0]);
+
+  initrd_size = grub_file_size (file);
+  initrd_pages = (page_align (initrd_size) >> 12);
+  initrd_mem = grub_efi_allocate_boot_pages (0, initrd_pages);
+  if (! initrd_mem)
+    grub_fatal ("cannot allocate pages");
+  
+  grub_printf ("  [addr=0x%lx, size=0x%lx]\n",
+	       (grub_uint64_t)initrd_mem, initrd_size);
+
+  if (grub_file_read (file, initrd_mem, initrd_size) 
+      != (grub_ssize_t)initrd_size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+ fail:
+  if (file)
+    grub_file_close (file);
+}
+
+void
+grub_rescue_cmd_module  (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size, len = 0;
+  char *module = 0, *cmdline = 0, *p;
+  struct ia64_boot_module *mod = NULL;
+  int i;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (!boot_param)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, 
+		  "You need to load the multiboot kernel first");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  module = grub_efi_allocate_boot_pages (0, page_align (size) >> 12);
+  if (! module)
+    goto fail;
+
+  grub_printf ("Module %s [addr=%llx + %lx]\n",
+	       argv[0], (grub_uint64_t)module, size);
+
+  if (grub_file_read (file, module, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  len = sizeof (struct ia64_boot_module);  
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  if (len > 4096)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "module command line too long");
+      goto fail;
+    }
+  mod = grub_efi_allocate_boot_pages (0, 1);
+  if (! mod)
+    goto fail;
+
+  p = (char *)(mod + 1);
+
+  mod->mod_start = (grub_uint64_t)module;
+  mod->mod_end = (grub_uint64_t)module + size;
+  mod->cmdline = (grub_uint64_t)p;
+  mod->next = 0;
+
+  if (last_module)
+    last_module->next = (grub_uint64_t)mod;
+  else
+    {
+      last_module = mod;
+      boot_param->modules_chain = (grub_uint64_t)mod;
+    }
+  boot_param->modules_nbr++;
+
+  /* Copy command line.  */
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+  
+  /* Remove the space after the last word.  */
+  *(--p) = '\0';
+
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (module);
+      grub_free (cmdline);
+    }
+}
+
+void
+grub_rescue_cmd_relocate  (int argc, char *argv[])
+{
+  static const char * const vals[] = { "off", "on", "force"};
+  unsigned int i;
+
+  if (argc == 0)
+    {
+      grub_printf ("relocate is %s\n", vals[relocate]);
+    }
+  else if (argc == 1)
+    {
+      if (kernel_mem != NULL)
+	grub_printf ("Warning: kernel already loaded!\n");
+      for (i = 0; i < sizeof (vals)/sizeof(vals[0]); i++)
+	if (grub_strcmp (argv[0], vals[i]) == 0)
+	  {
+	    relocate = i;
+	    return;
+	  }
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocate value");
+    }
+  else
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "accept 0 or 1 argument");
+    }
+}
+
+
+void
+grub_rescue_cmd_fpswa  (int argc, char *argv[] __attribute__((unused)))
+{
+  if (argc != 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Arguments not expected");
+      return;
+    }
+  query_fpswa ();
+  if (fpswa == NULL)
+    grub_printf ("No FPSWA loaded\n");
+  else
+    grub_printf ("FPSWA revision: %x\n", fpswa->revision);
+}
+
+GRUB_MOD_INIT(linux)
+{
+  grub_rescue_register_command ("linux",
+				grub_rescue_cmd_linux,
+				"load linux");
+  grub_rescue_register_command ("initrd",
+				grub_rescue_cmd_initrd,
+				"load initrd");
+  grub_rescue_register_command ("module", grub_rescue_cmd_module,
+				"load a multiboot module");
+  grub_rescue_register_command ("relocate", grub_rescue_cmd_relocate,
+				"set relocate feature");
+  grub_rescue_register_command ("fpswa", grub_rescue_cmd_fpswa,
+				"load fpswa");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_rescue_unregister_command ("linux");
+  grub_rescue_unregister_command ("initrd");
+  grub_rescue_unregister_command ("module");
+  grub_rescue_unregister_command ("relocate");
+  grub_rescue_unregister_command ("fpswa");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/loader/ia64/efi/linux_normal.c grub2/loader/ia64/efi/linux_normal.c
--- grub2.orig/loader/ia64/efi/linux_normal.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/loader/ia64/efi/linux_normal.c	2008-01-29 05:45:15.000000000 +0100
@@ -0,0 +1,107 @@
+/* linux_normal.c - boot linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+static grub_err_t
+grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)),
+			   int argc, char **args)
+{
+  grub_rescue_cmd_linux (argc, args);
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)),
+			    int argc, char **args)
+{
+  grub_rescue_cmd_initrd (argc, args);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)),
+			int argc, char **args)
+{
+  grub_rescue_cmd_module (argc, args);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_relocate (struct grub_arg_list *state __attribute__ ((unused)),
+			int argc, char **args)
+{
+  grub_rescue_cmd_relocate (argc, args);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_normal_cmd_fpswa (struct grub_arg_list *state __attribute__ ((unused)),
+			int argc, char **args)
+{
+  grub_rescue_cmd_fpswa (argc, args);
+  return grub_errno;
+}
+
+GRUB_MOD_INIT(linux_normal)
+{
+  (void) mod; /* To stop warning.  */
+  grub_register_command
+    ("linux", grub_normal_linux_command,
+     GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+     "linux FILE [ARGS...]",
+     "Load a linux kernel.", 0);
+  
+  grub_register_command
+    ("initrd", grub_normal_initrd_command,
+     GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+     "initrd FILE",
+     "Load an initrd.", 0);
+
+  grub_register_command
+    ("module", grub_normal_cmd_module,
+     GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+     "module FILE [ARGS...]",
+     "Load a Multiboot module.", 0);
+
+  grub_register_command
+    ("relocate", grub_normal_cmd_relocate,
+     GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+     "relocate [on|off|force]",
+     "Set relocate feature.", 0);
+
+  grub_register_command
+    ("fpswa", grub_normal_cmd_fpswa,
+     GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+     "fpswa",
+     "Display FPSWA version.", 0);
+}
+
+GRUB_MOD_FINI(linux_normal)
+{
+  grub_unregister_command ("linux");
+  grub_unregister_command ("initrd");
+  grub_unregister_command ("module");
+  grub_unregister_command ("relocate");
+  grub_unregister_command ("fpswa");
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/normal/ia64/longjmp.S grub2/normal/ia64/longjmp.S
--- grub2.orig/normal/ia64/longjmp.S	1970-01-01 01:00:00.000000000 +0100
+++ grub2/normal/ia64/longjmp.S	2008-01-29 06:13:19.000000000 +0100
@@ -0,0 +1,162 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2008  Free Software Foundation, Inc.
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   Note that __sigsetjmp() did NOT flush the register stack.  Instead,
+   we do it here since __longjmp() is usually much less frequently
+   invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
+   didn't (and wouldn't be able to) save ar.rnat either.  This is a problem
+   because if we're not careful, we could end up loading random NaT bits.
+   There are two cases:
+
+	(i)  ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+		ar.rnat contains the desired bits---preserve ar.rnat
+		across loadrs and write to ar.bspstore
+
+	(ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+		The desired ar.rnat is stored in
+		ia64_rse_rnat_addr(jmpbuf.ar_bsp).  Load those
+		bits into ar.rnat after setting ar.bspstore. */
+
+
+
+#	define	pPos	p6	/* is rotate count positive? */
+#	define	pNeg	p7	/* is rotate count negative? */
+
+
+	/* __longjmp(__jmp_buf buf, int val) */
+
+	.text 
+	.global longjmp
+	.proc longjmp
+longjmp:
+	alloc r8=ar.pfs,2,1,0,0
+	mov r27=ar.rsc
+	add r2=0x98,in0		// r2 <- &jmpbuf.orig_jmp_buf_addr
+	;;
+	ld8 r8=[r2],-16		// r8 <- orig_jmp_buf_addr
+	mov r10=ar.bsp
+	and r11=~0x3,r27	// clear ar.rsc.mode
+	;;
+	flushrs			// flush dirty regs to backing store (must be first in insn grp)
+	ld8 r23=[r2],8		// r23 <- jmpbuf.ar_bsp
+	sub r8=r8,in0		// r8 <- &orig_jmpbuf - &jmpbuf
+	;;
+	ld8 r25=[r2]		// r25 <- jmpbuf.ar_unat
+	extr.u r8=r8,3,6	// r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
+	;;
+	cmp.lt pNeg,pPos=r8,r0
+	mov r2=in0
+	;;
+(pPos)	mov r16=r8
+(pNeg)	add r16=64,r8
+(pPos)	sub r17=64,r8
+(pNeg)	sub r17=r0,r8
+	;;
+	mov ar.rsc=r11		// put RSE in enforced lazy mode
+	shr.u r8=r25,r16
+	add r3=8,in0		// r3 <- &jmpbuf.r1
+	shl r9=r25,r17
+	;;
+	or r25=r8,r9
+	;;
+	mov r26=ar.rnat
+	mov ar.unat=r25		// setup ar.unat (NaT bits for r1, r4-r7, and r12)
+	;;
+	ld8.fill.nta sp=[r2],16	// r12 (sp)
+	ld8.fill.nta gp=[r3],16		// r1 (gp)
+	dep r11=-1,r23,3,6	// r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+	;;
+	ld8.nta r16=[r2],16		// caller's unat
+	ld8.nta r17=[r3],16		// fpsr
+	;;
+	ld8.fill.nta r4=[r2],16	// r4
+	ld8.fill.nta r5=[r3],16		// r5 (gp)
+	cmp.geu p8,p0=r10,r11	// p8 <- (ar.bsp >= jmpbuf.ar_bsp)
+	;;
+	ld8.fill.nta r6=[r2],16	// r6
+	ld8.fill.nta r7=[r3],16		// r7
+	;;
+	mov ar.unat=r16			// restore caller's unat
+	mov ar.fpsr=r17			// restore fpsr
+	;;
+	ld8.nta r16=[r2],16		// b0
+	ld8.nta r17=[r3],16		// b1
+	;;
+(p8)	ld8 r26=[r11]		// r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+	mov ar.bspstore=r23	// restore ar.bspstore
+	;;
+	ld8.nta r18=[r2],16		// b2
+	ld8.nta r19=[r3],16		// b3
+	;;
+	ld8.nta r20=[r2],16		// b4
+	ld8.nta r21=[r3],16		// b5
+	;;
+	ld8.nta r11=[r2],16		// ar.pfs
+	ld8.nta r22=[r3],56		// ar.lc
+	;;
+	ld8.nta r24=[r2],32		// pr
+	mov b0=r16
+	;;
+	ldf.fill.nta f2=[r2],32
+	ldf.fill.nta f3=[r3],32
+	mov b1=r17
+	;;
+	ldf.fill.nta f4=[r2],32
+	ldf.fill.nta f5=[r3],32
+	mov b2=r18
+	;;
+	ldf.fill.nta f16=[r2],32
+	ldf.fill.nta f17=[r3],32
+	mov b3=r19
+	;;
+	ldf.fill.nta f18=[r2],32
+	ldf.fill.nta f19=[r3],32
+	mov b4=r20
+	;;
+	ldf.fill.nta f20=[r2],32
+	ldf.fill.nta f21=[r3],32
+	mov b5=r21
+	;;
+	ldf.fill.nta f22=[r2],32
+	ldf.fill.nta f23=[r3],32
+	mov ar.lc=r22
+	;;
+	ldf.fill.nta f24=[r2],32
+	ldf.fill.nta f25=[r3],32
+	cmp.eq p8,p9=0,in1
+	;;
+	ldf.fill.nta f26=[r2],32
+	ldf.fill.nta f27=[r3],32
+	mov ar.pfs=r11
+	;;
+	ldf.fill.nta f28=[r2],32
+	ldf.fill.nta f29=[r3],32
+	;;
+	ldf.fill.nta f30=[r2]
+	ldf.fill.nta f31=[r3]
+(p8)	mov r8=1
+
+	mov ar.rnat=r26		// restore ar.rnat
+	;;
+	mov ar.rsc=r27		// restore ar.rsc
+(p9)	mov r8=in1
+
+	invala			// virt. -> phys. regnum mapping may change
+	mov pr=r24,-1
+	br.ret.dptk.few rp
+	.endp longjmp
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/normal/ia64/setjmp.S grub2/normal/ia64/setjmp.S
--- grub2.orig/normal/ia64/setjmp.S	1970-01-01 01:00:00.000000000 +0100
+++ grub2/normal/ia64/setjmp.S	2008-01-29 06:13:12.000000000 +0100
@@ -0,0 +1,171 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.
+
+   The layout of the jmp_buf is as follows.  This is subject to change
+   and user-code should never depend on the particular layout of
+   jmp_buf!
+
+
+  	offset:	description:
+	-------	------------
+  	0x000	stack pointer (r12)	; unchangeable (see _JMPBUF_UNWINDS)
+  	0x008	r1 (gp)
+	0x010	caller's unat
+	0x018	fpsr
+  	0x020	r4
+  	0x028	r5
+  	0x030	r6
+  	0x038	r7
+  	0x040	rp (b0)
+  	0x048	b1
+  	0x050	b2
+  	0x058	b3
+  	0x060	b4
+  	0x068	b5
+  	0x070	ar.pfs
+  	0x078	ar.lc
+  	0x080	pr
+  	0x088	ar.bsp			; unchangeable (see __longjmp.S)
+  	0x090	ar.unat
+	0x098	&__jmp_buf	; address of the jmpbuf (needed to locate NaT bits in unat)
+	0x0a0	 f2
+	0x0b0	 f3
+	0x0c0	 f4
+	0x0d0	 f5
+	0x0e0	f16
+  	0x0f0	f17
+  	0x100	f18
+  	0x110	f19
+  	0x120	f20
+  	0x130	f21
+  	0x130	f22
+  	0x140	f23
+  	0x150	f24
+  	0x160	f25
+  	0x170	f26
+  	0x180	f27
+  	0x190	f28
+  	0x1a0	f29
+  	0x1b0	f30
+  	0x1c0	f31 */
+
+
+	/* The following two entry points are the traditional entry points: */
+
+	.text
+	.global setjmp
+	.proc setjmp
+setjmp:
+	alloc r8=ar.pfs,2,0,0,0
+	mov in1=1
+	br.cond.sptk.many __sigsetjmp
+	.endp setjmp
+
+	/* __sigsetjmp(__jmp_buf buf, int savemask) */
+
+	.proc __sigsetjmp
+__sigsetjmp:
+	//.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+	alloc loc1=ar.pfs,2,2,2,0
+	mov r16=ar.unat
+	;;
+	mov r17=ar.fpsr
+	mov r2=in0
+	add r3=8,in0
+	;;
+	st8.spill.nta [r2]=sp,16	// r12 (sp)
+	st8.spill.nta [r3]=gp,16	// r1 (gp)
+	;;
+	st8.nta [r2]=r16,16		// save caller's unat
+	st8.nta [r3]=r17,16		// save fpsr
+	add r8=0xa0,in0
+	;;
+	st8.spill.nta [r2]=r4,16	// r4
+	st8.spill.nta [r3]=r5,16	// r5
+	add r9=0xb0,in0
+	;;
+	stf.spill.nta [r8]=f2,32
+	stf.spill.nta [r9]=f3,32
+	mov loc0=rp
+	.body
+	;;
+	stf.spill.nta [r8]=f4,32
+	stf.spill.nta [r9]=f5,32
+	mov r17=b1
+	;;
+	stf.spill.nta [r8]=f16,32
+	stf.spill.nta [r9]=f17,32
+	mov r18=b2
+	;;
+	stf.spill.nta [r8]=f18,32
+	stf.spill.nta [r9]=f19,32
+	mov r19=b3
+	;;
+	stf.spill.nta [r8]=f20,32
+	stf.spill.nta [r9]=f21,32
+	mov r20=b4
+	;;
+	stf.spill.nta [r8]=f22,32
+	stf.spill.nta [r9]=f23,32
+	mov r21=b5
+	;;
+	stf.spill.nta [r8]=f24,32
+	stf.spill.nta [r9]=f25,32
+	mov r22=ar.lc
+	;;
+	stf.spill.nta [r8]=f26,32
+	stf.spill.nta [r9]=f27,32
+	mov r24=pr
+	;;
+	stf.spill.nta [r8]=f28,32
+	stf.spill.nta [r9]=f29,32
+	;;
+	stf.spill.nta [r8]=f30
+	stf.spill.nta [r9]=f31
+
+	st8.spill.nta [r2]=r6,16	// r6
+	st8.spill.nta [r3]=r7,16	// r7
+	;;
+	mov r23=ar.bsp
+	mov r25=ar.unat
+	mov out0=in0
+
+	st8.nta [r2]=loc0,16		// b0
+	st8.nta [r3]=r17,16		// b1
+	mov out1=in1
+	;;
+	st8.nta [r2]=r18,16		// b2
+	st8.nta [r3]=r19,16		// b3
+	;;
+	st8.nta [r2]=r20,16		// b4
+	st8.nta [r3]=r21,16		// b5
+	;;
+	st8.nta [r2]=loc1,16		// ar.pfs
+	st8.nta [r3]=r22,16		// ar.lc
+	;;
+	st8.nta [r2]=r24,16		// pr
+	st8.nta [r3]=r23,16		// ar.bsp
+	;;
+	st8.nta [r2]=r25		// ar.unat
+	st8.nta [r3]=in0		// &__jmp_buf
+	mov r8=0
+	mov rp=loc0
+	mov ar.pfs=loc1
+	br.ret.sptk.many rp
+
+	.endp __sigsetjmp
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/elf2pe.c grub2/util/ia64/efi/elf2pe.c
--- grub2.orig/util/ia64/efi/elf2pe.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/elf2pe.c	2008-01-29 06:41:55.000000000 +0100
@@ -0,0 +1,812 @@
+/* elf2pe.c - convert elf binary to PE/Coff.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <elf.h>
+
+#if defined(ELF2PE_I386)
+#define USE_ELF32
+#define USE_PE32
+#define ELF_MACHINE EM_386
+#define EFI_MACHINE PE32_MACHINE_I386
+#elif defined(ELF2PE_IA64)
+#define USE_ELF64
+#define USE_PE32PLUS
+#define ELF_MACHINE EM_IA_64
+#define EFI_MACHINE PE32_MACHINE_IA64
+#else
+#error "unknown architecture"
+#endif
+
+#include "pe32.h"
+
+const char *filename;
+
+int
+is_elf_header(uint8_t *buffer)
+{
+  return (buffer[EI_MAG0] == ELFMAG0
+	  && buffer[EI_MAG1] == ELFMAG1
+	  && buffer[EI_MAG2] == ELFMAG2
+	  && buffer[EI_MAG3] == ELFMAG3);
+}
+
+#ifdef USE_ELF32
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Sym Elf_Sym;
+#define ELFCLASS ELFCLASS32
+#define ELF_R_TYPE(r) ELF32_R_TYPE(r)
+#define ELF_R_SYM(r) ELF32_R_SYM(r)
+#else
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Sym Elf_Sym;
+#define ELFCLASS ELFCLASS64
+#define ELF_R_TYPE(r) ELF64_R_TYPE(r)
+#define ELF_R_SYM(r) ELF64_R_SYM(r)
+#endif
+
+#ifdef __ia64__
+#define ELF_ETYPE ET_DYN
+#else
+#define ELF_ETYPE ET_EXEC
+#endif
+
+/* Well known ELF structures.  */
+Elf_Ehdr *ehdr;
+Elf_Shdr *shdr_base;
+Elf_Shdr *shdr_dynamic;
+const uint8_t *shdr_str;
+
+/* PE section alignment.  */
+const uint32_t coff_alignment = 0x20;
+const uint32_t coff_nbr_sections = 4;
+
+/* Current offset in coff file.  */
+uint32_t coff_offset;
+
+/* Result Coff file in memory.  */
+uint8_t *coff_file;
+
+/* Offset in Coff file of headers and sections.  */
+uint32_t nt_hdr_offset;
+uint32_t table_offset;
+uint32_t text_offset;
+uint32_t data_offset;
+uint32_t reloc_offset;
+
+#ifdef __ia64__
+uint32_t coff_entry_descr_offset;
+uint32_t coff_entry_descr_func;
+uint64_t plt_base;
+#endif
+
+/* ELF sections to offset in Coff file.  */
+uint32_t *coff_sections_offset;
+
+struct pe32_fixup_block *coff_base_rel;
+uint16_t *coff_entry_rel;
+
+uint32_t
+coff_align(uint32_t offset)
+{
+  return (offset + coff_alignment - 1) & ~(coff_alignment - 1);
+}
+
+Elf_Shdr *
+get_shdr_by_index(uint32_t num)
+{
+  if (num >= ehdr->e_shnum)
+    return NULL;
+  return (Elf_Shdr*)((uint8_t*)shdr_base + num * ehdr->e_shentsize);
+}
+
+int
+check_elf_header (void)
+{
+  /* Note: Magic has already been tested.  */
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
+    return 0;
+  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
+    return 0;
+  if (ehdr->e_type != ELF_ETYPE)
+    return 0;
+  if (ehdr->e_machine != ELF_MACHINE)
+    return 0;
+  if (ehdr->e_version != EV_CURRENT)
+    return 0;
+  
+  shdr_base = (Elf_Shdr *)((uint8_t *)ehdr + ehdr->e_shoff);
+
+  coff_sections_offset =
+    (uint32_t *)malloc (ehdr->e_shnum * sizeof (uint32_t));
+  memset (coff_sections_offset, 0, ehdr->e_shnum * sizeof(uint32_t));
+
+  if (ehdr->e_shstrndx != SHN_UNDEF)
+    shdr_str = (uint8_t*)ehdr + shdr_base[ehdr->e_shstrndx].sh_offset;
+  else
+    shdr_str = NULL;
+
+  return 1;
+}
+
+int
+is_text_shdr (Elf_Shdr *shdr)
+{
+  if (shdr->sh_type != SHT_PROGBITS) {
+    return 0;
+  }
+#ifdef __ia64__
+  return (shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC))
+    == (SHF_ALLOC | SHF_EXECINSTR);
+#else
+  return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;
+#endif
+}
+
+int
+is_data_shdr (Elf_Shdr *shdr)
+{
+  if (shdr->sh_type != SHT_PROGBITS && shdr->sh_type != SHT_NOBITS) {
+    return 0;
+  }
+  return (shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
+}
+
+void
+create_section_header (const char *name, uint32_t offset, uint32_t size,
+		       uint32_t flags)
+{
+  struct pe32_section_header *hdr;
+  hdr = (struct pe32_section_header*)(coff_file + table_offset);
+
+  strcpy (hdr->name, name);
+  hdr->virtual_size = size;
+  hdr->virtual_address = offset;
+  hdr->raw_data_size = size;
+  hdr->raw_data_offset = offset;
+  hdr->relocations_offset = 0;
+  hdr->line_numbers_offset = 0;
+  hdr->num_relocations = 0;
+  hdr->num_line_numbers = 0;
+  hdr->characteristics = flags;
+
+  table_offset += sizeof (struct pe32_section_header);
+}
+
+int
+scan_sections (void)
+{
+  uint32_t i;
+  struct pe32_dos_header *doshdr;
+  struct pe32_nt_header *nt_hdr;
+  uint32_t coff_entry = 0;
+  int status = 0;
+
+  coff_offset = 0;
+
+  /* Coff file start with a DOS header.  */
+  coff_offset = sizeof(struct pe32_dos_header);
+  nt_hdr_offset = coff_offset;
+  coff_offset += sizeof(struct pe32_nt_header);
+  table_offset = coff_offset;
+  coff_offset += coff_nbr_sections * sizeof(struct pe32_section_header);
+
+  /* First text sections.  */
+  coff_offset = coff_align(coff_offset);
+  text_offset = coff_offset;
+  for (i = 0; i < ehdr->e_shnum; i++) {
+    Elf_Shdr *shdr = get_shdr_by_index (i);
+    if (is_text_shdr (shdr)) {
+      /* Relocate entry.  */
+      if (ehdr->e_entry >= shdr->sh_addr
+	  && ehdr->e_entry < shdr->sh_addr + shdr->sh_size) {
+	coff_entry = coff_offset + ehdr->e_entry - shdr->sh_addr;
+      }
+      coff_sections_offset[i] = coff_offset;
+      coff_offset += shdr->sh_size;
+#ifdef __ia64__
+      if (coff_sections_offset[i] != shdr->sh_addr) {
+	fprintf (stderr, 
+		 "Section %s: Coff offset (%x) != Elf offset (%lx)",
+		 shdr_str + shdr->sh_name,
+		 coff_sections_offset[i],
+		 shdr->sh_addr);
+	status = -1;
+      }
+#endif
+    }
+    if (shdr->sh_type == SHT_DYNAMIC) {
+      shdr_dynamic = shdr;
+    }
+  }
+#ifdef __ia64__
+  /* 16 bytes are reserved (by the ld script) for the entry point descriptor.
+   */
+  coff_entry_descr_offset = coff_offset - 16;
+#endif
+
+  coff_offset = coff_align (coff_offset);
+		       
+  /* Then data sections.  */
+  data_offset = coff_offset;
+  for (i = 0; i < ehdr->e_shnum; i++) {
+    Elf_Shdr *shdr = get_shdr_by_index (i);
+    if (is_data_shdr (shdr)) {
+      coff_sections_offset[i] = coff_offset;
+      coff_offset += shdr->sh_size;
+#ifdef __ia64__
+      if (coff_sections_offset[i] != shdr->sh_addr) {
+	fprintf (stderr,
+		 "Section %s: Coff offset (%x) != Elf offset (%lx)",
+		 shdr_str + shdr->sh_name,
+		 coff_sections_offset[i],
+		 shdr->sh_addr);
+	status = -1;
+      }
+#endif
+    }
+  }
+  coff_offset = coff_align (coff_offset);
+
+  reloc_offset = coff_offset;  
+
+  /* Allocate base Coff file.  Will be expanded later for relocations.  */
+  coff_file = (uint8_t *)malloc (coff_offset);
+  memset (coff_file, 0, coff_offset);
+
+  /* Fill headers.  */
+  doshdr = (struct pe32_dos_header *)coff_file;
+  doshdr->magic = 0x5A4D;
+  doshdr->new_hdr_offset = nt_hdr_offset;
+
+  nt_hdr = (struct pe32_nt_header*)(coff_file + nt_hdr_offset);
+
+  memcpy (nt_hdr->signature, "PE\0", 4);
+
+  nt_hdr->coff_header.machine = EFI_MACHINE;
+  nt_hdr->coff_header.num_sections = coff_nbr_sections;
+  nt_hdr->coff_header.time = time (NULL);
+  nt_hdr->coff_header.symtab_offset = 0;
+  nt_hdr->coff_header.num_symbols = 0;
+  nt_hdr->coff_header.optional_header_size = sizeof(nt_hdr->optional_header);
+  nt_hdr->coff_header.characteristics = PE32_EXECUTABLE_IMAGE
+    | PE32_LINE_NUMS_STRIPPED
+    | PE32_LOCAL_SYMS_STRIPPED
+    | PE32_32BIT_MACHINE;
+
+#ifdef USE_PE32
+  nt_hdr->optional_header.magic = PE32_PE32_MAGIC;
+#else
+  nt_hdr->optional_header.magic = PE32_PE64_MAGIC;
+#endif
+  nt_hdr->optional_header.code_size = data_offset - text_offset;
+  nt_hdr->optional_header.data_size = reloc_offset - data_offset;
+  nt_hdr->optional_header.bss_size = 0;
+#ifdef __ia64__
+  nt_hdr->optional_header.entry_addr = coff_entry_descr_offset;
+  coff_entry_descr_func = coff_entry;
+#else
+  nt_hdr->optional_header.entry_addr = coff_entry;
+#endif
+  nt_hdr->optional_header.code_base = text_offset;
+
+#ifdef USE_PE32
+  nt_hdr->optional_header.data_base = data_offset;
+#endif
+  nt_hdr->optional_header.image_base = 0;
+  nt_hdr->optional_header.section_alignment = coff_alignment;
+  nt_hdr->optional_header.file_alignment = coff_alignment;
+  nt_hdr->optional_header.image_size = 0;
+
+  nt_hdr->optional_header.header_size = text_offset;
+  nt_hdr->optional_header.num_data_directories = PE32_NUM_DATA_DIRECTORIES;
+
+  /* Section headers.  */
+  create_section_header (".text", text_offset, data_offset - text_offset,
+			 PE32_SCN_CNT_CODE
+			 | PE32_SCN_MEM_EXECUTE
+			 | PE32_SCN_MEM_READ);
+  create_section_header (".data", data_offset, reloc_offset - data_offset,
+			 PE32_SCN_CNT_INITIALIZED_DATA
+			 | PE32_SCN_MEM_WRITE
+			 | PE32_SCN_MEM_READ);
+#ifdef __ia64__
+  if (shdr_dynamic != NULL)
+    {
+      Elf64_Dyn *dyn = (Elf64_Dyn*)((uint8_t*)ehdr + shdr_dynamic->sh_offset);
+      while (dyn->d_tag != DT_NULL)
+	{
+	  if (dyn->d_tag == DT_PLTGOT)
+	    plt_base = dyn->d_un.d_ptr;
+	  dyn++;
+	}
+    }
+#endif
+  return status;
+}
+
+int
+write_sections (int (*filter)(Elf_Shdr *))
+{
+  uint32_t idx;
+  int status = 0;
+
+  /* First: copy sections.  */
+  for (idx = 0; idx < ehdr->e_shnum; idx++)
+    {
+      Elf_Shdr *shdr = get_shdr_by_index (idx);
+      if ((*filter)(shdr))
+	{
+	  switch (shdr->sh_type) {
+	  case SHT_PROGBITS:
+	    /* Copy.  */
+	    memcpy (coff_file + coff_sections_offset[idx],
+		    (uint8_t*)ehdr + shdr->sh_offset,
+		    shdr->sh_size);
+	    break;
+	  case SHT_NOBITS:
+	    memset (coff_file + coff_sections_offset[idx], 0, shdr->sh_size);
+	    break;
+	  case SHT_DYNAMIC:
+	    break;
+	  default:
+	    fprintf (stderr, "unhandled section type %x",
+		     (unsigned int)shdr->sh_type);
+	    status = -1;
+	  }
+	}
+    }
+
+  /* Second: apply relocations.  */
+  for (idx = 0; idx < ehdr->e_shnum; idx++)
+    {
+      Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
+      if (rel_shdr->sh_type != SHT_REL && rel_shdr->sh_type != SHT_RELA)
+	continue;
+      Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
+      uint32_t sec_offset = coff_sections_offset[rel_shdr->sh_info];
+
+      if (rel_shdr->sh_info == 0 || (*filter)(sec_shdr))
+	{
+	  uint32_t rel_idx;
+	  Elf_Shdr *symtab_shdr = get_shdr_by_index(rel_shdr->sh_link);
+	  uint8_t *symtab = (uint8_t*)ehdr + symtab_shdr->sh_offset;
+
+	  if (rel_shdr->sh_type == SHT_REL)
+	    {
+	      for (rel_idx = 0;
+		   rel_idx < rel_shdr->sh_size;
+		   rel_idx += rel_shdr->sh_entsize)
+		{
+		  Elf_Rel *rel = (Elf_Rel *)
+		    ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+		  Elf_Sym *sym = (Elf_Sym *)
+		    (symtab
+		     + ELF_R_SYM(rel->r_info) * symtab_shdr->sh_entsize);
+		  Elf_Shdr *sym_shdr;
+		  uint8_t *targ;
+
+		  if (sym->st_shndx == SHN_UNDEF
+		      || sym->st_shndx == SHN_ABS
+		      || sym->st_shndx > ehdr->e_shnum)
+		    {
+		      fprintf (stderr, "bad symbol definition");
+		      status = -1;
+		    }
+		  sym_shdr = get_shdr_by_index(sym->st_shndx);
+
+		  /* Note: r_offset in a memory address.
+		     Convert it to a pointer in the coff file.  */
+		  targ = coff_file + sec_offset
+		    + (rel->r_offset - sec_shdr->sh_addr);
+
+		  switch (ELF_R_TYPE(rel->r_info)) {
+		  case R_386_NONE:
+		    break;
+		  case R_386_32:
+		    /* Absolute relocation.  */
+		    *(uint32_t *)targ = *(uint32_t *)targ - sym_shdr->sh_addr
+		      + coff_sections_offset[sym->st_shndx];
+		    break;
+		  case R_386_PC32:
+		    /* Relative relocation: Symbol - Ip + Addend  */
+		    *(uint32_t *)targ = *(uint32_t *)targ
+		      + (coff_sections_offset[sym->st_shndx]
+			 - sym_shdr->sh_addr)
+		      - (sec_offset - sec_shdr->sh_addr);
+		    break;
+		  default:
+		    fprintf (stderr, "unhandled relocation type %lx",
+			     ELF_R_TYPE(rel->r_info));
+		    status = -1;
+		  }
+		}
+	    }
+	  else if (rel_shdr->sh_type == SHT_RELA)
+	    {
+	      for (rel_idx = 0;
+		   rel_idx < rel_shdr->sh_size;
+		   rel_idx += rel_shdr->sh_entsize) {
+		Elf_Rela *rela = (Elf_Rela *)
+		  ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+		Elf_Sym *sym = (Elf_Sym *)
+		  (symtab + ELF_R_SYM(rela->r_info) * symtab_shdr->sh_entsize);
+		Elf_Shdr *sym_shdr;
+		uint8_t *targ;
+		
+		if (ELF_R_TYPE(rela->r_info) == R_IA64_NONE)
+		  continue;
+		
+#if 0
+		if (sym->st_shndx == SHN_UNDEF
+		    || sym->st_shndx == SHN_ABS
+		    || sym->st_shndx > ehdr->e_shnum) {
+		  fprintf (stderr, "bad symbol definition %d",
+			   ELF_R_SYM(rela->r_info));
+		}
+#endif
+		sym_shdr = get_shdr_by_index (sym->st_shndx);
+		
+		/* Note: r_offset in a memory address.
+		   Convert it to a pointer in the coff file.  */
+		targ = coff_file + sec_offset
+		  + (rela->r_offset - sec_shdr->sh_addr);
+		
+		switch (ELF_R_TYPE(rela->r_info)) {
+		case R_IA64_IPLTLSB:
+		  /* If there is a descriptor with the same function
+		     pointer as the ELF entry point, use that
+		     descriptor for the PE/Coff entry.  */
+		  if (*(uint64_t*)targ == ehdr->e_entry) {
+		    struct pe32_nt_header *nt_hdr;
+		    
+		    nt_hdr = 
+		      (struct pe32_nt_header*)(coff_file + nt_hdr_offset);
+		    nt_hdr->optional_header.entry_addr = targ - coff_file;
+		  }
+		  break;
+		case R_IA64_REL64LSB:
+		case R_IA64_NONE:
+		  break;
+		default:
+		  fprintf (stderr,
+			   "unhandled relocation type %lx in section %d",
+			   ELF_R_TYPE(rela->r_info), rel_shdr->sh_info);
+		  status = -1;
+		}
+	      }
+	    }
+	}
+    }
+  return status;
+}
+
+void
+coff_add_fixup_entry (uint16_t val)
+{
+  *coff_entry_rel = val;
+  coff_entry_rel++;
+  coff_base_rel->block_size += 2;
+  coff_offset += 2;
+}
+
+void
+coff_add_fixup (uint32_t offset, uint8_t type)
+{
+  if (coff_base_rel == NULL
+      || coff_base_rel->page_rva != (offset & ~0xfff)) {
+    if (coff_base_rel != NULL) {
+      /* Add a null entry (is it required ?)  */
+      coff_add_fixup_entry (0);
+      /* Pad for alignment.  */
+      if (coff_offset % 4 != 0)
+	coff_add_fixup_entry (0);
+    }
+      
+    coff_file = realloc
+      (coff_file,
+       coff_offset + sizeof(struct pe32_fixup_block) + 2*0x1000);
+    memset(coff_file + coff_offset, 0,
+	   sizeof(struct pe32_fixup_block) + 2*0x1000);
+
+    coff_base_rel = (struct pe32_fixup_block*)(coff_file + coff_offset);
+    coff_base_rel->page_rva = offset & ~0xfff;
+    coff_base_rel->block_size = sizeof(struct pe32_fixup_block);
+
+    coff_entry_rel = (uint16_t *)(coff_base_rel + 1);
+    coff_offset += sizeof(struct pe32_fixup_block);
+  }
+
+  /* Fill the entry.  */
+  coff_add_fixup_entry ((type << 12) | (offset & 0xfff));
+}
+
+int
+write_relocations(void)
+{
+  uint32_t idx;
+  struct pe32_nt_header *nt_hdr;
+  struct pe32_data_directory *dir;
+  int status = 0;
+
+  for (idx = 0; idx < ehdr->e_shnum; idx++)
+    {
+      Elf_Shdr *rel_shdr = get_shdr_by_index (idx);
+      if (rel_shdr->sh_type == SHT_REL)
+	{
+	  Elf_Shdr *sec_shdr = get_shdr_by_index (rel_shdr->sh_info);
+	  if (is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
+	    {
+	      uint32_t rel_idx;
+	      for (rel_idx = 0;
+		   rel_idx < rel_shdr->sh_size;
+		   rel_idx += rel_shdr->sh_entsize)
+		{
+		  Elf_Rel *rel = (Elf_Rel *)
+		    ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+
+		  switch (ELF_R_TYPE(rel->r_info))
+		    {
+		    case R_386_NONE:
+		    case R_386_PC32:
+		      break;
+		    case R_386_32:
+		      coff_add_fixup(coff_sections_offset[rel_shdr->sh_info]
+				     + (rel->r_offset - sec_shdr->sh_addr),
+				     PE32_REL_BASED_HIGHLOW);
+		      break;
+		    default:
+		      fprintf (stderr, "unhandled relocation type %lx",
+			       ELF_R_TYPE(rel->r_info));
+		      status = -1;
+		    }
+		}
+	    }
+	}
+      else if (rel_shdr->sh_type == SHT_RELA)
+	{
+	  Elf_Shdr *sec_shdr = get_shdr_by_index(rel_shdr->sh_info);
+	  if (rel_shdr->sh_info == 0
+	      || is_text_shdr(sec_shdr) || is_data_shdr(sec_shdr))
+	    {
+	      uint32_t rel_idx;
+	      for (rel_idx = 0;
+		   rel_idx < rel_shdr->sh_size;
+		   rel_idx += rel_shdr->sh_entsize) {
+		Elf_Rela *rela = (Elf_Rela *)
+		  ((uint8_t*)ehdr + rel_shdr->sh_offset + rel_idx);
+		uint32_t Loc = coff_sections_offset[rel_shdr->sh_info]
+		  + (rela->r_offset - sec_shdr->sh_addr);
+
+		switch (ELF_R_TYPE(rela->r_info))
+		  {
+		  case R_IA64_IPLTLSB:
+		    coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+		    coff_add_fixup(Loc + 8, PE32_REL_BASED_DIR64);
+		    break;
+		  case R_IA64_REL64LSB:
+		    coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+		    break;
+		  case R_IA64_DIR64LSB:
+		    coff_add_fixup(Loc, PE32_REL_BASED_DIR64);
+		    break;
+		  case R_IA64_IMM64:
+		    coff_add_fixup(Loc, PE32_REL_BASED_IA64_IMM64);
+		    break;
+		  case R_IA64_PCREL21B:
+		  case R_IA64_PCREL64LSB:
+		  case R_IA64_SECREL32LSB:
+		  case R_IA64_SEGREL64LSB:
+		    break;
+		  case R_IA64_GPREL22:
+		  case R_IA64_LTOFF22X:
+		  case R_IA64_LDXMOV:
+		  case R_IA64_LTOFF_FPTR22:
+		  case R_IA64_NONE:
+		    break;
+		  default:
+		    fprintf (stderr, "unhandled relocation type %lx",
+			     ELF_R_TYPE(rela->r_info));
+		    status = -1;
+		  }
+	      }
+	    }
+	}
+    }
+  
+#ifdef __ia64__
+  coff_add_fixup (coff_entry_descr_offset, PE32_REL_BASED_DIR64);
+  coff_add_fixup (coff_entry_descr_offset + 8, PE32_REL_BASED_DIR64);
+#endif
+
+  /* Pad by adding empty entries.   */
+  while (coff_offset & (coff_alignment - 1))
+    coff_add_fixup_entry (0);
+
+  create_section_header (".reloc", reloc_offset, coff_offset - reloc_offset,
+			 PE32_SCN_CNT_INITIALIZED_DATA
+			 | PE32_SCN_MEM_DISCARDABLE
+			 | PE32_SCN_MEM_READ);
+  
+  nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+  dir = &nt_hdr->optional_header.base_relocation_table;
+  dir->rva = reloc_offset;
+  dir->size = coff_offset - reloc_offset;
+  
+  return status;
+}
+
+void
+write_debug(void)
+{
+  uint32_t len = strlen(filename) + 1;
+  uint32_t debug_offset = coff_offset;
+  struct pe32_nt_header *nt_hdr;
+  struct pe32_data_directory *data_dir;
+  struct pe32_debug_directory_entry *dir;
+  struct pe32_debug_codeview_nb10_entry *nb10;
+
+  coff_offset += sizeof (struct pe32_debug_directory_entry)
+    + sizeof(struct pe32_debug_codeview_nb10_entry)
+    + len;
+  coff_offset = coff_align(coff_offset);
+
+  coff_file = realloc
+    (coff_file, coff_offset);
+  memset(coff_file + debug_offset, 0, coff_offset - debug_offset);
+  
+  dir = (struct pe32_debug_directory_entry*)(coff_file + debug_offset);
+  dir->type = PE32_DEBUG_TYPE_CODEVIEW;
+  dir->data_size = sizeof(struct pe32_debug_directory_entry) + len;
+  dir->rva = debug_offset + sizeof(struct pe32_debug_directory_entry);
+  dir->file_offset = debug_offset + sizeof(struct pe32_debug_directory_entry);
+  
+  nb10 = (struct pe32_debug_codeview_nb10_entry*)(dir + 1);
+  nb10->signature = PE32_CODEVIEW_SIGNATURE_NB10;
+  strcpy (nb10->filename, filename);
+
+  create_section_header (".debug", debug_offset, coff_offset - debug_offset,
+		       PE32_SCN_CNT_INITIALIZED_DATA
+		       | PE32_SCN_MEM_DISCARDABLE
+		       | PE32_SCN_MEM_READ);
+
+  nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+  data_dir = &nt_hdr->optional_header.debug;
+  data_dir->rva = debug_offset;
+  data_dir->size = coff_offset - debug_offset;
+}
+
+int
+convert_elf (uint8_t **file_buffer, unsigned int *file_length)
+{
+  struct pe32_nt_header *nt_hdr;
+
+  /* Check header, read section table.  */
+  ehdr = (Elf_Ehdr*)*file_buffer;
+  if (!check_elf_header ())
+    return -1;
+
+  /* Compute sections new address.  */
+  if (scan_sections () != 0)
+    return -2;
+
+  /* Write and relocate sections.  */
+  if (write_sections (is_text_shdr) != 0)
+    return -3;
+
+#ifdef __ia64__
+  *(uint64_t*)(coff_file + coff_entry_descr_offset) = coff_entry_descr_func;
+  *(uint64_t*)(coff_file + coff_entry_descr_offset + 8) = plt_base;
+#endif
+
+  if (write_sections (is_data_shdr) != 0)
+    return -4;
+
+  /* Translate and write relocations.  */
+  if (write_relocations () != 0)
+    return -5;
+
+  /* Write debug info.  */
+  write_debug ();
+
+  nt_hdr = (struct pe32_nt_header *)(coff_file + nt_hdr_offset);
+  nt_hdr->optional_header.image_size = coff_offset;
+
+  nt_hdr->optional_header.subsystem = PE32_SUBSYSTEM_EFI_APPLICATION;
+
+  /* Replace.  */
+  free (*file_buffer);
+  *file_buffer = coff_file;
+  *file_length = coff_offset;
+
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  FILE *f;
+  unsigned int size;
+  uint8_t *buffer;
+  const char *outfile;
+  int status;
+
+  if (argc != 3)
+    {
+      fprintf (stderr, "usage: %s elf-file pe-file\n", argv[0]);
+      exit (1);
+    }
+
+  filename = argv[1];
+  outfile = argv[2];
+  f = fopen (filename, "rb");
+  fseek (f, 0, SEEK_END);
+  size = ftell (f);
+  fseek (f, 0, SEEK_SET);
+
+  buffer = malloc (size);
+  if (buffer == NULL)
+    {
+      fprintf (stderr, "cannot allocate %u bytes of memory\n", size);
+      exit (2);
+    }
+  if (fread (buffer, size, 1, f) != 1)
+    {
+      fprintf (stderr, "cannot read %s\n", filename);
+      exit (2);
+    }
+  fclose (f);
+
+  if (!is_elf_header (buffer))
+    {
+      fprintf (stderr, "%s is not an elf file\n", filename);
+      exit (2);
+    }
+  
+  status = convert_elf (&buffer, &size);
+  if (status != 0)
+    {
+      fprintf (stderr, "cannot convert %s to pe (err=%d)\n", filename, status);
+      exit (2);
+    }
+  
+  f = fopen (outfile, "wb");
+  if (f == NULL)
+    {
+      fprintf (stderr, "cannot open %s\n", outfile);
+      exit (2);
+    }
+  if (fwrite (buffer, size, 1, f) != 1)
+    {
+      fprintf (stderr, "cannot write to %s\n", outfile);
+      exit (2);
+    }
+  fclose (f);
+
+  return 0;
+}
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/grub-install.in grub2/util/ia64/efi/grub-install.in
--- grub2.orig/util/ia64/efi/grub-install.in	1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/grub-install.in	2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,233 @@
+#! /bin/sh
+
+# Install GRUB on your EFI partition.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+datadir=@datadir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/${PACKAGE_TARNAME}/${target_cpu}-${platform}
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}
+
+
+TARGET_CC=@TARGET_CC@
+TARGET_CFLAGS="@TARGET_CFLAGS@"
+TARGET_CPPFLAGS="@TARGET_CPPFLAGS@"
+TARGET_LDFLAGS="@TARGET_LDFLAGS@"
+OBJCOPY=@OBJCOPY@
+
+grub_setup=${sbindir}/grub-setup
+grub_mkimage=${bindir}/grub-mkimage
+grub_mkdevicemap=${sbindir}/grub-mkdevicemap
+grub_probefs=${sbindir}/grub-probefs
+rootdir=
+grub_prefix=/boot/grub
+modules=
+
+install_device=
+recheck=no
+debug=no
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-setup=FILE       use FILE as grub-setup
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+  --grub-probefs=FILE     use FILE as grub-probefs
+  --no-floppy             do not probe any floppy drive
+  --recheck               probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-setup=*)
+	grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --grub-mkdevicemap=*)
+	grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+    --grub-probefs=*)
+	grub_probefs=`echo "$option" | sed 's/--grub-probefs=//'` ;;
+    --pkglibdir=*)
+	pkglibdir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
+    --pkgdatadir=*)
+	pkgdatadir=`echo "$option" | sed 's/--pkgdatadir=//'` ;;
+    --recheck)
+	recheck=yes ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+#if test "x$install_device" = x; then
+#    echo "install_device not specified." 1>&2
+#    usage
+#    exit 1
+#fi
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot/efi
+
+grubdir=${bootdir}/grub
+device_map=${grubdir}/device.map
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# Copy the GRUB images to the GRUB directory.
+if false; then
+  for file in ${grubdir}/*.mod ${grubdir}/*.lst; do
+      if test -f $file; then
+	  rm -f $file || exit 1
+      fi
+  done
+  for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+      cp -f $file ${grubdir} || exit 1
+  done
+fi
+
+# Create the core image. First, auto-detect the filesystme module.
+#fs_module=`$grub_probefs --device-map=${device_map} ${grubdir}`
+#if test "x$fs_module" = x -a "x$modules" = x; then
+#    echo "Auto-detection of a filesystem module failed." 1>&2
+#    echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+#    exit 1
+#fi
+
+# Typically, _chain and pc are required.
+modules="$modules $fs_module _chain"
+
+modules="kernel gzio gpt fat normal ls cat fshelp help _linux linux $modules"
+modules="$modules memmap systab boot"
+
+if [ $debug = yes ]; then
+  tmpdir=.
+else
+  tmpdir=`mktemp -d /tmp/grub.XXXXXXXXXX` || exit 1
+  trap "rm -rf $tmpdir" 1 2 13 15
+fi
+
+# Generate init/fini for modules.
+modfile=$tmpdir/mod.c
+echo "/* Dummy modules.  */" > $modfile
+list=""
+init_list=""
+fini_list=""
+for m in $modules; do
+  file="$pkglibdir/${m}.mod"
+  name=`nm $file | sed -n "/ r grub_module_name/ s/.* r grub_module_name_\(.*\)/\1/p"`
+  init=`nm $file | sed -n "/ T grub_module_.*_init/ s/.* T //p"`
+  fini=`nm $file | sed -n "/ T grub_module_.*_fini/ s/.* T //p"`
+  init_list="$init_list $init"
+  fini_list="$fini_list $fini"
+  arg="\"$name\",${init:-0},${fini:-0}"
+  list="$list $arg"
+done
+echo "extern void grub_init_module (const char *, void (*init)(void *), void (*fini)(void));" >> $modfile
+echo "extern void grub_init_modules (void);" >> $modfile
+for m in $init_list; do
+  echo "extern void $m(void *);" >> $modfile
+done
+for m in $fini_list; do
+  echo "extern void $m(void);" >> $modfile
+done
+echo "void grub_init_modules (void)" >> $modfile
+echo "{" >> $modfile
+for m in $list; do
+  echo "  grub_init_module($m);" >> $modfile
+done
+echo "}" >> $modfile
+
+$TARGET_CC -c $TARGET_CFLAGS -o $tmpdir/mod.o $modfile
+
+mod_objs=
+for m in $modules; do mod_objs="$mod_objs $pkglibdir/${m}.mod"; done
+
+ld -pie -nostdlib -T $pkgdatadir/elf_ia64_efi.lds \
+ $mod_objs $tmpdir/mod.o -o $tmpdir/grub.elf 
+
+
+if ! $bindir/grub-elf2pe $tmpdir/grub.elf $grubdir/grub.efi; then
+  echo "Failed to build efi binary"
+  [ $debug = no ] && rm -rf $tmpdir
+  exit 1
+fi
+
+echo "grub.efi generated"
+
+[ $debug = no ] && rm -rf $tmpdir
+
+# Bye.
+exit 0
diff -ruNp -x '*~' -x CVS -x autom4te.cache -x '*.mk' -x configure grub2.orig/util/ia64/efi/pe32.h grub2/util/ia64/efi/pe32.h
--- grub2.orig/util/ia64/efi/pe32.h	1970-01-01 01:00:00.000000000 +0100
+++ grub2/util/ia64/efi/pe32.h	2008-01-28 16:29:58.000000000 +0100
@@ -0,0 +1,237 @@
+/* pe32.h  - PE/Coff definitions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifdef USE_PE32PLUS
+typedef uint64_t pe32_uintptr_t;
+#else
+typedef uint32_t pe32_uintptr_t;
+#endif
+
+struct pe32_coff_header
+{
+  uint16_t machine;
+  uint16_t num_sections;
+  uint32_t time;
+  uint32_t symtab_offset;
+  uint32_t num_symbols;
+  uint16_t optional_header_size;
+  uint16_t characteristics;
+};
+
+#define PE32_MACHINE_I386     0x014c
+#define PE32_MACHINE_IA64     0x0200
+#define PE32_MACHINE_EBC      0x0EBC
+#define PE32_MACHINE_X64      0x8664
+
+#define PE32_RELOCS_STRIPPED		0x0001
+#define PE32_EXECUTABLE_IMAGE		0x0002
+#define PE32_LINE_NUMS_STRIPPED		0x0004
+#define PE32_LOCAL_SYMS_STRIPPED	0x0008
+#define PE32_AGGRESSIVE_WS_TRIM		0x0010
+#define PE32_LARGE_ADDRESS_AWARE	0x0020
+#define PE32_16BIT_MACHINE		0x0040
+#define PE32_BYTES_REVERSED_LO		0x0080
+#define PE32_32BIT_MACHINE		0x0100
+#define PE32_DEBUG_STRIPPED		0x0200
+#define PE32_REMOVABLE_RUN_FROM_SWAP	0x0400
+#define PE32_SYSTEM			0x1000
+#define PE32_DLL			0x2000
+#define PE32_UP_SYSTEM_ONLY		0x4000
+#define PE32_BYTES_REVERSED_HI		0x8000
+
+struct pe32_data_directory
+{
+  uint32_t rva;
+  uint32_t size;
+};
+
+struct pe32_optional_header
+{
+  uint16_t magic;
+  uint8_t major_linker_version;
+  uint8_t minor_linker_version;
+  uint32_t code_size;
+  uint32_t data_size;
+  uint32_t bss_size;
+  uint32_t entry_addr;
+  uint32_t code_base;
+  
+#ifndef USE_PE32PLUS
+  uint32_t data_base;
+#endif
+
+  pe32_uintptr_t image_base;
+  uint32_t section_alignment;
+  uint32_t file_alignment;
+  uint16_t major_os_version;
+  uint16_t minor_os_version;
+  uint16_t major_image_version;
+  uint16_t minor_image_version;
+  uint16_t major_subsystem_version;
+  uint16_t minor_subsystem_version;
+  uint32_t reserved;
+  uint32_t image_size;
+  uint32_t header_size;
+  uint32_t checksum;
+  uint16_t subsystem;
+  uint16_t dll_characteristics;
+  pe32_uintptr_t stack_reserve_size;
+  pe32_uintptr_t stack_commit_size;
+  pe32_uintptr_t heap_reserve_size;
+  pe32_uintptr_t heap_commit_size;
+  uint32_t loader_flags;
+  uint32_t num_data_directories;
+  
+  /* Data directories.  */
+  struct pe32_data_directory export_table;
+  struct pe32_data_directory import_table;
+  struct pe32_data_directory resource_table;
+  struct pe32_data_directory exception_table;
+  struct pe32_data_directory certificate_table;
+  struct pe32_data_directory base_relocation_table;
+  struct pe32_data_directory debug;
+  struct pe32_data_directory architecture;
+  struct pe32_data_directory global_ptr;
+  struct pe32_data_directory tls_table;
+  struct pe32_data_directory load_config_table;
+  struct pe32_data_directory bound_import;
+  struct pe32_data_directory iat;
+  struct pe32_data_directory delay_import_descriptor;
+  struct pe32_data_directory com_runtime_header;
+  struct pe32_data_directory reserved_entry;
+};
+
+#define PE32_PE32_MAGIC	0x10b
+#define PE32_PE64_MAGIC	0x20b
+
+#define PE32_SUBSYSTEM_EFI_APPLICATION	       10
+#define PE32_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define PE32_SUBSYSTEM_EFI_RUNTIME_DRIVER      12
+#define PE32_SUBSYSTEM_EFI_EFI_ROM             13
+
+#define PE32_NUM_DATA_DIRECTORIES	16
+
+struct pe32_section_header
+{
+  char name[8];
+  uint32_t virtual_size;
+  uint32_t virtual_address;
+  uint32_t raw_data_size;
+  uint32_t raw_data_offset;
+  uint32_t relocations_offset;
+  uint32_t line_numbers_offset;
+  uint16_t num_relocations;
+  uint16_t num_line_numbers;
+  uint32_t characteristics;
+};
+
+#define PE32_SCN_CNT_CODE		0x00000020
+#define PE32_SCN_CNT_INITIALIZED_DATA	0x00000040
+#define PE32_SCN_MEM_DISCARDABLE	0x02000000
+#define PE32_SCN_MEM_EXECUTE		0x20000000
+#define PE32_SCN_MEM_READ		0x40000000
+#define PE32_SCN_MEM_WRITE		0x80000000
+
+struct pe32_dos_header
+{
+  uint16_t  magic;    // Magic number
+  uint16_t  cblp;     // Bytes on last page of file
+  uint16_t  cp;       // Pages in file
+  uint16_t  crlc;     // Relocations
+  uint16_t  cparhdr;  // Size of header in paragraphs
+  uint16_t  minalloc; // Minimum extra paragraphs needed
+  uint16_t  maxalloc; // Maximum extra paragraphs needed
+  uint16_t  ss;       // Initial (relative) SS value
+  uint16_t  sp;       // Initial SP value
+  uint16_t  csum;     // Checksum
+  uint16_t  ip;       // Initial IP value
+  uint16_t  cs;       // Initial (relative) CS value
+  uint16_t  lfa_rlc;   // File address of relocation table
+  uint16_t  ov_no;     // Overlay number
+  uint16_t  res[4];   // Reserved words
+  uint16_t  oem_id;    // OEM identifier (for e_oeminfo)
+  uint16_t  oem_info;  // OEM information; e_oemid specific
+  uint16_t  res2[10]; // Reserved words
+  uint32_t  new_hdr_offset;
+
+  uint16_t  stub[0x20];
+};
+
+struct pe32_nt_header
+{
+  /* This is always PE\0\0.  */
+  char signature[4];
+
+  /* The COFF file header.  */
+  struct pe32_coff_header coff_header;
+
+  /* The Optional header.  */
+  struct pe32_optional_header optional_header;
+};
+
+struct pe32_base_relocation
+{
+  uint32_t page_rva;
+  uint32_t block_size;
+};
+
+struct pe32_fixup_block
+{
+  uint32_t page_rva;
+  uint32_t block_size;
+  uint16_t entries[0];
+};
+
+#define PE32_FIXUP_ENTRY(type, offset)	(((type) << 12) | (offset))
+
+#define PE32_REL_BASED_ABSOLUTE	    0
+#define PE32_REL_BASED_HIGHLOW	    3
+#define PE32_REL_BASED_IA64_IMM64   9
+#define PE32_REL_BASED_DIR64        10
+
+#define PE32_DEBUG_TYPE_CODEVIEW 2
+struct pe32_debug_directory_entry {
+  uint32_t  characteristics;
+  uint32_t  time;
+  uint16_t  major_version;
+  uint16_t  minor_version;
+  uint32_t  type;
+  uint32_t  data_size;
+  uint32_t  rva;
+  uint32_t  file_offset;
+};
+
+#define PE32_CODEVIEW_SIGNATURE_NB10 0x3031424E  // "NB10"
+struct pe32_debug_codeview_nb10_entry {
+  uint32_t  signature;                        // "NB10"
+  uint32_t  unknown[3];
+  char filename[0];  /* Filename of .PDB */
+};
+
+
+#if 1
+#define pe32_check(name, x) extern char pe32_check_##name [x ? 1 : -1]
+#ifdef USE_PE32PLUS
+#define PE32_HEADER_SIZE 112
+#else
+#define PE32_HEADER_SIZE 96
+#endif
+
+pe32_check(optional_header, sizeof (struct pe32_optional_header) == PE32_HEADER_SIZE + PE32_NUM_DATA_DIRECTORIES * 8);
+#endif
+

  parent reply	other threads:[~2008-01-29  5:42 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-28 16:09 IA64 port Tristan Gingold
2008-01-28 16:55 ` Robert Millan
2008-01-29  5:12   ` Tristan Gingold
2008-01-29  9:17     ` Robert Millan
2008-01-29 10:31       ` tgingold
2008-01-29 11:08         ` Robert Millan
2008-01-29  9:59     ` Robert Millan
2008-01-29 10:35       ` tgingold
2008-01-29 11:32         ` Robert Millan
2008-01-29 12:56           ` tgingold
2008-01-29 13:19             ` Robert Millan
2008-01-29 14:46               ` Marco Gerards
2008-01-29 15:30                 ` Robert Millan
2008-01-29 16:38                   ` tgingold
2008-01-29 18:48                     ` Robert Millan
2008-01-30  5:23                       ` Tristan Gingold
2008-01-30 13:19                         ` Robert Millan
2008-01-29 16:35                 ` tgingold
2008-01-30  5:48                 ` Tristan Gingold
2008-01-30 15:07                   ` Robert Millan
2008-01-30 15:33                     ` Robert Millan
2008-01-30 16:22                     ` tgingold
2008-01-30 18:38                       ` Robert Millan
2008-02-04 15:45                   ` Marco Gerards
2008-02-04 16:07                     ` Robert Millan
2008-02-05  9:51                       ` tgingold
2008-02-10 22:43                   ` Alexandre Boeglin
2008-02-11  8:59                     ` tgingold
2010-01-18 18:03                   ` Robert Millan
2008-01-30  5:48                 ` Tristan Gingold
2008-01-30  5:57                 ` Tristan Gingold
2008-01-30 13:25                   ` Robert Millan
2008-01-30 16:04                     ` tgingold
2008-03-19 17:11                       ` Robert Millan
2008-03-20  6:34                         ` Tristan Gingold
2008-02-05 22:49       ` Alexandre Boeglin
2008-01-29  5:49   ` Tristan Gingold [this message]
2008-01-29  9:08     ` Robert Millan
2008-01-29 10:10       ` tgingold
2008-01-29 11:07         ` Robert Millan
2008-01-29 12:53           ` tgingold
2008-01-29 13:39             ` Robert Millan
2008-01-29 13:36     ` Robert Millan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080129054931.GA12985@saphi \
    --to=tgingold@free.fr \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.