]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: BaseTools changes for RISC-V platform.
authorAbner Chang <abner.chang@hpe.com>
Thu, 23 Apr 2020 13:52:32 +0000 (21:52 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 29 Apr 2020 02:52:08 +0000 (02:52 +0000)
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>
BaseTools/Source/C/Common/BasePeCoff.c
BaseTools/Source/C/Common/PeCoffLib.h
BaseTools/Source/C/Common/PeCoffLoaderEx.c
BaseTools/Source/C/GenFv/GenFvInternalLib.c
BaseTools/Source/C/GenFw/Elf32Convert.c
BaseTools/Source/C/GenFw/Elf64Convert.c
BaseTools/Source/C/GenFw/elf_common.h
BaseTools/Source/C/Include/IndustryStandard/PeImage.h

index e7566b383b66c9b19a9afcdd49f0051e1bd7515a..62fbb2985c8b20a936d5361046275e7ec33f9de8 100644 (file)
@@ -4,6 +4,7 @@
 \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
@@ -59,6 +60,14 @@ PeCoffLoaderRelocateArmImage (
   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
@@ -174,7 +183,8 @@ Returns:
       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
@@ -802,6 +812,9 @@ Returns:
         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
index 2fb2265e80f0d5cfdb674309ce6ec4ebce2f24c1..dd38f442f952ed2ca7a05752d08eaacf89558708 100644 (file)
@@ -2,6 +2,7 @@
   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
index e367836b96394012bbdd9806775fe1d6b3a7319e..588b3a2f84f5f123564c246a6f088c50d7862499 100644 (file)
@@ -3,6 +3,7 @@ IA32 and X64 Specific relocation fixups
 \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
@@ -61,6 +62,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #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
@@ -93,6 +96,89 @@ Returns:
   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
index daebfe894c77b2dbf204e531e917dfd921726261..d29a891c9c31353221b84ff5136ef3fb9314cf77 100644 (file)
@@ -4,6 +4,7 @@ This file contains the internal functions required to generate a Firmware Volume
 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
@@ -37,6 +38,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #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
@@ -2291,6 +2293,104 @@ Returns:
   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
@@ -2383,7 +2483,8 @@ Returns:
   // 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
@@ -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.");\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
@@ -2861,6 +2963,22 @@ Returns:
     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
@@ -3448,6 +3566,10 @@ Returns:
       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
@@ -3601,7 +3723,7 @@ Returns:
     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
index 46089ff3707582b4427acf4156ce9c3ce6535530..7f351287a93cc7e85b9d449e8436c0bfade845fd 100644 (file)
@@ -3,6 +3,7 @@ Elf32 Convert solution
 \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
@@ -141,8 +142,8 @@ InitializeElf32 (
     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
index d623dce1f9da020f110de1dd14d1182e9f90818a..4ed6b4477ea9310a488c5f58a3927c03b315ed78 100644 (file)
@@ -3,6 +3,7 @@ Elf64 convert solution
 \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
@@ -122,6 +123,13 @@ STATIC UINT32 mHiiRsrcOffset;
 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
@@ -153,8 +161,8 @@ InitializeElf64 (
     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
@@ -452,6 +460,147 @@ EmitGOTRelocations (
   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
@@ -481,6 +630,7 @@ ScanSections64 (
   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
@@ -690,6 +840,11 @@ ScanSections64 (
     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
@@ -894,12 +1049,18 @@ WriteSections64 (
             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
@@ -1151,6 +1312,11 @@ WriteSections64 (
           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
@@ -1170,6 +1336,7 @@ WriteRelocations64 (
   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
@@ -1276,6 +1443,107 @@ WriteRelocations64 (
             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
index 15c9e33d3f64a290b877fec01c5f56a04aac9fb1..b67f59e7a02fdb717c660a9e6be98e6aad0c38ad 100644 (file)
@@ -3,6 +3,7 @@ Ported ELF include files from FreeBSD
 \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
@@ -178,6 +179,8 @@ typedef struct {
 #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
@@ -979,5 +982,64 @@ typedef struct {
 #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
index 44037d13f32b0f39981837cc316101b6d4334ccf..f17b8ee19b340bc06bb0c2633eebd7c133b38a05 100644 (file)
@@ -6,6 +6,7 @@
 \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
@@ -41,6 +42,7 @@
 #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
@@ -50,6 +52,7 @@
 #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
@@ -504,7 +507,10 @@ typedef struct {
 #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