C code changes for building EDK2 RISC-V platform.
Signed-off-by: Abner Chang <abner.chang@hpe.com>
Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com>
Co-authored-by: Daniel Helmut Schaefer <daniel.schaefer@hpe.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Gilbert Chen <gilbert.chen@hpe.com>
\r
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
IN UINT64 Adjust\r
);\r
\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateRiscVImage (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
STATIC\r
RETURN_STATUS\r
PeCoffLoaderGetPeHeader (\r
ImageContext->Machine != EFI_IMAGE_MACHINE_X64 && \\r
ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \\r
ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \\r
- ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64) {\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {\r
if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {\r
//\r
// There are two types of ARM images. Pure ARM and ARM/Thumb.\r
case EFI_IMAGE_MACHINE_ARMT:\r
Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);\r
break;\r
+ case EFI_IMAGE_MACHINE_RISCV64:\r
+ Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);\r
+ break;\r
default:\r
Status = RETURN_UNSUPPORTED;\r
break;\r
Function prototypes and defines on Memory Only PE COFF loader\r
\r
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#define IMAGE_ERROR_FAILED_RELOCATION 9\r
#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10\r
\r
+//\r
+// Macro definitions for RISC-V architecture.\r
+//\r
+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))\r
+#define RISCV_IMM_BITS 12\r
+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)\r
+#define RISCV_CONST_HIGH_PART(VALUE) \\r
+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))\r
\r
//\r
// PE/COFF Loader Read Function passed in by caller\r
\r
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
+Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
--*/\r
#define IMM64_SIGN_INST_WORD_POS_X 27\r
#define IMM64_SIGN_VAL_POS_X 63\r
\r
+UINT32 *RiscVHi20Fixup = NULL;\r
+\r
RETURN_STATUS\r
PeCoffLoaderRelocateIa32Image (\r
IN UINT16 *Reloc,\r
return RETURN_UNSUPPORTED;\r
}\r
\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs an RISC-V specific relocation fixup\r
+\r
+Arguments:\r
+\r
+ Reloc - Pointer to the relocation record\r
+\r
+ Fixup - Pointer to the address to fix up\r
+\r
+ FixupData - Pointer to a buffer to log the fixups\r
+\r
+ Adjust - The offset to adjust the fixup\r
+\r
+Returns:\r
+\r
+ Status code\r
+\r
+--*/\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateRiscVImage (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+{\r
+ UINT32 Value;\r
+ UINT32 Value2;\r
+ UINT32 OrgValue;\r
+\r
+ OrgValue = *(UINT32 *) Fixup;\r
+ OrgValue = OrgValue;\r
+ switch ((*Reloc) >> 12) {\r
+ case EFI_IMAGE_REL_BASED_RISCV_HI20:\r
+ RiscVHi20Fixup = (UINT32 *) Fixup;\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12I:\r
+ if (RiscVHi20Fixup != NULL) {\r
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);\r
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));\r
+ if (Value2 & (RISCV_IMM_REACH/2)) {\r
+ Value2 |= ~(RISCV_IMM_REACH-1);\r
+ }\r
+ Value += Value2;\r
+ Value += (UINT32)Adjust;\r
+ Value2 = RISCV_CONST_HIGH_PART (Value);\r
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \\r
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));\r
+ *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \\r
+ (RV_X (*(UINT32 *)Fixup, 0, 20));\r
+ }\r
+ RiscVHi20Fixup = NULL;\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12S:\r
+ if (RiscVHi20Fixup != NULL) {\r
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);\r
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));\r
+ if (Value2 & (RISCV_IMM_REACH/2)) {\r
+ Value2 |= ~(RISCV_IMM_REACH-1);\r
+ }\r
+ Value += Value2;\r
+ Value += (UINT32)Adjust;\r
+ Value2 = RISCV_CONST_HIGH_PART (Value);\r
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \\r
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));\r
+ Value2 = *(UINT32 *)Fixup & 0x01fff07f;\r
+ Value &= RISCV_IMM_REACH - 1;\r
+ *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));\r
+ }\r
+ RiscVHi20Fixup = NULL;\r
+ break;\r
+\r
+ default:\r
+ return EFI_UNSUPPORTED;\r
+\r
+ }\r
+ return RETURN_SUCCESS;\r
+}\r
\r
/**\r
Pass in a pointer to an ARM MOVT or MOVW immediate instruction and\r
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>\r
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000\r
\r
BOOLEAN mArm = FALSE;\r
+BOOLEAN mRiscV = FALSE;\r
STATIC UINT32 MaxFfsAlignment = 0;\r
BOOLEAN VtfFileFlag = FALSE;\r
\r
return EFI_SUCCESS;\r
}\r
\r
+EFI_STATUS\r
+UpdateRiscvResetVectorIfNeeded (\r
+ MEMORY_FILE *FvImage,\r
+ FV_INFO *FvInfo\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This parses the FV looking for SEC and patches that address into the\r
+ beginning of the FV header.\r
+\r
+ For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h\r
+\r
+Arguments:\r
+ FvImage Memory file for the FV memory image/\r
+ FvInfo Information read from INF file.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Function Completed successfully.\r
+ EFI_ABORTED Error encountered.\r
+ EFI_INVALID_PARAMETER A required parameter was NULL.\r
+ EFI_NOT_FOUND PEI Core file not found.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT16 MachineType;\r
+ EFI_FILE_SECTION_POINTER SecPe32;\r
+ EFI_PHYSICAL_ADDRESS SecCoreEntryAddress;\r
+\r
+ UINT32 bSecCore;\r
+ UINT32 tmp;\r
+\r
+\r
+ //\r
+ // Verify input parameters\r
+ //\r
+ if (FvImage == NULL || FvInfo == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Initialize FV library\r
+ //\r
+ InitializeFvLib (FvImage->FileImage, FvInfo->Size);\r
+\r
+ //\r
+ // Find the Sec Core\r
+ //\r
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);\r
+ if(EFI_ERROR(Status)) {\r
+ printf("skip because Secutiry Core not found\n");\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL);\r
+\r
+ Status = GetCoreMachineType(SecPe32, &MachineType);\r
+ if(EFI_ERROR(Status)) {\r
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core.");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if (MachineType != EFI_IMAGE_MACHINE_RISCV64) {\r
+ Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Machine type is not RiscV.");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);\r
+ if(EFI_ERROR(Status)) {\r
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ VerboseMsg("SecCore entry point Address = 0x%llX", (unsigned long long) SecCoreEntryAddress);\r
+ VerboseMsg("BaseAddress = 0x%llX", (unsigned long long) FvInfo->BaseAddress);\r
+ bSecCore = (UINT32)(SecCoreEntryAddress - FvInfo->BaseAddress);\r
+ VerboseMsg("offset = 0x%llX", bSecCore);\r
+\r
+ if(bSecCore > 0x0fffff) {\r
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of start of the FV");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ tmp = bSecCore;\r
+ bSecCore = 0;\r
+ //J-type\r
+ bSecCore = (tmp&0x100000)<<11; //imm[20] at bit[31]\r
+ bSecCore |= (tmp&0x0007FE)<<20; //imm[10:1] at bit[30:21]\r
+ bSecCore |= (tmp&0x000800)<<9; //imm[11] at bit[20]\r
+ bSecCore |= (tmp&0x0FF000); //imm[19:12] at bit[19:12]\r
+ bSecCore |= 0x6F; //JAL opcode\r
+\r
+ memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
EFI_STATUS\r
GetPe32Info (\r
IN UINT8 *Pe32,\r
// Verify machine type is supported\r
//\r
if ((*MachineType != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&\r
- (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64)) {\r
+ (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&\r
+ (*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {\r
Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");\r
return EFI_UNSUPPORTED;\r
}\r
Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad file between the last file and the VTF file.");\r
goto Finish;\r
}\r
- if (!mArm) {\r
+\r
+ if (!mArm && !mRiscV) {\r
//\r
// Update reset vector (SALE_ENTRY for IPF)\r
// Now for IA32 and IA64 platform, the fv which has bsf file must have the\r
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));\r
}\r
\r
+ if (mRiscV) {\r
+ //\r
+ // Update RISCV reset vector.\r
+ //\r
+ Status = UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector for RISC-V.");\r
+ goto Finish;\r
+ }\r
+ //\r
+ // Update Checksum for FvHeader\r
+ //\r
+ FvHeader->Checksum = 0;\r
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));\r
+ }\r
+\r
//\r
// Update FV Alignment attribute to the largest alignment of all the FFS files in the FV\r
//\r
mArm = TRUE;\r
}\r
\r
+ if (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV64) {\r
+ mRiscV = TRUE;\r
+ }\r
+\r
//\r
// Keep Image Context for PE image in FV\r
//\r
ImageContext.DestinationAddress = NewPe32BaseAddress;\r
Status = PeCoffLoaderRelocateImage (&ImageContext);\r
if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);\r
free ((VOID *) MemoryImagePointer);\r
return Status;\r
}\r
\r
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>\r
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
return FALSE;\r
}\r
- if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) {\r
- Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");\r
+ if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM) || (mEhdr->e_machine == EM_RISCV))) {\r
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf32 machine.");\r
return FALSE;\r
}\r
if (mEhdr->e_version != EV_CURRENT) {\r
\r
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
STATIC UINT32 mRelocOffset;\r
STATIC UINT32 mDebugOffset;\r
\r
+//\r
+// Used for RISC-V relocations.\r
+//\r
+STATIC UINT8 *mRiscVPass1Targ = NULL;\r
+STATIC Elf_Shdr *mRiscVPass1Sym = NULL;\r
+STATIC Elf64_Half mRiscVPass1SymSecIndex = 0;\r
+\r
//\r
// Initialization Function\r
//\r
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
return FALSE;\r
}\r
- if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64))) {\r
- Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64");\r
+ if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {\r
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");\r
return FALSE;\r
}\r
if (mEhdr->e_version != EV_CURRENT) {\r
mGOTMaxCoffEntries = 0;\r
mGOTNumCoffEntries = 0;\r
}\r
+//\r
+// RISC-V 64 specific Elf WriteSection function.\r
+//\r
+STATIC\r
+VOID\r
+WriteSectionRiscV64 (\r
+ Elf_Rela *Rel,\r
+ UINT8 *Targ,\r
+ Elf_Shdr *SymShdr,\r
+ Elf_Sym *Sym\r
+ )\r
+{\r
+ UINT32 Value;\r
+ UINT32 Value2;\r
+\r
+ switch (ELF_R_TYPE(Rel->r_info)) {\r
+ case R_RISCV_NONE:\r
+ break;\r
+\r
+ case R_RISCV_32:\r
+ *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);\r
+ break;\r
+\r
+ case R_RISCV_64:\r
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
+ break;\r
+\r
+ case R_RISCV_HI20:\r
+ mRiscVPass1Targ = Targ;\r
+ mRiscVPass1Sym = SymShdr;\r
+ mRiscVPass1SymSecIndex = Sym->st_shndx;\r
+ break;\r
+\r
+ case R_RISCV_LO12_I:\r
+ if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {\r
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);\r
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));\r
+ if (Value2 & (RISCV_IMM_REACH/2)) {\r
+ Value2 |= ~(RISCV_IMM_REACH-1);\r
+ }\r
+ Value += Value2;\r
+ Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
+ Value2 = RISCV_CONST_HIGH_PART (Value);\r
+ *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \\r
+ (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));\r
+ *(UINT32 *)Targ = (RV_X (Value, 0, 12) << 20) | \\r
+ (RV_X (*(UINT32 *)Targ, 0, 20));\r
+ }\r
+ mRiscVPass1Sym = NULL;\r
+ mRiscVPass1Targ = NULL;\r
+ mRiscVPass1SymSecIndex = 0;\r
+ break;\r
+\r
+ case R_RISCV_LO12_S:\r
+ if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {\r
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);\r
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)Targ, 25, 7) << 5));\r
+ if (Value2 & (RISCV_IMM_REACH/2)) {\r
+ Value2 |= ~(RISCV_IMM_REACH-1);\r
+ }\r
+ Value += Value2;\r
+ Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
+ Value2 = RISCV_CONST_HIGH_PART (Value);\r
+ *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \\r
+ (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));\r
+ Value2 = *(UINT32 *)Targ & 0x01fff07f;\r
+ Value &= RISCV_IMM_REACH - 1;\r
+ *(UINT32 *)Targ = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));\r
+ }\r
+ mRiscVPass1Sym = NULL;\r
+ mRiscVPass1Targ = NULL;\r
+ mRiscVPass1SymSecIndex = 0;\r
+ break;\r
+\r
+ case R_RISCV_PCREL_HI20:\r
+ mRiscVPass1Targ = Targ;\r
+ mRiscVPass1Sym = SymShdr;\r
+ mRiscVPass1SymSecIndex = Sym->st_shndx;\r
+\r
+ Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));\r
+ break;\r
+\r
+ case R_RISCV_PCREL_LO12_I:\r
+ if (mRiscVPass1Targ != NULL && mRiscVPass1Sym != NULL && mRiscVPass1SymSecIndex != 0) {\r
+ int i;\r
+ Value2 = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));\r
+ Value = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));\r
+ if(Value & (RISCV_IMM_REACH/2)) {\r
+ Value |= ~(RISCV_IMM_REACH-1);\r
+ }\r
+ Value = Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOffset[mRiscVPass1SymSecIndex];\r
+ if(-2048 > (INT32)Value) {\r
+ i = (((INT32)Value * -1) / 4096);\r
+ Value2 -= i;\r
+ Value += 4096 * i;\r
+ if(-2048 > (INT32)Value) {\r
+ Value2 -= 1;\r
+ Value += 4096;\r
+ }\r
+ }\r
+ else if( 2047 < (INT32)Value) {\r
+ i = (Value / 4096);\r
+ Value2 += i;\r
+ Value -= 4096 * i;\r
+ if(2047 < (INT32)Value) {\r
+ Value2 += 1;\r
+ Value -= 4096;\r
+ }\r
+ }\r
+\r
+ *(UINT32 *)Targ = (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Targ, 0, 20));\r
+ *(UINT32 *)mRiscVPass1Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)mRiscVPass1Targ, 0, 12));\r
+ }\r
+ mRiscVPass1Sym = NULL;\r
+ mRiscVPass1Targ = NULL;\r
+ mRiscVPass1SymSecIndex = 0;\r
+ break;\r
+\r
+ case R_RISCV_ADD64:\r
+ case R_RISCV_SUB64:\r
+ case R_RISCV_ADD32:\r
+ case R_RISCV_SUB32:\r
+ case R_RISCV_BRANCH:\r
+ case R_RISCV_JAL:\r
+ case R_RISCV_GPREL_I:\r
+ case R_RISCV_GPREL_S:\r
+ case R_RISCV_CALL:\r
+ case R_RISCV_RVC_BRANCH:\r
+ case R_RISCV_RVC_JUMP:\r
+ case R_RISCV_RELAX:\r
+ case R_RISCV_SUB6:\r
+ case R_RISCV_SET6:\r
+ case R_RISCV_SET8:\r
+ case R_RISCV_SET16:\r
+ case R_RISCV_SET32:\r
+ break;\r
+\r
+ default:\r
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
+ }\r
+}\r
\r
//\r
// Elf functions interface implementation\r
switch (mEhdr->e_machine) {\r
case EM_X86_64:\r
case EM_AARCH64:\r
+ case EM_RISCV64:\r
mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
break;\r
default:\r
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64;\r
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
break;\r
+ case EM_RISCV64:\r
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;\r
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+ break;\r
+\r
default:\r
VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);\r
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
SymName = (const UINT8 *)"<unknown>";\r
}\r
\r
- Error (NULL, 0, 3000, "Invalid",\r
- "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "\r
- "For example, absolute and undefined symbols are not supported.",\r
- mInImageName, SymName, Sym->st_value);\r
+ //\r
+ // Skip error on EM_RISCV64 becasue no symble name is built\r
+ // from RISC-V toolchain.\r
+ //\r
+ if (mEhdr->e_machine != EM_RISCV64) {\r
+ Error (NULL, 0, 3000, "Invalid",\r
+ "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "\r
+ "For example, absolute and undefined symbols are not supported.",\r
+ mInImageName, SymName, Sym->st_value);\r
\r
- exit(EXIT_FAILURE);\r
+ exit(EXIT_FAILURE);\r
+ }\r
}\r
SymShdr = GetShdrByIndex(Sym->st_shndx);\r
\r
default:\r
Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
}\r
+ } else if (mEhdr->e_machine == EM_RISCV64) {\r
+ //\r
+ // Write section for RISC-V 64 architecture.\r
+ //\r
+ WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);\r
} else {\r
Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");\r
}\r
UINT32 Index;\r
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
EFI_IMAGE_DATA_DIRECTORY *Dir;\r
+ UINT32 RiscVRelType;\r
\r
for (Index = 0; Index < mEhdr->e_shnum; Index++) {\r
Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
default:\r
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
}\r
+ } else if (mEhdr->e_machine == EM_RISCV64) {\r
+ RiscVRelType = ELF_R_TYPE(Rel->r_info);\r
+ switch (RiscVRelType) {\r
+ case R_RISCV_NONE:\r
+ break;\r
+\r
+ case R_RISCV_32:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_HIGHLOW);\r
+ break;\r
+\r
+ case R_RISCV_64:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_DIR64);\r
+ break;\r
+\r
+ case R_RISCV_HI20:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_RISCV_HI20);\r
+ break;\r
+\r
+ case R_RISCV_LO12_I:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_RISCV_LOW12I);\r
+ break;\r
+\r
+ case R_RISCV_LO12_S:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_RISCV_LOW12S);\r
+ break;\r
+\r
+ case R_RISCV_ADD64:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_SUB64:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_ADD32:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_SUB32:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_BRANCH:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_JAL:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_ABSOLUTE);\r
+ break;\r
+\r
+ case R_RISCV_GPREL_I:\r
+ case R_RISCV_GPREL_S:\r
+ case R_RISCV_CALL:\r
+ case R_RISCV_RVC_BRANCH:\r
+ case R_RISCV_RVC_JUMP:\r
+ case R_RISCV_RELAX:\r
+ case R_RISCV_SUB6:\r
+ case R_RISCV_SET6:\r
+ case R_RISCV_SET8:\r
+ case R_RISCV_SET16:\r
+ case R_RISCV_SET32:\r
+ case R_RISCV_PCREL_HI20:\r
+ case R_RISCV_PCREL_LO12_I:\r
+ break;\r
+\r
+ default:\r
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
+ }\r
} else {\r
Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);\r
}\r
\r
Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
+Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */\r
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */\r
#define EM_AARCH64 183 /* ARM 64bit Architecture */\r
+#define EM_RISCV64 243 /* 64bit RISC-V Architecture */\r
+#define EM_RISCV 244 /* 32bit RISC-V Architecture */\r
\r
/* Non-standard or deprecated. */\r
#define EM_486 6 /* Intel i486. */\r
#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */\r
#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */\r
\r
+/*\r
+ * RISC-V relocation types\r
+ */\r
+\r
+/* Relocation types used by the dynamic linker */\r
+#define R_RISCV_NONE 0\r
+#define R_RISCV_32 1\r
+#define R_RISCV_64 2\r
+#define R_RISCV_RELATIVE 3\r
+#define R_RISCV_COPY 4\r
+#define R_RISCV_JUMP_SLOT 5\r
+#define R_RISCV_TLS_DTPMOD32 6\r
+#define R_RISCV_TLS_DTPMOD64 7\r
+#define R_RISCV_TLS_DTPREL32 8\r
+#define R_RISCV_TLS_DTPREL64 9\r
+#define R_RISCV_TLS_TPREL32 10\r
+#define R_RISCV_TLS_TPREL64 11\r
\r
+/* Relocation types not used by the dynamic linker */\r
+#define R_RISCV_BRANCH 16\r
+#define R_RISCV_JAL 17\r
+#define R_RISCV_CALL 18\r
+#define R_RISCV_CALL_PLT 19\r
+#define R_RISCV_GOT_HI20 20\r
+#define R_RISCV_TLS_GOT_HI20 21\r
+#define R_RISCV_TLS_GD_HI20 22\r
+#define R_RISCV_PCREL_HI20 23\r
+#define R_RISCV_PCREL_LO12_I 24\r
+#define R_RISCV_PCREL_LO12_S 25\r
+#define R_RISCV_HI20 26\r
+#define R_RISCV_LO12_I 27\r
+#define R_RISCV_LO12_S 28\r
+#define R_RISCV_TPREL_HI20 29\r
+#define R_RISCV_TPREL_LO12_I 30\r
+#define R_RISCV_TPREL_LO12_S 31\r
+#define R_RISCV_TPREL_ADD 32\r
+#define R_RISCV_ADD8 33\r
+#define R_RISCV_ADD16 34\r
+#define R_RISCV_ADD32 35\r
+#define R_RISCV_ADD64 36\r
+#define R_RISCV_SUB8 37\r
+#define R_RISCV_SUB16 38\r
+#define R_RISCV_SUB32 39\r
+#define R_RISCV_SUB64 40\r
+#define R_RISCV_GNU_VTINHERIT 41\r
+#define R_RISCV_GNU_VTENTRY 42\r
+#define R_RISCV_ALIGN 43\r
+#define R_RISCV_RVC_BRANCH 44\r
+#define R_RISCV_RVC_JUMP 45\r
+#define R_RISCV_RVC_LUI 46\r
+#define R_RISCV_GPREL_I 47\r
+#define R_RISCV_GPREL_S 48\r
+#define R_RISCV_TPREL_I 49\r
+#define R_RISCV_TPREL_S 50\r
+#define R_RISCV_RELAX 51\r
+#define R_RISCV_SUB6 52\r
+#define R_RISCV_SET6 53\r
+#define R_RISCV_SET8 54\r
+#define R_RISCV_SET16 55\r
+#define R_RISCV_SET32 56\r
#endif /* !_SYS_ELF_COMMON_H_ */\r
\r
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only\r
#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian\r
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian\r
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA\r
\r
//\r
// Support old names for backward compatible\r
#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64\r
#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT\r
#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64\r
+#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64\r
\r
#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ\r
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE\r
#define EFI_IMAGE_REL_BASED_HIGHADJ 4\r
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5\r
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5\r
+#define EFI_IMAGE_REL_BASED_RISCV_HI20 5\r
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7\r
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7\r
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8\r
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9\r
#define EFI_IMAGE_REL_BASED_DIR64 10\r
\r