From nobody Tue Nov 26 06:31:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+57687+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+57687+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=hpe.com ARC-Seal: i=1; a=rsa-sha256; t=1587436732; cv=none; d=zohomail.com; s=zohoarc; b=oHPy8vR8W9spbBooXPAyrQjCxMK2MH+QTx/MYL8NVnAE8SxD3QwBBu46SLZgR959GY4eLuRLqs/51evTdUL0c/Uv5+JPsudFIeB03fKRt0hfsh6knlD9S5NnZJ86eBqNo2Pz7Mlc7BWg0bvZIfVAGdWboqaKsrVdKKnpHDZdmCw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1587436732; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=XV/+KUVCaQmdGOvU6Um1jew0fgTvOa+bs8rNCINqeUs=; b=iMyzWaeZ7hdXVA0lxav+DIaoBKv9bjmq5zoaziyp8yKWfCat0jvsfe/f7kqvipW4SDCqqh/yh9uBVfoC+p3ZM8k0V4thXdaegxWIBy3Fpek8X2VkRytALX0WvASZDOLXywCwpToLHC5BeKkF8JhfkhlKETHzWUuvSl+9wQzhmZ0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+57687+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 158743673248678.2556263042369; Mon, 20 Apr 2020 19:38:52 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id HIAkYY1788612xzBYeQez2D0; Mon, 20 Apr 2020 19:38:52 -0700 X-Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web12.1828.1587436731478310040 for ; Mon, 20 Apr 2020 19:38:51 -0700 X-Received: from pps.filterd (m0150244.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03L2cnC1032072; Tue, 21 Apr 2020 02:38:49 GMT X-Received: from g4t3425.houston.hpe.com (g4t3425.houston.hpe.com [15.241.140.78]) by mx0b-002e3701.pphosted.com with ESMTP id 30gxf2smc7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 21 Apr 2020 02:38:49 +0000 X-Received: from g9t2301.houston.hpecorp.net (g9t2301.houston.hpecorp.net [16.220.97.129]) by g4t3425.houston.hpe.com (Postfix) with ESMTP id 52C49B4; Tue, 21 Apr 2020 02:38:37 +0000 (UTC) X-Received: from UB16Abner.asiapacific.hpqcorp.net (ub16abner.asiapacific.hpqcorp.net [15.119.209.229]) by g9t2301.houston.hpecorp.net (Postfix) with ESMTP id B27BE50; Tue, 21 Apr 2020 02:38:35 +0000 (UTC) From: "Abner Chang" To: devel@edk2.groups.io Cc: abner.chang@hpe.com, Gilbert Chen , Daniel Helmut Schaefer , Leif Lindholm , Bob Feng , Liming Gao Subject: [edk2-devel] [PATCH v3 2/3] BaseTools: BaseTools changes for RISC-V platform. Date: Tue, 21 Apr 2020 10:00:16 +0800 Message-Id: <20200421020017.16072-3-abner.chang@hpe.com> In-Reply-To: <20200421020017.16072-1-abner.chang@hpe.com> References: <20200421020017.16072-1-abner.chang@hpe.com> MIME-Version: 1.0 X-HPE-SCL: -1 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@hpe.com X-Gm-Message-State: zSu7tUFa1P8fZHDRhy3z3bDLx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1587436732; bh=3G59WS9BPRrD3Efs6SIEveJsHT+JfnOrzYxabxoxPvg=; h=Cc:Date:From:Reply-To:Subject:To; b=LAnhbXZS6CJz8OGYuPAn63m53YqY5EYTKDTTod+kcWzynvOfBZ8wszCcPWSWs+qBdy0 +oviY0ohX+RMFxtlDwzWM6rsCmq6VbnSjIKkK9/hlxO3/z6AbMnDJ5bb8CWmwg1u3YM8I YdKE7pmxI0CDXiXZxaYRnW3pa5IzNzVxQrs= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" C code changes for building EDK2 RISC-V platform. Signed-off-by: Abner Chang Co-authored-by: Gilbert Chen Co-authored-by: Daniel Helmut Schaefer Reviewed-by: Leif Lindholm Cc: Bob Feng Cc: Liming Gao Cc: Leif Lindholm Cc: Gilbert Chen --- BaseTools/Source/C/Common/PeCoffLib.h | 9 + BaseTools/Source/C/GenFw/elf_common.h | 62 ++++ .../C/Include/IndustryStandard/PeImage.h | 6 + BaseTools/Source/C/Common/BasePeCoff.c | 15 +- BaseTools/Source/C/Common/PeCoffLoaderEx.c | 86 ++++++ BaseTools/Source/C/GenFv/GenFvInternalLib.c | 128 +++++++- BaseTools/Source/C/GenFw/Elf32Convert.c | 5 +- BaseTools/Source/C/GenFw/Elf64Convert.c | 282 +++++++++++++++++- 8 files changed, 580 insertions(+), 13 deletions(-) diff --git a/BaseTools/Source/C/Common/PeCoffLib.h b/BaseTools/Source/C/Com= mon/PeCoffLib.h index 2fb2265e80..dd38f442f9 100644 --- a/BaseTools/Source/C/Common/PeCoffLib.h +++ b/BaseTools/Source/C/Common/PeCoffLib.h @@ -2,6 +2,7 @@ Function prototypes and defines on Memory Only PE COFF loader =20 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. A= ll rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -25,6 +26,14 @@ #define IMAGE_ERROR_FAILED_RELOCATION 9 #define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10 =20 +// +// Macro definitions for RISC-V architecture. +// +#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1)) +#define RISCV_IMM_BITS 12 +#define RISCV_IMM_REACH (1LL< Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All= rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 =20 @@ -178,6 +179,8 @@ typedef struct { #define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ #define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ #define EM_AARCH64 183 /* ARM 64bit Architecture */ +#define EM_RISCV64 243 /* 64bit RISC-V Architecture */ +#define EM_RISCV 244 /* 32bit RISC-V Architecture */ =20 /* Non-standard or deprecated. */ #define EM_486 6 /* Intel i486. */ @@ -979,5 +982,64 @@ typedef struct { #define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative of= fset to GOT entry without REX prefix, relaxable. */ #define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relativ= e offset to GOT entry with REX prefix, relaxable. */ =20 +/* + * RISC-V relocation types + */ + +/* Relocation types used by the dynamic linker */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 =20 +/* Relocation types not used by the dynamic linker */ +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 #endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/BaseTo= ols/Source/C/Include/IndustryStandard/PeImage.h index 44037d13f3..f17b8ee19b 100644 --- a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h +++ b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h @@ -6,6 +6,7 @@ =20 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All right= s reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -41,6 +42,7 @@ #define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only #define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/T= humb 2 Little Endian #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Lit= tle Endian +#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA =20 // // Support old names for backward compatible @@ -50,6 +52,7 @@ #define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 #define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT #define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64 +#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64 =20 #define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ #define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE @@ -504,7 +507,10 @@ typedef struct { #define EFI_IMAGE_REL_BASED_HIGHADJ 4 #define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 #define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 +#define EFI_IMAGE_REL_BASED_RISCV_HI20 5 #define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 #define EFI_IMAGE_REL_BASED_IA64_IMM64 9 #define EFI_IMAGE_REL_BASED_DIR64 10 =20 diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Co= mmon/BasePeCoff.c index e7566b383b..62fbb2985c 100644 --- a/BaseTools/Source/C/Common/BasePeCoff.c +++ b/BaseTools/Source/C/Common/BasePeCoff.c @@ -4,6 +4,7 @@ =20 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -59,6 +60,14 @@ PeCoffLoaderRelocateArmImage ( IN UINT64 Adjust ); =20 +RETURN_STATUS +PeCoffLoaderRelocateRiscVImage ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ); + STATIC RETURN_STATUS PeCoffLoaderGetPeHeader ( @@ -174,7 +183,8 @@ Returns: ImageContext->Machine !=3D EFI_IMAGE_MACHINE_X64 && \ ImageContext->Machine !=3D EFI_IMAGE_MACHINE_ARMT && \ ImageContext->Machine !=3D EFI_IMAGE_MACHINE_EBC && \ - ImageContext->Machine !=3D EFI_IMAGE_MACHINE_AARCH64) { + ImageContext->Machine !=3D EFI_IMAGE_MACHINE_AARCH64 && \ + ImageContext->Machine !=3D EFI_IMAGE_MACHINE_RISCV64) { if (ImageContext->Machine =3D=3D IMAGE_FILE_MACHINE_ARM) { // // There are two types of ARM images. Pure ARM and ARM/Thumb. @@ -802,6 +812,9 @@ Returns: case EFI_IMAGE_MACHINE_ARMT: Status =3D PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupDa= ta, Adjust); break; + case EFI_IMAGE_MACHINE_RISCV64: + Status =3D PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupD= ata, Adjust); + break; default: Status =3D RETURN_UNSUPPORTED; break; diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/= C/Common/PeCoffLoaderEx.c index e367836b96..588b3a2f84 100644 --- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c +++ b/BaseTools/Source/C/Common/PeCoffLoaderEx.c @@ -3,6 +3,7 @@ IA32 and X64 Specific relocation fixups =20 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights = reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 --*/ @@ -61,6 +62,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define IMM64_SIGN_INST_WORD_POS_X 27 #define IMM64_SIGN_VAL_POS_X 63 =20 +UINT32 *RiscVHi20Fixup =3D NULL; + RETURN_STATUS PeCoffLoaderRelocateIa32Image ( IN UINT16 *Reloc, @@ -93,6 +96,89 @@ Returns: return RETURN_UNSUPPORTED; } =20 +/*++ + +Routine Description: + + Performs an RISC-V specific relocation fixup + +Arguments: + + Reloc - Pointer to the relocation record + + Fixup - Pointer to the address to fix up + + FixupData - Pointer to a buffer to log the fixups + + Adjust - The offset to adjust the fixup + +Returns: + + Status code + +--*/ +RETURN_STATUS +PeCoffLoaderRelocateRiscVImage ( + IN UINT16 *Reloc, + IN OUT CHAR8 *Fixup, + IN OUT CHAR8 **FixupData, + IN UINT64 Adjust + ) +{ + UINT32 Value; + UINT32 Value2; + UINT32 OrgValue; + + OrgValue =3D *(UINT32 *) Fixup; + OrgValue =3D OrgValue; + switch ((*Reloc) >> 12) { + case EFI_IMAGE_REL_BASED_RISCV_HI20: + RiscVHi20Fixup =3D (UINT32 *) Fixup; + break; + + case EFI_IMAGE_REL_BASED_RISCV_LOW12I: + if (RiscVHi20Fixup !=3D NULL) { + Value =3D (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); + Value2 =3D (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12)); + if (Value2 & (RISCV_IMM_REACH/2)) { + Value2 |=3D ~(RISCV_IMM_REACH-1); + } + Value +=3D Value2; + Value +=3D (UINT32)Adjust; + Value2 =3D RISCV_CONST_HIGH_PART (Value); + *(UINT32 *)RiscVHi20Fixup =3D (RV_X (Value2, 12, 20) << 12) | \ + (RV_X (*(UINT32 *)RiscVHi20Fixu= p, 0, 12)); + *(UINT32 *)Fixup =3D (RV_X (Value, 0, 12) << 20) | \ + (RV_X (*(UINT32 *)Fixup, 0, 20)); + } + RiscVHi20Fixup =3D NULL; + break; + + case EFI_IMAGE_REL_BASED_RISCV_LOW12S: + if (RiscVHi20Fixup !=3D NULL) { + Value =3D (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); + Value2 =3D (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 = *)Fixup, 25, 7) << 5)); + if (Value2 & (RISCV_IMM_REACH/2)) { + Value2 |=3D ~(RISCV_IMM_REACH-1); + } + Value +=3D Value2; + Value +=3D (UINT32)Adjust; + Value2 =3D RISCV_CONST_HIGH_PART (Value); + *(UINT32 *)RiscVHi20Fixup =3D (RV_X (Value2, 12, 20) << 12) | \ + (RV_X (*(UINT32 *)RiscVHi20Fixu= p, 0, 12)); + Value2 =3D *(UINT32 *)Fixup & 0x01fff07f; + Value &=3D RISCV_IMM_REACH - 1; + *(UINT32 *)Fixup =3D Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) |= (RV_X(Value, 5, 7) << 25))); + } + RiscVHi20Fixup =3D NULL; + break; + + default: + return EFI_UNSUPPORTED; + + } + return RETURN_SUCCESS; +} =20 /** Pass in a pointer to an ARM MOVT or MOVW immediate instruction and diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source= /C/GenFv/GenFvInternalLib.c index daebfe894c..d29a891c9c 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -4,6 +4,7 @@ This file contains the internal functions required to gener= ate a Firmware Volume Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
Portions Copyright (c) 2016 HP Development Company, L.P.
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -37,6 +38,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000 =20 BOOLEAN mArm =3D FALSE; +BOOLEAN mRiscV =3D FALSE; STATIC UINT32 MaxFfsAlignment =3D 0; BOOLEAN VtfFileFlag =3D FALSE; =20 @@ -2291,6 +2293,104 @@ Returns: return EFI_SUCCESS; } =20 +EFI_STATUS +UpdateRiscvResetVectorIfNeeded ( + MEMORY_FILE *FvImage, + FV_INFO *FvInfo + ) +/*++ + +Routine Description: + This parses the FV looking for SEC and patches that address into the + beginning of the FV header. + + For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h + +Arguments: + FvImage Memory file for the FV memory image/ + FvInfo Information read from INF file. + +Returns: + + EFI_SUCCESS Function Completed successfully. + EFI_ABORTED Error encountered. + EFI_INVALID_PARAMETER A required parameter was NULL. + EFI_NOT_FOUND PEI Core file not found. + +--*/ +{ + EFI_STATUS Status; + UINT16 MachineType; + EFI_FILE_SECTION_POINTER SecPe32; + EFI_PHYSICAL_ADDRESS SecCoreEntryAddress; + + UINT32 bSecCore; + UINT32 tmp; + + + // + // Verify input parameters + // + if (FvImage =3D=3D NULL || FvInfo =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Initialize FV library + // + InitializeFvLib (FvImage->FileImage, FvInfo->Size); + + // + // Find the Sec Core + // + Status =3D FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FI= LETYPE_SECURITY_CORE, &SecPe32); + if(EFI_ERROR(Status)) { + printf("skip because Secutiry Core not found\n"); + return EFI_SUCCESS; + } + + DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL); + + Status =3D GetCoreMachineType(SecPe32, &MachineType); + if(EFI_ERROR(Status)) { + Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type f= or SEC core."); + return EFI_ABORTED; + } + + if (MachineType !=3D EFI_IMAGE_MACHINE_RISCV64) { + Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Mac= hine type is not RiscV."); + return EFI_ABORTED; + } + + Status =3D GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32,= &SecCoreEntryAddress); + if(EFI_ERROR(Status)) { + Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point ad= dress for SEC Core."); + return EFI_ABORTED; + } + + VerboseMsg("SecCore entry point Address =3D 0x%llX", (unsigned long long= ) SecCoreEntryAddress); + VerboseMsg("BaseAddress =3D 0x%llX", (unsigned long long) FvInfo->BaseAd= dress); + bSecCore =3D (UINT32)(SecCoreEntryAddress - FvInfo->BaseAddress); + VerboseMsg("offset =3D 0x%llX", bSecCore); + + if(bSecCore > 0x0fffff) { + Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of= start of the FV"); + return EFI_ABORTED; + } + + tmp =3D bSecCore; + bSecCore =3D 0; + //J-type + bSecCore =3D (tmp&0x100000)<<11; //imm[20] at bit[31] + bSecCore |=3D (tmp&0x0007FE)<<20; //imm[10:1] at bit[30:21] + bSecCore |=3D (tmp&0x000800)<<9; //imm[11] at bit[20] + bSecCore |=3D (tmp&0x0FF000); //imm[19:12] at bit[19:12] + bSecCore |=3D 0x6F; //JAL opcode + + memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore)); + + return EFI_SUCCESS; +} + EFI_STATUS GetPe32Info ( IN UINT8 *Pe32, @@ -2383,7 +2483,8 @@ Returns: // Verify machine type is supported // if ((*MachineType !=3D EFI_IMAGE_MACHINE_IA32) && (*MachineType !=3D EF= I_IMAGE_MACHINE_X64) && (*MachineType !=3D EFI_IMAGE_MACHINE_EBC) && - (*MachineType !=3D EFI_IMAGE_MACHINE_ARMT) && (*MachineType !=3D EFI= _IMAGE_MACHINE_AARCH64)) { + (*MachineType !=3D EFI_IMAGE_MACHINE_ARMT) && (*MachineType !=3D EFI= _IMAGE_MACHINE_AARCH64) && + (*MachineType !=3D EFI_IMAGE_MACHINE_RISCV64)) { Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE3= 2 file."); return EFI_UNSUPPORTED; } @@ -2826,7 +2927,8 @@ Returns: Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad = file between the last file and the VTF file."); goto Finish; } - if (!mArm) { + + if (!mArm && !mRiscV) { // // Update reset vector (SALE_ENTRY for IPF) // Now for IA32 and IA64 platform, the fv which has bsf file must ha= ve the @@ -2861,6 +2963,22 @@ Returns: FvHeader->Checksum =3D CalculateChecksum16 ((UINT16 *) FvHeader, FvHea= der->HeaderLength / sizeof (UINT16)); } =20 + if (mRiscV) { + // + // Update RISCV reset vector. + // + Status =3D UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDa= taInfo); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector= for RISC-V."); + goto Finish; + } + // + // Update Checksum for FvHeader + // + FvHeader->Checksum =3D 0; + FvHeader->Checksum =3D CalculateChecksum16 ((UINT16 *) FvHeader, FvHea= der->HeaderLength / sizeof (UINT16)); + } + // // Update FV Alignment attribute to the largest alignment of all the FFS= files in the FV // @@ -3448,6 +3566,10 @@ Returns: mArm =3D TRUE; } =20 + if (ImageContext.Machine =3D=3D EFI_IMAGE_MACHINE_RISCV64) { + mRiscV =3D TRUE; + } + // // Keep Image Context for PE image in FV // @@ -3601,7 +3723,7 @@ Returns: ImageContext.DestinationAddress =3D NewPe32BaseAddress; Status =3D PeCoffLoaderRelocateImage (&ImageC= ontext); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on reb= ase of %s", FileName); + Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on reb= ase of %s Status=3D%d", FileName, Status); free ((VOID *) MemoryImagePointer); return Status; } diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/G= enFw/Elf32Convert.c index 46089ff370..7f351287a9 100644 --- a/BaseTools/Source/C/GenFw/Elf32Convert.c +++ b/BaseTools/Source/C/GenFw/Elf32Convert.c @@ -3,6 +3,7 @@ Elf32 Convert solution =20 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2013, ARM Ltd. All rights reserved.
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -141,8 +142,8 @@ InitializeElf32 ( Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN= "); return FALSE; } - if (!((mEhdr->e_machine =3D=3D EM_386) || (mEhdr->e_machine =3D=3D EM_AR= M))) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_A= RM"); + if (!((mEhdr->e_machine =3D=3D EM_386) || (mEhdr->e_machine =3D=3D EM_AR= M) || (mEhdr->e_machine =3D=3D EM_RISCV))) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf32 machi= ne."); return FALSE; } if (mEhdr->e_version !=3D EV_CURRENT) { diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/G= enFw/Elf64Convert.c index d623dce1f9..4ed6b4477e 100644 --- a/BaseTools/Source/C/GenFw/Elf64Convert.c +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c @@ -3,6 +3,7 @@ Elf64 convert solution =20 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -122,6 +123,13 @@ STATIC UINT32 mHiiRsrcOffset; STATIC UINT32 mRelocOffset; STATIC UINT32 mDebugOffset; =20 +// +// Used for RISC-V relocations. +// +STATIC UINT8 *mRiscVPass1Targ =3D NULL; +STATIC Elf_Shdr *mRiscVPass1Sym =3D NULL; +STATIC Elf64_Half mRiscVPass1SymSecIndex =3D 0; + // // Initialization Function // @@ -153,8 +161,8 @@ InitializeElf64 ( Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN= "); return FALSE; } - if (!((mEhdr->e_machine =3D=3D EM_X86_64) || (mEhdr->e_machine =3D=3D EM= _AARCH64))) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or E= M_AARCH64"); + if (!((mEhdr->e_machine =3D=3D EM_X86_64) || (mEhdr->e_machine =3D=3D EM= _AARCH64) || (mEhdr->e_machine =3D=3D EM_RISCV64))) { + Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machi= ne."); return FALSE; } if (mEhdr->e_version !=3D EV_CURRENT) { @@ -452,6 +460,147 @@ EmitGOTRelocations ( mGOTMaxCoffEntries =3D 0; mGOTNumCoffEntries =3D 0; } +// +// RISC-V 64 specific Elf WriteSection function. +// +STATIC +VOID +WriteSectionRiscV64 ( + Elf_Rela *Rel, + UINT8 *Targ, + Elf_Shdr *SymShdr, + Elf_Sym *Sym + ) +{ + UINT32 Value; + UINT32 Value2; + + switch (ELF_R_TYPE(Rel->r_info)) { + case R_RISCV_NONE: + break; + + case R_RISCV_32: + *(UINT32 *)Targ =3D (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_a= ddr + mCoffSectionsOffset[Sym->st_shndx]); + break; + + case R_RISCV_64: + *(UINT64 *)Targ =3D *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSections= Offset[Sym->st_shndx]; + break; + + case R_RISCV_HI20: + mRiscVPass1Targ =3D Targ; + mRiscVPass1Sym =3D SymShdr; + mRiscVPass1SymSecIndex =3D Sym->st_shndx; + break; + + case R_RISCV_LO12_I: + if (mRiscVPass1Sym =3D=3D SymShdr && mRiscVPass1Targ !=3D NULL && mRis= cVPass1SymSecIndex =3D=3D Sym->st_shndx && mRiscVPass1SymSecIndex !=3D 0) { + Value =3D (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12); + Value2 =3D (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12)); + if (Value2 & (RISCV_IMM_REACH/2)) { + Value2 |=3D ~(RISCV_IMM_REACH-1); + } + Value +=3D Value2; + Value =3D Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym= ->st_shndx]; + Value2 =3D RISCV_CONST_HIGH_PART (Value); + *(UINT32 *)mRiscVPass1Targ =3D (RV_X (Value2, 12, 20) << 12) | \ + (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12)); + *(UINT32 *)Targ =3D (RV_X (Value, 0, 12) << 20) | \ + (RV_X (*(UINT32 *)Targ, 0, 20)); + } + mRiscVPass1Sym =3D NULL; + mRiscVPass1Targ =3D NULL; + mRiscVPass1SymSecIndex =3D 0; + break; + + case R_RISCV_LO12_S: + if (mRiscVPass1Sym =3D=3D SymShdr && mRiscVPass1Targ !=3D NULL && mRis= cVPass1SymSecIndex =3D=3D Sym->st_shndx && mRiscVPass1SymSecIndex !=3D 0) { + Value =3D (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12); + Value2 =3D (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)T= arg, 25, 7) << 5)); + if (Value2 & (RISCV_IMM_REACH/2)) { + Value2 |=3D ~(RISCV_IMM_REACH-1); + } + Value +=3D Value2; + Value =3D Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym= ->st_shndx]; + Value2 =3D RISCV_CONST_HIGH_PART (Value); + *(UINT32 *)mRiscVPass1Targ =3D (RV_X (Value2, 12, 20) << 12) | \ + (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12)= ); + Value2 =3D *(UINT32 *)Targ & 0x01fff07f; + Value &=3D RISCV_IMM_REACH - 1; + *(UINT32 *)Targ =3D Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (R= V_X(Value, 5, 7) << 25))); + } + mRiscVPass1Sym =3D NULL; + mRiscVPass1Targ =3D NULL; + mRiscVPass1SymSecIndex =3D 0; + break; + + case R_RISCV_PCREL_HI20: + mRiscVPass1Targ =3D Targ; + mRiscVPass1Sym =3D SymShdr; + mRiscVPass1SymSecIndex =3D Sym->st_shndx; + + Value =3D (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20)); + break; + + case R_RISCV_PCREL_LO12_I: + if (mRiscVPass1Targ !=3D NULL && mRiscVPass1Sym !=3D NULL && mRiscVPas= s1SymSecIndex !=3D 0) { + int i; + Value2 =3D (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20)); + Value =3D (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12)); + if(Value & (RISCV_IMM_REACH/2)) { + Value |=3D ~(RISCV_IMM_REACH-1); + } + Value =3D Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOff= set[mRiscVPass1SymSecIndex]; + if(-2048 > (INT32)Value) { + i =3D (((INT32)Value * -1) / 4096); + Value2 -=3D i; + Value +=3D 4096 * i; + if(-2048 > (INT32)Value) { + Value2 -=3D 1; + Value +=3D 4096; + } + } + else if( 2047 < (INT32)Value) { + i =3D (Value / 4096); + Value2 +=3D i; + Value -=3D 4096 * i; + if(2047 < (INT32)Value) { + Value2 +=3D 1; + Value -=3D 4096; + } + } + + *(UINT32 *)Targ =3D (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Tar= g, 0, 20)); + *(UINT32 *)mRiscVPass1Targ =3D (RV_X(Value2, 0, 20)<<12) | (RV_X(*(U= INT32 *)mRiscVPass1Targ, 0, 12)); + } + mRiscVPass1Sym =3D NULL; + mRiscVPass1Targ =3D NULL; + mRiscVPass1SymSecIndex =3D 0; + break; + + case R_RISCV_ADD64: + case R_RISCV_SUB64: + case R_RISCV_ADD32: + case R_RISCV_SUB32: + case R_RISCV_BRANCH: + case R_RISCV_JAL: + case R_RISCV_GPREL_I: + case R_RISCV_GPREL_S: + case R_RISCV_CALL: + case R_RISCV_RVC_BRANCH: + case R_RISCV_RVC_JUMP: + case R_RISCV_RELAX: + case R_RISCV_SUB6: + case R_RISCV_SET6: + case R_RISCV_SET8: + case R_RISCV_SET16: + case R_RISCV_SET32: + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported EL= F EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_= info)); + } +} =20 // // Elf functions interface implementation @@ -481,6 +630,7 @@ ScanSections64 ( switch (mEhdr->e_machine) { case EM_X86_64: case EM_AARCH64: + case EM_RISCV64: mCoffOffset +=3D sizeof (EFI_IMAGE_NT_HEADERS64); break; default: @@ -690,6 +840,11 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.Machine =3D EFI_IMAGE_MACHINE_AARCH64; NtHdr->Pe32Plus.OptionalHeader.Magic =3D EFI_IMAGE_NT_OPTIONAL_HDR64_M= AGIC; break; + case EM_RISCV64: + NtHdr->Pe32Plus.FileHeader.Machine =3D EFI_IMAGE_MACHINE_RISCV64; + NtHdr->Pe32Plus.OptionalHeader.Magic =3D EFI_IMAGE_NT_OPTIONAL_HDR64_M= AGIC; + break; + default: VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_m= achine); NtHdr->Pe32Plus.FileHeader.Machine =3D EFI_IMAGE_MACHINE_X64; @@ -894,12 +1049,18 @@ WriteSections64 ( SymName =3D (const UINT8 *)""; } =20 - Error (NULL, 0, 3000, "Invalid", - "%s: Bad definition for symbol '%s'@%#llx or unsupported = symbol type. " - "For example, absolute and undefined symbols are not supp= orted.", - mInImageName, SymName, Sym->st_value); + // + // Skip error on EM_RISCV64 becasue no symble name is built + // from RISC-V toolchain. + // + if (mEhdr->e_machine !=3D EM_RISCV64) { + Error (NULL, 0, 3000, "Invalid", + "%s: Bad definition for symbol '%s'@%#llx or unsupporte= d symbol type. " + "For example, absolute and undefined symbols are not su= pported.", + mInImageName, SymName, Sym->st_value); =20 - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); + } } SymShdr =3D GetShdrByIndex(Sym->st_shndx); =20 @@ -1151,6 +1312,11 @@ WriteSections64 ( default: Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupp= orted ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE= (Rel->r_info)); } + } else if (mEhdr->e_machine =3D=3D EM_RISCV64) { + // + // Write section for RISC-V 64 architecture. + // + WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym); } else { Error (NULL, 0, 3000, "Invalid", "Not a supported machine type"); } @@ -1170,6 +1336,7 @@ WriteRelocations64 ( UINT32 Index; EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; EFI_IMAGE_DATA_DIRECTORY *Dir; + UINT32 RiscVRelType; =20 for (Index =3D 0; Index < mEhdr->e_shnum; Index++) { Elf_Shdr *RelShdr =3D GetShdrByIndex(Index); @@ -1276,6 +1443,107 @@ WriteRelocations64 ( default: Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s= unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF= _R_TYPE(Rel->r_info)); } + } else if (mEhdr->e_machine =3D=3D EM_RISCV64) { + RiscVRelType =3D ELF_R_TYPE(Rel->r_info); + switch (RiscVRelType) { + case R_RISCV_NONE: + break; + + case R_RISCV_32: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_HIGHLOW); + break; + + case R_RISCV_64: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_DIR64); + break; + + case R_RISCV_HI20: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_RISCV_HI20); + break; + + case R_RISCV_LO12_I: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_RISCV_LOW12I); + break; + + case R_RISCV_LO12_S: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_RISCV_LOW12S); + break; + + case R_RISCV_ADD64: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_SUB64: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_ADD32: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_SUB32: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_BRANCH: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_JAL: + CoffAddFixup( + (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] + + (Rel->r_offset - SecShdr->sh_addr)), + EFI_IMAGE_REL_BASED_ABSOLUTE); + break; + + case R_RISCV_GPREL_I: + case R_RISCV_GPREL_S: + case R_RISCV_CALL: + case R_RISCV_RVC_BRANCH: + case R_RISCV_RVC_JUMP: + case R_RISCV_RELAX: + case R_RISCV_SUB6: + case R_RISCV_SET6: + case R_RISCV_SET8: + case R_RISCV_SET16: + case R_RISCV_SET32: + case R_RISCV_PCREL_HI20: + case R_RISCV_PCREL_LO12_I: + break; + + default: + Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s u= nsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R= _TYPE(Rel->r_info)); + } } else { Error (NULL, 0, 3000, "Not Supported", "This tool does not sup= port relocations for ELF with e_machine %u (processor type).", (unsigned) m= Ehdr->e_machine); } --=20 2.25.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#57687): https://edk2.groups.io/g/devel/message/57687 Mute This Topic: https://groups.io/mt/73164987/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-