From 3c9c791df40b4980cfa6f5d1ed6f0192b8a8ac5b Mon Sep 17 00:00:00 2001 From: sunway_fw Date: Mon, 16 Jun 2025 14:06:28 +0800 Subject: [PATCH] Add support for arch SW64 Signed-off-by: sunway_fw --- 0001-Add-support-for-SW64.patch | 1835 +++++++++++++++++++++++++++++++ BOOTSW64.CSV | Bin 0 -> 124 bytes shim.spec | 19 +- 3 files changed, 1852 insertions(+), 2 deletions(-) create mode 100755 0001-Add-support-for-SW64.patch create mode 100755 BOOTSW64.CSV diff --git a/0001-Add-support-for-SW64.patch b/0001-Add-support-for-SW64.patch new file mode 100755 index 0000000..d6ea0f6 --- /dev/null +++ b/0001-Add-support-for-SW64.patch @@ -0,0 +1,1835 @@ +From 811ba94a76118f8bcb1edef00a2fa4be64796d60 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 8 May 2025 15:44:10 +0800 +Subject: [PATCH] Add support for SW64 + +Signed-off-by: root +--- + Cryptlib/Include/OpenSslSupport.h | 2 +- + Cryptlib/Makefile | 5 + + Cryptlib/OpenSSL/Makefile | 4 + + Make.defaults | 7 + + elf_sw_64_efi.lds | 102 +++++++++++++++ + gnu-efi/Make.defaults | 7 +- + gnu-efi/gnuefi/crt0-efi-sw_64.S | 75 +++++++++++ + gnu-efi/gnuefi/reloc_sw_64.c | 79 ++++++++++++ + gnu-efi/inc/efi.h | 2 + + gnu-efi/inc/efilib.h | 2 + + gnu-efi/inc/elf.h | 4 + + gnu-efi/inc/sw_64/efibind.h | 153 ++++++++++++++++++++++ + gnu-efi/inc/sw_64/efilibplat.h | 20 +++ + gnu-efi/inc/sw_64/efisetjmp_arch.h | 26 ++++ + gnu-efi/lib/Makefile | 5 + + gnu-efi/lib/sw_64/Divide.S | 196 ++++++++++++++++++++++++++++ + gnu-efi/lib/sw_64/Dividew.S | 197 +++++++++++++++++++++++++++++ + gnu-efi/lib/sw_64/Rem.S | 195 ++++++++++++++++++++++++++++ + gnu-efi/lib/sw_64/Remw.S | 195 ++++++++++++++++++++++++++++ + gnu-efi/lib/sw_64/efi_stub.S | 2 + + gnu-efi/lib/sw_64/initplat.c | 25 ++++ + gnu-efi/lib/sw_64/math.c | 63 +++++++++ + gnu-efi/lib/sw_64/setjmp.S | 99 +++++++++++++++ + include/asm.h | 7 + + include/peimage.h | 1 + + include/system/stdarg.h | 2 +- + include/test.h | 2 + + lib/Makefile | 4 + + pe.c | 4 + + shim.h | 15 +++ + 30 files changed, 1497 insertions(+), 3 deletions(-) + create mode 100644 elf_sw_64_efi.lds + create mode 100644 gnu-efi/gnuefi/crt0-efi-sw_64.S + create mode 100644 gnu-efi/gnuefi/reloc_sw_64.c + create mode 100644 gnu-efi/inc/sw_64/efibind.h + create mode 100644 gnu-efi/inc/sw_64/efilibplat.h + create mode 100644 gnu-efi/inc/sw_64/efisetjmp_arch.h + create mode 100644 gnu-efi/lib/sw_64/Divide.S + create mode 100644 gnu-efi/lib/sw_64/Dividew.S + create mode 100644 gnu-efi/lib/sw_64/Rem.S + create mode 100644 gnu-efi/lib/sw_64/Remw.S + create mode 100644 gnu-efi/lib/sw_64/efi_stub.S + create mode 100644 gnu-efi/lib/sw_64/initplat.c + create mode 100644 gnu-efi/lib/sw_64/math.c + create mode 100644 gnu-efi/lib/sw_64/setjmp.S + +diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h +index 0c2fb8b..f179088 100644 +--- a/Cryptlib/Include/OpenSslSupport.h ++++ b/Cryptlib/Include/OpenSslSupport.h +@@ -61,7 +61,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + #define CONFIG_HEADER_BN_H + +-#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) ++#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) || defined(MDE_CPU_SW64) + // + // With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs + // SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is +diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile +index c95a960..7750806 100644 +--- a/Cryptlib/Makefile ++++ b/Cryptlib/Makefile +@@ -37,6 +37,11 @@ ifeq ($(ARCH),arm) + DEFINES += -DMDE_CPU_ARM + endif + ++ifeq ($(ARCH),sw_64) ++FEATUREFLAGS += -mgprel-size=32 ++DEFINES += -DMDE_CPU_SW64 ++endif ++ + LDFLAGS = -nostdlib -znocombreloc + + TARGET = libcryptlib.a +diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile +index 4923ac3..7311285 100644 +--- a/Cryptlib/OpenSSL/Makefile ++++ b/Cryptlib/OpenSSL/Makefile +@@ -49,6 +49,10 @@ endif + ifeq ($(ARCH),arm) + DEFINES += -DMDE_CPU_ARM + endif ++ifeq ($(ARCH),sw_64) ++FEATUREFLAGS += -mgprel-size=32 ++DEFINES += -DMDE_CPU_SW64 ++endif + + LDFLAGS = -nostdlib -znocombreloc + +diff --git a/Make.defaults b/Make.defaults +index c46164a..4d71722 100644 +--- a/Make.defaults ++++ b/Make.defaults +@@ -96,6 +96,13 @@ ifeq ($(ARCH),arm) + SUBSYSTEM := 0xa + ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM) + endif ++ifeq ($(ARCH),sw_64) ++ ARCH_CFLAGS ?= -DPAGE_SIZE=4096 -mgprel-size=32 -DMDE_CPU_SW64 ++ ARCH_GNUEFI ?= sw_64 ++ ARCH_SUFFIX ?= sw64 ++ ARCH_SUFFIX_UPPER ?= SW64 ++ ARCH_LDFLAGS ?= ++endif + + DEFINES = -DDEFAULT_LOADER='L"$(DEFAULT_LOADER)"' \ + -DDEFAULT_LOADER_CHAR='"$(DEFAULT_LOADER)"' +diff --git a/elf_sw_64_efi.lds b/elf_sw_64_efi.lds +new file mode 100644 +index 0000000..a978f3e +--- /dev/null ++++ b/elf_sw_64_efi.lds +@@ -0,0 +1,102 @@ ++OUTPUT_FORMAT("elf64-sw_64") ++OUTPUT_ARCH(sw_64) ++ENTRY(_start) ++SECTIONS ++{ ++ ImageBase = .; ++ .hash : { *(.hash) } ++ . = ALIGN(4096); ++ .eh_frame : ++ { ++ *(.eh_frame) ++ } ++ ++ .text : ++ { ++ _text = .; ++ *(.text.head) ++ *(.text) ++ *(.text.*) ++ *(.gnu.linkonce.t.*) ++ _etext = .; ++ } ++ . = ALIGN(4096); ++ .reloc : ++ { ++ *(.reloc) ++ } ++ . = ALIGN(4096); ++ .note.gnu.build-id : { ++ *(.note.gnu.build-id) ++ } ++ ++ . = ALIGN(4096); ++ .data.ident : { ++ *(.data.ident) ++ } ++ . = ALIGN(4096); ++ .sbatlevel : { ++ *(.sbatlevel) ++ } ++ ++ . = ALIGN(4096); ++ .data : ++ { ++ _data = .; ++ *(.rodata*) ++ *(.got.plt) ++ *(.got) ++ *(.data*) ++ *(.sdata) ++ ++ /* the EFI loader doesn't seem to like a .bss section, so we stick ++ it all into .data: */ ++ *(.sbss) ++ *(.scommon) ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ *(.rel.local) ++ } ++ .sbat : ++ { ++ _sbat = .; ++ *(.sbat) ++ *(.sbat.*) ++ _esbat = .; ++ . = ALIGN(4096); ++ _epsbat = .; ++ } ++ ++ . = ALIGN(4096); ++ .vendor_cert : ++ { ++ *(.vendor_cert) ++ } ++ . = ALIGN(4096); ++ .dynamic : { *(.dynamic) } ++ . = ALIGN(4096); ++ .rela : ++ { ++ *(.rela.sdata) ++ *(.rela.data*) ++ *(.rela.got*) ++ *(.rela.stab*) ++ } ++ _edata = .; ++ _data_size = . - _data; ++ ++ . = ALIGN(4096); ++ .dynsym : { *(.dynsym) } ++ . = ALIGN(4096); ++ .dynstr : { *(.dynstr) } ++ . = ALIGN(4096); ++ .ignored.reloc : ++ { ++ *(.rela.reloc) ++ *(.eh_frame) ++ *(.note.GNU-stack) ++ } ++ .comment 0 : { *(.comment) } ++ .note.gnu.build-id : { *(.note.gnu.build-id) } ++} +diff --git a/gnu-efi/Make.defaults b/gnu-efi/Make.defaults +index 3b56150..45d5a13 100755 +--- a/gnu-efi/Make.defaults ++++ b/gnu-efi/Make.defaults +@@ -36,7 +36,7 @@ + + TOPDIR ?= $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) + +-ARCHES = ia32 x86_64 ia64 aarch64 arm mips64el ++ARCHES = ia32 x86_64 ia64 aarch64 arm mips64el sw_64 + + # + # Variables below overridable from command-line: +@@ -103,6 +103,11 @@ CPPFLAGS += -DCONFIG_$(ARCH) + + CFLAGS += -Wno-error=pragmas + ++ifeq ($(ARCH),sw_64) ++ CFLAGS += -mgprel-size=32 ++ LDFLAGS += --no-warn-rwx-segments ++endif ++ + ifeq ($(ARCH),ia64) + CFLAGS += -mfixed-range=f32-f127 + endif +diff --git a/gnu-efi/gnuefi/crt0-efi-sw_64.S b/gnu-efi/gnuefi/crt0-efi-sw_64.S +new file mode 100644 +index 0000000..edf0d1e +--- /dev/null ++++ b/gnu-efi/gnuefi/crt0-efi-sw_64.S +@@ -0,0 +1,75 @@ ++/* ++ * crt0-efi-sw_64.S - PE/COFF header for SW64 EFI applications ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License as published by the Free Software Foundation; ++ * either version 2 of the License, or (at your option) any later version. ++ */ ++ .globl _start ++ .ent _start ++ .type _start, @function ++_start: ++ br $27, 2f ++2: ldgp $29, 0($27) ++ ++ ldi $8, _start + 4 ++ subl $27, $8, $2 ++ subl $31, 1, $1 ++ sll $1, 52, $1 ++ ldi $sp, -64($sp) ++ stl $26, 0($sp) ++ // save gp & ImageBase ++ stl $29, 8($sp) ++ stl $2, 16($sp) //save ImageBase ++ ++ br 1f ++1: ++ ++ stl $16, 24($sp) //$16=ImageHandle ++ stl $17, 32($sp) //$17=SystemTable ++ ++ // a2: ImageHandle ++ mov $16, $18 ++ // a3: SystemTable ++ mov $17, $19 ++ // a0: ImageBase ++ ++ mov $2, $16 //$2=ImageBase ++ // a1: DynamicSection ++ ldi $17, _DYNAMIC ++ addl $17, $2, $17 //relocate _DYNAMIC ++ nop ++ nop ++ ldi $20, _relocate ++ addl $20, $2, $20 //relocate _relocate ++ call ($20) ++ ++ // a0: ImageHandle ++ ldl $16, 24($sp) ++ // a1: SystemTable ++ ldl $17, 32($sp) ++ call efi_main ++ nop ++ nop ++ nop ++ ++3: ++ ldl $29, 8($sp) ++ ldl $26, 0($sp) ++ jmp $31, ($26) ++ ldi $sp, 64($sp) ++ .end _start ++ ++ // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: ++ .data ++.dummy0: ++.dummy1: ++ .4byte 0 ++ ++#define IMAGE_REL_ABSOLUTE 0 ++ .section .reloc, "a" ++ .4byte .dummy1-.dummy0 // Page RVA ++ .4byte 10 // Block Size (2*4+2) ++ .2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy ++ .section .note.GNU-stack,"a" ++ +diff --git a/gnu-efi/gnuefi/reloc_sw_64.c b/gnu-efi/gnuefi/reloc_sw_64.c +new file mode 100644 +index 0000000..fa6b7cb +--- /dev/null ++++ b/gnu-efi/gnuefi/reloc_sw_64.c +@@ -0,0 +1,79 @@ ++/* reloc_sw_64.c - position independent SW64 ELF shared object relocator ++ ++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ++ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, ++ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS ++ BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ++ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR ++ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF ++ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++*/ ++ ++#include ++#include ++ ++#include ++#include "../../include/console.h" ++ ++EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, ++ EFI_HANDLE image EFI_UNUSED, ++ EFI_SYSTEM_TABLE *systab EFI_UNUSED) ++{ ++ long relsz = 0, relent = 0; ++ Elf64_Rela *rel = 0; ++ unsigned long *addr; ++ int i; ++ ++ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { ++ switch (dyn[i].d_tag) { ++ case DT_RELA: ++ rel = (Elf64_Rela*) ++ ((unsigned long)dyn[i].d_un.d_ptr ++ + ldbase); ++ break; ++ ++ case DT_RELASZ: ++ relsz = dyn[i].d_un.d_val; ++ break; ++ ++ case DT_RELAENT: ++ relent = dyn[i].d_un.d_val; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ if (!rel && relent == 0) ++ return EFI_SUCCESS; ++ ++ if (!rel || relent == 0) ++ return EFI_LOAD_ERROR; ++ ++ while (relsz > 0) { ++ /* apply the relocs */ ++ switch (ELF64_R_TYPE (rel->r_info)) { ++ case R_SW_64_NONE: ++ case R_SW_64_REFQUAD: ++ case R_SW_64_RELATIVE: ++ addr = (unsigned long *) ++ (ldbase + rel->r_offset); ++ *addr += ldbase; ++ break; ++ ++ default: ++ break; ++ } ++ ++ rel = (Elf64_Rela*) ((char *) rel + relent); ++ relsz -= relent; ++ } ++ return EFI_SUCCESS; ++} +diff --git a/gnu-efi/inc/efi.h b/gnu-efi/inc/efi.h +index bd99451..82d11a7 100644 +--- a/gnu-efi/inc/efi.h ++++ b/gnu-efi/inc/efi.h +@@ -50,6 +50,8 @@ Revision History + #include "arm/efibind.h" + #elif defined (_M_MIPS64) || defined(__mips64__) + #include "mips64el/efibind.h" ++#elif defined(__sw_64__) ++#include "sw_64/efibind.h" + #else + #error Usupported architecture + #endif +diff --git a/gnu-efi/inc/efilib.h b/gnu-efi/inc/efilib.h +index af47019..7b16344 100644 +--- a/gnu-efi/inc/efilib.h ++++ b/gnu-efi/inc/efilib.h +@@ -33,6 +33,8 @@ Revision History + #include "arm/efilibplat.h" + #elif defined (_M_MIPS64) || defined(__mips64__) + #include "mips64el/efilibplat.h" ++#elif defined (__sw_64__) ++#include "sw_64/efilibplat.h" + #endif + #include "efilink.h" + #include "efirtlib.h" +diff --git a/gnu-efi/inc/elf.h b/gnu-efi/inc/elf.h +index 7682e9f..f6e8095 100644 +--- a/gnu-efi/inc/elf.h ++++ b/gnu-efi/inc/elf.h +@@ -3949,4 +3949,8 @@ enum { + #define R_NDS32_TLS_TPOFF 102 + #define R_NDS32_TLS_DESC 119 + ++#define R_SW_64_NONE 0 ++#define R_SW_64_REFQUAD 2 ++#define R_SW_64_RELATIVE 27 ++ + #endif /* elf.h */ +diff --git a/gnu-efi/inc/sw_64/efibind.h b/gnu-efi/inc/sw_64/efibind.h +new file mode 100644 +index 0000000..3176265 +--- /dev/null ++++ b/gnu-efi/inc/sw_64/efibind.h +@@ -0,0 +1,153 @@ ++/* ++ * Copright (C) 2014 - 2015 Linaro Ltd. ++ * Author: Ard Biesheuvel ++ * Copright (C) 2017 Lemote Co. ++ * Author: Heiher ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice and this list of conditions, without modification. ++ * 2. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License as published by the Free Software Foundation; ++ * either version 2 of the License, or (at your option) any later version. ++ */ ++ ++#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) ++ ++// ANSI C 1999/2000 stdint.h integer width declarations ++ ++typedef unsigned long uint64_t; ++typedef long int64_t; ++typedef unsigned int uint32_t; ++typedef int int32_t; ++typedef unsigned short uint16_t; ++typedef short int16_t; ++typedef unsigned char uint8_t; ++typedef signed char int8_t; // unqualified 'char' is unsigned on ARM ++typedef uint64_t uintptr_t; ++typedef int64_t intptr_t; ++ ++#else ++#include ++#endif ++ ++// ++// Basic EFI types of various widths ++// ++ ++typedef uint64_t UINT64; ++typedef int64_t INT64; ++ ++typedef uint32_t UINT32; ++typedef int32_t INT32; ++ ++typedef uint16_t UINT16; ++typedef uint16_t CHAR16; ++typedef int16_t INT16; ++ ++typedef uint8_t UINT8; ++typedef char CHAR8; ++typedef int8_t INT8; ++ ++#undef VOID ++#define VOID void ++ ++typedef int64_t INTN; ++typedef uint64_t UINTN; ++ ++#define EFIERR(a) (0x8000000000000000 | a) ++#define EFI_ERROR_MASK 0x8000000000000000 ++#define EFIERR_OEM(a) (0xc000000000000000 | a) ++ ++#define BAD_POINTER 0xFBFBFBFBFBFBFBFB ++#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF ++ ++#define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 ++ ++// ++// Pointers must be aligned to these address to function ++// ++ ++#define MIN_ALIGNMENT_SIZE 8 ++ ++#define ALIGN_VARIABLE(Value ,Adjustment) \ ++ (UINTN)Adjustment = 0; \ ++ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ ++ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ ++ Value = (UINTN)Value + (UINTN)Adjustment ++ ++ ++// ++// Define macros to build data structure signatures from characters. ++// ++ ++#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) ++#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) ++#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) ++ ++// ++// EFIAPI - prototype calling convention for EFI function pointers ++// BOOTSERVICE - prototype for implementation of a boot service interface ++// RUNTIMESERVICE - prototype for implementation of a runtime service interface ++// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service ++// RUNTIME_CODE - pragma macro for declaring runtime code ++// ++ ++#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options ++#define EFIAPI // Substitute expresion to force C calling convention ++#endif ++ ++#define BOOTSERVICE ++#define RUNTIMESERVICE ++#define RUNTIMEFUNCTION ++ ++ ++#define RUNTIME_CODE(a) alloc_text("rtcode", a) ++#define BEGIN_RUNTIME_DATA() data_seg("rtdata") ++#define END_RUNTIME_DATA() data_seg("") ++ ++#define VOLATILE volatile ++ ++#define MEMORY_FENCE __sync_synchronize ++ ++// ++// When build similiar to FW, then link everything together as ++// one big module. ++// ++ ++#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ ++ UINTN \ ++ InitializeDriver ( \ ++ VOID *ImageHandle, \ ++ VOID *SystemTable \ ++ ) \ ++ { \ ++ return InitFunction(ImageHandle, \ ++ SystemTable); \ ++ } \ ++ \ ++ EFI_STATUS efi_main( \ ++ EFI_HANDLE image, \ ++ EFI_SYSTEM_TABLE *systab \ ++ ) __attribute__((weak, \ ++ alias ("InitializeDriver"))); ++ ++#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ ++ (_if)->LoadInternal(type, name, entry) ++ ++ ++// ++// Some compilers don't support the forward reference construct: ++// typedef struct XXXXX ++// ++// The following macro provide a workaround for such cases. ++ ++#define INTERFACE_DECL(x) struct x ++ ++#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) ++#define EFI_FUNCTION +diff --git a/gnu-efi/inc/sw_64/efilibplat.h b/gnu-efi/inc/sw_64/efilibplat.h +new file mode 100644 +index 0000000..907c43c +--- /dev/null ++++ b/gnu-efi/inc/sw_64/efilibplat.h +@@ -0,0 +1,20 @@ ++/*++ ++ ++Module Name: ++ ++ efilibplat.h ++ ++Abstract: ++ ++ EFI to compile bindings ++ ++Revision History ++ ++--*/ ++ ++VOID ++InitializeLibPlatform ( ++ IN EFI_HANDLE ImageHandle, ++ IN EFI_SYSTEM_TABLE *SystemTable ++ ); ++ +diff --git a/gnu-efi/inc/sw_64/efisetjmp_arch.h b/gnu-efi/inc/sw_64/efisetjmp_arch.h +new file mode 100644 +index 0000000..a93487f +--- /dev/null ++++ b/gnu-efi/inc/sw_64/efisetjmp_arch.h +@@ -0,0 +1,26 @@ ++#ifndef GNU_EFI_SW64_SETJMP_H ++#define GNU_EFI_SW64_SETJMP_H ++ ++#define JMPBUF_ALIGN 8 ++ ++typedef struct { ++ UINT64 S0; ++ UINT64 S1; ++ UINT64 S2; ++ UINT64 S3; ++ UINT64 S4; ++ UINT64 S5; ++ UINT64 RA; ++ UINT64 FP; ++ UINT64 SP; ++ UINT64 F2; ++ UINT64 F3; ++ UINT64 F4; ++ UINT64 F5; ++ UINT64 F6; ++ UINT64 F7; ++ UINT64 F8; ++ UINT64 F9; ++} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; ++ ++#endif /* GNU_EFI_SW64_SETJMP_H */ +diff --git a/gnu-efi/lib/Makefile b/gnu-efi/lib/Makefile +index 4890b87..d89f30f 100644 +--- a/gnu-efi/lib/Makefile ++++ b/gnu-efi/lib/Makefile +@@ -63,6 +63,11 @@ FILES += $(ARCH)/uldiv $(ARCH)/ldivmod $(ARCH)/div $(ARCH)/llsl $(ARCH)/llsr \ + $(ARCH)/mullu + endif + ++ifeq ($(ARCH),sw_64) ++FILES += $(ARCH)/Divide $(ARCH)/Dividew $(ARCH)/Rem \ ++ $(ARCH)/Remw ++endif ++ + OBJS = $(FILES:%=%.o) + + SUBDIRS = $(ARCHES) runtime +diff --git a/gnu-efi/lib/sw_64/Divide.S b/gnu-efi/lib/sw_64/Divide.S +new file mode 100644 +index 0000000..fe9db49 +--- /dev/null ++++ b/gnu-efi/lib/sw_64/Divide.S +@@ -0,0 +1,196 @@ ++/* ++ * arch/sw64/lib/divide.S ++ * ++ * (C) 1995 Linus Torvalds ++ * ++ * SW64 division.. ++ */ ++ ++/* ++ * The sw64 chip doesn't provide hardware division, so we have to do it ++ * by hand. The compiler expects the functions ++ * ++ * __divqu: 64-bit unsigned long divide ++ * __remqu: 64-bit unsigned long remainder ++ * __divqs/__remqs: signed 64-bit ++ * __divlu/__remlu: unsigned 32-bit ++ * __divls/__remls: signed 32-bit ++ * ++ * These are not normal C functions: instead of the normal ++ * calling sequence, these expect their arguments in registers ++ * $24 and $25, and return the result in $27. Register $28 may ++ * be clobbered (assemembly temporary), anything else must be saved. ++ * ++ * In short: painful. ++ * ++ * This is a rather simple bit-at-a-time algorithm: it's very good ++ * at dividing random 64-bit numembers, but the more usual case where ++ * the divisor is small is handled better by the DEC algorithm ++ * using lookup tables. This uses much less memory, though, and is ++ * nicer on the cache.. Besides, I don't know the copyright status ++ * of the DEC code. ++ */ ++ ++/* ++ * My temporaries: ++ * $0 - current bit ++ * $1 - shifted divisor ++ * $2 - modulus/quotient ++ * ++ * $23 - return address ++ * $24 - dividend ++ * $25 - divisor ++ * ++ * $27 - quotient/modulus ++ * $28 - compare status ++ */ ++ ++#define halt .long 0 ++#define DIV 1 ++ ++/* ++ * Select function type and registers ++ */ ++#define mask $0 ++#define divisor $1 ++#define compare $28 ++#define tmp1 $3 ++#define tmp2 $4 ++ ++#ifdef DIV ++#define DIV_ONLY(x,y...) x,##y ++#define MOD_ONLY(x,y...) ++#define func(x) __div##x ++#define modulus $2 ++#define quotient $27 ++#define GETSIGN(x) xor $24,$25,x ++#define STACK 48 ++#else ++#define DIV_ONLY(x,y...) ++#define MOD_ONLY(x,y...) x,##y ++#define func(x) __rem##x ++#define modulus $27 ++#define quotient $2 ++#define GETSIGN(x) bis $24,$24,x ++#define STACK 32 ++#endif ++ ++/* ++ * For 32-bit operations, we need to extend to 64-bit ++ */ ++#ifdef INTSIZE ++#define ufunction func(wu) ++#define sfunction func(w) ++#define LONGIFY(x) zapnot x,15,x ++#define SLONGIFY(x) addw x,0,x ++#else ++#define ufunction func(lu) ++#define sfunction func(l) ++#define LONGIFY(x) ++#define SLONGIFY(x) ++#endif ++ ++.set noat ++.align 3 ++.globl ufunction ++.ent ufunction ++ufunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ ++7: stl $1, 0($30) ++ bis $25,$25,divisor ++ stl $2, 8($30) ++ bis $24,$24,modulus ++ stl $0,16($30) ++ bis $31,$31,quotient ++ LONGIFY(divisor) ++ stl tmp1,24($30) ++ LONGIFY(modulus) ++ bis $31,1,mask ++ DIV_ONLY(stl tmp2,32($30)) ++ beq divisor, 9f /* div by zero */ ++ ++#ifdef INTSIZE ++ /* ++ * shift divisor left, using 3-bit shifts for ++ * 32-bit divides as we can't overflow. Three-bit ++ * shifts will result in looping three times less ++ * here, but can result in two loops more later. ++ * Thus using a large shift isn't worth it (and ++ * s8add pairs better than a sll..) ++ */ ++1: cmpult divisor,modulus,compare ++ s8addl divisor,$31,divisor ++ s8addl mask,$31,mask ++ bne compare,1b ++#else ++1: cmpult divisor,modulus,compare ++ blt divisor, 2f ++ addl divisor,divisor,divisor ++ addl mask,mask,mask ++ bne compare,1b ++ nop ++#endif ++ ++ /* ok, start to go right again.. */ ++2: DIV_ONLY(addl quotient,mask,tmp2) ++ srl mask,1,mask ++ cmpule divisor,modulus,compare ++ subl modulus,divisor,tmp1 ++ DIV_ONLY(selne compare,tmp2,quotient,quotient) ++ srl divisor,1,divisor ++ selne compare,tmp1,modulus,modulus ++ bne mask,2b ++ ++9: ldl $1, 0($30) ++ ldl $2, 8($30) ++ ldl $0,16($30) ++ ldl tmp1,24($30) ++ DIV_ONLY(ldl tmp2,32($30)) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end ufunction ++ ++/* ++ * Uhh.. Ugly signed division. I'd rather not have it at all, but ++ * it's needed in some circumstances. There are different ways to ++ * handle this, really. This does: ++ * -a / b = a / -b = -(a / b) ++ * -a % b = -(a % b) ++ * a % -b = a % b ++ * which is probably not the best solution, but at least should ++ * have the property that (x/y)*y + (x%y) = x. ++ */ ++.align 3 ++.globl sfunction ++.ent sfunction ++sfunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ bis $24,$25,$28 ++ SLONGIFY($28) ++ bge $28,7b ++ stl $24,0($30) ++ subl $31,$24,$28 ++ stl $25,8($30) ++ sellt $24,$28,$24,$24 /* abs($24) */ ++ stl $23,16($30) ++ subl $31,$25,$28 ++ stl tmp1,24($30) ++ sellt $25,$28,$25,$25 /* abs($25) */ ++ nop ++ bsr $23,ufunction ++ ldl $24,0($30) ++ ldl $25,8($30) ++ GETSIGN($28) ++ subl $31,$27,tmp1 ++ SLONGIFY($28) ++ ldl $23,16($30) ++ sellt $28,tmp1,$27,$27 ++ ldl tmp1,24($30) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end sfunction +diff --git a/gnu-efi/lib/sw_64/Dividew.S b/gnu-efi/lib/sw_64/Dividew.S +new file mode 100644 +index 0000000..876e2ae +--- /dev/null ++++ b/gnu-efi/lib/sw_64/Dividew.S +@@ -0,0 +1,197 @@ ++/* ++ * arch/sw64/lib/divide.S ++ * ++ * (C) 1995 Linus Torvalds ++ * ++ * SW64 division.. ++ */ ++ ++/* ++ * The sw64 chip doesn't provide hardware division, so we have to do iti ++ * by hand. The compiler expects the functions ++ * ++ * __divqu: 64-bit unsigned long divide ++ * __remqu: 64-bit unsigned long remainder ++ * __divqs/__remqs: signed 64-bit ++ * __divlu/__remlu: unsigned 32-bit ++ * __divls/__remls: signed 32-bit ++ * ++ * These are not normal C functions: instead of the normal ++ * calling sequence, these expect their arguments in registers ++ * $24 and $25, and return the result in $27. Register $28 may ++ * be clobbered (assemembly temporary), anything else must be saved. ++ * ++ * In short: painful. ++ * ++ * This is a rather simple bit-at-a-time algorithm: it's very good ++ * at dividing random 64-bit numembers, but the more usual case where ++ * the divisor is small is handled better by the DEC algorithm ++ * using lookup tables. This uses much less memory, though, and is ++ * nicer on the cache.. Besides, I don't know the copyright status ++ * of the DEC code. ++ */ ++ ++/* ++ * My temporaries: ++ * $0 - current bit ++ * $1 - shifted divisor ++ * $2 - modulus/quotient ++ * ++ * $23 - return address ++ * $24 - dividend ++ * $25 - divisor ++ * ++ * $27 - quotient/modulus ++ * $28 - compare status ++ */ ++ ++#define halt .long 0 ++#define DIV 1 ++#define INTSIZE ++ ++/* ++ * Select function type and registers ++ */ ++#define mask $0 ++#define divisor $1 ++#define compare $28 ++#define tmp1 $3 ++#define tmp2 $4 ++ ++#ifdef DIV ++#define DIV_ONLY(x,y...) x,##y ++#define MOD_ONLY(x,y...) ++#define func(x) __div##x ++#define modulus $2 ++#define quotient $27 ++#define GETSIGN(x) xor $24,$25,x ++#define STACK 48 ++#else ++#define DIV_ONLY(x,y...) ++#define MOD_ONLY(x,y...) x,##y ++#define func(x) __rem##x ++#define modulus $27 ++#define quotient $2 ++#define GETSIGN(x) bis $24,$24,x ++#define STACK 32 ++#endif ++ ++/* ++ * For 32-bit operations, we need to extend to 64-bit ++ */ ++#ifdef INTSIZE ++#define ufunction func(wu) ++#define sfunction func(w) ++#define LONGIFY(x) zapnot x,15,x ++#define SLONGIFY(x) addw x,0,x ++#else ++#define ufunction func(lu) ++#define sfunction func(l) ++#define LONGIFY(x) ++#define SLONGIFY(x) ++#endif ++ ++.set noat ++.align 3 ++.globl ufunction ++.ent ufunction ++ufunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ ++7: stl $1, 0($30) ++ bis $25,$25,divisor ++ stl $2, 8($30) ++ bis $24,$24,modulus ++ stl $0,16($30) ++ bis $31,$31,quotient ++ LONGIFY(divisor) ++ stl tmp1,24($30) ++ LONGIFY(modulus) ++ bis $31,1,mask ++ DIV_ONLY(stl tmp2,32($30)) ++ beq divisor, 9f /* div by zero */ ++ ++#ifdef INTSIZE ++ /* ++ * shift divisor left, using 3-bit shifts for ++ * 32-bit divides as we can't overflow. Three-bit ++ * shifts will result in looping three times less ++ * here, but can result in two loops more later. ++ * Thus using a large shift isn't worth it (and ++ * s8add pairs better than a sll..) ++ */ ++1: cmpult divisor,modulus,compare ++ s8addl divisor,$31,divisor ++ s8addl mask,$31,mask ++ bne compare,1b ++#else ++1: cmpult divisor,modulus,compare ++ blt divisor, 2f ++ addl divisor,divisor,divisor ++ addl mask,mask,mask ++ bne compare,1b ++ nop ++#endif ++ ++ /* ok, start to go right again.. */ ++2: DIV_ONLY(addl quotient,mask,tmp2) ++ srl mask,1,mask ++ cmpule divisor,modulus,compare ++ subl modulus,divisor,tmp1 ++ DIV_ONLY(selne compare,tmp2,quotient,quotient) ++ srl divisor,1,divisor ++ selne compare,tmp1,modulus,modulus ++ bne mask,2b ++ ++9: ldl $1, 0($30) ++ ldl $2, 8($30) ++ ldl $0,16($30) ++ ldl tmp1,24($30) ++ DIV_ONLY(ldl tmp2,32($30)) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end ufunction ++ ++/* ++ * Uhh.. Ugly signed division. I'd rather not have it at all, but ++ * it's needed in some circumstances. There are different ways to ++ * handle this, really. This does: ++ * -a / b = a / -b = -(a / b) ++ * -a % b = -(a % b) ++ * a % -b = a % b ++ * which is probably not the best solution, but at least should ++ * have the property that (x/y)*y + (x%y) = x. ++ */ ++.align 3 ++.globl sfunction ++.ent sfunction ++sfunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ bis $24,$25,$28 ++ SLONGIFY($28) ++ bge $28,7b ++ stl $24,0($30) ++ subl $31,$24,$28 ++ stl $25,8($30) ++ sellt $24,$28,$24,$24 /* abs($24) */ ++ stl $23,16($30) ++ subl $31,$25,$28 ++ stl tmp1,24($30) ++ sellt $25,$28,$25,$25 /* abs($25) */ ++ nop ++ bsr $23,ufunction ++ ldl $24,0($30) ++ ldl $25,8($30) ++ GETSIGN($28) ++ subl $31,$27,tmp1 ++ SLONGIFY($28) ++ ldl $23,16($30) ++ sellt $28,tmp1,$27,$27 ++ ldl tmp1,24($30) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end sfunction +diff --git a/gnu-efi/lib/sw_64/Rem.S b/gnu-efi/lib/sw_64/Rem.S +new file mode 100644 +index 0000000..37df6da +--- /dev/null ++++ b/gnu-efi/lib/sw_64/Rem.S +@@ -0,0 +1,195 @@ ++/* ++ * arch/sw64/lib/divide.S ++ * ++ * (C) 1995 Linus Torvalds ++ * ++ * SW64 division.. ++ */ ++ ++/* ++ * The sw64 chip doesn't provide hardware division, so we have to do it ++ * by hand. The compiler expects the functions ++ * ++ * __divqu: 64-bit unsigned long divide ++ * __remqu: 64-bit unsigned long remainder ++ * __divqs/__remqs: signed 64-bit ++ * __divlu/__remlu: unsigned 32-bit ++ * __divls/__remls: signed 32-bit ++ * ++ * These are not normal C functions: instead of the normal ++ * calling sequence, these expect their arguments in registers ++ * $24 and $25, and return the result in $27. Register $28 may ++ * be clobbered (assemembly temporary), anything else must be saved. ++ * ++ * In short: painful. ++ * ++ * This is a rather simple bit-at-a-time algorithm: it's very good ++ * at dividing random 64-bit numembers, but the more usual case where ++ * the divisor is small is handled better by the DEC algorithm ++ * using lookup tables. This uses much less memory, though, and is ++ * nicer on the cache.. Besides, I don't know the copyright status ++ * of the DEC code. ++ */ ++ ++/* ++ * My temporaries: ++ * $0 - current bit ++ * $1 - shifted divisor ++ * $2 - modulus/quotient ++ * ++ * $23 - return address ++ * $24 - dividend ++ * $25 - divisor ++ * ++ * $27 - quotient/modulus ++ * $28 - compare status ++ */ ++ ++#define halt .long 0 ++ ++/* ++ * Select function type and registers ++ */ ++#define mask $0 ++#define divisor $1 ++#define compare $28 ++#define tmp1 $3 ++#define tmp2 $4 ++ ++#ifdef DIV ++#define DIV_ONLY(x,y...) x,##y ++#define MOD_ONLY(x,y...) ++#define func(x) __div##x ++#define modulus $2 ++#define quotient $27 ++#define GETSIGN(x) xor $24,$25,x ++#define STACK 48 ++#else ++#define DIV_ONLY(x,y...) ++#define MOD_ONLY(x,y...) x,##y ++#define func(x) __rem##x ++#define modulus $27 ++#define quotient $2 ++#define GETSIGN(x) bis $24,$24,x ++#define STACK 32 ++#endif ++ ++/* ++ * For 32-bit operations, we need to extend to 64-bit ++ */ ++#ifdef INTSIZE ++#define ufunction func(wu) ++#define sfunction func(w) ++#define LONGIFY(x) zapnot x,15,x ++#define SLONGIFY(x) addw x,0,x ++#else ++#define ufunction func(lu) ++#define sfunction func(l) ++#define LONGIFY(x) ++#define SLONGIFY(x) ++#endif ++ ++.set noat ++.align 3 ++.globl ufunction ++.ent ufunction ++ufunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ ++7: stl $1, 0($30) ++ bis $25,$25,divisor ++ stl $2, 8($30) ++ bis $24,$24,modulus ++ stl $0,16($30) ++ bis $31,$31,quotient ++ LONGIFY(divisor) ++ stl tmp1,24($30) ++ LONGIFY(modulus) ++ bis $31,1,mask ++ DIV_ONLY(stl tmp2,32($30)) ++ beq divisor, 9f /* div by zero */ ++ ++#ifdef INTSIZE ++ /* ++ * shift divisor left, using 3-bit shifts for ++ * 32-bit divides as we can't overflow. Three-bit ++ * shifts will result in looping three times less ++ * here, but can result in two loops more later. ++ * Thus using a large shift isn't worth it (and ++ * s8add pairs better than a sll..) ++ */ ++1: cmpult divisor,modulus,compare ++ s8addl divisor,$31,divisor ++ s8addl mask,$31,mask ++ bne compare,1b ++#else ++1: cmpult divisor,modulus,compare ++ blt divisor, 2f ++ addl divisor,divisor,divisor ++ addl mask,mask,mask ++ bne compare,1b ++ nop ++#endif ++ ++ /* ok, start to go right again.. */ ++2: DIV_ONLY(addl quotient,mask,tmp2) ++ srl mask,1,mask ++ cmpule divisor,modulus,compare ++ subl modulus,divisor,tmp1 ++ DIV_ONLY(selne compare,tmp2,quotient,quotient) ++ srl divisor,1,divisor ++ selne compare,tmp1,modulus,modulus ++ bne mask,2b ++ ++9: ldl $1, 0($30) ++ ldl $2, 8($30) ++ ldl $0,16($30) ++ ldl tmp1,24($30) ++ DIV_ONLY(ldl tmp2,32($30)) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end ufunction ++ ++/* ++ * Uhh.. Ugly signed division. I'd rather not have it at all, but ++ * it's needed in some circumstances. There are different ways to ++ * handle this, really. This does: ++ * -a / b = a / -b = -(a / b) ++ * -a % b = -(a % b) ++ * a % -b = a % b ++ * which is probably not the best solution, but at least should ++ * have the property that (x/y)*y + (x%y) = x. ++ */ ++.align 3 ++.globl sfunction ++.ent sfunction ++sfunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ bis $24,$25,$28 ++ SLONGIFY($28) ++ bge $28,7b ++ stl $24,0($30) ++ subl $31,$24,$28 ++ stl $25,8($30) ++ sellt $24,$28,$24,$24 /* abs($24) */ ++ stl $23,16($30) ++ subl $31,$25,$28 ++ stl tmp1,24($30) ++ sellt $25,$28,$25,$25 /* abs($25) */ ++ nop ++ bsr $23,ufunction ++ ldl $24,0($30) ++ ldl $25,8($30) ++ GETSIGN($28) ++ subl $31,$27,tmp1 ++ SLONGIFY($28) ++ ldl $23,16($30) ++ sellt $28,tmp1,$27,$27 ++ ldl tmp1,24($30) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end sfunction +diff --git a/gnu-efi/lib/sw_64/Remw.S b/gnu-efi/lib/sw_64/Remw.S +new file mode 100644 +index 0000000..c56f459 +--- /dev/null ++++ b/gnu-efi/lib/sw_64/Remw.S +@@ -0,0 +1,195 @@ ++/* ++ * arch/sw64/lib/divide.S ++ * ++ * (C) 1995 Linus Torvalds ++ * ++ * SW64 division.. ++ */ ++ ++/* ++ * The sw64 chip doesn't provide hardware division, so we have to do it ++ * by hand. The compiler expects the functions ++ * ++ * __divqu: 64-bit unsigned long divide ++ * __remqu: 64-bit unsigned long remainder ++ * __divqs/__remqs: signed 64-bit ++ * __divlu/__remlu: unsigned 32-bit ++ * __divls/__remls: signed 32-bit ++ * ++ * These are not normal C functions: instead of the normal ++ * calling sequence, these expect their arguments in registers ++ * $24 and $25, and return the result in $27. Register $28 may ++ * be clobbered (assemembly temporary), anything else must be saved. ++ * ++ * In short: painful. ++ * ++ * This is a rather simple bit-at-a-time algorithm: it's very good ++ * at dividing random 64-bit numembers, but the more usual case where ++ * the divisor is small is handled better by the DEC algorithm ++ * using lookup tables. This uses much less memory, though, and is ++ * nicer on the cache.. Besides, I don't know the copyright status ++ * of the DEC code. ++ */ ++ ++/* ++ * My temporaries: ++ * $0 - current bit ++ * $1 - shifted divisor ++ * $2 - modulus/quotient ++ * ++ * $23 - return address ++ * $24 - dividend ++ * $25 - divisor ++ * ++ * $27 - quotient/modulus ++ * $28 - compare status ++ */ ++ ++#define halt .long 0 ++#define INTSIZE ++/* ++ * Select function type and registers ++ */ ++#define mask $0 ++#define divisor $1 ++#define compare $28 ++#define tmp1 $3 ++#define tmp2 $4 ++ ++#ifdef DIV ++#define DIV_ONLY(x,y...) x,##y ++#define MOD_ONLY(x,y...) ++#define func(x) __div##x ++#define modulus $2 ++#define quotient $27 ++#define GETSIGN(x) xor $24,$25,x ++#define STACK 48 ++#else ++#define DIV_ONLY(x,y...) ++#define MOD_ONLY(x,y...) x,##y ++#define func(x) __rem##x ++#define modulus $27 ++#define quotient $2 ++#define GETSIGN(x) bis $24,$24,x ++#define STACK 32 ++#endif ++ ++/* ++ * For 32-bit operations, we need to extend to 64-bit ++ */ ++#ifdef INTSIZE ++#define ufunction func(wu) ++#define sfunction func(w) ++#define LONGIFY(x) zapnot x,15,x ++#define SLONGIFY(x) addw x,0,x ++#else ++#define ufunction func(lu) ++#define sfunction func(l) ++#define LONGIFY(x) ++#define SLONGIFY(x) ++#endif ++ ++.set noat ++.align 3 ++.globl ufunction ++.ent ufunction ++ufunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ ++7: stl $1, 0($30) ++ bis $25,$25,divisor ++ stl $2, 8($30) ++ bis $24,$24,modulus ++ stl $0,16($30) ++ bis $31,$31,quotient ++ LONGIFY(divisor) ++ stl tmp1,24($30) ++ LONGIFY(modulus) ++ bis $31,1,mask ++ DIV_ONLY(stl tmp2,32($30)) ++ beq divisor, 9f /* div by zero */ ++ ++#ifdef INTSIZE ++ /* ++ * shift divisor left, using 3-bit shifts for ++ * 32-bit divides as we can't overflow. Three-bit ++ * shifts will result in looping three times less ++ * here, but can result in two loops more later. ++ * Thus using a large shift isn't worth it (and ++ * s8add pairs better than a sll..) ++ */ ++1: cmpult divisor,modulus,compare ++ s8addl divisor,$31,divisor ++ s8addl mask,$31,mask ++ bne compare,1b ++#else ++1: cmpult divisor,modulus,compare ++ blt divisor, 2f ++ addl divisor,divisor,divisor ++ addl mask,mask,mask ++ bne compare,1b ++ nop ++#endif ++ ++ /* ok, start to go right again.. */ ++2: DIV_ONLY(addl quotient,mask,tmp2) ++ srl mask,1,mask ++ cmpule divisor,modulus,compare ++ subl modulus,divisor,tmp1 ++ DIV_ONLY(selne compare,tmp2,quotient,quotient) ++ srl divisor,1,divisor ++ selne compare,tmp1,modulus,modulus ++ bne mask,2b ++ ++9: ldl $1, 0($30) ++ ldl $2, 8($30) ++ ldl $0,16($30) ++ ldl tmp1,24($30) ++ DIV_ONLY(ldl tmp2,32($30)) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end ufunction ++ ++/* ++ * Uhh.. Ugly signed division. I'd rather not have it at all, but ++ * it's needed in some circumstances. There are different ways to ++ * handle this, really. This does: ++ * -a / b = a / -b = -(a / b) ++ * -a % b = -(a % b) ++ * a % -b = a % b ++ * which is probably not the best solution, but at least should ++ * have the property that (x/y)*y + (x%y) = x. ++ */ ++.align 3 ++.globl sfunction ++.ent sfunction ++sfunction: ++ subl $30,STACK,$30 ++ .frame $30,STACK,$23 ++ .prologue 0 ++ bis $24,$25,$28 ++ SLONGIFY($28) ++ bge $28,7b ++ stl $24,0($30) ++ subl $31,$24,$28 ++ stl $25,8($30) ++ sellt $24,$28,$24,$24 /* abs($24) */ ++ stl $23,16($30) ++ subl $31,$25,$28 ++ stl tmp1,24($30) ++ sellt $25,$28,$25,$25 /* abs($25) */ ++ nop ++ bsr $23,ufunction ++ ldl $24,0($30) ++ ldl $25,8($30) ++ GETSIGN($28) ++ subl $31,$27,tmp1 ++ SLONGIFY($28) ++ ldl $23,16($30) ++ sellt $28,tmp1,$27,$27 ++ ldl tmp1,24($30) ++ addl $30,STACK,$30 ++ ret $31,($23),1 ++ .end sfunction +diff --git a/gnu-efi/lib/sw_64/efi_stub.S b/gnu-efi/lib/sw_64/efi_stub.S +new file mode 100644 +index 0000000..fa951c9 +--- /dev/null ++++ b/gnu-efi/lib/sw_64/efi_stub.S +@@ -0,0 +1,2 @@ ++/* This stub is a stub to make the build happy */ ++ .section .note.GNU-stack,"a" +diff --git a/gnu-efi/lib/sw_64/initplat.c b/gnu-efi/lib/sw_64/initplat.c +new file mode 100644 +index 0000000..d27c948 +--- /dev/null ++++ b/gnu-efi/lib/sw_64/initplat.c +@@ -0,0 +1,25 @@ ++/*++ ++ ++Module Name: ++ ++ initplat.c ++ ++Abstract: ++ ++ ++ ++ ++Revision History ++ ++--*/ ++ ++#include "lib.h" ++ ++VOID ++InitializeLibPlatform ( ++ IN EFI_HANDLE ImageHandle EFI_UNUSED, ++ IN EFI_SYSTEM_TABLE *SystemTable EFI_UNUSED ++ ) ++{ ++} ++ +diff --git a/gnu-efi/lib/sw_64/math.c b/gnu-efi/lib/sw_64/math.c +new file mode 100644 +index 0000000..8c16444 +--- /dev/null ++++ b/gnu-efi/lib/sw_64/math.c +@@ -0,0 +1,63 @@ ++/* ++ * Copright (C) 2014 Linaro Ltd. ++ * Author: Ard Biesheuvel ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice and this list of conditions, without modification. ++ * 2. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License as published by the Free Software Foundation; ++ * either version 2 of the License, or (at your option) any later version. ++ */ ++ ++#include "lib.h" ++ ++UINT64 ++LShiftU64 ( ++ IN UINT64 Operand, ++ IN UINTN Count ++ ) ++// Left shift 64bit by 32bit and get a 64bit result ++{ ++ return Operand << Count; ++} ++ ++UINT64 ++RShiftU64 ( ++ IN UINT64 Operand, ++ IN UINTN Count ++ ) ++// Right shift 64bit by 32bit and get a 64bit result ++{ ++ return Operand >> Count; ++} ++ ++ ++UINT64 ++MultU64x32 ( ++ IN UINT64 Multiplicand, ++ IN UINTN Multiplier ++ ) ++// Multiple 64bit by 32bit and get a 64bit result ++{ ++ return Multiplicand * Multiplier; ++} ++ ++UINT64 ++DivU64x32 ( ++ IN UINT64 Dividend, ++ IN UINTN Divisor, ++ OUT UINTN *Remainder OPTIONAL ++ ) ++// divide 64bit by 32bit and get a 64bit result ++// N.B. only works for 31bit divisors!! ++{ ++ if (Remainder) ++ *Remainder = Dividend % Divisor; ++ return Dividend / Divisor; ++} +diff --git a/gnu-efi/lib/sw_64/setjmp.S b/gnu-efi/lib/sw_64/setjmp.S +new file mode 100644 +index 0000000..046040c +--- /dev/null ++++ b/gnu-efi/lib/sw_64/setjmp.S +@@ -0,0 +1,99 @@ ++#define FRAME 0 ++ ++#define v0 $0 ++ ++#define t0 $1 ++ ++#define a0 $16 ++#define a1 $17 ++#define s0 $9 /* saved-registers (callee-saved registers) */ ++#define s1 $10 ++#define s2 $11 ++#define s3 $12 ++#define s4 $13 ++#define s5 $14 ++ ++#define ra $26 ++#define sp $30 ++#define fp $15 ++ ++#define zero $31 ++ ++/// ++/// Private macros for accessing __jmp_buf contents. sw_64 version. ++/// ++#define JB_S0 0 ++#define JB_S1 1 ++#define JB_S2 2 ++#define JB_S3 3 ++#define JB_S4 4 ++#define JB_S5 5 ++#define JB_PC 6 ++#define JB_FP 7 ++#define JB_SP 8 ++#define JB_F2 9 ++#define JB_F3 10 ++#define JB_F4 11 ++#define JB_F5 12 ++#define JB_F6 13 ++#define JB_F7 14 ++#define JB_F8 15 ++#define JB_F9 16 ++ ++#define LEAF(x) \ ++ .align 3; \ ++ .globl x; \ ++ .ent x, 0; \ ++x: ; \ ++ .frame sp, 0, ra; \ ++ ++#define END(x) \ ++ .end x ++ ++LEAF(setjmp) ++ stl s0, JB_S0*8(a0) ++ stl s1, JB_S1*8(a0) ++ stl s2, JB_S2*8(a0) ++ stl s3, JB_S3*8(a0) ++ stl s4, JB_S4*8(a0) ++ stl s5, JB_S5*8(a0) ++ stl ra, JB_PC*8(a0) ++ stl fp, JB_FP*8(a0) ++ stl sp, JB_SP*8(a0) ++ ++ fstd $f2, JB_F2*8(a0) ++ fstd $f3, JB_F3*8(a0) ++ fstd $f4, JB_F4*8(a0) ++ fstd $f5, JB_F5*8(a0) ++ fstd $f6, JB_F6*8(a0) ++ fstd $f7, JB_F7*8(a0) ++ fstd $f8, JB_F8*8(a0) ++ fstd $f9, JB_F9*8(a0) ++ bis zero, zero, v0 ++ jmp zero, (ra) ++END(setjmp) ++ ++LEAF(longjmp) ++ mov a1, v0 ++ ldl s0, JB_S0*8(a0) ++ ldl s1, JB_S1*8(a0) ++ ldl s2, JB_S2*8(a0) ++ ldl s3, JB_S3*8(a0) ++ ldl s4, JB_S4*8(a0) ++ ldl s5, JB_S5*8(a0) ++ ldl ra, JB_PC*8(a0) ++ ldl fp, JB_FP*8(a0) ++ ldl t0, JB_SP*8(a0) ++ ++ fldd $f2, JB_F2*8(a0) ++ fldd $f3, JB_F3*8(a0) ++ fldd $f4, JB_F4*8(a0) ++ fldd $f5, JB_F5*8(a0) ++ fldd $f6, JB_F6*8(a0) ++ fldd $f7, JB_F7*8(a0) ++ fldd $f8, JB_F8*8(a0) ++ fldd $f9, JB_F9*8(a0) ++ seleq v0, 1, v0, v0 ++ mov t0, sp ++ ret ++END(longjmp) +diff --git a/include/asm.h b/include/asm.h +index 03b0655..0b118c7 100644 +--- a/include/asm.h ++++ b/include/asm.h +@@ -19,6 +19,8 @@ static inline uint64_t read_counter(void) + __asm__ __volatile__ ("mrs %0, pmccntr_el0" : "=r" (val)); + #elif defined(__arm__) + __asm__ __volatile__ ("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); ++#elif defined(__sw_64__) ++ __asm__ __volatile__("rtc %0": "=r"(val)); + #else + #error unsupported arch + #endif +@@ -35,6 +37,11 @@ static inline void wait_for_debug(void) + { + __asm__ __volatile__("wfi"); + } ++#elif defined(__sw_64__) ++static inline void wait_for_debug(void) ++{ ++ __asm__ __volatile__("halt"); ++} + #else + static inline void wait_for_debug(void) + { +diff --git a/include/peimage.h b/include/peimage.h +index 7a4f356..18f0d1d 100644 +--- a/include/peimage.h ++++ b/include/peimage.h +@@ -47,6 +47,7 @@ + #define IMAGE_FILE_MACHINE_X64 0x8664 + #define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2 + #define IMAGE_FILE_MACHINE_ARM64 0xaa64 ++#define IMAGE_FILE_MACHINE_SW64 0x0284 + + // + // EXE file formats +diff --git a/include/system/stdarg.h b/include/system/stdarg.h +index 68c171b..8b5b700 100644 +--- a/include/system/stdarg.h ++++ b/include/system/stdarg.h +@@ -24,7 +24,7 @@ typedef __builtin_va_list __builtin_sysv_va_list; + #endif + + #if defined(__aarch64__) || defined(__arm__) || defined(__i386__) || \ +- defined(__i486__) || defined(__i686__) || defined(__COVERITY__) ++ defined(__i486__) || defined(__i686__) || defined(__sw_64__) || defined(__COVERITY__) + + typedef __builtin_va_list ms_va_list; + typedef __builtin_va_list __builtin_ms_va_list; +diff --git a/include/test.h b/include/test.h +index 5261dbd..f92c7c4 100644 +--- a/include/test.h ++++ b/include/test.h +@@ -25,6 +25,8 @@ + #include + #elif defined(__x86_64__) + #include ++#elif defined(__sw_64__) ++#include + #else + #error what arch is this + #endif +diff --git a/lib/Makefile b/lib/Makefile +index f81c5c9..b388ad0 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -30,6 +30,10 @@ endif + ifeq ($(ARCH),arm) + DEFINES += -DMDE_CPU_ARM + endif ++ifeq ($(ARCH),sw_64) ++FEATUREFLAGS += -nostdinc -mgprel-size=32 ++DEFINES += -DMDE_CPU_SW64 ++endif + + LDFLAGS = -nostdlib -znocombreloc + +diff --git a/pe.c b/pe.c +index a61425d..2da96ea 100644 +--- a/pe.c ++++ b/pe.c +@@ -676,6 +676,8 @@ allow_64_bit(void) + if (in_protocol) + return 1; + return 0; ++#elif defined(__sw_64__) ++ return 1; + #else /* assuming everything else is 32-bit... */ + return 0; + #endif +@@ -722,6 +724,8 @@ static const UINT16 machine_type = + IMAGE_FILE_MACHINE_I386; + #elif defined(__ia64__) + IMAGE_FILE_MACHINE_IA64; ++#elif defined(__sw_64__) ++ IMAGE_FILE_MACHINE_SW64; + #else + #error this architecture is not supported by shim + #endif +diff --git a/shim.h b/shim.h +index bedd5ce..b9f2401 100644 +--- a/shim.h ++++ b/shim.h +@@ -128,6 +128,21 @@ + #endif + #endif + ++#if defined(__sw_64__) ++#ifndef DEFAULT_LOADER ++#define DEFAULT_LOADER L"\\grubsw64.efi" ++#endif ++#ifndef DEFAULT_LOADER_CHAR ++#define DEFAULT_LOADER_CHAR "\\grubsw64.efi" ++#endif ++#ifndef EFI_ARCH ++#define EFI_ARCH L"sw64" ++#endif ++#ifndef DEBUGDIR ++#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/sw64/" ++#endif ++#endif ++ + #ifndef DEBUGSRC + #define DEBUGSRC L"/usr/src/debug/shim-" VERSIONSTR "." EFI_ARCH + #endif +-- +2.33.0 + diff --git a/BOOTSW64.CSV b/BOOTSW64.CSV new file mode 100755 index 0000000000000000000000000000000000000000..6fe8622049a2aaf4da1a77c7192ecf6b70721853 GIT binary patch literal 124 zcmZXM%L#xm5JcbEDpEl3Bz9m2Rv;uO7$ZqUY+fC6^|JHf?L2p8W+9L{>FH>3cr}*D mF26Bwu*xNMma*~~Bj&qB*-0nyQOVSwBKnf|>XP)o)$jsLfEV)s literal 0 HcmV?d00001 diff --git a/shim.spec b/shim.spec index 97dedce..a1bddcd 100644 --- a/shim.spec +++ b/shim.spec @@ -10,6 +10,12 @@ %global bootefi BOOTX64.EFI %endif +%ifarch sw_64 +%global efi_arch sw64 +%global bootcsv BOOTSW64.CSV +%global bootefi BOOTSW64.EFI +%endif + %global debug_package %{nil} %global __debug_package 1 %global _binaries_in_noarch_packages_terminate_build 0 @@ -25,9 +31,9 @@ Name: shim Version: 15.7 -Release: 16 +Release: 17 Summary: First-stage UEFI bootloader -ExclusiveArch: x86_64 aarch64 +ExclusiveArch: x86_64 aarch64 sw_64 License: BSD URL: https://github.com/rhboot/shim Source0: https://github.com/rhboot/shim/releases/download/%{version}/shim-%{version}.tar.bz2 @@ -36,6 +42,7 @@ Source2: BOOTX64.CSV Source3: openEuler_ca.der Source4: shimaa64-cfca.efi Source5: shimx64-cfca.efi +Source6: BOOTSW64.CSV Patch1:backport-CVE-2023-40546.patch Patch2:backport-CVE-2023-40551-pe-relocate-Fix-bounds-check-for-MZ-b.patch @@ -56,6 +63,7 @@ Patch16:backport-Always-clear-SbatLevel-when-Secure-Boot-is-disabled.patch Patch17:backport-Align-section-size-up-to-page-size-for-mem-attrs.patch Patch18:backport-shim-don-t-set-second_stage-to-the-empty-string.patch Patch19:backport-Fix-the-issue-that-the-gBS-LoadImage-pointer-was-emp.patch +Patch20:0001-Add-support-for-SW64.patch # Feature for shim SMx support Patch9000:Feature-shim-openssl-add-ec-support.patch @@ -168,6 +176,10 @@ install -m 0700 %{SOURCE4} ${RPM_BUILD_ROOT}/%{shimBOOT}/BOOTAA64_CFCA.EFI install -m 0700 %{SOURCE2} ${RPM_BUILD_ROOT}/%{shimefivendor} install -m 0700 %{SOURCE5} ${RPM_BUILD_ROOT}/%{shimBOOT}/BOOTX64_CFCA.EFI %endif +%ifarch sw_64 +install -m 0700 %{SOURCE6} ${RPM_BUILD_ROOT}/%{shimefivendor} +%endif + %if "%{_vendor}" != "openEuler" iconv -f UTF-16LE -t UTF-8 ${RPM_BUILD_ROOT}/%{shimefivendor}/%{bootcsv} > /tmp/%{bootcsv}.tmp sed -i -e 's/openeuler/%{_vendor}/g' -e 's/openEuler/%{_vendor}/g' /tmp/%{bootcsv}.tmp @@ -213,6 +225,9 @@ make test /usr/src/debug/%{name}-%{version}-%{release}/* %changelog +* Mon Jun 16 2025 sunway_fw -15.7-17 +- add SW64 arch support + * Mon Jan 20 2025 xuce -15.7-16 - fix the issue that the gBS->LoadImage pointer was empty. -- Gitee