Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LoongArch support #658

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "gnu-efi"]
path = gnu-efi
url = https://github.com/rhboot/gnu-efi.git
branch = shim-15.8
branch = master
2 changes: 1 addition & 1 deletion Cryptlib/Include/OpenSslSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_LOONGARCH64)
//
// 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
Expand Down
3 changes: 3 additions & 0 deletions Cryptlib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ endif
ifeq ($(ARCH),aarch64)
DEFINES += -DMDE_CPU_AARCH64
endif
ifeq ($(ARCH),loongarch64)
DEFINES += -DMDE_CPU_LOONGARCH64
endif
ifeq ($(ARCH),arm)
DEFINES += -DMDE_CPU_ARM
endif
Expand Down
3 changes: 3 additions & 0 deletions Cryptlib/OpenSSL/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ endif
ifeq ($(ARCH),aarch64)
DEFINES += -DMDE_CPU_AARCH64
endif
ifeq ($(ARCH),loongarch64)
DEFINES += -DMDE_CPU_LOONGARCH64
endif
ifeq ($(ARCH),arm)
DEFINES += -DMDE_CPU_ARM
endif
Expand Down
1 change: 1 addition & 0 deletions Cryptlib/OpenSSL/crypto/modes/modes_lcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ typedef unsigned char u8;
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
defined(__aarch64__) || \
defined(__loongarch_lp64) || \
defined(__s390__) || defined(__s390x__)
# undef STRICT_ALIGNMENT
# endif
Expand Down
1 change: 1 addition & 0 deletions Cryptlib/OpenSSL/crypto/sha/sha512.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT;
defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
defined(__s390__) || defined(__s390x__) || \
defined(__aarch64__) || \
defined(__loongarch_lp64) || \
defined(SHA512_ASM)
# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
# endif
Expand Down
8 changes: 8 additions & 0 deletions Make.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ ifeq ($(ARCH),arm)
SUBSYSTEM := 0xa
ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
endif
ifeq ($(ARCH),loongarch64)
ARCH_CFLAGS ?= -DMDE_CPU_LOONGARCH64 -DPAGE_SIZE=4096 -mstrict-align
ARCH_GNUEFI ?= loongarch64
ARCH_SUFFIX ?= loongarch64
ARCH_SUFFIX_UPPER ?= LOONGARCH64
ARCH_LDFLAGS ?=
ARCH_CFLAGS ?=
endif

DEFINES = -DDEFAULT_LOADER='L"$(DEFAULT_LOADER)"' \
-DDEFAULT_LOADER_CHAR='"$(DEFAULT_LOADER)"'
Expand Down
100 changes: 100 additions & 0 deletions elf_loongarch64_efi.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch")
OUTPUT_ARCH(loongarch)
ENTRY(_start)
SECTIONS
{
. = 0;
ImageBase = .;
.hash : { *(.hash) } /* this MUST come first! */
. = ALIGN(4096);
.eh_frame :
{
*(.eh_frame)
}
. = ALIGN(4096);
.text :
{
_text = .;
*(.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)
}

. = ALIGN(4096);
.vendor_cert :
{
*(.vendor_cert)
}
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
.rela :
{
*(.rela.data*)
*(.rela.got*)
*(.rela.stab*)
}
_edata = .;
_data_size = . - _data;
. = ALIGN(4096);
.sbat :
{
_sbat = .;
*(.sbat)
*(.sbat.*)
}
_esbat = .;
_sbat_size = . - _sbat;

. = 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) }
}
2 changes: 1 addition & 1 deletion gnu-efi
Submodule gnu-efi updated 123 files
7 changes: 7 additions & 0 deletions include/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(__loongarch_lp64)
__asm__ __volatile__ ( "rdtime.d %0, $zero" : "=r" (val));
#else
#error unsupported arch
#endif
Expand All @@ -35,6 +37,11 @@ static inline void wait_for_debug(void)
{
__asm__ __volatile__("wfi");
}
#elif defined(__loongarch_lp64)
static inline void wait_for_debug(void)
{
__asm__ __volatile__("idle 0");
}
#else
static inline void wait_for_debug(void)
{
Expand Down
3 changes: 3 additions & 0 deletions include/peimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define IMAGE_FILE_MACHINE_X64 0x8664
#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264

//
// EXE file formats
Expand Down Expand Up @@ -545,6 +546,8 @@ typedef struct {
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
#define EFI_IMAGE_REL_BASED_LOONGARCH32_MARK_LA 8
#define EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA 8
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define EFI_IMAGE_REL_BASED_DIR64 10
Expand Down
4 changes: 3 additions & 1 deletion include/system/stdarg.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ 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(__COVERITY__) || \
defined(__loongarch_lp64)

typedef __builtin_va_list ms_va_list;
typedef __builtin_va_list __builtin_ms_va_list;
Expand All @@ -42,6 +43,7 @@ typedef __builtin_va_list sysv_va_list;
* OpenSSL's X509ConstructCertificateStack needs this.
*/
typedef __builtin_va_list VA_LIST;
typedef __builtin_va_list va_list;
#define VA_COPY(dest, start) __builtin_va_copy(dest, start)
#define VA_START(marker, arg) __builtin_va_start(marker, arg)
#define VA_END(marker) __builtin_va_end(marker)
Expand Down
2 changes: 2 additions & 0 deletions include/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <ia32/efibind.h>
#elif defined(__x86_64__)
#include <x86_64/efibind.h>
#elif defined(__loongarch_lp64)
#include <loongarch64/efibind.h>
#else
#error what arch is this
#endif
Expand Down
3 changes: 3 additions & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ endif
ifeq ($(ARCH),arm)
DEFINES += -DMDE_CPU_ARM
endif
ifeq ($(ARCH),loongarch64)
DEFINES += -DMDE_CPU_LOONGARCH64
endif

LDFLAGS = -nostdlib -znocombreloc

Expand Down
44 changes: 42 additions & 2 deletions pe-relocate.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
int size = context->ImageSize;
void *ImageEnd = (char *)orig + size;
int n = 0;
UINT64 hi12, hi20, low12, low20, value;

/* Alright, so here's how this works:
*
Expand Down Expand Up @@ -142,6 +143,43 @@ relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
*Fixup64 = *Fixup64 + (UINT64) Adjust;
break;

case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
/*
* The 64-bit addresses of the following 4 instructions
* need to be relocated and fixed together.

* lu12i.w: [0000 000] [imm20] [0 0000]
* ori : [0000 0000 00][imm12][00 0000 0000]
* lu32i.d: [0000 000] [imm20] [0 0000]
* lu52i.d: [0000 0000 00][imm12][00 0000 0000]
*/

#define IMM20_MASK 0x1ffffe0 /* 20-bit immediate mask in lu12i.w and lu32i.d */
#define IMM12_MASK 0x3ffc00 /* 12-bit immediate mask in ori and lu52i.d */

low20 = (*(UINT32*)Fixup & IMM20_MASK ) >> 5; /* lu12i.w 20-bits from bit5 */
low12 = (*((UINT32*)Fixup + 1) & IMM12_MASK ) >> 10; /* ori 12-bits from bit10 */
hi20 = (*((UINT32*)Fixup + 2) & IMM20_MASK) >> 5; /* lu32i.d 20-bits from bit5 */
hi12 = (*((UINT32*)Fixup + 3) & IMM12_MASK) >> 10; /* lu52i.d 12-bits from bit10 */

value = (hi12 << 52) | (hi20 << 32) | (low20 << 12) | low12;
value += Adjust;

/* lu12i.w */
*(UINT32*)Fixup = (*(UINT32*)Fixup & ~IMM20_MASK) | ((value >> 12) & 0xfffff) << 5;

/* ori */
Fixup += sizeof(UINT32);
*(UINT32*)Fixup = (*(UINT32*)Fixup & ~IMM12_MASK) | (value & 0xfff) << 10;

/* lu32i.d */
Fixup += sizeof(UINT32);
*(UINT32*)Fixup = (*(UINT32*)Fixup & ~IMM20_MASK) | ((value >> 32) & 0xfffff) << 5;

/* lu52i.d */
Fixup += sizeof(UINT32);
*(UINT32*)Fixup = (*(UINT32*)Fixup & ~IMM12_MASK) | ((value >> 52) & 0xfff) << 10;
break;
default:
perror(L"Reloc %d Unknown relocation\n", n);
return EFI_UNSUPPORTED;
Expand Down Expand Up @@ -272,7 +310,7 @@ get_section_vma_by_name (char *name, size_t namesz,
static int
allow_64_bit(void)
{
#if defined(__x86_64__) || defined(__aarch64__)
#if defined(__x86_64__) || defined(__aarch64__) || defined(__loongarch_lp64)
return 1;
#elif defined(__i386__) || defined(__i686__)
/* Right now blindly assuming the kernel will correctly detect this
Expand All @@ -298,7 +336,7 @@ allow_32_bit(void)
#endif
#elif defined(__i386__) || defined(__i686__)
return 1;
#elif defined(__aarch64__)
#elif defined(__aarch64__) || defined(__loongarch_lp64)
return 0;
#else /* assuming everything else is 32-bit... */
return 1;
Expand Down Expand Up @@ -326,6 +364,8 @@ static const UINT16 machine_type =
IMAGE_FILE_MACHINE_I386;
#elif defined(__ia64__)
IMAGE_FILE_MACHINE_IA64;
#elif defined(__loongarch_lp64)
IMAGE_FILE_MACHINE_LOONGARCH64;
#else
#error this architecture is not supported by shim
#endif
Expand Down
16 changes: 16 additions & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@
#endif
#endif

#if defined(__loongarch_lp64)
#ifndef DEFAULT_LOADER
#define DEFAULT_LOADER L"\\grubloongarch64.efi"
#endif
#ifndef DEFAULT_LOADER_CHAR
#define DEFAULT_LOADER_CHAR "\\grubloongarch64.efi"
#endif
#ifndef EFI_ARCH
#define EFI_ARCH L"loongarch64"
#endif
#ifndef DEBUGDIR
#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/loongarch64/"
#endif
#endif


#ifndef DEBUGSRC
#define DEBUGSRC L"/usr/src/debug/shim-" VERSIONSTR "." EFI_ARCH
#endif
Expand Down