From 3c31404703e92f675a71ab83bfb1e5c6f27e9070 Mon Sep 17 00:00:00 2001
From: sunway_fw <sunway_fw@wxiat.com>
Date: Tue, 18 Feb 2025 15:59:36 +0800
Subject: [PATCH 5/5] sw64: Add to build system

This patch adds SW64 to the GRUB build system and various tools, so GRUB
can be built on SW64 as a UEFI application.

Signed-off-by: sunway_fw <sunway_fw@wxiat.com>
---
 Makefile.util.def            |  1 +
 conf/Makefile.common         |  3 +++
 configure.ac                 |  4 ++++
 gentpl.py                    |  8 +++++---
 grub-core/Makefile.am        |  7 +++++++
 grub-core/Makefile.core.def  | 18 ++++++++++++++++++
 grub-core/commands/file.c    | 11 ++++++++++-
 grub-core/kern/compiler-rt.c |  2 +-
 grub-core/lib/setjmp.S       |  2 ++
 include/grub/compiler-rt.h   |  2 +-
 include/grub/efi/pe32.h      |  1 +
 include/grub/util/install.h  |  1 +
 util/grub-install-common.c   |  1 +
 util/grub-install.c          | 16 ++++++++++++++++
 util/grub-mknetdir.c         |  1 +
 util/grub-mkrescue.c         | 10 ++++++++--
 util/mkimage.c               | 16 ++++++++++++++++
 17 files changed, 96 insertions(+), 8 deletions(-)

diff --git a/Makefile.util.def b/Makefile.util.def
index ae3df11..aef0613 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -148,6 +148,7 @@ library = {
   common = grub-core/kern/arm/dl_helper.c;
   common = grub-core/kern/arm64/dl_helper.c;
   common = grub-core/kern/loongarch64/dl_helper.c;
+  common = grub-core/kern/sw64/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;
diff --git a/conf/Makefile.common b/conf/Makefile.common
index b8f216f..f3ab6b9 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -23,6 +23,9 @@ endif
 if COND_HAVE_PCI
   CFLAGS_PLATFORM += -DGRUB_HAS_PCI
 endif
+if COND_sw_64_efi
+  CFLAGS_PLATFORM += -Wno-packed-not-aligned -Wno-cast-align -Wno-sign-compare
+endif
 
 # Other options
 
diff --git a/configure.ac b/configure.ac
index 96f4f5e..89626d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -151,6 +151,7 @@ case "$target_cpu" in
 		;;
   riscv32*)	target_cpu=riscv32 ;;
   riscv64*)	target_cpu=riscv64 ;;
+  sw_64*)       target_cpu=sw64;;
 esac
 
 # Specify the platform (such as firmware).
@@ -177,6 +178,7 @@ if test "x$with_platform" = x; then
     loongarch64-*) platform=efi;;
     riscv32-*) platform=efi ;;
     riscv64-*) platform=efi ;;
+    sw64-*) platform=efi ;;
     *)
       AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities])
       platform=none
@@ -228,6 +230,7 @@ case "$target_cpu"-"$platform" in
   loongarch64-efi) ;;
   riscv32-efi) ;;
   riscv64-efi) ;;
+  sw64-efi) ;;
   *-emu) ;;
   *-none) ;;
   *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
@@ -2192,6 +2195,7 @@ AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ])
 AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ])
 AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi])
 AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_sw_64_efi], [test x$target_cpu = xsw64 -a x$platform = xefi])
 AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
 AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu])
 AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
diff --git a/gentpl.py b/gentpl.py
index 3dc607c..af6ce15 100644
--- a/gentpl.py
+++ b/gentpl.py
@@ -32,7 +32,8 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
                    "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
-                   "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
+                   "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi",
+                   "sw_64_efi" ]
 
 GROUPS = {}
 
@@ -50,10 +51,11 @@ GROUPS["arm64"]       = [ "arm64_efi" ]
 GROUPS["loongarch64"] = [ "loongarch64_efi" ]
 GROUPS["riscv32"]     = [ "riscv32_efi" ]
 GROUPS["riscv64"]     = [ "riscv64_efi" ]
+GROUPS["sw_64"]       = [ "sw_64_efi" ]
 
 # Groups based on firmware
 GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi",
-		   "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
+		   "loongarch64_efi", "riscv32_efi", "riscv64_efi", "sw_64_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
 GROUPS["uboot"] = [ "arm_uboot" ]
 GROUPS["xen"]  = [ "i386_xen", "x86_64_xen" ]
@@ -80,7 +82,7 @@ GROUPS["terminfomodule"]   = GRUB_PLATFORMS[:];
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
 # Flattened Device Trees (FDT)
-GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi", "sw_64_efi" ]
 
 # Needs software helpers for division
 # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index b524445..b6b1390 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -309,6 +309,13 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
 endif
 
+if COND_sw_64_efi
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sw64/divide.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+endif
+
 if COND_emu
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 1329b81..e781677 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -103,6 +103,8 @@ kernel = {
   sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
   mips_arc_ldflags    = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
   mips_qemu_mips_ldflags    = '-Wl,-Ttext,0x80200000';
+  sw_64_efi_ldflags = '-Wl,-r,-d';
+  sw_64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
 
   mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
   i386_qemu_cppflags     = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
@@ -133,6 +135,7 @@ kernel = {
   loongarch64_efi_startup = kern/loongarch64/efi/startup.S;
   riscv32_efi_startup = kern/riscv/efi/startup.S;
   riscv64_efi_startup = kern/riscv/efi/startup.S;
+  sw_64_efi_startup = kern/sw64/efi/startup.S;
 
   common = kern/buffer.c;
   common = kern/command.c;
@@ -328,6 +331,15 @@ kernel = {
   extra_dist = video/sm712_init.c;
   extra_dist = video/sis315_init.c;
   mips_loongson = commands/keylayouts.c;
+  sw_64_efi = kern/sw64/dl.c;
+  sw_64_efi = kern/sw64/dl_helper.c;
+  sw_64_efi = kern/sw64/efi/init.c;
+  sw_64_efi = kern/efi/fdt.c;
+  sw_64_efi = lib/sw64/divide.S;
+  sw_64_efi = kern/sw64/efi/callwrap.S;
+  sw_64_efi = kern/sw64/cache.c;
+  sw_64_efi = kern/sw64/cache_flush.S;
+  sw_64_efi = commands/keylayouts.c;
 
   powerpc_ieee1275 = kern/powerpc/cache.S;
   powerpc_ieee1275 = kern/powerpc/dl.c;
@@ -881,6 +893,7 @@ module = {
   enable = loongarch64_efi;
   enable = riscv32_efi;
   enable = riscv64_efi;
+  enable = sw_64_efi;
 };
 
 module = {
@@ -958,6 +971,7 @@ module = {
   i386_multiboot = commands/acpihalt.c;
   i386_efi = commands/acpihalt.c;
   x86_64_efi = commands/acpihalt.c;
+  sw_64_efi = commands/acpihalt.c;
   i386_multiboot = lib/i386/halt.c;
   i386_coreboot = lib/i386/halt.c;
   i386_qemu = lib/i386/halt.c;
@@ -1794,6 +1808,8 @@ module = {
   extra_dist = lib/arm64/setjmp.S;
   extra_dist = lib/riscv/setjmp.S;
   extra_dist = lib/loongarch64/setjmp.S;
+  extra_dist = lib/sw64/setjmp.S;
+  extra_dist = lib/sw64/divide.S;
 };
 
 module = {
@@ -1902,6 +1918,7 @@ module = {
   loongarch64 = loader/loongarch64/linux-elf.c;
   riscv32 = loader/efi/linux.c;
   riscv64 = loader/efi/linux.c;
+  sw_64_efi = loader/sw64/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   i386_efi = loader/efi/linux_boot.c;
@@ -2009,6 +2026,7 @@ module = {
   enable = riscv32_efi;
   enable = riscv64_efi;
   enable = mips;
+  enable = sw_64;
 };
 
 module = {
diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c
index 7c13e97..42b25e5 100644
--- a/grub-core/commands/file.c
+++ b/grub-core/commands/file.c
@@ -94,6 +94,8 @@ static const struct grub_arg_option options[] = {
    N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0},
   {"is-riscv64-efi", 0, 0,
    N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0},
+  {"is-sw64-efi", 0, 0,
+   N_("Check if FILE is SW64 EFI file"), 0, 0},
   {"is-hibernated-hiberfil", 0, 0,
    N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0},
   {"is-x86_64-xnu", 0, 0,
@@ -136,6 +138,7 @@ enum
   IS_ARM_EFI,
   IS_RISCV32_EFI,
   IS_RISCV64_EFI,
+  IS_SW64_EFI,
   IS_HIBERNATED,
   IS_XNU64,
   IS_XNU32,
@@ -590,6 +593,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
     case IS_ARM_EFI:
     case IS_RISCV32_EFI:
     case IS_RISCV64_EFI:
+    case IS_SW64_EFI:
       {
 	char signature[4];
 	grub_uint32_t pe_offset;
@@ -640,8 +644,13 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
 	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_RISCV64))
           /* TODO: Determine bitness dynamically */
 	  break;
+	if (type == IS_SW64_EFI
+            && coff_head.machine !=
+	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_SW_64))
+	  /* TODO: Determine bitness dynamically */
+	  break;
 	if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI ||
-	    type == IS_RISCV32_EFI || type == IS_RISCV64_EFI)
+	    type == IS_RISCV32_EFI || type == IS_RISCV64_EFI || type == IS_SW64_EFI)
 	  {
 	    struct grub_pe64_optional_header o64;
 	    if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c
index eda689a..5dbada2 100644
--- a/grub-core/kern/compiler-rt.c
+++ b/grub-core/kern/compiler-rt.c
@@ -335,7 +335,7 @@ __ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
 #endif
 
 #if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
-    defined(__arm__) || defined(__riscv)
+    defined(__arm__) || defined(__riscv) || defined(__sw_64__)
 
 /* Based on libgcc2.c from gcc suite.  */
 grub_uint32_t
diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S
index 5723ae0..9ab5aec 100644
--- a/grub-core/lib/setjmp.S
+++ b/grub-core/lib/setjmp.S
@@ -25,6 +25,8 @@
 #include "./riscv/setjmp.S"
 #elif defined(__s390x__)
 #include "./s390x/setjmp.S"
+#elif defined(__sw_64__)
+#include "./sw64/setjmp.S"
 #else
 #error "Unknown target cpu type"
 #endif
diff --git a/include/grub/compiler-rt.h b/include/grub/compiler-rt.h
index 17828b3..a8782fc 100644
--- a/include/grub/compiler-rt.h
+++ b/include/grub/compiler-rt.h
@@ -178,7 +178,7 @@ EXPORT_FUNC (__lshrdi3) (grub_uint64_t u, int b);
 #endif
 
 #if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
-    defined (__arm__) || defined(__riscv)
+    defined (__arm__) || defined(__riscv) || defined(__sw_64__)
 grub_uint32_t
 EXPORT_FUNC(__bswapsi2) (grub_uint32_t u);
 
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 4e6e9d2..993792b 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -92,6 +92,7 @@ struct grub_pe32_coff_header
 #define GRUB_PE32_MACHINE_LOONGARCH64		0x6264
 #define GRUB_PE32_MACHINE_RISCV32		0x5032
 #define GRUB_PE32_MACHINE_RISCV64		0x5064
+#define GRUB_PE32_MACHINE_SW_64                 0x0284
 
 #define GRUB_PE32_RELOCS_STRIPPED		0x0001
 #define GRUB_PE32_EXECUTABLE_IMAGE		0x0002
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 38c6da7..0f80ca2 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -116,6 +116,7 @@ enum grub_install_plat
     GRUB_INSTALL_PLATFORM_RISCV32_EFI,
     GRUB_INSTALL_PLATFORM_RISCV64_EFI,
     GRUB_INSTALL_PLATFORM_S390X_EMU,
+    GRUB_INSTALL_PLATFORM_SW64_EFI,
     GRUB_INSTALL_PLATFORM_MAX
   };
 
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 75fa039..c186293 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -955,6 +955,7 @@ static struct
     [GRUB_INSTALL_PLATFORM_RISCV32_EFI] =      { "riscv32",     "efi"       },
     [GRUB_INSTALL_PLATFORM_RISCV64_EFI] =      { "riscv64",     "efi"       },
     [GRUB_INSTALL_PLATFORM_S390X_EMU] =        { "s390x",   "emu"       },
+    [GRUB_INSTALL_PLATFORM_SW64_EFI] =         { "sw64",        "efi"       },
   };
 
 char *
diff --git a/util/grub-install.c b/util/grub-install.c
index 09c5bba..fb1c874 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -378,6 +378,8 @@ get_default_platform (void)
 #endif
 #elif defined (__s390x__)
    return "s390x-emu";
+#elif defined (__sw_64__)
+   return "sw64-efi";
 #else
    return NULL;
 #endif
@@ -572,6 +574,7 @@ have_bootdev (enum grub_install_plat pl)
     case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
 
     case GRUB_INSTALL_PLATFORM_S390X_EMU:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       return 0;
 
       /* pacify warning.  */
@@ -1014,6 +1017,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
     case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
     case GRUB_INSTALL_PLATFORM_S390X_EMU:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       break;
 
     case GRUB_INSTALL_PLATFORM_I386_QEMU:
@@ -1066,6 +1070,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
     case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
     case GRUB_INSTALL_PLATFORM_S390X_EMU:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       free (install_device);
       install_device = NULL;
       break;
@@ -1163,6 +1168,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
     case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       is_efi = 1;
       break;
     default:
@@ -1304,6 +1310,9 @@ main (int argc, char *argv[])
 	    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
 	      efi_file = "BOOTRISCV64.EFI";
 	      break;
+	    case GRUB_INSTALL_PLATFORM_SW64_EFI:
+              efi_file = "BOOTSW64.EFI";
+              break;
 	    default:
 	      grub_util_error ("%s", _("You've found a bug"));
 	      break;
@@ -1340,6 +1349,9 @@ main (int argc, char *argv[])
 	    case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
 	      efi_file = "grubriscv64.efi";
 	      break;
+	    case GRUB_INSTALL_PLATFORM_SW64_EFI:
+              efi_file = "grubsw64.efi";
+              break;
 	    default:
 	      efi_file = "grub.efi";
 	      break;
@@ -1682,6 +1694,7 @@ main (int argc, char *argv[])
 		  case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
 		  case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
 		  case GRUB_INSTALL_PLATFORM_IA64_EFI:
+		  case GRUB_INSTALL_PLATFORM_SW64_EFI:
 		    g = grub_util_guess_efi_drive (*curdev);
 		    break;
 		  case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
@@ -1874,6 +1887,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
     case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       core_name = "core.efi";
       snprintf (mkimage_target, sizeof (mkimage_target),
 		"%s-%s",
@@ -2087,6 +2101,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_I386_XEN:
     case GRUB_INSTALL_PLATFORM_X86_64_XEN:
     case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       break;
       /* pacify warning.  */
     case GRUB_INSTALL_PLATFORM_MAX:
@@ -2361,6 +2376,7 @@ main (int argc, char *argv[])
     case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
     case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
     case GRUB_INSTALL_PLATFORM_IA64_EFI:
+    case GRUB_INSTALL_PLATFORM_SW64_EFI:
       {
 	char *dst = grub_util_path_concat (2, efidir, efi_file);
 	grub_install_copy_file (imgfile, dst, 1);
diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c
index 46f304c..d277de0 100644
--- a/util/grub-mknetdir.c
+++ b/util/grub-mknetdir.c
@@ -111,6 +111,7 @@ static const struct
     [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64-efi", "efinet", ".efi" },
     [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" },
     [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" },
+    [GRUB_INSTALL_PLATFORM_SW64_EFI] = { "sw64-efi", "efinet", ".efi" },
   };
 
 static void
diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
index abcc1c2..168d6dd 100644
--- a/util/grub-mkrescue.c
+++ b/util/grub-mkrescue.c
@@ -564,7 +564,8 @@ main (int argc, char *argv[])
 	  || source_dirs[GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI]
 	  || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
 	  || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]
-	  || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI])
+	  || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]
+	  || source_dirs[GRUB_INSTALL_PLATFORM_SW64_EFI])
 	system_area = SYS_AREA_COMMON;
       else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275])
 	system_area = SYS_AREA_SPARC;
@@ -764,7 +765,8 @@ main (int argc, char *argv[])
       || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]
       || source_dirs[GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI]
       || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI]
-      || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI])
+      || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]
+      || source_dirs[GRUB_INSTALL_PLATFORM_SW64_EFI])
     {
       FILE *f;
       char *efidir_efi = grub_util_path_concat (2, iso9660_dir, "efi");
@@ -826,6 +828,10 @@ main (int argc, char *argv[])
       make_image_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", imgname);
       free (imgname);
 
+      imgname = grub_util_path_concat (2, efidir_efi_boot, "bootsw64.efi");
+      make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_SW64_EFI, "sw64-efi", imgname);
+      free (imgname);
+
       if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI])
 	{
 	  imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi");
diff --git a/util/mkimage.c b/util/mkimage.c
index 0737935..c4af2db 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -425,6 +425,22 @@ static const struct grub_install_image_target_desc image_targets[] =
       .pe_target = GRUB_PE32_MACHINE_IA64,
       .elf_target = EM_IA_64,
     },
+    {
+      .dirname = "sw64-efi",
+      .names = {"sw64-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_SW_64,
+      .elf_target = EM_SW_64,
+    },
     {
       .dirname = "mips-arc",
       .names = {"mips-arc", NULL},
-- 
2.33.0

