public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch platform.
@ 2022-09-14  9:40 Chao Li
  2022-09-15  6:27 ` 回复: " gaoliming
  0 siblings, 1 reply; 3+ messages in thread
From: Chao Li @ 2022-09-14  9:40 UTC (permalink / raw)
  To: devel
  Cc: Bob Feng, Liming Gao, Yuwei Chen, Dongyan Qian, Baoqi Zhang,
	Yang Zhou, Xiaotian Wu

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053

C code changes for building EDK2 LoongArch platform.

For definitions of PE/COFF and LOONGARCH relocation types, see the
"Machine Types" and "Basic Relocation Types" sections of this URL for
LOONGARCH values:
https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

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

Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Dongyan Qian <qiandongyan@loongson.cn>
Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn>
Co-authored-by: Yang Zhou <zhouyang@loongson.cn>
Co-authored-by: Xiaotian Wu <wuxiaotian@loongson.cn>
---
 BaseTools/Source/C/Common/BasePeCoff.c        |  15 +-
 BaseTools/Source/C/Common/PeCoffLoaderEx.c    |  79 +++++
 BaseTools/Source/C/GenFv/GenFvInternalLib.c   | 125 +++++++-
 BaseTools/Source/C/GenFw/Elf64Convert.c       | 293 +++++++++++++++++-
 BaseTools/Source/C/GenFw/elf_common.h         |  94 ++++++
 .../C/Include/IndustryStandard/PeImage.h      |  57 ++--
 BaseTools/Source/C/Makefiles/header.makefile  |   6 +
 7 files changed, 636 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..2cc428d733 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,81 @@ PeCoffLoaderRelocateArmImage (
 
   return RETURN_SUCCESS;
 }
+
+/**
+  Performs a LoongArch specific relocation fixup.
+
+  @param[in]       Reloc       Pointer to the relocation record.
+  @param[in, out]  Fixup       Pointer to the address to fix up.
+  @param[in, out]  FixupData   Pointer to a buffer to log the fixups.
+  @param[in]       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;
+  UINT64 Tmp1;
+  UINT64 Tmp2;
+
+  RelocType = ((*Reloc) >> 12);
+  Value     = 0;
+  Tmp1      = 0;
+  Tmp2      = 0;
+
+  switch (RelocType) {
+    case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
+      // The next four instructions are used to load a 64 bit address, relocate all of them
+      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..575b99b6ad 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,98 @@ 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[1];
+
+    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");
+
+      ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) & 0x3FFFFFF) >> 2;
+      ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) | ((ResetVector[0] >> 16) & 0x3FF);
+      ResetVector[0] |= 0x54000000; /* bl offset */
+    }
+
+    //
+    // 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 +2603,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 +3047,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 +3098,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 +3557,12 @@ Returns:
         VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
         mArm = TRUE;
       }
+
+      // Machine type is LOONGARCH64, set a flag so LoongArch64 reset vector processed.
+      if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {
+        VerboseMsg("Located LoongArch64 SEC core in child FV");
+        mLoongArch = TRUE;
+      }
     }
 
     //
@@ -3608,6 +3721,10 @@ Returns:
       mRiscV = TRUE;
     }
 
+    if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {
+      mLoongArch = TRUE;
+    }
+
     //
     // Keep Image Context for PE image in FV
     //
@@ -3885,6 +4002,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 ca3c8f8bee..ede2f0ef90 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-2022, 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
 
@@ -177,7 +178,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_LOONGARCH))) {
     Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");
   }
   if (mEhdr->e_version != EV_CURRENT) {
@@ -799,6 +800,7 @@ ScanSections64 (
   case EM_X86_64:
   case EM_AARCH64:
   case EM_RISCV64:
+  case EM_LOONGARCH:
     mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
   break;
   default:
@@ -1088,6 +1090,10 @@ ScanSections64 (
     NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
     NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
     break;
+  case EM_LOONGARCH:
+    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);
@@ -1333,10 +1339,10 @@ WriteSections64 (
           }
 
           //
-          // Skip error on EM_RISCV64 becasue no symble name is built
-          // from RISC-V toolchain.
+          // Skip error on EM_RISCV64 and EM_LOONGARCH because no symbol 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_LOONGARCH)) {
             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.",
@@ -1618,6 +1624,178 @@ WriteSections64 (
           // Write section for RISC-V 64 architecture.
           //
           WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
+        } else if (mEhdr->e_machine == EM_LOONGARCH) {
+          switch (ELF_R_TYPE(Rel->r_info)) {
+            INT64 Offset;
+            INT32 Lo, Hi;
+
+          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:
+          case R_LARCH_B16:
+          case R_LARCH_B21:
+          case R_LARCH_B26:
+          case R_LARCH_ABS_HI20:
+          case R_LARCH_ABS_LO12:
+          case R_LARCH_ABS64_LO20:
+          case R_LARCH_ABS64_HI12:
+          case R_LARCH_PCALA_LO12:
+          case R_LARCH_PCALA64_LO20:
+          case R_LARCH_PCALA64_HI12:
+          case R_LARCH_GOT_PC_LO12:
+          case R_LARCH_GOT64_PC_LO20:
+          case R_LARCH_GOT64_PC_HI12:
+          case R_LARCH_GOT64_HI20:
+          case R_LARCH_GOT64_LO12:
+          case R_LARCH_GOT64_LO20:
+          case R_LARCH_GOT64_HI12:
+          case R_LARCH_TLS_LE_HI20:
+          case R_LARCH_TLS_LE_LO12:
+          case R_LARCH_TLS_LE64_LO20:
+          case R_LARCH_TLS_LE64_HI12:
+          case R_LARCH_TLS_IE_PC_HI20:
+          case R_LARCH_TLS_IE_PC_LO12:
+          case R_LARCH_TLS_IE64_PC_LO20:
+          case R_LARCH_TLS_IE64_PC_HI12:
+          case R_LARCH_TLS_IE64_HI20:
+          case R_LARCH_TLS_IE64_LO12:
+          case R_LARCH_TLS_IE64_LO20:
+          case R_LARCH_TLS_IE64_HI12:
+          case R_LARCH_TLS_LD_PC_HI20:
+          case R_LARCH_TLS_LD64_HI20:
+          case R_LARCH_TLS_GD_PC_HI20:
+          case R_LARCH_TLS_GD64_HI20:
+          case R_LARCH_RELAX:
+            //
+            // These types are not used or do not require fixup.
+            //
+            break;
+
+          case R_LARCH_GOT_PC_HI20:
+            Offset = Sym->st_value - (UINTN)(Targ - mCoffFile);
+            if (Offset < 0) {
+              Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value;
+              Hi = (Offset / 0x1000) << 12;
+              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
+              if ((Lo < 0) && (Lo > -2048)) {
+                Hi += 0x1000;
+                Lo = ~(0x1000 - Lo) + 1;
+              }
+              Hi = ~Hi + 1;
+              Lo = ~Lo + 1;
+            } else {
+              Hi = (Offset / 0x1000) << 12;
+              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
+              if (Lo < 0) {
+                Hi += 0x1000;
+                Lo = ~(0x1000 - Lo) + 1;
+              }
+            }
+            // Re-encode the offset as an PCADD.D + ADDI.D(Convert LD.D) instruction
+            *(UINT32 *)Targ &= 0x1f;
+            *(UINT32 *)Targ |= 0x1c000000;
+            *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
+            *(UINT32 *)(Targ + 4) &= 0x3ff;
+            *(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10);
+            break;
+
+          //
+          // Attempt to convert instruction.
+          //
+          case R_LARCH_PCALA_HI20:
+            // Decode the PCALAU12I + ADDI.D instruction
+            Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7));
+            Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10) >> 20);
+            //
+            // PCALA offset is relative to the previous page boundary,
+            // whereas PCADD offset is relative to the instruction itself.
+            // So fix up the offset so it points to the page containing
+            // the symbol.
+            //
+            Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;
+            if (Offset < 0) {
+              Offset = -Offset;
+              Hi = (Offset / 0x1000) << 12;
+              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
+              if ((Lo < 0) && (Lo > -2048)) {
+                Hi += 0x1000;
+                Lo = ~(0x1000 - Lo) + 1;
+              }
+              Hi = ~Hi + 1;
+              Lo = ~Lo + 1;
+            } else {
+              Hi = (Offset / 0x1000) << 12;
+              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
+              if (Lo < 0) {
+                Hi += 0x1000;
+                Lo = ~(0x1000 - Lo) + 1;
+              }
+            }
+            // Re-encode the offset as an PCADD.D + ADDI.D instruction
+            *(UINT32 *)Targ &= 0x1f;
+            *(UINT32 *)Targ |= 0x1c000000;
+            *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
+            *(UINT32 *)(Targ + 4) &= 0xffc003ff;
+            *(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10;
+            break;
+          default:
+            Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));
+          }
         } else {
           Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
         }
@@ -1850,6 +2028,113 @@ 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_LOONGARCH) {
+            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:
+              case R_LARCH_B16:
+              case R_LARCH_B21:
+              case R_LARCH_B26:
+              case R_LARCH_ABS_HI20:
+              case R_LARCH_ABS_LO12:
+              case R_LARCH_ABS64_LO20:
+              case R_LARCH_ABS64_HI12:
+              case R_LARCH_PCALA_HI20:
+              case R_LARCH_PCALA_LO12:
+              case R_LARCH_PCALA64_LO20:
+              case R_LARCH_PCALA64_HI12:
+              case R_LARCH_GOT_PC_HI20:
+              case R_LARCH_GOT_PC_LO12:
+              case R_LARCH_GOT64_PC_LO20:
+              case R_LARCH_GOT64_PC_HI12:
+              case R_LARCH_GOT64_HI20:
+              case R_LARCH_GOT64_LO12:
+              case R_LARCH_GOT64_LO20:
+              case R_LARCH_GOT64_HI12:
+              case R_LARCH_TLS_LE_HI20:
+              case R_LARCH_TLS_LE_LO12:
+              case R_LARCH_TLS_LE64_LO20:
+              case R_LARCH_TLS_LE64_HI12:
+              case R_LARCH_TLS_IE_PC_HI20:
+              case R_LARCH_TLS_IE_PC_LO12:
+              case R_LARCH_TLS_IE64_PC_LO20:
+              case R_LARCH_TLS_IE64_PC_HI12:
+              case R_LARCH_TLS_IE64_HI20:
+              case R_LARCH_TLS_IE64_LO12:
+              case R_LARCH_TLS_IE64_LO20:
+              case R_LARCH_TLS_IE64_HI12:
+              case R_LARCH_TLS_LD_PC_HI20:
+              case R_LARCH_TLS_LD64_HI20:
+              case R_LARCH_TLS_GD_PC_HI20:
+              case R_LARCH_TLS_GD64_HI20:
+              case R_LARCH_RELAX:
+                //
+                // 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_LOONGARCH 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..7b7fdeb329 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_LOONGARCH 258 /* LoongArch Architecture */
 
 /* Non-standard or deprecated. */
 #define EM_486    6  /* Intel i486. */
@@ -1042,4 +1044,96 @@ 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
+#define R_LARCH_B16                        64
+#define R_LARCH_B21                        65
+#define R_LARCH_B26                        66
+#define R_LARCH_ABS_HI20                   67
+#define R_LARCH_ABS_LO12                   68
+#define R_LARCH_ABS64_LO20                 69
+#define R_LARCH_ABS64_HI12                 70
+#define R_LARCH_PCALA_HI20                 71
+#define R_LARCH_PCALA_LO12                 72
+#define R_LARCH_PCALA64_LO20               73
+#define R_LARCH_PCALA64_HI12               74
+#define R_LARCH_GOT_PC_HI20                75
+#define R_LARCH_GOT_PC_LO12                76
+#define R_LARCH_GOT64_PC_LO20              77
+#define R_LARCH_GOT64_PC_HI12              78
+#define R_LARCH_GOT64_HI20                 79
+#define R_LARCH_GOT64_LO12                 80
+#define R_LARCH_GOT64_LO20                 81
+#define R_LARCH_GOT64_HI12                 82
+#define R_LARCH_TLS_LE_HI20                83
+#define R_LARCH_TLS_LE_LO12                84
+#define R_LARCH_TLS_LE64_LO20              85
+#define R_LARCH_TLS_LE64_HI12              86
+#define R_LARCH_TLS_IE_PC_HI20             87
+#define R_LARCH_TLS_IE_PC_LO12             88
+#define R_LARCH_TLS_IE64_PC_LO20           89
+#define R_LARCH_TLS_IE64_PC_HI12           90
+#define R_LARCH_TLS_IE64_HI20              91
+#define R_LARCH_TLS_IE64_LO12              92
+#define R_LARCH_TLS_IE64_LO20              93
+#define R_LARCH_TLS_IE64_HI12              94
+#define R_LARCH_TLS_LD_PC_HI20             95
+#define R_LARCH_TLS_LD64_HI20              96
+#define R_LARCH_TLS_GD_PC_HI20             97
+#define R_LARCH_TLS_GD64_HI20              98
+#define R_LARCH_RELAX                      99
 #endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
index 21c968e650..77ded3f611 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
 
 
 ///
diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile
index 0df728f327..4e88a4fbd8 100644
--- a/BaseTools/Source/C/Makefiles/header.makefile
+++ b/BaseTools/Source/C/Makefiles/header.makefile
@@ -31,6 +31,9 @@ ifndef HOST_ARCH
   ifneq (,$(findstring riscv64,$(uname_m)))
     HOST_ARCH=RISCV64
   endif
+  ifneq (,$(findstring loongarch64,$(uname_m)))
+    HOST_ARCH=LOONGARCH64
+  endif
   ifndef HOST_ARCH
     $(info Could not detected HOST_ARCH from uname results)
     $(error HOST_ARCH is not defined!)
@@ -70,6 +73,9 @@ ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
 else ifeq ($(HOST_ARCH), RISCV64)
 ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/
 
+else ifeq ($(HOST_ARCH), LOONGARCH64)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/LoongArch64/
+
 else
 $(error Bad HOST_ARCH)
 endif
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* 回复: [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch platform.
  2022-09-14  9:40 [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch platform Chao Li
@ 2022-09-15  6:27 ` gaoliming
  2022-09-15  7:20   ` [edk2-devel] 回复: PATCH " Chao Li
  0 siblings, 1 reply; 3+ messages in thread
From: gaoliming @ 2022-09-15  6:27 UTC (permalink / raw)
  To: 'Chao Li', devel
  Cc: 'Bob Feng', 'Yuwei Chen', 'Dongyan Qian',
	'Baoqi Zhang', 'Yang Zhou', 'Xiaotian Wu'

Chao:
  This change is for BaseTools C tools . The commit message can be
BaseTools: Update GenFw/GenFv to support LoongArch platform.

  The code change is good to me. Reviewed-by: Liming Gao <gaoliming@byosoft.
com.cn>

Thanks
Liming
> -----邮件原件-----
> 发件人: Chao Li <lichao@loongson.cn>
> 发送时间: 2022年9月14日 17:40
> 收件人: devel@edk2.groups.io
> 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Yuwei Chen <yuwei.chen@intel.com>;
> Dongyan Qian <qiandongyan@loongson.cn>; Baoqi Zhang
> <zhangbaoqi@loongson.cn>; Yang Zhou <zhouyang@loongson.cn>; Xiaotian
> Wu <wuxiaotian@loongson.cn>
> 主题: [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch
> platform.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053
> 
> C code changes for building EDK2 LoongArch platform.
> 
> For definitions of PE/COFF and LOONGARCH relocation types, see the
> "Machine Types" and "Basic Relocation Types" sections of this URL for
> LOONGARCH values:
> https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
> 
> Cc: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Yuwei Chen <yuwei.chen@intel.com>
> 
> Signed-off-by: Chao Li <lichao@loongson.cn>
> Co-authored-by: Dongyan Qian <qiandongyan@loongson.cn>
> Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn>
> Co-authored-by: Yang Zhou <zhouyang@loongson.cn>
> Co-authored-by: Xiaotian Wu <wuxiaotian@loongson.cn>
> ---
>  BaseTools/Source/C/Common/BasePeCoff.c        |  15 +-
>  BaseTools/Source/C/Common/PeCoffLoaderEx.c    |  79 +++++
>  BaseTools/Source/C/GenFv/GenFvInternalLib.c   | 125 +++++++-
>  BaseTools/Source/C/GenFw/Elf64Convert.c       | 293
> +++++++++++++++++-
>  BaseTools/Source/C/GenFw/elf_common.h         |  94 ++++++
>  .../C/Include/IndustryStandard/PeImage.h      |  57 ++--
>  BaseTools/Source/C/Makefiles/header.makefile  |   6 +
>  7 files changed, 636 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..2cc428d733 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,81 @@ PeCoffLoaderRelocateArmImage (
> 
> 
>    return RETURN_SUCCESS;
> 
>  }
> 
> +
> 
> +/**
> 
> +  Performs a LoongArch specific relocation fixup.
> 
> +
> 
> +  @param[in]       Reloc       Pointer to the relocation record.
> 
> +  @param[in, out]  Fixup       Pointer to the address to fix up.
> 
> +  @param[in, out]  FixupData   Pointer to a buffer to log the fixups.
> 
> +  @param[in]       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;
> 
> +  UINT64 Tmp1;
> 
> +  UINT64 Tmp2;
> 
> +
> 
> +  RelocType = ((*Reloc) >> 12);
> 
> +  Value     = 0;
> 
> +  Tmp1      = 0;
> 
> +  Tmp2      = 0;
> 
> +
> 
> +  switch (RelocType) {
> 
> +    case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
> 
> +      // The next four instructions are used to load a 64 bit address,
> relocate all of them
> 
> +      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..575b99b6ad 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,98 @@ 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[1];
> 
> +
> 
> +    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");
> 
> +
> 
> +      ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) &
> 0x3FFFFFF) >> 2;
> 
> +      ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) |
> ((ResetVector[0] >> 16) & 0x3FF);
> 
> +      ResetVector[0] |= 0x54000000; /* bl offset */
> 
> +    }
> 
> +
> 
> +    //
> 
> +    // 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 +2603,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 +3047,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 +3098,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 +3557,12 @@ Returns:
>          VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
> 
>          mArm = TRUE;
> 
>        }
> 
> +
> 
> +      // Machine type is LOONGARCH64, set a flag so LoongArch64 reset
> vector processed.
> 
> +      if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {
> 
> +        VerboseMsg("Located LoongArch64 SEC core in child FV");
> 
> +        mLoongArch = TRUE;
> 
> +      }
> 
>      }
> 
> 
> 
>      //
> 
> @@ -3608,6 +3721,10 @@ Returns:
>        mRiscV = TRUE;
> 
>      }
> 
> 
> 
> +    if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) )
> {
> 
> +      mLoongArch = TRUE;
> 
> +    }
> 
> +
> 
>      //
> 
>      // Keep Image Context for PE image in FV
> 
>      //
> 
> @@ -3885,6 +4002,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 ca3c8f8bee..ede2f0ef90 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-2022, 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
> 
> 
> 
> @@ -177,7 +178,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_LOONGARCH))) {
> 
>      Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64
> machine.");
> 
>    }
> 
>    if (mEhdr->e_version != EV_CURRENT) {
> 
> @@ -799,6 +800,7 @@ ScanSections64 (
>    case EM_X86_64:
> 
>    case EM_AARCH64:
> 
>    case EM_RISCV64:
> 
> +  case EM_LOONGARCH:
> 
>      mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
> 
>    break;
> 
>    default:
> 
> @@ -1088,6 +1090,10 @@ ScanSections64 (
>      NtHdr->Pe32Plus.FileHeader.Machine =
> EFI_IMAGE_MACHINE_RISCV64;
> 
>      NtHdr->Pe32Plus.OptionalHeader.Magic =
> EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
> 
>      break;
> 
> +  case EM_LOONGARCH:
> 
> +    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);
> 
> @@ -1333,10 +1339,10 @@ WriteSections64 (
>            }
> 
> 
> 
>            //
> 
> -          // Skip error on EM_RISCV64 becasue no symble name is built
> 
> -          // from RISC-V toolchain.
> 
> +          // Skip error on EM_RISCV64 and EM_LOONGARCH because no
> symbol 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_LOONGARCH)) {
> 
>              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.",
> 
> @@ -1618,6 +1624,178 @@ WriteSections64 (
>            // Write section for RISC-V 64 architecture.
> 
>            //
> 
>            WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
> 
> +        } else if (mEhdr->e_machine == EM_LOONGARCH) {
> 
> +          switch (ELF_R_TYPE(Rel->r_info)) {
> 
> +            INT64 Offset;
> 
> +            INT32 Lo, Hi;
> 
> +
> 
> +          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:
> 
> +          case R_LARCH_B16:
> 
> +          case R_LARCH_B21:
> 
> +          case R_LARCH_B26:
> 
> +          case R_LARCH_ABS_HI20:
> 
> +          case R_LARCH_ABS_LO12:
> 
> +          case R_LARCH_ABS64_LO20:
> 
> +          case R_LARCH_ABS64_HI12:
> 
> +          case R_LARCH_PCALA_LO12:
> 
> +          case R_LARCH_PCALA64_LO20:
> 
> +          case R_LARCH_PCALA64_HI12:
> 
> +          case R_LARCH_GOT_PC_LO12:
> 
> +          case R_LARCH_GOT64_PC_LO20:
> 
> +          case R_LARCH_GOT64_PC_HI12:
> 
> +          case R_LARCH_GOT64_HI20:
> 
> +          case R_LARCH_GOT64_LO12:
> 
> +          case R_LARCH_GOT64_LO20:
> 
> +          case R_LARCH_GOT64_HI12:
> 
> +          case R_LARCH_TLS_LE_HI20:
> 
> +          case R_LARCH_TLS_LE_LO12:
> 
> +          case R_LARCH_TLS_LE64_LO20:
> 
> +          case R_LARCH_TLS_LE64_HI12:
> 
> +          case R_LARCH_TLS_IE_PC_HI20:
> 
> +          case R_LARCH_TLS_IE_PC_LO12:
> 
> +          case R_LARCH_TLS_IE64_PC_LO20:
> 
> +          case R_LARCH_TLS_IE64_PC_HI12:
> 
> +          case R_LARCH_TLS_IE64_HI20:
> 
> +          case R_LARCH_TLS_IE64_LO12:
> 
> +          case R_LARCH_TLS_IE64_LO20:
> 
> +          case R_LARCH_TLS_IE64_HI12:
> 
> +          case R_LARCH_TLS_LD_PC_HI20:
> 
> +          case R_LARCH_TLS_LD64_HI20:
> 
> +          case R_LARCH_TLS_GD_PC_HI20:
> 
> +          case R_LARCH_TLS_GD64_HI20:
> 
> +          case R_LARCH_RELAX:
> 
> +            //
> 
> +            // These types are not used or do not require fixup.
> 
> +            //
> 
> +            break;
> 
> +
> 
> +          case R_LARCH_GOT_PC_HI20:
> 
> +            Offset = Sym->st_value - (UINTN)(Targ - mCoffFile);
> 
> +            if (Offset < 0) {
> 
> +              Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value;
> 
> +              Hi = (Offset / 0x1000) << 12;
> 
> +              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> 
> +              if ((Lo < 0) && (Lo > -2048)) {
> 
> +                Hi += 0x1000;
> 
> +                Lo = ~(0x1000 - Lo) + 1;
> 
> +              }
> 
> +              Hi = ~Hi + 1;
> 
> +              Lo = ~Lo + 1;
> 
> +            } else {
> 
> +              Hi = (Offset / 0x1000) << 12;
> 
> +              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> 
> +              if (Lo < 0) {
> 
> +                Hi += 0x1000;
> 
> +                Lo = ~(0x1000 - Lo) + 1;
> 
> +              }
> 
> +            }
> 
> +            // Re-encode the offset as an PCADD.D + ADDI.D(Convert
> LD.D) instruction
> 
> +            *(UINT32 *)Targ &= 0x1f;
> 
> +            *(UINT32 *)Targ |= 0x1c000000;
> 
> +            *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
> 
> +            *(UINT32 *)(Targ + 4) &= 0x3ff;
> 
> +            *(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10);
> 
> +            break;
> 
> +
> 
> +          //
> 
> +          // Attempt to convert instruction.
> 
> +          //
> 
> +          case R_LARCH_PCALA_HI20:
> 
> +            // Decode the PCALAU12I + ADDI.D instruction
> 
> +            Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7));
> 
> +            Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10)
>>
> 20);
> 
> +            //
> 
> +            // PCALA offset is relative to the previous page boundary,
> 
> +            // whereas PCADD offset is relative to the instruction
itself.
> 
> +            // So fix up the offset so it points to the page containing
> 
> +            // the symbol.
> 
> +            //
> 
> +            Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;
> 
> +            if (Offset < 0) {
> 
> +              Offset = -Offset;
> 
> +              Hi = (Offset / 0x1000) << 12;
> 
> +              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> 
> +              if ((Lo < 0) && (Lo > -2048)) {
> 
> +                Hi += 0x1000;
> 
> +                Lo = ~(0x1000 - Lo) + 1;
> 
> +              }
> 
> +              Hi = ~Hi + 1;
> 
> +              Lo = ~Lo + 1;
> 
> +            } else {
> 
> +              Hi = (Offset / 0x1000) << 12;
> 
> +              Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> 
> +              if (Lo < 0) {
> 
> +                Hi += 0x1000;
> 
> +                Lo = ~(0x1000 - Lo) + 1;
> 
> +              }
> 
> +            }
> 
> +            // Re-encode the offset as an PCADD.D + ADDI.D instruction
> 
> +            *(UINT32 *)Targ &= 0x1f;
> 
> +            *(UINT32 *)Targ |= 0x1c000000;
> 
> +            *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
> 
> +            *(UINT32 *)(Targ + 4) &= 0xffc003ff;
> 
> +            *(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10;
> 
> +            break;
> 
> +          default:
> 
> +            Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s
> unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName,
> (unsigned) ELF64_R_TYPE(Rel->r_info));
> 
> +          }
> 
>          } else {
> 
>            Error (NULL, 0, 3000, "Invalid", "Not a supported machine
> type");
> 
>          }
> 
> @@ -1850,6 +2028,113 @@ 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_LOONGARCH) {
> 
> +            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:
> 
> +              case R_LARCH_B16:
> 
> +              case R_LARCH_B21:
> 
> +              case R_LARCH_B26:
> 
> +              case R_LARCH_ABS_HI20:
> 
> +              case R_LARCH_ABS_LO12:
> 
> +              case R_LARCH_ABS64_LO20:
> 
> +              case R_LARCH_ABS64_HI12:
> 
> +              case R_LARCH_PCALA_HI20:
> 
> +              case R_LARCH_PCALA_LO12:
> 
> +              case R_LARCH_PCALA64_LO20:
> 
> +              case R_LARCH_PCALA64_HI12:
> 
> +              case R_LARCH_GOT_PC_HI20:
> 
> +              case R_LARCH_GOT_PC_LO12:
> 
> +              case R_LARCH_GOT64_PC_LO20:
> 
> +              case R_LARCH_GOT64_PC_HI12:
> 
> +              case R_LARCH_GOT64_HI20:
> 
> +              case R_LARCH_GOT64_LO12:
> 
> +              case R_LARCH_GOT64_LO20:
> 
> +              case R_LARCH_GOT64_HI12:
> 
> +              case R_LARCH_TLS_LE_HI20:
> 
> +              case R_LARCH_TLS_LE_LO12:
> 
> +              case R_LARCH_TLS_LE64_LO20:
> 
> +              case R_LARCH_TLS_LE64_HI12:
> 
> +              case R_LARCH_TLS_IE_PC_HI20:
> 
> +              case R_LARCH_TLS_IE_PC_LO12:
> 
> +              case R_LARCH_TLS_IE64_PC_LO20:
> 
> +              case R_LARCH_TLS_IE64_PC_HI12:
> 
> +              case R_LARCH_TLS_IE64_HI20:
> 
> +              case R_LARCH_TLS_IE64_LO12:
> 
> +              case R_LARCH_TLS_IE64_LO20:
> 
> +              case R_LARCH_TLS_IE64_HI12:
> 
> +              case R_LARCH_TLS_LD_PC_HI20:
> 
> +              case R_LARCH_TLS_LD64_HI20:
> 
> +              case R_LARCH_TLS_GD_PC_HI20:
> 
> +              case R_LARCH_TLS_GD64_HI20:
> 
> +              case R_LARCH_RELAX:
> 
> +                //
> 
> +                // 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_LOONGARCH 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..7b7fdeb329 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_LOONGARCH 258 /* LoongArch Architecture */
> 
> 
> 
>  /* Non-standard or deprecated. */
> 
>  #define EM_486    6  /* Intel i486. */
> 
> @@ -1042,4 +1044,96 @@ 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
> 
> +#define R_LARCH_B16                        64
> 
> +#define R_LARCH_B21                        65
> 
> +#define R_LARCH_B26                        66
> 
> +#define R_LARCH_ABS_HI20                   67
> 
> +#define R_LARCH_ABS_LO12                   68
> 
> +#define R_LARCH_ABS64_LO20                 69
> 
> +#define R_LARCH_ABS64_HI12                 70
> 
> +#define R_LARCH_PCALA_HI20                 71
> 
> +#define R_LARCH_PCALA_LO12                 72
> 
> +#define R_LARCH_PCALA64_LO20               73
> 
> +#define R_LARCH_PCALA64_HI12               74
> 
> +#define R_LARCH_GOT_PC_HI20                75
> 
> +#define R_LARCH_GOT_PC_LO12                76
> 
> +#define R_LARCH_GOT64_PC_LO20              77
> 
> +#define R_LARCH_GOT64_PC_HI12              78
> 
> +#define R_LARCH_GOT64_HI20                 79
> 
> +#define R_LARCH_GOT64_LO12                 80
> 
> +#define R_LARCH_GOT64_LO20                 81
> 
> +#define R_LARCH_GOT64_HI12                 82
> 
> +#define R_LARCH_TLS_LE_HI20                83
> 
> +#define R_LARCH_TLS_LE_LO12                84
> 
> +#define R_LARCH_TLS_LE64_LO20              85
> 
> +#define R_LARCH_TLS_LE64_HI12              86
> 
> +#define R_LARCH_TLS_IE_PC_HI20             87
> 
> +#define R_LARCH_TLS_IE_PC_LO12             88
> 
> +#define R_LARCH_TLS_IE64_PC_LO20           89
> 
> +#define R_LARCH_TLS_IE64_PC_HI12           90
> 
> +#define R_LARCH_TLS_IE64_HI20              91
> 
> +#define R_LARCH_TLS_IE64_LO12              92
> 
> +#define R_LARCH_TLS_IE64_LO20              93
> 
> +#define R_LARCH_TLS_IE64_HI12              94
> 
> +#define R_LARCH_TLS_LD_PC_HI20             95
> 
> +#define R_LARCH_TLS_LD64_HI20              96
> 
> +#define R_LARCH_TLS_GD_PC_HI20             97
> 
> +#define R_LARCH_TLS_GD64_HI20              98
> 
> +#define R_LARCH_RELAX                      99
> 
>  #endif /* !_SYS_ELF_COMMON_H_ */
> 
> diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
> b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
> index 21c968e650..77ded3f611 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
> 
> 
> 
> 
> 
>  ///
> 
> diff --git a/BaseTools/Source/C/Makefiles/header.makefile
> b/BaseTools/Source/C/Makefiles/header.makefile
> index 0df728f327..4e88a4fbd8 100644
> --- a/BaseTools/Source/C/Makefiles/header.makefile
> +++ b/BaseTools/Source/C/Makefiles/header.makefile
> @@ -31,6 +31,9 @@ ifndef HOST_ARCH
>    ifneq (,$(findstring riscv64,$(uname_m)))
> 
>      HOST_ARCH=RISCV64
> 
>    endif
> 
> +  ifneq (,$(findstring loongarch64,$(uname_m)))
> 
> +    HOST_ARCH=LOONGARCH64
> 
> +  endif
> 
>    ifndef HOST_ARCH
> 
>      $(info Could not detected HOST_ARCH from uname results)
> 
>      $(error HOST_ARCH is not defined!)
> 
> @@ -70,6 +73,9 @@ ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
>  else ifeq ($(HOST_ARCH), RISCV64)
> 
>  ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/
> 
> 
> 
> +else ifeq ($(HOST_ARCH), LOONGARCH64)
> 
> +ARCH_INCLUDE = -I $(MAKEROOT)/Include/LoongArch64/
> 
> +
> 
>  else
> 
>  $(error Bad HOST_ARCH)
> 
>  endif
> 
> --
> 2.27.0
> 





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [edk2-devel] 回复: PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch platform.
  2022-09-15  6:27 ` 回复: " gaoliming
@ 2022-09-15  7:20   ` Chao Li
  0 siblings, 0 replies; 3+ messages in thread
From: Chao Li @ 2022-09-15  7:20 UTC (permalink / raw)
  To: devel@edk2.groups.io, gaoliming@byosoft.com.cn
  Cc: devel@edk2.groups.io, "'Bob Feng'",
	"'Yuwei Chen'", "'Dongyan Qian'",
	"'Baoqi Zhang'", "'Yang Zhou'",
	"'Xiaotian Wu'"

[-- Attachment #1: Type: text/plain, Size: 41631 bytes --]

Liming,
Ok, I will change the commit message in the V3.

Thanks,
Chao
--------

On 9月 15 2022, at 2:27 下午, "gaoliming via groups.io" <gaoliming=byosoft.com.cn@groups.io> wrote:
> Chao:
> This change is for BaseTools C tools . The commit message can be
> BaseTools: Update GenFw/GenFv to support LoongArch platform.
>
> The code change is good to me. Reviewed-by: Liming Gao <gaoliming@byosoft.
> com.cn>
>
> Thanks
> Liming
> > -----邮件原件-----
> > 发件人: Chao Li <lichao@loongson.cn>
> > 发送时间: 2022年9月14日 17:40
> > 收件人: devel@edk2.groups.io
> > 抄送: Bob Feng <bob.c.feng@intel.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>; Yuwei Chen <yuwei.chen@intel.com>;
> > Dongyan Qian <qiandongyan@loongson.cn>; Baoqi Zhang
> > <zhangbaoqi@loongson.cn>; Yang Zhou <zhouyang@loongson.cn>; Xiaotian
> > Wu <wuxiaotian@loongson.cn>
> > 主题: [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch
> > platform.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053
> >
> > C code changes for building EDK2 LoongArch platform.
> >
> > For definitions of PE/COFF and LOONGARCH relocation types, see the
> > "Machine Types" and "Basic Relocation Types" sections of this URL for
> > LOONGARCH values:
> > https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
> >
> > Cc: Bob Feng <bob.c.feng@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Yuwei Chen <yuwei.chen@intel.com>
> >
> > Signed-off-by: Chao Li <lichao@loongson.cn>
> > Co-authored-by: Dongyan Qian <qiandongyan@loongson.cn>
> > Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn>
> > Co-authored-by: Yang Zhou <zhouyang@loongson.cn>
> > Co-authored-by: Xiaotian Wu <wuxiaotian@loongson.cn>
> > ---
> > BaseTools/Source/C/Common/BasePeCoff.c | 15 +-
> > BaseTools/Source/C/Common/PeCoffLoaderEx.c | 79 +++++
> > BaseTools/Source/C/GenFv/GenFvInternalLib.c | 125 +++++++-
> > BaseTools/Source/C/GenFw/Elf64Convert.c | 293
> > +++++++++++++++++-
> > BaseTools/Source/C/GenFw/elf_common.h | 94 ++++++
> > .../C/Include/IndustryStandard/PeImage.h | 57 ++--
> > BaseTools/Source/C/Makefiles/header.makefile | 6 +
> > 7 files changed, 636 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..2cc428d733 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,81 @@ PeCoffLoaderRelocateArmImage (
> >
> >
> > return RETURN_SUCCESS;
> >
> > }
> >
> > +
> >
> > +/**
> >
> > + Performs a LoongArch specific relocation fixup.
> >
> > +
> >
> > + @param[in] Reloc Pointer to the relocation record.
> >
> > + @param[in, out] Fixup Pointer to the address to fix up.
> >
> > + @param[in, out] FixupData Pointer to a buffer to log the fixups.
> >
> > + @param[in] 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;
> >
> > + UINT64 Tmp1;
> >
> > + UINT64 Tmp2;
> >
> > +
> >
> > + RelocType = ((*Reloc) >> 12);
> >
> > + Value = 0;
> >
> > + Tmp1 = 0;
> >
> > + Tmp2 = 0;
> >
> > +
> >
> > + switch (RelocType) {
> >
> > + case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
> >
> > + // The next four instructions are used to load a 64 bit address,
> > relocate all of them
> >
> > + 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..575b99b6ad 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,98 @@ 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[1];
> >
> > +
> >
> > + 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");
> >
> > +
> >
> > + ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) &
> > 0x3FFFFFF) >> 2;
> >
> > + ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) |
> > ((ResetVector[0] >> 16) & 0x3FF);
> >
> > + ResetVector[0] |= 0x54000000; /* bl offset */
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // 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 +2603,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 +3047,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 +3098,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 +3557,12 @@ Returns:
> > VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
> >
> > mArm = TRUE;
> >
> > }
> >
> > +
> >
> > + // Machine type is LOONGARCH64, set a flag so LoongArch64 reset
> > vector processed.
> >
> > + if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {
> >
> > + VerboseMsg("Located LoongArch64 SEC core in child FV");
> >
> > + mLoongArch = TRUE;
> >
> > + }
> >
> > }
> >
> >
> >
> > //
> >
> > @@ -3608,6 +3721,10 @@ Returns:
> > mRiscV = TRUE;
> >
> > }
> >
> >
> >
> > + if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) )
> > {
> >
> > + mLoongArch = TRUE;
> >
> > + }
> >
> > +
> >
> > //
> >
> > // Keep Image Context for PE image in FV
> >
> > //
> >
> > @@ -3885,6 +4002,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 ca3c8f8bee..ede2f0ef90 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-2022, 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
> >
> >
> >
> > @@ -177,7 +178,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_LOONGARCH))) {
> >
> > Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64
> > machine.");
> >
> > }
> >
> > if (mEhdr->e_version != EV_CURRENT) {
> >
> > @@ -799,6 +800,7 @@ ScanSections64 (
> > case EM_X86_64:
> >
> > case EM_AARCH64:
> >
> > case EM_RISCV64:
> >
> > + case EM_LOONGARCH:
> >
> > mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
> >
> > break;
> >
> > default:
> >
> > @@ -1088,6 +1090,10 @@ ScanSections64 (
> > NtHdr->Pe32Plus.FileHeader.Machine =
> > EFI_IMAGE_MACHINE_RISCV64;
> >
> > NtHdr->Pe32Plus.OptionalHeader.Magic =
> > EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
> >
> > break;
> >
> > + case EM_LOONGARCH:
> >
> > + 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);
> >
> > @@ -1333,10 +1339,10 @@ WriteSections64 (
> > }
> >
> >
> >
> > //
> >
> > - // Skip error on EM_RISCV64 becasue no symble name is built
> >
> > - // from RISC-V toolchain.
> >
> > + // Skip error on EM_RISCV64 and EM_LOONGARCH because no
> > symbol 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_LOONGARCH)) {
> >
> > 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.",
> >
> > @@ -1618,6 +1624,178 @@ WriteSections64 (
> > // Write section for RISC-V 64 architecture.
> >
> > //
> >
> > WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
> >
> > + } else if (mEhdr->e_machine == EM_LOONGARCH) {
> >
> > + switch (ELF_R_TYPE(Rel->r_info)) {
> >
> > + INT64 Offset;
> >
> > + INT32 Lo, Hi;
> >
> > +
> >
> > + 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:
> >
> > + case R_LARCH_B16:
> >
> > + case R_LARCH_B21:
> >
> > + case R_LARCH_B26:
> >
> > + case R_LARCH_ABS_HI20:
> >
> > + case R_LARCH_ABS_LO12:
> >
> > + case R_LARCH_ABS64_LO20:
> >
> > + case R_LARCH_ABS64_HI12:
> >
> > + case R_LARCH_PCALA_LO12:
> >
> > + case R_LARCH_PCALA64_LO20:
> >
> > + case R_LARCH_PCALA64_HI12:
> >
> > + case R_LARCH_GOT_PC_LO12:
> >
> > + case R_LARCH_GOT64_PC_LO20:
> >
> > + case R_LARCH_GOT64_PC_HI12:
> >
> > + case R_LARCH_GOT64_HI20:
> >
> > + case R_LARCH_GOT64_LO12:
> >
> > + case R_LARCH_GOT64_LO20:
> >
> > + case R_LARCH_GOT64_HI12:
> >
> > + case R_LARCH_TLS_LE_HI20:
> >
> > + case R_LARCH_TLS_LE_LO12:
> >
> > + case R_LARCH_TLS_LE64_LO20:
> >
> > + case R_LARCH_TLS_LE64_HI12:
> >
> > + case R_LARCH_TLS_IE_PC_HI20:
> >
> > + case R_LARCH_TLS_IE_PC_LO12:
> >
> > + case R_LARCH_TLS_IE64_PC_LO20:
> >
> > + case R_LARCH_TLS_IE64_PC_HI12:
> >
> > + case R_LARCH_TLS_IE64_HI20:
> >
> > + case R_LARCH_TLS_IE64_LO12:
> >
> > + case R_LARCH_TLS_IE64_LO20:
> >
> > + case R_LARCH_TLS_IE64_HI12:
> >
> > + case R_LARCH_TLS_LD_PC_HI20:
> >
> > + case R_LARCH_TLS_LD64_HI20:
> >
> > + case R_LARCH_TLS_GD_PC_HI20:
> >
> > + case R_LARCH_TLS_GD64_HI20:
> >
> > + case R_LARCH_RELAX:
> >
> > + //
> >
> > + // These types are not used or do not require fixup.
> >
> > + //
> >
> > + break;
> >
> > +
> >
> > + case R_LARCH_GOT_PC_HI20:
> >
> > + Offset = Sym->st_value - (UINTN)(Targ - mCoffFile);
> >
> > + if (Offset < 0) {
> >
> > + Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value;
> >
> > + Hi = (Offset / 0x1000) << 12;
> >
> > + Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> >
> > + if ((Lo < 0) && (Lo > -2048)) {
> >
> > + Hi += 0x1000;
> >
> > + Lo = ~(0x1000 - Lo) + 1;
> >
> > + }
> >
> > + Hi = ~Hi + 1;
> >
> > + Lo = ~Lo + 1;
> >
> > + } else {
> >
> > + Hi = (Offset / 0x1000) << 12;
> >
> > + Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> >
> > + if (Lo < 0) {
> >
> > + Hi += 0x1000;
> >
> > + Lo = ~(0x1000 - Lo) + 1;
> >
> > + }
> >
> > + }
> >
> > + // Re-encode the offset as an PCADD.D + ADDI.D(Convert
> > LD.D) instruction
> >
> > + *(UINT32 *)Targ &= 0x1f;
> >
> > + *(UINT32 *)Targ |= 0x1c000000;
> >
> > + *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
> >
> > + *(UINT32 *)(Targ + 4) &= 0x3ff;
> >
> > + *(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10);
> >
> > + break;
> >
> > +
> >
> > + //
> >
> > + // Attempt to convert instruction.
> >
> > + //
> >
> > + case R_LARCH_PCALA_HI20:
> >
> > + // Decode the PCALAU12I + ADDI.D instruction
> >
> > + Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7));
> >
> > + Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10)
> >>
> > 20);
> >
> > + //
> >
> > + // PCALA offset is relative to the previous page boundary,
> >
> > + // whereas PCADD offset is relative to the instruction
> itself.
> >
> > + // So fix up the offset so it points to the page containing
> >
> > + // the symbol.
> >
> > + //
> >
> > + Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;
> >
> > + if (Offset < 0) {
> >
> > + Offset = -Offset;
> >
> > + Hi = (Offset / 0x1000) << 12;
> >
> > + Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> >
> > + if ((Lo < 0) && (Lo > -2048)) {
> >
> > + Hi += 0x1000;
> >
> > + Lo = ~(0x1000 - Lo) + 1;
> >
> > + }
> >
> > + Hi = ~Hi + 1;
> >
> > + Lo = ~Lo + 1;
> >
> > + } else {
> >
> > + Hi = (Offset / 0x1000) << 12;
> >
> > + Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
> >
> > + if (Lo < 0) {
> >
> > + Hi += 0x1000;
> >
> > + Lo = ~(0x1000 - Lo) + 1;
> >
> > + }
> >
> > + }
> >
> > + // Re-encode the offset as an PCADD.D + ADDI.D instruction
> >
> > + *(UINT32 *)Targ &= 0x1f;
> >
> > + *(UINT32 *)Targ |= 0x1c000000;
> >
> > + *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
> >
> > + *(UINT32 *)(Targ + 4) &= 0xffc003ff;
> >
> > + *(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10;
> >
> > + break;
> >
> > + default:
> >
> > + Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s
> > unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName,
> > (unsigned) ELF64_R_TYPE(Rel->r_info));
> >
> > + }
> >
> > } else {
> >
> > Error (NULL, 0, 3000, "Invalid", "Not a supported machine
> > type");
> >
> > }
> >
> > @@ -1850,6 +2028,113 @@ 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_LOONGARCH) {
> >
> > + 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:
> >
> > + case R_LARCH_B16:
> >
> > + case R_LARCH_B21:
> >
> > + case R_LARCH_B26:
> >
> > + case R_LARCH_ABS_HI20:
> >
> > + case R_LARCH_ABS_LO12:
> >
> > + case R_LARCH_ABS64_LO20:
> >
> > + case R_LARCH_ABS64_HI12:
> >
> > + case R_LARCH_PCALA_HI20:
> >
> > + case R_LARCH_PCALA_LO12:
> >
> > + case R_LARCH_PCALA64_LO20:
> >
> > + case R_LARCH_PCALA64_HI12:
> >
> > + case R_LARCH_GOT_PC_HI20:
> >
> > + case R_LARCH_GOT_PC_LO12:
> >
> > + case R_LARCH_GOT64_PC_LO20:
> >
> > + case R_LARCH_GOT64_PC_HI12:
> >
> > + case R_LARCH_GOT64_HI20:
> >
> > + case R_LARCH_GOT64_LO12:
> >
> > + case R_LARCH_GOT64_LO20:
> >
> > + case R_LARCH_GOT64_HI12:
> >
> > + case R_LARCH_TLS_LE_HI20:
> >
> > + case R_LARCH_TLS_LE_LO12:
> >
> > + case R_LARCH_TLS_LE64_LO20:
> >
> > + case R_LARCH_TLS_LE64_HI12:
> >
> > + case R_LARCH_TLS_IE_PC_HI20:
> >
> > + case R_LARCH_TLS_IE_PC_LO12:
> >
> > + case R_LARCH_TLS_IE64_PC_LO20:
> >
> > + case R_LARCH_TLS_IE64_PC_HI12:
> >
> > + case R_LARCH_TLS_IE64_HI20:
> >
> > + case R_LARCH_TLS_IE64_LO12:
> >
> > + case R_LARCH_TLS_IE64_LO20:
> >
> > + case R_LARCH_TLS_IE64_HI12:
> >
> > + case R_LARCH_TLS_LD_PC_HI20:
> >
> > + case R_LARCH_TLS_LD64_HI20:
> >
> > + case R_LARCH_TLS_GD_PC_HI20:
> >
> > + case R_LARCH_TLS_GD64_HI20:
> >
> > + case R_LARCH_RELAX:
> >
> > + //
> >
> > + // 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_LOONGARCH 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..7b7fdeb329 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_LOONGARCH 258 /* LoongArch Architecture */
> >
> >
> >
> > /* Non-standard or deprecated. */
> >
> > #define EM_486 6 /* Intel i486. */
> >
> > @@ -1042,4 +1044,96 @@ 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
> >
> > +#define R_LARCH_B16 64
> >
> > +#define R_LARCH_B21 65
> >
> > +#define R_LARCH_B26 66
> >
> > +#define R_LARCH_ABS_HI20 67
> >
> > +#define R_LARCH_ABS_LO12 68
> >
> > +#define R_LARCH_ABS64_LO20 69
> >
> > +#define R_LARCH_ABS64_HI12 70
> >
> > +#define R_LARCH_PCALA_HI20 71
> >
> > +#define R_LARCH_PCALA_LO12 72
> >
> > +#define R_LARCH_PCALA64_LO20 73
> >
> > +#define R_LARCH_PCALA64_HI12 74
> >
> > +#define R_LARCH_GOT_PC_HI20 75
> >
> > +#define R_LARCH_GOT_PC_LO12 76
> >
> > +#define R_LARCH_GOT64_PC_LO20 77
> >
> > +#define R_LARCH_GOT64_PC_HI12 78
> >
> > +#define R_LARCH_GOT64_HI20 79
> >
> > +#define R_LARCH_GOT64_LO12 80
> >
> > +#define R_LARCH_GOT64_LO20 81
> >
> > +#define R_LARCH_GOT64_HI12 82
> >
> > +#define R_LARCH_TLS_LE_HI20 83
> >
> > +#define R_LARCH_TLS_LE_LO12 84
> >
> > +#define R_LARCH_TLS_LE64_LO20 85
> >
> > +#define R_LARCH_TLS_LE64_HI12 86
> >
> > +#define R_LARCH_TLS_IE_PC_HI20 87
> >
> > +#define R_LARCH_TLS_IE_PC_LO12 88
> >
> > +#define R_LARCH_TLS_IE64_PC_LO20 89
> >
> > +#define R_LARCH_TLS_IE64_PC_HI12 90
> >
> > +#define R_LARCH_TLS_IE64_HI20 91
> >
> > +#define R_LARCH_TLS_IE64_LO12 92
> >
> > +#define R_LARCH_TLS_IE64_LO20 93
> >
> > +#define R_LARCH_TLS_IE64_HI12 94
> >
> > +#define R_LARCH_TLS_LD_PC_HI20 95
> >
> > +#define R_LARCH_TLS_LD64_HI20 96
> >
> > +#define R_LARCH_TLS_GD_PC_HI20 97
> >
> > +#define R_LARCH_TLS_GD64_HI20 98
> >
> > +#define R_LARCH_RELAX 99
> >
> > #endif /* !_SYS_ELF_COMMON_H_ */
> >
> > diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
> > b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
> > index 21c968e650..77ded3f611 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
> >
> >
> >
> >
> >
> > ///
> >
> > diff --git a/BaseTools/Source/C/Makefiles/header.makefile
> > b/BaseTools/Source/C/Makefiles/header.makefile
> > index 0df728f327..4e88a4fbd8 100644
> > --- a/BaseTools/Source/C/Makefiles/header.makefile
> > +++ b/BaseTools/Source/C/Makefiles/header.makefile
> > @@ -31,6 +31,9 @@ ifndef HOST_ARCH
> > ifneq (,$(findstring riscv64,$(uname_m)))
> >
> > HOST_ARCH=RISCV64
> >
> > endif
> >
> > + ifneq (,$(findstring loongarch64,$(uname_m)))
> >
> > + HOST_ARCH=LOONGARCH64
> >
> > + endif
> >
> > ifndef HOST_ARCH
> >
> > $(info Could not detected HOST_ARCH from uname results)
> >
> > $(error HOST_ARCH is not defined!)
> >
> > @@ -70,6 +73,9 @@ ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
> > else ifeq ($(HOST_ARCH), RISCV64)
> >
> > ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/
> >
> >
> >
> > +else ifeq ($(HOST_ARCH), LOONGARCH64)
> >
> > +ARCH_INCLUDE = -I $(MAKEROOT)/Include/LoongArch64/
> >
> > +
> >
> > else
> >
> > $(error Bad HOST_ARCH)
> >
> > endif
> >
> > --
> > 2.27.0
> >
>
>
>
>
>
>
> 
>


[-- Attachment #2: Type: text/html, Size: 62208 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-09-15  7:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-14  9:40 [PATCH v2 15/34] BaseTools: BaseTools changes for LoongArch platform Chao Li
2022-09-15  6:27 ` 回复: " gaoliming
2022-09-15  7:20   ` [edk2-devel] 回复: PATCH " Chao Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox