Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
IN UINT64 Adjust\r
);\r
\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateLoongArch64Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
STATIC\r
RETURN_STATUS\r
PeCoffLoaderGetPeHeader (\r
ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \\r
ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \\r
ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \\r
- ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64 && \\r
+ ImageContext->Machine != EFI_IMAGE_MACHINE_LOONGARCH64) {\r
if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {\r
//\r
// There are two types of ARM images. Pure ARM and ARM/Thumb.\r
case EFI_IMAGE_MACHINE_RISCV64:\r
Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);\r
break;\r
+ case EFI_IMAGE_MACHINE_LOONGARCH64:\r
+ Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust);\r
+ break;\r
default:\r
Status = RETURN_UNSUPPORTED;\r
break;\r
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
--*/\r
\r
return RETURN_SUCCESS;\r
}\r
+\r
+/**\r
+ Performs a LoongArch specific relocation fixup.\r
+\r
+ @param[in] Reloc Pointer to the relocation record.\r
+ @param[in, out] Fixup Pointer to the address to fix up.\r
+ @param[in, out] FixupData Pointer to a buffer to log the fixups.\r
+ @param[in] Adjust The offset to adjust the fixup.\r
+\r
+ @return Status code.\r
+**/\r
+RETURN_STATUS\r
+PeCoffLoaderRelocateLoongArch64Image (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+{\r
+ UINT8 RelocType;\r
+ UINT64 Value;\r
+ UINT64 Tmp1;\r
+ UINT64 Tmp2;\r
+\r
+ RelocType = ((*Reloc) >> 12);\r
+ Value = 0;\r
+ Tmp1 = 0;\r
+ Tmp2 = 0;\r
+\r
+ switch (RelocType) {\r
+ case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:\r
+ // The next four instructions are used to load a 64 bit address, relocate all of them\r
+ Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5\r
+ (*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10\r
+ Tmp1 = *((UINT32 *)Fixup + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5\r
+ Tmp2 = *((UINT32 *)Fixup + 3) & 0x3ffc00; // lu52i.d 12bits from bit10\r
+ Value = Value | (Tmp1 << 27) | (Tmp2 << 42);\r
+ Value += Adjust;\r
+\r
+ *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+ *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+ *FixupData = *FixupData + sizeof (UINT32);\r
+ }\r
+\r
+ Fixup += sizeof (UINT32);\r
+ *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10);\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+ *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+ *FixupData = *FixupData + sizeof (UINT32);\r
+ }\r
+\r
+ Fixup += sizeof (UINT32);\r
+ *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+ *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+ *FixupData = *FixupData + sizeof (UINT32);\r
+ }\r
+\r
+ Fixup += sizeof (UINT32);\r
+ *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);\r
+ if (*FixupData != NULL) {\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));\r
+ *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;\r
+ *FixupData = *FixupData + sizeof (UINT32);\r
+ }\r
+\r
+ break;\r
+ default:\r
+ Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32 *)Fixup, Adjust, *Reloc, RelocType);\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>\r
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
BOOLEAN mArm = FALSE;\r
BOOLEAN mRiscV = FALSE;\r
+BOOLEAN mLoongArch = FALSE;\r
STATIC UINT32 MaxFfsAlignment = 0;\r
BOOLEAN VtfFileFlag = FALSE;\r
\r
return EFI_SUCCESS;\r
}\r
\r
+EFI_STATUS\r
+UpdateLoongArchResetVectorIfNeeded (\r
+ IN MEMORY_FILE *FvImage,\r
+ IN FV_INFO *FvInfo\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This parses the FV looking for SEC and patches that address into the\r
+ beginning of the FV header.\r
+\r
+ For LoongArch ISA, the reset vector is at 0x1c000000.\r
+\r
+ We relocate it to SecCoreEntry and copy the ResetVector code to the\r
+ beginning of the FV.\r
+\r
+Arguments:\r
+ FvImage Memory file for the FV memory image\r
+ FvInfo Information read from INF file.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Function Completed successfully.\r
+ EFI_ABORTED Error encountered.\r
+ EFI_INVALID_PARAMETER A required parameter was NULL.\r
+ EFI_NOT_FOUND PEI Core file not found.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_SECTION_POINTER SecPe32;\r
+ BOOLEAN UpdateVectorSec = FALSE;\r
+ UINT16 MachineType = 0;\r
+ EFI_PHYSICAL_ADDRESS SecCoreEntryAddress = 0;\r
+\r
+ //\r
+ // Verify input parameters\r
+ //\r
+ if (FvImage == NULL || FvInfo == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Locate an SEC Core instance and if found extract the machine type and entry point address\r
+ //\r
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);\r
+ if (!EFI_ERROR(Status)) {\r
+\r
+ Status = GetCoreMachineType(SecPe32, &MachineType);\r
+ if (EFI_ERROR(Status)) {\r
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);\r
+ if (EFI_ERROR(Status)) {\r
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ UpdateVectorSec = TRUE;\r
+ }\r
+\r
+ if (!UpdateVectorSec)\r
+ return EFI_SUCCESS;\r
+\r
+ if (MachineType == EFI_IMAGE_MACHINE_LOONGARCH64) {\r
+ UINT32 ResetVector[1];\r
+\r
+ memset(ResetVector, 0, sizeof (ResetVector));\r
+\r
+ /* if we found an SEC core entry point then generate a branch instruction */\r
+ if (UpdateVectorSec) {\r
+ VerboseMsg("UpdateLoongArchResetVectorIfNeeded updating LOONGARCH64 SEC vector");\r
+\r
+ ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) & 0x3FFFFFF) >> 2;\r
+ ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) | ((ResetVector[0] >> 16) & 0x3FF);\r
+ ResetVector[0] |= 0x50000000; /* b offset */\r
+ }\r
+\r
+ //\r
+ // Copy to the beginning of the FV\r
+ //\r
+ memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));\r
+ } else {\r
+ Error(NULL, 0, 3000, "Invalid", "Unknown machine type");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
EFI_STATUS\r
GetPe32Info (\r
IN UINT8 *Pe32,\r
//\r
if ((*MachineType != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&\r
(*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&\r
- (*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {\r
+ (*MachineType != EFI_IMAGE_MACHINE_RISCV64) && (*MachineType != EFI_IMAGE_MACHINE_LOONGARCH64)) {\r
Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");\r
return EFI_UNSUPPORTED;\r
}\r
goto Finish;\r
}\r
\r
- if (!mArm && !mRiscV) {\r
+ if (!mArm && !mRiscV && !mLoongArch) {\r
//\r
// Update reset vector (SALE_ENTRY for IPF)\r
// Now for IA32 and IA64 platform, the fv which has bsf file must have the\r
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));\r
}\r
\r
+ if (mLoongArch) {\r
+ Status = UpdateLoongArchResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");\r
+ goto Finish;\r
+ }\r
+ //\r
+ // Update Checksum for FvHeader\r
+ //\r
+ FvHeader->Checksum = 0;\r
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));\r
+ }\r
+\r
//\r
// Update FV Alignment attribute to the largest alignment of all the FFS files in the FV\r
//\r
VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");\r
mArm = TRUE;\r
}\r
+\r
+ // Machine type is LOONGARCH64, set a flag so LoongArch64 reset vector processed.\r
+ if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {\r
+ VerboseMsg("Located LoongArch64 SEC core in child FV");\r
+ mLoongArch = TRUE;\r
+ }\r
}\r
\r
//\r
mRiscV = TRUE;\r
}\r
\r
+ if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {\r
+ mLoongArch = TRUE;\r
+ }\r
+\r
//\r
// Keep Image Context for PE image in FV\r
//\r
mArm = TRUE;\r
}\r
\r
+ if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {\r
+ mLoongArch = TRUE;\r
+ }\r
+\r
//\r
// Keep Image Context for TE image in FV\r
//\r
Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2013-2022, ARM Ltd. All rights reserved.<BR>\r
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
return FALSE;\r
}\r
- if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {\r
+ if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64) || (mEhdr->e_machine == EM_LOONGARCH))) {\r
Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");\r
}\r
if (mEhdr->e_version != EV_CURRENT) {\r
case EM_X86_64:\r
case EM_AARCH64:\r
case EM_RISCV64:\r
+ case EM_LOONGARCH:\r
mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
break;\r
default:\r
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;\r
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
break;\r
+ case EM_LOONGARCH:\r
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_LOONGARCH64;\r
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+ break;\r
\r
default:\r
VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);\r
}\r
\r
//\r
- // Skip error on EM_RISCV64 becasue no symble name is built\r
- // from RISC-V toolchain.\r
+ // Skip error on EM_RISCV64 and EM_LOONGARCH because no symbol name is built\r
+ // from RISC-V and LoongArch toolchain.\r
//\r
- if (mEhdr->e_machine != EM_RISCV64) {\r
+ if ((mEhdr->e_machine != EM_RISCV64) && (mEhdr->e_machine != EM_LOONGARCH)) {\r
Error (NULL, 0, 3000, "Invalid",\r
"%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "\r
"For example, absolute and undefined symbols are not supported.",\r
// Write section for RISC-V 64 architecture.\r
//\r
WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);\r
+ } else if (mEhdr->e_machine == EM_LOONGARCH) {\r
+ switch (ELF_R_TYPE(Rel->r_info)) {\r
+ INT64 Offset;\r
+ INT32 Lo, Hi;\r
+\r
+ case R_LARCH_SOP_PUSH_ABSOLUTE:\r
+ //\r
+ // Absolute relocation.\r
+ //\r
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
+ break;\r
+\r
+ case R_LARCH_MARK_LA:\r
+ case R_LARCH_64:\r
+ case R_LARCH_NONE:\r
+ case R_LARCH_32:\r
+ case R_LARCH_RELATIVE:\r
+ case R_LARCH_COPY:\r
+ case R_LARCH_JUMP_SLOT:\r
+ case R_LARCH_TLS_DTPMOD32:\r
+ case R_LARCH_TLS_DTPMOD64:\r
+ case R_LARCH_TLS_DTPREL32:\r
+ case R_LARCH_TLS_DTPREL64:\r
+ case R_LARCH_TLS_TPREL32:\r
+ case R_LARCH_TLS_TPREL64:\r
+ case R_LARCH_IRELATIVE:\r
+ case R_LARCH_MARK_PCREL:\r
+ case R_LARCH_SOP_PUSH_PCREL:\r
+ case R_LARCH_SOP_PUSH_DUP:\r
+ case R_LARCH_SOP_PUSH_GPREL:\r
+ case R_LARCH_SOP_PUSH_TLS_TPREL:\r
+ case R_LARCH_SOP_PUSH_TLS_GOT:\r
+ case R_LARCH_SOP_PUSH_TLS_GD:\r
+ case R_LARCH_SOP_PUSH_PLT_PCREL:\r
+ case R_LARCH_SOP_ASSERT:\r
+ case R_LARCH_SOP_NOT:\r
+ case R_LARCH_SOP_SUB:\r
+ case R_LARCH_SOP_SL:\r
+ case R_LARCH_SOP_SR:\r
+ case R_LARCH_SOP_ADD:\r
+ case R_LARCH_SOP_AND:\r
+ case R_LARCH_SOP_IF_ELSE:\r
+ case R_LARCH_SOP_POP_32_S_10_5:\r
+ case R_LARCH_SOP_POP_32_U_10_12:\r
+ case R_LARCH_SOP_POP_32_S_10_12:\r
+ case R_LARCH_SOP_POP_32_S_10_16:\r
+ case R_LARCH_SOP_POP_32_S_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_S_5_20:\r
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_U:\r
+ case R_LARCH_ADD8:\r
+ case R_LARCH_ADD16:\r
+ case R_LARCH_ADD24:\r
+ case R_LARCH_ADD32:\r
+ case R_LARCH_ADD64:\r
+ case R_LARCH_SUB8:\r
+ case R_LARCH_SUB16:\r
+ case R_LARCH_SUB24:\r
+ case R_LARCH_SUB32:\r
+ case R_LARCH_SUB64:\r
+ case R_LARCH_GNU_VTINHERIT:\r
+ case R_LARCH_GNU_VTENTRY:\r
+ case R_LARCH_B16:\r
+ case R_LARCH_B21:\r
+ case R_LARCH_B26:\r
+ case R_LARCH_ABS_HI20:\r
+ case R_LARCH_ABS_LO12:\r
+ case R_LARCH_ABS64_LO20:\r
+ case R_LARCH_ABS64_HI12:\r
+ case R_LARCH_PCALA_LO12:\r
+ case R_LARCH_PCALA64_LO20:\r
+ case R_LARCH_PCALA64_HI12:\r
+ case R_LARCH_GOT_PC_LO12:\r
+ case R_LARCH_GOT64_PC_LO20:\r
+ case R_LARCH_GOT64_PC_HI12:\r
+ case R_LARCH_GOT64_HI20:\r
+ case R_LARCH_GOT64_LO12:\r
+ case R_LARCH_GOT64_LO20:\r
+ case R_LARCH_GOT64_HI12:\r
+ case R_LARCH_TLS_LE_HI20:\r
+ case R_LARCH_TLS_LE_LO12:\r
+ case R_LARCH_TLS_LE64_LO20:\r
+ case R_LARCH_TLS_LE64_HI12:\r
+ case R_LARCH_TLS_IE_PC_HI20:\r
+ case R_LARCH_TLS_IE_PC_LO12:\r
+ case R_LARCH_TLS_IE64_PC_LO20:\r
+ case R_LARCH_TLS_IE64_PC_HI12:\r
+ case R_LARCH_TLS_IE64_HI20:\r
+ case R_LARCH_TLS_IE64_LO12:\r
+ case R_LARCH_TLS_IE64_LO20:\r
+ case R_LARCH_TLS_IE64_HI12:\r
+ case R_LARCH_TLS_LD_PC_HI20:\r
+ case R_LARCH_TLS_LD64_HI20:\r
+ case R_LARCH_TLS_GD_PC_HI20:\r
+ case R_LARCH_TLS_GD64_HI20:\r
+ case R_LARCH_RELAX:\r
+ //\r
+ // These types are not used or do not require fixup.\r
+ //\r
+ break;\r
+\r
+ case R_LARCH_GOT_PC_HI20:\r
+ Offset = Sym->st_value - (UINTN)(Targ - mCoffFile);\r
+ if (Offset < 0) {\r
+ Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value;\r
+ Hi = Offset & ~0xfff;\r
+ Lo = (INT32)((Offset & 0xfff) << 20) >> 20;\r
+ if ((Lo < 0) && (Lo > -2048)) {\r
+ Hi += 0x1000;\r
+ Lo = ~(0x1000 - Lo) + 1;\r
+ }\r
+ Hi = ~Hi + 1;\r
+ Lo = ~Lo + 1;\r
+ } else {\r
+ Hi = Offset & ~0xfff;\r
+ Lo = (INT32)((Offset & 0xfff) << 20) >> 20;\r
+ if (Lo < 0) {\r
+ Hi += 0x1000;\r
+ Lo = ~(0x1000 - Lo) + 1;\r
+ }\r
+ }\r
+ // Re-encode the offset as PCADDU12I + ADDI.D(Convert LD.D) instruction\r
+ *(UINT32 *)Targ &= 0x1f;\r
+ *(UINT32 *)Targ |= 0x1c000000;\r
+ *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);\r
+ *(UINT32 *)(Targ + 4) &= 0x3ff;\r
+ *(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10);\r
+ break;\r
+\r
+ //\r
+ // Attempt to convert instruction.\r
+ //\r
+ case R_LARCH_PCALA_HI20:\r
+ // Decode the PCALAU12I instruction and the instruction that following it.\r
+ Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7));\r
+ Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10) >> 20);\r
+ //\r
+ // PCALA offset is relative to the previous page boundary,\r
+ // whereas PCADD offset is relative to the instruction itself.\r
+ // So fix up the offset so it points to the page containing\r
+ // the symbol.\r
+ //\r
+ Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;\r
+ if (Offset < 0) {\r
+ Offset = -Offset;\r
+ Hi = Offset & ~0xfff;\r
+ Lo = (INT32)((Offset & 0xfff) << 20) >> 20;\r
+ if ((Lo < 0) && (Lo > -2048)) {\r
+ Hi += 0x1000;\r
+ Lo = ~(0x1000 - Lo) + 1;\r
+ }\r
+ Hi = ~Hi + 1;\r
+ Lo = ~Lo + 1;\r
+ } else {\r
+ Hi = Offset & ~0xfff;\r
+ Lo = (INT32)((Offset & 0xfff) << 20) >> 20;\r
+ if (Lo < 0) {\r
+ Hi += 0x1000;\r
+ Lo = ~(0x1000 - Lo) + 1;\r
+ }\r
+ }\r
+ // Convert the first instruction from PCALAU12I to PCADDU12I and re-encode the offset into them.\r
+ *(UINT32 *)Targ &= 0x1f;\r
+ *(UINT32 *)Targ |= 0x1c000000;\r
+ *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);\r
+ *(UINT32 *)(Targ + 4) &= 0xffc003ff;\r
+ *(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10;\r
+ break;\r
+ default:\r
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));\r
+ }\r
} else {\r
Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");\r
}\r
default:\r
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
}\r
+ } else if (mEhdr->e_machine == EM_LOONGARCH) {\r
+ switch (ELF_R_TYPE(Rel->r_info)) {\r
+ case R_LARCH_MARK_LA:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA);\r
+ break;\r
+ case R_LARCH_64:\r
+ CoffAddFixup(\r
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
+ + (Rel->r_offset - SecShdr->sh_addr)),\r
+ EFI_IMAGE_REL_BASED_DIR64);\r
+ break;\r
+ case R_LARCH_NONE:\r
+ case R_LARCH_32:\r
+ case R_LARCH_RELATIVE:\r
+ case R_LARCH_COPY:\r
+ case R_LARCH_JUMP_SLOT:\r
+ case R_LARCH_TLS_DTPMOD32:\r
+ case R_LARCH_TLS_DTPMOD64:\r
+ case R_LARCH_TLS_DTPREL32:\r
+ case R_LARCH_TLS_DTPREL64:\r
+ case R_LARCH_TLS_TPREL32:\r
+ case R_LARCH_TLS_TPREL64:\r
+ case R_LARCH_IRELATIVE:\r
+ case R_LARCH_MARK_PCREL:\r
+ case R_LARCH_SOP_PUSH_PCREL:\r
+ case R_LARCH_SOP_PUSH_ABSOLUTE:\r
+ case R_LARCH_SOP_PUSH_DUP:\r
+ case R_LARCH_SOP_PUSH_GPREL:\r
+ case R_LARCH_SOP_PUSH_TLS_TPREL:\r
+ case R_LARCH_SOP_PUSH_TLS_GOT:\r
+ case R_LARCH_SOP_PUSH_TLS_GD:\r
+ case R_LARCH_SOP_PUSH_PLT_PCREL:\r
+ case R_LARCH_SOP_ASSERT:\r
+ case R_LARCH_SOP_NOT:\r
+ case R_LARCH_SOP_SUB:\r
+ case R_LARCH_SOP_SL:\r
+ case R_LARCH_SOP_SR:\r
+ case R_LARCH_SOP_ADD:\r
+ case R_LARCH_SOP_AND:\r
+ case R_LARCH_SOP_IF_ELSE:\r
+ case R_LARCH_SOP_POP_32_S_10_5:\r
+ case R_LARCH_SOP_POP_32_U_10_12:\r
+ case R_LARCH_SOP_POP_32_S_10_12:\r
+ case R_LARCH_SOP_POP_32_S_10_16:\r
+ case R_LARCH_SOP_POP_32_S_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_S_5_20:\r
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:\r
+ case R_LARCH_SOP_POP_32_U:\r
+ case R_LARCH_ADD8:\r
+ case R_LARCH_ADD16:\r
+ case R_LARCH_ADD24:\r
+ case R_LARCH_ADD32:\r
+ case R_LARCH_ADD64:\r
+ case R_LARCH_SUB8:\r
+ case R_LARCH_SUB16:\r
+ case R_LARCH_SUB24:\r
+ case R_LARCH_SUB32:\r
+ case R_LARCH_SUB64:\r
+ case R_LARCH_GNU_VTINHERIT:\r
+ case R_LARCH_GNU_VTENTRY:\r
+ case R_LARCH_B16:\r
+ case R_LARCH_B21:\r
+ case R_LARCH_B26:\r
+ case R_LARCH_ABS_HI20:\r
+ case R_LARCH_ABS_LO12:\r
+ case R_LARCH_ABS64_LO20:\r
+ case R_LARCH_ABS64_HI12:\r
+ case R_LARCH_PCALA_HI20:\r
+ case R_LARCH_PCALA_LO12:\r
+ case R_LARCH_PCALA64_LO20:\r
+ case R_LARCH_PCALA64_HI12:\r
+ case R_LARCH_GOT_PC_HI20:\r
+ case R_LARCH_GOT_PC_LO12:\r
+ case R_LARCH_GOT64_PC_LO20:\r
+ case R_LARCH_GOT64_PC_HI12:\r
+ case R_LARCH_GOT64_HI20:\r
+ case R_LARCH_GOT64_LO12:\r
+ case R_LARCH_GOT64_LO20:\r
+ case R_LARCH_GOT64_HI12:\r
+ case R_LARCH_TLS_LE_HI20:\r
+ case R_LARCH_TLS_LE_LO12:\r
+ case R_LARCH_TLS_LE64_LO20:\r
+ case R_LARCH_TLS_LE64_HI12:\r
+ case R_LARCH_TLS_IE_PC_HI20:\r
+ case R_LARCH_TLS_IE_PC_LO12:\r
+ case R_LARCH_TLS_IE64_PC_LO20:\r
+ case R_LARCH_TLS_IE64_PC_HI12:\r
+ case R_LARCH_TLS_IE64_HI20:\r
+ case R_LARCH_TLS_IE64_LO12:\r
+ case R_LARCH_TLS_IE64_LO20:\r
+ case R_LARCH_TLS_IE64_HI12:\r
+ case R_LARCH_TLS_LD_PC_HI20:\r
+ case R_LARCH_TLS_LD64_HI20:\r
+ case R_LARCH_TLS_GD_PC_HI20:\r
+ case R_LARCH_TLS_GD64_HI20:\r
+ case R_LARCH_RELAX:\r
+ //\r
+ // These types are not used or do not require fixup in PE format files.\r
+ //\r
+ break;\r
+ default:\r
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));\r
+ }\r
} else {\r
Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);\r
}\r
Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
#define EM_AARCH64 183 /* ARM 64bit Architecture */\r
#define EM_RISCV64 243 /* 64bit RISC-V Architecture */\r
#define EM_RISCV 244 /* 32bit RISC-V Architecture */\r
+#define EM_LOONGARCH 258 /* LoongArch Architecture */\r
\r
/* Non-standard or deprecated. */\r
#define EM_486 6 /* Intel i486. */\r
#define R_RISCV_SET8 54\r
#define R_RISCV_SET16 55\r
#define R_RISCV_SET32 56\r
+\r
+/*\r
+ * LoongArch relocation types\r
+ */\r
+#define R_LARCH_NONE 0\r
+#define R_LARCH_32 1\r
+#define R_LARCH_64 2\r
+#define R_LARCH_RELATIVE 3\r
+#define R_LARCH_COPY 4\r
+#define R_LARCH_JUMP_SLOT 5\r
+#define R_LARCH_TLS_DTPMOD32 6\r
+#define R_LARCH_TLS_DTPMOD64 7\r
+#define R_LARCH_TLS_DTPREL32 8\r
+#define R_LARCH_TLS_DTPREL64 9\r
+#define R_LARCH_TLS_TPREL32 10\r
+#define R_LARCH_TLS_TPREL64 11\r
+#define R_LARCH_IRELATIVE 12\r
+#define R_LARCH_MARK_LA 20\r
+#define R_LARCH_MARK_PCREL 21\r
+#define R_LARCH_SOP_PUSH_PCREL 22\r
+#define R_LARCH_SOP_PUSH_ABSOLUTE 23\r
+#define R_LARCH_SOP_PUSH_DUP 24\r
+#define R_LARCH_SOP_PUSH_GPREL 25\r
+#define R_LARCH_SOP_PUSH_TLS_TPREL 26\r
+#define R_LARCH_SOP_PUSH_TLS_GOT 27\r
+#define R_LARCH_SOP_PUSH_TLS_GD 28\r
+#define R_LARCH_SOP_PUSH_PLT_PCREL 29\r
+#define R_LARCH_SOP_ASSERT 30\r
+#define R_LARCH_SOP_NOT 31\r
+#define R_LARCH_SOP_SUB 32\r
+#define R_LARCH_SOP_SL 33\r
+#define R_LARCH_SOP_SR 34\r
+#define R_LARCH_SOP_ADD 35\r
+#define R_LARCH_SOP_AND 36\r
+#define R_LARCH_SOP_IF_ELSE 37\r
+#define R_LARCH_SOP_POP_32_S_10_5 38\r
+#define R_LARCH_SOP_POP_32_U_10_12 39\r
+#define R_LARCH_SOP_POP_32_S_10_12 40\r
+#define R_LARCH_SOP_POP_32_S_10_16 41\r
+#define R_LARCH_SOP_POP_32_S_10_16_S2 42\r
+#define R_LARCH_SOP_POP_32_S_5_20 43\r
+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44\r
+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45\r
+#define R_LARCH_SOP_POP_32_U 46\r
+#define R_LARCH_ADD8 47\r
+#define R_LARCH_ADD16 48\r
+#define R_LARCH_ADD24 49\r
+#define R_LARCH_ADD32 50\r
+#define R_LARCH_ADD64 51\r
+#define R_LARCH_SUB8 52\r
+#define R_LARCH_SUB16 53\r
+#define R_LARCH_SUB24 54\r
+#define R_LARCH_SUB32 55\r
+#define R_LARCH_SUB64 56\r
+#define R_LARCH_GNU_VTINHERIT 57\r
+#define R_LARCH_GNU_VTENTRY 58\r
+#define R_LARCH_B16 64\r
+#define R_LARCH_B21 65\r
+#define R_LARCH_B26 66\r
+#define R_LARCH_ABS_HI20 67\r
+#define R_LARCH_ABS_LO12 68\r
+#define R_LARCH_ABS64_LO20 69\r
+#define R_LARCH_ABS64_HI12 70\r
+#define R_LARCH_PCALA_HI20 71\r
+#define R_LARCH_PCALA_LO12 72\r
+#define R_LARCH_PCALA64_LO20 73\r
+#define R_LARCH_PCALA64_HI12 74\r
+#define R_LARCH_GOT_PC_HI20 75\r
+#define R_LARCH_GOT_PC_LO12 76\r
+#define R_LARCH_GOT64_PC_LO20 77\r
+#define R_LARCH_GOT64_PC_HI12 78\r
+#define R_LARCH_GOT64_HI20 79\r
+#define R_LARCH_GOT64_LO12 80\r
+#define R_LARCH_GOT64_LO20 81\r
+#define R_LARCH_GOT64_HI12 82\r
+#define R_LARCH_TLS_LE_HI20 83\r
+#define R_LARCH_TLS_LE_LO12 84\r
+#define R_LARCH_TLS_LE64_LO20 85\r
+#define R_LARCH_TLS_LE64_HI12 86\r
+#define R_LARCH_TLS_IE_PC_HI20 87\r
+#define R_LARCH_TLS_IE_PC_LO12 88\r
+#define R_LARCH_TLS_IE64_PC_LO20 89\r
+#define R_LARCH_TLS_IE64_PC_HI12 90\r
+#define R_LARCH_TLS_IE64_HI20 91\r
+#define R_LARCH_TLS_IE64_LO12 92\r
+#define R_LARCH_TLS_IE64_LO20 93\r
+#define R_LARCH_TLS_IE64_HI12 94\r
+#define R_LARCH_TLS_LD_PC_HI20 95\r
+#define R_LARCH_TLS_LD64_HI20 96\r
+#define R_LARCH_TLS_GD_PC_HI20 97\r
+#define R_LARCH_TLS_GD64_HI20 98\r
+#define R_LARCH_RELAX 99\r
#endif /* !_SYS_ELF_COMMON_H_ */\r
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+ Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
//\r
// PE32+ Machine type for EFI images\r
//\r
-#define IMAGE_FILE_MACHINE_I386 0x014c\r
-#define IMAGE_FILE_MACHINE_EBC 0x0EBC\r
-#define IMAGE_FILE_MACHINE_X64 0x8664\r
-#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only\r
-#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian\r
-#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian\r
-#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA\r
+#define IMAGE_FILE_MACHINE_I386 0x014c\r
+#define IMAGE_FILE_MACHINE_EBC 0x0EBC\r
+#define IMAGE_FILE_MACHINE_X64 0x8664\r
+#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only\r
+#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian\r
+#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian\r
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA\r
+#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // 64bit LoongArch Architecture\r
\r
//\r
// Support old names for backward compatible\r
//\r
-#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386\r
-#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC\r
-#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64\r
-#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT\r
-#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64\r
-#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64\r
+#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386\r
+#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC\r
+#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64\r
+#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT\r
+#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64\r
+#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64\r
+#define EFI_IMAGE_MACHINE_LOONGARCH64 IMAGE_FILE_MACHINE_LOONGARCH64\r
\r
#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ\r
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE\r
//\r
// Based relocation types.\r
//\r
-#define EFI_IMAGE_REL_BASED_ABSOLUTE 0\r
-#define EFI_IMAGE_REL_BASED_HIGH 1\r
-#define EFI_IMAGE_REL_BASED_LOW 2\r
-#define EFI_IMAGE_REL_BASED_HIGHLOW 3\r
-#define EFI_IMAGE_REL_BASED_HIGHADJ 4\r
-#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5\r
-#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5\r
-#define EFI_IMAGE_REL_BASED_RISCV_HI20 5\r
-#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7\r
-#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7\r
-#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8\r
-#define EFI_IMAGE_REL_BASED_IA64_IMM64 9\r
-#define EFI_IMAGE_REL_BASED_DIR64 10\r
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0\r
+#define EFI_IMAGE_REL_BASED_HIGH 1\r
+#define EFI_IMAGE_REL_BASED_LOW 2\r
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3\r
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4\r
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5\r
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5\r
+#define EFI_IMAGE_REL_BASED_RISCV_HI20 5\r
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7\r
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7\r
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8\r
+#define EFI_IMAGE_REL_BASED_LOONGARCH32_MARK_LA 8\r
+#define EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA 8\r
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9\r
+#define EFI_IMAGE_REL_BASED_DIR64 10\r
\r
\r
///\r
ifneq (,$(findstring riscv64,$(uname_m)))\r
HOST_ARCH=RISCV64\r
endif\r
+ ifneq (,$(findstring loongarch64,$(uname_m)))\r
+ HOST_ARCH=LOONGARCH64\r
+ endif\r
ifndef HOST_ARCH\r
$(info Could not detected HOST_ARCH from uname results)\r
$(error HOST_ARCH is not defined!)\r
else ifeq ($(HOST_ARCH), RISCV64)\r
ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/\r
\r
+else ifeq ($(HOST_ARCH), LOONGARCH64)\r
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/LoongArch64/\r
+\r
else\r
$(error Bad HOST_ARCH)\r
endif\r