ARM 64 port by Leif Lindholm
authorLeif Lindholm <leif.lindholm@linaro.org>
Sat, 16 Nov 2013 19:52:55 +0000 (20:52 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 19:52:55 +0000 (20:52 +0100)
26 files changed:
Makefile.util.def
conf/Makefile.common
configure.ac
gentpl.py
grub-core/Makefile.am
grub-core/Makefile.core.def
grub-core/kern/arm64/cache.c [new file with mode: 0644]
grub-core/kern/arm64/cache_flush.S [new file with mode: 0644]
grub-core/kern/arm64/dl.c [new file with mode: 0644]
grub-core/kern/arm64/dl_helper.c [new file with mode: 0644]
grub-core/kern/arm64/efi/startup.S [new file with mode: 0644]
grub-core/lib/arm64/setjmp.S [new file with mode: 0644]
grub-core/lib/efi/halt.c
grub-core/lib/setjmp.S
include/grub/arm64/efi/memory.h [new file with mode: 0644]
include/grub/arm64/reloc.h [new file with mode: 0644]
include/grub/arm64/setjmp.h [new file with mode: 0644]
include/grub/arm64/time.h [new file with mode: 0644]
include/grub/arm64/types.h [new file with mode: 0644]
include/grub/efi/api.h
include/grub/efi/pe32.h
include/grub/elf.h
include/grub/util/install.h
util/grub-install.c
util/grub-mkimagexx.c
util/mkimage.c

index ede7468..b17c89b 100644 (file)
@@ -156,6 +156,8 @@ library = {
   common = grub-core/io/gzio.c;
   common = grub-core/io/lzopio.c;
   common = grub-core/kern/ia64/dl_helper.c;
+  common = grub-core/kern/arm/dl_helper.c;
+  common = grub-core/kern/arm64/dl_helper.c;
   common = grub-core/lib/minilzo/minilzo.c;
   common = grub-core/lib/xzembed/xz_dec_bcj.c;
   common = grub-core/lib/xzembed/xz_dec_lzma2.c;
@@ -176,8 +178,6 @@ program = {
   extra_dist = grub-core/osdep/unix/config.c;
   common = util/config.c;
 
-  common = grub-core/kern/arm/dl_helper.c;
-
   extra_dist = util/grub-mkimagexx.c;
 
   ldadd = libgrubmods.a;
@@ -511,8 +511,6 @@ program = {
   common = grub-core/kern/emu/hostfs.c;
   common = grub-core/disk/host.c;
 
-  common = grub-core/kern/arm/dl_helper.c;
-
   common = util/resolve.c;
 
   common = grub-core/kern/emu/argp_common.c;
@@ -557,8 +555,6 @@ program = {
   common = grub-core/kern/emu/hostfs.c;
   common = grub-core/disk/host.c;
 
-  common = grub-core/kern/arm/dl_helper.c;
-
   common = util/resolve.c;
 
   common = grub-core/kern/emu/argp_common.c;
@@ -594,8 +590,6 @@ program = {
   common = grub-core/osdep/config.c;
   common = util/config.c;
 
-  common = grub-core/kern/arm/dl_helper.c;
-
   common = util/resolve.c;
   enable = noemu;
   common = grub-core/kern/emu/argp_common.c;
@@ -631,8 +625,6 @@ program = {
   common = grub-core/osdep/config.c;
   common = util/config.c;
 
-  common = grub-core/kern/arm/dl_helper.c;
-
   common = util/resolve.c;
   common = grub-core/kern/emu/argp_common.c;
   common = grub-core/osdep/init.c;
index 39d2f4d..866998a 100644 (file)
@@ -23,6 +23,9 @@ if COND_arm
   CCASFLAGS_PLATFORM = -mthumb-interwork
   LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
 endif
+if COND_arm64
+  CFLAGS_PLATFORM += -mcmodel=large
+endif
 
 #FIXME: discover and check XEN headers
 CPPFLAGS_XEN = -I/usr/include
index 9f8fb8a..b7af65c 100644 (file)
@@ -99,6 +99,9 @@ case "$target_cpu" in
   arm*)
                target_cpu=arm;
                ;;
+  aarch64*)
+               target_cpu=arm64;
+               ;;
 esac
 
 # Specify the platform (such as firmware).
@@ -120,6 +123,7 @@ if test "x$with_platform" = x; then
     mips-*) platform=arc ;;
     ia64-*) platform=efi ;;
     arm-*) platform=uboot ;;
+    arm64-*) platform=efi ;;
     *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
   esac
 else
@@ -160,6 +164,7 @@ case "$target_cpu"-"$platform" in
   mipsel-loongson) ;;
   arm-uboot) ;;
   arm-efi) ;;
+  arm64-efi) ;;
   *-emu) ;;
   *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
 esac
@@ -210,6 +215,7 @@ case "$platform" in
 esac
 case "$target_cpu" in
   arm)         machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM=1" ;;
+  arm64)       machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM64=1" ;;
   mips |mipsel)        machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
   sparc64)      machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
 esac
@@ -1434,6 +1440,8 @@ AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
 AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
 AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
 AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi])
+AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ])
+AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi])
 
 AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
 AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
index 3ec853e..19fab42 100644 (file)
--- a/gentpl.py
+++ b/gentpl.py
@@ -24,7 +24,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
                    "i386_xen", "x86_64_xen",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
-                   "mips_qemu_mips", "arm_uboot", "arm_efi" ]
+                   "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ]
 
 GROUPS = {}
 
@@ -38,9 +38,10 @@ GROUPS["mips"]     = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
 GROUPS["sparc64"]  = [ "sparc64_ieee1275" ]
 GROUPS["powerpc"]  = [ "powerpc_ieee1275" ]
 GROUPS["arm"]      = [ "arm_uboot", "arm_efi" ]
+GROUPS["arm64"]    = [ "arm64_efi" ]
 
 # Groups based on firmware
-GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
+GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
 GROUPS["uboot"] = [ "arm_uboot" ]
 GROUPS["xen"]  = [ "i386_xen", "x86_64_xen" ]
@@ -66,7 +67,7 @@ GROUPS["terminfomodule"]   = GRUB_PLATFORMS[:];
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
 # Flattened Device Trees (FDT)
-GROUPS["fdt"] = [ "arm_uboot", "arm_efi" ]
+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ]
 
 # Miscelaneous groups schedulded to disappear in future
 GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
index 151b933..ec76ca0 100644 (file)
@@ -234,6 +234,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 endif
 
+if COND_arm64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+endif
+
 if COND_emu
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
index 4fff57f..74aa747 100644 (file)
@@ -67,6 +67,9 @@ kernel = {
   arm_efi_ldflags          = '-Wl,-r,-d';
   arm_efi_stripflags       = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
 
+  arm64_efi_ldflags          = '-Wl,-r,-d';
+  arm64_efi_stripflags       = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
+
   i386_pc_ldflags          = '$(TARGET_IMG_LDFLAGS)';
   i386_pc_ldflags          = '$(TARGET_IMG_BASE_LDOPT),0x9000';
 
@@ -106,6 +109,7 @@ kernel = {
   powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
   arm_uboot_startup = kern/arm/uboot/startup.S;
   arm_efi_startup = kern/arm/efi/startup.S;
+  arm64_efi_startup = kern/arm64/efi/startup.S;
 
   common = kern/command.c;
   common = kern/corecmd.c;
@@ -194,6 +198,8 @@ kernel = {
   arm_efi = kern/arm/efi/init.c;
   arm_efi = kern/arm/efi/misc.c;
 
+  arm64_efi = kern/arm/efi/init.c;
+
   i386_pc = kern/i386/pc/init.c;
   i386_pc = kern/i386/pc/mmap.c;
   i386_pc = term/i386/pc/console.c;
@@ -254,6 +260,11 @@ kernel = {
   arm = kern/arm/cache.c;
   arm = kern/arm/misc.S;
 
+  arm64 = kern/arm64/cache.c;
+  arm64 = kern/arm64/cache_flush.S;
+  arm64 = kern/arm64/dl.c;
+  arm64 = kern/arm64/dl_helper.c;
+
   emu = disk/host.c;
   emu = kern/emu/cache_s.S;
   emu = kern/emu/hostdisk.c;
@@ -750,6 +761,7 @@ module = {
   enable = mips_arc;
   enable = ia64_efi;
   enable = arm_efi;
+  enable = arm64_efi;
   enable = arm_uboot;
 };
 
@@ -845,6 +857,7 @@ module = {
   ia64_efi = lib/efi/reboot.c;
   x86_64_efi = lib/efi/reboot.c;
   arm_efi = lib/efi/reboot.c;
+  arm64_efi = lib/efi/reboot.c;
   powerpc_ieee1275 = lib/ieee1275/reboot.c;
   sparc64_ieee1275 = lib/ieee1275/reboot.c;
   mips_arc = lib/mips/arc/reboot.c;
@@ -1707,6 +1720,7 @@ module = {
   enable = x86;
   enable = ia64_efi;
   enable = arm_efi;
+  enable = arm64_efi;
   enable = mips;
 };
 
diff --git a/grub-core/kern/arm64/cache.c b/grub-core/kern/arm64/cache.c
new file mode 100644 (file)
index 0000000..c13ad21
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/cache.h>
+#include <grub/misc.h>
+
+grub_int64_t grub_arch_cache_dlinesz;
+grub_int64_t grub_arch_cache_ilinesz;
+
+/* Prototypes for asm functions. */
+void grub_arch_sync_caches_real (grub_uint64_t address, grub_uint64_t end);
+
+static void
+probe_caches (void)
+{
+  grub_uint32_t cache_type;
+
+  /* Read Cache Type Register */
+  asm volatile ("mrs   %0, ctr_el0": "=r"(cache_type));
+
+  grub_arch_cache_dlinesz = 8 << ((cache_type >> 16) & 0xf);
+  grub_arch_cache_ilinesz = 8 << (cache_type & 0xf);
+
+  grub_dprintf("cache", "D$ line size: %lld\n",
+              (long long) grub_arch_cache_dlinesz);
+  grub_dprintf("cache", "I$ line size: %lld\n",
+              (long long) grub_arch_cache_ilinesz);
+}
+
+void
+grub_arch_sync_caches (void *address, grub_size_t len)
+{
+  grub_uint64_t start, end;
+
+  if (grub_arch_cache_dlinesz == 0)
+    probe_caches();
+  if (grub_arch_cache_dlinesz == 0)
+    grub_fatal ("Unknown cache line size!");
+
+  grub_dprintf("cache", "syncing caches for %p-%lx\n",
+              address, (grub_addr_t) address + len);
+
+  /* Align here to both cache lines. Saves a tiny bit of asm complexity and
+     most of potential problems with different line sizes.  */
+  start = (grub_uint64_t) address;
+  end = (grub_uint64_t) address + len;
+  start = ALIGN_DOWN (start, grub_arch_cache_dlinesz);
+  start = ALIGN_DOWN (start, grub_arch_cache_ilinesz);
+
+  end = ALIGN_UP (end, grub_arch_cache_dlinesz);
+  end = ALIGN_UP (end, grub_arch_cache_ilinesz);
+
+  grub_dprintf("cache", "aligned to: %lx-%lx\n",
+              start, end);
+
+  grub_arch_sync_caches_real (start, end);
+}
diff --git a/grub-core/kern/arm64/cache_flush.S b/grub-core/kern/arm64/cache_flush.S
new file mode 100644 (file)
index 0000000..1a35120
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/symbol.h>
+
+       .file   "cache_flush.S"
+       .text
+
+/*
+ * Simple cache maintenance functions
+ */
+
+// r0 - *beg (inclusive)
+// r1 - *end (exclusive)
+clean_dcache_range:
+       // Clean data cache for range to point-of-unification
+       ldr     x2, =EXT_C(grub_arch_cache_dlinesz)
+       ldr     x2, [x2]
+1:     cmp     x0, x1
+       bge     2f
+       dc      cvau, x0                // Clean Virtual Address to PoU
+       add     x0, x0, x2              // Next line
+       b       1b
+2:     dsb     ish
+       ret
+
+// r0 - *beg (inclusive)
+// r1 - *end (exclusive)
+invalidate_icache_range:
+       // Invalidate instruction cache for range to point-of-unification
+       ldr     x2, =EXT_C(grub_arch_cache_ilinesz)
+       ldr     x2, [x2]
+1:     cmp     x0, x1
+       bge     2f
+       ic      ivau, x0                // Invalidate Virtual Address to PoU
+       add     x0, x0, x2              // Next line
+       b       1b
+       // Branch predictor invalidation not needed on AArch64
+2:     dsb     ish
+       isb
+       ret
+
+// void grub_arch_sync_caches_real (void *address, grub_size_t len)
+FUNCTION(grub_arch_sync_caches_real)
+       dsb     ish
+       stp     x0, x30, [sp, #-16]!
+       stp     x0, x1, [sp, #-16]!
+       bl      clean_dcache_range
+       ldp     x0, x1, [sp], #16
+       bl      invalidate_icache_range
+       ldp     x0, x30, [sp], #16
+       ret
diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c
new file mode 100644 (file)
index 0000000..afd0de2
--- /dev/null
@@ -0,0 +1,199 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+#include <grub/cpu/reloc.h>
+
+/*
+ * Check if EHDR is a valid ELF header.
+ */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS64
+      || e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_AARCH64)
+    return grub_error (GRUB_ERR_BAD_OS,
+                      N_("invalid arch-dependent ELF magic"));
+
+  return GRUB_ERR_NONE;
+}
+
+/*
+ * Unified function for both REL and RELA 
+ */
+static grub_err_t
+do_relX (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod)
+{
+  grub_err_t retval;
+  grub_dl_segment_t segment;
+  Elf_Rel *rel;
+  Elf_Rela *rela;
+  Elf_Sym *symbol;
+  int i, entnum;
+  unsigned long long  entsize;
+
+  /* Find the target segment for this relocation section. */
+  for (segment = mod->segment ; segment != 0 ; segment = segment->next)
+    if (segment->section == relhdr->sh_info)
+      break;
+  if (!segment)
+    return grub_error (GRUB_ERR_EOF, N_("relocation segment not found"));
+
+  rel = (Elf_Rel *) ((grub_addr_t) e + relhdr->sh_offset);
+  rela = (Elf_Rela *) rel;
+  if (relhdr->sh_type == SHT_RELA)
+    entsize = sizeof (Elf_Rela);
+  else
+    entsize = sizeof (Elf_Rel);
+
+  entnum = relhdr->sh_size / entsize;
+  retval = GRUB_ERR_NONE;
+
+  grub_dprintf("dl", "Processing %d relocation entries.\n", entnum);
+
+  /* Step through all relocations */
+  for (i = 0, symbol = mod->symtab; i < entnum; i++)
+    {
+      void *place;
+      grub_uint64_t sym_addr, symidx, reltype;
+
+      if (rel->r_offset >= segment->size)
+       return grub_error (GRUB_ERR_BAD_MODULE,
+                          "reloc offset is out of the segment");
+
+      symidx = ELF_R_SYM (rel->r_info);
+      reltype = ELF_R_TYPE (rel->r_info);
+
+      sym_addr = symbol[symidx].st_value;
+      if (relhdr->sh_type == SHT_RELA)
+       sym_addr += rela->r_addend;
+
+      place = (void *) ((grub_addr_t) segment->addr + rel->r_offset);
+
+      switch (reltype)
+       {
+       case R_AARCH64_ABS64:
+         {
+           grub_uint64_t *abs_place = place;
+
+           grub_dprintf ("dl", "  reloc_abs64 %p => 0x%016llx\n",
+                         place, (unsigned long long) sym_addr);
+
+           *abs_place = (grub_uint64_t) sym_addr;
+         }
+         break;
+       case R_AARCH64_CALL26:
+       case R_AARCH64_JUMP26:
+         retval = grub_arm64_reloc_xxxx26 (place, sym_addr);
+         break;
+       default:
+         return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                            N_("relocation 0x%x is not implemented yet"),
+                            reltype);
+       }
+
+      if (retval != GRUB_ERR_NONE)
+       break;
+
+      rel = (Elf_Rel *) ((grub_addr_t) rel + entsize);
+      rela++;
+    }
+
+  return retval;
+}
+
+/*
+ * Verify that provided ELF header contains reference to a symbol table
+ */
+static int
+has_symtab (Elf_Ehdr * e)
+{
+  int i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *) ((grub_addr_t) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      return 1;
+
+  return 0;
+}
+
+/*
+ * grub_arch_dl_relocate_symbols():
+ *   Locates the relocations section of the ELF object, and calls
+ *   do_relX() to deal with it.
+ */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  unsigned i;
+
+  if (!has_symtab (e))
+    return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
+
+#define FIRST_SHDR(x) ((Elf_Shdr *) ((grub_addr_t)(x) + (x)->e_shoff))
+#define NEXT_SHDR(x, y) ((Elf_Shdr *) ((grub_addr_t)(y) + (x)->e_shentsize))
+
+  for (i = 0, s = FIRST_SHDR (e); i < e->e_shnum; i++, s = NEXT_SHDR (e, s))
+    {
+      grub_err_t ret;
+
+      switch (s->sh_type)
+       {
+       case SHT_REL:
+       case SHT_RELA:
+         {
+           ret = do_relX (s, e, mod);
+           if (ret != GRUB_ERR_NONE)
+             return ret;
+         }
+         break;
+       case SHT_ARM_ATTRIBUTES:
+       case SHT_NOBITS:
+       case SHT_NULL:
+       case SHT_PROGBITS:
+       case SHT_SYMTAB:
+       case SHT_STRTAB:
+         break;
+       default:
+         {
+           grub_dprintf ("dl", "unhandled section_type: %d (0x%08x)\n",
+                         s->sh_type, s->sh_type);
+           return GRUB_ERR_NOT_IMPLEMENTED_YET;
+         };
+       }
+    }
+
+#undef FIRST_SHDR
+#undef NEXT_SHDR
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/arm64/dl_helper.c b/grub-core/kern/arm64/dl_helper.c
new file mode 100644 (file)
index 0000000..b2f7ee5
--- /dev/null
@@ -0,0 +1,70 @@
+/* dl_helper.c - relocation helper functions for modules and grub-mkimage */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+#include <grub/cpu/reloc.h>
+
+static grub_ssize_t
+sign_compress_offset (grub_ssize_t offset, int bitpos)
+{
+  return offset & ((1LL << (bitpos + 1)) - 1);
+}
+
+/*
+ * grub_arm64_reloc_xxxx26():
+ *
+ * JUMP26/CALL26 relocations for B and BL instructions.
+ */
+
+grub_err_t
+grub_arm64_reloc_xxxx26 (grub_uint32_t *place, Elf64_Addr adjust)
+{
+  grub_uint32_t insword, insmask;
+  grub_ssize_t offset;
+  const grub_ssize_t offset_low = -(1 << 27), offset_high = (1 << 27) - 1;
+
+  insword = grub_le_to_cpu32 (*place);
+  insmask = 0xfc000000;
+
+  offset = adjust;
+#ifndef GRUB_UTIL
+  offset -= (grub_addr_t) place;
+#endif
+
+  if ((offset < offset_low) || (offset > offset_high))
+    {
+      return grub_error (GRUB_ERR_BAD_MODULE,
+                        N_("CALL26 Relocation out of range"));
+    }
+
+  grub_dprintf ("dl", "  reloc_xxxx64 %p %c= 0x%llx\n",
+               place, offset > 0 ? '+' : '-',
+               offset < 0 ? (long long) -(unsigned long long) offset : offset);
+
+  offset = sign_compress_offset (offset, 27) >> 2;
+
+  *place = grub_cpu_to_le32 ((insword & insmask) | offset);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S
new file mode 100644 (file)
index 0000000..781c2b0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/symbol.h>
+
+       .file   "startup.S"
+       .text
+FUNCTION(_start)
+       /*
+        *  EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0.
+        */
+       ldr     x2, =EXT_C(grub_efi_image_handle)
+       str     x0, [x2]
+       ldr     x2, =EXT_C(grub_efi_system_table)
+       str     x1, [x2]
+       ldr     x2, =EXT_C(grub_main)
+       br      x2
+
+       .end
diff --git a/grub-core/lib/arm64/setjmp.S b/grub-core/lib/arm64/setjmp.S
new file mode 100644 (file)
index 0000000..adaafe4
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/symbol.h>
+
+       .file   "setjmp.S"
+       .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       stp     x19, x20, [x0], #16
+       stp     x21, x22, [x0], #16
+       stp     x23, x24, [x0], #16
+       stp     x25, x26, [x0], #16
+       stp     x27, x28, [x0], #16
+       stp     x29, x30, [x0], #16
+       mov     x1, sp
+       str     x1, [x0]
+       mov     x0, #0
+       ret
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       ldp     x19, x20, [x0], #16
+       ldp     x21, x22, [x0], #16
+       ldp     x23, x24, [x0], #16
+       ldp     x25, x26, [x0], #16
+       ldp     x27, x28, [x0], #16
+       ldp     x29, x30, [x0], #16
+       ldr     x2, [x0]
+       mov     sp, x2
+       cmp     x1, #0
+       csel    x0, x1, x0, ne
+       ret
index ce93db3..e9441c8 100644 (file)
@@ -29,7 +29,7 @@ void
 grub_halt (void)
 {
   grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
-#if !defined(__ia64__) && !defined(__arm__)
+#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__)
   grub_acpi_halt ();
 #endif
   efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
index feb7b43..f6e4905 100644 (file)
@@ -13,6 +13,8 @@
 #include "./ia64/longjmp.S"
 #elif defined(__arm__)
 #include "./arm/setjmp.S"
+#elif defined(__aarch64__)
+#include "./arm64/setjmp.S"
 #else
 #error "Unknown target cpu type"
 #endif
diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h
new file mode 100644 (file)
index 0000000..c9a61bb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/include/grub/arm64/reloc.h b/include/grub/arm64/reloc.h
new file mode 100644 (file)
index 0000000..606d71c
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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_ARM64_RELOC_H
+#define GRUB_ARM64_RELOC_H 1
+
+grub_err_t grub_arm64_reloc_xxxx26 (grub_uint32_t *target, Elf64_Addr sym_addr);
+
+#endif
diff --git a/include/grub/arm64/setjmp.h b/include/grub/arm64/setjmp.h
new file mode 100644 (file)
index 0000000..3ff7dfb
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef unsigned long long grub_jmp_buf[13];
+
+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE;
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/arm64/time.h b/include/grub/arm64/time.h
new file mode 100644 (file)
index 0000000..4128506
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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: this can't work until we handle interrupts.  */
+/*  __asm__ __volatile__ ("wfi"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/arm64/types.h b/include/grub/arm64/types.h
new file mode 100644 (file)
index 0000000..d132c5e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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
+
+/* currently only support little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+/* Unaligned accesses only supported if MMU enabled */
+#undef GRUB_HAVE_UNALIGNED_ACCESS
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
index f750340..3af0911 100644 (file)
@@ -1534,7 +1534,8 @@ struct grub_efi_block_io
 };
 typedef struct grub_efi_block_io grub_efi_block_io_t;
 
-#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__)
+#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
+  || defined (__aarch64__)
 
 #define efi_call_0(func)               func()
 #define efi_call_1(func, a)            func(a)
index 7cacabd..4adea60 100644 (file)
@@ -67,6 +67,7 @@ struct grub_pe32_coff_header
 #define GRUB_PE32_MACHINE_IA64                 0x200
 #define GRUB_PE32_MACHINE_X86_64               0x8664
 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED       0x01c2
+#define GRUB_PE32_MACHINE_ARM64                        0xAA64
 
 #define GRUB_PE32_RELOCS_STRIPPED              0x0001
 #define GRUB_PE32_EXECUTABLE_IMAGE             0x0002
index f64d6a8..140d24d 100644 (file)
@@ -246,6 +246,7 @@ typedef struct
 #define EM_ARC_A5      93              /* ARC Cores Tangent-A5 */
 #define EM_XTENSA      94              /* Tensilica Xtensa Architecture */
 #define EM_NUM         95
+#define EM_AARCH64     183             /* ARM 64-bit architecture */
 
 /* If it is necessary to assign new unofficial EM_* values, please
    pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@@ -2062,6 +2063,21 @@ typedef Elf32_Addr Elf32_Conflict;
 #define SHT_ARM_ATTRIBUTES     (SHT_LOPROC + 3) /* ARM attributes section.  */
 
 
+/* AArch64 relocs.  */
+#define R_AARCH64_NONE                 0       /* No relocation.  */
+#define R_AARCH64_ABS64                        257     /* Direct 64 bit. */
+#define R_AARCH64_ABS32                        258     /* Direct 32 bit.  */
+#define R_AARCH64_JUMP26               282     /* 26-bit relative. */
+#define R_AARCH64_CALL26               283     /* 26-bit relative. */
+#define R_AARCH64_COPY                 1024    /* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT             1025    /* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT            1026    /* Create PLT entry.  */
+#define R_AARCH64_RELATIVE             1027    /* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD64         1028    /* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL64         1029    /* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL64          1030    /* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC              1031    /* TLS Descriptor.  */
+
 /* ARM relocs.  */
 #define R_ARM_NONE             0       /* No reloc */
 #define R_ARM_PC24             1       /* PC relative 26 bit branch */
index c1cd6b3..0aead0a 100644 (file)
@@ -87,6 +87,7 @@ enum grub_install_plat
     GRUB_INSTALL_PLATFORM_ARM_EFI,
     GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS,
     GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
+    GRUB_INSTALL_PLATFORM_ARM64_EFI,
     GRUB_INSTALL_PLATFORM_MAX
   };
 
index 100f093..b9b6e69 100644 (file)
@@ -256,6 +256,8 @@ get_default_platform (void)
    return "ia64-efi";
 #elif defined (__arm__)
    return "arm-uboot";
+#elif defined (__aarch64__)
+   return "arm64-efi";
 #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__)
    return grub_install_get_default_x86_platform ();
 #else
@@ -389,6 +391,7 @@ have_bootdev (enum grub_install_plat pl)
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
     case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
@@ -736,6 +739,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_I386_EFI:
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
@@ -773,6 +777,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_I386_EFI:
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
     case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
@@ -818,6 +823,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_I386_EFI:
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       is_efi = 1;
       break;
@@ -922,6 +928,9 @@ main (int argc, char *argv[])
            case GRUB_INSTALL_PLATFORM_ARM_EFI:
              efi_file = "BOOTARM.EFI";
              break;
+           case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+             efi_file = "BOOTAARCH64.EFI";
+             break;
            default:
              grub_util_error ("%s", _("You've found a bug"));
              break;
@@ -946,6 +955,9 @@ main (int argc, char *argv[])
            case GRUB_INSTALL_PLATFORM_ARM_EFI:
              efi_file = "grubarm.efi";
              break;
+           case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+             efi_file = "grubarm64.efi";
+             break;
            default:
              efi_file = "grub.efi";
              break;
@@ -1171,6 +1183,7 @@ main (int argc, char *argv[])
                  case GRUB_INSTALL_PLATFORM_I386_EFI:
                  case GRUB_INSTALL_PLATFORM_X86_64_EFI:
                  case GRUB_INSTALL_PLATFORM_ARM_EFI:
+                 case GRUB_INSTALL_PLATFORM_ARM64_EFI:
                  case GRUB_INSTALL_PLATFORM_IA64_EFI:
                    g = grub_util_guess_efi_drive (*curdev);
                    break;
@@ -1258,6 +1271,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_I386_EFI:
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       core_name = "core.efi";
       snprintf (mkimage_target, sizeof (mkimage_target),
@@ -1358,6 +1372,7 @@ main (int argc, char *argv[])
       }
       break;
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
     case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS:
     case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
@@ -1488,6 +1503,7 @@ main (int argc, char *argv[])
 
     case GRUB_INSTALL_PLATFORM_X86_64_EFI:
     case GRUB_INSTALL_PLATFORM_ARM_EFI:
+    case GRUB_INSTALL_PLATFORM_ARM64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
       {
        char *dst = grub_util_path_concat (2, efidir, efi_file);
index 36a683d..b88e9b9 100644 (file)
@@ -718,6 +718,35 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
                  break;
                }
               break;
+            case EM_AARCH64:
+              {
+                sym_addr += addend;
+                switch (ELF_R_TYPE (info))
+                  {
+                  case R_AARCH64_ABS64:
+                    {
+                      *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+                    }
+                    break;
+                  case R_AARCH64_JUMP26:
+                  case R_AARCH64_CALL26:
+                    {
+                      grub_err_t err;
+                      sym_addr -= offset;
+                      sym_addr -= SUFFIX (entry_point);
+                      err = grub_arm64_reloc_xxxx26((grub_uint32_t *)target,
+                                                    sym_addr);
+                      if (err)
+                        grub_util_error ("%s", grub_errmsg);
+                    }
+                    break;
+                  default:
+                    grub_util_error (_("relocation %d is not implemented yet"),
+                                     (unsigned long long) ELF_R_TYPE (info));
+                    break;
+                  }
+              break;
+              }
 #endif
 #if defined(MKIMAGE_ELF32)
             case EM_ARM:
@@ -995,6 +1024,32 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out,
                  break;
                }
                break;
+             case EM_AARCH64:
+               switch (ELF_R_TYPE (info))
+                 {
+                 case R_AARCH64_ABS64:
+                   {
+                     Elf_Addr addr;
+
+                     addr = section_address + offset;
+                     current_address
+                       = SUFFIX (add_fixup_entry) (&lst,
+                                                   GRUB_PE32_REL_BASED_DIR64,
+                                                   addr, 0, current_address,
+                                                   image_target);
+                   }
+                   break;
+                   /* Relative relocations do not require fixup entries. */
+                 case R_AARCH64_CALL26:
+                 case R_AARCH64_JUMP26:
+                   break;
+                 default:
+                   grub_util_error (_("fixup for relocation %d is not implemented yet"),
+                                    (unsigned long long) ELF_R_TYPE (info));
+                   break;
+                 }
+               break;
+               break;
 #if defined(MKIMAGE_ELF32)
              case EM_ARM:
                switch (ELF_R_TYPE (info))
@@ -1358,7 +1413,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
                                          image_target);
       if (*start == 0)
        grub_util_error ("start symbol is not defined");
-      
+
       SUFFIX (entry_point) = (Elf_Addr) *start;
 
       /* Resolve addresses in the virtual address space.  */
@@ -1367,7 +1422,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
                                   num_sections, strtab,
                                   out_img, ia64_toff, ia64_got_off,
                                   image_target);
-         
+
       *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
                                                 section_vaddresses, sections,
                                                 section_entsize, num_sections,
index 4a51022..4bc82df 100644 (file)
@@ -42,6 +42,7 @@
 #include <grub/efi/pe32.h>
 #include <grub/uboot/image.h>
 #include <grub/arm/reloc.h>
+#include <grub/arm64/reloc.h>
 #include <grub/ia64/reloc.h>
 #include <grub/osdep/hostfile.h>
 #include <grub/util/install.h>
@@ -578,6 +579,22 @@ static const struct grub_install_image_target_desc image_targets[] =
       .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
       .elf_target = EM_ARM,
     },
+    {
+      .dirname = "arm64-efi",
+      .names = { "arm64-efi", NULL },
+      .voidp_sizeof = 8,
+      .bigendian = 0,
+      .id = IMAGE_EFI,
+      .flags = PLATFORM_FLAGS_NONE,
+      .total_module_size = TARGET_NO_FIELD,
+      .decompressor_compressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .section_align = GRUB_PE32_SECTION_ALIGNMENT,
+      .vaddr_offset = EFI64_HEADER_SIZE,
+      .pe_target = GRUB_PE32_MACHINE_ARM64,
+      .elf_target = EM_AARCH64,
+    },
   };
 
 #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))