[edk2-devel] [staging/LoongArch RESEND PATCH v1 13/33] BaseTools: BaseTools changes for LoongArch platform.

Chao Li lichao at loongson.cn
Wed Feb 9 06:54:52 UTC 2022


C code changes for building EDK2 LoongArch platform.

Cc: Bob Feng <bob.c.feng at intel.com>
Cc: Liming Gao <gaoliming at byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen at intel.com>

Signed-off-by: Chao Li <lichao at loongson.cn>
Co-authored-by: Baoqi Zhang <zhangbaoqi at loongson.cn>
---
 BaseTools/Source/C/Common/BasePeCoff.c        |  15 +-
 BaseTools/Source/C/Common/PeCoffLoaderEx.c    |  76 +++++++++
 BaseTools/Source/C/GenFv/GenFvInternalLib.c   | 128 ++++++++++++++-
 BaseTools/Source/C/GenFw/Elf64Convert.c       | 153 +++++++++++++++++-
 BaseTools/Source/C/GenFw/elf_common.h         |  58 +++++++
 .../C/Include/IndustryStandard/PeImage.h      |  57 ++++---
 6 files changed, 454 insertions(+), 33 deletions(-)

diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c
index 62fbb2985c..30400d1341 100644
--- a/BaseTools/Source/C/Common/BasePeCoff.c
+++ b/BaseTools/Source/C/Common/BasePeCoff.c
@@ -5,6 +5,7 @@
 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -68,6 +69,14 @@ PeCoffLoaderRelocateRiscVImage (
   IN UINT64      Adjust
   );
 
+RETURN_STATUS
+PeCoffLoaderRelocateLoongArch64Image (
+  IN UINT16      *Reloc,
+  IN OUT CHAR8   *Fixup,
+  IN OUT CHAR8   **FixupData,
+  IN UINT64      Adjust
+  );
+
 STATIC
 RETURN_STATUS
 PeCoffLoaderGetPeHeader (
@@ -184,7 +193,8 @@ Returns:
       ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \
       ImageContext->Machine != EFI_IMAGE_MACHINE_EBC  && \
       ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \
-      ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {
+      ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64 && \
+      ImageContext->Machine != EFI_IMAGE_MACHINE_LOONGARCH64) {
     if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {
       //
       // There are two types of ARM images. Pure ARM and ARM/Thumb.
@@ -815,6 +825,9 @@ Returns:
         case EFI_IMAGE_MACHINE_RISCV64:
           Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
           break;
+        case EFI_IMAGE_MACHINE_LOONGARCH64:
+          Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust);
+          break;
         default:
           Status = RETURN_UNSUPPORTED;
           break;
diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c
index 799f282970..b50ce8bdef 100644
--- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c
+++ b/BaseTools/Source/C/Common/PeCoffLoaderEx.c
@@ -4,6 +4,7 @@ IA32 and X64 Specific relocation fixups
 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 --*/
@@ -332,3 +333,78 @@ PeCoffLoaderRelocateArmImage (
 
   return RETURN_SUCCESS;
 }
+
+/**
+  Performs a LoongArch specific relocation fixup.
+
+  @param  Reloc       Pointer to the relocation record.
+  @param  Fixup       Pointer to the address to fix up.
+  @param  FixupData   Pointer to a buffer to log the fixups.
+  @param  Adjust      The offset to adjust the fixup.
+
+  @return Status code.
+**/
+RETURN_STATUS
+PeCoffLoaderRelocateLoongArch64Image (
+  IN UINT16      *Reloc,
+  IN OUT CHAR8   *Fixup,
+  IN OUT CHAR8   **FixupData,
+  IN UINT64      Adjust
+  )
+{
+  UINT8  RelocType;
+  UINT64 Value = 0;
+  UINT64 Tmp1 = 0;
+  UINT64 Tmp2 = 0;
+
+  RelocType = ((*Reloc) >> 12);
+
+  switch (RelocType) {
+    case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
+      /* The next four instructions are used to load a 64 bit address, we change it together*/
+      Value = (*(UINT32*)Fixup & 0x1ffffe0) << 7 |       /* lu12i.w 20bits from bit5 */
+              (*((UINT32*)Fixup + 1) & 0x3ffc00) >> 10;  /* ori  12bits from bit10 */
+      Tmp1 = *((UINT32*)Fixup + 2) & 0x1ffffe0;          /* lu32i.d 20bits from bit5 */
+      Tmp2 = *((UINT32*)Fixup + 3) & 0x3ffc00;           /* lu52i.d 12bits from bit10 */
+      Value = Value | (Tmp1 << 27) | (Tmp2 << 42);
+
+      Value += Adjust;
+
+      *(UINT32*)Fixup = (*(UINT32*)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);
+      if (*FixupData != NULL) {
+        *FixupData             = ALIGN_POINTER (*FixupData, sizeof (UINT32));
+        *(UINT32 *) (*FixupData) = *(UINT32*)Fixup;
+        *FixupData             = *FixupData + sizeof (UINT32);
+      }
+
+      Fixup += sizeof(UINT32);
+      *(UINT32*)Fixup = (*(UINT32*)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10);
+      if (*FixupData != NULL) {
+        *FixupData             = ALIGN_POINTER (*FixupData, sizeof (UINT32));
+        *(UINT32 *) (*FixupData) = *(UINT32*)Fixup;
+        *FixupData             = *FixupData + sizeof (UINT32);
+      }
+
+      Fixup += sizeof(UINT32);
+      *(UINT32*)Fixup = (*(UINT32*)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);
+      if (*FixupData != NULL) {
+        *FixupData             = ALIGN_POINTER (*FixupData, sizeof (UINT32));
+        *(UINT32 *) (*FixupData) = *(UINT32*)Fixup;
+        *FixupData             = *FixupData + sizeof (UINT32);
+      }
+
+      Fixup += sizeof(UINT32);
+      *(UINT32*)Fixup = (*(UINT32*)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
+      if (*FixupData != NULL) {
+        *FixupData             = ALIGN_POINTER (*FixupData, sizeof (UINT32));
+        *(UINT32 *) (*FixupData) = *(UINT32*)Fixup;
+        *FixupData             = *FixupData + sizeof (UINT32);
+      }
+      break;
+    default:
+      Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32*)Fixup, Adjust, *Reloc, RelocType);
+      return RETURN_UNSUPPORTED;
+  }
+
+  return RETURN_SUCCESS;
+}
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index d650a527a5..9c518b3609 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -5,6 +5,7 @@ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
 Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -57,6 +58,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 BOOLEAN mArm = FALSE;
 BOOLEAN mRiscV = FALSE;
+BOOLEAN mLoongArch = FALSE;
 STATIC UINT32   MaxFfsAlignment = 0;
 BOOLEAN VtfFileFlag = FALSE;
 
@@ -2416,6 +2418,102 @@ Returns:
   return EFI_SUCCESS;
 }
 
+EFI_STATUS
+UpdateLoongArchResetVectorIfNeeded (
+  IN MEMORY_FILE            *FvImage,
+  IN FV_INFO                *FvInfo
+  )
+/*++
+
+Routine Description:
+  This parses the FV looking for SEC and patches that address into the
+  beginning of the FV header.
+
+  For LoongArch ISA, the reset vector is at 0x1c000000.
+
+  We relocate it to SecCoreEntry and copy the ResetVector code to the
+  beginning of the FV.
+
+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;
+  EFI_FILE_SECTION_POINTER    SecPe32;
+  BOOLEAN                     UpdateVectorSec = FALSE;
+  UINT16                      MachineType = 0;
+  EFI_PHYSICAL_ADDRESS        SecCoreEntryAddress = 0;
+
+  //
+  // Verify input parameters
+  //
+  if (FvImage == NULL || FvInfo == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Locate an SEC Core instance and if found extract the machine type and entry point address
+  //
+  Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
+  if (!EFI_ERROR(Status)) {
+
+    Status = GetCoreMachineType(SecPe32, &MachineType);
+    if (EFI_ERROR(Status)) {
+      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
+      return EFI_ABORTED;
+    }
+
+    Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
+    if (EFI_ERROR(Status)) {
+      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+      return EFI_ABORTED;
+    }
+
+    UpdateVectorSec = TRUE;
+  }
+
+  if (!UpdateVectorSec)
+    return EFI_SUCCESS;
+
+  if (MachineType == EFI_IMAGE_MACHINE_LOONGARCH64) {
+    UINT32                      ResetVector[3];
+    UINT32                      InstrStack;
+
+    memset(ResetVector, 0, sizeof (ResetVector));
+
+    /* if we found an SEC core entry point then generate a branch instruction */
+    if (UpdateVectorSec) {
+      VerboseMsg("UpdateLoongArchResetVectorIfNeeded updating LOONGARCH64 SEC vector");
+
+      InstrStack = (SecCoreEntryAddress >> 12) & 0xfffff;
+      ResetVector[0] = 0x14000001 | (InstrStack << 5);    /* lu12i.w ra si20 */
+
+      InstrStack = (SecCoreEntryAddress & 0x0fff);
+      ResetVector[1] = 0x03800021 | (InstrStack << 10);   /* ori ra, ra, ui12 */
+      ResetVector[2] = 0x4c000021;                        /* jirl ra, ra, 0 */
+    }
+
+    //
+    // Copy to the beginning of the FV
+    //
+    memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));
+  } else {
+    Error(NULL, 0, 3000, "Invalid", "Unknown machine type");
+    return EFI_ABORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
 EFI_STATUS
 GetPe32Info (
   IN UINT8                  *Pe32,
@@ -2509,7 +2607,7 @@ Returns:
   //
   if ((*MachineType != EFI_IMAGE_MACHINE_IA32) &&  (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&
       (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&
-      (*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {
+      (*MachineType != EFI_IMAGE_MACHINE_RISCV64) && (*MachineType != EFI_IMAGE_MACHINE_LOONGARCH64)) {
     Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
     return EFI_UNSUPPORTED;
   }
@@ -2953,7 +3051,7 @@ Returns:
       goto Finish;
     }
 
-    if (!mArm && !mRiscV) {
+    if (!mArm && !mRiscV && !mLoongArch) {
       //
       // Update reset vector (SALE_ENTRY for IPF)
       // Now for IA32 and IA64 platform, the fv which has bsf file must have the
@@ -3004,6 +3102,19 @@ Returns:
     FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
   }
 
+  if (mLoongArch) {
+    Status = UpdateLoongArchResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
+    if (EFI_ERROR (Status)) {
+      Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
+      goto Finish;
+    }
+    //
+    // Update Checksum for FvHeader
+    //
+    FvHeader->Checksum = 0;
+    FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+  }
+
   //
   // Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
   //
@@ -3450,6 +3561,11 @@ Returns:
         VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
         mArm = TRUE;
       }
+      // machine type is LOONGARCH64, set a flag so LOONGARCH64 reset vector procesing occurs
+      if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {
+        VerboseMsg("Located LOONGARCH64 SEC core in child FV");
+        mLoongArch = TRUE;
+      }
     }
 
     //
@@ -3608,6 +3724,10 @@ Returns:
       mRiscV = TRUE;
     }
 
+    if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {
+      mLoongArch = TRUE;
+    }
+
     //
     // Keep Image Context for PE image in FV
     //
@@ -3885,6 +4005,10 @@ Returns:
       mArm = TRUE;
     }
 
+    if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {
+      mLoongArch = TRUE;
+    }
+
     //
     // Keep Image Context for TE image in FV
     //
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index 0bb3ead228..b66aadfd6c 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -4,6 +4,7 @@ Elf64 convert solution
 Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
 Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
 Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -163,7 +164,7 @@ InitializeElf64 (
     Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
     return FALSE;
   }
-  if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {
+  if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64) || (mEhdr->e_machine == EM_LOONGARCH64))) {
     Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");
   }
   if (mEhdr->e_version != EV_CURRENT) {
@@ -730,6 +731,7 @@ ScanSections64 (
   case EM_X86_64:
   case EM_AARCH64:
   case EM_RISCV64:
+  case EM_LOONGARCH64:
     mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
   break;
   default:
@@ -943,6 +945,10 @@ ScanSections64 (
     NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
     NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
     break;
+  case EM_LOONGARCH64:
+    NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_LOONGARCH64;
+    NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+    break;
 
   default:
     VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);
@@ -1149,10 +1155,10 @@ WriteSections64 (
           }
 
           //
-          // Skip error on EM_RISCV64 becasue no symble name is built
-          // from RISC-V toolchain.
+          // Skip error on EM_RISCV64 and EM_LOONGARCH64 becasue no symble name is built
+          // from RISC-V and LoongArch toolchain.
           //
-          if (mEhdr->e_machine != EM_RISCV64) {
+          if ((mEhdr->e_machine != EM_RISCV64) && (mEhdr->e_machine != EM_LOONGARCH64)) {
             Error (NULL, 0, 3000, "Invalid",
                    "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type.  "
                    "For example, absolute and undefined symbols are not supported.",
@@ -1417,6 +1423,74 @@ WriteSections64 (
           // Write section for RISC-V 64 architecture.
           //
           WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
+        } else if (mEhdr->e_machine == EM_LOONGARCH64) {
+          switch (ELF_R_TYPE(Rel->r_info)) {
+
+          case R_LARCH_SOP_PUSH_ABSOLUTE:
+            //
+            // Absolute relocation.
+            //
+            *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+            break;
+
+          case R_LARCH_MARK_LA:
+          case R_LARCH_64:
+          case R_LARCH_NONE:
+          case R_LARCH_32:
+          case R_LARCH_RELATIVE:
+          case R_LARCH_COPY:
+          case R_LARCH_JUMP_SLOT:
+          case R_LARCH_TLS_DTPMOD32:
+          case R_LARCH_TLS_DTPMOD64:
+          case R_LARCH_TLS_DTPREL32:
+          case R_LARCH_TLS_DTPREL64:
+          case R_LARCH_TLS_TPREL32:
+          case R_LARCH_TLS_TPREL64:
+          case R_LARCH_IRELATIVE:
+          case R_LARCH_MARK_PCREL:
+          case R_LARCH_SOP_PUSH_PCREL:
+          case R_LARCH_SOP_PUSH_DUP:
+          case R_LARCH_SOP_PUSH_GPREL:
+          case R_LARCH_SOP_PUSH_TLS_TPREL:
+          case R_LARCH_SOP_PUSH_TLS_GOT:
+          case R_LARCH_SOP_PUSH_TLS_GD:
+          case R_LARCH_SOP_PUSH_PLT_PCREL:
+          case R_LARCH_SOP_ASSERT:
+          case R_LARCH_SOP_NOT:
+          case R_LARCH_SOP_SUB:
+          case R_LARCH_SOP_SL:
+          case R_LARCH_SOP_SR:
+          case R_LARCH_SOP_ADD:
+          case R_LARCH_SOP_AND:
+          case R_LARCH_SOP_IF_ELSE:
+          case R_LARCH_SOP_POP_32_S_10_5:
+          case R_LARCH_SOP_POP_32_U_10_12:
+          case R_LARCH_SOP_POP_32_S_10_12:
+          case R_LARCH_SOP_POP_32_S_10_16:
+          case R_LARCH_SOP_POP_32_S_10_16_S2:
+          case R_LARCH_SOP_POP_32_S_5_20:
+          case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
+          case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
+          case R_LARCH_SOP_POP_32_U:
+          case R_LARCH_ADD8:
+          case R_LARCH_ADD16:
+          case R_LARCH_ADD24:
+          case R_LARCH_ADD32:
+          case R_LARCH_ADD64:
+          case R_LARCH_SUB8:
+          case R_LARCH_SUB16:
+          case R_LARCH_SUB24:
+          case R_LARCH_SUB32:
+          case R_LARCH_SUB64:
+          case R_LARCH_GNU_VTINHERIT:
+          case R_LARCH_GNU_VTENTRY:
+            //
+            // These types are not used or do not need to fix the offsets.
+            //
+            break;
+          default:
+            Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_LOONGARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));
+          }
         } else {
           Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
         }
@@ -1647,6 +1721,77 @@ WriteRelocations64 (
             default:
               Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
             }
+          } else if (mEhdr->e_machine == EM_LOONGARCH64) {
+            switch (ELF_R_TYPE(Rel->r_info)) {
+              case R_LARCH_MARK_LA:
+                CoffAddFixup(
+                  (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+                  + (Rel->r_offset - SecShdr->sh_addr)),
+                  EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA);
+                break;
+              case R_LARCH_64:
+                CoffAddFixup(
+                  (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+                  + (Rel->r_offset - SecShdr->sh_addr)),
+                  EFI_IMAGE_REL_BASED_DIR64);
+                break;
+              case R_LARCH_NONE:
+              case R_LARCH_32:
+              case R_LARCH_RELATIVE:
+              case R_LARCH_COPY:
+              case R_LARCH_JUMP_SLOT:
+              case R_LARCH_TLS_DTPMOD32:
+              case R_LARCH_TLS_DTPMOD64:
+              case R_LARCH_TLS_DTPREL32:
+              case R_LARCH_TLS_DTPREL64:
+              case R_LARCH_TLS_TPREL32:
+              case R_LARCH_TLS_TPREL64:
+              case R_LARCH_IRELATIVE:
+              case R_LARCH_MARK_PCREL:
+              case R_LARCH_SOP_PUSH_PCREL:
+              case R_LARCH_SOP_PUSH_ABSOLUTE:
+              case R_LARCH_SOP_PUSH_DUP:
+              case R_LARCH_SOP_PUSH_GPREL:
+              case R_LARCH_SOP_PUSH_TLS_TPREL:
+              case R_LARCH_SOP_PUSH_TLS_GOT:
+              case R_LARCH_SOP_PUSH_TLS_GD:
+              case R_LARCH_SOP_PUSH_PLT_PCREL:
+              case R_LARCH_SOP_ASSERT:
+              case R_LARCH_SOP_NOT:
+              case R_LARCH_SOP_SUB:
+              case R_LARCH_SOP_SL:
+              case R_LARCH_SOP_SR:
+              case R_LARCH_SOP_ADD:
+              case R_LARCH_SOP_AND:
+              case R_LARCH_SOP_IF_ELSE:
+              case R_LARCH_SOP_POP_32_S_10_5:
+              case R_LARCH_SOP_POP_32_U_10_12:
+              case R_LARCH_SOP_POP_32_S_10_12:
+              case R_LARCH_SOP_POP_32_S_10_16:
+              case R_LARCH_SOP_POP_32_S_10_16_S2:
+              case R_LARCH_SOP_POP_32_S_5_20:
+              case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
+              case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
+              case R_LARCH_SOP_POP_32_U:
+              case R_LARCH_ADD8:
+              case R_LARCH_ADD16:
+              case R_LARCH_ADD24:
+              case R_LARCH_ADD32:
+              case R_LARCH_ADD64:
+              case R_LARCH_SUB8:
+              case R_LARCH_SUB16:
+              case R_LARCH_SUB24:
+              case R_LARCH_SUB32:
+              case R_LARCH_SUB64:
+              case R_LARCH_GNU_VTINHERIT:
+              case R_LARCH_GNU_VTENTRY:
+                //
+                // These types are not used or do not require fixup in PE format files.
+                //
+                break;
+              default:
+                  Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_LOONGARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));
+            }
           } else {
             Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
           }
diff --git a/BaseTools/Source/C/GenFw/elf_common.h b/BaseTools/Source/C/GenFw/elf_common.h
index b67f59e7a0..34c8748f39 100644
--- a/BaseTools/Source/C/GenFw/elf_common.h
+++ b/BaseTools/Source/C/GenFw/elf_common.h
@@ -4,6 +4,7 @@ Ported ELF include files from FreeBSD
 Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
 Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 
@@ -181,6 +182,7 @@ typedef struct {
 #define EM_AARCH64  183  /* ARM 64bit Architecture */
 #define EM_RISCV64  243 /* 64bit RISC-V Architecture */
 #define EM_RISCV    244 /* 32bit RISC-V Architecture */
+#define EM_LOONGARCH64 258 /* LoongArch 64-bit Architecture */
 
 /* Non-standard or deprecated. */
 #define EM_486    6  /* Intel i486. */
@@ -1042,4 +1044,60 @@ typedef struct {
 #define R_RISCV_SET8            54
 #define R_RISCV_SET16           55
 #define R_RISCV_SET32           56
+
+/*
+ * LoongArch relocation types
+ */
+#define R_LARCH_NONE                       0
+#define R_LARCH_32                         1
+#define R_LARCH_64                         2
+#define R_LARCH_RELATIVE                   3
+#define R_LARCH_COPY                       4
+#define R_LARCH_JUMP_SLOT                  5
+#define R_LARCH_TLS_DTPMOD32               6
+#define R_LARCH_TLS_DTPMOD64               7
+#define R_LARCH_TLS_DTPREL32               8
+#define R_LARCH_TLS_DTPREL64               9
+#define R_LARCH_TLS_TPREL32                10
+#define R_LARCH_TLS_TPREL64                11
+#define R_LARCH_IRELATIVE                  12
+#define R_LARCH_MARK_LA                    20
+#define R_LARCH_MARK_PCREL                 21
+#define R_LARCH_SOP_PUSH_PCREL             22
+#define R_LARCH_SOP_PUSH_ABSOLUTE          23
+#define R_LARCH_SOP_PUSH_DUP               24
+#define R_LARCH_SOP_PUSH_GPREL             25
+#define R_LARCH_SOP_PUSH_TLS_TPREL         26
+#define R_LARCH_SOP_PUSH_TLS_GOT           27
+#define R_LARCH_SOP_PUSH_TLS_GD            28
+#define R_LARCH_SOP_PUSH_PLT_PCREL         29
+#define R_LARCH_SOP_ASSERT                 30
+#define R_LARCH_SOP_NOT                    31
+#define R_LARCH_SOP_SUB                    32
+#define R_LARCH_SOP_SL                     33
+#define R_LARCH_SOP_SR                     34
+#define R_LARCH_SOP_ADD                    35
+#define R_LARCH_SOP_AND                    36
+#define R_LARCH_SOP_IF_ELSE                37
+#define R_LARCH_SOP_POP_32_S_10_5          38
+#define R_LARCH_SOP_POP_32_U_10_12         39
+#define R_LARCH_SOP_POP_32_S_10_12         40
+#define R_LARCH_SOP_POP_32_S_10_16         41
+#define R_LARCH_SOP_POP_32_S_10_16_S2      42
+#define R_LARCH_SOP_POP_32_S_5_20          43
+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2  44
+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45
+#define R_LARCH_SOP_POP_32_U               46
+#define R_LARCH_ADD8                       47
+#define R_LARCH_ADD16                      48
+#define R_LARCH_ADD24                      49
+#define R_LARCH_ADD32                      50
+#define R_LARCH_ADD64                      51
+#define R_LARCH_SUB8                       52
+#define R_LARCH_SUB16                      53
+#define R_LARCH_SUB24                      54
+#define R_LARCH_SUB32                      55
+#define R_LARCH_SUB64                      56
+#define R_LARCH_GNU_VTINHERIT              57
+#define R_LARCH_GNU_VTENTRY                58
 #endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
index f17b8ee19b..80961e5576 100644
--- a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
+++ b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
@@ -7,6 +7,7 @@
   Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
   Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
   Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+  Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -36,23 +37,25 @@
 //
 // PE32+ Machine type for EFI images
 //
-#define IMAGE_FILE_MACHINE_I386     0x014c
-#define IMAGE_FILE_MACHINE_EBC      0x0EBC
-#define IMAGE_FILE_MACHINE_X64      0x8664
-#define IMAGE_FILE_MACHINE_ARM      0x01c0  // Thumb only
-#define IMAGE_FILE_MACHINE_ARMT     0x01c2  // 32bit Mixed ARM and Thumb/Thumb 2  Little Endian
-#define IMAGE_FILE_MACHINE_ARM64    0xAA64  // 64bit ARM Architecture, Little Endian
-#define IMAGE_FILE_MACHINE_RISCV64  0x5064  // 64bit RISC-V ISA
+#define IMAGE_FILE_MACHINE_I386        0x014c
+#define IMAGE_FILE_MACHINE_EBC         0x0EBC
+#define IMAGE_FILE_MACHINE_X64         0x8664
+#define IMAGE_FILE_MACHINE_ARM         0x01c0  // Thumb only
+#define IMAGE_FILE_MACHINE_ARMT        0x01c2  // 32bit Mixed ARM and Thumb/Thumb 2  Little Endian
+#define IMAGE_FILE_MACHINE_ARM64       0xAA64  // 64bit ARM Architecture, Little Endian
+#define IMAGE_FILE_MACHINE_RISCV64     0x5064  // 64bit RISC-V ISA
+#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264  // 64bit LoongArch Architecture
 
 //
 // Support old names for backward compatible
 //
-#define EFI_IMAGE_MACHINE_IA32      IMAGE_FILE_MACHINE_I386
-#define EFI_IMAGE_MACHINE_EBC       IMAGE_FILE_MACHINE_EBC
-#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
+#define EFI_IMAGE_MACHINE_IA32        IMAGE_FILE_MACHINE_I386
+#define EFI_IMAGE_MACHINE_EBC         IMAGE_FILE_MACHINE_EBC
+#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
+#define EFI_IMAGE_MACHINE_LOONGARCH64 IMAGE_FILE_MACHINE_LOONGARCH64
 
 #define EFI_IMAGE_DOS_SIGNATURE     0x5A4D      // MZ
 #define EFI_IMAGE_OS2_SIGNATURE     0x454E      // NE
@@ -500,19 +503,21 @@ typedef struct {
 //
 // Based relocation types.
 //
-#define EFI_IMAGE_REL_BASED_ABSOLUTE      0
-#define EFI_IMAGE_REL_BASED_HIGH          1
-#define EFI_IMAGE_REL_BASED_LOW           2
-#define EFI_IMAGE_REL_BASED_HIGHLOW       3
-#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
+#define EFI_IMAGE_REL_BASED_ABSOLUTE            0
+#define EFI_IMAGE_REL_BASED_HIGH                1
+#define EFI_IMAGE_REL_BASED_LOW                 2
+#define EFI_IMAGE_REL_BASED_HIGHLOW             3
+#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_LOONGARCH32_MARK_LA 8
+#define EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA 8
+#define EFI_IMAGE_REL_BASED_IA64_IMM64          9
+#define EFI_IMAGE_REL_BASED_DIR64               10
 
 
 ///
-- 
2.27.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#86503): https://edk2.groups.io/g/devel/message/86503
Mute This Topic: https://groups.io/mt/89016983/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list