add SW64 arch support

Signed-off-by: sunway_fw <sunway_fw@wxiat.com>
(cherry picked from commit c77b80a2ab9a7dc8f49fe33d54ea3a47d39c7d36)
This commit is contained in:
sunway_fw 2025-03-11 15:34:40 +08:00 committed by openeuler-sync-bot
parent edccaff157
commit e100bf4cab
7 changed files with 3558 additions and 1 deletions

View File

@ -319,3 +319,8 @@ Patch319: backport-0070-kern-partition-Add-sanity-check-after-grub_strtoul
Patch320: backport-0071-kern-misc-Add-sanity-check-after-grub_strtoul-call.patch Patch320: backport-0071-kern-misc-Add-sanity-check-after-grub_strtoul-call.patch
Patch321: backport-0072-loader-i386-linux-Cast-left-shift-to-grub_uint32_t.patch Patch321: backport-0072-loader-i386-linux-Cast-left-shift-to-grub_uint32_t.patch
Patch322: backport-0073-loader-i386-bsd-Use-safe-math-to-avoid-underflow.patch Patch322: backport-0073-loader-i386-bsd-Use-safe-math-to-avoid-underflow.patch
Patch323: sw64-Add-early-startup-code.patch
Patch324: sw64-Add-Linux-load-logic.patch
Patch325: sw64-Add-awareness-for-SW64-reloations.patch
Patch326: sw64-Add-auxiliary-files.patch
Patch327: sw64-Add-to-build-system.patch

View File

@ -22,7 +22,7 @@
Name: grub2 Name: grub2
Epoch: 1 Epoch: 1
Version: 2.12 Version: 2.12
Release: 33 Release: 38
Summary: Bootloader with support for Linux, Multiboot and more Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+ License: GPLv3+
URL: http://www.gnu.org/software/grub/ URL: http://www.gnu.org/software/grub/
@ -464,6 +464,36 @@ fi
%{_datadir}/man/man* %{_datadir}/man/man*
%changelog %changelog
* Mon Mar 10 2025 sunway_fw <sunway_fw@wxiat.com> - 1:2.12-38
- Type:requirement
- CVE:NA
- SUG:NA
- DESC: adds SW64 to the GRUB build system and various tools
* Mon Mar 10 2025 sunway_fw <sunway_fw@wxiat.com> - 1:2.12-37
- Type:requirement
- CVE:NA
- SUG:NA
- DESC:add helper functions of memory, cache, timer, etc support for SW64 arch
* Mon Mar 10 2025 sunway_fw <sunway_fw@wxiat.com> - 1:2.12-36
- Type:requirement
- CVE:NA
- SUG:NA
- DESC:add awareness of SW64 relocations throughout the grub tools and elf->PE relocation conversion support
* Mon Mar 10 2025 sunway_fw <sunway_fw@wxiat.com> - 1:2.12-35
- Type:requirement
- CVE:NA
- SUG:NA
- DESC:add support running Linux underneath as UEFI payload for SW64 arch
* Mon Mar 10 2025 sunway_fw <sunway_fw@wxiat.com> - 1:2.12-34
- Type:requirement
- CVE:NA
- SUG:NA
- DESC: add SW64 early startup code
* Thu Feb 20 2025 zhangqiumiao <zhangqiumiao1@huawei.com> - 1:2.12-33 * Thu Feb 20 2025 zhangqiumiao <zhangqiumiao1@huawei.com> - 1:2.12-33
- Type:CVE - Type:CVE
- CVE:CVE-2024-45781,CVE-2024-45782,CVE-2024-56737,CVE-2024-45780,CVE-2024-45783,CVE-2024-49504,CVE-2025-0624,CVE-20 - CVE:CVE-2024-45781,CVE-2024-45782,CVE-2024-56737,CVE-2024-45780,CVE-2024-45783,CVE-2024-49504,CVE-2025-0624,CVE-20

View File

@ -0,0 +1,593 @@
From 6b08e04d1a8e52d0880140b83470c53bb0c8b566 Mon Sep 17 00:00:00 2001
From: sunway_fw <sunway_fw@wxiat.com>
Date: Tue, 18 Feb 2025 14:58:36 +0800
Subject: [PATCH 2/5] sw64: Add Linux load logic
We currently only support to run grub on SW64 as UEFI payload. Ideally,
we also only want to support running Linux underneath as UEFI payload.
Signed-off-by: sunway_fw <sunway_fw@wxiat.com>
---
grub-core/loader/sw64/efi/linux.c | 515 ++++++++++++++++++++++++++++++
include/grub/sw64/linux.h | 47 +++
2 files changed, 562 insertions(+)
create mode 100644 grub-core/loader/sw64/efi/linux.c
create mode 100644 include/grub/sw64/linux.h
diff --git a/grub-core/loader/sw64/efi/linux.c b/grub-core/loader/sw64/efi/linux.c
new file mode 100644
index 0000000..88db8ea
--- /dev/null
+++ b/grub-core/loader/sw64/efi/linux.c
@@ -0,0 +1,515 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 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/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/command.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/api.h>
+#include <grub/efi/fdtload.h>
+#include <grub/efi/efi.h>
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/i18n.h>
+#include <grub/env.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/pal.h>
+#include <grub/lib/cmdline.h>
+#include <grub/linux.h>
+#include <grub/fdt.h>
+#include <grub/efi/memory.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+#define GRUB_EFI_SW64_FIRMWARE_INFO { 0xc47a23c3, 0xcebb, 0x4cc9, \
+ { 0xa5, 0xe2, 0xde, 0xd0, 0x8f, 0xe4, 0x20, 0xb5 } }
+
+#define GRUB_EFI_SW64_MEMORY_ATTRIBUTES { 0xdcfa911d, 0x26eb, 0x469f, \
+ { 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20 } }
+
+#define SW64_EFI_FIRMWARE_INFO_SIGNATURE \
+ ('S' << 24 | 'H' << 16 | 'I' << 8 | 'F')
+
+static grub_dl_t my_mod;
+static int loaded;
+static char *linux_args;
+
+/* Initrd base and size. */
+static void *initrd_mem;
+static grub_efi_uintn_t initrd_pages;
+static grub_addr_t initrd_start;
+static grub_efi_uintn_t initrd_size;
+static grub_uint64_t linux_entry;
+
+struct sw64_firmware_info_head
+{
+ grub_uint32_t signature;
+ grub_uint32_t revision;
+ grub_uint32_t length;
+};
+
+struct sw64_firmware_info
+{
+ struct sw64_firmware_info_head firmware_info_head;
+ grub_uint32_t reserved;
+ grub_uint32_t need_boot_param;
+};
+
+void *raw_fdt;
+static struct boot_param *sunway_boot_params = (struct boot_param *)BOOT_PARAM_START;
+
+static grub_efi_uint32_t
+sw64_efi_get_boot_param (void)
+{
+ unsigned i;
+ struct sw64_firmware_info_head *firmware_info_head;
+ static grub_packed_guid_t info_guid = GRUB_EFI_SW64_FIRMWARE_INFO;
+
+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+ {
+ grub_packed_guid_t *guid =
+ (grub_packed_guid_t *)&grub_efi_system_table->configuration_table[i].vendor_guid;
+
+ if (! grub_memcmp (guid, &info_guid, sizeof (grub_packed_guid_t)))
+ {
+ firmware_info_head = grub_efi_system_table->configuration_table[i].vendor_table;
+ if (firmware_info_head->signature != SW64_EFI_FIRMWARE_INFO_SIGNATURE) {
+ grub_printf ("Get a legacy firmware info\n");
+ return 1;
+ }
+
+ if (firmware_info_head->revision == 1) {
+ return ((struct sw64_firmware_info *)firmware_info_head)->need_boot_param;
+ }
+ }
+ }
+ return 1;
+}
+
+static void
+sw64_efi_memattr_repair (void)
+{
+ unsigned i;
+ static grub_packed_guid_t info_guid = GRUB_EFI_SW64_MEMORY_ATTRIBUTES;
+
+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) {
+ grub_packed_guid_t *guid = (grub_packed_guid_t *)&grub_efi_system_table->configuration_table[i].vendor_guid;
+
+ if (! grub_memcmp (guid, &info_guid, sizeof (grub_packed_guid_t))) {
+ grub_efi_system_table->configuration_table[i].vendor_table = (void *)grub_virt_to_phys((grub_uint64_t)grub_efi_system_table->configuration_table[i].vendor_table);
+ }
+ }
+}
+
+typedef
+void
+(*jump_to_kernel) (
+ grub_uint64_t magic,
+ grub_uint64_t device_tree_base
+ );
+
+static grub_err_t
+finalize_params_linux (void)
+{
+ int retval;
+ int node;
+ 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;
+ grub_efi_uintn_t i;
+ grub_uint32_t bootargs_size;
+ const char *last_bootargs;
+ static char *temp_linux_args;
+
+ mmap_buf = 0;
+
+ raw_fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+
+ if (!raw_fdt || grub_fdt_check_header_nosize(raw_fdt)) {
+ goto failure;
+ }
+
+ node = grub_fdt_find_subnode (raw_fdt, 0, "chosen");
+ if (node < 0)
+ node = grub_fdt_add_subnode (raw_fdt, 0, "chosen");
+
+ if (node < 1)
+ goto failure;
+
+ initrd_start = grub_virt_to_phys (initrd_start);
+
+ if (initrd_start) {
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,initrd-start", initrd_start);
+ if (retval)
+ goto failure;
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,initrd-end", initrd_start + initrd_size);
+ if (retval)
+ goto failure;
+ }
+
+ last_bootargs = grub_fdt_get_prop (raw_fdt, node, "bootargs", &bootargs_size);
+ if (last_bootargs && grub_strlen (last_bootargs) > 1) {
+ temp_linux_args = grub_malloc (grub_strlen (linux_args) + bootargs_size + 1);
+ if (!temp_linux_args)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory in finalize_params_linux"));
+ goto failure;
+ }
+ grub_memcpy (temp_linux_args, last_bootargs, bootargs_size - 1);
+ *(temp_linux_args + bootargs_size - 1) = ' ';
+ grub_memcpy (temp_linux_args + bootargs_size, linux_args, grub_strlen (linux_args) + 1);
+ grub_free (linux_args);
+ linux_args = temp_linux_args;
+ }
+
+ retval = grub_fdt_set_prop (raw_fdt, node, "bootargs", linux_args, grub_strlen (linux_args) + 1);
+ if (retval)
+ goto failure;
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,uefi-system-table",
+ grub_virt_to_phys((grub_uint64_t)grub_efi_system_table));
+ if (retval)
+ goto failure;
+
+ mmap_size = grub_efi_find_mmap_size ();
+ if (! mmap_size)
+ goto failure;
+
+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size));
+ if (! mmap_buf)
+ goto failure;
+
+ grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, &desc_size, &desc_version);
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,uefi-mmap-start",
+ grub_virt_to_phys((grub_uint64_t)mmap_buf));
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,uefi-mmap-size", mmap_size);
+ if (retval)
+ goto failure_without_dprintf;
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,uefi-mmap-desc-size", desc_size);
+ if (retval)
+ goto failure_without_dprintf;
+
+ retval = grub_fdt_set_prop64 (raw_fdt, node, "linux,uefi-mmap-desc-ver", desc_version);
+ if (retval)
+ goto failure_without_dprintf;
+
+ for (i = 0; i < mmap_size / desc_size; i++) {
+ grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
+ ((char *) mmap_buf + desc_size * i);
+
+ curdesc->physical_start = grub_virt_to_phys(curdesc->physical_start);
+ }
+
+ sw64_efi_memattr_repair();
+
+ return GRUB_ERR_NONE;
+
+failure:
+ grub_dprintf ("linux", "some wrong in finalize_params_linux\n");
+
+failure_without_dprintf:
+ grub_printf ("some wrong in finalize_params_linux\n");
+ raw_fdt = 0;
+ return GRUB_ERR_BAD_OS;
+}
+
+static grub_err_t
+legacy_finalize_params_linux (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;
+ grub_err_t err;
+ grub_efi_uintn_t i;
+
+ /* Initrd. */
+ sunway_boot_params->initrd_start = (grub_uint64_t)initrd_start;
+ sunway_boot_params->initrd_size = (grub_uint64_t)initrd_size;
+
+ /* DTB. */
+ raw_fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+
+ if (!raw_fdt)
+ {
+ sunway_boot_params->dtb_start = 0;
+ grub_dprintf ("linux", "not found registered FDT\n");
+ }
+
+ if (raw_fdt)
+ {
+ err = grub_fdt_check_header_nosize(raw_fdt);
+ if (err)
+ grub_dprintf ("linux", "illegal FDT file\n");
+
+ sunway_boot_params->dtb_start = (grub_uint64_t)raw_fdt;
+ grub_dprintf ("linux", "dtb: [addr=0x%lx, size=0x%x]\n",
+ (grub_uint64_t) raw_fdt, grub_fdt_get_totalsize(raw_fdt));
+ }
+
+ /* MDT.
+ Must be done after grub_machine_fini because map_key is used by
+ exit_boot_services. */
+ mmap_size = grub_efi_find_mmap_size ();
+ if (! mmap_size) {
+ grub_dprintf ("linux", "unable to get mmap_size\n");
+ return GRUB_ERR_BAD_OS;
+ }
+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size));
+ if (! mmap_buf) {
+ grub_dprintf ("linux", "cannot allocate memory map\n");
+ return GRUB_ERR_BAD_OS;
+ }
+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key,
+ &desc_size, &desc_version);
+ for (i = 0; i < mmap_size / desc_size; i++)
+ {
+ grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
+ ((char *) mmap_buf + desc_size * i);
+
+ curdesc->physical_start = grub_virt_to_phys(curdesc->physical_start);
+ }
+
+ sw64_efi_memattr_repair();
+
+ sunway_boot_params->command_line = (grub_uint64_t) linux_args;
+ sunway_boot_params->efi_systab = grub_virt_to_phys((grub_uint64_t)grub_efi_system_table);
+ sunway_boot_params->efi_memmap = grub_virt_to_phys((grub_uint64_t)mmap_buf);
+ sunway_boot_params->efi_memmap_size = mmap_size;
+ sunway_boot_params->efi_memdesc_size = desc_size;
+ sunway_boot_params->efi_memdesc_version = desc_version;
+
+ return GRUB_ERR_NONE;
+}
+static void
+start_kernel(void)
+{
+ local_irq_disable ();
+ grub_dprintf ("linux", "Jump to entry: %lx\n", linux_entry);
+
+ jump_to_kernel jump = (jump_to_kernel) linux_entry;
+ if (sw64_efi_get_boot_param()) {
+ jump (0, 0);
+ } else {
+ jump (0xdeed2024, (grub_uint64_t)raw_fdt);
+ }
+}
+
+static grub_err_t
+grub_linux_boot (void)
+{
+ if (sw64_efi_get_boot_param()) {
+ legacy_finalize_params_linux();
+ } else {
+ finalize_params_linux();
+ }
+
+ start_kernel ();
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+ grub_dl_unref (my_mod);
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_load_elf64 (grub_elf_t elf, const char *filename)
+{
+ Elf64_Addr base_addr;
+ grub_size_t linux_size;
+ grub_uint64_t align;
+
+ if (elf->ehdr.ehdr64.e_ident[EI_MAG0] != ELFMAG0
+ || elf->ehdr.ehdr64.e_ident[EI_MAG1] != ELFMAG1
+ || elf->ehdr.ehdr64.e_ident[EI_MAG2] != ELFMAG2
+ || elf->ehdr.ehdr64.e_ident[EI_MAG3] != ELFMAG3
+ || elf->ehdr.ehdr64.e_ident[EI_DATA] != ELFDATA2LSB)
+ return grub_error(GRUB_ERR_UNKNOWN_OS,
+ N_("invalid arch-independent ELF magic"));
+
+ if (elf->ehdr.ehdr64.e_ident[EI_CLASS] != ELFCLASS64
+ || elf->ehdr.ehdr64.e_version != EV_CURRENT
+ || elf->ehdr.ehdr64.e_machine != EM_SW_64)
+ return grub_error (GRUB_ERR_UNKNOWN_OS,
+ N_("invalid arch-dependent ELF magic"));
+
+ if (elf->ehdr.ehdr64.e_type != ET_EXEC)
+ return grub_error (GRUB_ERR_UNKNOWN_OS,
+ N_("this ELF file is not of the right type"));
+
+ /* FIXME: Should we support program headers at strange locations? */
+ if (elf->ehdr.ehdr64.e_phoff + elf->ehdr.ehdr64.e_phnum * elf->ehdr.ehdr64.e_phentsize > GRUB_ELF_SEARCH)
+ return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+ linux_size = grub_elf64_size (elf, &base_addr, &align);
+ if (linux_size == 0)
+ return grub_error (GRUB_ERR_BAD_OS, "linux size is 0");
+
+ linux_entry = (grub_uint64_t)elf->ehdr.ehdr64.e_entry;
+ grub_dprintf ("linux", "Segment phy_addr: %lx entry: %lx\n", (grub_uint64_t)base_addr,(grub_uint64_t)elf->ehdr.ehdr64.e_entry);
+
+ /* Now load the segments into the area we claimed. */
+ return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (0), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ grub_ssize_t size;
+ grub_elf_t elf = 0;
+
+ grub_dl_ref (my_mod);
+
+ grub_loader_unset ();
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
+ if (! elf)
+ goto fail;
+
+ grub_dprintf ("linux", "Loading linux: %s\n", argv[0]);
+
+ if (grub_load_elf64 (elf, argv[0]))
+ goto fail;
+
+ grub_memset (sunway_boot_params, 0, sizeof(*sunway_boot_params));
+ size = grub_loader_cmdline_size(argc, argv);
+
+ linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
+ if (!linux_args)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ goto fail;
+ }
+
+ /* Create kernel command line. */
+ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
+ grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
+ size, GRUB_VERIFY_KERNEL_CMDLINE);
+
+ grub_dprintf ("linux", "linux_args: '%s'\n", linux_args);
+ grub_errno = GRUB_ERR_NONE;
+
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
+
+ fail:
+ if (elf)
+ grub_elf_close (elf);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_dl_unref (my_mod);
+ loaded = 0;
+ }
+ else
+ loaded = 1;
+
+ return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char *argv[])
+{
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+
+ if (argc == 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
+ goto fail;
+ }
+
+ if (! loaded)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
+ goto fail;
+ }
+
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
+ goto fail;
+
+ initrd_size = grub_get_initrd_size (&initrd_ctx);
+ grub_dprintf ("linux", "Loading initrd %s\n", argv[0]);
+
+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
+ initrd_mem = grub_efi_allocate_any_pages (initrd_pages);
+ if (! initrd_mem)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate pages");
+ goto fail;
+ }
+
+ grub_dprintf ("linux", "initrd: [addr=0x%lx, size=0x%lx]\n",
+ (grub_uint64_t) initrd_mem, initrd_size);
+
+ if (grub_initrd_load (&initrd_ctx, initrd_mem))
+ goto fail;
+
+ initrd_start = (grub_addr_t) initrd_mem;
+
+ fail:
+ grub_initrd_close (&initrd_ctx);
+ if (initrd_mem && !initrd_start)
+ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+
+ return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT (linux)
+{
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+ N_("FILE [ARGS...]"), N_("Load Linux."));
+
+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+ N_("FILE"), N_("Load initrd."));
+
+ my_mod = mod;
+}
+
+GRUB_MOD_FINI (linux)
+{
+ grub_unregister_command (cmd_linux);
+ grub_unregister_command (cmd_initrd);
+}
diff --git a/include/grub/sw64/linux.h b/include/grub/sw64/linux.h
new file mode 100644
index 0000000..c4d0907
--- /dev/null
+++ b/include/grub/sw64/linux.h
@@ -0,0 +1,47 @@
+#ifndef GRUB_SW_H
+#define GRUB_SW_H 1
+#define PAGE_OFFSET 0xfff0000000000000UL
+#define KTEXT_OFFSET 0xffffffff80000000UL
+#define GRUB_PRINTK_START (PAGE_OFFSET | 0x800000)
+#define GRUB_PRINTK_SIZE (0x20000)
+#define BOOT_PARAM_START 0xfff000000090a100ULL
+
+#define GRUB_ELF_SEARCH 1024
+#define IPL_MIN 0
+#define IPL_MAX 7
+#define barrier() __asm__ __volatile__("": : :"memory")
+#define local_irq_disable() do { swpipl(IPL_MAX); barrier(); } while(0)
+#define local_irq_enable() do { barrier(); swpipl(IPL_MIN); } while(0)
+
+static inline
+grub_uint64_t
+grub_virt_to_phys(grub_uint64_t x)
+{
+ if (x >= KTEXT_OFFSET)
+ x -= KTEXT_OFFSET;
+ else if (x >= PAGE_OFFSET)
+ x -= PAGE_OFFSET;
+
+ return x;
+}
+
+struct boot_param
+{
+ grub_uint64_t initrd_start; /* logical address of initrd */
+ grub_uint64_t initrd_size; /* size of initrd */
+ grub_uint64_t dtb_start; /* logical address of dtb */
+ grub_uint64_t efi_systab; /* logical address of EFI system table */
+ grub_uint64_t efi_memmap; /* logical 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_uint64_t efi_memdesc_version; /* memory descriptor version */
+ grub_uint64_t command_line; /* logical address of cmdline */
+};
+
+struct linux_sw64_kernel_header
+{
+};
+
+#define linux_arch_kernel_header linux_sw64_kernel_header
+
+#endif
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,557 @@
From aebda5e118748d819291f21fc11d5cc8f20de2bb Mon Sep 17 00:00:00 2001
From: sunway_fw <sunway_fw@wxiat.com>
Date: Tue, 18 Feb 2025 15:13:24 +0800
Subject: [PATCH 3/5] sw64: Add awareness for SW64 reloations
This patch adds awareness of SW64 relocations throughout the grub tools
as well as dynamic linkage and elf->PE relocation conversion support.
Signed-off-by: sunway_fw <sunway_fw@wxiat.com>
---
grub-core/kern/sw64/dl.c | 214 ++++++++++++++++++++++++++++++++++++
include/grub/dl.h | 16 ++-
include/grub/elf.h | 39 +++++++
util/grub-mkimagexx.c | 146 +++++++++++++++++++++++-
util/grub-module-verifier.c | 18 +++
5 files changed, 430 insertions(+), 3 deletions(-)
create mode 100644 grub-core/kern/sw64/dl.c
diff --git a/grub-core/kern/sw64/dl.c b/grub-core/kern/sw64/dl.c
new file mode 100644
index 0000000..8e3cac2
--- /dev/null
+++ b/grub-core/kern/sw64/dl.c
@@ -0,0 +1,214 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 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/elf.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_DATA] != ELFDATA2LSB || e->e_machine != EM_SW_64)
+ return grub_error (GRUB_ERR_BAD_OS,
+ N_("invalid arch-dependent ELF magic"));
+
+ return GRUB_ERR_NONE;
+}
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+/* Relocate symbols. */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ Elf_Shdr *s, grub_dl_segment_t seg)
+{
+ Elf_Rela *rel, *max;
+ grub_uint64_t *gpptr, *gotptr;
+
+ gotptr = (grub_uint64_t *) mod->got;
+ gpptr = (grub_uint64_t *) ((grub_uint64_t) mod->got + 0x8000);
+
+ for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset),
+ max = (Elf_Rela *) ((char *) rel + s->sh_size);
+ rel < max;
+ rel = (Elf_Rela *) ((char *) rel + s->sh_entsize))
+ {
+ grub_addr_t addr;
+ Elf_Sym *sym;
+ grub_uint64_t value;
+
+ if (seg->size < (rel->r_offset & ~3))
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "reloc offset is out of the segment");
+
+ addr = (grub_addr_t) seg->addr + rel->r_offset;
+ sym = (Elf_Sym *) ((char *) mod->symtab
+ + mod->symsize * ELF_R_SYM (rel->r_info));
+
+ /* On the PPC the value does not have an explicit
+ addend, add it. */
+ value = sym->st_value + rel->r_addend;
+
+ switch (ELF_R_TYPE (rel->r_info))
+ {
+ case R_SW64_NONE:
+ break;
+ case R_SW64_REFLONG:
+ *(grub_uint32_t *)addr = value;
+ break;
+ case R_SW64_REFQUAD:
+ {
+ *(grub_uint32_t *)addr = value;
+ *((grub_uint32_t *)addr + 1) = value >> 32;
+ break;
+ }
+ case R_SW64_GPREL32:
+ {
+ value -= (grub_uint64_t)gpptr;
+ if ((grub_int32_t)value != value)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_GPREL32 relocation out of range");
+ *(grub_uint32_t *) addr = value;
+ break;
+ }
+ case R_SW64_LITERAL:
+ {
+ grub_uint64_t li_hi;
+ grub_uint64_t li_lo;
+
+ li_hi = (grub_uint64_t) gotptr + (((grub_uint64_t)ELF_R_TYPE(rel->r_info)) >> 8 );
+ li_lo = li_hi - ((grub_uint64_t) gpptr);
+ if ((grub_int16_t)li_lo != li_lo)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_LITERAL relocation out of range");
+
+ *(grub_uint16_t *) addr = (li_lo & 0xffff);
+ *(grub_uint64_t *) (li_hi) = value;
+ gotptr++;
+ break;
+ }
+ case R_SW64_LITERAL_GOT:
+ break;
+ case R_SW64_LITUSE:
+ break;
+ case R_SW64_GPDISP:
+ {
+ grub_uint64_t hi;
+ grub_uint64_t lo;
+ grub_uint64_t gpoffset = (grub_int64_t)gpptr - addr;
+ lo = (grub_int16_t) gpoffset;
+ hi = (grub_int32_t) (gpoffset - lo);
+ if (hi + lo != gpoffset)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_GPDISP relocation out of range");
+
+ if (gpoffset & 0x8000) {
+ hi = ((gpoffset + 0x8000) >> 16) & 0xffff;
+ lo = gpoffset & 0xffff;
+ } else {
+ hi = (gpoffset >> 16) & 0xffff;
+ lo = gpoffset & 0xffff;
+ }
+
+ *(grub_uint32_t *) addr = ( *(grub_uint32_t *)addr & 0xffff0000) | (hi & 0xffff);
+ *(grub_uint32_t *) ((unsigned long)addr + rel->r_addend) =
+ (((*(grub_uint32_t *)((unsigned long)addr + rel->r_addend)) & 0xffff0000) | (lo & 0xffff));
+ break;
+ }
+ case R_SW64_BRADDR:
+ {
+ grub_uint64_t braddr = (*(grub_uint64_t *)addr) + value - ((grub_uint64_t)addr + 4);
+ braddr = (grub_int64_t)braddr >> 2;
+ if (braddr + (1<<21) >= 1<<21)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_BRADDR relocation out of range");
+
+ *(grub_uint32_t *) addr = (*(grub_uint32_t *)addr & (~0x1fffff)) | (braddr & 0x1fffff);
+ break;
+ }
+ case R_SW64_HINT:
+ break;
+ case R_SW64_SREL32:
+ {
+ value -= (grub_uint64_t)addr;
+ if ((grub_int32_t)value != value)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_SREL32 relocation out of range");
+
+ *(grub_uint32_t *) addr = value;
+ break;
+ }
+ case R_SW64_SREL64:
+ {
+ grub_uint64_t srel64 = *(grub_uint64_t *)addr + value;;
+ srel64 -= (grub_uint64_t)addr;
+ *(grub_uint64_t *) addr = srel64;
+ break;
+ }
+ case R_SW64_GPRELHIGH:
+ {
+ grub_uint64_t gprel_hi = (grub_int64_t)(value - (grub_uint64_t)gpptr);
+
+ if (gprel_hi & 0x8000)
+ gprel_hi = (grub_int64_t)(((grub_int64_t)gprel_hi + 0x8000) >> 16);
+ else
+ gprel_hi = (grub_int64_t)gprel_hi >> 16;
+
+ if ((grub_int16_t)gprel_hi != gprel_hi)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "GPRELHIGH out of range\n");
+
+ *(grub_uint32_t *) addr = (*(grub_uint32_t *)addr & 0xffff0000) | (gprel_hi & 0xffff);
+ break;
+ }
+ case R_SW64_GPRELLOW:
+ {
+ grub_uint64_t gprel_lo = value - (grub_uint64_t)gpptr;
+ *(grub_uint32_t *) addr = (*(grub_uint32_t *)addr & 0xffff0000) | (gprel_lo & 0xffff);
+ break;
+ }
+ case R_SW64_GPREL16:
+ {
+ grub_uint64_t gprel16 = (*(grub_uint64_t *)addr + value);
+ gprel16 = (grub_uint64_t)(gprel16 - (grub_uint64_t)gpptr);
+ if ((grub_int16_t)gprel16 != gprel16)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "R_SW64_GPREL16 relocation out of range");
+ *(grub_uint16_t *) addr = gprel16;
+ break;
+ }
+ default:
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ N_("relocation 0x%lx is not implemented yet"),
+ ELF_R_TYPE (rel->r_info));
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
diff --git a/include/grub/dl.h b/include/grub/dl.h
index c5ab18c..a4cb287 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -292,17 +292,31 @@ grub_err_t
grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got);
+#if defined (__sw_64__)
+#define GRUB_SW64_DL_TRAMP_ALIGN 16
+#define GRUB_SW64_DL_GOT_ALIGN 16
+
+grub_err_t
+grub_sw64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
+ grub_size_t *got);
+#endif
+
#if defined (__ia64__)
#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN
#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN
#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size
#elif defined (__aarch64__)
#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size
+#elif defined (__sw_64__)
+#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_SW64_DL_TRAMP_ALIGN
+#define GRUB_ARCH_DL_GOT_ALIGN GRUB_SW64_DL_GOT_ALIGN
+#define grub_arch_dl_get_tramp_got_size grub_sw64_dl_get_tramp_got_size
#else
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got);
#endif
+#endif
#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) || \
(defined(__riscv) && (__riscv_xlen == 32))
@@ -317,6 +331,4 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
#define GRUB_ARCH_DL_GOT_ALIGN 8
#endif
-#endif
-
#endif /* ! GRUB_DL_H */
diff --git a/include/grub/elf.h b/include/grub/elf.h
index bd313a7..2af59fe 100644
--- a/include/grub/elf.h
+++ b/include/grub/elf.h
@@ -259,6 +259,7 @@ typedef struct
chances of collision with official or non-GNU unofficial values. */
#define EM_ALPHA 0x9026
+#define EM_SW_64 0x9916
/* Legal values for e_version (version). */
@@ -2537,6 +2538,44 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_RISCV_SET32 56
#define R_RISCV_32_PCREL 57
+/*
+ * SW-64 ELF relocation types
+ */
+#define R_SW64_NONE 0 /* No reloc */
+#define R_SW64_REFLONG 1 /* Direct 32 bit */
+#define R_SW64_REFQUAD 2 /* Direct 64 bit */
+#define R_SW64_GPREL32 3 /* GP relative 32 bit */
+#define R_SW64_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_SW64_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_SW64_GPDISP 6 /* Add displacement to GP */
+#define R_SW64_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_SW64_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_SW64_SREL16 9 /* PC relative 16 bit */
+#define R_SW64_SREL32 10 /* PC relative 32 bit */
+#define R_SW64_SREL64 11 /* PC relative 64 bit */
+#define R_SW64_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
+#define R_SW64_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
+#define R_SW64_GPREL16 19 /* GP relative 16 bit */
+#define R_SW64_COPY 24 /* Copy symbol at runtime */
+#define R_SW64_GLOB_DAT 25 /* Create GOT entry */
+#define R_SW64_JMP_SLOT 26 /* Create PLT entry */
+#define R_SW64_RELATIVE 27 /* Adjust by program base */
+#define R_SW64_BRSGP 28
+#define R_SW64_TLSGD 29
+#define R_SW64_TLS_LDM 30
+#define R_SW64_DTPMOD64 31
+#define R_SW64_GOTDTPREL 32
+#define R_SW64_DTPREL64 33
+#define R_SW64_DTPRELHI 34
+#define R_SW64_DTPRELLO 35
+#define R_SW64_DTPREL16 36
+#define R_SW64_GOTTPREL 37
+#define R_SW64_TPREL64 38
+#define R_SW64_TPRELHI 39
+#define R_SW64_TPRELLO 40
+#define R_SW64_TPREL16 41
+#define R_SW64_LITERAL_GOT 43
+
/* LoongArch relocations */
#define R_LARCH_NONE 0
#define R_LARCH_64 2
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index 9488f05..f327e26 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -819,8 +819,14 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
Elf_Half i;
Elf_Shdr *s;
#ifdef MKIMAGE_ELF64
+ grub_uint64_t got_offset = 0;
+
struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off);
grub_uint64_t *gpptr = (void *) (pe_target + got_off);
+ if (image_target->elf_target == EM_SW_64) {
+ got_offset = got_off;
+ gpptr = (void *) (pe_target + got_offset + 0x8000);
+ }
unsigned unmatched_adr_got_page = 0;
struct grub_loongarch64_stack stack;
grub_loongarch64_stack_init (&stack);
@@ -1163,6 +1169,119 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
}
break;
}
+ case EM_SW_64:
+ {
+ sym_addr += addend;
+ switch (ELF_R_TYPE (info))
+ {
+ case R_SW64_NONE:
+ break;
+ case R_SW64_REFLONG:
+ *(grub_uint32_t *)target = grub_host_to_target32 (sym_addr);
+ break;
+ case R_SW64_REFQUAD:
+ {
+ *(grub_uint32_t *)target = grub_host_to_target32(sym_addr);
+ *((grub_uint32_t *)target + 1) = grub_host_to_target32(sym_addr >> 32);
+ break;
+ }
+ case R_SW64_GPREL32:
+ {
+ *(grub_uint32_t *) target = (grub_host_to_target64 (sym_addr) -
+ ((char *) gpptr - (char *)pe_target + image_target->vaddr_offset )) & 0xffffffff;
+ break;
+ }
+ case R_SW64_LITERAL:
+ {
+ grub_uint64_t li_hi;
+ grub_uint64_t li_lo;
+
+ li_hi = (grub_uint64_t)pe_target + got_offset + (((grub_uint64_t)ELF_R_TYPE(r->r_info)) >> 8 );
+ li_lo = li_hi - ((grub_uint64_t) gpptr);
+ *(grub_uint16_t *) target = (li_lo & 0xffff);
+ *(grub_uint64_t *) (li_hi) = grub_host_to_target64(grub_host_to_target64 (sym_addr));
+ got_offset += 8;
+ break;
+ }
+ case R_SW64_LITERAL_GOT:
+ break;
+ case R_SW64_LITUSE:
+ break;
+ case R_SW64_GPDISP:
+ {
+ grub_uint64_t hi;
+ grub_uint64_t lo;
+ grub_int64_t gpoffset = (((char *) gpptr - (char *) pe_target + image_target->vaddr_offset))
+ - ((offset + target_section_addr + image_target->vaddr_offset));
+ if (gpoffset & 0x8000) {
+ hi = ((gpoffset + 0x8000) >> 16) & 0xffff;
+ lo = gpoffset & 0xffff;
+ } else {
+ hi = (gpoffset >> 16) & 0xffff;
+ lo = gpoffset & 0xffff;
+ }
+ *(grub_uint32_t *) target = grub_host_to_target32 ((grub_target_to_host32 (*target) & 0xffff0000) | (hi & 0xffff));
+ *(grub_uint32_t *) ((unsigned long)target + addend) =
+ grub_host_to_target32 ((grub_target_to_host32 (*(grub_uint32_t *)
+ ((unsigned long)target + addend)) & 0xffff0000) | (lo & 0xffff));
+ break;
+
+ }
+ case R_SW64_BRADDR:
+ {
+ grub_uint64_t braddr = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr) - ((grub_uint64_t)target + 4);
+ braddr = braddr >> 2;
+ *(grub_uint32_t *) target = (*(grub_uint32_t *)target & (~0x1fffff)) | (braddr & 0x1fffff);
+ break;
+ }
+ case R_SW64_HINT:
+ break;
+ case R_SW64_SREL32:
+ {
+ grub_uint64_t srel32 = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+ srel32 -= (grub_uint64_t)target;
+ *(grub_uint32_t *) target = srel32;
+ break;
+ }
+ case R_SW64_SREL64:
+ {
+ grub_uint64_t srel64 = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+ srel64 -= (grub_uint64_t)target;
+ *(grub_uint64_t *) target = srel64;
+ break;
+ }
+ case R_SW64_GPRELHIGH:
+ {
+ grub_uint64_t gprel_hi = ((grub_host_to_target64 (sym_addr) - (((char *) gpptr - (char *)pe_target + image_target->vaddr_offset) + 0x0)));
+
+ if (gprel_hi & 0x8000)
+ gprel_hi = ((gprel_hi + 0x8000) >> 16) & 0xffff;
+ else
+ gprel_hi = (gprel_hi >> 16) & 0xffff;
+
+ *(grub_uint32_t *) target = grub_host_to_target32 ((grub_target_to_host32 (*target) & 0xffff0000) | (gprel_hi & 0xffff));
+ break;
+ }
+ case R_SW64_GPRELLOW:
+ {
+ grub_uint64_t gprel_lo = (grub_host_to_target64 (sym_addr) - ((char *) gpptr - (char *)pe_target + image_target->vaddr_offset));
+ *(grub_uint32_t *) target = grub_host_to_target32 ((grub_target_to_host32 (*target) & 0xffff0000) | (gprel_lo & 0xffff));
+ break;
+ }
+ case R_SW64_GPREL16:
+ {
+ grub_uint64_t gprel16 = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
+ gprel16 = (grub_uint64_t)(gprel16 - (grub_uint64_t)gpptr);
+ *(grub_uint16_t *) target = gprel16;
+ break;
+ }
+ default:
+ grub_util_error (_("relocation 0x%lx is not implemented yet"),
+ ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
case EM_LOONGARCH:
{
grub_int64_t pc;
@@ -1700,6 +1819,19 @@ translate_relocation_pe (struct translate_context *ctx,
image_target);
}
break;
+ case EM_SW_64:
+ if (ELF_R_TYPE (info) == R_SW64_REFQUAD)
+ {
+ grub_util_info ("adding a relocation entry for 0x%llx",
+ (unsigned long long) addr);
+ ctx->current_address
+ = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr,
+ 0, ctx->current_address,
+ image_target);
+ }
+ break;
case EM_IA_64:
switch (ELF_R_TYPE (info))
{
@@ -2181,7 +2313,8 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
+ image_target->vaddr_offset,
2 * layout->ia64jmpnum,
image_target);
- if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64)
+ if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64 ||
+ image_target->elf_target == EM_SW_64)
create_u64_fixups (&ctx,
layout->got_off
+ image_target->vaddr_offset,
@@ -2550,6 +2683,17 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
grub_arm64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
+ layout->got_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (layout->got_size, 16);
+ }
+ else if (image_target->elf_target == EM_SW_64)
+ {
+ grub_size_t tramp;
+
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
+
+ grub_sw64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
+
layout->got_off = layout->kernel_size;
layout->kernel_size += ALIGN_UP (layout->got_size, 16);
}
diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index 91d9e8f..37fd0f6 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -209,6 +209,24 @@ struct grub_module_verifier_arch archs[] = {
-1
}
},
+ { "sw64", 8, 0, EM_SW_64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_SW64_NONE,
+ R_SW64_REFQUAD,
+ R_SW64_GPREL32,
+ R_SW64_LITERAL,
+ R_SW64_LITERAL_GOT,
+ R_SW64_LITUSE,
+ R_SW64_GPDISP,
+ R_SW64_BRSGP,
+ R_SW64_BRADDR,
+ R_SW64_HINT,
+ R_SW64_SREL32,
+ R_SW64_SREL64,
+ R_SW64_GPRELHIGH,
+ R_SW64_GPRELLOW,
+ R_SW64_GPREL16,
+ -1
+ } },
};
struct platform_whitelist {
--
2.33.0

View File

@ -0,0 +1,59 @@
From d8825597e923d22c8f901c63a51ffd8253eb427d Mon Sep 17 00:00:00 2001
From: sunway_fw <sunway_fw@wxiat.com>
Date: Tue, 18 Feb 2025 14:50:17 +0800
Subject: [PATCH 1/5] sw64: Add early startup code
On entry, we need to save the system table pointer as well as our image
handle. Add an early startup file that saves them and then brings us
into our main function.
Signed-off-by: sunway_fw <sunway_fw@wxiat.com>
---
grub-core/kern/sw64/efi/startup.S | 35 +++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 grub-core/kern/sw64/efi/startup.S
diff --git a/grub-core/kern/sw64/efi/startup.S b/grub-core/kern/sw64/efi/startup.S
new file mode 100644
index 0000000..8143f75
--- /dev/null
+++ b/grub-core/kern/sw64/efi/startup.S
@@ -0,0 +1,35 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 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>
+#include <grub/sw64/regdef.h>
+
+ .file "startup.S"
+ .text
+FUNCTION(_start)
+ /*
+ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0.
+ */
+ ldih $29,0($27) !gpdisp!1
+ ldi $29,0($29) !gpdisp!1
+ ldi $20, EXT_C(grub_efi_image_handle)
+ stl a0, 0($20)
+ ldi $20, EXT_C(grub_efi_system_table)
+ stl a1, 0($20)
+ call $31, grub_main
+ ret
--
2.33.0

View File

@ -0,0 +1,516 @@
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