From: Heiher <r...@hev.cc> --- configure.ac | 21 ++- gentpl.py | 5 +- grub-core/Makefile.am | 6 + grub-core/Makefile.core.def | 13 ++ grub-core/kern/mips64/cache.S | 23 ++++ grub-core/kern/mips64/dl.c | 150 +++++++++++++++++++++ grub-core/kern/mips64/efi/init.c | 44 ++++++ grub-core/kern/mips64/efi/startup.S | 47 +++++++ grub-core/kern/mips64/init.c | 47 +++++++ grub-core/lib/efi/halt.c | 2 +- grub-core/lib/mips64/setjmp.S | 69 ++++++++++ grub-core/lib/setjmp.S | 4 + grub-core/term/serial.c | 8 +- include/grub/cache.h | 2 +- include/grub/dl.h | 8 +- include/grub/efi/api.h | 2 +- include/grub/efi/pe32.h | 5 + include/grub/mips64/asm.h | 10 ++ include/grub/mips64/efi/boot.h | 0 include/grub/mips64/efi/loader.h | 25 ++++ include/grub/mips64/efi/memory.h | 6 + include/grub/mips64/efi/time.h | 0 include/grub/mips64/io.h | 62 +++++++++ include/grub/mips64/kernel.h | 24 ++++ include/grub/mips64/memory.h | 56 ++++++++ include/grub/mips64/mips.h | 30 +++++ include/grub/mips64/setjmp.h | 27 ++++ include/grub/mips64/time.h | 39 ++++++ include/grub/mips64/types.h | 38 ++++++ include/grub/misc.h | 2 +- include/grub/serial.h | 6 +- include/grub/util/install.h | 1 + util/grub-install-common.c | 1 + util/grub-install.c | 18 +++ util/grub-mkimagexx.c | 259 ++++++++++++++++++++++++++++++++++-- util/grub-mknetdir.c | 3 +- util/grub-mkrescue.c | 9 +- util/grub-module-verifier.c | 13 ++ util/grub-module-verifierXX.c | 11 +- util/mkimage.c | 16 +++ 40 files changed, 1078 insertions(+), 34 deletions(-) create mode 100644 grub-core/kern/mips64/cache.S create mode 100644 grub-core/kern/mips64/dl.c create mode 100644 grub-core/kern/mips64/efi/init.c create mode 100644 grub-core/kern/mips64/efi/startup.S create mode 100644 grub-core/kern/mips64/init.c create mode 100644 grub-core/lib/mips64/setjmp.S create mode 100644 include/grub/mips64/asm.h create mode 100644 include/grub/mips64/efi/boot.h create mode 100644 include/grub/mips64/efi/loader.h create mode 100644 include/grub/mips64/efi/memory.h create mode 100644 include/grub/mips64/efi/time.h create mode 100644 include/grub/mips64/io.h create mode 100644 include/grub/mips64/kernel.h create mode 100644 include/grub/mips64/memory.h create mode 100644 include/grub/mips64/mips.h create mode 100644 include/grub/mips64/setjmp.h create mode 100644 include/grub/mips64/time.h create mode 100644 include/grub/mips64/types.h
diff --git a/configure.ac b/configure.ac index 0893ad60c..fa017bc37 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,11 @@ case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; amd64) target_cpu=x86_64 ;; sparc) target_cpu=sparc64 ;; - mipsel|mips64el) + mips64el) + target_cpu=mips64el + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS64EL=1" + ;; + mipsel) target_cpu=mipsel machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1" ;; @@ -118,6 +122,7 @@ if test "x$with_platform" = x; then powerpc64-*) platform=ieee1275 ;; powerpc64le-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;; + mips64el-*) platform=efi;; mipsel-*) platform=loongson ;; mips-*) platform=arc ;; ia64-*) platform=efi ;; @@ -166,6 +171,7 @@ case "$target_cpu"-"$platform" in mipsel-yeeloong) platform=loongson ;; mipsel-fuloong) platform=loongson ;; mipsel-loongson) ;; + mips64el-efi) ;; arm-uboot) ;; arm-efi) ;; arm64-efi) ;; @@ -1234,10 +1240,15 @@ grub_CHECK_PIC # movk's which aren't representable. # Since default varies across dictributions use either -fPIC or -fno-PIC # explicitly. -if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 ) && test "x$grub_cv_cc_target_clang" = xyes ; then +if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 || test x$target_cpu = xmips64el ) && test "x$grub_cv_cc_target_clang" = xyes ; then TARGET_CFLAGS="$TARGET_CFLAGS -fPIC" elif [ x"$pic_possible" = xyes ]; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" +fi +# Don't generate SVR4-style position-independent code for MIPS64. +if test x$target_cpu = xmips64el ; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-abicalls" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-abicalls" fi] CFLAGS="$TARGET_CFLAGS" @@ -1894,12 +1905,14 @@ AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen]) AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) +AM_CONDITIONAL([COND_mips64_efi], [test x$target_cpu = xmips64el -a x$platform = xefi]) AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson]) AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips]) AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) 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_mips64el], [test x$target_cpu = xmips64el]) 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]) @@ -1956,7 +1969,9 @@ AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir]) # Output files. if test "$platform" != none; then cpudir="${target_cpu}" - if test x${cpudir} = xmipsel; then + if test x${cpudir} = xmips64el; then + cpudir=mips64; + elif test x${cpudir} = xmipsel; then cpudir=mips; fi grub_CHECK_LINK_DIR diff --git a/gentpl.py b/gentpl.py index f08bcc404..e9ec540ca 100644 --- a/gentpl.py +++ b/gentpl.py @@ -29,7 +29,7 @@ import re GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "x86_64_efi", "i386_xen", "x86_64_xen", - "mips_loongson", "sparc64_ieee1275", + "mips_loongson", "mips64_efi", "sparc64_ieee1275", "powerpc_ieee1275", "mips_arc", "ia64_efi", "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ] @@ -42,13 +42,14 @@ GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i38 GROUPS["x86_64"] = [ "x86_64_efi" ] GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] +GROUPS["mips64"] = [ "mips64_efi" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ] GROUPS["arm"] = [ "arm_uboot", "arm_efi" ] GROUPS["arm64"] = [ "arm64_efi" ] # Groups based on firmware -GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" ] +GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "mips64_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 04e9395fd..5512f274f 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -216,6 +216,12 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h endif +if COND_mips64_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 +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 2dfa22a92..e23782c1f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -93,6 +93,9 @@ kernel = { arm_uboot_ldflags = '-Wl,-r,-d'; arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + mips64_efi_ldflags = '-Wl,-r,-d'; + mips64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame -R .MIPS.abiflags'; + 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; @@ -103,6 +106,7 @@ kernel = { i386_coreboot_startup = kern/i386/coreboot/startup.S; i386_multiboot_startup = kern/i386/coreboot/startup.S; mips_startup = kern/mips/startup.S; + mips64_efi_startup = kern/mips64/efi/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; arm_uboot_startup = kern/arm/uboot/startup.S; @@ -263,6 +267,12 @@ kernel = { extra_dist = video/sis315_init.c; mips_loongson = commands/keylayouts.c; + mips64 = kern/mips64/init.c; + mips64 = kern/mips64/dl.c; + mips64 = kern/mips64/cache.S; + mips64 = kern/generic/rtc_get_time_ms.c; + mips64_efi = kern/mips64/efi/init.c; + powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/dl.c; powerpc_ieee1275 = kern/powerpc/compiler-rt.S; @@ -750,6 +760,7 @@ module = { enable = sparc64_ieee1275; enable = powerpc_ieee1275; enable = mips_arc; + enable = mips64_efi; enable = ia64_efi; enable = arm_efi; enable = arm64_efi; @@ -853,6 +864,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; + mips64_efi = lib/efi/reboot.c; xen = lib/xen/reboot.c; uboot = lib/uboot/reboot.c; common = commands/reboot.c; @@ -1762,6 +1774,7 @@ module = { enable = arm_efi; enable = arm64_efi; enable = mips; + enable = mips64_efi; }; module = { diff --git a/grub-core/kern/mips64/cache.S b/grub-core/kern/mips64/cache.S new file mode 100644 index 000000000..c1fb4d44a --- /dev/null +++ b/grub-core/kern/mips64/cache.S @@ -0,0 +1,23 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/symbol.h> + +FUNCTION (grub_arch_sync_caches) + jr.hb $ra + diff --git a/grub-core/kern/mips64/dl.c b/grub-core/kern/mips64/dl.c new file mode 100644 index 000000000..7c6a0833b --- /dev/null +++ b/grub-core/kern/mips64/dl.c @@ -0,0 +1,150 @@ +/* dl-mips64.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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/dl.h> +#include <grub/elf.h> +#include <grub/misc.h> +#include <grub/err.h> +#include <grub/cpu/types.h> +#include <grub/mm.h> +#include <grub/i18n.h> + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ +#ifdef GRUB_CPU_WORDS_BIGENDIAN + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_MIPS) +#else + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_MIPS) +#endif + 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; + + 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 << 32) | + (grub_uint32_t) grub_be_to_cpu64 (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_MIPS_64: + *(grub_uint64_t *) addr += sym_value; + break; + case R_MIPS_32: + *(grub_uint32_t *) addr += sym_value; + break; + case R_MIPS_26: + { + grub_uint32_t value; + grub_uint32_t raw; + raw = (*(grub_uint32_t *) addr) & 0x3ffffff; + value = raw << 2; + value += sym_value; + raw = (value >> 2) & 0x3ffffff; + + *(grub_uint32_t *) addr = + raw | ((*(grub_uint32_t *) addr) & 0xfc000000); + } + break; + case R_MIPS_LO16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) sym_value; + break; + case R_MIPS_HI16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x8000UL) >> 16); + break; + case R_MIPS_HIGHER: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x80008000UL) >> 32); + break; + case R_MIPS_HIGHEST: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_uint16_t) ((sym_value + 0x800080008000UL) >> 48); + 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/mips64/efi/init.c b/grub-core/kern/mips64/efi/init.c new file mode 100644 index 000000000..074736db9 --- /dev/null +++ b/grub-core/kern/mips64/efi/init.c @@ -0,0 +1,44 @@ +/* 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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/env.h> +#include <grub/kernel.h> +#include <grub/misc.h> +#include <grub/mm.h> +#include <grub/cpu/time.h> +#include <grub/efi/efi.h> +#include <grub/loader.h> + +void +grub_machine_init (void) +{ + grub_efi_init (); + + /* FIXME: Get cpuclock from EFI. */ + grub_timer_init (1000000000U); +} + +void +grub_machine_fini (int flags) +{ + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) + return; + + grub_efi_fini (); +} diff --git a/grub-core/kern/mips64/efi/startup.S b/grub-core/kern/mips64/efi/startup.S new file mode 100644 index 000000000..4fee9bee1 --- /dev/null +++ b/grub-core/kern/mips64/efi/startup.S @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/symbol.h> + + .file "startup.S" + .text + + .set push + .align 4 + +FUNCTION(_start) + /* + * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. + */ + daddiu $sp, -16 + sd $ra, ($sp) + + dla $a2, grub_efi_image_handle + sd $a0, ($a2) + dla $a2, grub_efi_system_table + sd $a1, ($a2) + + jal grub_main + +1: + ld $ra, ($sp) + daddiu $sp, 16 + jr $ra + + .set pop + diff --git a/grub-core/kern/mips64/init.c b/grub-core/kern/mips64/init.c new file mode 100644 index 000000000..8fd0a88a5 --- /dev/null +++ b/grub-core/kern/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/kernel.h> +#include <grub/env.h> +#include <grub/time.h> +#include <grub/cpu/mips.h> + +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 ("mfc0 %0, " GRUB_CPU_MIPS_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/efi/halt.c b/grub-core/lib/efi/halt.c index e9441c844..3c4453922 100644 --- a/grub-core/lib/efi/halt.c +++ b/grub-core/lib/efi/halt.c @@ -29,7 +29,7 @@ void grub_halt (void) { grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); -#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) +#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) grub_acpi_halt (); #endif efi_call_4 (grub_efi_system_table->runtime_services->reset_system, diff --git a/grub-core/lib/mips64/setjmp.S b/grub-core/lib/mips64/setjmp.S new file mode 100644 index 000000000..99ae22c18 --- /dev/null +++ b/grub-core/lib/mips64/setjmp.S @@ -0,0 +1,69 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/symbol.h> +#include <grub/dl.h> +#include <grub/mips64/asm.h> + + .file "setjmp.S" + +GRUB_MOD_LICENSE "GPLv3+" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + GRUB_ASM_REG_S $s0, 0($a0) + GRUB_ASM_REG_S $s1, 8($a0) + GRUB_ASM_REG_S $s2, 16($a0) + GRUB_ASM_REG_S $s3, 24($a0) + GRUB_ASM_REG_S $s4, 32($a0) + GRUB_ASM_REG_S $s5, 40($a0) + GRUB_ASM_REG_S $s6, 48($a0) + GRUB_ASM_REG_S $s7, 56($a0) + GRUB_ASM_REG_S $s8, 64($a0) + GRUB_ASM_REG_S $gp, 72($a0) + GRUB_ASM_REG_S $sp, 80($a0) + GRUB_ASM_REG_S $ra, 88($a0) + 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, 0($a0) + GRUB_ASM_REG_L $s1, 8($a0) + GRUB_ASM_REG_L $s2, 16($a0) + GRUB_ASM_REG_L $s3, 24($a0) + GRUB_ASM_REG_L $s4, 32($a0) + GRUB_ASM_REG_L $s5, 40($a0) + GRUB_ASM_REG_L $s6, 48($a0) + GRUB_ASM_REG_L $s7, 56($a0) + GRUB_ASM_REG_L $s8, 64($a0) + GRUB_ASM_REG_L $gp, 72($a0) + GRUB_ASM_REG_L $sp, 80($a0) + GRUB_ASM_REG_L $ra, 88($a0) + addiu $v0, $zero, 1 + movn $v0, $a1, $a1 + move $v1, $zero + jr $ra + nop diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index f6e4905e2..8799fa133 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -5,7 +5,11 @@ #elif defined(__sparc__) #include "./sparc64/setjmp.S" #elif defined(__mips__) +#if _MIPS_SIM == _ABI64 +#include "./mips64/setjmp.S" +#else #include "./mips/setjmp.S" +#endif #elif defined(__powerpc__) || defined(__PPC__) #include "./powerpc/setjmp.S" #elif defined(__ia64__) diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index db80b3ba0..3b2e01c93 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -22,7 +22,7 @@ #include <grub/dl.h> #include <grub/misc.h> #include <grub/terminfo.h> -#if !defined (GRUB_MACHINE_EMU) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) +#if !defined (GRUB_MACHINE_EMU) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) #include <grub/cpu/io.h> #endif #include <grub/extcmd.h> @@ -151,7 +151,7 @@ grub_serial_find (const char *name) if (grub_strcmp (port->name, name) == 0) break; -#if (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) +#if ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 && grub_isxdigit (name [sizeof ("port") - 1])) { @@ -286,7 +286,7 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) err = port->driver->configure (port, &config); if (err) return err; -#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) /* Compatibility kludge. */ if (port->driver == &grub_ns8250_driver) @@ -436,7 +436,7 @@ GRUB_MOD_INIT(serial) &grub_serial_terminfo_input_template, sizeof (grub_serial_terminfo_input)); -#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) grub_ns8250_init (); #endif #ifdef GRUB_MACHINE_IEEE1275 diff --git a/include/grub/cache.h b/include/grub/cache.h index fc669dfd1..93583ea15 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -34,7 +34,7 @@ void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); #endif #ifndef GRUB_MACHINE_EMU -#ifdef _mips +#if defined(__mips__) && (_MIPS_SIM != _ABI64) void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len); #else diff --git a/include/grub/dl.h b/include/grub/dl.h index 2bca56ce0..89216b175 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -187,7 +187,7 @@ struct grub_dl void *tramp; void *trampptr; #endif -#ifdef __mips__ +#if defined(__mips__) && (_MIPS_SIM != _ABI64) grub_uint32_t *reginfo; #endif void *base; @@ -252,7 +252,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, Elf_Shdr *s, grub_dl_segment_t seg); #endif -#if defined (_mips) +#if defined (__mips__) && (_MIPS_SIM != _ABI64) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); #endif @@ -279,12 +279,12 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #endif -#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) +#if defined (__powerpc__) || (defined (__mips__) && (_MIPS_SIM != _ABI64)) || defined (__arm__) #define GRUB_ARCH_DL_TRAMP_ALIGN 4 #define GRUB_ARCH_DL_GOT_ALIGN 4 #endif -#if defined (__aarch64__) || defined (__sparc__) +#if defined (__aarch64__) || defined (__sparc__) || (defined (__mips__) && (_MIPS_SIM == _ABI64)) #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 c7c9f0e1d..cb4848323 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -1686,7 +1686,7 @@ struct grub_efi_block_io typedef struct grub_efi_block_io grub_efi_block_io_t; #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) + || defined (__aarch64__) || defined(__mips__) || defined (__MINGW64__) || defined (__CYGWIN__) #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 f79c36c02..a2bff174e 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -64,6 +64,7 @@ struct grub_pe32_coff_header }; #define GRUB_PE32_MACHINE_I386 0x14c +#define GRUB_PE32_MACHINE_MIPS 0x166 #define GRUB_PE32_MACHINE_IA64 0x200 #define GRUB_PE32_MACHINE_X86_64 0x8664 #define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 @@ -278,6 +279,10 @@ struct grub_pe32_fixup_block #define GRUB_PE32_REL_BASED_HIGHLOW 3 #define GRUB_PE32_REL_BASED_HIGHADJ 4 #define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5 +#define GRUB_PE32_REL_BASED_MIPS_LOW 6 +#define GRUB_PE32_REL_BASED_MIPS_HIGH 4 +#define GRUB_PE32_REL_BASED_MIPS_HIGHER 7 +#define GRUB_PE32_REL_BASED_MIPS_HIGHEST 8 #define GRUB_PE32_REL_BASED_ARM_MOV32A 5 #define GRUB_PE32_REL_BASED_SECTION 6 #define GRUB_PE32_REL_BASED_REL 7 diff --git a/include/grub/mips64/asm.h b/include/grub/mips64/asm.h new file mode 100644 index 000000000..062bdf5e9 --- /dev/null +++ b/include/grub/mips64/asm.h @@ -0,0 +1,10 @@ +#ifndef GRUB_MIPS64_ASM_HEADER +#define GRUB_MIPS64_ASM_HEADER 1 + +#define GRUB_ASM_T4 $a4 +#define GRUB_ASM_T5 $a5 +#define GRUB_ASM_SZREG 8 +#define GRUB_ASM_REG_S sd +#define GRUB_ASM_REG_L ld + +#endif diff --git a/include/grub/mips64/efi/boot.h b/include/grub/mips64/efi/boot.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mips64/efi/loader.h b/include/grub/mips64/efi/loader.h new file mode 100644 index 000000000..71a015977 --- /dev/null +++ b/include/grub/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include <grub/types.h> +#include <grub/symbol.h> + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/mips64/efi/memory.h b/include/grub/mips64/efi/memory.h new file mode 100644 index 000000000..52e6ae6eb --- /dev/null +++ b/include/grub/mips64/efi/memory.h @@ -0,0 +1,6 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include <grub/efi/memory.h> + +#define GRUB_EFI_MAX_USABLE_ADDRESS 0x980000000fffffffUL + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/mips64/efi/time.h b/include/grub/mips64/efi/time.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mips64/io.h b/include/grub/mips64/io.h new file mode 100644 index 000000000..5f341037a --- /dev/null +++ b/include/grub/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_IO_H +#define GRUB_IO_H 1 + +#include <grub/types.h> + +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/mips64/kernel.h b/include/grub/mips64/kernel.h new file mode 100644 index 000000000..909d5397d --- /dev/null +++ b/include/grub/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#include <grub/symbol.h> + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips64/memory.h b/include/grub/mips64/memory.h new file mode 100644 index 000000000..573a70f79 --- /dev/null +++ b/include/grub/mips64/memory.h @@ -0,0 +1,56 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 + +#ifndef ASM_FILE +#include <grub/symbol.h> +#include <grub/err.h> +#include <grub/types.h> +#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) +{ + if ((a + size) < 0x20000000UL) + return (void *) (a | 0xffffffff80000000UL); + return (void *) (a | 0x9800000000000000UL); +} + +static inline void +grub_unmap_memory (void *a __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + +#endif + +#endif diff --git a/include/grub/mips64/mips.h b/include/grub/mips64/mips.h new file mode 100644 index 000000000..a13c709e0 --- /dev/null +++ b/include/grub/mips64/mips.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 <http://www.gnu.org/licenses/>. + */ + +#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_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) + +#endif diff --git a/include/grub/mips64/setjmp.h b/include/grub/mips64/setjmp.h new file mode 100644 index 000000000..d9a0776b6 --- /dev/null +++ b/include/grub/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#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/mips64/time.h b/include/grub/mips64/time.h new file mode 100644 index 000000000..c9a733488 --- /dev/null +++ b/include/grub/mips64/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 <http://www.gnu.org/licenses/>. + */ + +#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/mips64/types.h b/include/grub/mips64/types.h new file mode 100644 index 000000000..fc896c83b --- /dev/null +++ b/include/grub/mips64/types.h @@ -0,0 +1,38 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +#ifdef GRUB_CPU_MIPS64EL +/* mips64EL is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN +#elif defined (GRUB_CPU_MIPS64) +/* mips64 is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN +#elif !defined (GRUB_SYMBOL_GENERATOR) +#error Neither GRUB_CPU_MIPS64 nor GRUB_CPU_MIPS64EL is defined +#endif + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h index 2a9f87cc2..2ba97b493 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -410,7 +410,7 @@ void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); /* Halt the system, using APM if possible. If NO_APM is true, don't * use APM even if it is available. */ void grub_halt (int no_apm) __attribute__ ((noreturn)); -#elif defined (__mips__) && !defined (GRUB_MACHINE_EMU) +#elif (defined (__mips__) && (_MIPS_SIM != _ABI64)) && !defined (GRUB_MACHINE_EMU) void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); #else void grub_halt (void) __attribute__ ((noreturn)); diff --git a/include/grub/serial.h b/include/grub/serial.h index 67379de45..f8cc4612b 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -21,7 +21,7 @@ #define GRUB_SERIAL_HEADER 1 #include <grub/types.h> -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) #include <grub/cpu/io.h> #endif #include <grub/usb.h> @@ -86,7 +86,7 @@ struct grub_serial_port */ union { -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) grub_port_t port; #endif struct @@ -175,7 +175,7 @@ grub_serial_config_defaults (struct grub_serial_port *port) return port->driver->configure (port, &config); } -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) void grub_ns8250_init (void); char *grub_serial_ns8250_add_port (grub_port_t port); #endif diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 5ca4811cd..a14ed5a85 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -99,6 +99,7 @@ enum grub_install_plat GRUB_INSTALL_PLATFORM_I386_XEN, GRUB_INSTALL_PLATFORM_X86_64_XEN, GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_MIPS64_EFI, GRUB_INSTALL_PLATFORM_MAX }; diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 452b230da..5c8aa00d2 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -665,6 +665,7 @@ static struct [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, + [GRUB_INSTALL_PLATFORM_MIPS64_EFI] = { "mips64", "efi" }, [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, }; diff --git a/util/grub-install.c b/util/grub-install.c index 6c89c2b0c..462b81f43 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -313,7 +313,11 @@ get_default_platform (void) #elif defined (__sparc__) || defined (__sparc64__) return "sparc64-ieee1275"; #elif defined (__MIPSEL__) +#if _MIPS_SIM == _ABI64 + return "mips64-efi"; +#else return "mipsel-loongson"; +#endif #elif defined (__MIPSEB__) return "mips-arc"; #elif defined (__ia64__) @@ -477,6 +481,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_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: @@ -898,6 +903,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: @@ -941,6 +947,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: @@ -992,6 +999,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: is_efi = 1; break; @@ -1105,6 +1113,9 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM64_EFI: efi_file = "BOOTAA64.EFI"; break; + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: + efi_file = "BOOTMIPS64.EFI"; + break; default: grub_util_error ("%s", _("You've found a bug")); break; @@ -1132,6 +1143,9 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM64_EFI: efi_file = "grubaa64.efi"; break; + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: + efi_file = "grubmips64.efi"; + break; default: efi_file = "grub.efi"; break; @@ -1434,6 +1448,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: g = grub_util_guess_efi_drive (*curdev); break; @@ -1524,6 +1539,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: core_name = "core.efi"; snprintf (mkimage_target, sizeof (mkimage_target), @@ -1625,6 +1641,7 @@ main (int argc, char *argv[]) break; case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: @@ -1853,6 +1870,7 @@ main (int argc, char *argv[]) } case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: { char *dst = grub_util_path_concat (2, efidir, efi_file); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index f8faae878..f70e98241 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -769,7 +769,11 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, offset = grub_target_to_host (r->r_offset); target = SUFFIX (get_target_address) (e, target_section, offset, image_target); - info = grub_target_to_host (r->r_info); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, ELF_R_SYM (info), image_target); @@ -1051,6 +1055,66 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, } break; } + case EM_MIPS: + { + sym_addr += addend; + switch (ELF_R_TYPE (info)) + { + case R_MIPS_NONE: + break; + case R_MIPS_64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr); + } + break; + case R_MIPS_32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + sym_addr); + } + break; + case R_MIPS_26: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t32 = ((*t32) & 0xfc000000U) | ((addr >> 2) & 0x3ffffffUL); + } + break; + case R_MIPS_LO16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) addr; + } + break; + case R_MIPS_HI16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x8000UL) >> 16); + } + break; + case R_MIPS_HIGHER: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x80008000UL) >> 32); + } + break; + case R_MIPS_HIGHEST: + { + grub_uint16_t *t16 = (grub_uint16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_uint16_t) ((addr + 0x800080008000UL) >> 48); + } + 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: @@ -1176,7 +1240,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, /* First, check if it is necessary to write out the current block. */ if ((*cblock)->state) { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + if (flush || (type && (addr < b->page_rva || b->page_rva + 0x1000 <= addr))) { grub_uint32_t size; @@ -1239,7 +1303,8 @@ 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)); + if (type) + b->page_rva = (addr & ~(0x1000 - 1)); b->block_size = sizeof (*b); } @@ -1249,7 +1314,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, /* Add a new entry. */ cur_index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); b->entries[cur_index] = grub_host_to_target16 (entry); b->block_size += 2; } @@ -1295,6 +1360,8 @@ static void translate_relocation_pe (struct translate_context *ctx, Elf_Addr addr, Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, const struct grub_install_image_target_desc *image_target) { /* Necessary to relocate only absolute addresses. */ @@ -1405,7 +1472,162 @@ translate_relocation_pe (struct translate_context *ctx, break; } break; +#if defined(MKIMAGE_ELF64) + case EM_MIPS: + switch (ELF_R_TYPE (info)) + { + case R_MIPS_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_32: +#if 0 + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } +#endif + break; + case R_MIPS_26: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_JMPADDR, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_LO16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_LOW, + addr, 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HI16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGH, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHER: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHER, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHEST: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHEST, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + } + 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: switch (ELF_R_TYPE (info)) @@ -1494,10 +1716,12 @@ static void translate_relocation (struct translate_context *ctx, Elf_Addr addr, Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, const struct grub_install_image_target_desc *image_target) { if (image_target->id == IMAGE_EFI) - translate_relocation_pe (ctx, addr, info, image_target); + translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target); else translate_relocation_raw (ctx, addr, info, image_target); } @@ -1640,12 +1864,17 @@ 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)) { - Elf_Rel *r; + Elf_Rela *r; Elf_Word rtab_size, r_size, num_rs; Elf_Off rtab_offset; + Elf_Shdr *symtab_section; Elf_Addr section_address; Elf_Word j; + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + grub_util_info ("translating the relocation section %s", strtab + grub_le_to_cpu32 (s->sh_name)); @@ -1656,20 +1885,30 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) + j++, r = (Elf_Rela *) ((char *) r + r_size)) { Elf_Addr info; Elf_Addr offset; Elf_Addr addr; + Elf_Addr sym_addr; + Elf_Addr addend; offset = grub_target_to_host (r->r_offset); - info = grub_target_to_host (r->r_info); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); + 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; addr = section_address + offset; - translate_relocation (&ctx, addr, info, image_target); + translate_relocation (&ctx, addr, info, sym_addr, addend, image_target); } } diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c index 82073d5cc..d3c92ea06 100644 --- a/util/grub-mknetdir.c +++ b/util/grub-mknetdir.c @@ -107,7 +107,8 @@ static const 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_MIPS64_EFI] = { "mips64-efi", "efinet", ".efi" } }; static void diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 238d4840e..f64391788 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -530,6 +530,7 @@ main (int argc, char *argv[]) || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) system_area = SYS_AREA_COMMON; else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) @@ -727,7 +728,8 @@ main (int argc, char *argv[]) || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] - || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI]) + || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64_EFI]) { char *efidir = grub_util_make_temporary_dir (); char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); @@ -762,6 +764,11 @@ main (int argc, char *argv[]) imgname); free (imgname); + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootmips64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_MIPS64_EFI, "mips64-efi", + imgname); + free (imgname); + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) { imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c index d0cf8176f..6b07631d6 100644 --- a/util/grub-module-verifier.c +++ b/util/grub-module-verifier.c @@ -118,6 +118,19 @@ struct grub_module_verifier_arch archs[] = { -1 } }, + { "mips64el", 8, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_64, + R_MIPS_32, + R_MIPS_26, + R_MIPS_LO16, + R_MIPS_HI16, + R_MIPS_HIGHER, + R_MIPS_HIGHEST, + -1 + }, (int[]){ + -1 + } + }, }; struct platform_whitelist { diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c index 1feaafc9b..0b0446e98 100644 --- a/util/grub-module-verifierXX.c +++ b/util/grub-module-verifierXX.c @@ -296,7 +296,14 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e if (target_seg_size < grub_target_to_host (rel->r_offset)) grub_util_error ("reloc offset is out of the segment"); - grub_uint32_t type = ELF_R_TYPE (grub_target_to_host (rel->r_info)); + grub_size_t r_info; + if (arch->machine == EM_MIPS && arch->voidp_sizeof == 8) + r_info = ((grub_uint64_t) rel->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (rel->r_info); + else + r_info = grub_target_to_host (rel->r_info); + + grub_uint32_t type = ELF_R_TYPE (r_info); if (arch->machine == EM_SPARCV9) type &= 0xff; @@ -313,7 +320,7 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e break; if (arch->short_relocations[i] == -1) grub_util_error ("unsupported relocation 0x%x", type); - sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (grub_target_to_host (rel->r_info))); + sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (r_info)); if (is_symbol_local (sym)) continue; diff --git a/util/mkimage.c b/util/mkimage.c index 9ad4cfe42..c80e1722e 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -570,6 +570,22 @@ static const struct grub_install_image_target_desc image_targets[] = .pe_target = GRUB_PE32_MACHINE_ARM64, .elf_target = EM_AARCH64, }, + { + .dirname = "mips64-efi", + .names = { "mips64-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_MIPS, + .elf_target = EM_MIPS, + }, }; #include <grub/lib/LzmaEnc.h> -- 2.11.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel