From f29ddf1264935d00af91a8bef5da87aaa8643bdc Mon Sep 17 00:00:00 2001 From: anolis-bot Date: Tue, 10 Jan 2023 16:28:41 +0800 Subject: [PATCH 1/6] update to grub2-2.02-142.el8_7.1 Signed-off-by: anolis-bot --- ...ort-for-trusted-boot-using-a-vTPM-2..patch | 221 ++ ...ackport-ibmvtpm-support-to-grub-2.02.patch | 94 + ...erpc-do-CAS-in-a-more-compatible-way.patch | 112 + ...etection-support-device-names-with-c.patch | 73 + 0505-make-ofdisk_retries-optional.patch | 43 + ...loader-grub_load_and_start_image-doe.patch | 1 - ...hainloader-simplify-the-loader-state.patch | 1 - ...ot-Add-API-to-pass-context-to-loader.patch | 1 - ...i-chainloader-Use-grub_loader_set_ex.patch | 1 - ...linux-Avoid-a-use-after-free-in-the-.patch | 1 - ...386-efi-linux-Use-grub_loader_set_ex.patch | 1 - ...linux-Fix-a-memory-leak-in-the-initr.patch | 1 - ...-leak-device_name-on-error-in-grub_f.patch | 1 - ...g-Abort-sooner-if-a-read-operation-f.patch | 1 - ...g-Refuse-to-handle-multiple-image-he.patch | 1 - ...g-Drop-greyscale-support-to-fix-heap.patch | 1 - ...g-Avoid-heap-OOB-R-W-inserting-huff-.patch | 1 - ...-png-Sanity-check-some-huffman-codes.patch | 1 - ...eg-Abort-sooner-if-a-read-operation-.patch | 1 - ...eg-Do-not-reallocate-a-given-huff-ta.patch | 1 - ...eg-Refuse-to-handle-multiple-start-o.patch | 1 - ...eg-Block-int-underflow-wild-pointer-.patch | 1 - ...ix-array-out-of-bounds-formatting-un.patch | 1 - ...ff-Block-overly-large-netbuff-allocs.patch | 1 - ...5-net-ip-Do-IP-fragment-maths-safely.patch | 1 - ...le-free-addresses-on-corrupt-DNS-res.patch | 1 - ...ad-past-the-end-of-the-string-we-re-.patch | 1 - ...-a-UAF-and-double-free-from-a-failed.patch | 1 - ...ng-for-grub_error-should-be-a-litera.patch | 1 - ...=> 0530-net-tftp-Avoid-a-trivial-UAF.patch | 1 - ...tear-down-socket-if-it-s-already-bee.patch | 1 - ...Fix-OOB-write-for-split-http-headers.patch | 1 - ...or-out-on-headers-with-LF-without-CR.patch | 1 - ...ead-past-the-end-of-nat-journal-entr.patch | 1 - ...-not-read-past-the-end-of-nat-bitmap.patch | 1 - ...ot-copy-file-names-that-are-too-long.patch | 1 - ...eral-fuzz-issues-with-invalid-dir-it.patch | 1 - ...efi_status_t-from-grub_efi_get_varia.patch | 1 - ...on-to-read-EFI-variables-with-attrib.patch | 1 - ... 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch | 1 - ...grub_min-and-grub_max-more-resilient.patch | 1 - ...FS-switch-to-using-grub_min-grub_max.patch | 1 - ...oot_time-also-call-grub_dprintf-boot.patch | 1 - ...dules-make-.module_license-read-only.patch | 1 - ...p-.llvm_addrsig-sections-and-similar.patch | 1 - ...locate-space-for-non-allocable-secti.patch | 1 - ...eader-struct-and-fix-some-bad-naming.patch | 1 - ...nel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch | 1 - ...ule-sections-at-page-aligned-address.patch | 1 - ...-nx-add-memory-attribute-get-set-API.patch | 1 - ...-page-permissions-for-loaded-modules.patch | 1 - ...2-nx-set-attrs-in-our-kernel-loaders.patch | 1 - ...x-compatible-flag-in-EFI-grub-images.patch | 3 +- ...efi_get_variable-type-in-our-loaders.patch | 1 - ...file-show-which-file-filters-get-run.patch | 47 + ...ed-array-positions-for-our-allocatio.patch | 83 + ...tion-policy-for-kernel-vs-initrd-mem.patch | 129 + ...ER_-CODE-DATA-for-kernel-and-initrd-.patch | 63 + ...5-implement-vec5-for-cas-negotiation.patch | 72 + ...ncorrect-array-size-in-kernel-alloca.patch | 38 + ...g-don-t-assume-newline-at-end-of-cfg.patch | 25 + ...hs-exceeds-font-max_glyph_width-or-f.patch | 33 + ...erflow-in-grub_font_get_glyph_intern.patch | 112 + ...-integer-overflows-in-grub_font_cons.patch | 81 + 0565-font-Remove-grub_font_dup_glyph.patch | 42 + ...nteger-overflow-in-ensure_comb_space.patch | 48 + ...nt-Fix-integer-overflow-in-BMP-index.patch | 65 + ...-underflow-in-binary-search-of-char-.patch | 85 + 0569-fbutil-Fix-integer-overflow.patch | 85 + ...ix-an-integer-underflow-in-blit_comb.patch | 91 + ..._font_blit_glyph-and-grub_font_blit_.patch | 75 + ...l_font-to-glyphs-in-ascii_font_glyph.patch | 36 + ...ix-an-integer-overflow-in-grub_unico.patch | 55 + 1001-bls-make-list.patch | 119 - ...-support-and-update-interface-to-v40.patch | 3444 ----------------- ...x-EFI-loader-kernel-image-allocation.patch | 185 - 20-grub.install | 2 +- dist | 1 + grub.macros | 20 +- grub.patches | 125 +- grub2.spec | 94 +- redhatsecureboot303.cer | Bin 899 -> 0 bytes redhatsecureboot701.cer | Bin 0 -> 916 bytes sbat.csv.in | 2 +- 84 files changed, 1945 insertions(+), 3906 deletions(-) create mode 100644 0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch create mode 100644 0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch create mode 100644 0503-powerpc-do-CAS-in-a-more-compatible-way.patch create mode 100644 0504-powerpc-prefix-detection-support-device-names-with-c.patch create mode 100644 0505-make-ofdisk_retries-optional.patch rename 0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch => 0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch (97%) rename 0502-loader-efi-chainloader-simplify-the-loader-state.patch => 0507-loader-efi-chainloader-simplify-the-loader-state.patch (99%) rename 0503-commands-boot-Add-API-to-pass-context-to-loader.patch => 0508-commands-boot-Add-API-to-pass-context-to-loader.patch (98%) rename 0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch => 0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch (98%) rename 0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch => 0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch (95%) rename 0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch => 0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch (99%) rename 0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch => 0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch (97%) rename 0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch => 0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch (95%) rename 0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch => 0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch (98%) rename 0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch => 0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch (94%) rename 0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch => 0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch (98%) rename 0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch => 0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch (95%) rename 0513-video-readers-png-Sanity-check-some-huffman-codes.patch => 0518-video-readers-png-Sanity-check-some-huffman-codes.patch (96%) rename 0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch => 0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch (99%) rename 0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch => 0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch (94%) rename 0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch => 0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch (96%) rename 0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch => 0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch (96%) rename 0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch => 0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch (95%) rename 0519-net-netbuff-Block-overly-large-netbuff-allocs.patch => 0524-net-netbuff-Block-overly-large-netbuff-allocs.patch (95%) rename 0520-net-ip-Do-IP-fragment-maths-safely.patch => 0525-net-ip-Do-IP-fragment-maths-safely.patch (95%) rename 0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch => 0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch (96%) rename 0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch => 0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch (97%) rename 0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch => 0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch (98%) rename 0524-misc-Format-string-for-grub_error-should-be-a-litera.patch => 0529-misc-Format-string-for-grub_error-should-be-a-litera.patch (96%) rename 0525-net-tftp-Avoid-a-trivial-UAF.patch => 0530-net-tftp-Avoid-a-trivial-UAF.patch (95%) rename 0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch => 0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch (96%) rename 0527-net-http-Fix-OOB-write-for-split-http-headers.patch => 0532-net-http-Fix-OOB-write-for-split-http-headers.patch (96%) rename 0528-net-http-Error-out-on-headers-with-LF-without-CR.patch => 0533-net-http-Error-out-on-headers-with-LF-without-CR.patch (96%) rename 0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch => 0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch (97%) rename 0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch => 0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch (98%) rename 0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch => 0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch (95%) rename 0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch => 0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch (97%) rename 0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch => 0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch (98%) rename 0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch => 0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch (97%) rename 0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch => 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch (93%) rename 0536-misc-Make-grub_min-and-grub_max-more-resilient.patch => 0541-misc-Make-grub_min-and-grub_max-more-resilient.patch (97%) rename 0537-ReiserFS-switch-to-using-grub_min-grub_max.patch => 0542-ReiserFS-switch-to-using-grub_min-grub_max.patch (98%) rename 0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch => 0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch (96%) rename 0539-modules-make-.module_license-read-only.patch => 0544-modules-make-.module_license-read-only.patch (95%) rename 0540-modules-strip-.llvm_addrsig-sections-and-similar.patch => 0545-modules-strip-.llvm_addrsig-sections-and-similar.patch (95%) rename 0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch => 0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch (95%) rename 0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch => 0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch (97%) rename 0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch => 0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch (98%) rename 0544-modules-load-module-sections-at-page-aligned-address.patch => 0549-modules-load-module-sections-at-page-aligned-address.patch (99%) rename 0545-nx-add-memory-attribute-get-set-API.patch => 0550-nx-add-memory-attribute-get-set-API.patch (99%) rename 0546-nx-set-page-permissions-for-loaded-modules.patch => 0551-nx-set-page-permissions-for-loaded-modules.patch (99%) rename 0547-nx-set-attrs-in-our-kernel-loaders.patch => 0552-nx-set-attrs-in-our-kernel-loaders.patch (99%) rename 0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch => 0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch (93%) rename 0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch => 0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch (96%) create mode 100644 0555-Make-debug-file-show-which-file-filters-get-run.patch create mode 100644 0556-efi-use-enumerated-array-positions-for-our-allocatio.patch create mode 100644 0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch create mode 100644 0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch create mode 100644 0559-ieee1275-implement-vec5-for-cas-negotiation.patch create mode 100644 0560-x86-efi-Fix-an-incorrect-array-size-in-kernel-alloca.patch create mode 100644 0561-switch-to-blscfg-don-t-assume-newline-at-end-of-cfg.patch create mode 100644 0562-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch create mode 100644 0563-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch create mode 100644 0564-font-Fix-several-integer-overflows-in-grub_font_cons.patch create mode 100644 0565-font-Remove-grub_font_dup_glyph.patch create mode 100644 0566-font-Fix-integer-overflow-in-ensure_comb_space.patch create mode 100644 0567-font-Fix-integer-overflow-in-BMP-index.patch create mode 100644 0568-font-Fix-integer-underflow-in-binary-search-of-char-.patch create mode 100644 0569-fbutil-Fix-integer-overflow.patch create mode 100644 0570-font-Fix-an-integer-underflow-in-blit_comb.patch create mode 100644 0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch create mode 100644 0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch create mode 100644 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch delete mode 100644 1001-bls-make-list.patch delete mode 100644 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch delete mode 100644 1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch create mode 100644 dist delete mode 100644 redhatsecureboot303.cer create mode 100644 redhatsecureboot701.cer diff --git a/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch b/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch new file mode 100644 index 0000000..a2d6ebc --- /dev/null +++ b/0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch @@ -0,0 +1,221 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Sun, 15 Mar 2020 12:37:10 -0400 +Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0 + +Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275 +PowerPC platform. With this patch grub now measures text and binary data +into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform +does. + +This patch requires Daniel Axtens's patches for claiming more memory. + +For vTPM support to work on PowerVM, system driver levels 1010.30 +or 1020.00 are required. + +Note: Previous versions of firmware levels with the 2hash-ext-log +API call have a bug that, once this API call is invoked, has the +effect of disabling the vTPM driver under Linux causing an error +message to be displayed in the Linux kernel log. Those users will +have to update their machines to the firmware levels mentioned +above. + +Cc: Eric Snowberg +Signed-off-by: Stefan Berger +--- + grub-core/Makefile.core.def | 7 ++ + grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++ + include/grub/ieee1275/ieee1275.h | 3 + + 3 files changed, 162 insertions(+) + create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index ef06f8c95a..b11f74e6b2 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1104,6 +1104,13 @@ module = { + enable = powerpc_ieee1275; + }; + ++module = { ++ name = tpm; ++ common = commands/tpm.c; ++ ieee1275 = commands/ieee1275/ibmvtpm.c; ++ enable = powerpc_ieee1275; ++}; ++ + module = { + name = terminal; + common = commands/terminal.c; +diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c +new file mode 100644 +index 0000000000..e68b8448bc +--- /dev/null ++++ b/grub-core/commands/ieee1275/ibmvtpm.c +@@ -0,0 +1,152 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * Copyright (C) 2021 IBM Corporation ++ * ++ * 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 . ++ * ++ * IBM vTPM support code. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static grub_ieee1275_ihandle_t tpm_ihandle; ++static grub_uint8_t tpm_version; ++ ++#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0) ++ ++static void ++tpm_get_tpm_version (void) ++{ ++ grub_ieee1275_phandle_t vtpm; ++ char buffer[20]; ++ ++ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) && ++ !grub_ieee1275_get_property (vtpm, "compatible", buffer, ++ sizeof (buffer), NULL) && ++ !grub_strcmp (buffer, "IBM,vtpm20")) ++ tpm_version = 2; ++} ++ ++static grub_err_t ++tpm_init (void) ++{ ++ static int init_success = 0; ++ ++ if (!init_success) ++ { ++ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) { ++ tpm_ihandle = IEEE1275_IHANDLE_INVALID; ++ return GRUB_ERR_UNKNOWN_DEVICE; ++ } ++ ++ init_success = 1; ++ ++ tpm_get_tpm_version (); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static int ++ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex, ++ grub_uint32_t eventtype, ++ const char *description, ++ grub_size_t description_size, ++ void *buf, grub_size_t size) ++{ ++ struct tpm_2hash_ext_log ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t size; ++ grub_ieee1275_cell_t buf; ++ grub_ieee1275_cell_t description_size; ++ grub_ieee1275_cell_t description; ++ grub_ieee1275_cell_t eventtype; ++ grub_ieee1275_cell_t pcrindex; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t rc; ++ } ++ args; ++ ++ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2); ++ args.method = (grub_ieee1275_cell_t) "2hash-ext-log"; ++ args.ihandle = tpm_ihandle; ++ args.pcrindex = pcrindex; ++ args.eventtype = eventtype; ++ args.description = (grub_ieee1275_cell_t) description; ++ args.description_size = description_size; ++ args.buf = (grub_ieee1275_cell_t) buf; ++ args.size = (grub_ieee1275_cell_t) size; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&args) == -1) ++ return -1; ++ ++ /* ++ * catch_result is set if firmware does not support 2hash-ext-log ++ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure ++ */ ++ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE) ++ return -1; ++ ++ return 0; ++} ++ ++static grub_err_t ++tpm2_log_event (unsigned char *buf, ++ grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ static int error_displayed = 0; ++ int err; ++ ++ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL, ++ description, ++ grub_strlen(description) + 1, ++ buf, size); ++ if (err && !error_displayed) ++ { ++ error_displayed++; ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ "2HASH-EXT-LOG failed: Firmware is likely too old.\n"); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ grub_err_t err = tpm_init(); ++ ++ /* Absence of a TPM isn't a failure. */ ++ if (err != GRUB_ERR_NONE) ++ return GRUB_ERR_NONE; ++ ++ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", ++ pcr, size, description); ++ ++ if (tpm_version == 2) ++ return tpm2_log_event (buf, size, pcr, description); ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 131808d619..87b9f95d34 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -24,6 +24,9 @@ + #include + #include + ++#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0) ++#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1) ++ + struct grub_ieee1275_mem_region + { + unsigned int start; diff --git a/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch b/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch new file mode 100644 index 0000000..ba6a869 --- /dev/null +++ b/0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Fri, 11 Feb 2022 16:34:23 -0500 +Subject: [PATCH] ibmvtpm: Backport ibmvtpm support to grub 2.02 + +Backport ibmvtpm support to grub 2.02 by making as few changes to the +source as possible and building it into the core. + +Since ibmvtpm support is built into grub 2.02 do not print the error +message we would typically print if it was a module and the user had +a choice to not use vTPM support if there was no vTPM by avoiding +to use the module. + +Signed-off-by: Stefan Berger +--- + grub-core/Makefile.core.def | 8 +------- + grub-core/commands/ieee1275/ibmvtpm.c | 13 ++++++++++--- + include/grub/tpm.h | 2 +- + 3 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index b11f74e6b2..637d7203e3 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -298,6 +298,7 @@ kernel = { + powerpc_ieee1275 = kern/powerpc/cache.S; + powerpc_ieee1275 = kern/powerpc/dl.c; + powerpc_ieee1275 = kern/powerpc/compiler-rt.S; ++ powerpc_ieee1275 = commands/ieee1275/ibmvtpm.c; + + sparc64_ieee1275 = kern/sparc64/cache.S; + sparc64_ieee1275 = kern/sparc64/dl.c; +@@ -1104,13 +1105,6 @@ module = { + enable = powerpc_ieee1275; + }; + +-module = { +- name = tpm; +- common = commands/tpm.c; +- ieee1275 = commands/ieee1275/ibmvtpm.c; +- enable = powerpc_ieee1275; +-}; +- + module = { + name = terminal; + common = commands/terminal.c; +diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c +index e68b8448bc..728b2cbdcd 100644 +--- a/grub-core/commands/ieee1275/ibmvtpm.c ++++ b/grub-core/commands/ieee1275/ibmvtpm.c +@@ -115,7 +115,8 @@ tpm2_log_event (unsigned char *buf, + grub_size_t size, grub_uint8_t pcr, + const char *description) + { +- static int error_displayed = 0; ++ /* Do not print error since vTPM support is built-in */ ++ static int error_displayed = 1; + int err; + + err = ibmvtpm_2hash_ext_log (pcr, EV_IPL, +@@ -132,8 +133,8 @@ tpm2_log_event (unsigned char *buf, + return GRUB_ERR_NONE; + } + +-grub_err_t +-grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, ++static grub_err_t ++_grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) + { + grub_err_t err = tpm_init(); +@@ -150,3 +151,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + + return GRUB_ERR_NONE; + } ++ ++grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size, ++ grub_uint8_t pcr, const char *description) ++{ ++ return _grub_tpm_measure(buf, size, pcr, description); ++} +diff --git a/include/grub/tpm.h b/include/grub/tpm.h +index ce52be4ff7..52af2b8448 100644 +--- a/include/grub/tpm.h ++++ b/include/grub/tpm.h +@@ -69,7 +69,7 @@ typedef struct { + grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size, + grub_uint8_t pcr, const char *kind, + const char *description); +-#if defined (GRUB_MACHINE_EFI) ++#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_IEEE1275) + grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, + PassThroughToTPM_OutputParamBlock *outbuf); + grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size, diff --git a/0503-powerpc-do-CAS-in-a-more-compatible-way.patch b/0503-powerpc-do-CAS-in-a-more-compatible-way.patch new file mode 100644 index 0000000..b33cab3 --- /dev/null +++ b/0503-powerpc-do-CAS-in-a-more-compatible-way.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 8 Apr 2022 12:35:28 +1000 +Subject: [PATCH] powerpc: do CAS in a more compatible way + +I wrongly assumed that the most compatible way to perform CAS +negotiation was to only set the minimum number of vectors required +to ask for more memory. It turns out that this messes up booting +if the minimum VP capacity would be less than the default 10% in +vector 4. + +Linux configures the minimum capacity to be 1%, so copy it for that +and for vector 3 which we now need to specify as well. + +Signed-off-by: Daniel Axtens +(cherry picked from commit e6f02ad4e75cd995a8ee2954d28949c415b6cbfe) +(cherry picked from commit 9f825ebc319c56ca503741e6dc1a0f27ff36fe2d) +--- + grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------ + 1 file changed, 31 insertions(+), 23 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index adf4bd5a88..1414695cc6 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -294,33 +294,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total) + + /* Based on linux - arch/powerpc/kernel/prom_init.c */ + struct option_vector2 { +- grub_uint8_t byte1; +- grub_uint16_t reserved; +- grub_uint32_t real_base; +- grub_uint32_t real_size; +- grub_uint32_t virt_base; +- grub_uint32_t virt_size; +- grub_uint32_t load_base; +- grub_uint32_t min_rma; +- grub_uint32_t min_load; +- grub_uint8_t min_rma_percent; +- grub_uint8_t max_pft_size; ++ grub_uint8_t byte1; ++ grub_uint16_t reserved; ++ grub_uint32_t real_base; ++ grub_uint32_t real_size; ++ grub_uint32_t virt_base; ++ grub_uint32_t virt_size; ++ grub_uint32_t load_base; ++ grub_uint32_t min_rma; ++ grub_uint32_t min_load; ++ grub_uint8_t min_rma_percent; ++ grub_uint8_t max_pft_size; + } __attribute__((packed)); + + struct pvr_entry { +- grub_uint32_t mask; +- grub_uint32_t entry; ++ grub_uint32_t mask; ++ grub_uint32_t entry; + }; + + struct cas_vector { +- struct { +- struct pvr_entry terminal; +- } pvr_list; +- grub_uint8_t num_vecs; +- grub_uint8_t vec1_size; +- grub_uint8_t vec1; +- grub_uint8_t vec2_size; +- struct option_vector2 vec2; ++ struct { ++ struct pvr_entry terminal; ++ } pvr_list; ++ grub_uint8_t num_vecs; ++ grub_uint8_t vec1_size; ++ grub_uint8_t vec1; ++ grub_uint8_t vec2_size; ++ struct option_vector2 vec2; ++ grub_uint8_t vec3_size; ++ grub_uint16_t vec3; ++ grub_uint8_t vec4_size; ++ grub_uint16_t vec4; + } __attribute__((packed)); + + /* Call ibm,client-architecture-support to try to get more RMA. +@@ -341,13 +345,17 @@ grub_ieee1275_ibm_cas (void) + } args; + struct cas_vector vector = { + .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ +- .num_vecs = 2 - 1, ++ .num_vecs = 4 - 1, + .vec1_size = 0, + .vec1 = 0x80, /* ignore */ + .vec2_size = 1 + sizeof(struct option_vector2) - 2, + .vec2 = { + 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48 + }, ++ .vec3_size = 2 - 1, ++ .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied ++ .vec4_size = 2 - 1, ++ .vec4 = 0x0001, // set required minimum capacity % to the lowest value + }; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); +@@ -360,7 +368,7 @@ grub_ieee1275_ibm_cas (void) + args.ihandle = root; + args.cas_addr = (grub_ieee1275_cell_t)&vector; + +- grub_printf("Calling ibm,client-architecture-support..."); ++ grub_printf("Calling ibm,client-architecture-support from grub..."); + IEEE1275_CALL_ENTRY_FN (&args); + grub_printf("done\n"); + diff --git a/0504-powerpc-prefix-detection-support-device-names-with-c.patch b/0504-powerpc-prefix-detection-support-device-names-with-c.patch new file mode 100644 index 0000000..50a5d64 --- /dev/null +++ b/0504-powerpc-prefix-detection-support-device-names-with-c.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Thu, 24 Mar 2022 14:34:32 +1100 +Subject: [PATCH] powerpc: prefix detection: support device names with commas + +Frustratingly, the device name itself can contain an embedded comma: +e.g /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b + +So my previous approach was wrong: we cannot rely upon the presence +of a comma to say that a partition has been specified! + +It turns out for prefixes like (,gpt2)/grub2 we really want to make +up a full (device,partition)/patch prefix, because root discovery code +in 10_linux will reset the root variable and use search to fill it again. +If you have run grub-install, you probably don't have search built in, +and if you don't have prefix containing (device,partition), grub will +construct ($root)$prefix/powerpc-ieee1275/search.mod - but because $root +has just been changed, this will no longer work, and the boot will fail! + +Retain the gist of the logic, but instead of looking for a comma, look for +a leading '('. This matches the earlier code better anyway. + +There's certainly a better fix to be had. But any time you chose to build +with a bare prefix like '/grub2', you're almost certainly going to build in +search anyway, so this will do. + +Signed-off-by: Daniel Axtens +(cherry picked from commit 80b6eb5e55e6d1a4c9896361e61de31c29e6939d) +(cherry picked from commit f3df9f1c2335df22d020e80583d932e254594f0e) +--- + grub-core/kern/main.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 40a709117f..abbf8af9e6 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -241,14 +241,29 @@ grub_set_prefix_and_root (void) + what sorts of paths represent disks with partition tables and those + without partition tables. + +- So we act unless there is a comma in the device, which would indicate +- a partition has already been specified. ++ - Frustratingly, the device name itself can contain an embedded comma: ++ /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b ++ So we cannot even rely upon the presence of a comma to say that a ++ partition has been specified! + +- (If we only have a path, the code in normal to discover config files +- will try both without partitions and then with any partitions so we +- will cover both CDs and HDs.) ++ If we only have a path in $prefix, the code in normal to discover ++ config files will try all disks, both without partitions and then with ++ any partitions so we will cover both CDs and HDs. ++ ++ However, it doesn't then set the prefix to be something like ++ (discovered partition)/path, and so it is fragile against runtime ++ changes to $root. For example some of the stuff done in 10_linux to ++ reload $root sets root differently and then uses search to find it ++ again. If the search module is not built in, when we change root, grub ++ will look in (new root)/path/powerpc-ieee1275, that won't work, and we ++ will not be able to load the search module and the boot will fail. ++ ++ This is particularly likely to hit us in the grub-install ++ (,msdos2)/grub2 case, so we act unless the supplied prefix starts with ++ '(', which would likely indicate a partition has already been ++ specified. + */ +- if (grub_strchr (device, ',') == NULL) ++ if (prefix && prefix[0] != '(') + grub_env_set ("prefix", path); + else + #endif diff --git a/0505-make-ofdisk_retries-optional.patch b/0505-make-ofdisk_retries-optional.patch new file mode 100644 index 0000000..fce9702 --- /dev/null +++ b/0505-make-ofdisk_retries-optional.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Thu, 24 Mar 2022 13:14:42 -0400 +Subject: [PATCH] make ofdisk_retries optional + +The feature Retry on Fail added to GRUB can cause a LPM to take +longer if the SAN is slow. + +When a LPM to external site occur, the path of the disk can change +and thus the disk search function on grub can take some time since +it is used as a hint. This can cause the Retry on Fail feature to +try to access the disk 20x times (since this is hardcoded number) +and, if the SAN is slow, the boot time can increase a lot. +In some situations not acceptable. + +The following patch enables a configuration at user space of the +maximum number of retries we want for this feature. + +The variable ofdisk_retries should be set using grub2-editenv +and will be checked by retry function. If the variable is not set, +so the default number of retries will be used instead. +--- + include/grub/ieee1275/ofdisk.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h +index 7d2d540930..0074d55eee 100644 +--- a/include/grub/ieee1275/ofdisk.h ++++ b/include/grub/ieee1275/ofdisk.h +@@ -25,7 +25,12 @@ extern void grub_ofdisk_fini (void); + #define MAX_RETRIES 20 + + +-#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \ ++#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) \ ++ unsigned max_retries = MAX_RETRIES; \ ++ if(grub_env_get("ofdisk_retries") != NULL) \ ++ max_retries = grub_strtoul(grub_env_get("ofdisk_retries"), 0, 10)+1; \ ++ grub_dprintf("ofdisk","MAX_RETRIES set to %u\n",max_retries); \ ++ unsigned retry_i=0;for(retry_i=0; retry_i < max_retries; retry_i++){ \ + if(!grub_ieee1275_open(device, last_ihandle)) \ + break; \ + grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } diff --git a/0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch similarity index 97% rename from 0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch rename to 0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch index 1383d29..6472129 100644 --- a/0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch +++ b/0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch @@ -18,7 +18,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6) (cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538) (cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f) -(cherry picked from commit 4a23f40cb6400d94621de688a7e79dfe124f5a63) --- grub-core/loader/efi/chainloader.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/0502-loader-efi-chainloader-simplify-the-loader-state.patch b/0507-loader-efi-chainloader-simplify-the-loader-state.patch similarity index 99% rename from 0502-loader-efi-chainloader-simplify-the-loader-state.patch rename to 0507-loader-efi-chainloader-simplify-the-loader-state.patch index 4eb34ff..83b8823 100644 --- a/0502-loader-efi-chainloader-simplify-the-loader-state.patch +++ b/0507-loader-efi-chainloader-simplify-the-loader-state.patch @@ -20,7 +20,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit 6080ad5d91d6a80d5f67c592dd33b6dd413e9453) [rharwood: double frees and unintialized, context fuzz - orig_dp] Signed-off-by: Robbie Harwood -(cherry picked from commit b44b88ae45008611ec0469fb47139f4c0d1ee233) --- grub-core/loader/efi/chainloader.c | 160 +++++++++++++++++++++++-------------- 1 file changed, 102 insertions(+), 58 deletions(-) diff --git a/0503-commands-boot-Add-API-to-pass-context-to-loader.patch b/0508-commands-boot-Add-API-to-pass-context-to-loader.patch similarity index 98% rename from 0503-commands-boot-Add-API-to-pass-context-to-loader.patch rename to 0508-commands-boot-Add-API-to-pass-context-to-loader.patch index 4270078..a036524 100644 --- a/0503-commands-boot-Add-API-to-pass-context-to-loader.patch +++ b/0508-commands-boot-Add-API-to-pass-context-to-loader.patch @@ -20,7 +20,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3) (cherry picked from commit 937ad0e2159b6b8cb0d2ce3515da3a8b797c7927) (cherry picked from commit 873038ae7048f6cae8a3ebb2f97a8d361a080e13) -(cherry picked from commit 7eefe9ba7e8f1557705f0f854ab7a3014d6cb5e2) --- grub-core/commands/boot.c | 66 +++++++++++++++++++++++++++++++++++++++++------ include/grub/loader.h | 5 ++++ diff --git a/0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch similarity index 98% rename from 0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch rename to 0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch index 4ccc6df..d494a85 100644 --- a/0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch +++ b/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch @@ -11,7 +11,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9) (cherry picked from commit fc1a79bf0e0bc019362ace46d908a92b48dcd55b) (cherry picked from commit f5b653dfe00271384ff7fbd82db926ab95dbd80e) -(cherry picked from commit 535a9d787f71ed6eb43e7c3a136a149684ec62ea) [rharwood: context sludge from previous commit] Signed-off-by: Robbie Harwood --- diff --git a/0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch similarity index 95% rename from 0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch rename to 0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch index cdbd769..f8809e6 100644 --- a/0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch +++ b/0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch @@ -14,7 +14,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2) (cherry picked from commit 4744b62e20d07674017213ac54d7442d679f9d1a) (cherry picked from commit 329633cb060957c3d2aca677ac733f07b213a63f) -(cherry picked from commit 47b839b0a801ee4852447a85fb5de91dc7d2c856) --- grub-core/loader/i386/efi/linux.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch b/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch similarity index 99% rename from 0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch rename to 0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch index a0f04a2..981ea45 100644 --- a/0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch +++ b/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch @@ -20,7 +20,6 @@ Signed-off-by: Chris Coulson [rharwood: verifying twice] Signed-off-by: Robbie Harwood (cherry picked from commit df804892f1a754d88a9779320f9429bf40d2a1b3) -(cherry picked from commit d1b506f6c910b96ad47a20247b438c6402a74948) --- grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch b/0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch similarity index 97% rename from 0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch rename to 0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch index 6236395..1a8cae9 100644 --- a/0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch +++ b/0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch @@ -11,7 +11,6 @@ Signed-off-by: Chris Coulson (cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0) (cherry picked from commit 62234d6a00e6d1dd8e017ff161d359feb5234082) (cherry picked from commit bda5a10716dc9676400dce1374232452f46d0bc4) -(cherry picked from commit b862299a8502282a09af8e6c6189edd5b0a368b0) --- grub-core/loader/i386/efi/linux.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch b/0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch similarity index 95% rename from 0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch rename to 0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch index 3afccaf..aff3231 100644 --- a/0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch +++ b/0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch @@ -15,7 +15,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea) (cherry picked from commit 2ec50b289d8b24922433439533113087f111f110) (cherry picked from commit 17c36ae88d7d6040cabc01cd4a21e71ff4731668) -(cherry picked from commit 723e7dbedb7669343e564d453d21b8ed2ab81216) --- grub-core/kern/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch b/0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch similarity index 98% rename from 0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch rename to 0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch index db3764a..12dba4d 100644 --- a/0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch +++ b/0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch @@ -13,7 +13,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494) (cherry picked from commit 3f6fc3ebfd58fcdb3fe6c2f7a5a4fa05772ae786) (cherry picked from commit aac5b8257d4078c3f764216aeae3367bdc19043f) -(cherry picked from commit e9e58c9711de334fcf48a651ee20c21f2855a4bd) --- grub-core/video/readers/png.c | 55 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch b/0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch similarity index 94% rename from 0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch rename to 0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch index f882341..e6bad78 100644 --- a/0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch +++ b/0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch @@ -10,7 +10,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb) (cherry picked from commit 6e10bba6a4cbfd6c7bf116f41fd4e037465e19d8) (cherry picked from commit 812272d919ecfd368c008f15b677d369616ada54) -(cherry picked from commit c04569b35600aa29d5b4cd8990a8ee1dd1162c72) --- grub-core/video/readers/png.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch similarity index 98% rename from 0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch rename to 0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch index ba88782..5233539 100644 --- a/0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +++ b/0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch @@ -37,7 +37,6 @@ Reviewed-by: Daniel Kiper Signed-off-by: Robbie Harwood (cherry picked from commit 4c631c8119206b3178912df2905434d967661c3d) (cherry picked from commit 6d5d5f51266b8113c6ba560835500e3c135f3722) -(cherry picked from commit b20fc5589561a8c57a2071b2ae93fcdcf51a10d4) --- grub-core/video/readers/png.c | 85 +++---------------------------------------- 1 file changed, 6 insertions(+), 79 deletions(-) diff --git a/0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch similarity index 95% rename from 0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch rename to 0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch index a25685c..8c59310 100644 --- a/0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +++ b/0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch @@ -18,7 +18,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa) (cherry picked from commit 132ccc681cf642ad748580f26b54c9259a7f43fd) (cherry picked from commit 3a70e1f6e69af6e0d3c3cf526faa44dc0c80ac19) -(cherry picked from commit 809d25ffa6b89d390a66d2f3cf3090196f07e2aa) --- grub-core/video/readers/png.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/0513-video-readers-png-Sanity-check-some-huffman-codes.patch b/0518-video-readers-png-Sanity-check-some-huffman-codes.patch similarity index 96% rename from 0513-video-readers-png-Sanity-check-some-huffman-codes.patch rename to 0518-video-readers-png-Sanity-check-some-huffman-codes.patch index 4ba2e4d..ca2e209 100644 --- a/0513-video-readers-png-Sanity-check-some-huffman-codes.patch +++ b/0518-video-readers-png-Sanity-check-some-huffman-codes.patch @@ -12,7 +12,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117) (cherry picked from commit 5d09addf58086aa11d5f9a91af5632ff87c2d2ee) (cherry picked from commit ff12584f9376a472f37d4ec14213fd29bf3b233a) -(cherry picked from commit ac8b5464a076d2e38ecf7f761be9cd1f5bbeb784) --- grub-core/video/readers/png.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch b/0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch similarity index 99% rename from 0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch rename to 0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch index b5c2ca9..5d71be6 100644 --- a/0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch +++ b/0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch @@ -13,7 +13,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c) (cherry picked from commit 1ff8df0d2dea8ec7c8575241d5e7d6622c204ec3) (cherry picked from commit b07767383b74a0ce7135c09ba8701510d4ad32f0) -(cherry picked from commit 5f097165152d61d4aea02f26dc789d840147d50e) --- grub-core/video/readers/jpeg.c | 86 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch b/0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch similarity index 94% rename from 0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch rename to 0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch index 7677c8d..fb89198 100644 --- a/0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch +++ b/0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch @@ -11,7 +11,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9) (cherry picked from commit 5298bf758ea39a90537f9a1c76541ff2f21b970b) (cherry picked from commit aae6bac7f26c6b848156ed7adcff83309b833664) -(cherry picked from commit bc58c0da3aed59486042759a03fe61a9782e36ce) --- grub-core/video/readers/jpeg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch b/0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch similarity index 96% rename from 0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch rename to 0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch index bc4ef25..b484648 100644 --- a/0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch +++ b/0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch @@ -15,7 +15,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f) (cherry picked from commit db0154828989a0a52ee59a4dda8c3803752bc827) (cherry picked from commit 75afb375ef46bc99a7faf5879d0283934e34db97) -(cherry picked from commit 82f8de94e19be775cdabd05528dc7acf0cb485a7) --- grub-core/video/readers/jpeg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch similarity index 96% rename from 0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch rename to 0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch index 9434ba1..90decbc 100644 --- a/0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +++ b/0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch @@ -34,7 +34,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5) (cherry picked from commit 5f9582490792108306d047379fed2371bee286f8) (cherry picked from commit 7e4bf25d9bb5219fbf11c523296dc3bd78b80698) -(cherry picked from commit 397ecffe404b892470c41f4d24340526d3d33666) --- grub-core/video/readers/jpeg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch b/0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch similarity index 95% rename from 0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch rename to 0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch index 2043b05..6cbd3a5 100644 --- a/0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch +++ b/0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch @@ -17,7 +17,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d) (cherry picked from commit f2c10aaf335b88a69885375c4d68ffab2429df77) (cherry picked from commit 4c942e1ba8d1f1199a58d2eb139022ae22f75cb2) -(cherry picked from commit 83efea59ad671d043b3a48fe0581f11beb63303c) --- grub-core/normal/charset.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0519-net-netbuff-Block-overly-large-netbuff-allocs.patch b/0524-net-netbuff-Block-overly-large-netbuff-allocs.patch similarity index 95% rename from 0519-net-netbuff-Block-overly-large-netbuff-allocs.patch rename to 0524-net-netbuff-Block-overly-large-netbuff-allocs.patch index 6d590ee..5a59ff4 100644 --- a/0519-net-netbuff-Block-overly-large-netbuff-allocs.patch +++ b/0524-net-netbuff-Block-overly-large-netbuff-allocs.patch @@ -14,7 +14,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57) (cherry picked from commit acde668bb9d9fa862a1a63e3bbd5fa47fdfa9183) (cherry picked from commit e47ad2eb4fe38ef2bdcab52245286f31170e73e3) -(cherry picked from commit 3517b6baf69ee77065f0216ff29190ad392a2c84) --- grub-core/net/netbuff.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/0520-net-ip-Do-IP-fragment-maths-safely.patch b/0525-net-ip-Do-IP-fragment-maths-safely.patch similarity index 95% rename from 0520-net-ip-Do-IP-fragment-maths-safely.patch rename to 0525-net-ip-Do-IP-fragment-maths-safely.patch index 433d703..e4b8f45 100644 --- a/0520-net-ip-Do-IP-fragment-maths-safely.patch +++ b/0525-net-ip-Do-IP-fragment-maths-safely.patch @@ -12,7 +12,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936) (cherry picked from commit 552ad34583e788542e9ca08524a0d4bc8f98c297) (cherry picked from commit 2c8cb7e3b8b48b136a950e5692fa6251b76df90e) -(cherry picked from commit 17bb2fe79e6b9688cf2008b840af9022804204ec) --- grub-core/net/ip.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch b/0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch similarity index 96% rename from 0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch rename to 0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch index 1fa2c3e..11f6cb6 100644 --- a/0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch +++ b/0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch @@ -34,7 +34,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1) (cherry picked from commit d801a27e7acec6c1a83067fab0bb975877eaf704) (cherry picked from commit 4d8b6e36ddfda4084e370b3b08c432e8a462e9be) -(cherry picked from commit ae133c18f304cb0a22c569c98abc62e15ccf56d0) --- grub-core/net/dns.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch similarity index 97% rename from 0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch rename to 0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch index bd7797a..d641a9e 100644 --- a/0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch +++ b/0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch @@ -13,7 +13,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21) (cherry picked from commit e0589624e86bc96666cbdb62f6e55cafec2871b3) (cherry picked from commit 95ecbc0b9aacfd43ba96cccc50daaf39eccd9f7f) -(cherry picked from commit 110eee925ecd9efeebb8d018b042fcf067a443c2) --- grub-core/net/dns.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch b/0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch similarity index 98% rename from 0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch rename to 0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch index 6df1527..dc4aab2 100644 --- a/0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch +++ b/0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch @@ -46,7 +46,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81) (cherry picked from commit 352c5ae8a9fc715712e6ecbd7ccb6218122c748f) (cherry picked from commit 61a010085ab9f0ecf42677773a6fc212f1579b0a) -(cherry picked from commit 277d38531a47be78ac5062894e449726db2baf65) --- grub-core/net/net.c | 11 +++++++++-- grub-core/net/tftp.c | 1 + diff --git a/0524-misc-Format-string-for-grub_error-should-be-a-litera.patch b/0529-misc-Format-string-for-grub_error-should-be-a-litera.patch similarity index 96% rename from 0524-misc-Format-string-for-grub_error-should-be-a-litera.patch rename to 0529-misc-Format-string-for-grub_error-should-be-a-litera.patch index f4a4f32..ae0ec53 100644 --- a/0524-misc-Format-string-for-grub_error-should-be-a-litera.patch +++ b/0529-misc-Format-string-for-grub_error-should-be-a-litera.patch @@ -6,7 +6,6 @@ Subject: [PATCH] misc: Format string for grub_error() should be a literal Signed-off-by: Glenn Washburn Reviewed-by: Daniel Kiper (cherry-picked from commit 60875f4e15d704b875969b415501802b531c4db3) -(cherry-picked from commit 6353cbd63cb3615a2b7aece183e3b177250d9415) --- grub-core/loader/efi/chainloader.c | 2 +- grub-core/net/tftp.c | 2 +- diff --git a/0525-net-tftp-Avoid-a-trivial-UAF.patch b/0530-net-tftp-Avoid-a-trivial-UAF.patch similarity index 95% rename from 0525-net-tftp-Avoid-a-trivial-UAF.patch rename to 0530-net-tftp-Avoid-a-trivial-UAF.patch index 8c44b1f..f6f77f3 100644 --- a/0525-net-tftp-Avoid-a-trivial-UAF.patch +++ b/0530-net-tftp-Avoid-a-trivial-UAF.patch @@ -16,7 +16,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5) (cherry picked from commit dbe9abcdee6ce796811111b67e3f24eefe2135d1) (cherry picked from commit 72ae9c5d389d2c0337c44edead6e00db0bb84039) -(cherry picked from commit 6a367d5b45cee3b452319cbaba1052f045c68081) --- grub-core/net/tftp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch b/0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch similarity index 96% rename from 0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch rename to 0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch index 75082a8..6fcb3c6 100644 --- a/0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch +++ b/0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch @@ -15,7 +15,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85) (cherry picked from commit d39cf87ed701b9f0900daed7f672e07994d37ce8) (cherry picked from commit e0aa5c3acec70eac3489d6df1893a93726cbce3a) -(cherry picked from commit d29000397693cae279291b75ff89e5b9a5e2ed97) --- grub-core/net/http.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/0527-net-http-Fix-OOB-write-for-split-http-headers.patch b/0532-net-http-Fix-OOB-write-for-split-http-headers.patch similarity index 96% rename from 0527-net-http-Fix-OOB-write-for-split-http-headers.patch rename to 0532-net-http-Fix-OOB-write-for-split-http-headers.patch index eea35d6..daabc9e 100644 --- a/0527-net-http-Fix-OOB-write-for-split-http-headers.patch +++ b/0532-net-http-Fix-OOB-write-for-split-http-headers.patch @@ -27,7 +27,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617) (cherry picked from commit b604916beb6c39e8ed27f72851eb16f3eaa293c5) (cherry picked from commit c3c6b1167a43275991efd6847160a46ce3839fae) -(cherry picked from commit 9b4ef71ed4f6fce00e868e3223cdbfb734e840d6) --- grub-core/net/http.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/0528-net-http-Error-out-on-headers-with-LF-without-CR.patch b/0533-net-http-Error-out-on-headers-with-LF-without-CR.patch similarity index 96% rename from 0528-net-http-Error-out-on-headers-with-LF-without-CR.patch rename to 0533-net-http-Error-out-on-headers-with-LF-without-CR.patch index a50904e..86a3b28 100644 --- a/0528-net-http-Error-out-on-headers-with-LF-without-CR.patch +++ b/0533-net-http-Error-out-on-headers-with-LF-without-CR.patch @@ -24,7 +24,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de) (cherry picked from commit 8960e6d6137090a7e8c6592077da6e387a4ef972) (cherry picked from commit 9b6b9398c90dd76ce0b935d21c4ecb8954c4b2b7) -(cherry picked from commit 3eef2cc845f7ed34a89d8d0a7042d7768e43eaad) --- grub-core/net/http.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch b/0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch similarity index 97% rename from 0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch rename to 0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch index 93637a4..684fc75 100644 --- a/0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch +++ b/0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch @@ -15,7 +15,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit a3988cb3f0a108dd67ac127a79a4c8479d23334e) (cherry picked from commit 7125978aa7d6068812ef6da0ab38ce521ae7eba1) (cherry picked from commit e488538cbf9fc63796c7047550b0598e1ef95c03) -(cherry picked from commit a2e520d7ced2ded854fb24f3718530e1e6d7dd5e) --- grub-core/fs/f2fs.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch b/0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch similarity index 98% rename from 0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch rename to 0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch index 07de7cd..30ea7c6 100644 --- a/0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch +++ b/0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch @@ -23,7 +23,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 62d63d5e38c67a6e349148bf7cb87c560e935a7e) (cherry picked from commit 92219e6d379b5b4d30b05361830b72ab1d95d281) (cherry picked from commit c23d97e3b56594bf0f802d94062e14b221143115) -(cherry picked from commit e9536dd7fbdc632efbe3506386dbfb3bfc0465c8) --- grub-core/fs/f2fs.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch b/0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch similarity index 95% rename from 0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch rename to 0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch index 3444e4f..5ab2414 100644 --- a/0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch +++ b/0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch @@ -19,7 +19,6 @@ Reviewed-by: Daniel Kiper (cherry picked from commit 9a891f638509e031d322c94e3cbcf38d36f3993a) (cherry picked from commit 13f9160ae0d2806baed459884999356817096cd7) (cherry picked from commit a48ba4d48b3c66431e6bbeb386078efc6602110c) -(cherry picked from commit f0440b61cebbab807638b90eb2ae86265d6cf49f) --- grub-core/fs/f2fs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch b/0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch similarity index 97% rename from 0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch rename to 0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch index 289f139..21e95cf 100644 --- a/0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch +++ b/0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch @@ -24,7 +24,6 @@ Reviewed-by: Daniel Kiper Signed-off-by: Robbie Harwood (cherry picked from commit e3e21b9a81aea09dd43368cf097c1029a8380d82) (cherry picked from commit ab14a39777edb60c99751d4fdf1cc254a4faebf5) -(cherry picked from commit 90a9fbd5969325993e069ee5a04a802b59657920) --- grub-core/fs/btrfs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch b/0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch similarity index 98% rename from 0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch rename to 0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch index 0bc744f..184165b 100644 --- a/0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch +++ b/0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch @@ -12,7 +12,6 @@ Signed-off-by: Marco A Benatto Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Kiper (cherry picked from commit 04ae030d0eea8668d4417702d88bf2cf04713d80) -(cherry picked from commit ed33b47f00bc0d728197357b8ae632028f91599b) --- grub-core/commands/efi/efifwsetup.c | 8 ++++---- grub-core/kern/efi/efi.c | 16 +++++++++------- diff --git a/0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch b/0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch similarity index 97% rename from 0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch rename to 0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch index 8bc2666..526a123 100644 --- a/0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch +++ b/0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch @@ -12,7 +12,6 @@ Signed-off-by: Marco A Benatto Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Kiper (cherry picked from commit ac5c9367548750e75ed1e7fc4354a3d20186d733) -(cherry picked from commit 51b11f8b3ab96c38efb1636d9c53b5a86503f1f2) --- grub-core/kern/efi/efi.c | 16 +++++++++++++--- include/grub/efi/efi.h | 5 +++++ diff --git a/0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch b/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch similarity index 93% rename from 0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch rename to 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch index 6b00c5c..354ec29 100644 --- a/0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch +++ b/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch @@ -9,7 +9,6 @@ lock protocol definition and some other guids we don't care about right now. Signed-off-by: Robbie Harwood -(cherry picked from commit e44d6f8e801fae4716dd2528d7194f759c52aa12) --- include/grub/efi/api.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/0536-misc-Make-grub_min-and-grub_max-more-resilient.patch b/0541-misc-Make-grub_min-and-grub_max-more-resilient.patch similarity index 97% rename from 0536-misc-Make-grub_min-and-grub_max-more-resilient.patch rename to 0541-misc-Make-grub_min-and-grub_max-more-resilient.patch index 3cca336..bf1741b 100644 --- a/0536-misc-Make-grub_min-and-grub_max-more-resilient.patch +++ b/0541-misc-Make-grub_min-and-grub_max-more-resilient.patch @@ -20,7 +20,6 @@ create uniquely named internal variables. Signed-off-by: Peter Jones (cherry picked from commit 2d6800450fa731d7b3ef9893986806e88e819eb6) (cherry picked from commit adaf6a5ae66fb8a23274e3030e9df2714d0fc396) -(cherry picked from commit 5282d19d1942d9c3470337a84aa4a92562ba1575) --- grub-core/loader/multiboot_elfxx.c | 4 +--- include/grub/misc.h | 25 +++++++++++++++++++++++-- diff --git a/0537-ReiserFS-switch-to-using-grub_min-grub_max.patch b/0542-ReiserFS-switch-to-using-grub_min-grub_max.patch similarity index 98% rename from 0537-ReiserFS-switch-to-using-grub_min-grub_max.patch rename to 0542-ReiserFS-switch-to-using-grub_min-grub_max.patch index c3baecf..e8688dc 100644 --- a/0537-ReiserFS-switch-to-using-grub_min-grub_max.patch +++ b/0542-ReiserFS-switch-to-using-grub_min-grub_max.patch @@ -10,7 +10,6 @@ instead. Signed-off-by: Peter Jones (cherry picked from commit 5fc601574fce99b32fe4dfb55bd8f3ab0175fd6a) (cherry picked from commit 31e581893c564582c729fd0c033d3ce021854be8) -(cherry picked from commit 2c46aae48eabcf91d7ed34a7bed2b59aa80c2c03) --- grub-core/fs/reiserfs.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch b/0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch similarity index 96% rename from 0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch rename to 0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch index 9455dd1..37cb0a8 100644 --- a/0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch +++ b/0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch @@ -14,7 +14,6 @@ in DEBUG, regardless of BOOT_TIME_STATS. Signed-off-by: Peter Jones (cherry picked from commit 4fd282de00df05ce289467861deb7a0e186cfbd7) (cherry picked from commit cc7e60a9f3ad1fa74b9cd48a7e66b1976f9a554a) -(cherry picked from commit 9e78e5749d5c99a01c96c9c0d9ec3e98633a4cbd) --- grub-core/kern/misc.c | 3 ++- include/grub/misc.h | 2 +- diff --git a/0539-modules-make-.module_license-read-only.patch b/0544-modules-make-.module_license-read-only.patch similarity index 95% rename from 0539-modules-make-.module_license-read-only.patch rename to 0544-modules-make-.module_license-read-only.patch index 94dc892..e5af3e9 100644 --- a/0539-modules-make-.module_license-read-only.patch +++ b/0544-modules-make-.module_license-read-only.patch @@ -13,7 +13,6 @@ set. Signed-off-by: Peter Jones (cherry picked from commit 2eff3e2c9d9e6b75daa81b840c96f112ef7d5de6) (cherry picked from commit 3c3c1858d1c056eee660d67888be80e7eae498ca) -(cherry picked from commit ebcce09e35ef6916a2d1ddbf0906e9f3f5c539ad) --- include/grub/dl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0540-modules-strip-.llvm_addrsig-sections-and-similar.patch b/0545-modules-strip-.llvm_addrsig-sections-and-similar.patch similarity index 95% rename from 0540-modules-strip-.llvm_addrsig-sections-and-similar.patch rename to 0545-modules-strip-.llvm_addrsig-sections-and-similar.patch index 51aba29..c8a17de 100644 --- a/0540-modules-strip-.llvm_addrsig-sections-and-similar.patch +++ b/0545-modules-strip-.llvm_addrsig-sections-and-similar.patch @@ -18,7 +18,6 @@ failure is just reversion to the status quo, so that's not a big problem. Signed-off-by: Peter Jones (cherry picked from commit e85d1c4d795f8135ad0acfa36d64760d12d6fed1) (cherry picked from commit d3024204b2e2c69ecb91392eeb87c1e6835c3743) -(cherry picked from commit f729241a34394b1019d83d75ffe6bfe0986ab274) --- grub-core/genmod.sh.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch b/0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch similarity index 95% rename from 0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch rename to 0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch index 12c1a59..2f3bc0c 100644 --- a/0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch +++ b/0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch @@ -17,7 +17,6 @@ loop does. Signed-off-by: Peter Jones (cherry picked from commit 03215e342f552396ab08125ea769b1e166417ec1) (cherry picked from commit 91518751b9bcba078e3f4385f4b2f6c39cab49cd) -(cherry picked from commit ee945970425488bd5b72d837706764a6a0fde46c) --- grub-core/kern/dl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch b/0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch similarity index 97% rename from 0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch rename to 0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch index 8cc3da5..f9c2234 100644 --- a/0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch +++ b/0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch @@ -17,7 +17,6 @@ define, and adds defines for the actual PE magic. Signed-off-by: Peter Jones (cherry picked from commit 955f47aa8300387eecf18b0866d21dde7720593d) (cherry picked from commit 662744c2e986cb770fe49e71e019aaf33a66272d) -(cherry picked from commit 4b541b7e76b77d131ff534e537a622551e774a2b) --- grub-core/loader/arm64/linux.c | 2 +- include/grub/efi/pe32.h | 28 ++++++++++++++++++++++++++-- diff --git a/0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch b/0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch similarity index 98% rename from 0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch rename to 0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch index 7d7a44a..8644e51 100644 --- a/0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch +++ b/0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch @@ -16,7 +16,6 @@ Signed-off-by: Peter Jones Signed-off-by: Robbie Harwood (cherry picked from commit 8b31058a12d3e85f0f0180ac90b98d6465fccbb7) (cherry picked from commit 460df66aab9b3a57fc0d14a21a595cd467c4b13e) -(cherry picked from commit 2380ad45c78ed12710f1186eda9f2ba38c20f6ba) --- grub-core/loader/i386/efi/linux.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/0544-modules-load-module-sections-at-page-aligned-address.patch b/0549-modules-load-module-sections-at-page-aligned-address.patch similarity index 99% rename from 0544-modules-load-module-sections-at-page-aligned-address.patch rename to 0549-modules-load-module-sections-at-page-aligned-address.patch index 5cc42b1..44ecd2b 100644 --- a/0544-modules-load-module-sections-at-page-aligned-address.patch +++ b/0549-modules-load-module-sections-at-page-aligned-address.patch @@ -58,7 +58,6 @@ Signed-off-by: Peter Jones (cherry picked from commit 04f1df6b665493e38de66018aebe377fdac4ceec) [rharwood: not risc-v yet] Signed-off-by: Robbie Harwood -(cherry picked from commit 62c48da3ef51fc4f98746fbc35791ec2beab0426) --- grub-core/kern/arm/dl.c | 13 +++++++++++++ grub-core/kern/arm64/dl.c | 13 +++++++++++++ diff --git a/0545-nx-add-memory-attribute-get-set-API.patch b/0550-nx-add-memory-attribute-get-set-API.patch similarity index 99% rename from 0545-nx-add-memory-attribute-get-set-API.patch rename to 0550-nx-add-memory-attribute-get-set-API.patch index eec3160..41ae1d0 100644 --- a/0545-nx-add-memory-attribute-get-set-API.patch +++ b/0550-nx-add-memory-attribute-get-set-API.patch @@ -23,7 +23,6 @@ Signed-off-by: Peter Jones (cherry picked from commit 46cb4f9557bdba1db0a17d012df705d94d81a9f6) [rharwood: context fuzz, guids] Signed-off-by: Robbie Harwood -(cherry picked from commit 7d8eea48e82c4ef572cc0f9d3252487c1d7e5729) --- grub-core/kern/efi/efi.c | 36 +++++++++++++ grub-core/kern/efi/mm.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/0546-nx-set-page-permissions-for-loaded-modules.patch b/0551-nx-set-page-permissions-for-loaded-modules.patch similarity index 99% rename from 0546-nx-set-page-permissions-for-loaded-modules.patch rename to 0551-nx-set-page-permissions-for-loaded-modules.patch index 0d40b91..1032ea6 100644 --- a/0546-nx-set-page-permissions-for-loaded-modules.patch +++ b/0551-nx-set-page-permissions-for-loaded-modules.patch @@ -17,7 +17,6 @@ Signed-off-by: Peter Jones Signed-off-by: Robbie Harwood (cherry-picked from commit ca74904ede0406b594cbedc52ce8e38a6633d2ae) (cherry picked from commit 2e2e72026f41cf7cffeb46a6a47f3c67d0b3be45) -(cherry picked from commit 736e5ccd9175d31ebea848f3b627f3e99988bb0a) --- grub-core/kern/dl.c | 120 +++++++++++++++++++++++++++++++++++++++------------- include/grub/dl.h | 44 +++++++++++++++++++ diff --git a/0547-nx-set-attrs-in-our-kernel-loaders.patch b/0552-nx-set-attrs-in-our-kernel-loaders.patch similarity index 99% rename from 0547-nx-set-attrs-in-our-kernel-loaders.patch rename to 0552-nx-set-attrs-in-our-kernel-loaders.patch index 3fddaae..e4c4c3e 100644 --- a/0547-nx-set-attrs-in-our-kernel-loaders.patch +++ b/0552-nx-set-attrs-in-our-kernel-loaders.patch @@ -15,7 +15,6 @@ Signed-off-by: Peter Jones (cherry picked from commit daba852bd3e4d7b7784b19cf7acf107dc3c0dce4) [rharwood: stack_attrs initialization, no risc-v, arm renames, arm age] Signed-off-by: Robbie Harwood -(cherry picked from commit 3a402a2e54b3468b20eae182d98913600a6b68dd) --- grub-core/kern/efi/mm.c | 78 ++++++++++++++++++ grub-core/loader/arm64/linux.c | 16 +++- diff --git a/0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch b/0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch similarity index 93% rename from 0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch rename to 0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch index 801efca..662de5d 100644 --- a/0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch +++ b/0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch @@ -18,7 +18,8 @@ GRUB_PE32_NX_COMPAT, and changes grub-mkimage to set that flag. Signed-off-by: Peter Jones (cherry picked from commit 0c7f1aed5a87f75051b421903a900ccb4bbd795a) (cherry picked from commit 2f9446d488da96de963f4ffe03b0a1c60a4664f5) -(cherry picked from commit f56671343622b0e0216340cd07e77dfc4e88a97a) +[rharwood: fix uninitialized use of stack_attrs] +Signed-off-by: Robbie Harwood --- util/mkimage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch b/0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch similarity index 96% rename from 0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch rename to 0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch index 8ec08c8..7d0ca72 100644 --- a/0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch +++ b/0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch @@ -7,7 +7,6 @@ Has a new type now that we have 04ae030d0eea8668d4417702d88bf2cf04713d80 ("efi: Return grub_efi_status_t from grub_efi_get_variable()"). Signed-off-by: Robbie Harwood -(cherry picked from commit d27cee05d31a9612f0b877d2de727b22cc3ec51a) --- grub-core/kern/efi/init.c | 4 ++-- grub-core/kern/efi/sb.c | 4 ++-- diff --git a/0555-Make-debug-file-show-which-file-filters-get-run.patch b/0555-Make-debug-file-show-which-file-filters-get-run.patch new file mode 100644 index 0000000..b614ef3 --- /dev/null +++ b/0555-Make-debug-file-show-which-file-filters-get-run.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 29 Jul 2022 15:56:00 -0400 +Subject: [PATCH] Make debug=file show which file filters get run. + +If one of the file filters breaks things, it's hard to figure out where +it has happened. + +This makes grub log which filter is being run, which makes it easier to +figure out where you are in the sequence of events. + +Signed-off-by: Peter Jones +(cherry picked from commit d3d6518a13b5440a3be6c66b0ae47447182f2891) +(cherry picked from commit d197e70761b1383827e9008e21ee41c6c7015776) +--- + grub-core/kern/file.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c +index f062fc21e7..5e1f29d0dd 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -30,6 +30,14 @@ void (*EXPORT_VAR (grub_grubnet_fini)) (void); + + grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX]; + ++static char *filter_names[] = { ++ [GRUB_FILE_FILTER_VERIFY] = "GRUB_FILE_FILTER_VERIFY", ++ [GRUB_FILE_FILTER_GZIO] = "GRUB_FILE_FILTER_GZIO", ++ [GRUB_FILE_FILTER_XZIO] = "GRUB_FILE_FILTER_XZIO", ++ [GRUB_FILE_FILTER_LZOPIO] = "GRUB_FILE_FILTER_LZOPIO", ++ [GRUB_FILE_FILTER_MAX] = "GRUB_FILE_FILTER_MAX" ++}; ++ + /* Get the device part of the filename NAME. It is enclosed by parentheses. */ + char * + grub_file_get_device_name (const char *name) +@@ -121,6 +129,9 @@ grub_file_open (const char *name, enum grub_file_type type) + if (grub_file_filters[filter]) + { + last_file = file; ++ if (filter < GRUB_FILE_FILTER_MAX) ++ grub_dprintf ("file", "Running %s file filter\n", ++ filter_names[filter]); + file = grub_file_filters[filter] (file, type); + if (file && file != last_file) + { diff --git a/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch b/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch new file mode 100644 index 0000000..6f1bfc7 --- /dev/null +++ b/0556-efi-use-enumerated-array-positions-for-our-allocatio.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 1 Aug 2022 14:06:30 -0400 +Subject: [PATCH] efi: use enumerated array positions for our allocation + choices + +In our kernel allocator on EFI systems, we currently have a growing +amount of code that references the various allocation policies by +position in the array, and of course maintenance of this code scales +very poorly. + +This patch changes them to be enumerated, so they're easier to refer to +farther along in the code without confusion. + +Signed-off-by: Peter Jones +(cherry picked from commit 6768026270cca015d7fef0ecc8a4119e9b3d3923) +(cherry picked from commit 50b2ca3274b6950393a4ffc7edde04a1a3de594e) +--- + grub-core/loader/i386/efi/linux.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index d80d6ec312..23b27f6507 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -60,17 +60,26 @@ struct allocation_choice { + grub_efi_allocate_type_t alloc_type; + }; + +-static struct allocation_choice max_addresses[4] = ++enum { ++ KERNEL_PREF_ADDRESS, ++ KERNEL_4G_LIMIT, ++ KERNEL_NO_LIMIT, ++}; ++ ++static struct allocation_choice max_addresses[] = + { + /* the kernel overrides this one with pref_address and + * GRUB_EFI_ALLOCATE_ADDRESS */ +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ [KERNEL_PREF_ADDRESS] = ++ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ /* If the flag in params is set, this one gets changed to be above 4GB. */ ++ [KERNEL_4G_LIMIT] = ++ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, + /* this one is always below 4GB, which we still *prefer* even if the flag + * is set. */ +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, +- /* If the flag in params is set, this one gets changed to be above 4GB. */ +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, +- { 0, 0 } ++ [KERNEL_NO_LIMIT] = ++ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ { NO_MEM, 0, 0 } + }; + static struct allocation_choice saved_addresses[4]; + +@@ -423,7 +432,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G) + { + grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n"); +- max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS; ++ max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_USABLE_ADDRESS; + } + else + { +@@ -495,11 +504,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address); + if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS) + { +- max_addresses[0].addr = lh->pref_address; +- max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; ++ max_addresses[KERNEL_PREF_ADDRESS].addr = lh->pref_address; ++ max_addresses[KERNEL_PREF_ADDRESS].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; + } +- max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; +- max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; ++ max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; ++ max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; + kernel_size = lh->init_size; + kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE, + N_("can't allocate kernel")); diff --git a/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch b/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch new file mode 100644 index 0000000..08d2765 --- /dev/null +++ b/0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 1 Aug 2022 14:24:39 -0400 +Subject: [PATCH] efi: split allocation policy for kernel vs initrd memories. + +Currently in our kernel allocator, we use the same set of choices for +all of our various kernel and initramfs allocations, though they do not +have exactly the same constraints. + +This patch adds the concept of an allocation purpose, which currently +can be KERNEL_MEM or INITRD_MEM, and updates kernel_alloc() calls +appropriately, but does not change any current policy decision. It +also adds a few debug prints. + +Signed-off-by: Peter Jones +(cherry picked from commit 36307bed28cd838116fc4af26a30719660d62d4c) +(cherry picked from commit dc1196350b0cbe89582832f44df0fce67e0c9fb2) +--- + grub-core/loader/i386/efi/linux.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 23b27f6507..09e7596064 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -55,7 +55,14 @@ struct grub_linuxefi_context { + + #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) + ++typedef enum { ++ NO_MEM, ++ KERNEL_MEM, ++ INITRD_MEM, ++} kernel_alloc_purpose_t; ++ + struct allocation_choice { ++ kernel_alloc_purpose_t purpose; + grub_efi_physical_address_t addr; + grub_efi_allocate_type_t alloc_type; + }; +@@ -64,6 +71,7 @@ enum { + KERNEL_PREF_ADDRESS, + KERNEL_4G_LIMIT, + KERNEL_NO_LIMIT, ++ INITRD_MAX_ADDRESS, + }; + + static struct allocation_choice max_addresses[] = +@@ -71,14 +79,17 @@ static struct allocation_choice max_addresses[] = + /* the kernel overrides this one with pref_address and + * GRUB_EFI_ALLOCATE_ADDRESS */ + [KERNEL_PREF_ADDRESS] = +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, + /* If the flag in params is set, this one gets changed to be above 4GB. */ + [KERNEL_4G_LIMIT] = +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, + /* this one is always below 4GB, which we still *prefer* even if the flag + * is set. */ + [KERNEL_NO_LIMIT] = +- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, ++ /* this is for the initrd */ ++ [INITRD_MAX_ADDRESS] = ++ { INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, + { NO_MEM, 0, 0 } + }; + static struct allocation_choice saved_addresses[4]; +@@ -95,7 +106,8 @@ kernel_free(void *addr, grub_efi_uintn_t size) + } + + static void * +-kernel_alloc(grub_efi_uintn_t size, ++kernel_alloc(kernel_alloc_purpose_t purpose, ++ grub_efi_uintn_t size, + grub_efi_memory_type_t memtype, + const char * const errmsg) + { +@@ -108,6 +120,9 @@ kernel_alloc(grub_efi_uintn_t size, + grub_uint64_t max = max_addresses[i].addr; + grub_efi_uintn_t pages; + ++ if (purpose != max_addresses[i].purpose) ++ continue; ++ + /* + * When we're *not* loading the kernel, or >4GB allocations aren't + * supported, these entries are basically all the same, so don't re-try +@@ -262,7 +277,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + } + } + +- initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA, ++ grub_dprintf ("linux", "Trying to allocate initrd mem\n"); ++ initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA, + N_("can't allocate initrd")); + if (initrd_mem == NULL) + goto fail; +@@ -440,7 +456,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + } + #endif + +- params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA, ++ params = kernel_alloc (KERNEL_MEM, sizeof(*params), ++ GRUB_EFI_RUNTIME_SERVICES_DATA, + "cannot allocate kernel parameters"); + if (!params) + goto fail; +@@ -462,7 +479,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("linux", "new lh is at %p\n", lh); + + grub_dprintf ("linux", "setting up cmdline\n"); +- cmdline = kernel_alloc (lh->cmdline_size + 1, ++ cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1, + GRUB_EFI_RUNTIME_SERVICES_DATA, + N_("can't allocate cmdline")); + if (!cmdline) +@@ -510,7 +527,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; + max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; + kernel_size = lh->init_size; +- kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE, ++ grub_dprintf ("linux", "Trying to allocate kernel mem\n"); ++ kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size, ++ GRUB_EFI_RUNTIME_SERVICES_CODE, + N_("can't allocate kernel")); + restore_addresses(); + if (!kernel_mem) diff --git a/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch b/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch new file mode 100644 index 0000000..28f603e --- /dev/null +++ b/0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 1 Aug 2022 13:04:43 -0400 +Subject: [PATCH] efi: use EFI_LOADER_(CODE|DATA) for kernel and initrd + allocations + +At some point due to an erroneous kernel warning, we switched kernel and +initramfs to being loaded in EFI_RUNTIME_SERVICES_CODE and +EFI_RUNTIME_SERVICES_DATA memory pools. This doesn't appear to be +correct according to the spec, and that kernel warning has gone away. + +This patch puts them back in EFI_LOADER_CODE and EFI_LOADER_DATA +allocations, respectively. + +Resolves: rhbz#2108456 + +Signed-off-by: Peter Jones +(cherry picked from commit 35b5d5fa47bc394c76022e6595b173e68f53225e) +(cherry picked from commit 66e1c922b40957fca488435e06a2f875a219844b) +--- + grub-core/loader/i386/efi/linux.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 09e7596064..4d39023792 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -278,7 +278,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) + } + + grub_dprintf ("linux", "Trying to allocate initrd mem\n"); +- initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA, ++ initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_LOADER_DATA, + N_("can't allocate initrd")); + if (initrd_mem == NULL) + goto fail; +@@ -457,7 +457,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + #endif + + params = kernel_alloc (KERNEL_MEM, sizeof(*params), +- GRUB_EFI_RUNTIME_SERVICES_DATA, ++ GRUB_EFI_LOADER_DATA, + "cannot allocate kernel parameters"); + if (!params) + goto fail; +@@ -480,7 +480,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + + grub_dprintf ("linux", "setting up cmdline\n"); + cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1, +- GRUB_EFI_RUNTIME_SERVICES_DATA, ++ GRUB_EFI_LOADER_DATA, + N_("can't allocate cmdline")); + if (!cmdline) + goto fail; +@@ -529,7 +529,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + kernel_size = lh->init_size; + grub_dprintf ("linux", "Trying to allocate kernel mem\n"); + kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size, +- GRUB_EFI_RUNTIME_SERVICES_CODE, ++ GRUB_EFI_LOADER_CODE, + N_("can't allocate kernel")); + restore_addresses(); + if (!kernel_mem) diff --git a/0559-ieee1275-implement-vec5-for-cas-negotiation.patch b/0559-ieee1275-implement-vec5-for-cas-negotiation.patch new file mode 100644 index 0000000..ff614f8 --- /dev/null +++ b/0559-ieee1275-implement-vec5-for-cas-negotiation.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Thu, 25 Aug 2022 11:37:56 -0400 +Subject: [PATCH] ieee1275: implement vec5 for cas negotiation + +As a legacy support, if the vector 5 is not implemented, Power +Hypervisor will consider the max CPUs as 64 instead 256 currently +supported during client-architecture-support negotiation. + +This patch implements the vector 5 and set the MAX CPUs to 256 while +setting the others values to 0 (default). + +Signed-off-by: Diego Domingos +Signed-off-by: Robbie Harwood +(cherry picked from commit f735c65b6da8a9d4251242b37774e1a517511253) +(cherry picked from commit 1639f43b2db4ac405ac2a92e50ed4cff351c3baa) +--- + grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 1414695cc6..37f3098c39 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -307,6 +307,18 @@ struct option_vector2 { + grub_uint8_t max_pft_size; + } __attribute__((packed)); + ++struct option_vector5 { ++ grub_uint8_t byte1; ++ grub_uint8_t byte2; ++ grub_uint8_t byte3; ++ grub_uint8_t cmo; ++ grub_uint8_t associativity; ++ grub_uint8_t bin_opts; ++ grub_uint8_t micro_checkpoint; ++ grub_uint8_t reserved0; ++ grub_uint32_t max_cpus; ++} __attribute__((packed)); ++ + struct pvr_entry { + grub_uint32_t mask; + grub_uint32_t entry; +@@ -325,6 +337,8 @@ struct cas_vector { + grub_uint16_t vec3; + grub_uint8_t vec4_size; + grub_uint16_t vec4; ++ grub_uint8_t vec5_size; ++ struct option_vector5 vec5; + } __attribute__((packed)); + + /* Call ibm,client-architecture-support to try to get more RMA. +@@ -345,7 +359,7 @@ grub_ieee1275_ibm_cas (void) + } args; + struct cas_vector vector = { + .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ +- .num_vecs = 4 - 1, ++ .num_vecs = 5 - 1, + .vec1_size = 0, + .vec1 = 0x80, /* ignore */ + .vec2_size = 1 + sizeof(struct option_vector2) - 2, +@@ -356,6 +370,10 @@ grub_ieee1275_ibm_cas (void) + .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied + .vec4_size = 2 - 1, + .vec4 = 0x0001, // set required minimum capacity % to the lowest value ++ .vec5_size = 1 + sizeof(struct option_vector5) - 2, ++ .vec5 = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 256 ++ } + }; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); diff --git a/0560-x86-efi-Fix-an-incorrect-array-size-in-kernel-alloca.patch b/0560-x86-efi-Fix-an-incorrect-array-size-in-kernel-alloca.patch new file mode 100644 index 0000000..a422b99 --- /dev/null +++ b/0560-x86-efi-Fix-an-incorrect-array-size-in-kernel-alloca.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 11 Oct 2022 17:00:50 -0400 +Subject: [PATCH] x86-efi: Fix an incorrect array size in kernel allocation + +In 81a6ebf62bbe166ddc968463df2e8bd481bf697c ("efi: split allocation +policy for kernel vs initrd memories."), I introduced a split in the +kernel allocator to allow for different dynamic policies for the kernel +and the initrd allocations. + +Unfortunately, that change increased the size of the policy data used to +make decisions, but did not change the size of the temporary storage we +use to back it up and restore. This results in some of .data getting +clobbered at runtime, and hilarity ensues. + +This patch makes the size of the backup storage be based on the size of +the initial policy data. + +Signed-off-by: Peter Jones +(cherry picked from commit 37747b22342499a798ca3a8895770cd93b6e1258) +(cherry picked from commit 72713ce761720235c86bbda412480c97b2892e00) +--- + grub-core/loader/i386/efi/linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 4d39023792..3d55f8b8d2 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -92,7 +92,7 @@ static struct allocation_choice max_addresses[] = + { INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, + { NO_MEM, 0, 0 } + }; +-static struct allocation_choice saved_addresses[4]; ++static struct allocation_choice saved_addresses[sizeof(max_addresses) / sizeof(max_addresses[0])]; + + #define save_addresses() grub_memcpy(saved_addresses, max_addresses, sizeof(max_addresses)) + #define restore_addresses() grub_memcpy(max_addresses, saved_addresses, sizeof(max_addresses)) diff --git a/0561-switch-to-blscfg-don-t-assume-newline-at-end-of-cfg.patch b/0561-switch-to-blscfg-don-t-assume-newline-at-end-of-cfg.patch new file mode 100644 index 0000000..fee71eb --- /dev/null +++ b/0561-switch-to-blscfg-don-t-assume-newline-at-end-of-cfg.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 18 Oct 2022 14:15:28 -0400 +Subject: [PATCH] switch-to-blscfg: don't assume newline at end of cfg + +Signed-off-by: Robbie Harwood +--- + util/grub-switch-to-blscfg.in | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in +index eeea130770..5a97954c39 100644 +--- a/util/grub-switch-to-blscfg.in ++++ b/util/grub-switch-to-blscfg.in +@@ -277,7 +277,9 @@ if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ + fi + GENERATE=1 + elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then +- if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then ++ # prepend in case admins have been bad at newlines ++ sed -i '1iGRUB_ENABLE_BLSCFG=true' "${etcdefaultgrub}" ++ if ! grep -q '^GRUB_ENABLE_BLSCFG=true' "${etcdefaultgrub}" ; then + gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" + exit 1 + fi diff --git a/0562-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch b/0562-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch new file mode 100644 index 0000000..e7f7a0c --- /dev/null +++ b/0562-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Wed, 3 Aug 2022 19:45:33 +0800 +Subject: [PATCH] font: Reject glyphs exceeds font->max_glyph_width or + font->max_glyph_height + +Check glyph's width and height against limits specified in font's +metadata. Reject the glyph (and font) if such limits are exceeded. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit 5760fcfd466cc757540ea0d591bad6a08caeaa16) +(cherry picked from commit 3b410ef4bb95e607cadeba2193fa90ae9bddb98d) +(cherry picked from commit 8ebe587def61af7893ebcae87d45c883f3cfb713) +--- + grub-core/font/font.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index b67507fcc8..8d1a990401 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) + || read_be_uint16 (font->file, &height) != 0 + || read_be_int16 (font->file, &xoff) != 0 + || read_be_int16 (font->file, &yoff) != 0 +- || read_be_int16 (font->file, &dwidth) != 0) ++ || read_be_int16 (font->file, &dwidth) != 0 ++ || width > font->max_char_width ++ || height > font->max_char_height) + { + remove_font (font); + return 0; diff --git a/0563-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch b/0563-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch new file mode 100644 index 0000000..df3a705 --- /dev/null +++ b/0563-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 5 Aug 2022 00:51:20 +0800 +Subject: [PATCH] font: Fix size overflow in grub_font_get_glyph_internal() + +The length of memory allocation and file read may overflow. This patch +fixes the problem by using safemath macros. + +There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe +if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz(). +It is safe replacement for such code. It has safemath-like prototype. + +This patch also introduces grub_cast(value, pointer), it casts value to +typeof(*pointer) then store the value to *pointer. It returns true when +overflow occurs or false if there is no overflow. The semantics of arguments +and return value are designed to be consistent with other safemath macros. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit 941d10ad6f1dcbd12fb613002249e29ba035f985) +(cherry picked from commit 6bca9693878bdf61dd62b8c784862a48e75f569a) +(cherry picked from commit edbbda5486cf8c3dc2b68fbd3dead822ab448022) +--- + grub-core/font/font.c | 17 +++++++++++++---- + include/grub/bitmap.h | 18 ++++++++++++++++++ + include/grub/safemath.h | 2 ++ + 3 files changed, 33 insertions(+), 4 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 8d1a990401..d6df79602d 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) + grub_int16_t xoff; + grub_int16_t yoff; + grub_int16_t dwidth; +- int len; ++ grub_ssize_t len; ++ grub_size_t sz; + + if (index_entry->glyph) + /* Return cached glyph. */ +@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) + return 0; + } + +- len = (width * height + 7) / 8; +- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); +- if (!glyph) ++ /* Calculate real struct size of current glyph. */ ++ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) || ++ grub_add (sizeof (struct grub_font_glyph), len, &sz)) ++ { ++ remove_font (font); ++ return 0; ++ } ++ ++ /* Allocate and initialize the glyph struct. */ ++ glyph = grub_malloc (sz); ++ if (glyph == NULL) + { + remove_font (font); + return 0; +diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h +index 5728f8ca3a..0d9603f619 100644 +--- a/include/grub/bitmap.h ++++ b/include/grub/bitmap.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + struct grub_video_bitmap + { +@@ -79,6 +80,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) + return bitmap->mode_info.height; + } + ++/* ++ * Calculate and store the size of data buffer of 1bit bitmap in result. ++ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs. ++ * Return true when overflow occurs or false if there is no overflow. ++ * This function is intentionally implemented as a macro instead of ++ * an inline function. Although a bit awkward, it preserves data types for ++ * safemath macros and reduces macro side effects as much as possible. ++ * ++ * XXX: Will report false overflow if width * height > UINT64_MAX. ++ */ ++#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \ ++({ \ ++ grub_uint64_t _bitmap_pixels; \ ++ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \ ++ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \ ++}) ++ + void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap, + struct grub_video_mode_info *mode_info); + +diff --git a/include/grub/safemath.h b/include/grub/safemath.h +index 1ccac276b5..30800ad6a1 100644 +--- a/include/grub/safemath.h ++++ b/include/grub/safemath.h +@@ -30,6 +30,8 @@ + #define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) + #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) + ++#define grub_cast(a, res) grub_add ((a), 0, (res)) ++ + #else + /* + * Copyright 2020 Rasmus Villemoes diff --git a/0564-font-Fix-several-integer-overflows-in-grub_font_cons.patch b/0564-font-Fix-several-integer-overflows-in-grub_font_cons.patch new file mode 100644 index 0000000..0afdf93 --- /dev/null +++ b/0564-font-Fix-several-integer-overflows-in-grub_font_cons.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 5 Aug 2022 01:58:27 +0800 +Subject: [PATCH] font: Fix several integer overflows in + grub_font_construct_glyph() + +This patch fixes several integer overflows in grub_font_construct_glyph(). +Glyphs of invalid size, zero or leading to an overflow, are rejected. +The inconsistency between "glyph" and "max_glyph_size" when grub_malloc() +returns NULL is fixed too. + +Fixes: CVE-2022-2601 + +Reported-by: Zhang Boyang +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit b1805f251b31a9d3cfae5c3572ddfa630145dbbf) +(cherry picked from commit b91eb9bd6c724339b7d7bb4765b9d36f1ee88b84) +(cherry picked from commit 1ebafd82dd19e522f0d753fd9828553fe8bcac78) +--- + grub-core/font/font.c | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index d6df79602d..129aaa3838 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, + struct grub_video_signed_rect bounds; + static struct grub_font_glyph *glyph = 0; + static grub_size_t max_glyph_size = 0; ++ grub_size_t cur_glyph_size; + + ensure_comb_space (glyph_id); + +@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font, + if (!glyph_id->ncomb && !glyph_id->attributes) + return main_glyph; + +- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) ++ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) || ++ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size)) ++ return main_glyph; ++ ++ if (max_glyph_size < cur_glyph_size) + { + grub_free (glyph); +- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; +- if (max_glyph_size < 8) +- max_glyph_size = 8; +- glyph = grub_malloc (max_glyph_size); ++ if (grub_mul (cur_glyph_size, 2, &max_glyph_size)) ++ max_glyph_size = 0; ++ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL; + } + if (!glyph) + { ++ max_glyph_size = 0; + grub_errno = GRUB_ERR_NONE; + return main_glyph; + } + +- grub_memset (glyph, 0, sizeof (*glyph) +- + (bounds.width * bounds.height +- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); ++ grub_memset (glyph, 0, cur_glyph_size); + + glyph->font = main_glyph->font; +- glyph->width = bounds.width; +- glyph->height = bounds.height; +- glyph->offset_x = bounds.x; +- glyph->offset_y = bounds.y; ++ if (bounds.width == 0 || bounds.height == 0 || ++ grub_cast (bounds.width, &glyph->width) || ++ grub_cast (bounds.height, &glyph->height) || ++ grub_cast (bounds.x, &glyph->offset_x) || ++ grub_cast (bounds.y, &glyph->offset_y)) ++ return main_glyph; + + if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) + grub_font_blit_glyph_mirror (glyph, main_glyph, diff --git a/0565-font-Remove-grub_font_dup_glyph.patch b/0565-font-Remove-grub_font_dup_glyph.patch new file mode 100644 index 0000000..2f9a33e --- /dev/null +++ b/0565-font-Remove-grub_font_dup_glyph.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 5 Aug 2022 02:13:29 +0800 +Subject: [PATCH] font: Remove grub_font_dup_glyph() + +Remove grub_font_dup_glyph() since nobody is using it since 2013, and +I'm too lazy to fix the integer overflow problem in it. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit 25ad31c19c331aaa2dbd9bd2b2e2655de5766a9d) +(cherry picked from commit ad950e1e033318bb50222ed268a6dcfb97389035) +(cherry picked from commit 71644fccc1d43309f0a379dcfe9341ec3bd9657d) +--- + grub-core/font/font.c | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 129aaa3838..347e9dfa29 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) + return best_glyph; + } + +-#if 0 +-static struct grub_font_glyph * +-grub_font_dup_glyph (struct grub_font_glyph *glyph) +-{ +- static struct grub_font_glyph *ret; +- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); +- if (!ret) +- return NULL; +- grub_memcpy (ret, glyph, sizeof (*ret) +- + (glyph->width * glyph->height + 7) / 8); +- return ret; +-} +-#endif +- + /* FIXME: suboptimal. */ + static void + grub_font_blit_glyph (struct grub_font_glyph *target, diff --git a/0566-font-Fix-integer-overflow-in-ensure_comb_space.patch b/0566-font-Fix-integer-overflow-in-ensure_comb_space.patch new file mode 100644 index 0000000..baa2d74 --- /dev/null +++ b/0566-font-Fix-integer-overflow-in-ensure_comb_space.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 5 Aug 2022 02:27:05 +0800 +Subject: [PATCH] font: Fix integer overflow in ensure_comb_space() + +In fact it can't overflow at all because glyph_id->ncomb is only 8-bit +wide. But let's keep safe if somebody changes the width of glyph_id->ncomb +in the future. This patch also fixes the inconsistency between +render_max_comb_glyphs and render_combining_glyphs when grub_malloc() +returns NULL. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit b2740b7e4a03bb8331d48b54b119afea76bb9d5f) +(cherry picked from commit f66ea1e60c347408e92b6695d5105c7e0f24d568) +(cherry picked from commit 0e07159c24cdbb62a9d19fba8199065b049e03c7) +--- + grub-core/font/font.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 347e9dfa29..1367e44743 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id) + if (glyph_id->ncomb <= render_max_comb_glyphs) + return; + +- render_max_comb_glyphs = 2 * glyph_id->ncomb; +- if (render_max_comb_glyphs < 8) ++ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs)) ++ render_max_comb_glyphs = 0; ++ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8) + render_max_comb_glyphs = 8; + grub_free (render_combining_glyphs); +- render_combining_glyphs = grub_malloc (render_max_comb_glyphs +- * sizeof (render_combining_glyphs[0])); ++ render_combining_glyphs = (render_max_comb_glyphs > 0) ? ++ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL; + if (!render_combining_glyphs) +- grub_errno = 0; ++ { ++ render_max_comb_glyphs = 0; ++ grub_errno = GRUB_ERR_NONE; ++ } + } + + int diff --git a/0567-font-Fix-integer-overflow-in-BMP-index.patch b/0567-font-Fix-integer-overflow-in-BMP-index.patch new file mode 100644 index 0000000..c28337d --- /dev/null +++ b/0567-font-Fix-integer-overflow-in-BMP-index.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Mon, 15 Aug 2022 02:04:58 +0800 +Subject: [PATCH] font: Fix integer overflow in BMP index + +The BMP index (font->bmp_idx) is designed as a reverse lookup table of +char entries (font->char_index), in order to speed up lookups for BMP +chars (i.e. code < 0x10000). The values in BMP index are the subscripts +of the corresponding char entries, stored in grub_uint16_t, while 0xffff +means not found. + +This patch fixes the problem of large subscript truncated to grub_uint16_t, +leading BMP index to return wrong char entry or report false miss. The +code now checks for bounds and uses BMP index as a hint, and fallbacks +to binary-search if necessary. + +On the occasion add a comment about BMP index is initialized to 0xffff. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit afda8b60ba0712abe01ae1e64c5f7a067a0e6492) +(cherry picked from commit 6d90568929e11739b56f09ebbce9185ca9c23519) +(cherry picked from commit b8c47c3dd6894b3135db861e3e563f661efad5c3) +--- + grub-core/font/font.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 1367e44743..059c23dff7 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct + font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); + if (!font->bmp_idx) + return 1; ++ ++ /* Init the BMP index array to 0xffff. */ + grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); + + +@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct + return 1; + } + +- if (entry->code < 0x10000) ++ if (entry->code < 0x10000 && i < 0xffff) + font->bmp_idx[entry->code] = i; + + last_code = entry->code; +@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code) + /* Use BMP index if possible. */ + if (code < 0x10000 && font->bmp_idx) + { +- if (font->bmp_idx[code] == 0xffff) +- return 0; +- return &table[font->bmp_idx[code]]; ++ if (font->bmp_idx[code] < 0xffff) ++ return &table[font->bmp_idx[code]]; ++ /* ++ * When we are here then lookup in BMP index result in miss, ++ * fallthough to binary-search. ++ */ + } + + /* Do a binary search in `char_index', which is ordered by code point. */ diff --git a/0568-font-Fix-integer-underflow-in-binary-search-of-char-.patch b/0568-font-Fix-integer-underflow-in-binary-search-of-char-.patch new file mode 100644 index 0000000..31b66af --- /dev/null +++ b/0568-font-Fix-integer-underflow-in-binary-search-of-char-.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Sun, 14 Aug 2022 18:09:38 +0800 +Subject: [PATCH] font: Fix integer underflow in binary search of char index + +If search target is less than all entries in font->index then "hi" +variable is set to -1, which translates to SIZE_MAX and leads to errors. + +This patch fixes the problem by replacing the entire binary search code +with the libstdc++'s std::lower_bound() implementation. + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit c140a086838e7c9af87842036f891b8393a8c4bc) +(cherry picked from commit e110997335b1744464ea232d57a7d86e16ca8dee) +(cherry picked from commit 403053a5116ae945f9515a82c37ff8cfb927362c) +--- + grub-core/font/font.c | 40 ++++++++++++++++++++++------------------ + 1 file changed, 22 insertions(+), 18 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 059c23dff7..31786ab339 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) + static inline struct char_index_entry * + find_glyph (const grub_font_t font, grub_uint32_t code) + { +- struct char_index_entry *table; +- grub_size_t lo; +- grub_size_t hi; +- grub_size_t mid; ++ struct char_index_entry *table, *first, *end; ++ grub_size_t len; + + table = font->char_index; ++ if (table == NULL) ++ return NULL; + + /* Use BMP index if possible. */ + if (code < 0x10000 && font->bmp_idx) +@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code) + */ + } + +- /* Do a binary search in `char_index', which is ordered by code point. */ +- lo = 0; +- hi = font->num_chars - 1; ++ /* ++ * Do a binary search in char_index which is ordered by code point. ++ * The code below is the same as libstdc++'s std::lower_bound(). ++ */ ++ first = table; ++ len = font->num_chars; ++ end = first + len; + +- if (!table) +- return 0; +- +- while (lo <= hi) ++ while (len > 0) + { +- mid = lo + (hi - lo) / 2; +- if (code < table[mid].code) +- hi = mid - 1; +- else if (code > table[mid].code) +- lo = mid + 1; ++ grub_size_t half = len >> 1; ++ struct char_index_entry *middle = first + half; ++ ++ if (middle->code < code) ++ { ++ first = middle + 1; ++ len = len - half - 1; ++ } + else +- return &table[mid]; ++ len = half; + } + +- return 0; ++ return (first < end && first->code == code) ? first : NULL; + } + + /* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded diff --git a/0569-fbutil-Fix-integer-overflow.patch b/0569-fbutil-Fix-integer-overflow.patch new file mode 100644 index 0000000..8854410 --- /dev/null +++ b/0569-fbutil-Fix-integer-overflow.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Tue, 6 Sep 2022 03:03:21 +0800 +Subject: [PATCH] fbutil: Fix integer overflow + +Expressions like u64 = u32 * u32 are unsafe because their products are +truncated to u32 even if left hand side is u64. This patch fixes all +problems like that one in fbutil. + +To get right result not only left hand side have to be u64 but it's also +necessary to cast at least one of the operands of all leaf operators of +right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be +u64 = (u64)u32 * u32 + (u64)u32 * u32. + +For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any +combination of values in (grub_uint64_t)u32 * u32 + u32 expression will +not overflow grub_uint64_t. + +Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable. +They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32. + +This patch also adds a comment to grub_video_fb_get_video_ptr() which +says it's arguments must be valid and no sanity check is performed +(like its siblings in grub-core/video/fb/fbutil.c). + +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit 50a11a81bc842c58962244a2dc86bbd31a426e12) +(cherry picked from commit 8fa75d647362c938c4cc302cf5945b31fb92c078) +(cherry picked from commit 91005e39b3c8b6ca8dcc84ecb19ac9328966aaea) +--- + grub-core/video/fb/fbutil.c | 4 ++-- + include/grub/fbutil.h | 13 +++++++++---- + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c +index b98bb51fe8..25ef39f47d 100644 +--- a/grub-core/video/fb/fbutil.c ++++ b/grub-core/video/fb/fbutil.c +@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source, + case 1: + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) + { +- int bit_index = y * source->mode_info->width + x; ++ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; + grub_uint8_t *ptr = source->data + bit_index / 8; + int bit_pos = 7 - bit_index % 8; + color = (*ptr >> bit_pos) & 0x01; +@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source, + case 1: + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) + { +- int bit_index = y * source->mode_info->width + x; ++ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; + grub_uint8_t *ptr = source->data + bit_index / 8; + int bit_pos = 7 - bit_index % 8; + *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos); +diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h +index 4205eb917f..78a1ab3b45 100644 +--- a/include/grub/fbutil.h ++++ b/include/grub/fbutil.h +@@ -31,14 +31,19 @@ struct grub_video_fbblit_info + grub_uint8_t *data; + }; + +-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level +- and it doesn't make sense, in general, to ask for a pointer +- to a particular pixel's data. */ ++/* ++ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level ++ * and it doesn't make sense, in general, to ask for a pointer ++ * to a particular pixel's data. ++ * ++ * This function assumes that bounds checking has been done in previous phase ++ * and they are opted out in here. ++ */ + static inline void * + grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, + unsigned int x, unsigned int y) + { +- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel; ++ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel; + } + + /* Advance pointer by VAL bytes. If there is no unaligned access available, diff --git a/0570-font-Fix-an-integer-underflow-in-blit_comb.patch b/0570-font-Fix-an-integer-underflow-in-blit_comb.patch new file mode 100644 index 0000000..8da101f --- /dev/null +++ b/0570-font-Fix-an-integer-underflow-in-blit_comb.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Mon, 24 Oct 2022 08:05:35 +0800 +Subject: [PATCH] font: Fix an integer underflow in blit_comb() + +The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may +evaluate to a very big invalid value even if both ctx.bounds.height and +combining_glyphs[i]->height are small integers. For example, if +ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this +expression evaluates to 2147483647 (expected -1). This is because +coordinates are allowed to be negative but ctx.bounds.height is an +unsigned int. So, the subtraction operates on unsigned ints and +underflows to a very big value. The division makes things even worse. +The quotient is still an invalid value even if converted back to int. + +This patch fixes the problem by casting ctx.bounds.height to int. As +a result the subtraction will operate on int and grub_uint16_t which +will be promoted to an int. So, the underflow will no longer happen. Other +uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int, +to ensure coordinates are always calculated on signed integers. + +Fixes: CVE-2022-3775 + +Reported-by: Daniel Axtens +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4) +(cherry picked from commit 05e532fb707bbf79aa4e1efbde4d208d7da89d6b) +(cherry picked from commit 0b2592fbb245d53c5c42885d695ece03ddb0eb12) +--- + grub-core/font/font.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 31786ab339..fc9d92fce4 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + ctx.bounds.height = main_glyph->height; + + above_rightx = main_glyph->offset_x + main_glyph->width; +- above_righty = ctx.bounds.y + ctx.bounds.height; ++ above_righty = ctx.bounds.y + (int) ctx.bounds.height; + + above_leftx = main_glyph->offset_x; +- above_lefty = ctx.bounds.y + ctx.bounds.height; ++ above_lefty = ctx.bounds.y + (int) ctx.bounds.height; + +- below_rightx = ctx.bounds.x + ctx.bounds.width; ++ below_rightx = ctx.bounds.x + (int) ctx.bounds.width; + below_righty = ctx.bounds.y; + + comb = grub_unicode_get_comb (glyph_id); +@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + + if (!combining_glyphs[i]) + continue; +- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; ++ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; + /* CGJ is to avoid diacritics reordering. */ + if (comb[i].code + == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) +@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + case GRUB_UNICODE_COMB_OVERLAY: + do_blit (combining_glyphs[i], + targetx, +- (ctx.bounds.height - combining_glyphs[i]->height) / 2 +- - (ctx.bounds.height + ctx.bounds.y), &ctx); ++ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2 ++ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; +@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + /* Fallthrough. */ + case GRUB_UNICODE_STACK_ATTACHED_ABOVE: + do_blit (combining_glyphs[i], targetx, +- -(ctx.bounds.height + ctx.bounds.y + space ++ -((int) ctx.bounds.height + ctx.bounds.y + space + + combining_glyphs[i]->height), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; +@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + + case GRUB_UNICODE_COMB_HEBREW_DAGESH: + do_blit (combining_glyphs[i], targetx, +- -(ctx.bounds.height / 2 + ctx.bounds.y ++ -((int) ctx.bounds.height / 2 + ctx.bounds.y + + combining_glyphs[i]->height / 2), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; diff --git a/0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch b/0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch new file mode 100644 index 0000000..87b8e33 --- /dev/null +++ b/0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Mon, 24 Oct 2022 07:15:41 +0800 +Subject: [PATCH] font: Harden grub_font_blit_glyph() and + grub_font_blit_glyph_mirror() + +As a mitigation and hardening measure add sanity checks to +grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch +makes these two functions do nothing if target blitting area isn't fully +contained in target bitmap. Therefore, if complex calculations in caller +overflows and malicious coordinates are given, we are still safe because +any coordinates which result in out-of-bound-write are rejected. However, +this patch only checks for invalid coordinates, and doesn't provide any +protection against invalid source glyph or destination glyph, e.g. +mismatch between glyph size and buffer size. + +This hardening measure is designed to mitigate possible overflows in +blit_comb(). If overflow occurs, it may return invalid bounding box +during dry run and call grub_font_blit_glyph() with malicious +coordinates during actual blitting. However, we are still safe because +the scratch glyph itself is valid, although its size makes no sense, and +any invalid coordinates are rejected. + +It would be better to call grub_fatal() if illegal parameter is detected. +However, doing this may end up in a dangerous recursion because grub_fatal() +would print messages to the screen and we are in the progress of drawing +characters on the screen. + +Reported-by: Daniel Axtens +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6) +(cherry picked from commit 1d37ec63a1c76a14fdf70f548eada92667b42ddb) +(cherry picked from commit 686c72ea0a841343b7d8ab64e815751aa36e24b5) +--- + grub-core/font/font.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index fc9d92fce4..cfa4bd5096 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1069,8 +1069,15 @@ static void + grub_font_blit_glyph (struct grub_font_glyph *target, + struct grub_font_glyph *src, unsigned dx, unsigned dy) + { ++ grub_uint16_t max_x, max_y; + unsigned src_bit, tgt_bit, src_byte, tgt_byte; + unsigned i, j; ++ ++ /* Harden against out-of-bound writes. */ ++ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || ++ (grub_add (dy, src->height, &max_y) || max_y > target->height)) ++ return; ++ + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i) % 8; +@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target, + struct grub_font_glyph *src, + unsigned dx, unsigned dy) + { ++ grub_uint16_t max_x, max_y; + unsigned tgt_bit, src_byte, tgt_byte; + signed src_bit; + unsigned i, j; ++ ++ /* Harden against out-of-bound writes. */ ++ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || ++ (grub_add (dy, src->height, &max_y) || max_y > target->height)) ++ return; ++ + for (i = 0; i < src->height; i++) + { + src_bit = (src->width * i + src->width - 1) % 8; diff --git a/0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch b/0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch new file mode 100644 index 0000000..981d5df --- /dev/null +++ b/0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 28 Oct 2022 17:29:16 +0800 +Subject: [PATCH] font: Assign null_font to glyphs in ascii_font_glyph[] + +The calculations in blit_comb() need information from glyph's font, e.g. +grub_font_get_xheight(main_glyph->font). However, main_glyph->font is +NULL if main_glyph comes from ascii_font_glyph[]. Therefore +grub_font_get_*() crashes because of NULL pointer. + +There is already a solution, the null_font. So, assign it to those glyphs +in ascii_font_glyph[]. + +Reported-by: Daniel Axtens +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit dd539d695482069d28b40f2d3821f710cdcf6ee6) +(cherry picked from commit 87526376857eaceae474c9797e3cee5b50597332) +(cherry picked from commit b4807bbb09d9adf82fe9ae12a3af1c852dc4e32d) +--- + grub-core/font/font.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index cfa4bd5096..30cd1fe07f 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code) + ascii_font_glyph[current]->offset_x = 0; + ascii_font_glyph[current]->offset_y = -2; + ascii_font_glyph[current]->device_width = 8; +- ascii_font_glyph[current]->font = NULL; ++ ascii_font_glyph[current]->font = &null_font; + + grub_memcpy (ascii_font_glyph[current]->bitmap, + &ascii_bitmaps[current * ASCII_BITMAP_SIZE], diff --git a/0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch b/0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch new file mode 100644 index 0000000..283d560 --- /dev/null +++ b/0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhang Boyang +Date: Fri, 28 Oct 2022 21:31:39 +0800 +Subject: [PATCH] normal/charset: Fix an integer overflow in + grub_unicode_aglomerate_comb() + +The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255. +However, code in grub_unicode_aglomerate_comb() doesn't check for an +overflow when incrementing out->ncomb. If out->ncomb is already 255, +after incrementing it will get 0 instead of 256, and cause illegal +memory access in subsequent processing. + +This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max +acceptable value of ncomb. The code now checks for this limit and +ignores additional combining characters when limit is reached. + +Reported-by: Daniel Axtens +Signed-off-by: Zhang Boyang +Reviewed-by: Daniel Kiper +(cherry picked from commit da90d62316a3b105d2fbd7334d6521936bd6dcf6) +(cherry picked from commit 26fafec86000b5322837722a115279ef03922ca6) +(cherry picked from commit 872fba1c44dee2ab5cb36b2c7a883847f91ed907) +--- + grub-core/normal/charset.c | 3 +++ + include/grub/unicode.h | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c +index 7b2de12001..4849cf06f7 100644 +--- a/grub-core/normal/charset.c ++++ b/grub-core/normal/charset.c +@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, + if (!haveout) + continue; + ++ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX) ++ continue; ++ + if (comb_type == GRUB_UNICODE_COMB_MC + || comb_type == GRUB_UNICODE_COMB_ME + || comb_type == GRUB_UNICODE_COMB_MN) +diff --git a/include/grub/unicode.h b/include/grub/unicode.h +index 4de986a857..c4f6fca043 100644 +--- a/include/grub/unicode.h ++++ b/include/grub/unicode.h +@@ -147,7 +147,9 @@ struct grub_unicode_glyph + grub_uint8_t bidi_level:6; /* minimum: 6 */ + enum grub_bidi_type bidi_type:5; /* minimum: :5 */ + ++#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1) + unsigned ncomb:8; ++ + /* Hint by unicode subsystem how wide this character usually is. + Real width is determined by font. Set only in UTF-8 stream. */ + int estimated_width:8; diff --git a/1001-bls-make-list.patch b/1001-bls-make-list.patch deleted file mode 100644 index ac39162..0000000 --- a/1001-bls-make-list.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhongling He -Date: Tue, 29 Mar 2022 17:27:13 +0800 -Subject: [PATCH] Fix a bug in bls_make_list, blscfg - -We have encountered a bug while running LifseaOS aarch64 version without -initrd. This commit fixes this bug. It may have fixed some potential -bugs as well. - -There are 4 partitions in a LifseaOS disk image: -- The 1st partition is for BIOS bootloader -- The 2nd partition is for UEFI booting, which contains grub binary - compiled from this source code, grubaa64.efi -- The 3rd partition contains grub.cfg files and - loader/entries/ostree-1-LifseaOS.conf -- The 4th partition contains rootfs - -Since x86_64 supports both BIOS and UEFI booting and we employ BIOS -booting for x86_64 (w/o initrd) image, we don't put the grub2 binary -compiled into the 2nd partition. As a result, this bug was not observed. -However, aarch64 only supports UEFI booting. In other words, we are -using this grub2 to boot LifseaOS (w/o initrd). - -grubaa64.efi from the 2nd partition will read `/grub2/grub.cfg` in the -3rd partition. - -``` -... - set ignition_firstboot="ignition.firstboot -${ignition_network_kcmdline}" -fi - -blscfg -``` - -`blscfg` is a command to convert `loader/entries/ostree-1-LifseaOS.conf` -into a typical grub.cfg. However, here comes the bug. While booting, an -error message will appear. - -``` -error: ../../grub-core/loader/arm64/linux.c:292:filename expected. -Press any key to continue. -``` - -This is because the bug in `blscfg` unexpectedly add a line, `initrd`, -into the generated grub.cfg file. Grub2 will expect an initrd file path -after `initrd`. As a result, the error occurs. - -In grub-core/command/blscfg.c:676, if `initrds` is a non-NULL pointer, -then `src` will contain a `initrd` line. - -``` -static void create_entry (struct bls_entry *entry){ - ... - initrds = bls_make_list (entry, "initrd", NULL); // - ... - if (initrds){ - ... - tmp = grub_stpcpy(initrd, "initrd "); - ... - } - ... - src = grub_xasprintf ("load_video\n" - "set gfx_payload=keep\n" - "insmod gzio\n" - "linux %s%s%s%s\n" - "%s", - GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options -: "", - initrd ? initrd : ""); -``` - -In grub-core/command/blscfg.c:562, `bls_make_list` will always return a -non-NULL pointer except for a `grub_malloc` error. - -``` -static char **bls_make_list (struct bls_entry *entry, const char *key, -int *num) -{ - ... - list = grub_malloc (sizeof (char *)); - if (!list) - return NULL; - list[0] = NULL; - ... - return list; -} -``` - -Therefore, `initrd` like will be appended into the auto-generated -grub.cfg if `grub_malloc` succeed, regardless of whether initrd is -stated in config file. Our bug fix, same as upstream, modifies the -behaviour of `bls_make_list`. `bls_make_list` will now return a non-NULL -pointer only if the required field actually exists. - ---- - grub-core/commands/blscfg.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -index 795a9f9..bf18270 100644 ---- a/grub-core/commands/blscfg.c -+++ b/grub-core/commands/blscfg.c -@@ -589,6 +589,12 @@ static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) - list[nlist] = NULL; - } - -+ if (!nlist) -+ { -+ grub_free (list); -+ return NULL; -+ } -+ - if (num) - *num = nlist; - --- -2.27.0 - diff --git a/1002-Add-LoongArch64-support-and-update-interface-to-v40.patch b/1002-Add-LoongArch64-support-and-update-interface-to-v40.patch deleted file mode 100644 index 36750c1..0000000 --- a/1002-Add-LoongArch64-support-and-update-interface-to-v40.patch +++ /dev/null @@ -1,3444 +0,0 @@ -From 478205a88ea71b0c546987602cd879027819125e Mon Sep 17 00:00:00 2001 -From: yangqiming -Date: Thu, 7 Jul 2022 11:25:02 +0800 -Subject: [PATCH] Add LoongArch64 support and update interface to V40 - - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 521cdda..d9f058b 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -20,6 +20,10 @@ endif - if COND_powerpc_ieee1275 - CFLAGS_PLATFORM += -mcpu=powerpc - endif -+if COND_loongarch64 -+ CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large -+ CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large -+endif - - # Other options - -diff --git a/configure.ac b/configure.ac -index f59a7b8..4715d17 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -116,6 +116,10 @@ case "$target_cpu" in - i[[3456]]86) target_cpu=i386 ;; - amd64) target_cpu=x86_64 ;; - sparc) target_cpu=sparc64 ;; -+ loongarch64) -+ target_cpu=loongarch64 -+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_LOONGARCH64=1" -+ ;; - mipsel|mips64el) - target_cpu=mipsel - machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1" -@@ -148,6 +152,7 @@ if test "x$with_platform" = x; then - powerpc64-*) platform=ieee1275 ;; - powerpc64le-*) platform=ieee1275 ;; - sparc64-*) platform=ieee1275 ;; -+ loongarch64-*) platform=efi;; - mipsel-*) platform=loongson ;; - mips-*) platform=arc ;; - ia64-*) platform=efi ;; -@@ -196,6 +201,7 @@ case "$target_cpu"-"$platform" in - mipsel-yeeloong) platform=loongson ;; - mipsel-fuloong) platform=loongson ;; - mipsel-loongson) ;; -+ loongarch64-efi) ;; - arm-uboot) ;; - arm-coreboot) ;; - arm-efi) ;; -@@ -251,6 +257,7 @@ case "$platform" in - pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; - emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; - loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; -+ loongson64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_LOONARCH64=1" ;; - qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; - arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; - esac -@@ -2098,6 +2105,8 @@ AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = - 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_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -+AM_CONDITIONAL([COND_loongarch64_efi], [test x$target_cpu = xloongarch64 -a x$platform = xefi]) -+AM_CONDITIONAL([COND_loongarch64], [test x$target_cpu = xloongarch64]) - AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) -diff --git a/gentpl.py b/gentpl.py -index d662c30..3afd642 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -32,7 +32,7 @@ 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"] -+ "arm_coreboot", "loongarch64_efi"] - - GROUPS = {} - -@@ -44,13 +44,14 @@ GROUPS["x86_64"] = [ "x86_64_efi" ] - GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] - GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] - GROUPS["sparc64"] = [ "sparc64_ieee1275" ] -+GROUPS["loongarch64"] = [ "loongarch64_efi" ] - GROUPS["powerpc"] = [ "powerpc_ieee1275" ] - GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] - GROUPS["arm64"] = [ "arm64_efi" ] - - # Groups based on firmware - GROUPS["pc"] = [ "i386_pc" ] --GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ] -+GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "loongarch64_efi"] - GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] - GROUPS["uboot"] = [ "arm_uboot" ] - GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index 308ad88..a976fad 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -222,6 +222,14 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h - KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h - endif - -+if COND_loongarch64_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/acpi.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h -+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h -+endif -+ - if COND_powerpc_ieee1275 - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index ef06f8c..54f6bf0 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -95,6 +95,9 @@ kernel = { - arm_coreboot_ldflags = '-Wl,-r,-d'; - arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - -+ loongarch64_efi_ldflags = '-Wl,-r,-d'; -+ loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; -+ - i386_pc_startup = kern/i386/pc/startup.S; - i386_efi_startup = kern/i386/efi/startup.S; - x86_64_efi_startup = kern/x86_64/efi/startup.S; -@@ -105,6 +108,7 @@ kernel = { - i386_coreboot_startup = kern/i386/coreboot/startup.S; - i386_multiboot_startup = kern/i386/coreboot/startup.S; - mips_startup = kern/mips/startup.S; -+ loongarch64_efi_startup = kern/loongarch64/efi/startup.S; - sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; - powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; - arm_uboot_startup = kern/arm/startup.S; -@@ -295,6 +299,15 @@ kernel = { - extra_dist = video/sis315_init.c; - mips_loongson = commands/keylayouts.c; - -+ loongarch64 = kern/loongarch64/init.c; -+ loongarch64 = kern/loongarch64/dl.c; -+ loongarch64 = kern/loongarch64/cache.S; -+ loongarch64 = kern/generic/rtc_get_time_ms.c; -+ loongarch64 = kern/efi/fdt.c; -+ loongarch64 = lib/fdt.c; -+ loongarch64_efi = kern/loongarch64/efi/init.c; -+ loongarch64_efi = lib/loongarch64/efi/loongson.c; -+ - powerpc_ieee1275 = kern/powerpc/cache.S; - powerpc_ieee1275 = kern/powerpc/dl.c; - powerpc_ieee1275 = kern/powerpc/compiler-rt.S; -@@ -810,6 +823,7 @@ module = { - enable = sparc64_ieee1275; - enable = powerpc_ieee1275; - enable = mips_arc; -+ enable = loongarch64_efi; - enable = ia64_efi; - enable = arm_efi; - enable = arm64_efi; -@@ -896,6 +910,7 @@ module = { - i386_qemu = lib/i386/halt.c; - xen = lib/xen/halt.c; - efi = lib/efi/halt.c; -+ loongarch64_efi = commands/acpihalt.c; - ieee1275 = lib/ieee1275/halt.c; - emu = lib/emu/halt.c; - uboot = lib/dummy/halt.c; -@@ -911,6 +926,7 @@ module = { - mips_arc = lib/mips/arc/reboot.c; - mips_loongson = lib/mips/loongson/reboot.c; - mips_qemu_mips = lib/mips/qemu_mips/reboot.c; -+ loongarch64_efi = lib/loongson/reboot.c; - xen = lib/xen/reboot.c; - uboot = lib/uboot/reboot.c; - arm_coreboot = lib/dummy/reboot.c; -@@ -1608,6 +1624,8 @@ module = { - efi = lib/efi/relocator.c; - mips = lib/mips/relocator_asm.S; - mips = lib/mips/relocator.c; -+ loongarch64 = lib/loongarch64/relocator_asm.S; -+ loongarch64 = lib/loongarch64/relocator.c; - powerpc = lib/powerpc/relocator_asm.S; - powerpc = lib/powerpc/relocator.c; - xen = lib/xen/relocator.c; -@@ -1620,6 +1638,7 @@ module = { - extra_dist = kern/powerpc/cache_flush.S; - - enable = mips; -+ enable = loongarch64; - enable = powerpc; - enable = x86; - enable = xen; -@@ -1737,6 +1756,7 @@ module = { - xen = loader/i386/xen.c; - i386_pc = lib/i386/pc/vesa_modes_table.c; - mips = loader/mips/linux.c; -+ loongarch64 = loader/loongarch64/linux.c; - powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; - sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; - ia64_efi = loader/ia64/efi/linux.c; -@@ -1838,6 +1858,7 @@ module = { - enable = arm_efi; - enable = arm64_efi; - enable = mips; -+ enable = loongarch64_efi; - }; - - module = { -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 8a89614..0b5f158 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -122,7 +122,11 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, - grub_efi_boot_services_t *b; - grub_efi_physical_address_t address = max; - -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (max > grub_efi_max_usable_address()) -+#else - if (max > GRUB_EFI_MAX_USABLE_ADDRESS) -+#endif - return 0; - - b = grub_efi_system_table->boot_services; -@@ -157,11 +161,19 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - grub_efi_physical_address_t ret = address; - - /* Limit the memory access to less than 4GB for 32-bit platforms. */ -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (address > grub_efi_max_usable_address()) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("invalid memory address 0x%llx"), -+ address); -+#else - if (address > GRUB_EFI_MAX_USABLE_ADDRESS) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid memory address (0x%llx > 0x%llx)"), - address, GRUB_EFI_MAX_USABLE_ADDRESS); -+#endif - return NULL; - } - -@@ -177,7 +189,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - { - /* Uggh, the address 0 was allocated... This is too annoying, - so reallocate another one. */ -+#ifdef GRUB_CPU_LOONGARCH64 -+ ret = grub_efi_max_usable_address(); -+#else - ret = address; -+#endif - status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); - grub_efi_free_pages (0, pages); - if (status != GRUB_EFI_SUCCESS) -@@ -195,9 +211,15 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - void * - grub_efi_allocate_any_pages (grub_efi_uintn_t pages) - { -+#ifdef GRUB_CPU_LOONGARCH64 -+ return grub_efi_allocate_pages_real (grub_efi_max_usable_address(), -+ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, -+ GRUB_EFI_LOADER_DATA); -+#else - return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, - pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, - GRUB_EFI_LOADER_DATA); -+#endif - } - - void * -@@ -471,7 +493,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) - { - if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY --#if 1 -+#ifdef GRUB_CPU_LOONGARCH64 -+ && desc->physical_start <= grub_efi_max_usable_address() -+#else - && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS - #endif - && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 -@@ -487,7 +511,14 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, - desc->physical_start = 0x100000; - } - --#if 1 -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (BYTES_TO_PAGES (filtered_desc->physical_start) -+ + filtered_desc->num_pages -+ > BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address())) -+ filtered_desc->num_pages -+ = (BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address()) -+ - BYTES_TO_PAGES (filtered_desc->physical_start)); -+#else - if (BYTES_TO_PAGES (filtered_desc->physical_start) - + filtered_desc->num_pages - > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) -@@ -765,7 +796,7 @@ grub_efi_mm_init (void) - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); - } - --#if defined (__aarch64__) || defined (__arm__) -+#if defined (__aarch64__) || defined (__arm__) || defined (__loongarch__) - grub_err_t - grub_efi_get_ram_base(grub_addr_t *base_addr) - { -@@ -784,9 +815,15 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) - if (ret < 1) - return GRUB_ERR_BUG; - -+#ifdef GRUB_CPU_LOONGARCH64 -+ for (desc = memory_map, *base_addr = grub_efi_max_usable_address(); -+ (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); -+ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) -+#else - for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; - (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) -+#endif - { - if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY && - (desc->attribute & GRUB_EFI_MEMORY_WB)) -@@ -800,7 +837,11 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) - } - } - -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (*base_addr == grub_efi_max_usable_address()) -+#else - if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS) -+#endif - grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr); - - grub_free(memory_map); -diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S -new file mode 100644 -index 0000000..d291c67 ---- /dev/null -+++ b/grub-core/kern/loongarch64/cache.S -@@ -0,0 +1,26 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 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 . -+ */ -+ -+#include -+ -+FUNCTION (grub_arch_sync_caches) -+ jr $ra -+ -+FUNCTION (grub_arch_sync_dma_caches) -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c -new file mode 100644 -index 0000000..7d9e2a1 ---- /dev/null -+++ b/grub-core/kern/loongarch64/dl.c -@@ -0,0 +1,266 @@ -+/* loongarch64/dl.c - arch-dependent part of loadable module support */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2007,2009,2017 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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_LOONGARCH64) -+ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ -+ return GRUB_ERR_NONE; -+} -+ -+#pragma GCC diagnostic ignored "-Wcast-align" -+ -+grub_err_t -+grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), -+ grub_size_t *tramp, grub_size_t *got) -+{ -+ *tramp = 0; -+ *got = 0; -+ return GRUB_ERR_NONE; -+} -+ -+/* 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_Ehdr *e = ehdr; -+ Elf_Rel *rel, *max; -+ grub_uint64_t oprs[10240]={0}; -+ int opri=-1; -+ grub_uint32_t la_abs = 0; -+ -+ for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), -+ max = (Elf_Rel *) ((char *) rel + s->sh_size); -+ rel < max; -+ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) -+ { -+ grub_uint8_t *addr; -+ Elf_Sym *sym; -+ Elf_Addr r_info; -+ grub_uint64_t sym_value; -+ -+ if (seg->size < rel->r_offset) -+ return grub_error (GRUB_ERR_BAD_MODULE, -+ "reloc offset is out of the segment"); -+ -+ r_info = (grub_uint64_t) (rel->r_info); -+ -+ addr = (grub_uint8_t *) ((char*)seg->addr + rel->r_offset); -+ sym = (Elf_Sym *) ((char*)mod->symtab -+ + mod->symsize * ELF_R_SYM (r_info)); -+ sym_value = sym->st_value; -+ if (s->sh_type == SHT_RELA) -+ { -+ sym_value += ((Elf_Rela *) rel)->r_addend; -+ } -+ switch (ELF_R_TYPE (r_info)) -+ { -+ case R_LARCH_64: -+ { -+ *(grub_uint64_t *)addr=(grub_uint64_t)sym_value; -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ { -+ la_abs=1; -+ } -+ break; -+ case R_LARCH_SOP_PUSH_PCREL: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)(sym_value-(grub_uint64_t)addr); -+ } -+ break; -+ case R_LARCH_SOP_PUSH_ABSOLUTE: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)sym_value; -+ } -+ break; -+ case R_LARCH_SOP_PUSH_PLT_PCREL: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)(sym_value-(grub_uint64_t)addr); -+ } -+ break; -+ case R_LARCH_SOP_SUB: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 - opr2; -+ } -+ break; -+ case R_LARCH_SOP_SL: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 << opr2; -+ } -+ break; -+ case R_LARCH_SOP_SR: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 >> opr2; -+ } -+ break; -+ case R_LARCH_SOP_ADD: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 + opr2; -+ } -+ break; -+ case R_LARCH_SOP_AND: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 & opr2; -+ } -+ break; -+ case R_LARCH_SOP_IF_ELSE: -+ { -+ grub_uint64_t opr3=oprs[opri]; -+ opri--; -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ if(opr1){ -+ opri++; -+ oprs[opri]=opr2; -+ } else { -+ opri++; -+ oprs[opri]=opr3; -+ } -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_5: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 & 0x1f) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_U_10_12: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 & 0xfff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_12: -+ { -+ if(la_abs==1) -+ la_abs=0; -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xfff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xffff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_5_20: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xfffff)<<5) ; -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 >> 18) & 0x1f); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); -+ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 >> 18) & 0x3ff); -+ } -+ break; -+ default: -+ { -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ N_("relocation 0x%x is not implemented yet"), -+ ELF_R_TYPE (r_info)); -+ } -+ break; -+ } -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+ return 1; -+} -diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c -new file mode 100644 -index 0000000..632c39a ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/init.c -@@ -0,0 +1,74 @@ -+/* init.c - initialize an arm-based EFI system */ -+/* -+ * 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static grub_uint64_t tmr; -+static grub_efi_event_t tmr_evt; -+ -+static grub_uint64_t -+grub_efi_get_time_ms (void) -+{ -+ return tmr; -+} -+ -+static void -+grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), -+ void *context __attribute__ ((unused))) -+{ -+ tmr += 10; -+} -+ -+void -+grub_machine_init (void) -+{ -+ grub_efi_boot_services_t *b; -+ -+ grub_efi_init (); -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); -+ -+ grub_install_get_time_ms (grub_efi_get_time_ms); -+} -+ -+void -+grub_machine_fini (int flags) -+{ -+ grub_efi_boot_services_t *b; -+ -+ if (!(flags & GRUB_LOADER_FLAG_NORETURN)) -+ return; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); -+ efi_call_1 (b->close_event, tmr_evt); -+ -+ grub_efi_fini (); -+} -diff --git a/grub-core/kern/loongarch64/efi/startup.S b/grub-core/kern/loongarch64/efi/startup.S -new file mode 100644 -index 0000000..1ffff08 ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/startup.S -@@ -0,0 +1,45 @@ -+/* -+ * 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 . -+ */ -+ -+#include -+ -+ .file "startup.S" -+ .text -+ .globl start, _start -+ .align 4 -+ -+FUNCTION(start) -+FUNCTION(_start) -+ /* -+ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. -+ */ -+ addi.d $sp, $sp, -16 -+ st.d $ra, $sp, 0 -+ -+ la $a2, grub_efi_image_handle -+ st.d $a0, $a2, 0 -+ la $a2, grub_efi_system_table -+ st.d $a1, $a2, 0 -+ -+ bl grub_main -+ -+1: -+ ld.d $ra, $sp, 0 -+ addi.d $sp, $sp, 16 -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/init.c b/grub-core/kern/loongarch64/init.c -new file mode 100644 -index 0000000..b2de930 ---- /dev/null -+++ b/grub-core/kern/loongarch64/init.c -@@ -0,0 +1,47 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+grub_uint32_t grub_arch_cpuclock; -+ -+/* FIXME: use interrupt to count high. */ -+grub_uint64_t -+grub_get_rtc (void) -+{ -+ static grub_uint32_t high = 0; -+ static grub_uint32_t last = 0; -+ grub_uint32_t low; -+ -+ asm volatile ("csrrd %0, " GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT : "=r" (low)); -+ if (low < last) -+ high++; -+ last = low; -+ -+ return (((grub_uint64_t) high) << 32) | low; -+} -+ -+void -+grub_timer_init (grub_uint32_t cpuclock) -+{ -+ grub_arch_cpuclock = cpuclock; -+ grub_install_get_time_ms (grub_rtc_get_time_ms); -+} -diff --git a/grub-core/lib/loongarch64/efi/loongson.c b/grub-core/lib/loongarch64/efi/loongson.c -new file mode 100644 -index 0000000..eda1e1c ---- /dev/null -+++ b/grub-core/lib/loongarch64/efi/loongson.c -@@ -0,0 +1,119 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+unsigned long -+grub_efi_get_bpi_version (const char *str) -+{ -+ unsigned long version = GRUB_EFI_BPI_VER_NONE; -+ -+ version = grub_strtoul (str + 4, 0, 0); -+ -+ return version; -+} -+ -+void * -+grub_efi_loongson_get_boot_params (void) -+{ -+ static void * boot_params = NULL; -+ grub_efi_configuration_table_t *tables; -+ grub_efi_guid_t loongson_bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; -+ unsigned int i; -+ -+ if (boot_params) -+ return boot_params; -+ -+ /* Look for Loongson boot params interface in UEFI config tables. */ -+ tables = grub_efi_system_table->configuration_table; -+ -+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) -+ if (grub_memcmp (&tables[i].vendor_guid, &loongson_bpi_guid, sizeof (loongson_bpi_guid)) == 0) -+ { -+ boot_params= tables[i].vendor_table; -+ grub_dprintf ("loongson", "found registered BPI @ %p\n", boot_params); -+ break; -+ } -+ return boot_params; -+} -+ -+grub_uint8_t -+grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) -+{ -+ grub_uint8_t sum; -+ grub_efi_uintn_t count; -+ -+ for (sum = 0, count = 0; count < length; count++) -+ { -+ sum = (grub_uint8_t) (sum + *(buffer + count)); -+ } -+ return sum; -+} -+ -+grub_uint8_t -+grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) -+{ -+ grub_uint8_t checksum; -+ -+ checksum = grub_efi_loongson_calculatesum8(buffer, length); -+ -+ return (grub_uint8_t) (0x100 - checksum); -+} -+ -+ -+grub_uint32_t -+grub_efi_loongson_memmap_v1_sort(struct memmap_v1 array[], grub_uint32_t length, -+ mem_map_v1 * bpmem, grub_uint32_t index, grub_uint32_t memtype) -+{ -+ grub_uint64_t tempmemsize = 0; -+ grub_uint32_t j = 0; -+ grub_uint32_t t = 0; -+ -+ for(j = 0; j < length;) -+ { -+ tempmemsize = array[j].memsize; -+ for(t = j + 1; t < length; t++) -+ { -+ if(array[j].memstart + tempmemsize == array[t].memstart) -+ { -+ tempmemsize += array[t].memsize; -+ } -+ else -+ { -+ break; -+ } -+ } -+ bpmem->map[index].memtype = memtype; -+ bpmem->map[index].memstart = array[j].memstart; -+ bpmem->map[index].memsize = tempmemsize; -+ grub_dprintf("loongson", "v1 map[%d]:type %x, start 0x%lx, end 0x%lx\n", -+ index, -+ bpmem->map[index].memtype, -+ bpmem->map[index].memstart, -+ bpmem->map[index].memstart+ bpmem->map[index].memsize -+ ); -+ j = t; -+ index++; -+ } -+ return index; -+} -diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c -new file mode 100644 -index 0000000..4b253ca ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator.c -@@ -0,0 +1,163 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+extern grub_uint8_t grub_relocator_forward_start; -+extern grub_uint8_t grub_relocator_forward_end; -+extern grub_uint8_t grub_relocator_backward_start; -+extern grub_uint8_t grub_relocator_backward_end; -+ -+#define REGW_SIZEOF (4 * sizeof (grub_uint32_t)) -+#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) -+ -+#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ -+ - &grub_relocator_##x##_start) -+#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ -+ + REGW_SIZEOF * 3) -+grub_size_t grub_relocator_align = sizeof (grub_uint64_t); -+grub_size_t grub_relocator_forward_size; -+grub_size_t grub_relocator_backward_size; -+grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; -+ -+void -+grub_cpu_relocator_init (void) -+{ -+ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); -+ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); -+} -+ -+static void -+write_reg (int regn, grub_uint64_t val, void **target) -+{ -+ grub_uint32_t lu12iw=0x14000000; -+ grub_uint32_t ori=0x03800000; -+ grub_uint32_t lu32id=0x16000000; -+ grub_uint32_t lu52id=0x03000000; -+ -+ *(grub_uint32_t *) *target = (lu12iw | (grub_uint32_t)((val & 0xfffff000)>>12<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (ori | (grub_uint32_t)((val & 0xfff)<<10) | (grub_uint32_t)(regn | regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu32id | (grub_uint32_t)((val & 0xfffff00000000)>>32<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu52id | (grub_uint32_t)((val & 0xfff0000000000000)>>52<<10) | (grub_uint32_t)(regn | regn<<5));; -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+static void -+write_jump (int regn, void **target) -+{ -+ grub_uint32_t jirl=0x4c000000; -+ -+ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+void -+grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -+{ -+ write_reg (1, addr, &rels); -+ write_jump (1, &rels); -+} -+ -+void -+grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_backward_start, -+ RELOCATOR_SRC_SIZEOF (backward)); -+} -+ -+void -+grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_forward_start, -+ RELOCATOR_SRC_SIZEOF (forward)); -+} -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state) -+{ -+ grub_relocator_chunk_t ch; -+ void *ptr; -+ grub_err_t err; -+ void *relst; -+ grub_size_t relsize; -+ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; -+ unsigned i; -+ grub_addr_t vtarget; -+ -+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, -+ (0xffffffff - stateset_size) -+ + 1, stateset_size, -+ grub_relocator_align, -+ GRUB_RELOCATOR_PREFERENCE_NONE, 0); -+ if (err) -+ return err; -+ -+ ptr = get_virtual_current_address (ch); -+ for (i = 1; i < 32; i++) -+ write_reg (i, state.gpr[i], &ptr); -+ write_jump (state.jumpreg, &ptr); -+ -+ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), -+ stateset_size); -+ -+ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); -+ if (err) -+ return err; -+ -+ grub_arch_sync_caches ((void *) relst, relsize); -+ -+ asm volatile ( -+ "ibar 0 \n"); -+ -+ grub_uint64_t val; -+ __asm__ __volatile__( -+ "li.w %0, 0x4\n\t" -+ "csrxchg $r0, %0, 0x0\n\t" -+ : "=r"(val) -+ : -+ : -+ ); -+ -+ ((void (*) (void)) relst) (); -+ -+ /* Not reached. */ -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/lib/loongarch64/relocator_asm.S b/grub-core/lib/loongarch64/relocator_asm.S -new file mode 100644 -index 0000000..cf1724d ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator_asm.S -@@ -0,0 +1,51 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#include -+ -+ .p2align 4 /* force 16-byte alignment */ -+ -+VARIABLE (grub_relocator_forward_start) -+ -+copycont1: -+ ld.d $r11,$r8,0 -+ st.d $r11,$r9,0 -+ addi.d $r8, $r8, 8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, 8 -+ bne $r10, $r0, copycont1 -+ -+VARIABLE (grub_relocator_forward_end) -+ -+VARIABLE (grub_relocator_backward_start) -+ -+ add.d $r9, $r9, $r10 -+ add.d $r8, $r8, $r10 -+ /* Backward movsl is implicitly off-by-one. compensate that. */ -+ addi.d $r9, $r9, -8 -+ addi.d $r8, $r8, -8 -+copycont2: -+ ld.w $r11,$r8,0 -+ st.w $r11,$r9,0 -+ addi.d $r8, $r8, -8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, -8 -+ bne $r10, $r0, copycont2 -+ -+VARIABLE (grub_relocator_backward_end) -+ -diff --git a/grub-core/lib/loongarch64/setjmp.S b/grub-core/lib/loongarch64/setjmp.S -new file mode 100644 -index 0000000..47db814 ---- /dev/null -+++ b/grub-core/lib/loongarch64/setjmp.S -@@ -0,0 +1,74 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2003,2007,2009 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 . -+ */ -+ -+#include -+#include -+#include -+ -+ .file "setjmp.S" -+ -+GRUB_MOD_LICENSE "GPLv3+" -+ -+ .text -+ -+/* -+ * int grub_setjmp (grub_jmp_buf env) -+ */ -+FUNCTION(grub_setjmp) -+ GRUB_ASM_REG_S $s0, $a0,0 -+ GRUB_ASM_REG_S $s1, $a0,8 -+ GRUB_ASM_REG_S $s2, $a0,16 -+ GRUB_ASM_REG_S $s3, $a0,24 -+ GRUB_ASM_REG_S $s4, $a0,32 -+ GRUB_ASM_REG_S $s5, $a0,40 -+ GRUB_ASM_REG_S $s6, $a0,48 -+ GRUB_ASM_REG_S $s7, $a0,56 -+ GRUB_ASM_REG_S $s8, $a0,64 -+ GRUB_ASM_REG_S $fp, $a0,72 -+ GRUB_ASM_REG_S $sp, $a0,80 -+ GRUB_ASM_REG_S $ra, $a0,88 -+ move $v0, $zero -+ move $v1, $zero -+ jr $ra -+ nop -+/* -+ * int grub_longjmp (grub_jmp_buf env, int val) -+ */ -+FUNCTION(grub_longjmp) -+ GRUB_ASM_REG_L $s0, $a0,0 -+ GRUB_ASM_REG_L $s1, $a0,8 -+ GRUB_ASM_REG_L $s2, $a0,16 -+ GRUB_ASM_REG_L $s3, $a0,24 -+ GRUB_ASM_REG_L $s4, $a0,32 -+ GRUB_ASM_REG_L $s5, $a0,40 -+ GRUB_ASM_REG_L $s6, $a0,48 -+ GRUB_ASM_REG_L $s7, $a0,56 -+ GRUB_ASM_REG_L $s8, $a0,64 -+ GRUB_ASM_REG_L $fp, $a0,72 -+ GRUB_ASM_REG_L $sp, $a0,80 -+ GRUB_ASM_REG_L $ra, $a0,88 -+ addi.w $v0, $zero, 1 -+ /* -+ * replace: movn $v0, $a1, $a1 -+ */ -+ bnez $a1, .ZW0 -+ addi.d $v0, $a1, 0 -+.ZW0: -+ addi.d $v1,$zero,0 -+ jr $ra -+ nop -diff --git a/grub-core/lib/loongson/reboot.c b/grub-core/lib/loongson/reboot.c -new file mode 100644 -index 0000000..107787a ---- /dev/null -+++ b/grub-core/lib/loongson/reboot.c -@@ -0,0 +1,33 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2011 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void -+grub_la_reboot (void) -+{ -+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); -+ efi_call_4 (grub_efi_system_table->runtime_services->reset_system, -+ GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); -+ for (;;) ; -+} -diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S -index f6e4905..023dc90 100644 ---- a/grub-core/lib/setjmp.S -+++ b/grub-core/lib/setjmp.S -@@ -15,6 +15,8 @@ - #include "./arm/setjmp.S" - #elif defined(__aarch64__) - #include "./arm64/setjmp.S" -+#elif defined(__loongarch64) -+#include "./loongarch64/setjmp.S" - #else - #error "Unknown target cpu type" - #endif -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index b72e6bd..f4066b5 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -343,6 +343,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = - GRUB_PE32_MACHINE_I386; - #elif defined(__ia64__) - GRUB_PE32_MACHINE_IA64; -+#elif defined(__loongarch64) -+ GRUB_PE32_MACHINE_LOONGARCH64; - #else - #error this architecture is not supported by grub2 - #endif -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -new file mode 100644 -index 0000000..7594ca2 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux.c -@@ -0,0 +1,690 @@ -+/* linux.c - boot Linux */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2003,2004,2005,2007,2009,2010,2017 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#pragma GCC diagnostic ignored "-Wcast-align" -+ -+typedef unsigned long size_t; -+ -+#define FDT_ADDR_CELLS_STRING "#address-cells" -+#define FDT_SIZE_CELLS_STRING "#size-cells" -+#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ -+ sizeof (FDT_ADDR_CELLS_STRING) + \ -+ sizeof (FDT_SIZE_CELLS_STRING)) -+ -+static grub_dl_t my_mod; -+static int loaded; -+static int initrd_loaded = 0; -+static grub_size_t linux_size; -+ -+static struct grub_relocator *relocator; -+static grub_addr_t target_addr, entry_addr; -+static int linux_argc; -+static grub_uint8_t *linux_args_addr; -+static grub_off_t rd_addr_arg_off, rd_size_arg_off, initrd_addr_arg_off; -+ -+static void *fdt; -+static int is_fdt_boot; -+static grub_addr_t initrd_start, initrd_end; -+static char *fdt_linux_args; -+ -+static grub_err_t -+allocate_fdt_and_exit_boot (void) -+{ -+ int node, retval; -+ grub_err_t err; -+ unsigned int size; -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ -+ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; -+ -+ fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); -+ if (!fdt) -+ return GRUB_ERR_OUT_OF_MEMORY; -+ -+ grub_fdt_create_empty_tree (fdt, size); -+ grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); -+ grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); -+ -+ node = grub_fdt_find_subnode (fdt, 0, "chosen"); -+ if (node < 0) -+ node = grub_fdt_add_subnode (fdt, 0, "chosen"); -+ if (node < 1) -+ goto failure; -+ -+ grub_dprintf ("loongson", "command_line %s, len %ld\n", -+ fdt_linux_args, grub_strlen(fdt_linux_args) + 1); -+ if ((fdt_linux_args != NULL) && (grub_strlen(fdt_linux_args) > 0)) { -+ retval = grub_fdt_set_prop (fdt, node, "bootargs", fdt_linux_args, -+ grub_strlen(fdt_linux_args) + 1); -+ if (retval) -+ goto failure; -+ } -+ -+ /* Set initrd info */ -+ if (initrd_start && initrd_end > initrd_start) -+ { -+ grub_dprintf ("linux", "Initrd @ %p-%p\n", -+ (void *) initrd_start, (void *) initrd_end); -+ -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", -+ initrd_start); -+ if (retval) -+ goto failure; -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", -+ initrd_end); -+ if (retval) -+ goto failure; -+ } -+ -+ node = grub_fdt_find_subnode (fdt, 0, "chosen"); -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-system-table", -+ (grub_uint64_t)grub_efi_system_table); -+ if (retval) -+ goto failure; -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-mmap-start", -+ (grub_uint64_t)mmap_buf); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-size", -+ mmap_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-size", -+ desc_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-ver", -+ desc_version); -+ if (retval) -+ goto failure; -+ -+ return GRUB_ERR_NONE; -+ -+failure: -+ if (!fdt) { -+ return GRUB_ERR_BAD_OS; -+ } -+ grub_efi_free_pages ((grub_addr_t) fdt, -+ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt))); -+ fdt = NULL; -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} -+ -+static grub_err_t -+allocate_boot_params_and_exit_boot (void) -+{ -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ grub_efi_memory_descriptor_t * lsdesc = NULL; -+ grub_err_t err; -+ struct boot_params_interface * boot_params; -+ mem_map_v1 * mem_map_v1_table = NULL; -+ unsigned long bpi_version = 0; -+ grub_int8_t checksum = 0; -+ grub_uint32_t tmp_index = 0; -+ grub_uint32_t free_index = 0; -+ grub_uint32_t reserve_index = 0; -+ grub_uint32_t acpi_table_index = 0; -+ grub_uint32_t acpi_nvs_index = 0; -+ -+ struct memmap_v1 reserve_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap_v1 free_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap_v1 acpi_table_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap_v1 acpi_nvs_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ -+ grub_memset(reserve_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(free_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(acpi_table_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(acpi_nvs_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ -+ boot_params = (struct boot_params_interface *)grub_efi_loongson_get_boot_params(); -+ -+ ext_list * listpointer = NULL; -+ /* Check extlist headers */ -+ listpointer = boot_params->extlist; -+ for( ;listpointer != NULL; listpointer = listpointer->next) -+ { -+ char *pl= (char *)&(listpointer->signature); -+ if(grub_strncmp(pl, "MEM", 3) == 0) -+ { -+ mem_map_v1_table = (mem_map_v1 *)listpointer; -+ break; -+ } -+ } -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ char *p = (char *)&(boot_params->signature); -+ bpi_version = grub_efi_get_bpi_version(p); -+ grub_dprintf("loongson", "get bpi version:%ld\n", bpi_version); -+ -+ if (bpi_version <= GRUB_EFI_BPI_VER_V2) -+ { -+ /* -+ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ -+ now we can fill platform specific memory structure. -+ */ -+ for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); -+ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) -+ { -+ grub_dprintf("loongson", "type:%d, phy_start:0x%lx, phy_end:0x%lx\n", lsdesc->type, -+ lsdesc->physical_start, lsdesc->physical_start + lsdesc->num_pages * GRUB_EFI_PAGE_SIZE); -+ -+ /* System RAM */ -+ if ((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ -+ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ -+ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ -+ (lsdesc->type != GRUB_EFI_PAL_CODE)) -+ { -+ free_mem_v1[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; -+ free_mem_v1[free_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ free_mem_v1[free_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ free_index++; -+ -+ /*ACPI*/ -+ } else if ((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ -+ acpi_table_mem_v1[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; -+ acpi_table_mem_v1[acpi_table_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_table_mem_v1[acpi_table_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_table_index++; -+ } else if ((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ -+ acpi_nvs_mem_v1[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; -+ acpi_nvs_mem_v1[acpi_nvs_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_nvs_mem_v1[acpi_nvs_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_nvs_index++; -+ -+ /* Reserve */ -+ } else { -+ reserve_mem_v1[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; -+ reserve_mem_v1[reserve_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ reserve_mem_v1[reserve_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ reserve_index++; -+ } -+ } -+ -+ tmp_index = mem_map_v1_table->mapcount; -+ /*System RAM Sort*/ -+ tmp_index = grub_efi_loongson_memmap_v1_sort(free_mem_v1, free_index, mem_map_v1_table, -+ tmp_index, GRUB_EFI_LOONGSON_SYSTEM_RAM); -+ /*ACPI Sort*/ -+ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_table_mem_v1, acpi_table_index, -+ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); -+ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_nvs_mem_v1, acpi_nvs_index, -+ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); -+ /*Reserve Sort*/ -+ { -+ grub_uint64_t loongarch_addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); -+ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) -+ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, -+ mem_map_v1_table, tmp_index, -+ GRUB_EFI_LOONGSON_MEMORY_RESERVED); -+ else -+ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, -+ mem_map_v1_table, tmp_index, -+ GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); -+ } -+ mem_map_v1_table->mapcount = tmp_index; -+ mem_map_v1_table->header.checksum = 0; -+ -+ checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)mem_map_v1_table, -+ mem_map_v1_table->header.length); -+ mem_map_v1_table->header.checksum = checksum; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linux_boot (void) -+{ -+ struct grub_relocator64_state state; -+ -+ grub_memset (&state, 0, sizeof (state)); -+ -+ /* Boot the kernel. */ -+ state.gpr[1] = entry_addr; -+ grub_dprintf("loongson", "entry_addr is 0x%lx\n", state.gpr[1]); -+ -+ if (is_fdt_boot == 1) -+ { -+ if (allocate_fdt_and_exit_boot () != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; -+ state.gpr[5] = (grub_uint64_t)fdt; -+ state.gpr[6] = 0; -+ } else { -+ state.gpr[4] = linux_argc; -+ state.gpr[5] = (grub_addr_t) linux_args_addr; -+ state.gpr[6] = (grub_uint64_t)grub_efi_loongson_get_boot_params(); -+ -+ if (allocate_boot_params_and_exit_boot () != GRUB_ERR_NONE) -+ return grub_errno; -+ } -+ grub_dprintf("loongson", "gpr[4]:%ld, gpr[5]:0x%lx, gpr[6]:0x%lx\n", -+ state.gpr[4], state.gpr[5], state.gpr[6]); -+ -+ state.jumpreg = 1; -+ grub_relocator64_boot (relocator, state); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linux_unload (void) -+{ -+ grub_relocator_unload (relocator); -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linux_load64 (grub_elf_t elf, const char *filename) -+{ -+ Elf64_Addr base; -+ grub_err_t err; -+ grub_uint8_t *playground; -+ grub_uint64_t addr; -+ int flag; -+ -+ /* Linux's entry point incorrectly contains a virtual address. */ -+ entry_addr = elf->ehdr.ehdr64.e_entry; -+ grub_dprintf("loongson", "entry address = 0x%lx\n", entry_addr); -+ -+ linux_size = grub_elf64_size (elf, &base, 0); -+ grub_dprintf("loongson", "base = 0x%lx\n", base); -+ -+ if (linux_size == 0) -+ return grub_errno; -+ target_addr = base; -+ linux_size = ALIGN_UP (base + linux_size - base, 8); -+ -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) { -+ flag = GRUB_ELF_LOAD_FLAGS_NONE; -+ } else { -+ flag = GRUB_ELF_LOAD_FLAGS_30BITS; -+ base &= ~ELF64_LOADMASK; -+ entry_addr &= ~ELF64_LOADMASK; -+ } -+ -+ relocator = grub_relocator_new (); -+ if (!relocator) -+ return grub_errno; -+ -+ { -+ grub_relocator_chunk_t ch; -+ err = grub_relocator_alloc_chunk_addr (relocator, &ch, -+ grub_vtop ((void *) target_addr), -+ linux_size); -+ if (err) -+ return err; -+ playground = get_virtual_current_address (ch); -+ } -+ -+ /* Now load the segments into the area we claimed. */ -+ return grub_elf64_load (elf, filename, playground - base, flag, 0, 0); -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_elf_t elf = 0; -+ grub_err_t err; -+ int args_size = 0; -+ -+ grub_dl_ref (my_mod); -+ -+ if (argc == 0) -+ { -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ } -+ -+ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); -+ if (! elf) -+ return grub_errno; -+ -+ if (elf->ehdr.ehdr64.e_type != ET_EXEC) -+ { -+ grub_elf_close (elf); -+ return grub_error (GRUB_ERR_UNKNOWN_OS, -+ N_("this ELF file is not of the right type")); -+ } -+ -+ /* Release the previously used memory. */ -+ grub_loader_unset (); -+ loaded = 0; -+ -+ if (grub_elf_is_elf64 (elf)) -+ err = grub_linux_load64 (elf, argv[0]); -+ else -+ err = grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ -+ grub_elf_close (elf); -+ -+ if (err) -+ return err; -+ -+ if (grub_efi_loongson_get_boot_params() == NULL) { -+ grub_size_t cmdline_size; -+ -+ is_fdt_boot = 1; -+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); -+ fdt_linux_args = grub_malloc (cmdline_size); -+ if (!fdt_linux_args) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ grub_memcpy (fdt_linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ err = grub_create_loader_cmdline (argc, argv, -+ fdt_linux_args + sizeof (LINUX_IMAGE) - 1, -+ cmdline_size, -+ GRUB_VERIFY_KERNEL_CMDLINE); -+ if (err) -+ goto fail; -+ grub_dprintf("loongson", "fdt linux args:%s\n", -+ fdt_linux_args + sizeof (LINUX_IMAGE) - 1); -+ -+ } else { -+ int i; -+ grub_uint64_t *linux_argv; -+ char *linux_args; -+ -+ is_fdt_boot = 0; -+ /* For arguments. */ -+ linux_argc = argc; -+ /* Main arguments. */ -+ args_size = (linux_argc) * sizeof (grub_uint64_t); -+ /* Initrd address/size and initrd */ -+ args_size += 3 * sizeof (grub_uint64_t); -+ /* NULL terminator. */ -+ args_size += sizeof (grub_uint64_t); -+ /* First argument is always "a0". */ -+ args_size += ALIGN_UP (sizeof ("a0"), 4); -+ /* Normal arguments. */ -+ for (i = 1; i < argc; i++) -+ args_size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); -+ -+ /* rd arguments. */ -+ args_size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ args_size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ args_size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ -+ args_size = ALIGN_UP (args_size, 8); -+ -+ linux_args_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (args_size)); -+ grub_dprintf ("linux", "linux args numpages: %lld\n", -+ (long long) GRUB_EFI_BYTES_TO_PAGES (args_size)); -+ if (!linux_args_addr) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ linux_argv = (grub_uint64_t *) linux_args_addr; -+ linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); -+ -+ grub_memcpy (linux_args, "a0", sizeof ("a0")); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("a0"), 4); -+ -+ for (i = 1; i < argc; i++) -+ { -+ grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); -+ } -+ -+ /* Reserve space for rd arguments. */ -+ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; -+ -+ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; -+ -+ /* Reserve space for initrd arguments. */ -+ initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; -+ -+ *linux_argv = 0; -+ } -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ { -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); -+ loaded = 1; -+ } -+ -+ initrd_loaded = 0; -+ -+fail: -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (fdt_linux_args && !loaded) -+ grub_free (fdt_linux_args); -+ -+ if (linux_args_addr && !loaded) -+ grub_efi_free_pages ((grub_addr_t) linux_args_addr, -+ GRUB_EFI_BYTES_TO_PAGES (args_size)); -+ -+ return grub_errno; -+} -+ -+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) -+ -+/* -+ * This function returns a pointer to a legally allocated initrd buffer, -+ * or NULL if unsuccessful -+ */ -+static void * -+allocate_initrd_mem (int initrd_pages) -+{ -+ grub_addr_t max_addr; -+ -+ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) -+ return NULL; -+ -+ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; -+ -+ return grub_efi_allocate_pages_real (max_addr, initrd_pages, -+ GRUB_EFI_ALLOCATE_MAX_ADDRESS, -+ GRUB_EFI_LOADER_DATA); -+} -+ -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_size_t initrd_size, initrd_pages; -+ grub_err_t err; -+ void *initrd_mem = NULL; -+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; -+ -+ if (argc == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ -+ if (!loaded) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); -+ -+ if (initrd_loaded) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued."); -+ -+ if (grub_initrd_init (argc, argv, &initrd_ctx)) -+ goto fail; -+ -+ initrd_size = grub_get_initrd_size (&initrd_ctx); -+ -+ if (is_fdt_boot == 1) //fdt -+ { -+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -+ initrd_mem = allocate_initrd_mem (initrd_pages); -+ if (!initrd_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ } else { -+ grub_relocator_chunk_t ch; -+ err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xffffffff - initrd_size) + 1, -+ initrd_size, 0x10000, -+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); -+ -+ if (err) -+ return err; -+ initrd_mem = get_virtual_current_address (ch); -+ } -+ -+ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) -+ goto fail; -+ -+ initrd_start = (grub_addr_t) initrd_mem; -+ initrd_end = initrd_start + initrd_size; -+ grub_dprintf ("linux", "[addr=%p, size=0x%lx]\n", -+ (void *) initrd_start, initrd_size); -+ -+ if (is_fdt_boot == 0) //bpi -+ { -+ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, -+ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), -+ "rd_start=0x%lx", -+ (grub_uint64_t) initrd_mem); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); -+ linux_argc++; -+ -+ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, -+ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", -+ (grub_uint64_t) initrd_size); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); -+ linux_argc++; -+ -+ grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, -+ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) initrd_mem & GRUB_EFI_MAX_PHY_ADDRESS), -+ (grub_uint64_t) initrd_size); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); -+ linux_argc++; -+ } -+ -+ initrd_loaded = 1; -+ -+ fail: -+ grub_initrd_close (&initrd_ctx); -+ if (is_fdt_boot == 1) -+ 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, -+ 0, N_("Load Linux.")); -+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, -+ 0, 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/dl.h b/include/grub/dl.h -index 6f46b7e..50e04ac 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -360,7 +360,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - #define GRUB_ARCH_DL_GOT_ALIGN 4 - #endif - --#if defined (__aarch64__) || defined (__sparc__) -+#if defined (__aarch64__) || defined (__sparc__) || defined (__loongarch64) - #define GRUB_ARCH_DL_TRAMP_ALIGN 8 - #define GRUB_ARCH_DL_GOT_ALIGN 8 - #endif -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 510a403..a57187f 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -2117,7 +2117,8 @@ struct grub_efi_memory_attribute_protocol - typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t; - - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ -- || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) -+ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ -+ || defined (__loongarch64) - - #define efi_call_0(func) func() - #define efi_call_1(func, a) func(a) -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 8ca8c38..fe1df9d 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -138,7 +138,7 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, - extern grub_addr_t EXPORT_VAR(grub_stack_addr); - extern grub_size_t EXPORT_VAR(grub_stack_size); - --#if defined(__arm__) || defined(__aarch64__) -+#if defined(__arm__) || defined(__aarch64__) || defined (__loongarch__) - void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); - grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); - #include -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index 45c9f8b..f612a55 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -89,6 +89,7 @@ struct grub_pe32_coff_header - }; - - #define GRUB_PE32_MACHINE_I386 0x14c -+#define GRUB_PE32_MACHINE_LOONGARCH64 0x6264 - #define GRUB_PE32_MACHINE_IA64 0x200 - #define GRUB_PE32_MACHINE_X86_64 0x8664 - #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 -@@ -355,6 +356,7 @@ struct grub_pe32_fixup_block - #define GRUB_PE32_REL_BASED_IA64_IMM64 9 - #define GRUB_PE32_REL_BASED_DIR64 10 - #define GRUB_PE32_REL_BASED_HIGH3ADJ 11 -+#define GRUB_PE32_REL_BASED_LOONGARCH64 8 - - struct grub_pe32_symbol - { -diff --git a/include/grub/elf.h b/include/grub/elf.h -index c8492f9..2c0b163 100644 ---- a/include/grub/elf.h -+++ b/include/grub/elf.h -@@ -247,6 +247,7 @@ typedef struct - #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ - #define EM_NUM 95 - #define EM_AARCH64 183 /* ARM 64-bit architecture */ -+#define EM_LOONGARCH64 258 /* LoongArch64 architecture */ - - /* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -@@ -1448,6 +1449,60 @@ typedef struct - #define OHWA0_R4KEOP_CHECKED 0x00000001 - #define OHWA1_R4KEOP_CLEAN 0x00000002 - -+/* LOONGARCH64 relocs. */ -+#define R_LARCH_NONE 0 -+#define R_LARCH_32 1 -+#define R_LARCH_64 2 -+#define R_LARCH_RELATIVE 3 -+#define R_LARCH_COPY 4 -+#define R_LARCH_JUMP_SLOT 5 -+#define R_LARCH_TLS_DTPMOD32 6 -+#define R_LARCH_TLS_DTPMOD64 7 -+#define R_LARCH_TLS_DTPREL32 8 -+#define R_LARCH_TLS_DTPREL64 9 -+#define R_LARCH_TLS_TPREL32 10 -+#define R_LARCH_TLS_TPREL64 11 -+#define R_LARCH_IRELATIVE 12 -+#define R_LARCH_MARK_LA 20 -+#define R_LARCH_MARK_PCREL 21 -+#define R_LARCH_SOP_PUSH_PCREL 22 -+#define R_LARCH_SOP_PUSH_ABSOLUTE 23 -+#define R_LARCH_SOP_PUSH_DUP 24 -+#define R_LARCH_SOP_PUSH_GPREL 25 -+#define R_LARCH_SOP_PUSH_TLS_TPREL 26 -+#define R_LARCH_SOP_PUSH_TLS_GOT 27 -+#define R_LARCH_SOP_PUSH_TLS_GD 28 -+#define R_LARCH_SOP_PUSH_PLT_PCREL 29 -+#define R_LARCH_SOP_ASSERT 30 -+#define R_LARCH_SOP_NOT 31 -+#define R_LARCH_SOP_SUB 32 -+#define R_LARCH_SOP_SL 33 -+#define R_LARCH_SOP_SR 34 -+#define R_LARCH_SOP_ADD 35 -+#define R_LARCH_SOP_AND 36 -+#define R_LARCH_SOP_IF_ELSE 37 -+#define R_LARCH_SOP_POP_32_S_10_5 38 -+#define R_LARCH_SOP_POP_32_U_10_12 39 -+#define R_LARCH_SOP_POP_32_S_10_12 40 -+#define R_LARCH_SOP_POP_32_S_10_16 41 -+#define R_LARCH_SOP_POP_32_S_10_16_S2 42 -+#define R_LARCH_SOP_POP_32_S_5_20 43 -+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 -+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 -+#define R_LARCH_SOP_POP_32_U 46 -+#define R_LARCH_ADD8 47 -+#define R_LARCH_ADD16 48 -+#define R_LARCH_ADD24 49 -+#define R_LARCH_ADD32 50 -+#define R_LARCH_ADD64 51 -+#define R_LARCH_SUB8 52 -+#define R_LARCH_SUB16 53 -+#define R_LARCH_SUB24 54 -+#define R_LARCH_SUB32 55 -+#define R_LARCH_SUB64 56 -+#define R_LARCH_GNU_VTINHERIT 57 -+#define R_LARCH_GNU_VTENTRY 58 -+ - /* MIPS relocs. */ - - #define R_MIPS_NONE 0 /* No reloc */ -diff --git a/include/grub/fdt.h b/include/grub/fdt.h -index 6ee57e1..a0710ab 100644 ---- a/include/grub/fdt.h -+++ b/include/grub/fdt.h -@@ -19,11 +19,14 @@ - #ifndef GRUB_FDT_HEADER - #define GRUB_FDT_HEADER 1 - --#if defined(__arm__) || defined(__aarch64__) -+#if defined(__arm__) || defined(__aarch64__) || defined (__loongarch__) - - #include - #include - -+/* Space required when preparing the /chosen node after boot has been called. */ -+#define GRUB_EFI_LINUX_FDT_EXTRA_SPACE 0x400 -+ - #define FDT_MAGIC 0xD00DFEED - - typedef struct { -diff --git a/include/grub/loongarch64/asm.h b/include/grub/loongarch64/asm.h -new file mode 100644 -index 0000000..c3e77e9 ---- /dev/null -+++ b/include/grub/loongarch64/asm.h -@@ -0,0 +1,10 @@ -+#ifndef GRUB_LOONGARCH64_ASM_HEADER -+#define GRUB_LOONGARCH64_ASM_HEADER 1 -+ -+#define GRUB_ASM_T4 $a4 -+#define GRUB_ASM_T5 $a5 -+#define GRUB_ASM_SZREG 8 -+#define GRUB_ASM_REG_S st.d -+#define GRUB_ASM_REG_L ld.d -+ -+#endif -diff --git a/include/grub/loongarch64/efi/loongson.h b/include/grub/loongarch64/efi/loongson.h -new file mode 100644 -index 0000000..7a9ccb4 ---- /dev/null -+++ b/include/grub/loongarch64/efi/loongson.h -@@ -0,0 +1,113 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#ifndef GRUB_EFI_LOONGSON_HEADER -+#define GRUB_EFI_LOONGSON_HEADER 1 -+ -+#include -+ -+#include -+ -+#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ -+ { 0x4660f721, 0x2ec5, 0x416a, \ -+ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ -+ } -+ -+#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL -+#define ELF32_LOADMASK (0xf0000000UL) -+#define ELF64_LOADMASK (0xf000000000000000ULL) -+#define FLAGS_EFI_SUPPORT_BIT 0 -+#define GRUB_EFI_LOONGSON_MMAP_MAX 128 -+ -+typedef enum -+ { -+ GRUB_EFI_LOONGSON_SYSTEM_RAM = 1, -+ GRUB_EFI_LOONGSON_MEMORY_RESERVED, -+ GRUB_EFI_LOONGSON_ACPI_TABLE, -+ GRUB_EFI_LOONGSON_ACPI_NVS, -+ GRUB_EFI_LOONGSON_MAX_MEMORY_TYPE -+ } -+grub_efi_loongson_memory_type; -+ -+typedef enum -+ { -+ GRUB_EFI_BPI_VER_NONE = 0, -+ GRUB_EFI_BPI_VER_V1 = 1000, -+ GRUB_EFI_BPI_VER_V2 = 1001, -+ } -+ grub_efi_loongson_bpi_version; -+ -+grub_uint8_t -+EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, -+ grub_efi_uintn_t Length); -+ -+grub_uint8_t -+EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, -+ grub_efi_uintn_t Length); -+ -+unsigned long -+EXPORT_FUNC(grub_efi_get_bpi_version) (const char *str); -+ -+void * -+EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); -+ -+typedef struct _extention_list_hdr { -+ grub_uint64_t signature; -+ grub_uint32_t length; -+ grub_uint8_t revision; -+ grub_uint8_t checksum; -+ union { -+ struct _extention_list_hdr *next; -+ grub_uint64_t next_offset; -+ }; -+}GRUB_PACKED -+ext_list; -+ -+typedef struct boot_params_interface { -+ grub_uint64_t signature; //{'B', 'P', 'I', 'x', 'x', 'x', 'x', 'x'} -+ grub_efi_system_table_t *systemtable; -+ union { -+ ext_list *extlist; -+ grub_uint64_t extlist_offset; -+ }; -+ grub_uint64_t flags; -+}GRUB_PACKED -+boot_params_interface; -+ -+typedef struct { -+ ext_list header; //{MEM} -+ grub_uint8_t mapcount; -+ struct GRUB_PACKED memmap_v1 { -+ grub_uint32_t memtype; -+ grub_uint64_t memstart; -+ grub_uint64_t memsize; -+ } map[GRUB_EFI_LOONGSON_MMAP_MAX]; -+}GRUB_PACKED -+mem_map_v1; -+ -+typedef struct { -+ ext_list header; //{VBIOS} -+ grub_uint64_t vbiosaddr; -+}GRUB_PACKED -+vbios; -+ -+grub_uint32_t -+EXPORT_FUNC (grub_efi_loongson_memmap_v1_sort) (struct memmap_v1 array[], -+ grub_uint32_t length, mem_map_v1 * mem, -+ grub_uint32_t index, grub_uint32_t memtype); -+#endif /* ! GRUB_EFI_LOONGSON_HEADER */ -diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h -new file mode 100644 -index 0000000..73641a1 ---- /dev/null -+++ b/include/grub/loongarch64/efi/memory.h -@@ -0,0 +1,12 @@ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#include -+ -+static inline grub_uint64_t -+grub_efi_max_usable_address(void) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ return addr |= 0xffffffffffUL; -+} -+ -+#endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/loongarch64/efi/time.h b/include/grub/loongarch64/efi/time.h -new file mode 100644 -index 0000000..e69de29 -diff --git a/include/grub/loongarch64/io.h b/include/grub/loongarch64/io.h -new file mode 100644 -index 0000000..5f34103 ---- /dev/null -+++ b/include/grub/loongarch64/io.h -@@ -0,0 +1,62 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 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 . -+ */ -+ -+#ifndef GRUB_IO_H -+#define GRUB_IO_H 1 -+ -+#include -+ -+typedef grub_addr_t grub_port_t; -+ -+static __inline unsigned char -+grub_inb (grub_port_t port) -+{ -+ return *(volatile grub_uint8_t *) port; -+} -+ -+static __inline unsigned short int -+grub_inw (grub_port_t port) -+{ -+ return *(volatile grub_uint16_t *) port; -+} -+ -+static __inline unsigned int -+grub_inl (grub_port_t port) -+{ -+ return *(volatile grub_uint32_t *) port; -+} -+ -+static __inline void -+grub_outb (unsigned char value, grub_port_t port) -+{ -+ *(volatile grub_uint8_t *) port = value; -+} -+ -+static __inline void -+grub_outw (unsigned short int value, grub_port_t port) -+{ -+ *(volatile grub_uint16_t *) port = value; -+} -+ -+static __inline void -+grub_outl (unsigned int value, grub_port_t port) -+{ -+ *(volatile grub_uint32_t *) port = value; -+} -+ -+#endif /* _SYS_IO_H */ -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -new file mode 100644 -index 0000000..3c6cf65 ---- /dev/null -+++ b/include/grub/loongarch64/linux.h -@@ -0,0 +1,74 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 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 . -+ */ -+ -+#ifndef GRUB_LOONGARCH64_LINUX_HEADER -+#define GRUB_LOONGARCH64_LINUX_HEADER 1 -+ -+#include -+ -+/* LoongArch linux kernel type */ -+#define GRUB_LOONGARCH_LINUX_BAD 0 -+#define GRUB_LOONGARCH_LINUX_ELF 1 -+#define GRUB_LOONGARCH_LINUX_EFI 2 -+ -+#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 -+ -+#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x4C6F6F6E67417263 /* 'LoongArc' */ -+#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE2 0x68 /* 'h' */ -+#define linux_arch_kernel_header linux_loongarch64_kernel_header -+ -+/* From linux/Documentation/loongarch/booting.txt -+ * -+ * 0-1: MZ -+ * 0x28: LoongArch\0 -+ * 0x3c: PE/COFF头偏移 -+ * 0x20e:内核版本号偏移-512 -+ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 -+ */ -+struct linux_loongarch64_kernel_header -+{ -+ grub_uint32_t code0; /* Executable code */ -+ grub_uint32_t code1; /* Executable code */ -+ grub_uint64_t text_offset; /* Image load offset */ -+ grub_uint64_t res0; /* reserved */ -+ grub_uint64_t res1; /* reserved */ -+ grub_uint64_t res2; /* reserved */ -+ grub_uint64_t magic; /* Magic number, little endian, "LoongArc" */ -+ grub_uint32_t magic1; /* Magic number, little endian, "h" */ -+ grub_uint64_t res3; /* reserved */ -+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -+}; -+ -+struct linux_loongarch64_kernel_params -+{ -+ grub_addr_t kernel_addr; /* kernel entry address */ -+ grub_size_t kernel_size; /* kernel size */ -+ grub_addr_t ramdisk_addr; /* initrd load address */ -+ grub_size_t ramdisk_size; /* initrd size */ -+ int linux_argc; -+ grub_addr_t linux_argv; -+ void* linux_args; -+}; -+ -+#include -+#include -+ -+#define ELF32_LOADMASK (0xf0000000UL) -+#define ELF64_LOADMASK (0xf000000000000000ULL) -+ -+#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ -diff --git a/include/grub/loongarch64/loongarch64.h b/include/grub/loongarch64/loongarch64.h -new file mode 100644 -index 0000000..ea3be3d ---- /dev/null -+++ b/include/grub/loongarch64/loongarch64.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2010,2017 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 . -+ */ -+ -+#ifndef GRUB_REGISTERS_CPU_HEADER -+#define GRUB_REGISTERS_CPU_HEADER 1 -+ -+#ifdef ASM_FILE -+#define GRUB_CPU_REGISTER_WRAP(x) x -+#else -+#define GRUB_CPU_REGISTER_WRAP(x) #x -+#endif -+ -+#define GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP(9) -+ -+#endif -diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h -new file mode 100644 -index 0000000..8281dab ---- /dev/null -+++ b/include/grub/loongarch64/memory.h -@@ -0,0 +1,60 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#define GRUB_MEMORY_CPU_HEADER 1 -+ -+#ifndef ASM_FILE -+#include -+#include -+#include -+#endif -+ -+#ifndef ASM_FILE -+ -+typedef grub_addr_t grub_phys_addr_t; -+ -+static inline grub_phys_addr_t -+grub_vtop (void *a) -+{ -+ if (-1 == ((grub_int64_t) a >> 32)) -+ return ((grub_phys_addr_t) a) & 0x1fffffffUL; -+ return ((grub_phys_addr_t) a) & 0xffffffffffffUL; -+} -+ -+static inline void * -+grub_map_memory (grub_phys_addr_t a, -+ grub_size_t size __attribute__ ((unused))) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) -+ return (void *) (a | (addr & 0xffffffffffffff00UL)); -+ else -+ return (void *) a; -+} -+ -+static inline void -+grub_unmap_memory (void *a __attribute__ ((unused)), -+ grub_size_t size __attribute__ ((unused))) -+{ -+} -+ -+#endif -+ -+#endif -diff --git a/include/grub/loongarch64/relocator.h b/include/grub/loongarch64/relocator.h -new file mode 100644 -index 0000000..8815314 ---- /dev/null -+++ b/include/grub/loongarch64/relocator.h -@@ -0,0 +1,38 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#ifndef GRUB_RELOCATOR_CPU_HEADER -+#define GRUB_RELOCATOR_CPU_HEADER 1 -+ -+#include -+#include -+#include -+ -+struct grub_relocator64_state -+{ -+ /* gpr[0] is ignored since it's hardwired to 0. */ -+ grub_uint64_t gpr[32]; -+ /* Register holding target $pc. */ -+ int jumpreg; -+}; -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state); -+ -+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ -diff --git a/include/grub/loongarch64/setjmp.h b/include/grub/loongarch64/setjmp.h -new file mode 100644 -index 0000000..d9a0776 ---- /dev/null -+++ b/include/grub/loongarch64/setjmp.h -@@ -0,0 +1,27 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2004,2006,2007,2009,2017 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 . -+ */ -+ -+#ifndef GRUB_SETJMP_CPU_HEADER -+#define GRUB_SETJMP_CPU_HEADER 1 -+ -+typedef grub_uint64_t grub_jmp_buf[12]; -+ -+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/loongarch64/time.h b/include/grub/loongarch64/time.h -new file mode 100644 -index 0000000..c9a7334 ---- /dev/null -+++ b/include/grub/loongarch64/time.h -@@ -0,0 +1,39 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2003,2004,2005,2007,2017 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 . -+ */ -+ -+#ifndef KERNEL_CPU_TIME_HEADER -+#define KERNEL_CPU_TIME_HEADER 1 -+ -+#ifndef GRUB_UTIL -+ -+#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) -+ -+void grub_timer_init (grub_uint32_t cpuclock); -+ -+/* Return the real time in ticks. */ -+grub_uint64_t grub_get_rtc (void); -+ -+extern grub_uint32_t grub_arch_cpuclock; -+#endif -+ -+static inline void -+grub_cpu_idle(void) -+{ -+} -+ -+#endif -diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h -new file mode 100644 -index 0000000..5dc7f21 ---- /dev/null -+++ b/include/grub/loongarch64/types.h -@@ -0,0 +1,34 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2006,2007,2009,2017 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 . -+ */ -+ -+#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 -+ -+#ifdef GRUB_CPU_LOONGARCH -+/* loongarch is little-endian. */ -+#undef GRUB_TARGET_WORDS_BIGENDIAN -+ -+#endif /* ! GRUB_TYPES_CPU_HEADER */ -+ -+#endif -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index dad1756..33feae9 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -107,6 +107,7 @@ enum grub_install_plat - GRUB_INSTALL_PLATFORM_X86_64_XEN, - GRUB_INSTALL_PLATFORM_ARM64_EFI, - GRUB_INSTALL_PLATFORM_ARM_COREBOOT, -+ GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, - GRUB_INSTALL_PLATFORM_MAX - }; - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index fde4ca7..6504637 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -738,27 +738,28 @@ static struct - const char *platform; - } platforms[GRUB_INSTALL_PLATFORM_MAX] = - { -- [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, -- [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, -- [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, -- [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, -- [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, -- [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, -- [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, -- [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, -- [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, -- [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, -- [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, -- [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, -- [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, -- [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, -- [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, -- [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, -- [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, -- [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, -- [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, -- [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, -- [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, -+ [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, -+ [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, -+ [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, -+ [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, -+ [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, -+ [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, -+ [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, -+ [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, -+ [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, -+ [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, -+ [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, -+ [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, -+ [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, -+ [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, -+ [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, -+ [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, -+ [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, -+ [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, -+ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, -+ [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, -+ [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, -+ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, - }; - - char * -diff --git a/util/grub-install.c b/util/grub-install.c -index 65bb2f9..28b5d74 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -322,6 +322,8 @@ get_default_platform (void) - return "arm-uboot"; - #elif defined (__aarch64__) - return "arm64-efi"; -+#elif defined (__loongarch64) -+ return "loongarch64-efi"; - #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) - return grub_install_get_default_x86_platform (); - #else -@@ -477,6 +479,7 @@ have_bootdev (enum grub_install_plat pl) - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: - case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: -@@ -895,6 +898,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_I386_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_X86_64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - is_efi = 1; - grub_util_error (_("this utility cannot be used for EFI platforms" - " because it does not support UEFI Secure Boot")); -@@ -921,6 +925,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: - case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: -@@ -965,6 +970,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_ARM_UBOOT: - case GRUB_INSTALL_PLATFORM_I386_QEMU: -@@ -1110,6 +1116,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - efi_file = "BOOTAA64.EFI"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "BOOTLOONGARCH64.EFI"; -+ break; - default: - grub_util_error ("%s", _("You've found a bug")); - break; -@@ -1137,6 +1146,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - efi_file = "grubaa64.efi"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "grubloongarch64.efi"; -+ break; - default: - efi_file = "grub.efi"; - break; -@@ -1440,6 +1452,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - g = grub_util_guess_efi_drive (*curdev); - break; - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: -@@ -1581,6 +1594,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - core_name = "core.efi"; - snprintf (mkimage_target, sizeof (mkimage_target), - "%s-%s", -@@ -1683,6 +1697,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: - case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: - case GRUB_INSTALL_PLATFORM_I386_COREBOOT: -@@ -1917,6 +1932,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM_EFI: - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - { - char *dst = grub_util_path_concat (2, efidir, efi_file); - grub_install_copy_file (imgfile, dst, 1); -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index 1bb5eb8..240e193 100644 ---- a/util/grub-mkimagexx.c -+++ b/util/grub-mkimagexx.c -@@ -783,6 +783,9 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, - struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); - grub_uint64_t *gpptr = (void *) (pe_target + got_off); - unsigned unmatched_adr_got_page = 0; -+ grub_uint64_t oprs[10240]= {0}; -+ int opri = -1; -+ grub_uint32_t la_abs = 0; - #define MASK19 ((1 << 19) - 1) - #else - grub_uint32_t *tr = (void *) (pe_target + tramp_off); -@@ -1122,6 +1125,173 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, - } - break; - } -+ case EM_LOONGARCH64: -+ { -+ sym_addr += addend; -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_64: -+ { -+ *target=(grub_uint64_t)sym_addr; -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ { -+ la_abs=1; -+ } -+ break; -+ case R_LARCH_SOP_PUSH_PCREL: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)(sym_addr-(target_section_addr+offset+image_target->vaddr_offset)); -+ } -+ break; -+ case R_LARCH_SOP_PUSH_ABSOLUTE: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)sym_addr; -+ } -+ break; -+ case R_LARCH_SOP_PUSH_PLT_PCREL: -+ { -+ opri++; -+ oprs[opri]=(grub_uint64_t)(sym_addr-(target_section_addr+offset+image_target->vaddr_offset)); -+ } -+ break; -+ case R_LARCH_SOP_SUB: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 - opr2; -+ } -+ break; -+ case R_LARCH_SOP_SL: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 << opr2; -+ } -+ break; -+ case R_LARCH_SOP_SR: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 >> opr2; -+ } -+ break; -+ case R_LARCH_SOP_ADD: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 + opr2; -+ } -+ break; -+ case R_LARCH_SOP_AND: -+ { -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ opri++; -+ oprs[opri]=opr1 & opr2; -+ } -+ break; -+ case R_LARCH_SOP_IF_ELSE: -+ { -+ grub_uint64_t opr3=oprs[opri]; -+ opri--; -+ grub_uint64_t opr2=oprs[opri]; -+ opri--; -+ grub_uint64_t opr1=oprs[opri]; -+ opri--; -+ if(opr1){ -+ opri++; -+ oprs[opri]=opr2; -+ } else { -+ opri++; -+ oprs[opri]=opr3; -+ } -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_5: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target=(*target) | ((opr1 & 0x1f) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_U_10_12: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target=(*target) | ((opr1 & 0xfff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_12: -+ { -+ if(la_abs==1) -+ la_abs=0; -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target = (*target) | ((opr1 & 0xfff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target = (*target) | ((opr1 & 0xffff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target = (*target) | (((opr1 >> 2) & 0xffff) << 10); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_5_20: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target = (*target) | ((opr1 & 0xfffff)<<5) ; -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target =(*target) | (((opr1 >> 2) & 0xffff) << 10); -+ *target =(*target) | ((opr1 >> 18) & 0x1f); -+ } -+ break; -+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: -+ { -+ grub_uint64_t opr1 = oprs[opri]; -+ opri--; -+ *target =(*target) | (((opr1 >> 2) & 0xffff) << 10); -+ *target =(*target) | ((opr1 >> 18) & 0x3ff); -+ } -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; -+ } - #endif - #if defined(MKIMAGE_ELF32) - case EM_ARM: -@@ -1310,7 +1480,10 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ -- b->page_rva = (addr & ~(0x1000 - 1)); -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (type) -+#endif -+ b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - -@@ -1320,7 +1493,11 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* Add a new entry. */ - cur_index = ((b->block_size - sizeof (*b)) >> 1); -+#ifdef GRUB_CPU_LOONGARCH64 -+ entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); -+#else - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); -+#endif - b->entries[cur_index] = grub_host_to_target16 (entry); - b->block_size += 2; - } -@@ -1366,6 +1543,10 @@ static void - translate_relocation_pe (struct translate_context *ctx, - Elf_Addr addr, - Elf_Addr info, -+#ifdef GRUB_CPU_LOONGARCH64 -+ Elf_Addr sym_addr, -+ Elf_Addr addend, -+#endif - const struct grub_install_image_target_desc *image_target) - { - /* Necessary to relocate only absolute addresses. */ -@@ -1477,6 +1658,133 @@ translate_relocation_pe (struct translate_context *ctx, - } - break; - break; -+ case EM_LOONGARCH64: -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_NONE: -+ break; -+ case R_LARCH_32: -+ break; -+ case R_LARCH_64: -+ { -+ ctx->current_address = add_fixup_entry ( -+ &ctx->lst, -+ GRUB_PE32_REL_BASED_DIR64, -+ addr, 0, ctx->current_address, -+ image_target); -+ } -+ break; -+ case R_LARCH_RELATIVE: -+ break; -+ case R_LARCH_COPY: -+ break; -+ case R_LARCH_JUMP_SLOT: -+ break; -+ case R_LARCH_TLS_DTPMOD32: -+ break; -+ case R_LARCH_TLS_DTPMOD64: -+ break; -+ case R_LARCH_TLS_DTPREL32: -+ break; -+ case R_LARCH_TLS_DTPREL64: -+ break; -+ case R_LARCH_TLS_TPREL32: -+ break; -+ case R_LARCH_TLS_TPREL64: -+ break; -+ case R_LARCH_IRELATIVE: -+ break; -+ case R_LARCH_MARK_LA: -+ { -+ ctx->current_address = add_fixup_entry ( -+ &ctx->lst, -+ GRUB_PE32_REL_BASED_LOONGARCH64, -+ addr, 0, ctx->current_address, -+ image_target); -+ } -+ break; -+ case R_LARCH_MARK_PCREL: -+ break; -+ case R_LARCH_SOP_PUSH_PCREL: -+ break; -+ case R_LARCH_SOP_PUSH_ABSOLUTE: -+ break; -+ case R_LARCH_SOP_PUSH_DUP: -+ break; -+ case R_LARCH_SOP_PUSH_GPREL: -+ break; -+ case R_LARCH_SOP_PUSH_TLS_TPREL: -+ break; -+ case R_LARCH_SOP_PUSH_TLS_GOT: -+ break; -+ case R_LARCH_SOP_PUSH_TLS_GD: -+ break; -+ case R_LARCH_SOP_PUSH_PLT_PCREL: -+ break; -+ case R_LARCH_SOP_ASSERT: -+ break; -+ case R_LARCH_SOP_NOT: -+ break; -+ case R_LARCH_SOP_SUB: -+ break; -+ case R_LARCH_SOP_SL: -+ break; -+ case R_LARCH_SOP_SR: -+ break; -+ case R_LARCH_SOP_ADD: -+ break; -+ case R_LARCH_SOP_AND: -+ break; -+ case R_LARCH_SOP_IF_ELSE: -+ break; -+ case R_LARCH_SOP_POP_32_S_10_5: -+ break; -+ case R_LARCH_SOP_POP_32_U_10_12: -+ break; -+ case R_LARCH_SOP_POP_32_S_10_12: -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16: -+ break; -+ case R_LARCH_SOP_POP_32_S_10_16_S2: -+ break; -+ case R_LARCH_SOP_POP_32_S_5_20: -+ break; -+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: -+ break; -+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: -+ break; -+ case R_LARCH_SOP_POP_32_U: -+ break; -+ case R_LARCH_ADD8: -+ break; -+ case R_LARCH_ADD16: -+ break; -+ case R_LARCH_ADD24: -+ break; -+ case R_LARCH_ADD32: -+ break; -+ case R_LARCH_ADD64: -+ break; -+ case R_LARCH_SUB8: -+ break; -+ case R_LARCH_SUB16: -+ break; -+ case R_LARCH_SUB24: -+ break; -+ case R_LARCH_SUB32: -+ break; -+ case R_LARCH_SUB64: -+ break; -+ case R_LARCH_GNU_VTINHERIT: -+ break; -+ case R_LARCH_GNU_VTENTRY: -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; - #if defined(MKIMAGE_ELF32) - case EM_ARM: - switch (ELF_R_TYPE (info)) -@@ -1565,10 +1873,18 @@ static void - translate_relocation (struct translate_context *ctx, - Elf_Addr addr, - Elf_Addr info, -+#ifdef GRUB_CPU_LOONGARCH64 -+ Elf_Addr sym_addr, -+ Elf_Addr addend, -+#endif - const struct grub_install_image_target_desc *image_target) - { - if (image_target->id == IMAGE_EFI) -+#ifdef GRUB_CPU_LOONGARCH64 -+ translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target); -+#else - translate_relocation_pe (ctx, addr, info, image_target); -+#endif - else - translate_relocation_raw (ctx, addr, info, image_target); - } -@@ -1709,11 +2025,21 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, - if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || - (grub_target_to_host32 (s->sh_type) == SHT_RELA)) - { -+#ifdef GRUB_CPU_LOONGARCH64 -+ Elf_Rela *r; -+#else - Elf_Rel *r; -+#endif - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; -+#ifdef GRUB_CPU_LOONGARCH64 -+ Elf_Shdr *symtab_section; -+ -+ symtab_section = (Elf_Shdr *) ((char *) smd->sections -+ + (grub_target_to_host32 (s->sh_link) * smd->section_entsize)); -+#endif - - if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd)) - { -@@ -1732,20 +2058,39 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, - - section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)]; - -+#ifdef GRUB_CPU_LOONGARCH64 -+ for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); -+ j < num_rs; -+ j++, r = (Elf_Rela *) ((char *) r + r_size)) -+#else - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) -+#endif - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr addr; -+#ifdef GRUB_CPU_LOONGARCH64 -+ Elf_Addr sym_addr; -+ Elf_Addr addend; -+#endif - - offset = grub_target_to_host (r->r_offset); - info = grub_target_to_host (r->r_info); -- -+#ifdef GRUB_CPU_LOONGARCH64 -+ sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, -+ ELF_R_SYM (info), image_target); -+ addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? -+ grub_target_to_host (r->r_addend) : 0; -+#endif - addr = section_address + offset; - -+#ifdef GRUB_CPU_LOONGARCH64 -+ translate_relocation (&ctx, addr, info, sym_addr, addend, image_target); -+#else - translate_relocation (&ctx, addr, info, image_target); -+#endif - } - } - -diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c -index ae31271..c998850 100644 ---- a/util/grub-mknetdir.c -+++ b/util/grub-mknetdir.c -@@ -112,7 +112,8 @@ static struct - [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, - [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, - [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }, -- [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" } -+ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }, -+ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64-efi", "efinet", ".efi" } - }; - - static void -diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c -index 03ba1ab..4a9943a 100644 ---- a/util/grub-module-verifier.c -+++ b/util/grub-module-verifier.c -@@ -119,6 +119,52 @@ struct grub_module_verifier_arch archs[] = { - -1 - } - }, -+ { "loongarch64", 8, 0, EM_LOONGARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ -+ R_LARCH_NONE, -+ R_LARCH_32, -+ R_LARCH_64, -+ R_LARCH_RELATIVE, -+ R_LARCH_COPY, -+ R_LARCH_JUMP_SLOT, -+ R_LARCH_TLS_DTPMOD32, -+ R_LARCH_TLS_DTPMOD64, -+ R_LARCH_TLS_DTPREL32, -+ R_LARCH_TLS_DTPREL64, -+ R_LARCH_TLS_TPREL32, -+ R_LARCH_TLS_TPREL64, -+ R_LARCH_IRELATIVE, -+ R_LARCH_MARK_LA, -+ R_LARCH_MARK_PCREL, -+ R_LARCH_SOP_PUSH_PCREL, -+ R_LARCH_SOP_PUSH_ABSOLUTE, -+ R_LARCH_SOP_PUSH_DUP, -+ R_LARCH_SOP_PUSH_GPREL, -+ R_LARCH_SOP_PUSH_TLS_TPREL, -+ R_LARCH_SOP_PUSH_TLS_GOT, -+ R_LARCH_SOP_PUSH_TLS_GD, -+ R_LARCH_SOP_PUSH_PLT_PCREL, -+ R_LARCH_SOP_ASSERT, -+ R_LARCH_SOP_NOT, -+ R_LARCH_SOP_SUB, -+ R_LARCH_SOP_SL, -+ R_LARCH_SOP_SR, -+ R_LARCH_SOP_ADD, -+ R_LARCH_SOP_AND, -+ R_LARCH_SOP_IF_ELSE, -+ R_LARCH_SOP_POP_32_S_10_5, -+ R_LARCH_SOP_POP_32_U_10_12, -+ R_LARCH_SOP_POP_32_S_10_12, -+ R_LARCH_SOP_POP_32_S_10_16, -+ R_LARCH_SOP_POP_32_S_10_16_S2, -+ R_LARCH_SOP_POP_32_S_5_20, -+ R_LARCH_SOP_POP_32_S_0_5_10_16_S2, -+ R_LARCH_SOP_POP_32_S_0_10_10_16_S2, -+ R_LARCH_SOP_POP_32_U, -+ -1 -+ }, (int[]){ -+ -1 -+ } -+ }, - }; - - struct platform_whitelist { -diff --git a/util/mkimage.c b/util/mkimage.c -index c770259..250ca81 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -609,6 +609,22 @@ static const struct grub_install_image_target_desc image_targets[] = - .pe_target = GRUB_PE32_MACHINE_ARM64, - .elf_target = EM_AARCH64, - }, -+ { -+ .dirname = "loongarch64-efi", -+ .names = { "loongarch64-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_LOONGARCH64, -+ .elf_target = EM_LOONGARCH64, -+ }, - }; - - #include --- -2.1.0 - diff --git a/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch b/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch deleted file mode 100644 index eb68c33..0000000 --- a/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch +++ /dev/null @@ -1,185 +0,0 @@ -From c0d084eeea91ae5e4a6509716f9055fb75da1e03 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Fri, 2 Sep 2022 15:24:10 +0800 -Subject: [PATCH] arm64: Fix EFI loader kernel image allocation - -backport from https://github.com/rhboot/grub2/ -commit/188f3f977341cdbd7ac582e794ca31c5415495ce - -Signed-off-by: Fedora Ninjas ---- - grub-core/loader/arm64/linux.c | 100 ++++++++++++++++++++++----------- - 1 file changed, 66 insertions(+), 34 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 37f5d0c..81261c0 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -41,6 +41,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - static grub_dl_t my_mod; - static int loaded; - -+static void *kernel_alloc_addr; -+static grub_uint32_t kernel_alloc_pages; - static void *kernel_addr; - static grub_uint64_t kernel_size; - static grub_uint32_t handover_offset; -@@ -229,9 +231,8 @@ grub_linux_unload (void) - GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); - initrd_start = initrd_end = 0; - grub_free (linux_args); -- if (kernel_addr) -- grub_efi_free_pages ((grub_addr_t) kernel_addr, -- GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -+ if (kernel_alloc_addr) -+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); - grub_fdt_unload (); - return GRUB_ERR_NONE; - } -@@ -336,14 +337,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - -+static grub_err_t -+parse_pe_header (void *kernel, grub_uint64_t *total_size, -+ grub_uint32_t *entry_offset, -+ grub_uint32_t *alignment) -+{ -+ struct linux_armxx_kernel_header *lh = kernel; -+ struct grub_armxx_linux_pe_header *pe; -+ -+ pe = (void *)((unsigned long)kernel + lh->hdr_offset); -+ -+ if (pe->opt.magic != GRUB_PE32_PE64_MAGIC) -+ return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic"); -+ -+ *total_size = pe->opt.image_size; -+ *entry_offset = pe->opt.entry_addr; -+ *alignment = pe->opt.section_alignment; -+ -+ return GRUB_ERR_NONE; -+} -+ - static grub_err_t - grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) - { - grub_file_t file = 0; -- struct linux_armxx_kernel_header lh; -- struct grub_armxx_linux_pe_header *pe; - int rc; -+ grub_off_t filelen; -+ grub_uint32_t align; -+ void *kernel = NULL; - grub_err_t err; - int nx_supported = 1; - -@@ -359,40 +381,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (!file) - goto fail; - -- kernel_size = grub_file_size (file); -- -- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) -- return grub_errno; -- -- if (grub_armxx_efi_linux_check_image (&lh) != GRUB_ERR_NONE) -- goto fail; -- -- grub_loader_unset(); -- -- grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); -- kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -- grub_dprintf ("linux", "kernel numpages: %lld\n", -- (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -- if (!kernel_addr) -+ filelen = grub_file_size (file); -+ kernel = grub_malloc(filelen); -+ if (!kernel) - { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer")); - goto fail; - } - -- grub_file_seek (file, 0); -- if (grub_file_read (file, kernel_addr, kernel_size) -- < (grub_int64_t) kernel_size) -+ if (grub_file_read (file, kernel, filelen) < (grub_ssize_t)filelen) - { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), -+ argv[0]); - goto fail; - } - -- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); -- - if (grub_efi_secure_boot ()) - { -- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -+ rc = grub_linuxefi_secure_validate (kernel, filelen); - if (rc <= 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, -@@ -405,8 +411,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (err != GRUB_ERR_NONE) - goto fail; - -- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); -- handover_offset = pe->opt.entry_addr; -+ if (grub_armxx_efi_linux_check_image (kernel) != GRUB_ERR_NONE) -+ goto fail; -+ if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align) != GRUB_ERR_NONE) -+ goto fail; -+ grub_dprintf ("linux", "kernel mem size : %lld\n", (long long) kernel_size); -+ grub_dprintf ("linux", "kernel entry offset : %d\n", handover_offset); -+ grub_dprintf ("linux", "kernel alignment : 0x%x\n", align); -+ -+ grub_loader_unset(); -+ -+ kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1); -+ kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages); -+ grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages); -+ if (!kernel_alloc_addr) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ kernel_addr = (void *)ALIGN_UP((grub_uint64_t)kernel_alloc_addr, align); -+ -+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); -+ grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)); -+ if (kernel_size > filelen) -+ grub_memset ((char *)kernel_addr + filelen, 0, kernel_size - filelen); -+ grub_free(kernel); -+ kernel = NULL; - - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); - linux_args = grub_malloc (cmdline_size); -@@ -430,6 +460,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - fail: -+ if (kernel) -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - -@@ -442,9 +475,8 @@ fail: - if (linux_args && !loaded) - grub_free (linux_args); - -- if (kernel_addr && !loaded) -- grub_efi_free_pages ((grub_addr_t) kernel_addr, -- GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -+ if (kernel_alloc_addr && !loaded) -+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); - - return grub_errno; - } --- -2.27.0 - diff --git a/20-grub.install b/20-grub.install index a05c15c..9b74538 100755 --- a/20-grub.install +++ b/20-grub.install @@ -62,7 +62,7 @@ case "$COMMAND" in "$KERNEL_DIR"/dtb do [[ -e "$i" ]] || continue - rm -rf "/boot/${i##*/}-${KERNEL_VERSION}" + rm -f "/boot/${i##*/}-${KERNEL_VERSION}" cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}" command -v restorecon &>/dev/null && \ restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}" diff --git a/dist b/dist new file mode 100644 index 0000000..535c690 --- /dev/null +++ b/dist @@ -0,0 +1 @@ +an8_7 diff --git a/grub.macros b/grub.macros index c610494..c9ed442 100644 --- a/grub.macros +++ b/grub.macros @@ -92,7 +92,7 @@ %endif -%global efi_only aarch64 %{arm} loongarch64 +%global efi_only aarch64 %{arm} %global efi_arch x86_64 ia64 %{efi_only} %ifarch %{efi_arch} %global with_efi_arch 1 @@ -122,7 +122,7 @@ %global platform_modules " appendedsig " %endif -%ifarch aarch64 %{arm} loongarch64 +%ifarch aarch64 %{arm} %global platform_modules " " %endif @@ -187,14 +187,6 @@ )} %endif -%ifarch loongarch64 -%global with_emu_arch 0 -%global efiarch loongarch64 -%global target_cpu_name loongarch64 -%global grub_target_name loongarch64-efi -%global package_arch efi-loongarch64 -%endif - %global _target_platform %{target_cpu_name}-%{_vendor}-%{_target_os}%{?_gnu} %global _alt_target_platform %{alt_target_cpu_name}-%{_vendor}-%{_target_os}%{?_gnu} @@ -230,7 +222,7 @@ %ifarch x86_64 %global with_efi_common 1 -%global with_legacy_modules 1 +%global with_legacy_modules 0 %global with_legacy_common 0 %else %global with_efi_common 0 @@ -387,11 +379,11 @@ for x in grub-mkimage ; do \\\ done \ %{nil} -%global grub_modules " all_video boot blscfg \\\ +%global grub_modules " all_video boot blscfg \\\ cat configfile cryptodisk echo ext2 \\\ fat font gcry_rijndael gcry_rsa gcry_serpent \\\ gcry_sha256 gcry_twofish gcry_whirlpool \\\ - gfxmenu gfxterm gzio halt http \\\ + gfxmenu gfxterm gzio halt http \\\ increment iso9660 jpeg loadenv loopback linux \\\ lvm luks mdraid09 mdraid1x minicmd net \\\ normal part_apple part_msdos part_gpt \\\ @@ -604,7 +596,7 @@ touch ${RPM_BUILD_ROOT}/boot/%{name}/grub.cfg \ %{expand:%%files %{1}} \ %defattr(-,root,root,-) \ %config(noreplace) %{_sysconfdir}/%{name}.cfg \ -%ghost %config(noreplace) /boot/%{name}/grub.cfg \ +%ghost %config(noreplace) %attr(0700,root,root)/boot/%{name}/grub.cfg \ %dir %attr(0700,root,root)/boot/loader/entries \ %ifarch ppc64le \ %dir %{_libdir}/grub/%{2}/ \ diff --git a/grub.patches b/grub.patches index 4bc33e8..373afa7 100644 --- a/grub.patches +++ b/grub.patches @@ -498,55 +498,76 @@ Patch0497: 0497-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch Patch0498: 0498-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch Patch0499: 0499-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch Patch0500: 0500-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch -Patch0501: 0501-loader-efi-chainloader-grub_load_and_start_image-doe.patch -Patch0502: 0502-loader-efi-chainloader-simplify-the-loader-state.patch -Patch0503: 0503-commands-boot-Add-API-to-pass-context-to-loader.patch -Patch0504: 0504-loader-efi-chainloader-Use-grub_loader_set_ex.patch -Patch0505: 0505-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch -Patch0506: 0506-loader-i386-efi-linux-Use-grub_loader_set_ex.patch -Patch0507: 0507-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch -Patch0508: 0508-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch -Patch0509: 0509-video-readers-png-Abort-sooner-if-a-read-operation-f.patch -Patch0510: 0510-video-readers-png-Refuse-to-handle-multiple-image-he.patch -Patch0511: 0511-video-readers-png-Drop-greyscale-support-to-fix-heap.patch -Patch0512: 0512-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch -Patch0513: 0513-video-readers-png-Sanity-check-some-huffman-codes.patch -Patch0514: 0514-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch -Patch0515: 0515-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch -Patch0516: 0516-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch -Patch0517: 0517-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch -Patch0518: 0518-normal-charset-Fix-array-out-of-bounds-formatting-un.patch -Patch0519: 0519-net-netbuff-Block-overly-large-netbuff-allocs.patch -Patch0520: 0520-net-ip-Do-IP-fragment-maths-safely.patch -Patch0521: 0521-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch -Patch0522: 0522-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch -Patch0523: 0523-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch -Patch0524: 0524-misc-Format-string-for-grub_error-should-be-a-litera.patch -Patch0525: 0525-net-tftp-Avoid-a-trivial-UAF.patch -Patch0526: 0526-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch -Patch0527: 0527-net-http-Fix-OOB-write-for-split-http-headers.patch -Patch0528: 0528-net-http-Error-out-on-headers-with-LF-without-CR.patch -Patch0529: 0529-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch -Patch0530: 0530-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch -Patch0531: 0531-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch -Patch0532: 0532-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch -Patch0533: 0533-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch -Patch0534: 0534-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch -Patch0535: 0535-Define-GRUB_EFI_SHIM_LOCK_GUID.patch -Patch0536: 0536-misc-Make-grub_min-and-grub_max-more-resilient.patch -Patch0537: 0537-ReiserFS-switch-to-using-grub_min-grub_max.patch -Patch0538: 0538-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch -Patch0539: 0539-modules-make-.module_license-read-only.patch -Patch0540: 0540-modules-strip-.llvm_addrsig-sections-and-similar.patch -Patch0541: 0541-modules-Don-t-allocate-space-for-non-allocable-secti.patch -Patch0542: 0542-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch -Patch0543: 0543-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch -Patch0544: 0544-modules-load-module-sections-at-page-aligned-address.patch -Patch0545: 0545-nx-add-memory-attribute-get-set-API.patch -Patch0546: 0546-nx-set-page-permissions-for-loaded-modules.patch -Patch0547: 0547-nx-set-attrs-in-our-kernel-loaders.patch -Patch0548: 0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch -Patch0549: 0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch -Patch1001: 1001-bls-make-list.patch -Patch1002: 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch -Patch1003: 1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch +Patch0501: 0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch +Patch0502: 0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch +Patch0503: 0503-powerpc-do-CAS-in-a-more-compatible-way.patch +Patch0504: 0504-powerpc-prefix-detection-support-device-names-with-c.patch +Patch0505: 0505-make-ofdisk_retries-optional.patch +Patch0506: 0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch +Patch0507: 0507-loader-efi-chainloader-simplify-the-loader-state.patch +Patch0508: 0508-commands-boot-Add-API-to-pass-context-to-loader.patch +Patch0509: 0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch +Patch0510: 0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch +Patch0511: 0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch +Patch0512: 0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch +Patch0513: 0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch +Patch0514: 0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch +Patch0515: 0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch +Patch0516: 0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +Patch0517: 0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +Patch0518: 0518-video-readers-png-Sanity-check-some-huffman-codes.patch +Patch0519: 0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch +Patch0520: 0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch +Patch0521: 0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch +Patch0522: 0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +Patch0523: 0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch +Patch0524: 0524-net-netbuff-Block-overly-large-netbuff-allocs.patch +Patch0525: 0525-net-ip-Do-IP-fragment-maths-safely.patch +Patch0526: 0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch +Patch0527: 0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch +Patch0528: 0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch +Patch0529: 0529-misc-Format-string-for-grub_error-should-be-a-litera.patch +Patch0530: 0530-net-tftp-Avoid-a-trivial-UAF.patch +Patch0531: 0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch +Patch0532: 0532-net-http-Fix-OOB-write-for-split-http-headers.patch +Patch0533: 0533-net-http-Error-out-on-headers-with-LF-without-CR.patch +Patch0534: 0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch +Patch0535: 0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch +Patch0536: 0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch +Patch0537: 0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch +Patch0538: 0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch +Patch0539: 0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch +Patch0540: 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch +Patch0541: 0541-misc-Make-grub_min-and-grub_max-more-resilient.patch +Patch0542: 0542-ReiserFS-switch-to-using-grub_min-grub_max.patch +Patch0543: 0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch +Patch0544: 0544-modules-make-.module_license-read-only.patch +Patch0545: 0545-modules-strip-.llvm_addrsig-sections-and-similar.patch +Patch0546: 0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch +Patch0547: 0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch +Patch0548: 0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch +Patch0549: 0549-modules-load-module-sections-at-page-aligned-address.patch +Patch0550: 0550-nx-add-memory-attribute-get-set-API.patch +Patch0551: 0551-nx-set-page-permissions-for-loaded-modules.patch +Patch0552: 0552-nx-set-attrs-in-our-kernel-loaders.patch +Patch0553: 0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch +Patch0554: 0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch +Patch0555: 0555-Make-debug-file-show-which-file-filters-get-run.patch +Patch0556: 0556-efi-use-enumerated-array-positions-for-our-allocatio.patch +Patch0557: 0557-efi-split-allocation-policy-for-kernel-vs-initrd-mem.patch +Patch0558: 0558-efi-use-EFI_LOADER_-CODE-DATA-for-kernel-and-initrd-.patch +Patch0559: 0559-ieee1275-implement-vec5-for-cas-negotiation.patch +Patch0560: 0560-x86-efi-Fix-an-incorrect-array-size-in-kernel-alloca.patch +Patch0561: 0561-switch-to-blscfg-don-t-assume-newline-at-end-of-cfg.patch +Patch0562: 0562-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch +Patch0563: 0563-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch +Patch0564: 0564-font-Fix-several-integer-overflows-in-grub_font_cons.patch +Patch0565: 0565-font-Remove-grub_font_dup_glyph.patch +Patch0566: 0566-font-Fix-integer-overflow-in-ensure_comb_space.patch +Patch0567: 0567-font-Fix-integer-overflow-in-BMP-index.patch +Patch0568: 0568-font-Fix-integer-underflow-in-binary-search-of-char-.patch +Patch0569: 0569-fbutil-Fix-integer-overflow.patch +Patch0570: 0570-font-Fix-an-integer-underflow-in-blit_comb.patch +Patch0571: 0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch +Patch0572: 0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch +Patch0573: 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch diff --git a/grub2.spec b/grub2.spec index 5db14b9..a76b3bc 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,18 +1,13 @@ -%define anolis_release .0.3 %undefine _hardened_build %global tarversion 2.02 %undefine _missing_build_ids_terminate_build %global _configure_gnuconfig_hack 0 -%ifarch loongarch64 -%global _configure_gnuconfig_hack 1 -%endif - Name: grub2 Epoch: 1 Version: 2.02 -Release: 123%{anolis_release}%{?dist}.8 +Release: 142%{?dist}.1 Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base License: GPLv3+ @@ -33,8 +28,8 @@ Source13: redhatsecurebootca3.cer Source14: redhatsecureboot301.cer Source15: redhatsecurebootca5.cer Source16: redhatsecureboot502.cer -Source17: redhatsecureboot303.cer -Source18: redhatsecureboot601.cer +Source17: redhatsecureboot601.cer +Source18: redhatsecureboot701.cer Source19: sbat.csv.in %include %{SOURCE1} @@ -51,7 +46,7 @@ Source19: sbat.csv.in %ifarch ppc64le %define old_sb_cer %{SOURCE17} %define sb_cer %{SOURCE18} -%define sb_key redhatsecureboot602 +%define sb_key redhatsecureboot702 %endif # generate with do-rebase @@ -119,7 +114,7 @@ Requires(post): dracut %{desc} This subpackage provides tools for support of all platforms. -%ifarch x86_64 loongarch64 +%ifarch x86_64 %package tools-efi Summary: Support tools for GRUB. Group: System Environment/Base @@ -189,11 +184,6 @@ git add grub-%{grublegacyarch}-%{tarversion} %endif git commit -m "After making subdirs" -%ifarch loongarch64 -%_update_config_sub -%_update_config_guess -%endif - %build %if 0%{with_efi_arch} %{expand:%do_primary_efi_build %%{grubefiarch} %%{grubefiname} %%{grubeficdname} %%{_target_platform} %%{efi_target_cflags} %%{efi_host_cflags} %{old_sb_ca} %{old_sb_cer} %{old_sb_key} %{sb_ca} %{sb_cer} %{sb_key}} @@ -235,11 +225,8 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir ln -s %{name}-set-password ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-setpassword echo '.so man8/%{name}-set-password.8' > ${RPM_BUILD_ROOT}/%{_datadir}/man/man8/%{name}-setpassword.8 %ifnarch x86_64 -rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-bios-setup -%endif - -%ifnarch x86_64 loongarch64 rm -vf ${RPM_BUILD_ROOT}/%{_bindir}/%{name}-render-label +rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-bios-setup rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-macbless %endif @@ -399,7 +386,7 @@ fi %{_datadir}/man/man1/%{name}-editenv* %{_datadir}/man/man1/%{name}-mkpasswd-* -%ifarch x86_64 loongarch64 +%ifarch x86_64 %files tools-efi %{_sbindir}/%{name}-macbless %{_bindir}/%{name}-render-label @@ -523,43 +510,68 @@ fi %endif %changelog -* Fri Sep 2 2022 Liwei Ge - 2.02-123.0.3.8 -- arm64: Fix EFI loader kernel image allocation +* Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 +- Sync with 8.8 (actually 2.02-145) +- Resolves: CVE-2022-2601 + +* Thu Sep 08 2022 Robbie Harwood - 2.02-142 +- Drop the arena size changes +- Resolves: #2118896 + +* Thu Aug 25 2022 Robbie Harwood - 2.02-141 +- Implement vec5 for cas negotiation +- Resolves: #2117914 + +* Wed Aug 24 2022 Robbie Harwood - 2.02-140 +- Or two, because I forgot the debug patch +- Resolves: #2118896 -* Thu Jul 7 2022 QiMing Yang - 2.02-123.0.2.8 -- Delete LoongArch64 support old version due to compile error -- Add LoongArch64 support -- LoongArch64 support fdt and phy-addr BIOS -- Remove dtb dir with correct argument (Liwei Ge) +* Thu Aug 18 2022 Robbie Harwood - 2.02-139 +- Kernel allocator fixups (in one pass) +- Resolves: #2118896 -* Fri Jun 17 2022 Bo Ren - 2.02-123.0.1.8 -- Build pc-modules package on x86_64 (geliwei@openanolis.org) -- Add loongarch64 base support (zhangwenlong@loongson.cn)(chenguoqi@loongson.cn) -- Fix a bug in bls_make_list, blscfg. (zhonglingh@linux.alibaba.com) +* Wed Jul 20 2022 Robbie Harwood - 2.02-138 +- Rotate signing keys on ppc64le +- Resolves: #2074762 -* Fri Jun 03 2022 Robbie Harwood - 2.06-123.el8_6.8 +* Fri Jun 03 2022 Robbie Harwood - 2.02-137 - CVE fixes for 2022-06-07 - CVE-2022-28736 CVE-2022-28735 CVE-2022-28734 CVE-2022-28733 - CVE-2021-3697 CVE-2021-3696 CVE-2021-3695 -- Resolves: #2031899 +- Resolves: #2070687 + +* Mon May 16 2022 Robbie Harwood - 2.02-129 +- ppc64le: Slow boot after LPM +- Resolves: #2070347 + +* Wed May 04 2022 Robbie Harwood - 2.02-127 +- ppc64le: CAS improvements, prefix detection, and vTPM support +- Resolves: #2076795 +- Resolves: #2026568 +- Resolves: #2051331 + +* Wed May 04 2022 Robbie Harwood - 2.02-126 +- Fix rpm verification error on grub.cfg permissions +- Resolves: #2071643 + +* Wed Apr 20 2022 Robbie Harwood - 2.02-125 +- RHEL 8.6.0 import; no code changes +- Resolves: #2062892 -* Mon Mar 28 2022 Robbie Harwood - 2.06-123 +* Mon Mar 28 2022 Robbie Harwood - 2.02-123 - Bump for signing -- Resolves: #2061252 -* Wed Mar 09 2022 Robbie Harwood - 2.06-122 +* Wed Mar 09 2022 Robbie Harwood - 2.02-122 - Fix initialization on efidisk patch -- Resolves: #2061252 -* Tue Mar 08 2022 Robbie Harwood - 2.06-121 +* Tue Mar 08 2022 Robbie Harwood - 2.02-121 - Backport support for loading initrd above 4GB -- Resolves: #2048433 -* Mon Feb 28 2022 Robbie Harwood - 2.06-120 +* Mon Feb 28 2022 Robbie Harwood - 2.02-120 - Bump signing - Resolves: #2032294 -* Mon Feb 28 2022 Robbie Harwood - 2.06-119 +* Mon Feb 28 2022 Robbie Harwood - 2.02-119 - Enable connectefi module - Resolves: #2032294 diff --git a/redhatsecureboot303.cer b/redhatsecureboot303.cer deleted file mode 100644 index 2c0087dbc5da376aef641bb23833401857c34940..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 899 zcmXqLVy-u6VoG1Y%*4pV#L4h}zvyHQr&GoTylk9WZ60mkc^MhGSs4s`4b=@)*_cCF zn1$tnQd1N>5=#_OQj1C) zic(WD5=-=w^K%X4#CZ)Z4a^Ko3@l8IOe~_rd5tX$3=NE+T!SD(9Rn?}bv(*gtt-w< z&&$k92is{(oSjXKO31!qWMyD(V&rEqXkz4IYGPz$II>2G|M$FqPFt5GY@Z}j_wdcG z>qlNkR*SLi2#vh>#O(I_Wno7c`4SC2=y=Zd`<9;a@{@2)?V*sz8{HTFd-E&#gtt#; zUgHuWz1pJ-y#K9{o_n?Q@4oA|9nu>-nGU?#lm1zM!m(4+W^!G6o63L4^zhgAs4rhs zUmj^WrxfJ3J}dJeuq`Lta*xk?}tZlL3PPH;Bj2!otkN-e4dL;_$JEv50IdKm9LW&^Yn$5_R6=HKv!R z$vZ?D$b+PnStJa^8bln#TEtw=Sv9h7u(GGU__1hC>W>)Y2mmH4U<5ES#PkO5sC<9x z!JKt`$32eKDcv>kntnv_@NIu_U*Q=Xk1EvP<=w1`yP>!G=8u`mTv|szZevQCch1^& z!q2ncK3iyARETApaF1br*%L8#fw_eaRczCW1C=8SIyp9OHWxSD>F|+J;%msh6TGS4 z7i9eW_V~}UtyNmb|NVAU_`StO+3?O0&CipWay2jh-RRBjrY}Bi{e-UnA#J9g_4+s? zD*o^EabCXQ^?4Wm+_igF-`xN2a7LS$!jkBBmcGB8+wcBUs^a;5FNJd^r+L3*+)39L zjQ8{>JTSZxpz7w(F!4!Co|pZnnG+e$u$S(t-F5BW&3P{?riLzZE|e}c7rGqT{#S2( H=YvQ9de&%$ diff --git a/redhatsecureboot701.cer b/redhatsecureboot701.cer new file mode 100644 index 0000000000000000000000000000000000000000..25e3743e47c3c1f06da0124a1d99e99e4920f6e7 GIT binary patch literal 916 zcmXqLVxC~o#8k0>nTe5!iId@pypfsK^#n41{+84Q{jxtN+585ynxiti9Hzr++{YFiX}{@nDZ%!WV8j3UD8 zZ+!lKjZO1y#-iirm+g-*`lJ<_aM|wiv%8TJnzQ!ssVaZm*kb4QPDg$M*B3_rD>p7% z?kp3_`l%Ar=Hn_UygBpZEbi)Ej8jc|c~`Do@=M>(-s$x6M`x*I82hq3^kj zzuK$&zt%X$xEUWcHLYq&I>7dM`!bUmYMbq*C9;>wz4$bJrJ2L!EH9x2*$dfwGPGu! z{Wi>7Cb@4_kMxc`jGwn$@9lan`0s9L(CJAVx;#y9x!n46o{5=}fpKw#L74#$Fw|v* z85#exFc~ly@PT;zARY@d6MKV!7>KV5;`11Av2kd#F|x9z^TJke=Yf+TuQImK*!64p6$GYbw=2q@m%cdpg{kMBT+r(Ch*_zS5 zA5Nx}NPA6rc(7rbaoFblPiE%v-1)WHp{F9M%kPns%89$*zq+znD|%ZCrmwr|cKX<| Tt1h>T)0Nk#SZ8pFAMXMHU|?Vk literal 0 HcmV?d00001 diff --git a/sbat.csv.in b/sbat.csv.in index 55b3d10..b338b5f 100755 --- a/sbat.csv.in +++ b/sbat.csv.in @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -grub,2,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/ +grub,3,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/ grub.rh,2,Red Hat,grub2,@@VERSION_RELEASE@@,mailto:secalert@redhat.com -- Gitee From fa48c25a011399a0b1cd491a8430b977ef1cb965 Mon Sep 17 00:00:00 2001 From: songmingliang Date: Tue, 17 May 2022 18:12:12 +0800 Subject: [PATCH 2/6] build: build pc-modules package on x86_64 --- grub.macros | 2 +- grub2.spec | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/grub.macros b/grub.macros index c9ed442..8d0205d 100644 --- a/grub.macros +++ b/grub.macros @@ -222,7 +222,7 @@ %ifarch x86_64 %global with_efi_common 1 -%global with_legacy_modules 0 +%global with_legacy_modules 1 %global with_legacy_common 0 %else %global with_efi_common 0 diff --git a/grub2.spec b/grub2.spec index a76b3bc..3daebd3 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 %undefine _hardened_build %global tarversion 2.02 @@ -7,7 +8,7 @@ Name: grub2 Epoch: 1 Version: 2.02 -Release: 142%{?dist}.1 +Release: 142%{anolis_release}%{?dist}.1 Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base License: GPLv3+ @@ -510,6 +511,9 @@ fi %endif %changelog +* Tue Jan 10 2023 Bo Ren - 2.02-142.0.1.1 +- Build pc-modules package on x86_64 (geliwei@openanolis.org) + * Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 - Sync with 8.8 (actually 2.02-145) - Resolves: CVE-2022-2601 -- Gitee From 7c342477d190b467e01c84fef7510f41e596bf6d Mon Sep 17 00:00:00 2001 From: songmingliang Date: Tue, 17 May 2022 18:43:45 +0800 Subject: [PATCH 3/6] Add loongarch64 base support --- 1000-loongarch64-add-support.patch | 3968 ++++++++++++++++++++++++++++ grub.macros | 12 +- grub.patches | 2 + grub2.spec | 19 +- 4 files changed, 3996 insertions(+), 5 deletions(-) create mode 100644 1000-loongarch64-add-support.patch diff --git a/1000-loongarch64-add-support.patch b/1000-loongarch64-add-support.patch new file mode 100644 index 0000000..2d83c94 --- /dev/null +++ b/1000-loongarch64-add-support.patch @@ -0,0 +1,3968 @@ +From febee03c70471fd2ce6f0b4cc0f365c32c106ab3 Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Wed, 18 May 2022 23:50:45 +0800 +Subject: [PATCH] add loongarch64 support + +--- + conf/Makefile.common | 4 + + configure.ac | 9 + + gentpl.py | 5 +- + grub-core/Makefile.am | 7 + + grub-core/Makefile.core.def | 20 + + grub-core/kern/efi/mm.c | 29 +- + grub-core/kern/elfXX.c | 6 + + grub-core/kern/loongarch64/cache.S | 26 + + grub-core/kern/loongarch64/dl.c | 258 +++++++++ + grub-core/kern/loongarch64/efi/init.c | 76 +++ + grub-core/kern/loongarch64/efi/startup.S | 45 ++ + grub-core/kern/loongarch64/init.c | 47 ++ + grub-core/lib/loongarch64/efi/loongson.c | 505 ++++++++++++++++ + grub-core/lib/loongarch64/efi/loongson_asm.S | 58 ++ + grub-core/lib/loongarch64/relocator.c | 163 ++++++ + grub-core/lib/loongarch64/relocator_asm.S | 51 ++ + grub-core/lib/loongarch64/setjmp.S | 74 +++ + grub-core/lib/loongson/reboot.c | 33 ++ + grub-core/lib/setjmp.S | 2 + + grub-core/loader/efi/chainloader.c | 2 + + grub-core/loader/loongarch64/linux.c | 580 +++++++++++++++++++ + include/grub/dl.h | 2 +- + include/grub/efi/api.h | 3 +- + include/grub/efi/pe32.h | 2 + + include/grub/elf.h | 55 ++ + include/grub/loongarch64/asm.h | 10 + + include/grub/loongarch64/efi/boot.h | 0 + include/grub/loongarch64/efi/loader.h | 25 + + include/grub/loongarch64/efi/loongson.h | 290 ++++++++++ + include/grub/loongarch64/efi/memory.h | 14 + + include/grub/loongarch64/efi/time.h | 0 + include/grub/loongarch64/io.h | 62 ++ + include/grub/loongarch64/kernel.h | 24 + + include/grub/loongarch64/linux.h | 22 + + include/grub/loongarch64/loongarch64.h | 30 + + include/grub/loongarch64/memory.h | 57 ++ + include/grub/loongarch64/relocator.h | 38 ++ + include/grub/loongarch64/setjmp.h | 27 + + include/grub/loongarch64/time.h | 39 ++ + include/grub/loongarch64/types.h | 34 ++ + include/grub/util/install.h | 1 + + util/grub-install-common.c | 43 +- + util/grub-install.c | 16 + + util/grub-mkimagexx.c | 349 ++++++++++- + util/grub-mknetdir.c | 3 +- + util/grub-module-verifier.c | 46 ++ + util/mkimage.c | 16 + + 47 files changed, 3176 insertions(+), 32 deletions(-) + create mode 100644 grub-core/kern/loongarch64/cache.S + create mode 100644 grub-core/kern/loongarch64/dl.c + create mode 100644 grub-core/kern/loongarch64/efi/init.c + create mode 100644 grub-core/kern/loongarch64/efi/startup.S + create mode 100644 grub-core/kern/loongarch64/init.c + create mode 100644 grub-core/lib/loongarch64/efi/loongson.c + create mode 100644 grub-core/lib/loongarch64/efi/loongson_asm.S + create mode 100644 grub-core/lib/loongarch64/relocator.c + create mode 100644 grub-core/lib/loongarch64/relocator_asm.S + create mode 100644 grub-core/lib/loongarch64/setjmp.S + create mode 100644 grub-core/lib/loongson/reboot.c + create mode 100644 grub-core/loader/loongarch64/linux.c + create mode 100644 include/grub/loongarch64/asm.h + create mode 100644 include/grub/loongarch64/efi/boot.h + create mode 100644 include/grub/loongarch64/efi/loader.h + create mode 100644 include/grub/loongarch64/efi/loongson.h + create mode 100644 include/grub/loongarch64/efi/memory.h + create mode 100644 include/grub/loongarch64/efi/time.h + create mode 100644 include/grub/loongarch64/io.h + create mode 100644 include/grub/loongarch64/kernel.h + create mode 100644 include/grub/loongarch64/linux.h + create mode 100644 include/grub/loongarch64/loongarch64.h + create mode 100644 include/grub/loongarch64/memory.h + create mode 100644 include/grub/loongarch64/relocator.h + create mode 100644 include/grub/loongarch64/setjmp.h + create mode 100644 include/grub/loongarch64/time.h + create mode 100644 include/grub/loongarch64/types.h + +diff --git a/conf/Makefile.common b/conf/Makefile.common +index 521cdda..cc1d190 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -20,6 +20,10 @@ endif + if COND_powerpc_ieee1275 + CFLAGS_PLATFORM += -mcpu=powerpc + endif ++if COND_loongarch64 ++ CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel ++ CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel ++endif + + # Other options + +diff --git a/configure.ac b/configure.ac +index f59a7b8..4715d17 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -116,6 +116,10 @@ case "$target_cpu" in + i[[3456]]86) target_cpu=i386 ;; + amd64) target_cpu=x86_64 ;; + sparc) target_cpu=sparc64 ;; ++ loongarch64) ++ target_cpu=loongarch64 ++ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_LOONGARCH64=1" ++ ;; + mipsel|mips64el) + target_cpu=mipsel + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1" +@@ -148,6 +152,7 @@ if test "x$with_platform" = x; then + powerpc64-*) platform=ieee1275 ;; + powerpc64le-*) platform=ieee1275 ;; + sparc64-*) platform=ieee1275 ;; ++ loongarch64-*) platform=efi;; + mipsel-*) platform=loongson ;; + mips-*) platform=arc ;; + ia64-*) platform=efi ;; +@@ -196,6 +201,7 @@ case "$target_cpu"-"$platform" in + mipsel-yeeloong) platform=loongson ;; + mipsel-fuloong) platform=loongson ;; + mipsel-loongson) ;; ++ loongarch64-efi) ;; + arm-uboot) ;; + arm-coreboot) ;; + arm-efi) ;; +@@ -251,6 +257,7 @@ case "$platform" in + pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; + emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; + loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; ++ loongson64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_LOONARCH64=1" ;; + qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; + arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; + esac +@@ -2098,6 +2105,8 @@ AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = + 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_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) ++AM_CONDITIONAL([COND_loongarch64_efi], [test x$target_cpu = xloongarch64 -a x$platform = xefi]) ++AM_CONDITIONAL([COND_loongarch64], [test x$target_cpu = xloongarch64]) + AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) + AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) + AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) +diff --git a/gentpl.py b/gentpl.py +index d662c30..3afd642 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -32,7 +32,7 @@ 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"] ++ "arm_coreboot", "loongarch64_efi"] + + GROUPS = {} + +@@ -44,13 +44,14 @@ GROUPS["x86_64"] = [ "x86_64_efi" ] + GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] + GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] + GROUPS["sparc64"] = [ "sparc64_ieee1275" ] ++GROUPS["loongarch64"] = [ "loongarch64_efi" ] + GROUPS["powerpc"] = [ "powerpc_ieee1275" ] + GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] + GROUPS["arm64"] = [ "arm64_efi" ] + + # Groups based on firmware + GROUPS["pc"] = [ "i386_pc" ] +-GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ] ++GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "loongarch64_efi"] + GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] + GROUPS["uboot"] = [ "arm_uboot" ] + GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 308ad88..24e2ac3 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -222,6 +222,13 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + endif + ++if COND_loongarch64_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/acpi.h ++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h ++endif ++ + if COND_powerpc_ieee1275 + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index ef06f8c..74e66d3 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -95,6 +95,9 @@ kernel = { + arm_coreboot_ldflags = '-Wl,-r,-d'; + arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + ++ loongarch64_efi_ldflags = '-Wl,-r,-d'; ++ loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; ++ + i386_pc_startup = kern/i386/pc/startup.S; + i386_efi_startup = kern/i386/efi/startup.S; + x86_64_efi_startup = kern/x86_64/efi/startup.S; +@@ -105,6 +108,7 @@ kernel = { + i386_coreboot_startup = kern/i386/coreboot/startup.S; + i386_multiboot_startup = kern/i386/coreboot/startup.S; + mips_startup = kern/mips/startup.S; ++ loongarch64_efi_startup = kern/loongarch64/efi/startup.S; + sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; + powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; + arm_uboot_startup = kern/arm/startup.S; +@@ -295,6 +299,14 @@ kernel = { + extra_dist = video/sis315_init.c; + mips_loongson = commands/keylayouts.c; + ++ loongarch64 = kern/loongarch64/init.c; ++ loongarch64 = kern/loongarch64/dl.c; ++ loongarch64 = kern/loongarch64/cache.S; ++ loongarch64 = kern/generic/rtc_get_time_ms.c; ++ loongarch64_efi = kern/loongarch64/efi/init.c; ++ loongarch64_efi = lib/loongarch64/efi/loongson.c; ++ loongarch64_efi = lib/loongarch64/efi/loongson_asm.S; ++ + powerpc_ieee1275 = kern/powerpc/cache.S; + powerpc_ieee1275 = kern/powerpc/dl.c; + powerpc_ieee1275 = kern/powerpc/compiler-rt.S; +@@ -810,6 +822,7 @@ module = { + enable = sparc64_ieee1275; + enable = powerpc_ieee1275; + enable = mips_arc; ++ enable = loongarch64_efi; + enable = ia64_efi; + enable = arm_efi; + enable = arm64_efi; +@@ -896,6 +909,7 @@ module = { + i386_qemu = lib/i386/halt.c; + xen = lib/xen/halt.c; + efi = lib/efi/halt.c; ++ loongarch64_efi = commands/acpihalt.c; + ieee1275 = lib/ieee1275/halt.c; + emu = lib/emu/halt.c; + uboot = lib/dummy/halt.c; +@@ -911,6 +925,7 @@ module = { + mips_arc = lib/mips/arc/reboot.c; + mips_loongson = lib/mips/loongson/reboot.c; + mips_qemu_mips = lib/mips/qemu_mips/reboot.c; ++ loongarch64_efi = lib/loongson/reboot.c; + xen = lib/xen/reboot.c; + uboot = lib/uboot/reboot.c; + arm_coreboot = lib/dummy/reboot.c; +@@ -1608,6 +1623,8 @@ module = { + efi = lib/efi/relocator.c; + mips = lib/mips/relocator_asm.S; + mips = lib/mips/relocator.c; ++ loongarch64 = lib/loongarch64/relocator_asm.S; ++ loongarch64 = lib/loongarch64/relocator.c; + powerpc = lib/powerpc/relocator_asm.S; + powerpc = lib/powerpc/relocator.c; + xen = lib/xen/relocator.c; +@@ -1620,6 +1637,7 @@ module = { + extra_dist = kern/powerpc/cache_flush.S; + + enable = mips; ++ enable = loongarch64; + enable = powerpc; + enable = x86; + enable = xen; +@@ -1737,6 +1755,7 @@ module = { + xen = loader/i386/xen.c; + i386_pc = lib/i386/pc/vesa_modes_table.c; + mips = loader/mips/linux.c; ++ loongarch64 = loader/loongarch64/linux.c; + powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; + sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; + ia64_efi = loader/ia64/efi/linux.c; +@@ -1838,6 +1857,7 @@ module = { + enable = arm_efi; + enable = arm64_efi; + enable = mips; ++ enable = loongarch64_efi; + }; + + module = { +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 9e76f23..fb087e3 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -157,7 +157,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + grub_efi_physical_address_t ret = address; + + /* Limit the memory access to less than 4GB for 32-bit platforms. */ ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (address > grub_efi_max_usable_address()) ++#else + if (address > GRUB_EFI_MAX_USABLE_ADDRESS) ++#endif + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("invalid memory address (0x%llx > 0x%llx)"), +@@ -177,7 +181,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ ++#ifdef GRUB_CPU_LOONGARCH64 ++ ret = grub_efi_max_usable_address(); ++#else + ret = address; ++#endif + status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) +@@ -195,9 +203,14 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + void * + grub_efi_allocate_any_pages (grub_efi_uintn_t pages) + { +- return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, ++#ifdef GRUB_CPU_LOONGARCH64 ++ return grub_efi_allocate_pages_real (grub_efi_max_usable_address(), + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); ++#else ++ return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, ++ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++#endif GRUB_EFI_LOADER_DATA); + } + + void * +@@ -471,7 +484,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY +-#if 1 ++#ifdef GRUB_CPU_LOONGARCH64 ++ && desc->physical_start <= grub_efi_max_usable_address() ++#else + && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS + #endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 +@@ -486,8 +501,14 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + - desc->physical_start); + desc->physical_start = 0x100000; + } +- +-#if 1 ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (BYTES_TO_PAGES (filtered_desc->physical_start) ++ + filtered_desc->num_pages ++ > BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address())) ++ filtered_desc->num_pages ++ = (BYTES_TO_PAGES_DOWN (grub_efi_max_usable_address()) ++ - BYTES_TO_PAGES (filtered_desc->physical_start)); ++#else + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages + > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) +diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c +index 1859d18..8b1dce9 100644 +--- a/grub-core/kern/elfXX.c ++++ b/grub-core/kern/elfXX.c +@@ -134,6 +134,12 @@ grub_elfXX_load (grub_elf_t elf, const char *filename, + load_addr &= 0x3FFFFFFFFFFFFFFFULL; + break; + } ++#ifdef GRUB_CPU_LOONGARCH64 ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ if ((load_addr >> 48) != (addr >> 48)) ++ return grub_error (GRUB_ERR_BAD_OS, "bad address space"); ++#endif + load_addr += (grub_addr_t) load_offset; + + if (load_addr < load_base) +diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S +new file mode 100644 +index 0000000..d291c67 +--- /dev/null ++++ b/grub-core/kern/loongarch64/cache.S +@@ -0,0 +1,26 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2009,2017 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 . ++ */ ++ ++#include ++ ++FUNCTION (grub_arch_sync_caches) ++ jr $ra ++ ++FUNCTION (grub_arch_sync_dma_caches) ++ jr $ra ++ +diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c +new file mode 100644 +index 0000000..a6fd387 +--- /dev/null ++++ b/grub-core/kern/loongarch64/dl.c +@@ -0,0 +1,258 @@ ++/* loongarch64/dl.c - arch-dependent part of loadable module support */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2005,2007,2009,2017 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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_LOONGARCH64) ++ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++#pragma GCC diagnostic ignored "-Wcast-align" ++ ++grub_err_t ++grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), ++ grub_size_t *tramp, grub_size_t *got) ++{ ++ *tramp = 0; ++ *got = 0; ++ return GRUB_ERR_NONE; ++} ++ ++/* 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_Ehdr *e = ehdr; ++ Elf_Rel *rel, *max; ++ grub_uint64_t oprs[10240]={0}; ++ int opri=-1; ++ grub_uint32_t la_abs = 0; ++ ++ for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), ++ max = (Elf_Rel *) ((char *) rel + s->sh_size); ++ rel < max; ++ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) ++ { ++ grub_uint8_t *addr; ++ Elf_Sym *sym; ++ Elf_Addr r_info; ++ grub_uint64_t sym_value; ++ ++ if (seg->size < rel->r_offset) ++ return grub_error (GRUB_ERR_BAD_MODULE, ++ "reloc offset is out of the segment"); ++ ++ r_info = (grub_uint64_t) (rel->r_info); ++ ++ addr = (grub_uint8_t *) ((char*)seg->addr + rel->r_offset); ++ sym = (Elf_Sym *) ((char*)mod->symtab ++ + mod->symsize * ELF_R_SYM (r_info)); ++ sym_value = sym->st_value; ++ if (s->sh_type == SHT_RELA) ++ { ++ sym_value += ((Elf_Rela *) rel)->r_addend; ++ } ++ switch (ELF_R_TYPE (r_info)) ++ { ++ case R_LARCH_64: ++ { ++ *(grub_uint64_t *)addr=(grub_uint64_t)sym_value; ++ } ++ break; ++ case R_LARCH_MARK_LA: ++ { ++ la_abs=1; ++ } ++ break; ++ case R_LARCH_SOP_PUSH_PCREL: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)(sym_value-(grub_uint64_t)addr); ++ } ++ break; ++ case R_LARCH_SOP_PUSH_ABSOLUTE: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)sym_value; ++ } ++ break; ++ case R_LARCH_SOP_PUSH_PLT_PCREL: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)(sym_value-(grub_uint64_t)addr); ++ } ++ break; ++ case R_LARCH_SOP_SUB: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 - opr2; ++ } ++ break; ++ case R_LARCH_SOP_SL: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 << opr2; ++ } ++ break; ++ case R_LARCH_SOP_SR: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 >> opr2; ++ } ++ break; ++ case R_LARCH_SOP_ADD: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 + opr2; ++ } ++ break; ++ case R_LARCH_SOP_AND: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 & opr2; ++ } ++ break; ++ case R_LARCH_SOP_IF_ELSE: ++ { ++ grub_uint64_t opr3=oprs[opri]; ++ opri--; ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ if(opr1){ ++ opri++; ++ oprs[opri]=opr2; ++ } else { ++ opri++; ++ oprs[opri]=opr3; ++ } ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_5: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 & 0x1f) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_U_10_12: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 & 0xfff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_12: ++ { ++ if(la_abs==1) ++ la_abs=0; ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xfff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xffff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_5_20: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr= (*(grub_uint64_t *)addr) | ((opr1 & 0xfffff)<<5) ; ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 >> 18) & 0x1f); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | (((opr1 >> 2) & 0xffff) << 10); ++ *(grub_uint64_t *)addr=(*(grub_uint64_t *)addr) | ((opr1 >> 18) & 0x3ff); ++ } ++ break; ++ default: ++ { ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ N_("relocation 0x%x is not implemented yet"), ++ ELF_R_TYPE (r_info)); ++ } ++ break; ++ } ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ +diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c +new file mode 100644 +index 0000000..b21d4f1 +--- /dev/null ++++ b/grub-core/kern/loongarch64/efi/init.c +@@ -0,0 +1,76 @@ ++/* init.c - initialize an arm-based EFI system */ ++/* ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static grub_uint64_t tmr; ++static grub_efi_event_t tmr_evt; ++ ++static grub_uint64_t ++grub_efi_get_time_ms (void) ++{ ++ return tmr; ++} ++ ++static void ++grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), ++ void *context __attribute__ ((unused))) ++{ ++ tmr += 10; ++} ++ ++ ++ ++void ++grub_machine_init (void) ++{ ++ grub_efi_boot_services_t *b; ++ ++ grub_efi_init (); ++ ++ b = grub_efi_system_table->boot_services; ++ efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, ++ GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); ++ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); ++ ++ grub_install_get_time_ms (grub_efi_get_time_ms); ++} ++ ++void ++grub_machine_fini (int flags) ++{ ++ grub_efi_boot_services_t *b; ++ ++ if (!(flags & GRUB_LOADER_FLAG_NORETURN)) ++ return; ++ ++ b = grub_efi_system_table->boot_services; ++ ++ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); ++ efi_call_1 (b->close_event, tmr_evt); ++ ++ grub_efi_fini (); ++} +diff --git a/grub-core/kern/loongarch64/efi/startup.S b/grub-core/kern/loongarch64/efi/startup.S +new file mode 100644 +index 0000000..1ffff08 +--- /dev/null ++++ b/grub-core/kern/loongarch64/efi/startup.S +@@ -0,0 +1,45 @@ ++/* ++ * 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 . ++ */ ++ ++#include ++ ++ .file "startup.S" ++ .text ++ .globl start, _start ++ .align 4 ++ ++FUNCTION(start) ++FUNCTION(_start) ++ /* ++ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. ++ */ ++ addi.d $sp, $sp, -16 ++ st.d $ra, $sp, 0 ++ ++ la $a2, grub_efi_image_handle ++ st.d $a0, $a2, 0 ++ la $a2, grub_efi_system_table ++ st.d $a1, $a2, 0 ++ ++ bl grub_main ++ ++1: ++ ld.d $ra, $sp, 0 ++ addi.d $sp, $sp, 16 ++ jr $ra ++ +diff --git a/grub-core/kern/loongarch64/init.c b/grub-core/kern/loongarch64/init.c +new file mode 100644 +index 0000000..b2de930 +--- /dev/null ++++ b/grub-core/kern/loongarch64/init.c +@@ -0,0 +1,47 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2009,2017 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++grub_uint32_t grub_arch_cpuclock; ++ ++/* FIXME: use interrupt to count high. */ ++grub_uint64_t ++grub_get_rtc (void) ++{ ++ static grub_uint32_t high = 0; ++ static grub_uint32_t last = 0; ++ grub_uint32_t low; ++ ++ asm volatile ("csrrd %0, " GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT : "=r" (low)); ++ if (low < last) ++ high++; ++ last = low; ++ ++ return (((grub_uint64_t) high) << 32) | low; ++} ++ ++void ++grub_timer_init (grub_uint32_t cpuclock) ++{ ++ grub_arch_cpuclock = cpuclock; ++ grub_install_get_time_ms (grub_rtc_get_time_ms); ++} +diff --git a/grub-core/lib/loongarch64/efi/loongson.c b/grub-core/lib/loongarch64/efi/loongson.c +new file mode 100644 +index 0000000..8b60d82 +--- /dev/null ++++ b/grub-core/lib/loongarch64/efi/loongson.c +@@ -0,0 +1,505 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp) ++#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8) ++#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start) ++ ++extern grub_uint8_t grub_efi_loongson_reset_start; ++extern grub_uint8_t grub_efi_loongson_reset_end; ++ ++static struct ++{ ++ grub_efi_loongson_boot_params boot_params; ++ grub_efi_loongson_memory_map memory_map; ++ grub_efi_loongson_cpu_info cpu_info; ++ grub_efi_loongson_system_info system_info; ++ grub_efi_loongson_irq_src_routing_table irq_src_routing_table; ++ grub_efi_loongson_interface_info interface_info; ++ grub_efi_loongson_special_attribute special_attribute; ++ grub_efi_loongson_board_devices board_devices; ++} GRUB_PACKED ++* loongson_boot_params; ++ ++static void ++grub_efi_loongson_init_reset_system (void) ++{ ++ grub_efi_loongson_boot_params *boot_params; ++ grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params + ++ loongson_boot_params_size; ++ ++ boot_params = &loongson_boot_params->boot_params; ++ grub_efi_loongson_reset_system_addr = ++ (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system; ++ grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size); ++ grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size); ++ ++ boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr + ++ ((grub_uint64_t) &grub_efi_loongson_reset_cold - ++ (grub_uint64_t) &grub_efi_loongson_reset_start); ++ boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr + ++ ((grub_uint64_t) &grub_efi_loongson_reset_warm - ++ (grub_uint64_t) &grub_efi_loongson_reset_start); ++ boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr + ++ ((grub_uint64_t) &grub_efi_loongson_reset_shutdown - ++ (grub_uint64_t) &grub_efi_loongson_reset_start); ++ boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr + ++ ((grub_uint64_t) &grub_efi_loongson_reset_suspend - ++ (grub_uint64_t) &grub_efi_loongson_reset_start); ++} ++ ++static void ++grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios; ++ ++ dst->vers = smbios_table->vers; ++ dst->vga_bios = smbios_table->vga_bios; ++} ++ ++static void ++grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset; ++ grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info)); ++ loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++static void ++grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset; ++ grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info)); ++ loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++static void ++grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset; ++ grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table)); ++ loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++static void ++grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset; ++ grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info)); ++ loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++static void ++grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset; ++ grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute)); ++ loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++static void ++grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table) ++{ ++ grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset; ++ grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices; ++ ++ if (!src) ++ return; ++ ++ grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices)); ++ loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++} ++ ++#define ADD_MEMORY_DESCRIPTOR(desc, size) \ ++ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) ++ ++static void ++grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table, ++ grub_efi_memory_descriptor_t *mmap_buf, ++ grub_efi_uintn_t mmap_size, ++ grub_efi_uintn_t desc_size) ++{ ++ grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset; ++ grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map; ++ grub_efi_memory_descriptor_t *mmap_end; ++ grub_efi_memory_descriptor_t *desc; ++ grub_efi_memory_descriptor_t *desc_next; ++ grub_efi_uint32_t mem_types_reserved[] = ++ { ++ 1, // GRUB_EFI_RESERVED_MEMORY_TYPE ++ 0, // GRUB_EFI_LOADER_CODE ++ 0, // GRUB_EFI_LOADER_DATA ++ 0, // GRUB_EFI_BOOT_SERVICES_CODE ++ 0, // GRUB_EFI_BOOT_SERVICES_DATA ++ 1, // GRUB_EFI_RUNTIME_SERVICES_CODE ++ 1, // GRUB_EFI_RUNTIME_SERVICES_DATA ++ 0, // GRUB_EFI_CONVENTIONAL_MEMORY ++ 1, // GRUB_EFI_UNUSABLE_MEMORY ++ 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY ++ 0, // GRUB_EFI_ACPI_MEMORY_NVS ++ 1, // GRUB_EFI_MEMORY_MAPPED_IO ++ 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE ++ 1, // GRUB_EFI_PAL_CODE ++ 1, // GRUB_EFI_PERSISTENT_MEMORY ++ }; ++ grub_uint32_t need_sort = 1; ++ ++ if (!src) ++ return; ++ ++ dst->vers = src->vers; ++ dst->nr_map = 0; ++ dst->mem_freq = src->mem_freq; ++ loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; ++ ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return; ++ ++ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); ++ ++ /* drop reserved */ ++ for (desc = mmap_buf, ++ desc_next = desc; ++ desc < mmap_end; ++ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) ++ { ++ desc->type = mem_types_reserved[desc->type]; ++ if (desc->type) ++ continue; ++ ++ if (desc != desc_next) ++ *desc_next = *desc; ++ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size); ++ } ++ mmap_end = desc_next; ++ ++ /* sort: low->high */ ++ while (need_sort) ++ { ++ need_sort = 0; ++ ++ for (desc = mmap_buf, ++ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); ++ (desc < mmap_end) && (desc_next < mmap_end); ++ desc = desc_next, ++ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) ++ { ++ grub_efi_memory_descriptor_t tmp; ++ ++ if (desc->physical_start <= desc_next->physical_start) ++ continue; ++ ++ tmp = *desc; ++ *desc = *desc_next; ++ *desc_next = tmp; ++ need_sort = 1; ++ } ++ } ++ ++ /* combine continuous memory map */ ++ for (desc = mmap_buf, ++ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); ++ desc_next < mmap_end; ++ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size)) ++ { ++ grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12); ++ ++ if (prev_end == desc_next->physical_start) ++ { ++ desc->num_pages += desc_next->num_pages; ++ continue; ++ } ++ ++ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size); ++ grub_memcpy (desc, desc_next, desc_size); ++ } ++ mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size); ++ ++ /* write to loongson memory map */ ++ for (desc = mmap_buf; ++ desc < mmap_end; ++ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) ++ { ++ grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start); ++ grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12); ++ ++ physical_start = ALIGN_UP (physical_start, 0x100000); ++ physical_end = ALIGN_DOWN (physical_end, 0x100000); ++ ++ if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000) ++ continue; ++ ++ dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf; ++ dst->map[dst->nr_map].mem_type = GRUB_EFI_LOONGSON_SYSTEM_RAM; ++ dst->map[dst->nr_map].mem_start = physical_start; ++ dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20; ++ ++ grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n", ++ dst->nr_map, physical_start, physical_end - physical_start, ++ dst->map[dst->nr_map].node_id); ++ ++ dst->nr_map ++; ++ } ++} ++ ++#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) ++#define SUB_MEMORY_DESCRIPTOR(desc, size) \ ++ ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size))) ++ ++void ++grub_efi_loongson_alloc_boot_params (void) ++{ ++ grub_efi_memory_descriptor_t *mmap_buf; ++ grub_efi_memory_descriptor_t *mmap_end; ++ grub_efi_memory_descriptor_t *desc; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_physical_address_t address; ++ grub_efi_allocate_type_t type; ++ grub_efi_uintn_t pages; ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; ++ int mm_status; ++ ++ type = GRUB_EFI_ALLOCATE_ADDRESS; ++ pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size); ++ ++ mmap_size = (1 << 12); ++ mmap_buf = grub_malloc (mmap_size); ++ if (!mmap_buf) ++ grub_fatal ("out of memory!"); ++ ++ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); ++ if (mm_status == 0) ++ { ++ grub_free (mmap_buf); ++ mmap_size += desc_size * 32; ++ ++ mmap_buf = grub_malloc (mmap_size); ++ if (!mmap_buf) ++ grub_fatal ("out of memory!"); ++ ++ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); ++ } ++ ++ if (mm_status < 0) ++ grub_fatal ("cannot get memory map!"); ++ ++ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); ++ ++ for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size); ++ desc >= mmap_buf; ++ desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size)) ++ { ++ if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) ++ continue; ++ if (desc->physical_start >= grub_efi_max_usable_address()) ++ continue; ++ if (desc->num_pages < pages) ++ continue; ++ ++ address = desc->physical_start; ++ break; ++ } ++ ++ grub_free (mmap_buf); ++ ++ b = grub_efi_system_table->boot_services; ++ status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); ++ if (status != GRUB_EFI_SUCCESS) ++ grub_fatal ("cannot allocate Loongson boot parameters!"); ++ ++ loongson_boot_params = (void *) ((grub_addr_t) address); ++} ++ ++void ++grub_efi_loongson_free_boot_params (void) ++{ ++ grub_efi_free_pages ((grub_addr_t) loongson_boot_params, ++ BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size)); ++} ++ ++void * ++grub_efi_loongson_get_smbios_table (void) ++{ ++ static grub_efi_loongson_smbios_table *smbios_table; ++ grub_efi_loongson_boot_params *old_boot_params; ++ struct bootparamsinterface* boot_params; ++ void * tmp_boot_params = NULL; ++ char * p = NULL; ++ if(smbios_table) ++ return smbios_table; ++ ++ tmp_boot_params = grub_efi_loongson_get_boot_params(); ++ if(tmp_boot_params == NULL) ++ { ++ grub_dprintf("loongson", "tmp_boot_params is NULL\n"); ++ return tmp_boot_params; ++ } ++ ++ boot_params = (struct bootparamsinterface *)tmp_boot_params; ++ p = (char *)&(boot_params->signature); ++ if(grub_strncmp(p, "BPI", 3) == 0) ++ { ++ grub_dprintf("loongson", "find new bpi\n"); ++ return boot_params ? boot_params : 0; ++ } ++ else ++ { ++ old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params; ++ /* ++ { ++ grub_dprintf("loongson", "smbios addr%llx\n", &old_boot_params->efi.smbios); ++ grub_dprintf("loongson", "smbios vers%d\n", (grub_uint16_t)(&old_boot_params->efi.smbios.vers)); ++ grub_dprintf("loongson", "smbios vga_bios%d\n", &old_boot_params->efi.smbios.vga_bios); ++ grub_dprintf("loongson", "lp memory offset %llx\n", &old_boot_params->efi.smbios.lp.memory_offset); ++ grub_dprintf("loongson", "lp cpu offset %llx\n", &old_boot_params->efi.smbios.lp.cpu_offset); ++ grub_dprintf("loongson", "lp system offset %llx\n", &old_boot_params->efi.smbios.lp.system_offset); ++ grub_dprintf("loongson", "lp irq offset %llx\n", &old_boot_params->efi.smbios.lp.irq_offset); ++ grub_dprintf("loongson", "lp interface offset %llx\n", &old_boot_params->efi.smbios.p.interface_offset); ++ grub_dprintf("loongson", "lp special offset %llx\n", &old_boot_params->efi.smbios.lp.special_offset); ++ grub_dprintf("loongson", "lp boarddev table offset %llx\n", &old_boot_params->efi.smbios.lp.boarddev_table_offset); ++ } ++ */ ++ return old_boot_params ? &old_boot_params->efi.smbios : 0; ++ } ++ ++} ++ ++int ++grub_efi_is_loongson (void) ++{ ++ return grub_efi_loongson_get_smbios_table () ? 1 : 0; ++} ++ ++void * ++grub_efi_loongson_get_boot_params (void) ++{ ++ static void * boot_params = NULL; ++ grub_efi_configuration_table_t *tables; ++ grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID; ++ unsigned int i; ++ ++ if (boot_params) ++ return boot_params; ++ ++ /* Look for Loongson SMBIOS in UEFI config tables. */ ++ tables = grub_efi_system_table->configuration_table; ++ ++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) ++ if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0) ++ { ++ boot_params= tables[i].vendor_table; ++ grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params); ++ break; ++ } ++ return boot_params; ++} ++ ++grub_uint8_t ++grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) ++{ ++ grub_uint8_t sum; ++ grub_efi_uintn_t count; ++ ++ for (sum = 0, count = 0; count < length; count++) ++ { ++ sum = (grub_uint8_t) (sum + *(buffer + count)); ++ } ++ return sum; ++} ++ ++grub_uint8_t ++grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) ++{ ++ grub_uint8_t checksum; ++ ++ checksum = grub_efi_loongson_calculatesum8(buffer, length); ++ ++ return (grub_uint8_t) (0x100 - checksum); ++} ++ ++ ++grub_uint32_t ++grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype) ++{ ++ grub_uint64_t tempmemsize = 0; ++ grub_uint32_t j = 0; ++ grub_uint32_t t = 0; ++ ++ for(j = 0; j < length;) ++ { ++ tempmemsize = array[j].memsize; ++ for(t = j + 1; t < length; t++) ++ { ++ if(array[j].memstart + tempmemsize == array[t].memstart) ++ { ++ tempmemsize += array[t].memsize; ++ } ++ else ++ { ++ break; ++ } ++ } ++ bpmem->map[index].memtype = memtype; ++ bpmem->map[index].memstart = array[j].memstart; ++ bpmem->map[index].memsize = tempmemsize; ++ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", ++ index, ++ bpmem->map[index].memtype, ++ bpmem->map[index].memstart, ++ bpmem->map[index].memstart+ bpmem->map[index].memsize ++ ); ++ j = t; ++ index++; ++ } ++ return index; ++} ++ +diff --git a/grub-core/lib/loongarch64/efi/loongson_asm.S b/grub-core/lib/loongarch64/efi/loongson_asm.S +new file mode 100644 +index 0000000..4a04d34 +--- /dev/null ++++ b/grub-core/lib/loongarch64/efi/loongson_asm.S +@@ -0,0 +1,58 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#include ++ ++ .file "loongson_asm.S" ++ .text ++ ++ .align 4 ++ ++VARIABLE (grub_efi_loongson_reset_start) ++ ++VARIABLE (grub_efi_loongson_reset_system_addr) ++ .dword 0 ++ ++reset_system: ++ bl 1f ++ move $a1, $zero ++1: ++ ld.d $t8, $ra, -16 ++ move $a2, $zero ++ jr $t8 ++ move $a3, $zero ++ ++FUNCTION(grub_efi_loongson_reset_cold) ++ b reset_system ++ li.w $a0, 0 ++ ++FUNCTION(grub_efi_loongson_reset_warm) ++ b reset_system ++ li.w $a0, 1 ++ ++FUNCTION(grub_efi_loongson_reset_shutdown) ++ b reset_system ++ li.w $a0, 2 ++ ++FUNCTION(grub_efi_loongson_reset_suspend) ++ b reset_system ++ li.w $a0, 3 ++ ++VARIABLE (grub_efi_loongson_reset_end) ++ ++ +diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c +new file mode 100644 +index 0000000..f6c1b01 +--- /dev/null ++++ b/grub-core/lib/loongarch64/relocator.c +@@ -0,0 +1,163 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++extern grub_uint8_t grub_relocator_forward_start; ++extern grub_uint8_t grub_relocator_forward_end; ++extern grub_uint8_t grub_relocator_backward_start; ++extern grub_uint8_t grub_relocator_backward_end; ++ ++#define REGW_SIZEOF (4 * sizeof (grub_uint32_t)) ++#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) ++ ++#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ ++ - &grub_relocator_##x##_start) ++#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ ++ + REGW_SIZEOF * 3) ++grub_size_t grub_relocator_align = sizeof (grub_uint64_t); ++grub_size_t grub_relocator_forward_size; ++grub_size_t grub_relocator_backward_size; ++grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; ++ ++void ++grub_cpu_relocator_init (void) ++{ ++ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); ++ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); ++} ++ ++static void ++write_reg (int regn, grub_uint64_t val, void **target) ++{ ++ grub_uint32_t lu12iw=0x14000000; ++ grub_uint32_t ori=0x03800000; ++ grub_uint32_t lu32id=0x16000000; ++ grub_uint32_t lu52id=0x03000000; ++ ++ *(grub_uint32_t *) *target = (lu12iw | (grub_uint32_t)((val & 0xfffff000)>>12<<5) | (grub_uint32_t)regn);; ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (ori | (grub_uint32_t)((val & 0xfff)<<10) | (grub_uint32_t)(regn | regn<<5)); ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (lu32id | (grub_uint32_t)((val & 0xfffff00000000)>>32<<5) | (grub_uint32_t)regn);; ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = (lu52id | (grub_uint32_t)((val & 0xfff0000000000000)>>52<<10) | (grub_uint32_t)(regn | regn<<5));; ++ *target = ((grub_uint32_t *) *target) + 1; ++} ++ ++static void ++write_jump (int regn, void **target) ++{ ++ grub_uint32_t andi=0x4c000000; ++ grub_uint32_t nop=0x03400000; ++ ++ *(grub_uint32_t *) *target = (andi | (grub_uint32_t)(regn<<5)); ++ *target = ((grub_uint32_t *) *target) + 1; ++ *(grub_uint32_t *) *target = nop; ++ *target = ((grub_uint32_t *) *target) + 1; ++} ++ ++void ++grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) ++{ ++ write_reg (1, addr, &rels); ++ write_jump (1, &rels); ++} ++ ++void ++grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, ++ grub_size_t size) ++{ ++ void *ptr = ptr0; ++ write_reg (8, (grub_uint64_t) src, &ptr); ++ write_reg (9, (grub_uint64_t) dest, &ptr); ++ write_reg (10, (grub_uint64_t) size, &ptr); ++ grub_memcpy (ptr, &grub_relocator_backward_start, ++ RELOCATOR_SRC_SIZEOF (backward)); ++} ++ ++void ++grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, ++ grub_size_t size) ++{ ++ void *ptr = ptr0; ++ write_reg (8, (grub_uint64_t) src, &ptr); ++ write_reg (9, (grub_uint64_t) dest, &ptr); ++ write_reg (10, (grub_uint64_t) size, &ptr); ++ grub_memcpy (ptr, &grub_relocator_forward_start, ++ RELOCATOR_SRC_SIZEOF (forward)); ++} ++ ++grub_err_t ++grub_relocator64_boot (struct grub_relocator *rel, ++ struct grub_relocator64_state state) ++{ ++ grub_relocator_chunk_t ch; ++ void *ptr; ++ grub_err_t err; ++ void *relst; ++ grub_size_t relsize; ++ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; ++ unsigned i; ++ grub_addr_t vtarget; ++ ++ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, ++ (0xffffffff - stateset_size) ++ + 1, stateset_size, ++ grub_relocator_align, ++ GRUB_RELOCATOR_PREFERENCE_NONE, 0); ++ if (err) ++ return err; ++ ++ ptr = get_virtual_current_address (ch); ++ for (i = 1; i < 32; i++) ++ write_reg (i, state.gpr[i], &ptr); ++ write_jump (state.jumpreg, &ptr); ++ ++ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), ++ stateset_size); ++ ++ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); ++ if (err) ++ return err; ++ ++ grub_arch_sync_caches ((void *) relst, relsize); ++ ++ grub_uint64_t val; ++ __asm__ __volatile__( ++ "li.w %0, 0x4\n\t" ++ "csrxchg $r0, %0, 0x0\n\t" ++ : "=r"(val) ++ : ++ : ++ ); ++ ++ ((void (*) (void)) relst) (); ++ ++ /* Not reached. */ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/lib/loongarch64/relocator_asm.S b/grub-core/lib/loongarch64/relocator_asm.S +new file mode 100644 +index 0000000..cf1724d +--- /dev/null ++++ b/grub-core/lib/loongarch64/relocator_asm.S +@@ -0,0 +1,51 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#include ++ ++ .p2align 4 /* force 16-byte alignment */ ++ ++VARIABLE (grub_relocator_forward_start) ++ ++copycont1: ++ ld.d $r11,$r8,0 ++ st.d $r11,$r9,0 ++ addi.d $r8, $r8, 8 ++ addi.d $r10, $r10, -8 ++ addi.d $r9, $r9, 8 ++ bne $r10, $r0, copycont1 ++ ++VARIABLE (grub_relocator_forward_end) ++ ++VARIABLE (grub_relocator_backward_start) ++ ++ add.d $r9, $r9, $r10 ++ add.d $r8, $r8, $r10 ++ /* Backward movsl is implicitly off-by-one. compensate that. */ ++ addi.d $r9, $r9, -8 ++ addi.d $r8, $r8, -8 ++copycont2: ++ ld.w $r11,$r8,0 ++ st.w $r11,$r9,0 ++ addi.d $r8, $r8, -8 ++ addi.d $r10, $r10, -8 ++ addi.d $r9, $r9, -8 ++ bne $r10, $r0, copycont2 ++ ++VARIABLE (grub_relocator_backward_end) ++ +diff --git a/grub-core/lib/loongarch64/setjmp.S b/grub-core/lib/loongarch64/setjmp.S +new file mode 100644 +index 0000000..47db814 +--- /dev/null ++++ b/grub-core/lib/loongarch64/setjmp.S +@@ -0,0 +1,74 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2003,2007,2009 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 . ++ */ ++ ++#include ++#include ++#include ++ ++ .file "setjmp.S" ++ ++GRUB_MOD_LICENSE "GPLv3+" ++ ++ .text ++ ++/* ++ * int grub_setjmp (grub_jmp_buf env) ++ */ ++FUNCTION(grub_setjmp) ++ GRUB_ASM_REG_S $s0, $a0,0 ++ GRUB_ASM_REG_S $s1, $a0,8 ++ GRUB_ASM_REG_S $s2, $a0,16 ++ GRUB_ASM_REG_S $s3, $a0,24 ++ GRUB_ASM_REG_S $s4, $a0,32 ++ GRUB_ASM_REG_S $s5, $a0,40 ++ GRUB_ASM_REG_S $s6, $a0,48 ++ GRUB_ASM_REG_S $s7, $a0,56 ++ GRUB_ASM_REG_S $s8, $a0,64 ++ GRUB_ASM_REG_S $fp, $a0,72 ++ GRUB_ASM_REG_S $sp, $a0,80 ++ GRUB_ASM_REG_S $ra, $a0,88 ++ move $v0, $zero ++ move $v1, $zero ++ jr $ra ++ nop ++/* ++ * int grub_longjmp (grub_jmp_buf env, int val) ++ */ ++FUNCTION(grub_longjmp) ++ GRUB_ASM_REG_L $s0, $a0,0 ++ GRUB_ASM_REG_L $s1, $a0,8 ++ GRUB_ASM_REG_L $s2, $a0,16 ++ GRUB_ASM_REG_L $s3, $a0,24 ++ GRUB_ASM_REG_L $s4, $a0,32 ++ GRUB_ASM_REG_L $s5, $a0,40 ++ GRUB_ASM_REG_L $s6, $a0,48 ++ GRUB_ASM_REG_L $s7, $a0,56 ++ GRUB_ASM_REG_L $s8, $a0,64 ++ GRUB_ASM_REG_L $fp, $a0,72 ++ GRUB_ASM_REG_L $sp, $a0,80 ++ GRUB_ASM_REG_L $ra, $a0,88 ++ addi.w $v0, $zero, 1 ++ /* ++ * replace: movn $v0, $a1, $a1 ++ */ ++ bnez $a1, .ZW0 ++ addi.d $v0, $a1, 0 ++.ZW0: ++ addi.d $v1,$zero,0 ++ jr $ra ++ nop +diff --git a/grub-core/lib/loongson/reboot.c b/grub-core/lib/loongson/reboot.c +new file mode 100644 +index 0000000..107787a +--- /dev/null ++++ b/grub-core/lib/loongson/reboot.c +@@ -0,0 +1,33 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2011 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++grub_la_reboot (void) ++{ ++ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); ++ efi_call_4 (grub_efi_system_table->runtime_services->reset_system, ++ GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); ++ for (;;) ; ++} +diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S +index f6e4905..023dc90 100644 +--- a/grub-core/lib/setjmp.S ++++ b/grub-core/lib/setjmp.S +@@ -15,6 +15,8 @@ + #include "./arm/setjmp.S" + #elif defined(__aarch64__) + #include "./arm64/setjmp.S" ++#elif defined(__loongarch64) ++#include "./loongarch64/setjmp.S" + #else + #error "Unknown target cpu type" + #endif +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 29663f7..c0ca17d 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -332,6 +332,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = + GRUB_PE32_MACHINE_I386; + #elif defined(__ia64__) + GRUB_PE32_MACHINE_IA64; ++#elif defined(__loongarch64) ++ GRUB_PE32_MACHINE_LOONGARCH64; + #else + #error this architecture is not supported by grub2 + #endif +diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c +new file mode 100644 +index 0000000..c769bb2 +--- /dev/null ++++ b/grub-core/loader/loongarch64/linux.c +@@ -0,0 +1,580 @@ ++/* linux.c - boot Linux */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2003,2004,2005,2007,2009,2010,2017 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#pragma GCC diagnostic ignored "-Wcast-align" ++ ++typedef unsigned long size_t; ++ ++static grub_dl_t my_mod; ++ ++static int loaded; ++ ++static grub_uint32_t tmp_index = 0; ++static grub_size_t linux_size; ++ ++static struct grub_relocator *relocator; ++static grub_addr_t target_addr, entry_addr; ++static int linux_argc; ++static grub_uint8_t *linux_args_addr; ++static grub_off_t rd_addr_arg_off, rd_size_arg_off; ++static grub_off_t initrd_addr_arg_off; ++static int initrd_loaded = 0; ++ ++ ++static grub_uint32_t j = 0; ++static grub_uint32_t t = 0; ++grub_uint64_t tempMemsize = 0; ++grub_uint32_t free_index = 0; ++grub_uint32_t reserve_index = 0; ++grub_uint32_t acpi_table_index = 0; ++grub_uint32_t acpi_nvs_index = 0; ++ ++static inline grub_size_t ++page_align (grub_size_t size) ++{ ++ return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); ++} ++ ++/* Find the optimal number of pages for the memory map. Is it better to ++ move this code to efi/mm.c? */ ++static grub_efi_uintn_t ++find_mmap_size (void) ++{ ++ static grub_efi_uintn_t mmap_size = 0; ++ ++ if (mmap_size != 0) ++ return mmap_size; ++ ++ mmap_size = (1 << 12); ++ while (1) ++ { ++ int ret; ++ grub_efi_memory_descriptor_t *mmap; ++ grub_efi_uintn_t desc_size; ++ ++ mmap = grub_malloc (mmap_size); ++ if (! mmap) ++ return 0; ++ ++ ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); ++ grub_free (mmap); ++ ++ if (ret < 0) ++ { ++ grub_error (GRUB_ERR_IO, "cannot get memory map"); ++ return 0; ++ } ++ else if (ret > 0) ++ break; ++ ++ mmap_size += (1 << 12); ++ } ++ ++ ++ /* Increase the size a bit for safety, because GRUB allocates more on ++ later, and EFI itself may allocate more. */ ++ mmap_size += (1 << 12); ++ ++ return page_align (mmap_size); ++} ++ ++static grub_err_t ++grub_linux_boot (void) ++{ ++ struct grub_relocator64_state state; ++ grub_int8_t checksum = 0; ++ grub_efi_memory_descriptor_t * lsdesc = NULL; ++ ++ grub_memset (&state, 0, sizeof (state)); ++ ++ /* Boot the kernel. */ ++ state.gpr[1] = entry_addr; ++ grub_dprintf("loongson", "entry_addr is %p\n", state.gpr[1]); ++ state.gpr[4] = linux_argc; ++ grub_dprintf("loongson", "linux_argc is %d\n", state.gpr[4]); ++ state.gpr[5] = (grub_addr_t) linux_args_addr; ++ grub_dprintf("loongson", "args_addr is %p\n", state.gpr[5]); ++ ++ if(grub_efi_is_loongson ()) ++ { ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_memory_descriptor_t *mmap_buf; ++ grub_err_t err; ++ struct bootparamsinterface * boot_params; ++ void * tmp_boot_params = NULL; ++ grub_efi_uint8_t new_interface_flag = 0; ++ mem_map * new_interface_mem = NULL; ++ char *p = NULL; ++ ++ struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ ++ grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ ++ tmp_boot_params = grub_efi_loongson_get_boot_params(); ++ if(tmp_boot_params == NULL) ++ { ++ grub_printf("not find param\n"); ++ return -1; ++ } ++ ++ boot_params = (struct bootparamsinterface *)tmp_boot_params; ++ p = (char *)&(boot_params->signature); ++ if(grub_strncmp(p, "BPI", 3) == 0) ++ { ++ /* Check extlist headers */ ++ ext_list * listpointer = NULL; ++ listpointer = boot_params->extlist; ++ for( ;listpointer != NULL; listpointer = listpointer->next) ++ { ++ char *pl= (char *)&(listpointer->signature); ++ if(grub_strncmp(pl, "MEM", 3) == 0) ++ { ++ new_interface_mem = (mem_map *)listpointer; ++ } ++ } ++ ++ new_interface_flag = 1; ++ grub_dprintf("loongson", "get new parameter interface\n"); ++ }else{ ++ new_interface_flag = 0; ++ grub_dprintf("loongson", "get old parameter interface\n"); ++ } ++ state.gpr[6] = (grub_uint64_t)tmp_boot_params; ++ grub_dprintf("loongson", "boot_params is %p\n", state.gpr[6]); ++ ++ mmap_size = find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, NULL); ++ if (err) ++ return err; ++ ++ if(new_interface_flag) ++ { ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return -1; ++ tmp_index = new_interface_mem -> mapcount; ++ ++ /* ++ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ ++ now we can fill platform specific memory structure. ++ */ ++ for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); ++ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) ++ { ++ /* Recovery */ ++ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ ++ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ ++ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ ++ (lsdesc->type != GRUB_EFI_PAL_CODE)) ++ { ++ free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; ++ free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; ++ free_mem[free_index].memsize = lsdesc->num_pages * 4096; ++ free_index++; ++ ++ /*ACPI*/ ++ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ ++ acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; ++ acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; ++ acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096; ++ acpi_table_index++; ++ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ ++ acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; ++ acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; ++ acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096; ++ acpi_nvs_index++; ++ ++ /* Reserve */ ++ }else{ ++ reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; ++ reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; ++ reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096; ++ reserve_index++; ++ } ++ } ++ ++ /* Recovery sort */ ++ for(j = 0; j < free_index;) ++ { ++ tempMemsize = free_mem[j].memsize; ++ for(t = j + 1; t < free_index; t++) ++ { ++ if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype)) ++ { ++ tempMemsize += free_mem[t].memsize; ++ }else{ ++ break; ++ } ++ } ++ ++ new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; ++ new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart; ++ new_interface_mem->map[tmp_index].memsize = tempMemsize; ++ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", ++ tmp_index, ++ new_interface_mem->map[tmp_index].memtype, ++ new_interface_mem->map[tmp_index].memstart, ++ new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize ++ ); ++ j = t; ++ tmp_index++; ++ } ++ /*ACPI Sort*/ ++ tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); ++ tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); ++ /*Reserve Sort*/ ++ grub_uint64_t loongarch_addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); ++ if((loongarch_addr & 0xff00000000000000) == 0x9000000000000000){ ++ tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED); ++ }else{ ++ tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); ++ } ++ ++ new_interface_mem->mapcount = tmp_index; ++ new_interface_mem->header.checksum = 0; ++ ++ checksum = grub_efi_loongson_grub_calculatechecksum8(new_interface_mem, new_interface_mem->header.length); ++ new_interface_mem->header.checksum = checksum; ++ } ++ } ++ ++ state.jumpreg = 1; ++ grub_relocator64_boot (relocator, state); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linux_unload (void) ++{ ++ grub_relocator_unload (relocator); ++ grub_dl_unref (my_mod); ++ ++ loaded = 0; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linux_load32 (grub_elf_t elf, const char *filename) ++{ ++ Elf32_Addr base; ++ grub_err_t err; ++ grub_uint8_t *playground; ++ ++ /* Linux's entry point incorrectly contains a virtual address. */ ++ entry_addr = elf->ehdr.ehdr32.e_entry; ++ ++ linux_size = grub_elf32_size (elf, &base, 0); ++ if (linux_size == 0) ++ return grub_errno; ++ target_addr = base; ++ linux_size = ALIGN_UP (base + linux_size - base, 8); ++ ++ relocator = grub_relocator_new (); ++ if (!relocator) ++ return grub_errno; ++ ++ { ++ grub_relocator_chunk_t ch; ++ err = grub_relocator_alloc_chunk_addr (relocator, &ch, ++ grub_vtop ((void *) target_addr), ++ linux_size); ++ if (err) ++ return err; ++ playground = get_virtual_current_address (ch); ++ } ++ ++ /* Now load the segments into the area we claimed. */ ++ return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); ++} ++ ++static grub_err_t ++grub_linux_load64 (grub_elf_t elf, const char *filename) ++{ ++ Elf64_Addr base; ++ grub_err_t err; ++ grub_uint8_t *playground; ++ ++ /* Linux's entry point incorrectly contains a virtual address. */ ++ entry_addr = elf->ehdr.ehdr64.e_entry; ++ grub_dprintf("loongson", "entry address = %p\n", entry_addr); ++ ++ linux_size = grub_elf64_size (elf, &base, 0); ++ grub_dprintf("loongson", "base = %p\n", base); ++ ++ if (linux_size == 0) ++ return grub_errno; ++ target_addr = base; ++ linux_size = ALIGN_UP (base + linux_size - base, 8); ++ ++ relocator = grub_relocator_new (); ++ // linux_size=0x322fa80; ++ if (!relocator) ++ return grub_errno; ++ ++ { ++ grub_relocator_chunk_t ch; ++ err = grub_relocator_alloc_chunk_addr (relocator, &ch, ++ grub_vtop ((void *) target_addr), ++ linux_size); ++ if (err) ++ return err; ++ playground = get_virtual_current_address (ch); ++ } ++ ++ /* Now load the segments into the area we claimed. */ ++ return grub_elf64_load (elf, filename, playground - base, 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_elf_t elf = 0; ++ int size; ++ int i; ++ grub_uint64_t *linux_argv; ++ char *linux_args; ++ grub_err_t err; ++ ++ if (argc == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ ++ elf = grub_elf_open (argv[0],GRUB_FILE_TYPE_LINUX_KERNEL); ++ if (! elf) ++ return grub_errno; ++ ++ if (elf->ehdr.ehdr32.e_type != ET_EXEC) ++ { ++ grub_elf_close (elf); ++ return grub_error (GRUB_ERR_UNKNOWN_OS, ++ N_("this ELF file is not of the right type")); ++ } ++ ++ /* Release the previously used memory. */ ++ grub_loader_unset (); ++ loaded = 0; ++ ++ /* For arguments. */ ++ linux_argc = argc; ++ /* Main arguments. */ ++ size = (linux_argc) * sizeof (grub_uint64_t); ++ /* Initrd address and size. */ ++ size += 3 * sizeof (grub_uint64_t); ++ /* NULL terminator. */ ++ size += sizeof (grub_uint64_t); ++ /* First argument is always "a0". */ ++ size += ALIGN_UP (sizeof ("a0"), 4); ++ /* Normal arguments. */ ++ for (i = 1; i < argc; i++) ++ size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); ++ ++ /* rd arguments. */ ++ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ ++ size = ALIGN_UP (size, 8); ++ ++ if (grub_elf_is_elf32 (elf)) ++ err = grub_linux_load32 (elf, argv[0]); ++ else ++ if (grub_elf_is_elf64 (elf)) ++ err = grub_linux_load64 (elf, argv[0]); ++ else ++ err = grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); ++ ++ grub_elf_close (elf); ++ ++ if (err) ++ return err; ++ ++ { ++ grub_relocator_chunk_t ch; ++ err = grub_relocator_alloc_chunk_align (relocator, &ch, ++ 0, (0xffffffff - size) + 1, ++ size, 8, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); ++ if (err) ++ return err; ++ linux_args_addr = get_virtual_current_address (ch); ++ } ++ ++ linux_argv = (grub_uint64_t *) linux_args_addr; ++ linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); ++ ++ grub_memcpy (linux_args, "a0", sizeof ("a0")); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof ("a0"), 4); ++ ++ for (i = 1; i < argc; i++) ++ { ++ grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); ++ } ++ ++ /* Reserve space for rd arguments. */ ++ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; ++ ++ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; ++ ++ /* Reserve space for initrd arguments. */ ++ initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; ++ ++ *linux_argv = 0; ++ ++ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); ++ initrd_loaded = 0; ++ loaded = 1; ++ grub_dl_ref (my_mod); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_size_t size = 0; ++ void *initrd_dest; ++ grub_err_t err; ++ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; ++ ++ if (argc == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ ++ if (!loaded) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); ++ ++ if (initrd_loaded) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued."); ++ ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) ++ goto fail; ++ ++ size = grub_get_initrd_size (&initrd_ctx); ++ ++ { ++ grub_relocator_chunk_t ch; ++ err = grub_relocator_alloc_chunk_align (relocator, &ch, ++ 0, (0xffffffff - size) + 1, ++ size, 0x10000, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); ++ ++ if (err) ++ goto fail; ++ initrd_dest = get_virtual_current_address (ch); ++ } ++ ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_dest)) ++ goto fail; ++ ++ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, ++ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx", ++ (grub_uint64_t) initrd_dest); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); ++ linux_argc++; ++ ++ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, ++ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", ++ (grub_uint64_t) size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); ++ linux_argc++; ++ ++ ++ grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, ++ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), "initrd=0x%lx,0x%lx", ++ ((grub_uint64_t) initrd_dest & 0xffffffff), (grub_uint64_t) size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); ++ linux_argc++; ++ ++ initrd_loaded = 1; ++ ++ fail: ++ grub_initrd_close (&initrd_ctx); ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_linux, cmd_initrd; ++ ++GRUB_MOD_INIT(linux) ++{ ++ cmd_linux = grub_register_command ("linux", grub_cmd_linux, ++ 0, N_("Load Linux.")); ++ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, ++ 0, 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/dl.h b/include/grub/dl.h +index 6a3e251..c1b6dd9 100644 +--- a/include/grub/dl.h ++++ b/include/grub/dl.h +@@ -314,7 +314,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + #define GRUB_ARCH_DL_GOT_ALIGN 4 + #endif + +-#if defined (__aarch64__) || defined (__sparc__) ++#if defined (__aarch64__) || defined (__sparc__) || defined (__loongarch64) + #define GRUB_ARCH_DL_TRAMP_ALIGN 8 + #define GRUB_ARCH_DL_GOT_ALIGN 8 + #endif +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 37e7b16..049326c 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -2087,7 +2087,8 @@ struct grub_efi_rng_protocol + typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; + + #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ +- || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) ++ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ ++ || defined (__loongarch64) + + #define efi_call_0(func) func() + #define efi_call_1(func, a) func(a) +diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h +index c03cc59..be88c54 100644 +--- a/include/grub/efi/pe32.h ++++ b/include/grub/efi/pe32.h +@@ -66,6 +66,7 @@ struct grub_pe32_coff_header + }; + + #define GRUB_PE32_MACHINE_I386 0x14c ++#define GRUB_PE32_MACHINE_LOONGARCH64 0x6264 + #define GRUB_PE32_MACHINE_IA64 0x200 + #define GRUB_PE32_MACHINE_X86_64 0x8664 + #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 +@@ -329,6 +330,7 @@ struct grub_pe32_fixup_block + #define GRUB_PE32_REL_BASED_IA64_IMM64 9 + #define GRUB_PE32_REL_BASED_DIR64 10 + #define GRUB_PE32_REL_BASED_HIGH3ADJ 11 ++#define GRUB_PE32_REL_BASED_LOONGARCH64 8 + + struct grub_pe32_symbol + { +diff --git a/include/grub/elf.h b/include/grub/elf.h +index c8492f9..2c0b163 100644 +--- a/include/grub/elf.h ++++ b/include/grub/elf.h +@@ -247,6 +247,7 @@ typedef struct + #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ + #define EM_NUM 95 + #define EM_AARCH64 183 /* ARM 64-bit architecture */ ++#define EM_LOONGARCH64 258 /* LoongArch64 architecture */ + + /* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the +@@ -1448,6 +1449,60 @@ typedef struct + #define OHWA0_R4KEOP_CHECKED 0x00000001 + #define OHWA1_R4KEOP_CLEAN 0x00000002 + ++/* LOONGARCH64 relocs. */ ++#define R_LARCH_NONE 0 ++#define R_LARCH_32 1 ++#define R_LARCH_64 2 ++#define R_LARCH_RELATIVE 3 ++#define R_LARCH_COPY 4 ++#define R_LARCH_JUMP_SLOT 5 ++#define R_LARCH_TLS_DTPMOD32 6 ++#define R_LARCH_TLS_DTPMOD64 7 ++#define R_LARCH_TLS_DTPREL32 8 ++#define R_LARCH_TLS_DTPREL64 9 ++#define R_LARCH_TLS_TPREL32 10 ++#define R_LARCH_TLS_TPREL64 11 ++#define R_LARCH_IRELATIVE 12 ++#define R_LARCH_MARK_LA 20 ++#define R_LARCH_MARK_PCREL 21 ++#define R_LARCH_SOP_PUSH_PCREL 22 ++#define R_LARCH_SOP_PUSH_ABSOLUTE 23 ++#define R_LARCH_SOP_PUSH_DUP 24 ++#define R_LARCH_SOP_PUSH_GPREL 25 ++#define R_LARCH_SOP_PUSH_TLS_TPREL 26 ++#define R_LARCH_SOP_PUSH_TLS_GOT 27 ++#define R_LARCH_SOP_PUSH_TLS_GD 28 ++#define R_LARCH_SOP_PUSH_PLT_PCREL 29 ++#define R_LARCH_SOP_ASSERT 30 ++#define R_LARCH_SOP_NOT 31 ++#define R_LARCH_SOP_SUB 32 ++#define R_LARCH_SOP_SL 33 ++#define R_LARCH_SOP_SR 34 ++#define R_LARCH_SOP_ADD 35 ++#define R_LARCH_SOP_AND 36 ++#define R_LARCH_SOP_IF_ELSE 37 ++#define R_LARCH_SOP_POP_32_S_10_5 38 ++#define R_LARCH_SOP_POP_32_U_10_12 39 ++#define R_LARCH_SOP_POP_32_S_10_12 40 ++#define R_LARCH_SOP_POP_32_S_10_16 41 ++#define R_LARCH_SOP_POP_32_S_10_16_S2 42 ++#define R_LARCH_SOP_POP_32_S_5_20 43 ++#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 ++#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 ++#define R_LARCH_SOP_POP_32_U 46 ++#define R_LARCH_ADD8 47 ++#define R_LARCH_ADD16 48 ++#define R_LARCH_ADD24 49 ++#define R_LARCH_ADD32 50 ++#define R_LARCH_ADD64 51 ++#define R_LARCH_SUB8 52 ++#define R_LARCH_SUB16 53 ++#define R_LARCH_SUB24 54 ++#define R_LARCH_SUB32 55 ++#define R_LARCH_SUB64 56 ++#define R_LARCH_GNU_VTINHERIT 57 ++#define R_LARCH_GNU_VTENTRY 58 ++ + /* MIPS relocs. */ + + #define R_MIPS_NONE 0 /* No reloc */ +diff --git a/include/grub/loongarch64/asm.h b/include/grub/loongarch64/asm.h +new file mode 100644 +index 0000000..c3e77e9 +--- /dev/null ++++ b/include/grub/loongarch64/asm.h +@@ -0,0 +1,10 @@ ++#ifndef GRUB_LOONGARCH64_ASM_HEADER ++#define GRUB_LOONGARCH64_ASM_HEADER 1 ++ ++#define GRUB_ASM_T4 $a4 ++#define GRUB_ASM_T5 $a5 ++#define GRUB_ASM_SZREG 8 ++#define GRUB_ASM_REG_S st.d ++#define GRUB_ASM_REG_L ld.d ++ ++#endif +diff --git a/include/grub/loongarch64/efi/boot.h b/include/grub/loongarch64/efi/boot.h +new file mode 100644 +index 0000000..e69de29 +diff --git a/include/grub/loongarch64/efi/loader.h b/include/grub/loongarch64/efi/loader.h +new file mode 100644 +index 0000000..71a0159 +--- /dev/null ++++ b/include/grub/loongarch64/efi/loader.h +@@ -0,0 +1,25 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2003,2004,2006,2007,2017 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 . ++ */ ++ ++#ifndef GRUB_LOADER_MACHINE_HEADER ++#define GRUB_LOADER_MACHINE_HEADER 1 ++ ++#include ++#include ++ ++#endif /* ! GRUB_LOADER_MACHINE_HEADER */ +diff --git a/include/grub/loongarch64/efi/loongson.h b/include/grub/loongarch64/efi/loongson.h +new file mode 100644 +index 0000000..fa32ef5 +--- /dev/null ++++ b/include/grub/loongarch64/efi/loongson.h +@@ -0,0 +1,290 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#ifndef GRUB_EFI_LOONGSON_HEADER ++#define GRUB_EFI_LOONGSON_HEADER 1 ++ ++#include ++ ++#include ++ ++#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \ ++ { 0x4660f721, 0x2ec5, 0x416a, \ ++ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ ++ } ++ ++#define GRUB_EFI_LOONGSON_MMAP_MAX 128 ++typedef enum ++ { ++ GRUB_EFI_LOONGSON_SYSTEM_RAM = 1, ++ GRUB_EFI_LOONGSON_MEMORY_RESERVED, ++ GRUB_EFI_LOONGSON_ACPI_TABLE, ++ GRUB_EFI_LOONGSON_ACPI_NVS, ++ GRUB_EFI_LOONGSON_MAX_MEMORY_TYPE ++ } ++grub_efi_loongson_memory_type; ++ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ grub_uint32_t nr_map; /* number of memory_maps */ ++ grub_uint32_t mem_freq; /* memory frequence */ ++ struct mem_map { ++ grub_uint32_t node_id; /* node_id which memory attached to */ ++ grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ ++ grub_uint64_t mem_start; /* memory map start address */ ++ grub_uint32_t mem_size; /* each memory_map size, not the total size */ ++ } map[GRUB_EFI_LOONGSON_MMAP_MAX]; ++} GRUB_PACKED ++grub_efi_loongson_memory_map; ++ ++/* ++ * Capability and feature descriptor structure for LOONGARCH CPU ++ */ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ ++ grub_uint32_t cputype; /* Loongson_3A/3B, etc. */ ++ grub_uint32_t total_node; /* num of total numa nodes */ ++ grub_uint16_t cpu_startup_core_id; /* Boot core id */ ++ grub_uint16_t reserved_cores_mask; ++ grub_uint32_t cpu_clock_freq; /* cpu_clock */ ++ grub_uint32_t nr_cpus; ++} GRUB_PACKED ++grub_efi_loongson_cpu_info; ++ ++#define GRUB_EFI_LOONGSON_MAX_UARTS 64 ++ ++typedef struct ++{ ++ grub_uint32_t iotype; /* see include/linux/serial_core.h */ ++ grub_uint32_t uartclk; ++ grub_uint32_t int_offset; ++ grub_uint64_t uart_base; ++} GRUB_PACKED ++grub_efi_loongson_uart_device; ++ ++#define GRUB_EFI_LOONGSON_MAX_SENSORS 64 ++ ++typedef struct ++{ ++ char name[32]; /* a formal name */ ++ char label[64]; /* a flexible description */ ++ grub_uint32_t type; /* SENSOR_* */ ++ grub_uint32_t id; /* instance id of a sensor-class */ ++ grub_uint32_t fan_policy; ++ grub_uint32_t fan_percent; /* only for constant speed policy */ ++ grub_uint64_t base_addr; /* base address of device registers */ ++} GRUB_PACKED ++grub_efi_loongson_sensor_device; ++ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ ++ grub_uint32_t sing_double_channel; /* 1:single; 2:double */ ++ grub_uint32_t nr_uarts; ++ grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS]; ++ grub_uint32_t nr_sensors; ++ grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS]; ++ char has_ec; ++ char ec_name[32]; ++ grub_uint64_t ec_base_addr; ++ char has_tcm; ++ char tcm_name[32]; ++ grub_uint64_t tcm_base_addr; ++ grub_uint64_t workarounds; /* see workarounds.h */ ++} GRUB_PACKED ++grub_efi_loongson_system_info; ++ ++typedef struct ++{ ++ grub_uint16_t vers; ++ grub_uint16_t size; ++ grub_uint16_t rtr_bus; ++ grub_uint16_t rtr_devfn; ++ grub_uint32_t vendor; ++ grub_uint32_t device; ++ grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ ++ grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ ++ grub_uint64_t ht_enable; /* irqs used in this PIC */ ++ grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ ++ grub_uint64_t pci_mem_start_addr; ++ grub_uint64_t pci_mem_end_addr; ++ grub_uint64_t pci_io_start_addr; ++ grub_uint64_t pci_io_end_addr; ++ grub_uint64_t pci_config_addr; ++ grub_uint32_t dma_mask_bits; ++} GRUB_PACKED ++grub_efi_loongson_irq_src_routing_table; ++ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ grub_uint16_t size; ++ grub_uint8_t flag; ++ char description[64]; ++} GRUB_PACKED ++grub_efi_loongson_interface_info; ++ ++#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128 ++ ++typedef struct ++{ ++ grub_uint64_t start; /* resource start address */ ++ grub_uint64_t end; /* resource end address */ ++ char name[64]; ++ grub_uint32_t flags; ++} ++grub_efi_loongson_resource; ++ ++/* arch specific additions */ ++typedef struct ++{ ++} ++grub_efi_loongson_archdev_data; ++ ++typedef struct ++{ ++ char name[64]; /* hold the device name */ ++ grub_uint32_t num_resources; /* number of device_resource */ ++ /* for each device's resource */ ++ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; ++ /* arch specific additions */ ++ grub_efi_loongson_archdev_data archdata; ++} ++grub_efi_loongson_board_devices; ++ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ char special_name[64]; /* special_atribute_name */ ++ grub_uint32_t loongson_special_type; /* type of special device */ ++ /* for each device's resource */ ++ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; ++} ++grub_efi_loongson_special_attribute; ++ ++typedef struct ++{ ++ grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */ ++ grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */ ++ grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */ ++ grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */ ++ grub_uint64_t interface_offset; /* interface_info struct offset */ ++ grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */ ++ grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */ ++} ++grub_efi_loongson_params; ++ ++typedef struct ++{ ++ grub_uint16_t vers; /* version */ ++ grub_uint64_t vga_bios; /* vga_bios address */ ++ grub_efi_loongson_params lp; ++} ++grub_efi_loongson_smbios_table; ++ ++typedef struct ++{ ++ grub_uint64_t reset_cold; ++ grub_uint64_t reset_warm; ++ grub_uint64_t reset_type; ++ grub_uint64_t shutdown; ++ grub_uint64_t do_suspend; /* NULL if not support */ ++} ++grub_efi_loongson_reset_system; ++ ++typedef struct ++{ ++ grub_uint64_t mps; /* MPS table */ ++ grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ ++ grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ ++ grub_efi_loongson_smbios_table smbios; /* SM BIOS table */ ++ grub_uint64_t sal_systab; /* SAL system table */ ++ grub_uint64_t boot_info; /* boot info table */ ++} ++grub_efi_loongson; ++ ++typedef struct ++{ ++ grub_efi_loongson efi; ++ grub_efi_loongson_reset_system reset_system; ++} ++grub_efi_loongson_boot_params; ++ ++extern grub_uint64_t grub_efi_loongson_reset_system_addr; ++ ++extern void grub_efi_loongson_reset_cold (void); ++extern void grub_efi_loongson_reset_warm (void); ++extern void grub_efi_loongson_reset_shutdown (void); ++extern void grub_efi_loongson_reset_suspend (void); ++ ++void grub_efi_loongson_alloc_boot_params (void); ++void grub_efi_loongson_free_boot_params (void); ++void * grub_efi_loongson_get_smbios_table (void); ++ ++int EXPORT_FUNC(grub_efi_is_loongson) (void); ++ ++grub_uint8_t ++EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++ ++grub_uint8_t ++EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++ ++ ++void * ++EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); ++ ++typedef struct _extention_list_hdr{ ++ grub_uint64_t signature; ++ grub_uint32_t length; ++ grub_uint8_t revision; ++ grub_uint8_t checksum; ++ struct _extention_list_hdr *next; ++}GRUB_PACKED ++ext_list; ++ ++typedef struct bootparamsinterface { ++ grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'} ++ grub_efi_system_table_t *systemtable; ++ ext_list *extlist; ++}GRUB_PACKED ++bootparamsinterface; ++ ++typedef struct { ++ ext_list header; // {'M', 'E', 'M'} ++ grub_uint8_t mapcount; ++ struct GRUB_PACKED memmap { ++ grub_uint32_t memtype; ++ grub_uint64_t memstart; ++ grub_uint64_t memsize; ++ } map[GRUB_EFI_LOONGSON_MMAP_MAX]; ++}GRUB_PACKED ++mem_map; ++ ++typedef struct { ++ ext_list header; // {VBIOS} ++ grub_uint64_t vbiosaddr; ++}GRUB_PACKED ++vbios; ++ ++grub_uint32_t ++EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype); ++#endif /* ! GRUB_EFI_LOONGSON_HEADER */ +diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h +new file mode 100644 +index 0000000..b8556c7 +--- /dev/null ++++ b/include/grub/loongarch64/efi/memory.h +@@ -0,0 +1,14 @@ ++#ifndef GRUB_MEMORY_CPU_HEADER ++#include ++ ++#define GRUB_EFI_MAX_USABLE_ADDRESS 0x9800000fffffffffUL ++#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS ++ ++static inline grub_uint64_t grub_efi_max_usable_address(void) ++{ ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ return addr |= 0xffffffffffUL; ++} ++ ++#endif /* ! GRUB_MEMORY_CPU_HEADER */ +diff --git a/include/grub/loongarch64/efi/time.h b/include/grub/loongarch64/efi/time.h +new file mode 100644 +index 0000000..e69de29 +diff --git a/include/grub/loongarch64/io.h b/include/grub/loongarch64/io.h +new file mode 100644 +index 0000000..5f34103 +--- /dev/null ++++ b/include/grub/loongarch64/io.h +@@ -0,0 +1,62 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2009,2017 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 . ++ */ ++ ++#ifndef GRUB_IO_H ++#define GRUB_IO_H 1 ++ ++#include ++ ++typedef grub_addr_t grub_port_t; ++ ++static __inline unsigned char ++grub_inb (grub_port_t port) ++{ ++ return *(volatile grub_uint8_t *) port; ++} ++ ++static __inline unsigned short int ++grub_inw (grub_port_t port) ++{ ++ return *(volatile grub_uint16_t *) port; ++} ++ ++static __inline unsigned int ++grub_inl (grub_port_t port) ++{ ++ return *(volatile grub_uint32_t *) port; ++} ++ ++static __inline void ++grub_outb (unsigned char value, grub_port_t port) ++{ ++ *(volatile grub_uint8_t *) port = value; ++} ++ ++static __inline void ++grub_outw (unsigned short int value, grub_port_t port) ++{ ++ *(volatile grub_uint16_t *) port = value; ++} ++ ++static __inline void ++grub_outl (unsigned int value, grub_port_t port) ++{ ++ *(volatile grub_uint32_t *) port = value; ++} ++ ++#endif /* _SYS_IO_H */ +diff --git a/include/grub/loongarch64/kernel.h b/include/grub/loongarch64/kernel.h +new file mode 100644 +index 0000000..909d539 +--- /dev/null ++++ b/include/grub/loongarch64/kernel.h +@@ -0,0 +1,24 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2005,2006,2007,2008,2009,2017 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 . ++ */ ++ ++#ifndef GRUB_KERNEL_CPU_HEADER ++#define GRUB_KERNEL_CPU_HEADER 1 ++ ++#include ++ ++#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ +diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h +new file mode 100644 +index 0000000..cbf8775 +--- /dev/null ++++ b/include/grub/loongarch64/linux.h +@@ -0,0 +1,22 @@ ++/* ++ * 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 . ++ */ ++ ++#ifndef GRUB_LOONGARCH64_LINUX_HEADER ++#define GRUB_LOONGARCH64_LINUX_HEADER 1 ++ ++#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ +diff --git a/include/grub/loongarch64/loongarch64.h b/include/grub/loongarch64/loongarch64.h +new file mode 100644 +index 0000000..ea3be3d +--- /dev/null ++++ b/include/grub/loongarch64/loongarch64.h +@@ -0,0 +1,30 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2010,2017 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 . ++ */ ++ ++#ifndef GRUB_REGISTERS_CPU_HEADER ++#define GRUB_REGISTERS_CPU_HEADER 1 ++ ++#ifdef ASM_FILE ++#define GRUB_CPU_REGISTER_WRAP(x) x ++#else ++#define GRUB_CPU_REGISTER_WRAP(x) #x ++#endif ++ ++#define GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP(9) ++ ++#endif +diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h +new file mode 100644 +index 0000000..03398b3 +--- /dev/null ++++ b/include/grub/loongarch64/memory.h +@@ -0,0 +1,57 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#ifndef GRUB_MEMORY_CPU_HEADER ++#define GRUB_MEMORY_CPU_HEADER 1 ++ ++#ifndef ASM_FILE ++#include ++#include ++#include ++#endif ++ ++#ifndef ASM_FILE ++ ++typedef grub_addr_t grub_phys_addr_t; ++ ++static inline grub_phys_addr_t ++grub_vtop (void *a) ++{ ++ if (-1 == ((grub_int64_t) a >> 32)) ++ return ((grub_phys_addr_t) a) & 0x1fffffffUL; ++ return ((grub_phys_addr_t) a) & 0xffffffffffffUL; ++} ++ ++static inline void * ++grub_map_memory (grub_phys_addr_t a, grub_size_t size) ++{ ++ grub_uint64_t addr; ++ ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ return (void *) (a | (addr & 0xffffffffffffff00UL)); ++} ++ ++static inline void ++grub_unmap_memory (void *a __attribute__ ((unused)), ++ grub_size_t size __attribute__ ((unused))) ++{ ++} ++ ++#endif ++ ++#endif +diff --git a/include/grub/loongarch64/relocator.h b/include/grub/loongarch64/relocator.h +new file mode 100644 +index 0000000..8815314 +--- /dev/null ++++ b/include/grub/loongarch64/relocator.h +@@ -0,0 +1,38 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2017 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 . ++ */ ++ ++#ifndef GRUB_RELOCATOR_CPU_HEADER ++#define GRUB_RELOCATOR_CPU_HEADER 1 ++ ++#include ++#include ++#include ++ ++struct grub_relocator64_state ++{ ++ /* gpr[0] is ignored since it's hardwired to 0. */ ++ grub_uint64_t gpr[32]; ++ /* Register holding target $pc. */ ++ int jumpreg; ++}; ++ ++grub_err_t ++grub_relocator64_boot (struct grub_relocator *rel, ++ struct grub_relocator64_state state); ++ ++#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ +diff --git a/include/grub/loongarch64/setjmp.h b/include/grub/loongarch64/setjmp.h +new file mode 100644 +index 0000000..d9a0776 +--- /dev/null ++++ b/include/grub/loongarch64/setjmp.h +@@ -0,0 +1,27 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2004,2006,2007,2009,2017 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 . ++ */ ++ ++#ifndef GRUB_SETJMP_CPU_HEADER ++#define GRUB_SETJMP_CPU_HEADER 1 ++ ++typedef grub_uint64_t grub_jmp_buf[12]; ++ ++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/loongarch64/time.h b/include/grub/loongarch64/time.h +new file mode 100644 +index 0000000..c9a7334 +--- /dev/null ++++ b/include/grub/loongarch64/time.h +@@ -0,0 +1,39 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2003,2004,2005,2007,2017 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 . ++ */ ++ ++#ifndef KERNEL_CPU_TIME_HEADER ++#define KERNEL_CPU_TIME_HEADER 1 ++ ++#ifndef GRUB_UTIL ++ ++#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) ++ ++void grub_timer_init (grub_uint32_t cpuclock); ++ ++/* Return the real time in ticks. */ ++grub_uint64_t grub_get_rtc (void); ++ ++extern grub_uint32_t grub_arch_cpuclock; ++#endif ++ ++static inline void ++grub_cpu_idle(void) ++{ ++} ++ ++#endif +diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h +new file mode 100644 +index 0000000..5dc7f21 +--- /dev/null ++++ b/include/grub/loongarch64/types.h +@@ -0,0 +1,34 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2006,2007,2009,2017 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 . ++ */ ++ ++#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 ++ ++#ifdef GRUB_CPU_LOONGARCH ++/* loongarch is little-endian. */ ++#undef GRUB_TARGET_WORDS_BIGENDIAN ++ ++#endif /* ! GRUB_TYPES_CPU_HEADER */ ++ ++#endif +diff --git a/include/grub/util/install.h b/include/grub/util/install.h +index dad1756..33feae9 100644 +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -107,6 +107,7 @@ enum grub_install_plat + GRUB_INSTALL_PLATFORM_X86_64_XEN, + GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_ARM_COREBOOT, ++ GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, + GRUB_INSTALL_PLATFORM_MAX + }; + +diff --git a/util/grub-install-common.c b/util/grub-install-common.c +index fde4ca7..6504637 100644 +--- a/util/grub-install-common.c ++++ b/util/grub-install-common.c +@@ -738,27 +738,28 @@ static struct + const char *platform; + } platforms[GRUB_INSTALL_PLATFORM_MAX] = + { +- [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, +- [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, +- [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, +- [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, +- [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, +- [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, +- [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, +- [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, +- [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, +- [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, +- [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, +- [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, +- [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, +- [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, +- [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, +- [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, +- [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, +- [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, +- [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, +- [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, +- [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, ++ [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, ++ [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, ++ [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, ++ [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, ++ [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, ++ [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, ++ [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, ++ [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, ++ [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, ++ [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, ++ [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, ++ [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, ++ [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, ++ [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, ++ [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, ++ [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, ++ [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, ++ [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, ++ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, ++ [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, ++ [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, ++ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, + }; + + char * +diff --git a/util/grub-install.c b/util/grub-install.c +index 65bb2f9..28b5d74 100644 +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -322,6 +322,8 @@ get_default_platform (void) + return "arm-uboot"; + #elif defined (__aarch64__) + return "arm64-efi"; ++#elif defined (__loongarch64) ++ return "loongarch64-efi"; + #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) + return grub_install_get_default_x86_platform (); + #else +@@ -477,6 +479,7 @@ have_bootdev (enum grub_install_plat pl) + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: +@@ -895,6 +898,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + is_efi = 1; + grub_util_error (_("this utility cannot be used for EFI platforms" + " because it does not support UEFI Secure Boot")); +@@ -921,6 +925,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: +@@ -965,6 +970,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: +@@ -1110,6 +1116,9 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "BOOTAA64.EFI"; + break; ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: ++ efi_file = "BOOTLOONGARCH64.EFI"; ++ break; + default: + grub_util_error ("%s", _("You've found a bug")); + break; +@@ -1137,6 +1146,9 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "grubaa64.efi"; + break; ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: ++ efi_file = "grubloongarch64.efi"; ++ break; + default: + efi_file = "grub.efi"; + break; +@@ -1440,6 +1452,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + g = grub_util_guess_efi_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: +@@ -1581,6 +1594,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + core_name = "core.efi"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", +@@ -1683,6 +1697,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: +@@ -1917,6 +1932,7 @@ main (int argc, char *argv[]) + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: ++ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + { + char *dst = grub_util_path_concat (2, efidir, efi_file); + grub_install_copy_file (imgfile, dst, 1); +diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c +index 1bb5eb8..240e193 100644 +--- a/util/grub-mkimagexx.c ++++ b/util/grub-mkimagexx.c +@@ -783,6 +783,9 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, + struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); + grub_uint64_t *gpptr = (void *) (pe_target + got_off); + unsigned unmatched_adr_got_page = 0; ++ grub_uint64_t oprs[10240]= {0}; ++ int opri = -1; ++ grub_uint32_t la_abs = 0; + #define MASK19 ((1 << 19) - 1) + #else + grub_uint32_t *tr = (void *) (pe_target + tramp_off); +@@ -1122,6 +1125,173 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, + } + break; + } ++ case EM_LOONGARCH64: ++ { ++ sym_addr += addend; ++ switch (ELF_R_TYPE (info)) ++ { ++ case R_LARCH_64: ++ { ++ *target=(grub_uint64_t)sym_addr; ++ } ++ break; ++ case R_LARCH_MARK_LA: ++ { ++ la_abs=1; ++ } ++ break; ++ case R_LARCH_SOP_PUSH_PCREL: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)(sym_addr-(target_section_addr+offset+image_target->vaddr_offset)); ++ } ++ break; ++ case R_LARCH_SOP_PUSH_ABSOLUTE: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)sym_addr; ++ } ++ break; ++ case R_LARCH_SOP_PUSH_PLT_PCREL: ++ { ++ opri++; ++ oprs[opri]=(grub_uint64_t)(sym_addr-(target_section_addr+offset+image_target->vaddr_offset)); ++ } ++ break; ++ case R_LARCH_SOP_SUB: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 - opr2; ++ } ++ break; ++ case R_LARCH_SOP_SL: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 << opr2; ++ } ++ break; ++ case R_LARCH_SOP_SR: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 >> opr2; ++ } ++ break; ++ case R_LARCH_SOP_ADD: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 + opr2; ++ } ++ break; ++ case R_LARCH_SOP_AND: ++ { ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ opri++; ++ oprs[opri]=opr1 & opr2; ++ } ++ break; ++ case R_LARCH_SOP_IF_ELSE: ++ { ++ grub_uint64_t opr3=oprs[opri]; ++ opri--; ++ grub_uint64_t opr2=oprs[opri]; ++ opri--; ++ grub_uint64_t opr1=oprs[opri]; ++ opri--; ++ if(opr1){ ++ opri++; ++ oprs[opri]=opr2; ++ } else { ++ opri++; ++ oprs[opri]=opr3; ++ } ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_5: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target=(*target) | ((opr1 & 0x1f) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_U_10_12: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target=(*target) | ((opr1 & 0xfff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_12: ++ { ++ if(la_abs==1) ++ la_abs=0; ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target = (*target) | ((opr1 & 0xfff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target = (*target) | ((opr1 & 0xffff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target = (*target) | (((opr1 >> 2) & 0xffff) << 10); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_5_20: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target = (*target) | ((opr1 & 0xfffff)<<5) ; ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target =(*target) | (((opr1 >> 2) & 0xffff) << 10); ++ *target =(*target) | ((opr1 >> 18) & 0x1f); ++ } ++ break; ++ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: ++ { ++ grub_uint64_t opr1 = oprs[opri]; ++ opri--; ++ *target =(*target) | (((opr1 >> 2) & 0xffff) << 10); ++ *target =(*target) | ((opr1 >> 18) & 0x3ff); ++ } ++ break; ++ default: ++ grub_util_error (_("relocation 0x%x is not implemented yet"), ++ (unsigned int) ELF_R_TYPE (info)); ++ break; ++ } ++ break; ++ } + #endif + #if defined(MKIMAGE_ELF32) + case EM_ARM: +@@ -1310,7 +1480,10 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ +- b->page_rva = (addr & ~(0x1000 - 1)); ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (type) ++#endif ++ b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + +@@ -1320,7 +1493,11 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + + /* Add a new entry. */ + cur_index = ((b->block_size - sizeof (*b)) >> 1); ++#ifdef GRUB_CPU_LOONGARCH64 ++ entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); ++#else + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); ++#endif + b->entries[cur_index] = grub_host_to_target16 (entry); + b->block_size += 2; + } +@@ -1366,6 +1543,10 @@ static void + translate_relocation_pe (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, ++#ifdef GRUB_CPU_LOONGARCH64 ++ Elf_Addr sym_addr, ++ Elf_Addr addend, ++#endif + const struct grub_install_image_target_desc *image_target) + { + /* Necessary to relocate only absolute addresses. */ +@@ -1477,6 +1658,133 @@ translate_relocation_pe (struct translate_context *ctx, + } + break; + break; ++ case EM_LOONGARCH64: ++ switch (ELF_R_TYPE (info)) ++ { ++ case R_LARCH_NONE: ++ break; ++ case R_LARCH_32: ++ break; ++ case R_LARCH_64: ++ { ++ ctx->current_address = add_fixup_entry ( ++ &ctx->lst, ++ GRUB_PE32_REL_BASED_DIR64, ++ addr, 0, ctx->current_address, ++ image_target); ++ } ++ break; ++ case R_LARCH_RELATIVE: ++ break; ++ case R_LARCH_COPY: ++ break; ++ case R_LARCH_JUMP_SLOT: ++ break; ++ case R_LARCH_TLS_DTPMOD32: ++ break; ++ case R_LARCH_TLS_DTPMOD64: ++ break; ++ case R_LARCH_TLS_DTPREL32: ++ break; ++ case R_LARCH_TLS_DTPREL64: ++ break; ++ case R_LARCH_TLS_TPREL32: ++ break; ++ case R_LARCH_TLS_TPREL64: ++ break; ++ case R_LARCH_IRELATIVE: ++ break; ++ case R_LARCH_MARK_LA: ++ { ++ ctx->current_address = add_fixup_entry ( ++ &ctx->lst, ++ GRUB_PE32_REL_BASED_LOONGARCH64, ++ addr, 0, ctx->current_address, ++ image_target); ++ } ++ break; ++ case R_LARCH_MARK_PCREL: ++ break; ++ case R_LARCH_SOP_PUSH_PCREL: ++ break; ++ case R_LARCH_SOP_PUSH_ABSOLUTE: ++ break; ++ case R_LARCH_SOP_PUSH_DUP: ++ break; ++ case R_LARCH_SOP_PUSH_GPREL: ++ break; ++ case R_LARCH_SOP_PUSH_TLS_TPREL: ++ break; ++ case R_LARCH_SOP_PUSH_TLS_GOT: ++ break; ++ case R_LARCH_SOP_PUSH_TLS_GD: ++ break; ++ case R_LARCH_SOP_PUSH_PLT_PCREL: ++ break; ++ case R_LARCH_SOP_ASSERT: ++ break; ++ case R_LARCH_SOP_NOT: ++ break; ++ case R_LARCH_SOP_SUB: ++ break; ++ case R_LARCH_SOP_SL: ++ break; ++ case R_LARCH_SOP_SR: ++ break; ++ case R_LARCH_SOP_ADD: ++ break; ++ case R_LARCH_SOP_AND: ++ break; ++ case R_LARCH_SOP_IF_ELSE: ++ break; ++ case R_LARCH_SOP_POP_32_S_10_5: ++ break; ++ case R_LARCH_SOP_POP_32_U_10_12: ++ break; ++ case R_LARCH_SOP_POP_32_S_10_12: ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16: ++ break; ++ case R_LARCH_SOP_POP_32_S_10_16_S2: ++ break; ++ case R_LARCH_SOP_POP_32_S_5_20: ++ break; ++ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: ++ break; ++ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: ++ break; ++ case R_LARCH_SOP_POP_32_U: ++ break; ++ case R_LARCH_ADD8: ++ break; ++ case R_LARCH_ADD16: ++ break; ++ case R_LARCH_ADD24: ++ break; ++ case R_LARCH_ADD32: ++ break; ++ case R_LARCH_ADD64: ++ break; ++ case R_LARCH_SUB8: ++ break; ++ case R_LARCH_SUB16: ++ break; ++ case R_LARCH_SUB24: ++ break; ++ case R_LARCH_SUB32: ++ break; ++ case R_LARCH_SUB64: ++ break; ++ case R_LARCH_GNU_VTINHERIT: ++ break; ++ case R_LARCH_GNU_VTENTRY: ++ break; ++ default: ++ grub_util_error (_("relocation 0x%x is not implemented yet"), ++ (unsigned int) ELF_R_TYPE (info)); ++ break; ++ } ++ break; + #if defined(MKIMAGE_ELF32) + case EM_ARM: + switch (ELF_R_TYPE (info)) +@@ -1565,10 +1873,18 @@ static void + translate_relocation (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, ++#ifdef GRUB_CPU_LOONGARCH64 ++ Elf_Addr sym_addr, ++ Elf_Addr addend, ++#endif + const struct grub_install_image_target_desc *image_target) + { + if (image_target->id == IMAGE_EFI) ++#ifdef GRUB_CPU_LOONGARCH64 ++ translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target); ++#else + translate_relocation_pe (ctx, addr, info, image_target); ++#endif + else + translate_relocation_raw (ctx, addr, info, image_target); + } +@@ -1709,11 +2025,21 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, + if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || + (grub_target_to_host32 (s->sh_type) == SHT_RELA)) + { ++#ifdef GRUB_CPU_LOONGARCH64 ++ Elf_Rela *r; ++#else + Elf_Rel *r; ++#endif + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; ++#ifdef GRUB_CPU_LOONGARCH64 ++ Elf_Shdr *symtab_section; ++ ++ symtab_section = (Elf_Shdr *) ((char *) smd->sections ++ + (grub_target_to_host32 (s->sh_link) * smd->section_entsize)); ++#endif + + if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { +@@ -1732,20 +2058,39 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, + + section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)]; + ++#ifdef GRUB_CPU_LOONGARCH64 ++ for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); ++ j < num_rs; ++ j++, r = (Elf_Rela *) ((char *) r + r_size)) ++#else + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) ++#endif + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr addr; ++#ifdef GRUB_CPU_LOONGARCH64 ++ Elf_Addr sym_addr; ++ Elf_Addr addend; ++#endif + + offset = grub_target_to_host (r->r_offset); + info = grub_target_to_host (r->r_info); +- ++#ifdef GRUB_CPU_LOONGARCH64 ++ sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, ++ ELF_R_SYM (info), image_target); ++ addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? ++ grub_target_to_host (r->r_addend) : 0; ++#endif + addr = section_address + offset; + ++#ifdef GRUB_CPU_LOONGARCH64 ++ translate_relocation (&ctx, addr, info, sym_addr, addend, image_target); ++#else + translate_relocation (&ctx, addr, info, image_target); ++#endif + } + } + +diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c +index ae31271..c998850 100644 +--- a/util/grub-mknetdir.c ++++ b/util/grub-mknetdir.c +@@ -112,7 +112,8 @@ static struct + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }, +- [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" } ++ [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }, ++ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64-efi", "efinet", ".efi" } + }; + + static void +diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c +index 03ba1ab..4a9943a 100644 +--- a/util/grub-module-verifier.c ++++ b/util/grub-module-verifier.c +@@ -119,6 +119,52 @@ struct grub_module_verifier_arch archs[] = { + -1 + } + }, ++ { "loongarch64", 8, 0, EM_LOONGARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ ++ R_LARCH_NONE, ++ R_LARCH_32, ++ R_LARCH_64, ++ R_LARCH_RELATIVE, ++ R_LARCH_COPY, ++ R_LARCH_JUMP_SLOT, ++ R_LARCH_TLS_DTPMOD32, ++ R_LARCH_TLS_DTPMOD64, ++ R_LARCH_TLS_DTPREL32, ++ R_LARCH_TLS_DTPREL64, ++ R_LARCH_TLS_TPREL32, ++ R_LARCH_TLS_TPREL64, ++ R_LARCH_IRELATIVE, ++ R_LARCH_MARK_LA, ++ R_LARCH_MARK_PCREL, ++ R_LARCH_SOP_PUSH_PCREL, ++ R_LARCH_SOP_PUSH_ABSOLUTE, ++ R_LARCH_SOP_PUSH_DUP, ++ R_LARCH_SOP_PUSH_GPREL, ++ R_LARCH_SOP_PUSH_TLS_TPREL, ++ R_LARCH_SOP_PUSH_TLS_GOT, ++ R_LARCH_SOP_PUSH_TLS_GD, ++ R_LARCH_SOP_PUSH_PLT_PCREL, ++ R_LARCH_SOP_ASSERT, ++ R_LARCH_SOP_NOT, ++ R_LARCH_SOP_SUB, ++ R_LARCH_SOP_SL, ++ R_LARCH_SOP_SR, ++ R_LARCH_SOP_ADD, ++ R_LARCH_SOP_AND, ++ R_LARCH_SOP_IF_ELSE, ++ R_LARCH_SOP_POP_32_S_10_5, ++ R_LARCH_SOP_POP_32_U_10_12, ++ R_LARCH_SOP_POP_32_S_10_12, ++ R_LARCH_SOP_POP_32_S_10_16, ++ R_LARCH_SOP_POP_32_S_10_16_S2, ++ R_LARCH_SOP_POP_32_S_5_20, ++ R_LARCH_SOP_POP_32_S_0_5_10_16_S2, ++ R_LARCH_SOP_POP_32_S_0_10_10_16_S2, ++ R_LARCH_SOP_POP_32_U, ++ -1 ++ }, (int[]){ ++ -1 ++ } ++ }, + }; + + struct platform_whitelist { +diff --git a/util/mkimage.c b/util/mkimage.c +index 16418e2..0d39c07 100644 +--- a/util/mkimage.c ++++ b/util/mkimage.c +@@ -609,6 +609,22 @@ static const struct grub_install_image_target_desc image_targets[] = + .pe_target = GRUB_PE32_MACHINE_ARM64, + .elf_target = EM_AARCH64, + }, ++ { ++ .dirname = "loongarch64-efi", ++ .names = { "loongarch64-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_LOONGARCH64, ++ .elf_target = EM_LOONGARCH64, ++ }, + }; + + #include +-- +2.27.0 + diff --git a/grub.macros b/grub.macros index 8d0205d..cc84169 100644 --- a/grub.macros +++ b/grub.macros @@ -92,7 +92,7 @@ %endif -%global efi_only aarch64 %{arm} +%global efi_only aarch64 %{arm} loongarch64 %global efi_arch x86_64 ia64 %{efi_only} %ifarch %{efi_arch} %global with_efi_arch 1 @@ -122,7 +122,7 @@ %global platform_modules " appendedsig " %endif -%ifarch aarch64 %{arm} +%ifarch aarch64 %{arm} loongarch64 %global platform_modules " " %endif @@ -187,6 +187,14 @@ )} %endif +%ifarch loongarch64 +%global with_emu_arch 0 +%global efiarch loongarch64 +%global target_cpu_name loongarch64 +%global grub_target_name loongarch64-efi +%global package_arch efi-loongarch64 +%endif + %global _target_platform %{target_cpu_name}-%{_vendor}-%{_target_os}%{?_gnu} %global _alt_target_platform %{alt_target_cpu_name}-%{_vendor}-%{_target_os}%{?_gnu} diff --git a/grub.patches b/grub.patches index 373afa7..0e557c0 100644 --- a/grub.patches +++ b/grub.patches @@ -571,3 +571,5 @@ Patch0570: 0570-font-Fix-an-integer-underflow-in-blit_comb.patch Patch0571: 0571-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch Patch0572: 0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch Patch0573: 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch +# Support loongarch64 +#Patch1000: 1000-loongarch64-add-support.patch diff --git a/grub2.spec b/grub2.spec index 3daebd3..18f806d 100644 --- a/grub2.spec +++ b/grub2.spec @@ -5,6 +5,10 @@ %undefine _missing_build_ids_terminate_build %global _configure_gnuconfig_hack 0 +%ifarch loongarch64 +%global _configure_gnuconfig_hack 1 +%endif + Name: grub2 Epoch: 1 Version: 2.02 @@ -115,7 +119,7 @@ Requires(post): dracut %{desc} This subpackage provides tools for support of all platforms. -%ifarch x86_64 +%ifarch x86_64 loongarch64 %package tools-efi Summary: Support tools for GRUB. Group: System Environment/Base @@ -185,6 +189,11 @@ git add grub-%{grublegacyarch}-%{tarversion} %endif git commit -m "After making subdirs" +%ifarch loongarch64 +%_update_config_sub +%_update_config_guess +%endif + %build %if 0%{with_efi_arch} %{expand:%do_primary_efi_build %%{grubefiarch} %%{grubefiname} %%{grubeficdname} %%{_target_platform} %%{efi_target_cflags} %%{efi_host_cflags} %{old_sb_ca} %{old_sb_cer} %{old_sb_key} %{sb_ca} %{sb_cer} %{sb_key}} @@ -226,8 +235,11 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir ln -s %{name}-set-password ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-setpassword echo '.so man8/%{name}-set-password.8' > ${RPM_BUILD_ROOT}/%{_datadir}/man/man8/%{name}-setpassword.8 %ifnarch x86_64 -rm -vf ${RPM_BUILD_ROOT}/%{_bindir}/%{name}-render-label rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-bios-setup +%endif + +%ifnarch x86_64 loongarch64 +rm -vf ${RPM_BUILD_ROOT}/%{_bindir}/%{name}-render-label rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-macbless %endif @@ -387,7 +399,7 @@ fi %{_datadir}/man/man1/%{name}-editenv* %{_datadir}/man/man1/%{name}-mkpasswd-* -%ifarch x86_64 +%ifarch x86_64 loongarch64 %files tools-efi %{_sbindir}/%{name}-macbless %{_bindir}/%{name}-render-label @@ -513,6 +525,7 @@ fi %changelog * Tue Jan 10 2023 Bo Ren - 2.02-142.0.1.1 - Build pc-modules package on x86_64 (geliwei@openanolis.org) +- Add loongarch64 base support (zhangwenlong@loongson.cn)(chenguoqi@loongson.cn) * Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 - Sync with 8.8 (actually 2.02-145) -- Gitee From 579dc1f972b2f4e54ab53ff0b28cb163d934cfc7 Mon Sep 17 00:00:00 2001 From: songmingliang Date: Thu, 19 May 2022 00:17:50 +0800 Subject: [PATCH 4/6] Fix a bug in bls_make_list, blscfg --- 1001-bls-make-list.patch | 119 +++++++++++++++++++++++++++++++++++++++ grub.patches | 1 + grub2.spec | 1 + 3 files changed, 121 insertions(+) create mode 100644 1001-bls-make-list.patch diff --git a/1001-bls-make-list.patch b/1001-bls-make-list.patch new file mode 100644 index 0000000..ac39162 --- /dev/null +++ b/1001-bls-make-list.patch @@ -0,0 +1,119 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhongling He +Date: Tue, 29 Mar 2022 17:27:13 +0800 +Subject: [PATCH] Fix a bug in bls_make_list, blscfg + +We have encountered a bug while running LifseaOS aarch64 version without +initrd. This commit fixes this bug. It may have fixed some potential +bugs as well. + +There are 4 partitions in a LifseaOS disk image: +- The 1st partition is for BIOS bootloader +- The 2nd partition is for UEFI booting, which contains grub binary + compiled from this source code, grubaa64.efi +- The 3rd partition contains grub.cfg files and + loader/entries/ostree-1-LifseaOS.conf +- The 4th partition contains rootfs + +Since x86_64 supports both BIOS and UEFI booting and we employ BIOS +booting for x86_64 (w/o initrd) image, we don't put the grub2 binary +compiled into the 2nd partition. As a result, this bug was not observed. +However, aarch64 only supports UEFI booting. In other words, we are +using this grub2 to boot LifseaOS (w/o initrd). + +grubaa64.efi from the 2nd partition will read `/grub2/grub.cfg` in the +3rd partition. + +``` +... + set ignition_firstboot="ignition.firstboot +${ignition_network_kcmdline}" +fi + +blscfg +``` + +`blscfg` is a command to convert `loader/entries/ostree-1-LifseaOS.conf` +into a typical grub.cfg. However, here comes the bug. While booting, an +error message will appear. + +``` +error: ../../grub-core/loader/arm64/linux.c:292:filename expected. +Press any key to continue. +``` + +This is because the bug in `blscfg` unexpectedly add a line, `initrd`, +into the generated grub.cfg file. Grub2 will expect an initrd file path +after `initrd`. As a result, the error occurs. + +In grub-core/command/blscfg.c:676, if `initrds` is a non-NULL pointer, +then `src` will contain a `initrd` line. + +``` +static void create_entry (struct bls_entry *entry){ + ... + initrds = bls_make_list (entry, "initrd", NULL); // + ... + if (initrds){ + ... + tmp = grub_stpcpy(initrd, "initrd "); + ... + } + ... + src = grub_xasprintf ("load_video\n" + "set gfx_payload=keep\n" + "insmod gzio\n" + "linux %s%s%s%s\n" + "%s", + GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options +: "", + initrd ? initrd : ""); +``` + +In grub-core/command/blscfg.c:562, `bls_make_list` will always return a +non-NULL pointer except for a `grub_malloc` error. + +``` +static char **bls_make_list (struct bls_entry *entry, const char *key, +int *num) +{ + ... + list = grub_malloc (sizeof (char *)); + if (!list) + return NULL; + list[0] = NULL; + ... + return list; +} +``` + +Therefore, `initrd` like will be appended into the auto-generated +grub.cfg if `grub_malloc` succeed, regardless of whether initrd is +stated in config file. Our bug fix, same as upstream, modifies the +behaviour of `bls_make_list`. `bls_make_list` will now return a non-NULL +pointer only if the required field actually exists. + +--- + grub-core/commands/blscfg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +index 795a9f9..bf18270 100644 +--- a/grub-core/commands/blscfg.c ++++ b/grub-core/commands/blscfg.c +@@ -589,6 +589,12 @@ static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) + list[nlist] = NULL; + } + ++ if (!nlist) ++ { ++ grub_free (list); ++ return NULL; ++ } ++ + if (num) + *num = nlist; + +-- +2.27.0 + diff --git a/grub.patches b/grub.patches index 0e557c0..d138efb 100644 --- a/grub.patches +++ b/grub.patches @@ -573,3 +573,4 @@ Patch0572: 0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch Patch0573: 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch # Support loongarch64 #Patch1000: 1000-loongarch64-add-support.patch +Patch1001: 1001-bls-make-list.patch diff --git a/grub2.spec b/grub2.spec index 18f806d..054929e 100644 --- a/grub2.spec +++ b/grub2.spec @@ -526,6 +526,7 @@ fi * Tue Jan 10 2023 Bo Ren - 2.02-142.0.1.1 - Build pc-modules package on x86_64 (geliwei@openanolis.org) - Add loongarch64 base support (zhangwenlong@loongson.cn)(chenguoqi@loongson.cn) +- Fix a bug in bls_make_list, blscfg. (zhonglingh@linux.alibaba.com) * Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 - Sync with 8.8 (actually 2.02-145) -- Gitee From 63fcac0d66eac38885592284823785f4415b9e88 Mon Sep 17 00:00:00 2001 From: yangqiming Date: Wed, 6 Jul 2022 23:45:53 -0400 Subject: [PATCH 5/6] Add LoongArch64 support and update interface to v40 --- ...-support-and-update-interface-to-v40.patch | 1968 ++++++----------- grub.patches | 1 + grub2.spec | 3 + 3 files changed, 726 insertions(+), 1246 deletions(-) rename 1000-loongarch64-add-support.patch => 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch (64%) diff --git a/1000-loongarch64-add-support.patch b/1002-Add-LoongArch64-support-and-update-interface-to-v40.patch similarity index 64% rename from 1000-loongarch64-add-support.patch rename to 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch index 2d83c94..36750c1 100644 --- a/1000-loongarch64-add-support.patch +++ b/1002-Add-LoongArch64-support-and-update-interface-to-v40.patch @@ -1,87 +1,11 @@ -From febee03c70471fd2ce6f0b4cc0f365c32c106ab3 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Wed, 18 May 2022 23:50:45 +0800 -Subject: [PATCH] add loongarch64 support +From 478205a88ea71b0c546987602cd879027819125e Mon Sep 17 00:00:00 2001 +From: yangqiming +Date: Thu, 7 Jul 2022 11:25:02 +0800 +Subject: [PATCH] Add LoongArch64 support and update interface to V40 ---- - conf/Makefile.common | 4 + - configure.ac | 9 + - gentpl.py | 5 +- - grub-core/Makefile.am | 7 + - grub-core/Makefile.core.def | 20 + - grub-core/kern/efi/mm.c | 29 +- - grub-core/kern/elfXX.c | 6 + - grub-core/kern/loongarch64/cache.S | 26 + - grub-core/kern/loongarch64/dl.c | 258 +++++++++ - grub-core/kern/loongarch64/efi/init.c | 76 +++ - grub-core/kern/loongarch64/efi/startup.S | 45 ++ - grub-core/kern/loongarch64/init.c | 47 ++ - grub-core/lib/loongarch64/efi/loongson.c | 505 ++++++++++++++++ - grub-core/lib/loongarch64/efi/loongson_asm.S | 58 ++ - grub-core/lib/loongarch64/relocator.c | 163 ++++++ - grub-core/lib/loongarch64/relocator_asm.S | 51 ++ - grub-core/lib/loongarch64/setjmp.S | 74 +++ - grub-core/lib/loongson/reboot.c | 33 ++ - grub-core/lib/setjmp.S | 2 + - grub-core/loader/efi/chainloader.c | 2 + - grub-core/loader/loongarch64/linux.c | 580 +++++++++++++++++++ - include/grub/dl.h | 2 +- - include/grub/efi/api.h | 3 +- - include/grub/efi/pe32.h | 2 + - include/grub/elf.h | 55 ++ - include/grub/loongarch64/asm.h | 10 + - include/grub/loongarch64/efi/boot.h | 0 - include/grub/loongarch64/efi/loader.h | 25 + - include/grub/loongarch64/efi/loongson.h | 290 ++++++++++ - include/grub/loongarch64/efi/memory.h | 14 + - include/grub/loongarch64/efi/time.h | 0 - include/grub/loongarch64/io.h | 62 ++ - include/grub/loongarch64/kernel.h | 24 + - include/grub/loongarch64/linux.h | 22 + - include/grub/loongarch64/loongarch64.h | 30 + - include/grub/loongarch64/memory.h | 57 ++ - include/grub/loongarch64/relocator.h | 38 ++ - include/grub/loongarch64/setjmp.h | 27 + - include/grub/loongarch64/time.h | 39 ++ - include/grub/loongarch64/types.h | 34 ++ - include/grub/util/install.h | 1 + - util/grub-install-common.c | 43 +- - util/grub-install.c | 16 + - util/grub-mkimagexx.c | 349 ++++++++++- - util/grub-mknetdir.c | 3 +- - util/grub-module-verifier.c | 46 ++ - util/mkimage.c | 16 + - 47 files changed, 3176 insertions(+), 32 deletions(-) - create mode 100644 grub-core/kern/loongarch64/cache.S - create mode 100644 grub-core/kern/loongarch64/dl.c - create mode 100644 grub-core/kern/loongarch64/efi/init.c - create mode 100644 grub-core/kern/loongarch64/efi/startup.S - create mode 100644 grub-core/kern/loongarch64/init.c - create mode 100644 grub-core/lib/loongarch64/efi/loongson.c - create mode 100644 grub-core/lib/loongarch64/efi/loongson_asm.S - create mode 100644 grub-core/lib/loongarch64/relocator.c - create mode 100644 grub-core/lib/loongarch64/relocator_asm.S - create mode 100644 grub-core/lib/loongarch64/setjmp.S - create mode 100644 grub-core/lib/loongson/reboot.c - create mode 100644 grub-core/loader/loongarch64/linux.c - create mode 100644 include/grub/loongarch64/asm.h - create mode 100644 include/grub/loongarch64/efi/boot.h - create mode 100644 include/grub/loongarch64/efi/loader.h - create mode 100644 include/grub/loongarch64/efi/loongson.h - create mode 100644 include/grub/loongarch64/efi/memory.h - create mode 100644 include/grub/loongarch64/efi/time.h - create mode 100644 include/grub/loongarch64/io.h - create mode 100644 include/grub/loongarch64/kernel.h - create mode 100644 include/grub/loongarch64/linux.h - create mode 100644 include/grub/loongarch64/loongarch64.h - create mode 100644 include/grub/loongarch64/memory.h - create mode 100644 include/grub/loongarch64/relocator.h - create mode 100644 include/grub/loongarch64/setjmp.h - create mode 100644 include/grub/loongarch64/time.h - create mode 100644 include/grub/loongarch64/types.h diff --git a/conf/Makefile.common b/conf/Makefile.common -index 521cdda..cc1d190 100644 +index 521cdda..d9f058b 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -20,6 +20,10 @@ endif @@ -89,8 +13,8 @@ index 521cdda..cc1d190 100644 CFLAGS_PLATFORM += -mcpu=powerpc endif +if COND_loongarch64 -+ CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel -+ CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-pcrel ++ CFLAGS_PLATFORM += -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large ++ CPPFLAGS_PLATFORM = -fno-strict-aliasing -march=loongarch64 -mabi=lp64 -fno-plt -Wa,-mla-global-with-abs -mcmodel=large +endif # Other options @@ -173,10 +97,10 @@ index d662c30..3afd642 100644 GROUPS["uboot"] = [ "arm_uboot" ] GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index 308ad88..24e2ac3 100644 +index 308ad88..a976fad 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am -@@ -222,6 +222,13 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h +@@ -222,6 +222,14 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h endif @@ -184,6 +108,7 @@ index 308ad88..24e2ac3 100644 +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/acpi.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h +endif + @@ -191,7 +116,7 @@ index 308ad88..24e2ac3 100644 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index ef06f8c..74e66d3 100644 +index ef06f8c..54f6bf0 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -95,6 +95,9 @@ kernel = { @@ -212,7 +137,7 @@ index ef06f8c..74e66d3 100644 sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; arm_uboot_startup = kern/arm/startup.S; -@@ -295,6 +299,14 @@ kernel = { +@@ -295,6 +299,15 @@ kernel = { extra_dist = video/sis315_init.c; mips_loongson = commands/keylayouts.c; @@ -220,14 +145,15 @@ index ef06f8c..74e66d3 100644 + loongarch64 = kern/loongarch64/dl.c; + loongarch64 = kern/loongarch64/cache.S; + loongarch64 = kern/generic/rtc_get_time_ms.c; ++ loongarch64 = kern/efi/fdt.c; ++ loongarch64 = lib/fdt.c; + loongarch64_efi = kern/loongarch64/efi/init.c; + loongarch64_efi = lib/loongarch64/efi/loongson.c; -+ loongarch64_efi = lib/loongarch64/efi/loongson_asm.S; + powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/dl.c; powerpc_ieee1275 = kern/powerpc/compiler-rt.S; -@@ -810,6 +822,7 @@ module = { +@@ -810,6 +823,7 @@ module = { enable = sparc64_ieee1275; enable = powerpc_ieee1275; enable = mips_arc; @@ -235,7 +161,7 @@ index ef06f8c..74e66d3 100644 enable = ia64_efi; enable = arm_efi; enable = arm64_efi; -@@ -896,6 +909,7 @@ module = { +@@ -896,6 +910,7 @@ module = { i386_qemu = lib/i386/halt.c; xen = lib/xen/halt.c; efi = lib/efi/halt.c; @@ -243,7 +169,7 @@ index ef06f8c..74e66d3 100644 ieee1275 = lib/ieee1275/halt.c; emu = lib/emu/halt.c; uboot = lib/dummy/halt.c; -@@ -911,6 +925,7 @@ module = { +@@ -911,6 +926,7 @@ module = { mips_arc = lib/mips/arc/reboot.c; mips_loongson = lib/mips/loongson/reboot.c; mips_qemu_mips = lib/mips/qemu_mips/reboot.c; @@ -251,7 +177,7 @@ index ef06f8c..74e66d3 100644 xen = lib/xen/reboot.c; uboot = lib/uboot/reboot.c; arm_coreboot = lib/dummy/reboot.c; -@@ -1608,6 +1623,8 @@ module = { +@@ -1608,6 +1624,8 @@ module = { efi = lib/efi/relocator.c; mips = lib/mips/relocator_asm.S; mips = lib/mips/relocator.c; @@ -260,7 +186,7 @@ index ef06f8c..74e66d3 100644 powerpc = lib/powerpc/relocator_asm.S; powerpc = lib/powerpc/relocator.c; xen = lib/xen/relocator.c; -@@ -1620,6 +1637,7 @@ module = { +@@ -1620,6 +1638,7 @@ module = { extra_dist = kern/powerpc/cache_flush.S; enable = mips; @@ -268,7 +194,7 @@ index ef06f8c..74e66d3 100644 enable = powerpc; enable = x86; enable = xen; -@@ -1737,6 +1755,7 @@ module = { +@@ -1737,6 +1756,7 @@ module = { xen = loader/i386/xen.c; i386_pc = lib/i386/pc/vesa_modes_table.c; mips = loader/mips/linux.c; @@ -276,7 +202,7 @@ index ef06f8c..74e66d3 100644 powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; ia64_efi = loader/ia64/efi/linux.c; -@@ -1838,6 +1857,7 @@ module = { +@@ -1838,6 +1858,7 @@ module = { enable = arm_efi; enable = arm64_efi; enable = mips; @@ -285,22 +211,42 @@ index ef06f8c..74e66d3 100644 module = { diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 9e76f23..fb087e3 100644 +index 8a89614..0b5f158 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c -@@ -157,7 +157,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, +@@ -122,7 +122,11 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, + grub_efi_boot_services_t *b; + grub_efi_physical_address_t address = max; + ++#ifdef GRUB_CPU_LOONGARCH64 ++ if (max > grub_efi_max_usable_address()) ++#else + if (max > GRUB_EFI_MAX_USABLE_ADDRESS) ++#endif + return 0; + + b = grub_efi_system_table->boot_services; +@@ -157,11 +161,19 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, grub_efi_physical_address_t ret = address; /* Limit the memory access to less than 4GB for 32-bit platforms. */ +#ifdef GRUB_CPU_LOONGARCH64 + if (address > grub_efi_max_usable_address()) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("invalid memory address 0x%llx"), ++ address); +#else if (address > GRUB_EFI_MAX_USABLE_ADDRESS) -+#endif { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid memory address (0x%llx > 0x%llx)"), -@@ -177,7 +181,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + address, GRUB_EFI_MAX_USABLE_ADDRESS); ++#endif + return NULL; + } + +@@ -177,7 +189,11 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, { /* Uggh, the address 0 was allocated... This is too annoying, so reallocate another one. */ @@ -312,23 +258,23 @@ index 9e76f23..fb087e3 100644 status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); grub_efi_free_pages (0, pages); if (status != GRUB_EFI_SUCCESS) -@@ -195,9 +203,14 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, +@@ -195,9 +211,15 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, void * grub_efi_allocate_any_pages (grub_efi_uintn_t pages) { -- return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, +#ifdef GRUB_CPU_LOONGARCH64 + return grub_efi_allocate_pages_real (grub_efi_max_usable_address(), ++ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_LOADER_DATA); ++#else + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA); -+#else -+ return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, -+ pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, -+#endif GRUB_EFI_LOADER_DATA); ++#endif } void * -@@ -471,7 +484,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, +@@ -471,7 +493,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY @@ -339,11 +285,10 @@ index 9e76f23..fb087e3 100644 && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS #endif && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 -@@ -486,8 +501,14 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, - - desc->physical_start); +@@ -487,7 +511,14 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc->physical_start = 0x100000; } -- + -#if 1 +#ifdef GRUB_CPU_LOONGARCH64 + if (BYTES_TO_PAGES (filtered_desc->physical_start) @@ -356,23 +301,43 @@ index 9e76f23..fb087e3 100644 if (BYTES_TO_PAGES (filtered_desc->physical_start) + filtered_desc->num_pages > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) -diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c -index 1859d18..8b1dce9 100644 ---- a/grub-core/kern/elfXX.c -+++ b/grub-core/kern/elfXX.c -@@ -134,6 +134,12 @@ grub_elfXX_load (grub_elf_t elf, const char *filename, - load_addr &= 0x3FFFFFFFFFFFFFFFULL; - break; - } +@@ -765,7 +796,7 @@ grub_efi_mm_init (void) + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + } + +-#if defined (__aarch64__) || defined (__arm__) ++#if defined (__aarch64__) || defined (__arm__) || defined (__loongarch__) + grub_err_t + grub_efi_get_ram_base(grub_addr_t *base_addr) + { +@@ -784,9 +815,15 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) + if (ret < 1) + return GRUB_ERR_BUG; + ++#ifdef GRUB_CPU_LOONGARCH64 ++ for (desc = memory_map, *base_addr = grub_efi_max_usable_address(); ++ (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); ++ desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) ++#else + for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; + (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) ++#endif + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY && + (desc->attribute & GRUB_EFI_MEMORY_WB)) +@@ -800,7 +837,11 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) + } + } + +#ifdef GRUB_CPU_LOONGARCH64 -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if ((load_addr >> 48) != (addr >> 48)) -+ return grub_error (GRUB_ERR_BAD_OS, "bad address space"); ++ if (*base_addr == grub_efi_max_usable_address()) ++#else + if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS) +#endif - load_addr += (grub_addr_t) load_offset; + grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr); - if (load_addr < load_base) + grub_free(memory_map); diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S new file mode 100644 index 0000000..d291c67 @@ -407,10 +372,10 @@ index 0000000..d291c67 + diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c new file mode 100644 -index 0000000..a6fd387 +index 0000000..7d9e2a1 --- /dev/null +++ b/grub-core/kern/loongarch64/dl.c -@@ -0,0 +1,258 @@ +@@ -0,0 +1,266 @@ +/* loongarch64/dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader @@ -669,12 +634,20 @@ index 0000000..a6fd387 + return GRUB_ERR_NONE; +} + ++/* ++ * Tell the loader what our minimum section alignment is. ++ */ ++grub_size_t ++grub_arch_dl_min_alignment (void) ++{ ++ return 1; ++} diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c new file mode 100644 -index 0000000..b21d4f1 +index 0000000..632c39a --- /dev/null +++ b/grub-core/kern/loongarch64/efi/init.c -@@ -0,0 +1,76 @@ +@@ -0,0 +1,74 @@ +/* init.c - initialize an arm-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader @@ -698,7 +671,7 @@ index 0000000..b21d4f1 +#include +#include +#include -+#include ++#include +#include +#include +#include @@ -719,15 +692,13 @@ index 0000000..b21d4f1 + tmr += 10; +} + -+ -+ +void +grub_machine_init (void) +{ + grub_efi_boot_services_t *b; + + grub_efi_init (); -+ ++ + b = grub_efi_system_table->boot_services; + efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); @@ -857,10 +828,10 @@ index 0000000..b2de930 +} diff --git a/grub-core/lib/loongarch64/efi/loongson.c b/grub-core/lib/loongarch64/efi/loongson.c new file mode 100644 -index 0000000..8b60d82 +index 0000000..eda1e1c --- /dev/null +++ b/grub-core/lib/loongarch64/efi/loongson.c -@@ -0,0 +1,505 @@ +@@ -0,0 +1,119 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. @@ -886,400 +857,14 @@ index 0000000..8b60d82 +#include +#include + -+#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp) -+#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8) -+#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start) -+ -+extern grub_uint8_t grub_efi_loongson_reset_start; -+extern grub_uint8_t grub_efi_loongson_reset_end; -+ -+static struct -+{ -+ grub_efi_loongson_boot_params boot_params; -+ grub_efi_loongson_memory_map memory_map; -+ grub_efi_loongson_cpu_info cpu_info; -+ grub_efi_loongson_system_info system_info; -+ grub_efi_loongson_irq_src_routing_table irq_src_routing_table; -+ grub_efi_loongson_interface_info interface_info; -+ grub_efi_loongson_special_attribute special_attribute; -+ grub_efi_loongson_board_devices board_devices; -+} GRUB_PACKED -+* loongson_boot_params; -+ -+static void -+grub_efi_loongson_init_reset_system (void) -+{ -+ grub_efi_loongson_boot_params *boot_params; -+ grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params + -+ loongson_boot_params_size; -+ -+ boot_params = &loongson_boot_params->boot_params; -+ grub_efi_loongson_reset_system_addr = -+ (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system; -+ grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size); -+ grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size); -+ -+ boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr + -+ ((grub_uint64_t) &grub_efi_loongson_reset_cold - -+ (grub_uint64_t) &grub_efi_loongson_reset_start); -+ boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr + -+ ((grub_uint64_t) &grub_efi_loongson_reset_warm - -+ (grub_uint64_t) &grub_efi_loongson_reset_start); -+ boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr + -+ ((grub_uint64_t) &grub_efi_loongson_reset_shutdown - -+ (grub_uint64_t) &grub_efi_loongson_reset_start); -+ boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr + -+ ((grub_uint64_t) &grub_efi_loongson_reset_suspend - -+ (grub_uint64_t) &grub_efi_loongson_reset_start); -+} -+ -+static void -+grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios; -+ -+ dst->vers = smbios_table->vers; -+ dst->vga_bios = smbios_table->vga_bios; -+} -+ -+static void -+grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset; -+ grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info)); -+ loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+static void -+grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset; -+ grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info)); -+ loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+static void -+grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset; -+ grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table)); -+ loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+static void -+grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset; -+ grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info)); -+ loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+static void -+grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset; -+ grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute)); -+ loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+static void -+grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table) -+{ -+ grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset; -+ grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices; -+ -+ if (!src) -+ return; -+ -+ grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices)); -+ loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+} -+ -+#define ADD_MEMORY_DESCRIPTOR(desc, size) \ -+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) -+ -+static void -+grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table, -+ grub_efi_memory_descriptor_t *mmap_buf, -+ grub_efi_uintn_t mmap_size, -+ grub_efi_uintn_t desc_size) -+{ -+ grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset; -+ grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map; -+ grub_efi_memory_descriptor_t *mmap_end; -+ grub_efi_memory_descriptor_t *desc; -+ grub_efi_memory_descriptor_t *desc_next; -+ grub_efi_uint32_t mem_types_reserved[] = -+ { -+ 1, // GRUB_EFI_RESERVED_MEMORY_TYPE -+ 0, // GRUB_EFI_LOADER_CODE -+ 0, // GRUB_EFI_LOADER_DATA -+ 0, // GRUB_EFI_BOOT_SERVICES_CODE -+ 0, // GRUB_EFI_BOOT_SERVICES_DATA -+ 1, // GRUB_EFI_RUNTIME_SERVICES_CODE -+ 1, // GRUB_EFI_RUNTIME_SERVICES_DATA -+ 0, // GRUB_EFI_CONVENTIONAL_MEMORY -+ 1, // GRUB_EFI_UNUSABLE_MEMORY -+ 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY -+ 0, // GRUB_EFI_ACPI_MEMORY_NVS -+ 1, // GRUB_EFI_MEMORY_MAPPED_IO -+ 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE -+ 1, // GRUB_EFI_PAL_CODE -+ 1, // GRUB_EFI_PERSISTENT_MEMORY -+ }; -+ grub_uint32_t need_sort = 1; -+ -+ if (!src) -+ return; -+ -+ dst->vers = src->vers; -+ dst->nr_map = 0; -+ dst->mem_freq = src->mem_freq; -+ loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return; -+ -+ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); -+ -+ /* drop reserved */ -+ for (desc = mmap_buf, -+ desc_next = desc; -+ desc < mmap_end; -+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) -+ { -+ desc->type = mem_types_reserved[desc->type]; -+ if (desc->type) -+ continue; -+ -+ if (desc != desc_next) -+ *desc_next = *desc; -+ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size); -+ } -+ mmap_end = desc_next; -+ -+ /* sort: low->high */ -+ while (need_sort) -+ { -+ need_sort = 0; -+ -+ for (desc = mmap_buf, -+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); -+ (desc < mmap_end) && (desc_next < mmap_end); -+ desc = desc_next, -+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) -+ { -+ grub_efi_memory_descriptor_t tmp; -+ -+ if (desc->physical_start <= desc_next->physical_start) -+ continue; -+ -+ tmp = *desc; -+ *desc = *desc_next; -+ *desc_next = tmp; -+ need_sort = 1; -+ } -+ } -+ -+ /* combine continuous memory map */ -+ for (desc = mmap_buf, -+ desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); -+ desc_next < mmap_end; -+ desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size)) -+ { -+ grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12); -+ -+ if (prev_end == desc_next->physical_start) -+ { -+ desc->num_pages += desc_next->num_pages; -+ continue; -+ } -+ -+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size); -+ grub_memcpy (desc, desc_next, desc_size); -+ } -+ mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size); -+ -+ /* write to loongson memory map */ -+ for (desc = mmap_buf; -+ desc < mmap_end; -+ desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) -+ { -+ grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start); -+ grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12); -+ -+ physical_start = ALIGN_UP (physical_start, 0x100000); -+ physical_end = ALIGN_DOWN (physical_end, 0x100000); -+ -+ if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000) -+ continue; -+ -+ dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf; -+ dst->map[dst->nr_map].mem_type = GRUB_EFI_LOONGSON_SYSTEM_RAM; -+ dst->map[dst->nr_map].mem_start = physical_start; -+ dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20; -+ -+ grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n", -+ dst->nr_map, physical_start, physical_end - physical_start, -+ dst->map[dst->nr_map].node_id); -+ -+ dst->nr_map ++; -+ } -+} -+ -+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) -+#define SUB_MEMORY_DESCRIPTOR(desc, size) \ -+ ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size))) -+ -+void -+grub_efi_loongson_alloc_boot_params (void) -+{ -+ grub_efi_memory_descriptor_t *mmap_buf; -+ grub_efi_memory_descriptor_t *mmap_end; -+ grub_efi_memory_descriptor_t *desc; -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_physical_address_t address; -+ grub_efi_allocate_type_t type; -+ grub_efi_uintn_t pages; -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ int mm_status; -+ -+ type = GRUB_EFI_ALLOCATE_ADDRESS; -+ pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size); -+ -+ mmap_size = (1 << 12); -+ mmap_buf = grub_malloc (mmap_size); -+ if (!mmap_buf) -+ grub_fatal ("out of memory!"); -+ -+ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); -+ if (mm_status == 0) -+ { -+ grub_free (mmap_buf); -+ mmap_size += desc_size * 32; -+ -+ mmap_buf = grub_malloc (mmap_size); -+ if (!mmap_buf) -+ grub_fatal ("out of memory!"); -+ -+ mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); -+ } -+ -+ if (mm_status < 0) -+ grub_fatal ("cannot get memory map!"); -+ -+ mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); -+ -+ for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size); -+ desc >= mmap_buf; -+ desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size)) -+ { -+ if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) -+ continue; -+ if (desc->physical_start >= grub_efi_max_usable_address()) -+ continue; -+ if (desc->num_pages < pages) -+ continue; -+ -+ address = desc->physical_start; -+ break; -+ } -+ -+ grub_free (mmap_buf); -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); -+ if (status != GRUB_EFI_SUCCESS) -+ grub_fatal ("cannot allocate Loongson boot parameters!"); -+ -+ loongson_boot_params = (void *) ((grub_addr_t) address); -+} -+ -+void -+grub_efi_loongson_free_boot_params (void) -+{ -+ grub_efi_free_pages ((grub_addr_t) loongson_boot_params, -+ BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size)); -+} -+ -+void * -+grub_efi_loongson_get_smbios_table (void) ++unsigned long ++grub_efi_get_bpi_version (const char *str) +{ -+ static grub_efi_loongson_smbios_table *smbios_table; -+ grub_efi_loongson_boot_params *old_boot_params; -+ struct bootparamsinterface* boot_params; -+ void * tmp_boot_params = NULL; -+ char * p = NULL; -+ if(smbios_table) -+ return smbios_table; -+ -+ tmp_boot_params = grub_efi_loongson_get_boot_params(); -+ if(tmp_boot_params == NULL) -+ { -+ grub_dprintf("loongson", "tmp_boot_params is NULL\n"); -+ return tmp_boot_params; -+ } -+ -+ boot_params = (struct bootparamsinterface *)tmp_boot_params; -+ p = (char *)&(boot_params->signature); -+ if(grub_strncmp(p, "BPI", 3) == 0) -+ { -+ grub_dprintf("loongson", "find new bpi\n"); -+ return boot_params ? boot_params : 0; -+ } -+ else -+ { -+ old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params; -+ /* -+ { -+ grub_dprintf("loongson", "smbios addr%llx\n", &old_boot_params->efi.smbios); -+ grub_dprintf("loongson", "smbios vers%d\n", (grub_uint16_t)(&old_boot_params->efi.smbios.vers)); -+ grub_dprintf("loongson", "smbios vga_bios%d\n", &old_boot_params->efi.smbios.vga_bios); -+ grub_dprintf("loongson", "lp memory offset %llx\n", &old_boot_params->efi.smbios.lp.memory_offset); -+ grub_dprintf("loongson", "lp cpu offset %llx\n", &old_boot_params->efi.smbios.lp.cpu_offset); -+ grub_dprintf("loongson", "lp system offset %llx\n", &old_boot_params->efi.smbios.lp.system_offset); -+ grub_dprintf("loongson", "lp irq offset %llx\n", &old_boot_params->efi.smbios.lp.irq_offset); -+ grub_dprintf("loongson", "lp interface offset %llx\n", &old_boot_params->efi.smbios.p.interface_offset); -+ grub_dprintf("loongson", "lp special offset %llx\n", &old_boot_params->efi.smbios.lp.special_offset); -+ grub_dprintf("loongson", "lp boarddev table offset %llx\n", &old_boot_params->efi.smbios.lp.boarddev_table_offset); -+ } -+ */ -+ return old_boot_params ? &old_boot_params->efi.smbios : 0; -+ } ++ unsigned long version = GRUB_EFI_BPI_VER_NONE; + -+} ++ version = grub_strtoul (str + 4, 0, 0); + -+int -+grub_efi_is_loongson (void) -+{ -+ return grub_efi_loongson_get_smbios_table () ? 1 : 0; ++ return version; +} + +void * @@ -1287,20 +872,20 @@ index 0000000..8b60d82 +{ + static void * boot_params = NULL; + grub_efi_configuration_table_t *tables; -+ grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID; ++ grub_efi_guid_t loongson_bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; + unsigned int i; + + if (boot_params) + return boot_params; + -+ /* Look for Loongson SMBIOS in UEFI config tables. */ ++ /* Look for Loongson boot params interface in UEFI config tables. */ + tables = grub_efi_system_table->configuration_table; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) -+ if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0) ++ if (grub_memcmp (&tables[i].vendor_guid, &loongson_bpi_guid, sizeof (loongson_bpi_guid)) == 0) + { + boot_params= tables[i].vendor_table; -+ grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params); ++ grub_dprintf ("loongson", "found registered BPI @ %p\n", boot_params); + break; + } + return boot_params; @@ -1330,8 +915,9 @@ index 0000000..8b60d82 +} + + -+grub_uint32_t -+grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype) ++grub_uint32_t ++grub_efi_loongson_memmap_v1_sort(struct memmap_v1 array[], grub_uint32_t length, ++ mem_map_v1 * bpmem, grub_uint32_t index, grub_uint32_t memtype) +{ + grub_uint64_t tempmemsize = 0; + grub_uint32_t j = 0; @@ -1342,19 +928,19 @@ index 0000000..8b60d82 + tempmemsize = array[j].memsize; + for(t = j + 1; t < length; t++) + { -+ if(array[j].memstart + tempmemsize == array[t].memstart) ++ if(array[j].memstart + tempmemsize == array[t].memstart) + { + tempmemsize += array[t].memsize; + } + else -+ { ++ { + break; + } + } + bpmem->map[index].memtype = memtype; + bpmem->map[index].memstart = array[j].memstart; + bpmem->map[index].memsize = tempmemsize; -+ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", ++ grub_dprintf("loongson", "v1 map[%d]:type %x, start 0x%lx, end 0x%lx\n", + index, + bpmem->map[index].memtype, + bpmem->map[index].memstart, @@ -1365,74 +951,9 @@ index 0000000..8b60d82 + } + return index; +} -+ -diff --git a/grub-core/lib/loongarch64/efi/loongson_asm.S b/grub-core/lib/loongarch64/efi/loongson_asm.S -new file mode 100644 -index 0000000..4a04d34 ---- /dev/null -+++ b/grub-core/lib/loongarch64/efi/loongson_asm.S -@@ -0,0 +1,58 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 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 . -+ */ -+ -+#include -+ -+ .file "loongson_asm.S" -+ .text -+ -+ .align 4 -+ -+VARIABLE (grub_efi_loongson_reset_start) -+ -+VARIABLE (grub_efi_loongson_reset_system_addr) -+ .dword 0 -+ -+reset_system: -+ bl 1f -+ move $a1, $zero -+1: -+ ld.d $t8, $ra, -16 -+ move $a2, $zero -+ jr $t8 -+ move $a3, $zero -+ -+FUNCTION(grub_efi_loongson_reset_cold) -+ b reset_system -+ li.w $a0, 0 -+ -+FUNCTION(grub_efi_loongson_reset_warm) -+ b reset_system -+ li.w $a0, 1 -+ -+FUNCTION(grub_efi_loongson_reset_shutdown) -+ b reset_system -+ li.w $a0, 2 -+ -+FUNCTION(grub_efi_loongson_reset_suspend) -+ b reset_system -+ li.w $a0, 3 -+ -+VARIABLE (grub_efi_loongson_reset_end) -+ -+ diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c new file mode 100644 -index 0000000..f6c1b01 +index 0000000..4b253ca --- /dev/null +++ b/grub-core/lib/loongarch64/relocator.c @@ -0,0 +1,163 @@ @@ -1510,12 +1031,9 @@ index 0000000..f6c1b01 +static void +write_jump (int regn, void **target) +{ -+ grub_uint32_t andi=0x4c000000; -+ grub_uint32_t nop=0x03400000; ++ grub_uint32_t jirl=0x4c000000; + -+ *(grub_uint32_t *) *target = (andi | (grub_uint32_t)(regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = nop; ++ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); + *target = ((grub_uint32_t *) *target) + 1; +} + @@ -1585,6 +1103,9 @@ index 0000000..f6c1b01 + + grub_arch_sync_caches ((void *) relst, relsize); + ++ asm volatile ( ++ "ibar 0 \n"); ++ + grub_uint64_t val; + __asm__ __volatile__( + "li.w %0, 0x4\n\t" @@ -1789,10 +1310,10 @@ index f6e4905..023dc90 100644 #error "Unknown target cpu type" #endif diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 29663f7..c0ca17d 100644 +index b72e6bd..f4066b5 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c -@@ -332,6 +332,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = +@@ -343,6 +343,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = GRUB_PE32_MACHINE_I386; #elif defined(__ia64__) GRUB_PE32_MACHINE_IA64; @@ -1803,10 +1324,10 @@ index 29663f7..c0ca17d 100644 #endif diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c new file mode 100644 -index 0000000..c769bb2 +index 0000000..7594ca2 --- /dev/null +++ b/grub-core/loader/loongarch64/linux.c -@@ -0,0 +1,580 @@ +@@ -0,0 +1,690 @@ +/* linux.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader @@ -1838,10 +1359,12 @@ index 0000000..c769bb2 +#include +#include +#include ++#include +#include +#include +#include -+ ++#include ++#include + +GRUB_MOD_LICENSE ("GPLv3+"); + @@ -1849,253 +1372,302 @@ index 0000000..c769bb2 + +typedef unsigned long size_t; + -+static grub_dl_t my_mod; ++#define FDT_ADDR_CELLS_STRING "#address-cells" ++#define FDT_SIZE_CELLS_STRING "#size-cells" ++#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ ++ sizeof (FDT_ADDR_CELLS_STRING) + \ ++ sizeof (FDT_SIZE_CELLS_STRING)) + ++static grub_dl_t my_mod; +static int loaded; -+ -+static grub_uint32_t tmp_index = 0; ++static int initrd_loaded = 0; +static grub_size_t linux_size; + +static struct grub_relocator *relocator; +static grub_addr_t target_addr, entry_addr; +static int linux_argc; +static grub_uint8_t *linux_args_addr; -+static grub_off_t rd_addr_arg_off, rd_size_arg_off; -+static grub_off_t initrd_addr_arg_off; -+static int initrd_loaded = 0; -+ ++static grub_off_t rd_addr_arg_off, rd_size_arg_off, initrd_addr_arg_off; + -+static grub_uint32_t j = 0; -+static grub_uint32_t t = 0; -+grub_uint64_t tempMemsize = 0; -+grub_uint32_t free_index = 0; -+grub_uint32_t reserve_index = 0; -+grub_uint32_t acpi_table_index = 0; -+grub_uint32_t acpi_nvs_index = 0; ++static void *fdt; ++static int is_fdt_boot; ++static grub_addr_t initrd_start, initrd_end; ++static char *fdt_linux_args; + -+static inline grub_size_t -+page_align (grub_size_t size) ++static grub_err_t ++allocate_fdt_and_exit_boot (void) +{ -+ return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); -+} ++ int node, retval; ++ grub_err_t err; ++ unsigned int size; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; + -+/* Find the optimal number of pages for the memory map. Is it better to -+ move this code to efi/mm.c? */ -+static grub_efi_uintn_t -+find_mmap_size (void) -+{ -+ static grub_efi_uintn_t mmap_size = 0; ++ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; ++ ++ fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); ++ if (!fdt) ++ return GRUB_ERR_OUT_OF_MEMORY; ++ ++ grub_fdt_create_empty_tree (fdt, size); ++ grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); ++ grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); ++ ++ node = grub_fdt_find_subnode (fdt, 0, "chosen"); ++ if (node < 0) ++ node = grub_fdt_add_subnode (fdt, 0, "chosen"); ++ if (node < 1) ++ goto failure; ++ ++ grub_dprintf ("loongson", "command_line %s, len %ld\n", ++ fdt_linux_args, grub_strlen(fdt_linux_args) + 1); ++ if ((fdt_linux_args != NULL) && (grub_strlen(fdt_linux_args) > 0)) { ++ retval = grub_fdt_set_prop (fdt, node, "bootargs", fdt_linux_args, ++ grub_strlen(fdt_linux_args) + 1); ++ if (retval) ++ goto failure; ++ } + -+ if (mmap_size != 0) -+ return mmap_size; ++ /* Set initrd info */ ++ if (initrd_start && initrd_end > initrd_start) ++ { ++ grub_dprintf ("linux", "Initrd @ %p-%p\n", ++ (void *) initrd_start, (void *) initrd_end); ++ ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", ++ initrd_start); ++ if (retval) ++ goto failure; ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", ++ initrd_end); ++ if (retval) ++ goto failure; ++ } + -+ mmap_size = (1 << 12); -+ while (1) -+ { -+ int ret; -+ grub_efi_memory_descriptor_t *mmap; -+ grub_efi_uintn_t desc_size; ++ node = grub_fdt_find_subnode (fdt, 0, "chosen"); ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-system-table", ++ (grub_uint64_t)grub_efi_system_table); ++ if (retval) ++ goto failure; + -+ mmap = grub_malloc (mmap_size); -+ if (! mmap) -+ return 0; ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) ++ return err; + -+ ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); -+ grub_free (mmap); ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return GRUB_ERR_BAD_ARGUMENT; + -+ if (ret < 0) -+ { -+ grub_error (GRUB_ERR_IO, "cannot get memory map"); -+ return 0; -+ } -+ else if (ret > 0) -+ break; ++ retval = grub_fdt_set_prop64 (fdt, node, "linux,uefi-mmap-start", ++ (grub_uint64_t)mmap_buf); ++ if (retval) ++ goto failure; + -+ mmap_size += (1 << 12); -+ } ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-size", ++ mmap_size); ++ if (retval) ++ goto failure; ++ ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-size", ++ desc_size); ++ if (retval) ++ goto failure; + ++ retval = grub_fdt_set_prop32 (fdt, node, "linux,uefi-mmap-desc-ver", ++ desc_version); ++ if (retval) ++ goto failure; + -+ /* Increase the size a bit for safety, because GRUB allocates more on -+ later, and EFI itself may allocate more. */ -+ mmap_size += (1 << 12); ++ return GRUB_ERR_NONE; + -+ return page_align (mmap_size); ++failure: ++ if (!fdt) { ++ return GRUB_ERR_BAD_OS; ++ } ++ grub_efi_free_pages ((grub_addr_t) fdt, ++ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt))); ++ fdt = NULL; ++ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); +} + +static grub_err_t -+grub_linux_boot (void) ++allocate_boot_params_and_exit_boot (void) +{ -+ struct grub_relocator64_state state; -+ grub_int8_t checksum = 0; ++ grub_efi_uintn_t mmap_size; ++ grub_efi_uintn_t desc_size; ++ grub_efi_uint32_t desc_version; ++ grub_efi_memory_descriptor_t *mmap_buf; + grub_efi_memory_descriptor_t * lsdesc = NULL; -+ -+ grub_memset (&state, 0, sizeof (state)); -+ -+ /* Boot the kernel. */ -+ state.gpr[1] = entry_addr; -+ grub_dprintf("loongson", "entry_addr is %p\n", state.gpr[1]); -+ state.gpr[4] = linux_argc; -+ grub_dprintf("loongson", "linux_argc is %d\n", state.gpr[4]); -+ state.gpr[5] = (grub_addr_t) linux_args_addr; -+ grub_dprintf("loongson", "args_addr is %p\n", state.gpr[5]); -+ -+ if(grub_efi_is_loongson ()) -+ { -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ grub_err_t err; -+ struct bootparamsinterface * boot_params; -+ void * tmp_boot_params = NULL; -+ grub_efi_uint8_t new_interface_flag = 0; -+ mem_map * new_interface_mem = NULL; -+ char *p = NULL; -+ -+ struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; -+ -+ grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); -+ -+ tmp_boot_params = grub_efi_loongson_get_boot_params(); -+ if(tmp_boot_params == NULL) -+ { -+ grub_printf("not find param\n"); -+ return -1; -+ } -+ -+ boot_params = (struct bootparamsinterface *)tmp_boot_params; -+ p = (char *)&(boot_params->signature); -+ if(grub_strncmp(p, "BPI", 3) == 0) ++ grub_err_t err; ++ struct boot_params_interface * boot_params; ++ mem_map_v1 * mem_map_v1_table = NULL; ++ unsigned long bpi_version = 0; ++ grub_int8_t checksum = 0; ++ grub_uint32_t tmp_index = 0; ++ grub_uint32_t free_index = 0; ++ grub_uint32_t reserve_index = 0; ++ grub_uint32_t acpi_table_index = 0; ++ grub_uint32_t acpi_nvs_index = 0; ++ ++ struct memmap_v1 reserve_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 free_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 acpi_table_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ struct memmap_v1 acpi_nvs_mem_v1[GRUB_EFI_LOONGSON_MMAP_MAX]; ++ ++ grub_memset(reserve_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(free_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_table_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ grub_memset(acpi_nvs_mem_v1, 0, sizeof(struct memmap_v1) * GRUB_EFI_LOONGSON_MMAP_MAX); ++ ++ boot_params = (struct boot_params_interface *)grub_efi_loongson_get_boot_params(); ++ ++ ext_list * listpointer = NULL; ++ /* Check extlist headers */ ++ listpointer = boot_params->extlist; ++ for( ;listpointer != NULL; listpointer = listpointer->next) + { -+ /* Check extlist headers */ -+ ext_list * listpointer = NULL; -+ listpointer = boot_params->extlist; -+ for( ;listpointer != NULL; listpointer = listpointer->next) ++ char *pl= (char *)&(listpointer->signature); ++ if(grub_strncmp(pl, "MEM", 3) == 0) + { -+ char *pl= (char *)&(listpointer->signature); -+ if(grub_strncmp(pl, "MEM", 3) == 0) -+ { -+ new_interface_mem = (mem_map *)listpointer; -+ } ++ mem_map_v1_table = (mem_map_v1 *)listpointer; ++ break; + } -+ -+ new_interface_flag = 1; -+ grub_dprintf("loongson", "get new parameter interface\n"); -+ }else{ -+ new_interface_flag = 0; -+ grub_dprintf("loongson", "get old parameter interface\n"); + } -+ state.gpr[6] = (grub_uint64_t)tmp_boot_params; -+ grub_dprintf("loongson", "boot_params is %p\n", state.gpr[6]); + -+ mmap_size = find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, NULL); -+ if (err) -+ return err; ++ mmap_size = grub_efi_find_mmap_size (); ++ if (! mmap_size) ++ return grub_errno; ++ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); ++ if (! mmap_buf) ++ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); ++ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, ++ &desc_size, &desc_version); ++ if (err) ++ return err; + -+ if(new_interface_flag) -+ { -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return -1; -+ tmp_index = new_interface_mem -> mapcount; ++ if (!mmap_buf || !mmap_size || !desc_size) ++ return GRUB_ERR_BAD_ARGUMENT; + ++ char *p = (char *)&(boot_params->signature); ++ bpi_version = grub_efi_get_bpi_version(p); ++ grub_dprintf("loongson", "get bpi version:%ld\n", bpi_version); ++ ++ if (bpi_version <= GRUB_EFI_BPI_VER_V2) ++ { + /* -+ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ -+ now we can fill platform specific memory structure. -+ */ ++ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ ++ now we can fill platform specific memory structure. ++ */ + for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); -+ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) ++ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) + { -+ /* Recovery */ -+ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ -+ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ -+ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ -+ (lsdesc->type != GRUB_EFI_PAL_CODE)) ++ grub_dprintf("loongson", "type:%d, phy_start:0x%lx, phy_end:0x%lx\n", lsdesc->type, ++ lsdesc->physical_start, lsdesc->physical_start + lsdesc->num_pages * GRUB_EFI_PAGE_SIZE); ++ ++ /* System RAM */ ++ if ((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ ++ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ ++ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ ++ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ ++ (lsdesc->type != GRUB_EFI_PAL_CODE)) + { -+ free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; -+ free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; -+ free_mem[free_index].memsize = lsdesc->num_pages * 4096; ++ free_mem_v1[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; ++ free_mem_v1[free_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ free_mem_v1[free_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + free_index++; + + /*ACPI*/ -+ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ -+ acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; -+ acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; -+ acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096; ++ } else if ((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ ++ acpi_table_mem_v1[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; ++ acpi_table_mem_v1[acpi_table_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_table_mem_v1[acpi_table_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + acpi_table_index++; -+ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ -+ acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; -+ acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; -+ acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096; ++ } else if ((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ ++ acpi_nvs_mem_v1[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; ++ acpi_nvs_mem_v1[acpi_nvs_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ acpi_nvs_mem_v1[acpi_nvs_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + acpi_nvs_index++; + + /* Reserve */ -+ }else{ -+ reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; -+ reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; -+ reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096; ++ } else { ++ reserve_mem_v1[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; ++ reserve_mem_v1[reserve_index].memstart = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; ++ reserve_mem_v1[reserve_index].memsize = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; + reserve_index++; + } + } + -+ /* Recovery sort */ -+ for(j = 0; j < free_index;) -+ { -+ tempMemsize = free_mem[j].memsize; -+ for(t = j + 1; t < free_index; t++) -+ { -+ if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype)) -+ { -+ tempMemsize += free_mem[t].memsize; -+ }else{ -+ break; -+ } -+ } -+ -+ new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM; -+ new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart; -+ new_interface_mem->map[tmp_index].memsize = tempMemsize; -+ grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", -+ tmp_index, -+ new_interface_mem->map[tmp_index].memtype, -+ new_interface_mem->map[tmp_index].memstart, -+ new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize -+ ); -+ j = t; -+ tmp_index++; -+ } ++ tmp_index = mem_map_v1_table->mapcount; ++ /*System RAM Sort*/ ++ tmp_index = grub_efi_loongson_memmap_v1_sort(free_mem_v1, free_index, mem_map_v1_table, ++ tmp_index, GRUB_EFI_LOONGSON_SYSTEM_RAM); + /*ACPI Sort*/ -+ tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); -+ tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); ++ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_table_mem_v1, acpi_table_index, ++ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); ++ tmp_index = grub_efi_loongson_memmap_v1_sort(acpi_nvs_mem_v1, acpi_nvs_index, ++ mem_map_v1_table, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); + /*Reserve Sort*/ -+ grub_uint64_t loongarch_addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); -+ if((loongarch_addr & 0xff00000000000000) == 0x9000000000000000){ -+ tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED); -+ }else{ -+ tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); -+ } -+ -+ new_interface_mem->mapcount = tmp_index; -+ new_interface_mem->header.checksum = 0; ++ { ++ grub_uint64_t loongarch_addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); ++ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) ++ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, ++ mem_map_v1_table, tmp_index, ++ GRUB_EFI_LOONGSON_MEMORY_RESERVED); ++ else ++ tmp_index = grub_efi_loongson_memmap_v1_sort(reserve_mem_v1, reserve_index, ++ mem_map_v1_table, tmp_index, ++ GRUB_EFI_LOONGSON_MEMORY_RESERVED + 1); ++ } ++ mem_map_v1_table->mapcount = tmp_index; ++ mem_map_v1_table->header.checksum = 0; + -+ checksum = grub_efi_loongson_grub_calculatechecksum8(new_interface_mem, new_interface_mem->header.length); -+ new_interface_mem->header.checksum = checksum; ++ checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)mem_map_v1_table, ++ mem_map_v1_table->header.length); ++ mem_map_v1_table->header.checksum = checksum; + } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linux_boot (void) ++{ ++ struct grub_relocator64_state state; ++ ++ grub_memset (&state, 0, sizeof (state)); ++ ++ /* Boot the kernel. */ ++ state.gpr[1] = entry_addr; ++ grub_dprintf("loongson", "entry_addr is 0x%lx\n", state.gpr[1]); ++ ++ if (is_fdt_boot == 1) ++ { ++ if (allocate_fdt_and_exit_boot () != GRUB_ERR_NONE) ++ return grub_errno; ++ ++ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; ++ state.gpr[5] = (grub_uint64_t)fdt; ++ state.gpr[6] = 0; ++ } else { ++ state.gpr[4] = linux_argc; ++ state.gpr[5] = (grub_addr_t) linux_args_addr; ++ state.gpr[6] = (grub_uint64_t)grub_efi_loongson_get_boot_params(); ++ ++ if (allocate_boot_params_and_exit_boot () != GRUB_ERR_NONE) ++ return grub_errno; + } ++ grub_dprintf("loongson", "gpr[4]:%ld, gpr[5]:0x%lx, gpr[6]:0x%lx\n", ++ state.gpr[4], state.gpr[5], state.gpr[6]); + + state.jumpreg = 1; + grub_relocator64_boot (relocator, state); @@ -2108,67 +1680,42 @@ index 0000000..c769bb2 +{ + grub_relocator_unload (relocator); + grub_dl_unref (my_mod); -+ + loaded = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t -+grub_linux_load32 (grub_elf_t elf, const char *filename) -+{ -+ Elf32_Addr base; -+ grub_err_t err; -+ grub_uint8_t *playground; -+ -+ /* Linux's entry point incorrectly contains a virtual address. */ -+ entry_addr = elf->ehdr.ehdr32.e_entry; -+ -+ linux_size = grub_elf32_size (elf, &base, 0); -+ if (linux_size == 0) -+ return grub_errno; -+ target_addr = base; -+ linux_size = ALIGN_UP (base + linux_size - base, 8); -+ -+ relocator = grub_relocator_new (); -+ if (!relocator) -+ return grub_errno; -+ -+ { -+ grub_relocator_chunk_t ch; -+ err = grub_relocator_alloc_chunk_addr (relocator, &ch, -+ grub_vtop ((void *) target_addr), -+ linux_size); -+ if (err) -+ return err; -+ playground = get_virtual_current_address (ch); -+ } -+ -+ /* Now load the segments into the area we claimed. */ -+ return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); -+} -+ -+static grub_err_t +grub_linux_load64 (grub_elf_t elf, const char *filename) +{ + Elf64_Addr base; + grub_err_t err; + grub_uint8_t *playground; ++ grub_uint64_t addr; ++ int flag; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry; -+ grub_dprintf("loongson", "entry address = %p\n", entry_addr); ++ grub_dprintf("loongson", "entry address = 0x%lx\n", entry_addr); + + linux_size = grub_elf64_size (elf, &base, 0); -+ grub_dprintf("loongson", "base = %p\n", base); ++ grub_dprintf("loongson", "base = 0x%lx\n", base); + + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ if (addr & 0x1) { ++ flag = GRUB_ELF_LOAD_FLAGS_NONE; ++ } else { ++ flag = GRUB_ELF_LOAD_FLAGS_30BITS; ++ base &= ~ELF64_LOADMASK; ++ entry_addr &= ~ELF64_LOADMASK; ++ } ++ + relocator = grub_relocator_new (); -+ // linux_size=0x322fa80; + if (!relocator) + return grub_errno; + @@ -2183,7 +1730,7 @@ index 0000000..c769bb2 + } + + /* Now load the segments into the area we claimed. */ -+ return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); ++ return grub_elf64_load (elf, filename, playground - base, flag, 0, 0); +} + +static grub_err_t @@ -2191,20 +1738,21 @@ index 0000000..c769bb2 + int argc, char *argv[]) +{ + grub_elf_t elf = 0; -+ int size; -+ int i; -+ grub_uint64_t *linux_argv; -+ char *linux_args; + grub_err_t err; ++ int args_size = 0; ++ ++ grub_dl_ref (my_mod); + + if (argc == 0) ++ { + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ } + -+ elf = grub_elf_open (argv[0],GRUB_FILE_TYPE_LINUX_KERNEL); ++ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! elf) + return grub_errno; + -+ if (elf->ehdr.ehdr32.e_type != ET_EXEC) ++ if (elf->ehdr.ehdr64.e_type != ET_EXEC) + { + grub_elf_close (elf); + return grub_error (GRUB_ERR_UNKNOWN_OS, @@ -2215,30 +1763,6 @@ index 0000000..c769bb2 + grub_loader_unset (); + loaded = 0; + -+ /* For arguments. */ -+ linux_argc = argc; -+ /* Main arguments. */ -+ size = (linux_argc) * sizeof (grub_uint64_t); -+ /* Initrd address and size. */ -+ size += 3 * sizeof (grub_uint64_t); -+ /* NULL terminator. */ -+ size += sizeof (grub_uint64_t); -+ /* First argument is always "a0". */ -+ size += ALIGN_UP (sizeof ("a0"), 4); -+ /* Normal arguments. */ -+ for (i = 1; i < argc; i++) -+ size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); -+ -+ /* rd arguments. */ -+ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ -+ size = ALIGN_UP (size, 8); -+ -+ if (grub_elf_is_elf32 (elf)) -+ err = grub_linux_load32 (elf, argv[0]); -+ else + if (grub_elf_is_elf64 (elf)) + err = grub_linux_load64 (elf, argv[0]); + else @@ -2249,26 +1773,71 @@ index 0000000..c769bb2 + if (err) + return err; + -+ { -+ grub_relocator_chunk_t ch; -+ err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xffffffff - size) + 1, -+ size, 8, -+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); -+ if (err) -+ return err; -+ linux_args_addr = get_virtual_current_address (ch); -+ } ++ if (grub_efi_loongson_get_boot_params() == NULL) { ++ grub_size_t cmdline_size; + -+ linux_argv = (grub_uint64_t *) linux_args_addr; -+ linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); ++ is_fdt_boot = 1; ++ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); ++ fdt_linux_args = grub_malloc (cmdline_size); ++ if (!fdt_linux_args) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ grub_memcpy (fdt_linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ err = grub_create_loader_cmdline (argc, argv, ++ fdt_linux_args + sizeof (LINUX_IMAGE) - 1, ++ cmdline_size, ++ GRUB_VERIFY_KERNEL_CMDLINE); ++ if (err) ++ goto fail; ++ grub_dprintf("loongson", "fdt linux args:%s\n", ++ fdt_linux_args + sizeof (LINUX_IMAGE) - 1); ++ ++ } else { ++ int i; ++ grub_uint64_t *linux_argv; ++ char *linux_args; ++ ++ is_fdt_boot = 0; ++ /* For arguments. */ ++ linux_argc = argc; ++ /* Main arguments. */ ++ args_size = (linux_argc) * sizeof (grub_uint64_t); ++ /* Initrd address/size and initrd */ ++ args_size += 3 * sizeof (grub_uint64_t); ++ /* NULL terminator. */ ++ args_size += sizeof (grub_uint64_t); ++ /* First argument is always "a0". */ ++ args_size += ALIGN_UP (sizeof ("a0"), 4); ++ /* Normal arguments. */ ++ for (i = 1; i < argc; i++) ++ args_size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); ++ ++ /* rd arguments. */ ++ args_size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ args_size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ args_size += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ ++ args_size = ALIGN_UP (args_size, 8); ++ ++ linux_args_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ grub_dprintf ("linux", "linux args numpages: %lld\n", ++ (long long) GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ if (!linux_args_addr) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ linux_argv = (grub_uint64_t *) linux_args_addr; ++ linux_args = (char *) (linux_argv + (linux_argc + 1 + 3)); + -+ grub_memcpy (linux_args, "a0", sizeof ("a0")); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("a0"), 4); ++ grub_memcpy (linux_args, "a0", sizeof ("a0")); ++ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; ++ linux_argv++; ++ linux_args += ALIGN_UP (sizeof ("a0"), 4); + -+ for (i = 1; i < argc; i++) ++ for (i = 1; i < argc; i++) + { + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); + *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; @@ -2276,40 +1845,80 @@ index 0000000..c769bb2 + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + } + -+ /* Reserve space for rd arguments. */ -+ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; ++ /* Reserve space for rd arguments. */ ++ rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; ++ ++ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; + -+ rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; ++ /* Reserve space for initrd arguments. */ ++ initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; ++ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); ++ *linux_argv = 0; ++ linux_argv++; + -+ /* Reserve space for initrd arguments. */ -+ initrd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; -+ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ *linux_argv = 0; -+ linux_argv++; ++ *linux_argv = 0; ++ } + -+ *linux_argv = 0; ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); ++ loaded = 1; ++ } + -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + initrd_loaded = 0; -+ loaded = 1; -+ grub_dl_ref (my_mod); + -+ return GRUB_ERR_NONE; ++fail: ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ } ++ ++ if (fdt_linux_args && !loaded) ++ grub_free (fdt_linux_args); ++ ++ if (linux_args_addr && !loaded) ++ grub_efi_free_pages ((grub_addr_t) linux_args_addr, ++ GRUB_EFI_BYTES_TO_PAGES (args_size)); ++ ++ return grub_errno; ++} ++ ++#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) ++ ++/* ++ * This function returns a pointer to a legally allocated initrd buffer, ++ * or NULL if unsuccessful ++ */ ++static void * ++allocate_initrd_mem (int initrd_pages) ++{ ++ grub_addr_t max_addr; ++ ++ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) ++ return NULL; ++ ++ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; ++ ++ return grub_efi_allocate_pages_real (max_addr, initrd_pages, ++ GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_LOADER_DATA); +} + ++ +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ -+ grub_size_t size = 0; -+ void *initrd_dest; ++ grub_size_t initrd_size, initrd_pages; + grub_err_t err; ++ void *initrd_mem = NULL; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) @@ -2324,49 +1933,71 @@ index 0000000..c769bb2 + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + -+ size = grub_get_initrd_size (&initrd_ctx); ++ initrd_size = grub_get_initrd_size (&initrd_ctx); + ++ if (is_fdt_boot == 1) //fdt + { ++ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); ++ initrd_mem = allocate_initrd_mem (initrd_pages); ++ if (!initrd_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto fail; ++ } ++ } else { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xffffffff - size) + 1, -+ size, 0x10000, -+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); ++ 0, (0xffffffff - initrd_size) + 1, ++ initrd_size, 0x10000, ++ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + + if (err) -+ goto fail; -+ initrd_dest = get_virtual_current_address (ch); ++ return err; ++ initrd_mem = get_virtual_current_address (ch); + } + -+ if (grub_initrd_load (&initrd_ctx, argv, initrd_dest)) ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + -+ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, -+ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx", -+ (grub_uint64_t) initrd_dest); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); -+ linux_argc++; -+ -+ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, -+ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", -+ (grub_uint64_t) size); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); -+ linux_argc++; -+ ++ initrd_start = (grub_addr_t) initrd_mem; ++ initrd_end = initrd_start + initrd_size; ++ grub_dprintf ("linux", "[addr=%p, size=0x%lx]\n", ++ (void *) initrd_start, initrd_size); + -+ grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, -+ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) initrd_dest & 0xffffffff), (grub_uint64_t) size); -+ ((grub_uint64_t *) linux_args_addr)[linux_argc] -+ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); -+ linux_argc++; ++ if (is_fdt_boot == 0) //bpi ++ { ++ grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, ++ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), ++ "rd_start=0x%lx", ++ (grub_uint64_t) initrd_mem); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); ++ linux_argc++; ++ ++ grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, ++ sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", ++ (grub_uint64_t) initrd_size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); ++ linux_argc++; ++ ++ grub_snprintf ((char *) linux_args_addr + initrd_addr_arg_off, ++ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), ++ "initrd=0x%lx,0x%lx", ++ ((grub_uint64_t) initrd_mem & GRUB_EFI_MAX_PHY_ADDRESS), ++ (grub_uint64_t) initrd_size); ++ ((grub_uint64_t *) linux_args_addr)[linux_argc] ++ = (grub_uint64_t) ((grub_addr_t) linux_args_addr + initrd_addr_arg_off); ++ linux_argc++; ++ } + + initrd_loaded = 1; + + fail: + grub_initrd_close (&initrd_ctx); ++ if (is_fdt_boot == 1) ++ if (initrd_mem && !initrd_start) ++ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + + return grub_errno; +} @@ -2388,10 +2019,10 @@ index 0000000..c769bb2 + grub_unregister_command (cmd_initrd); +} diff --git a/include/grub/dl.h b/include/grub/dl.h -index 6a3e251..c1b6dd9 100644 +index 6f46b7e..50e04ac 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h -@@ -314,7 +314,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, +@@ -360,7 +360,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, #define GRUB_ARCH_DL_GOT_ALIGN 4 #endif @@ -2401,11 +2032,11 @@ index 6a3e251..c1b6dd9 100644 #define GRUB_ARCH_DL_GOT_ALIGN 8 #endif diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 37e7b16..049326c 100644 +index 510a403..a57187f 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h -@@ -2087,7 +2087,8 @@ struct grub_efi_rng_protocol - typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; +@@ -2117,7 +2117,8 @@ struct grub_efi_memory_attribute_protocol + typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t; #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) @@ -2414,11 +2045,24 @@ index 37e7b16..049326c 100644 #define efi_call_0(func) func() #define efi_call_1(func, a) func(a) +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index 8ca8c38..fe1df9d 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -138,7 +138,7 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, + extern grub_addr_t EXPORT_VAR(grub_stack_addr); + extern grub_size_t EXPORT_VAR(grub_stack_size); + +-#if defined(__arm__) || defined(__aarch64__) ++#if defined(__arm__) || defined(__aarch64__) || defined (__loongarch__) + void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); + grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); + #include diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index c03cc59..be88c54 100644 +index 45c9f8b..f612a55 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h -@@ -66,6 +66,7 @@ struct grub_pe32_coff_header +@@ -89,6 +89,7 @@ struct grub_pe32_coff_header }; #define GRUB_PE32_MACHINE_I386 0x14c @@ -2426,7 +2070,7 @@ index c03cc59..be88c54 100644 #define GRUB_PE32_MACHINE_IA64 0x200 #define GRUB_PE32_MACHINE_X86_64 0x8664 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 -@@ -329,6 +330,7 @@ struct grub_pe32_fixup_block +@@ -355,6 +356,7 @@ struct grub_pe32_fixup_block #define GRUB_PE32_REL_BASED_IA64_IMM64 9 #define GRUB_PE32_REL_BASED_DIR64 10 #define GRUB_PE32_REL_BASED_HIGH3ADJ 11 @@ -2507,6 +2151,26 @@ index c8492f9..2c0b163 100644 /* MIPS relocs. */ #define R_MIPS_NONE 0 /* No reloc */ +diff --git a/include/grub/fdt.h b/include/grub/fdt.h +index 6ee57e1..a0710ab 100644 +--- a/include/grub/fdt.h ++++ b/include/grub/fdt.h +@@ -19,11 +19,14 @@ + #ifndef GRUB_FDT_HEADER + #define GRUB_FDT_HEADER 1 + +-#if defined(__arm__) || defined(__aarch64__) ++#if defined(__arm__) || defined(__aarch64__) || defined (__loongarch__) + + #include + #include + ++/* Space required when preparing the /chosen node after boot has been called. */ ++#define GRUB_EFI_LINUX_FDT_EXTRA_SPACE 0x400 ++ + #define FDT_MAGIC 0xD00DFEED + + typedef struct { diff --git a/include/grub/loongarch64/asm.h b/include/grub/loongarch64/asm.h new file mode 100644 index 0000000..c3e77e9 @@ -2523,46 +2187,12 @@ index 0000000..c3e77e9 +#define GRUB_ASM_REG_L ld.d + +#endif -diff --git a/include/grub/loongarch64/efi/boot.h b/include/grub/loongarch64/efi/boot.h -new file mode 100644 -index 0000000..e69de29 -diff --git a/include/grub/loongarch64/efi/loader.h b/include/grub/loongarch64/efi/loader.h -new file mode 100644 -index 0000000..71a0159 ---- /dev/null -+++ b/include/grub/loongarch64/efi/loader.h -@@ -0,0 +1,25 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2003,2004,2006,2007,2017 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 . -+ */ -+ -+#ifndef GRUB_LOADER_MACHINE_HEADER -+#define GRUB_LOADER_MACHINE_HEADER 1 -+ -+#include -+#include -+ -+#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/loongarch64/efi/loongson.h b/include/grub/loongarch64/efi/loongson.h new file mode 100644 -index 0000000..fa32ef5 +index 0000000..7a9ccb4 --- /dev/null +++ b/include/grub/loongarch64/efi/loongson.h -@@ -0,0 +1,290 @@ +@@ -0,0 +1,113 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. @@ -2588,12 +2218,17 @@ index 0000000..fa32ef5 + +#include + -+#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \ ++#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ + { 0x4660f721, 0x2ec5, 0x416a, \ + { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ + } + ++#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL ++#define ELF32_LOADMASK (0xf0000000UL) ++#define ELF64_LOADMASK (0xf000000000000000ULL) ++#define FLAGS_EFI_SUPPORT_BIT 0 +#define GRUB_EFI_LOONGSON_MMAP_MAX 128 ++ +typedef enum + { + GRUB_EFI_LOONGSON_SYSTEM_RAM = 1, @@ -2604,272 +2239,88 @@ index 0000000..fa32ef5 + } +grub_efi_loongson_memory_type; + -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ grub_uint32_t nr_map; /* number of memory_maps */ -+ grub_uint32_t mem_freq; /* memory frequence */ -+ struct mem_map { -+ grub_uint32_t node_id; /* node_id which memory attached to */ -+ grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ -+ grub_uint64_t mem_start; /* memory map start address */ -+ grub_uint32_t mem_size; /* each memory_map size, not the total size */ -+ } map[GRUB_EFI_LOONGSON_MMAP_MAX]; -+} GRUB_PACKED -+grub_efi_loongson_memory_map; -+ -+/* -+ * Capability and feature descriptor structure for LOONGARCH CPU -+ */ -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ -+ grub_uint32_t cputype; /* Loongson_3A/3B, etc. */ -+ grub_uint32_t total_node; /* num of total numa nodes */ -+ grub_uint16_t cpu_startup_core_id; /* Boot core id */ -+ grub_uint16_t reserved_cores_mask; -+ grub_uint32_t cpu_clock_freq; /* cpu_clock */ -+ grub_uint32_t nr_cpus; -+} GRUB_PACKED -+grub_efi_loongson_cpu_info; -+ -+#define GRUB_EFI_LOONGSON_MAX_UARTS 64 -+ -+typedef struct -+{ -+ grub_uint32_t iotype; /* see include/linux/serial_core.h */ -+ grub_uint32_t uartclk; -+ grub_uint32_t int_offset; -+ grub_uint64_t uart_base; -+} GRUB_PACKED -+grub_efi_loongson_uart_device; -+ -+#define GRUB_EFI_LOONGSON_MAX_SENSORS 64 -+ -+typedef struct -+{ -+ char name[32]; /* a formal name */ -+ char label[64]; /* a flexible description */ -+ grub_uint32_t type; /* SENSOR_* */ -+ grub_uint32_t id; /* instance id of a sensor-class */ -+ grub_uint32_t fan_policy; -+ grub_uint32_t fan_percent; /* only for constant speed policy */ -+ grub_uint64_t base_addr; /* base address of device registers */ -+} GRUB_PACKED -+grub_efi_loongson_sensor_device; -+ -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ -+ grub_uint32_t sing_double_channel; /* 1:single; 2:double */ -+ grub_uint32_t nr_uarts; -+ grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS]; -+ grub_uint32_t nr_sensors; -+ grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS]; -+ char has_ec; -+ char ec_name[32]; -+ grub_uint64_t ec_base_addr; -+ char has_tcm; -+ char tcm_name[32]; -+ grub_uint64_t tcm_base_addr; -+ grub_uint64_t workarounds; /* see workarounds.h */ -+} GRUB_PACKED -+grub_efi_loongson_system_info; -+ -+typedef struct -+{ -+ grub_uint16_t vers; -+ grub_uint16_t size; -+ grub_uint16_t rtr_bus; -+ grub_uint16_t rtr_devfn; -+ grub_uint32_t vendor; -+ grub_uint32_t device; -+ grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ -+ grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ -+ grub_uint64_t ht_enable; /* irqs used in this PIC */ -+ grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ -+ grub_uint64_t pci_mem_start_addr; -+ grub_uint64_t pci_mem_end_addr; -+ grub_uint64_t pci_io_start_addr; -+ grub_uint64_t pci_io_end_addr; -+ grub_uint64_t pci_config_addr; -+ grub_uint32_t dma_mask_bits; -+} GRUB_PACKED -+grub_efi_loongson_irq_src_routing_table; -+ -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ grub_uint16_t size; -+ grub_uint8_t flag; -+ char description[64]; -+} GRUB_PACKED -+grub_efi_loongson_interface_info; -+ -+#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128 -+ -+typedef struct -+{ -+ grub_uint64_t start; /* resource start address */ -+ grub_uint64_t end; /* resource end address */ -+ char name[64]; -+ grub_uint32_t flags; -+} -+grub_efi_loongson_resource; -+ -+/* arch specific additions */ -+typedef struct -+{ -+} -+grub_efi_loongson_archdev_data; -+ -+typedef struct -+{ -+ char name[64]; /* hold the device name */ -+ grub_uint32_t num_resources; /* number of device_resource */ -+ /* for each device's resource */ -+ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; -+ /* arch specific additions */ -+ grub_efi_loongson_archdev_data archdata; -+} -+grub_efi_loongson_board_devices; -+ -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ char special_name[64]; /* special_atribute_name */ -+ grub_uint32_t loongson_special_type; /* type of special device */ -+ /* for each device's resource */ -+ grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; -+} -+grub_efi_loongson_special_attribute; -+ -+typedef struct -+{ -+ grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */ -+ grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */ -+ grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */ -+ grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */ -+ grub_uint64_t interface_offset; /* interface_info struct offset */ -+ grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */ -+ grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */ -+} -+grub_efi_loongson_params; -+ -+typedef struct -+{ -+ grub_uint16_t vers; /* version */ -+ grub_uint64_t vga_bios; /* vga_bios address */ -+ grub_efi_loongson_params lp; -+} -+grub_efi_loongson_smbios_table; -+ -+typedef struct -+{ -+ grub_uint64_t reset_cold; -+ grub_uint64_t reset_warm; -+ grub_uint64_t reset_type; -+ grub_uint64_t shutdown; -+ grub_uint64_t do_suspend; /* NULL if not support */ -+} -+grub_efi_loongson_reset_system; -+ -+typedef struct -+{ -+ grub_uint64_t mps; /* MPS table */ -+ grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ -+ grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ -+ grub_efi_loongson_smbios_table smbios; /* SM BIOS table */ -+ grub_uint64_t sal_systab; /* SAL system table */ -+ grub_uint64_t boot_info; /* boot info table */ -+} -+grub_efi_loongson; -+ -+typedef struct -+{ -+ grub_efi_loongson efi; -+ grub_efi_loongson_reset_system reset_system; -+} -+grub_efi_loongson_boot_params; -+ -+extern grub_uint64_t grub_efi_loongson_reset_system_addr; -+ -+extern void grub_efi_loongson_reset_cold (void); -+extern void grub_efi_loongson_reset_warm (void); -+extern void grub_efi_loongson_reset_shutdown (void); -+extern void grub_efi_loongson_reset_suspend (void); -+ -+void grub_efi_loongson_alloc_boot_params (void); -+void grub_efi_loongson_free_boot_params (void); -+void * grub_efi_loongson_get_smbios_table (void); -+ -+int EXPORT_FUNC(grub_efi_is_loongson) (void); ++typedef enum ++ { ++ GRUB_EFI_BPI_VER_NONE = 0, ++ GRUB_EFI_BPI_VER_V1 = 1000, ++ GRUB_EFI_BPI_VER_V2 = 1001, ++ } ++ grub_efi_loongson_bpi_version; + +grub_uint8_t -+EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, ++ grub_efi_uintn_t Length); + +grub_uint8_t -+EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); ++EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, ++ grub_efi_uintn_t Length); + ++unsigned long ++EXPORT_FUNC(grub_efi_get_bpi_version) (const char *str); + +void * +EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); + -+typedef struct _extention_list_hdr{ ++typedef struct _extention_list_hdr { + grub_uint64_t signature; + grub_uint32_t length; + grub_uint8_t revision; + grub_uint8_t checksum; -+ struct _extention_list_hdr *next; ++ union { ++ struct _extention_list_hdr *next; ++ grub_uint64_t next_offset; ++ }; +}GRUB_PACKED +ext_list; + -+typedef struct bootparamsinterface { -+ grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'} ++typedef struct boot_params_interface { ++ grub_uint64_t signature; //{'B', 'P', 'I', 'x', 'x', 'x', 'x', 'x'} + grub_efi_system_table_t *systemtable; -+ ext_list *extlist; ++ union { ++ ext_list *extlist; ++ grub_uint64_t extlist_offset; ++ }; ++ grub_uint64_t flags; +}GRUB_PACKED -+bootparamsinterface; ++boot_params_interface; + +typedef struct { -+ ext_list header; // {'M', 'E', 'M'} ++ ext_list header; //{MEM} + grub_uint8_t mapcount; -+ struct GRUB_PACKED memmap { ++ struct GRUB_PACKED memmap_v1 { + grub_uint32_t memtype; + grub_uint64_t memstart; + grub_uint64_t memsize; + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +}GRUB_PACKED -+mem_map; ++mem_map_v1; + +typedef struct { -+ ext_list header; // {VBIOS} ++ ext_list header; //{VBIOS} + grub_uint64_t vbiosaddr; +}GRUB_PACKED +vbios; + -+grub_uint32_t -+EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype); ++grub_uint32_t ++EXPORT_FUNC (grub_efi_loongson_memmap_v1_sort) (struct memmap_v1 array[], ++ grub_uint32_t length, mem_map_v1 * mem, ++ grub_uint32_t index, grub_uint32_t memtype); +#endif /* ! GRUB_EFI_LOONGSON_HEADER */ diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h new file mode 100644 -index 0000000..b8556c7 +index 0000000..73641a1 --- /dev/null +++ b/include/grub/loongarch64/efi/memory.h -@@ -0,0 +1,14 @@ +@@ -0,0 +1,12 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include + -+#define GRUB_EFI_MAX_USABLE_ADDRESS 0x9800000fffffffffUL -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS -+ -+static inline grub_uint64_t grub_efi_max_usable_address(void) ++static inline grub_uint64_t ++grub_efi_max_usable_address(void) +{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ return addr |= 0xffffffffffUL; ++ grub_uint64_t addr; ++ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); ++ return addr |= 0xffffffffffUL; +} + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ @@ -2944,15 +2395,15 @@ index 0000000..5f34103 +} + +#endif /* _SYS_IO_H */ -diff --git a/include/grub/loongarch64/kernel.h b/include/grub/loongarch64/kernel.h +diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h new file mode 100644 -index 0000000..909d539 +index 0000000..3c6cf65 --- /dev/null -+++ b/include/grub/loongarch64/kernel.h -@@ -0,0 +1,24 @@ ++++ b/include/grub/loongarch64/linux.h +@@ -0,0 +1,74 @@ +/* + * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2005,2006,2007,2008,2009,2017 Free Software Foundation, Inc. ++ * Copyright (C) 2021 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 @@ -2968,38 +2419,60 @@ index 0000000..909d539 + * along with GRUB. If not, see . + */ + -+#ifndef GRUB_KERNEL_CPU_HEADER -+#define GRUB_KERNEL_CPU_HEADER 1 ++#ifndef GRUB_LOONGARCH64_LINUX_HEADER ++#define GRUB_LOONGARCH64_LINUX_HEADER 1 + -+#include ++#include + -+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -new file mode 100644 -index 0000000..cbf8775 ---- /dev/null -+++ b/include/grub/loongarch64/linux.h -@@ -0,0 +1,22 @@ -+/* -+ * 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. ++/* LoongArch linux kernel type */ ++#define GRUB_LOONGARCH_LINUX_BAD 0 ++#define GRUB_LOONGARCH_LINUX_ELF 1 ++#define GRUB_LOONGARCH_LINUX_EFI 2 ++ ++#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 ++ ++#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x4C6F6F6E67417263 /* 'LoongArc' */ ++#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE2 0x68 /* 'h' */ ++#define linux_arch_kernel_header linux_loongarch64_kernel_header ++ ++/* From linux/Documentation/loongarch/booting.txt + * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . ++ * 0-1: MZ ++ * 0x28: LoongArch\0 ++ * 0x3c: PE/COFF头偏移 ++ * 0x20e:内核版本号偏移-512 ++ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 + */ ++struct linux_loongarch64_kernel_header ++{ ++ grub_uint32_t code0; /* Executable code */ ++ grub_uint32_t code1; /* Executable code */ ++ grub_uint64_t text_offset; /* Image load offset */ ++ grub_uint64_t res0; /* reserved */ ++ grub_uint64_t res1; /* reserved */ ++ grub_uint64_t res2; /* reserved */ ++ grub_uint64_t magic; /* Magic number, little endian, "LoongArc" */ ++ grub_uint32_t magic1; /* Magic number, little endian, "h" */ ++ grub_uint64_t res3; /* reserved */ ++ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ ++}; + -+#ifndef GRUB_LOONGARCH64_LINUX_HEADER -+#define GRUB_LOONGARCH64_LINUX_HEADER 1 ++struct linux_loongarch64_kernel_params ++{ ++ grub_addr_t kernel_addr; /* kernel entry address */ ++ grub_size_t kernel_size; /* kernel size */ ++ grub_addr_t ramdisk_addr; /* initrd load address */ ++ grub_size_t ramdisk_size; /* initrd size */ ++ int linux_argc; ++ grub_addr_t linux_argv; ++ void* linux_args; ++}; ++ ++#include ++#include ++ ++#define ELF32_LOADMASK (0xf0000000UL) ++#define ELF64_LOADMASK (0xf000000000000000ULL) + +#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ diff --git a/include/grub/loongarch64/loongarch64.h b/include/grub/loongarch64/loongarch64.h @@ -3040,10 +2513,10 @@ index 0000000..ea3be3d +#endif diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h new file mode 100644 -index 0000000..03398b3 +index 0000000..8281dab --- /dev/null +++ b/include/grub/loongarch64/memory.h -@@ -0,0 +1,57 @@ +@@ -0,0 +1,60 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. @@ -3084,12 +2557,15 @@ index 0000000..03398b3 +} + +static inline void * -+grub_map_memory (grub_phys_addr_t a, grub_size_t size) ++grub_map_memory (grub_phys_addr_t a, ++ grub_size_t size __attribute__ ((unused))) +{ + grub_uint64_t addr; -+ + asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ return (void *) (a | (addr & 0xffffffffffffff00UL)); ++ if (addr & 0x1) ++ return (void *) (a | (addr & 0xffffffffffffff00UL)); ++ else ++ return (void *) a; +} + +static inline void @@ -3937,7 +3413,7 @@ index 03ba1ab..4a9943a 100644 struct platform_whitelist { diff --git a/util/mkimage.c b/util/mkimage.c -index 16418e2..0d39c07 100644 +index c770259..250ca81 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -609,6 +609,22 @@ static const struct grub_install_image_target_desc image_targets[] = @@ -3964,5 +3440,5 @@ index 16418e2..0d39c07 100644 #include -- -2.27.0 +2.1.0 diff --git a/grub.patches b/grub.patches index d138efb..ad599c3 100644 --- a/grub.patches +++ b/grub.patches @@ -574,3 +574,4 @@ Patch0573: 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch # Support loongarch64 #Patch1000: 1000-loongarch64-add-support.patch Patch1001: 1001-bls-make-list.patch +Patch1002: 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch diff --git a/grub2.spec b/grub2.spec index 054929e..f5efb3f 100644 --- a/grub2.spec +++ b/grub2.spec @@ -527,6 +527,9 @@ fi - Build pc-modules package on x86_64 (geliwei@openanolis.org) - Add loongarch64 base support (zhangwenlong@loongson.cn)(chenguoqi@loongson.cn) - Fix a bug in bls_make_list, blscfg. (zhonglingh@linux.alibaba.com) +- Delete LoongArch64 support old version due to compile error(yangqiming@loongson.cn) +- Add LoongArch64 support(yangqiming@loongson.cn) +- LoongArch64 support fdt and phy-addr BIOS(yangqiming@loongson.cn) * Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 - Sync with 8.8 (actually 2.02-145) -- Gitee From 6f77925e6aff374638e9b4c27d5cfb5c4829c303 Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Thu, 18 Aug 2022 16:47:48 +0800 Subject: [PATCH 6/6] kernel-install: remove dtb dir with correct rm argument --- 20-grub.install | 2 +- grub2.spec | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/20-grub.install b/20-grub.install index 9b74538..a05c15c 100755 --- a/20-grub.install +++ b/20-grub.install @@ -62,7 +62,7 @@ case "$COMMAND" in "$KERNEL_DIR"/dtb do [[ -e "$i" ]] || continue - rm -f "/boot/${i##*/}-${KERNEL_VERSION}" + rm -rf "/boot/${i##*/}-${KERNEL_VERSION}" cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}" command -v restorecon &>/dev/null && \ restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}" diff --git a/grub2.spec b/grub2.spec index f5efb3f..e47595d 100644 --- a/grub2.spec +++ b/grub2.spec @@ -530,6 +530,7 @@ fi - Delete LoongArch64 support old version due to compile error(yangqiming@loongson.cn) - Add LoongArch64 support(yangqiming@loongson.cn) - LoongArch64 support fdt and phy-addr BIOS(yangqiming@loongson.cn) +- Remove dtb dir with correct argument (Liwei Ge) * Thu Nov 08 2022 Robbie Harwood - 2.02-142.el8_7.1 - Sync with 8.8 (actually 2.02-145) -- Gitee