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


Chao Li
 

C code changes for building EDK2 LoongArch platform.

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

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

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

Join devel@edk2.groups.io to automatically receive all group messages.