mirror of https://github.com/acidanthera/audk.git
BaseTools: BaseTools changes for RISC-V platform.
C code changes for building EDK2 RISC-V platform. Signed-off-by: Abner Chang <abner.chang@hpe.com> Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com> Co-authored-by: Daniel Helmut Schaefer <daniel.schaefer@hpe.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Reviewed-by: Bob Feng <bob.c.feng@intel.com> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Gilbert Chen <gilbert.chen@hpe.com>
This commit is contained in:
parent
cdc3fa5418
commit
ad1db975c0
|
@ -4,6 +4,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>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -59,6 +60,14 @@ PeCoffLoaderRelocateArmImage (
|
|||
IN UINT64 Adjust
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
PeCoffLoaderRelocateRiscVImage (
|
||||
IN UINT16 *Reloc,
|
||||
IN OUT CHAR8 *Fixup,
|
||||
IN OUT CHAR8 **FixupData,
|
||||
IN UINT64 Adjust
|
||||
);
|
||||
|
||||
STATIC
|
||||
RETURN_STATUS
|
||||
PeCoffLoaderGetPeHeader (
|
||||
|
@ -174,7 +183,8 @@ Returns:
|
|||
ImageContext->Machine != EFI_IMAGE_MACHINE_X64 && \
|
||||
ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \
|
||||
ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \
|
||||
ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64) {
|
||||
ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \
|
||||
ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {
|
||||
if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {
|
||||
//
|
||||
// There are two types of ARM images. Pure ARM and ARM/Thumb.
|
||||
|
@ -802,6 +812,9 @@ Returns:
|
|||
case EFI_IMAGE_MACHINE_ARMT:
|
||||
Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);
|
||||
break;
|
||||
case EFI_IMAGE_MACHINE_RISCV64:
|
||||
Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
|
||||
break;
|
||||
default:
|
||||
Status = RETURN_UNSUPPORTED;
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
Function prototypes and defines on Memory Only PE COFF loader
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -25,6 +26,14 @@
|
|||
#define IMAGE_ERROR_FAILED_RELOCATION 9
|
||||
#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10
|
||||
|
||||
//
|
||||
// Macro definitions for RISC-V architecture.
|
||||
//
|
||||
#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
|
||||
#define RISCV_IMM_BITS 12
|
||||
#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
|
||||
#define RISCV_CONST_HIGH_PART(VALUE) \
|
||||
(((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
|
||||
|
||||
//
|
||||
// PE/COFF Loader Read Function passed in by caller
|
||||
|
|
|
@ -3,6 +3,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>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
--*/
|
||||
|
@ -61,6 +62,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
#define IMM64_SIGN_INST_WORD_POS_X 27
|
||||
#define IMM64_SIGN_VAL_POS_X 63
|
||||
|
||||
UINT32 *RiscVHi20Fixup = NULL;
|
||||
|
||||
RETURN_STATUS
|
||||
PeCoffLoaderRelocateIa32Image (
|
||||
IN UINT16 *Reloc,
|
||||
|
@ -93,6 +96,89 @@ Returns:
|
|||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Performs an RISC-V specific relocation fixup
|
||||
|
||||
Arguments:
|
||||
|
||||
Reloc - Pointer to the relocation record
|
||||
|
||||
Fixup - Pointer to the address to fix up
|
||||
|
||||
FixupData - Pointer to a buffer to log the fixups
|
||||
|
||||
Adjust - The offset to adjust the fixup
|
||||
|
||||
Returns:
|
||||
|
||||
Status code
|
||||
|
||||
--*/
|
||||
RETURN_STATUS
|
||||
PeCoffLoaderRelocateRiscVImage (
|
||||
IN UINT16 *Reloc,
|
||||
IN OUT CHAR8 *Fixup,
|
||||
IN OUT CHAR8 **FixupData,
|
||||
IN UINT64 Adjust
|
||||
)
|
||||
{
|
||||
UINT32 Value;
|
||||
UINT32 Value2;
|
||||
UINT32 OrgValue;
|
||||
|
||||
OrgValue = *(UINT32 *) Fixup;
|
||||
OrgValue = OrgValue;
|
||||
switch ((*Reloc) >> 12) {
|
||||
case EFI_IMAGE_REL_BASED_RISCV_HI20:
|
||||
RiscVHi20Fixup = (UINT32 *) Fixup;
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
|
||||
if (RiscVHi20Fixup != NULL) {
|
||||
Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
|
||||
Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));
|
||||
if (Value2 & (RISCV_IMM_REACH/2)) {
|
||||
Value2 |= ~(RISCV_IMM_REACH-1);
|
||||
}
|
||||
Value += Value2;
|
||||
Value += (UINT32)Adjust;
|
||||
Value2 = RISCV_CONST_HIGH_PART (Value);
|
||||
*(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
|
||||
(RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
|
||||
*(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \
|
||||
(RV_X (*(UINT32 *)Fixup, 0, 20));
|
||||
}
|
||||
RiscVHi20Fixup = NULL;
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
|
||||
if (RiscVHi20Fixup != NULL) {
|
||||
Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
|
||||
Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));
|
||||
if (Value2 & (RISCV_IMM_REACH/2)) {
|
||||
Value2 |= ~(RISCV_IMM_REACH-1);
|
||||
}
|
||||
Value += Value2;
|
||||
Value += (UINT32)Adjust;
|
||||
Value2 = RISCV_CONST_HIGH_PART (Value);
|
||||
*(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
|
||||
(RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
|
||||
Value2 = *(UINT32 *)Fixup & 0x01fff07f;
|
||||
Value &= RISCV_IMM_REACH - 1;
|
||||
*(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
|
||||
}
|
||||
RiscVHi20Fixup = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
}
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
|
||||
|
|
|
@ -4,6 +4,7 @@ This file contains the internal functions required to generate a Firmware Volume
|
|||
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
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>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -37,6 +38,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000
|
||||
|
||||
BOOLEAN mArm = FALSE;
|
||||
BOOLEAN mRiscV = FALSE;
|
||||
STATIC UINT32 MaxFfsAlignment = 0;
|
||||
BOOLEAN VtfFileFlag = FALSE;
|
||||
|
||||
|
@ -2291,6 +2293,104 @@ Returns:
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
UpdateRiscvResetVectorIfNeeded (
|
||||
MEMORY_FILE *FvImage,
|
||||
FV_INFO *FvInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This parses the FV looking for SEC and patches that address into the
|
||||
beginning of the FV header.
|
||||
|
||||
For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h
|
||||
|
||||
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;
|
||||
UINT16 MachineType;
|
||||
EFI_FILE_SECTION_POINTER SecPe32;
|
||||
EFI_PHYSICAL_ADDRESS SecCoreEntryAddress;
|
||||
|
||||
UINT32 bSecCore;
|
||||
UINT32 tmp;
|
||||
|
||||
|
||||
//
|
||||
// Verify input parameters
|
||||
//
|
||||
if (FvImage == NULL || FvInfo == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
// Initialize FV library
|
||||
//
|
||||
InitializeFvLib (FvImage->FileImage, FvInfo->Size);
|
||||
|
||||
//
|
||||
// Find the Sec Core
|
||||
//
|
||||
Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
|
||||
if(EFI_ERROR(Status)) {
|
||||
printf("skip because Secutiry Core not found\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (MachineType != EFI_IMAGE_MACHINE_RISCV64) {
|
||||
Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Machine type is not RiscV.");
|
||||
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;
|
||||
}
|
||||
|
||||
VerboseMsg("SecCore entry point Address = 0x%llX", (unsigned long long) SecCoreEntryAddress);
|
||||
VerboseMsg("BaseAddress = 0x%llX", (unsigned long long) FvInfo->BaseAddress);
|
||||
bSecCore = (UINT32)(SecCoreEntryAddress - FvInfo->BaseAddress);
|
||||
VerboseMsg("offset = 0x%llX", bSecCore);
|
||||
|
||||
if(bSecCore > 0x0fffff) {
|
||||
Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of start of the FV");
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
tmp = bSecCore;
|
||||
bSecCore = 0;
|
||||
//J-type
|
||||
bSecCore = (tmp&0x100000)<<11; //imm[20] at bit[31]
|
||||
bSecCore |= (tmp&0x0007FE)<<20; //imm[10:1] at bit[30:21]
|
||||
bSecCore |= (tmp&0x000800)<<9; //imm[11] at bit[20]
|
||||
bSecCore |= (tmp&0x0FF000); //imm[19:12] at bit[19:12]
|
||||
bSecCore |= 0x6F; //JAL opcode
|
||||
|
||||
memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetPe32Info (
|
||||
IN UINT8 *Pe32,
|
||||
|
@ -2383,7 +2483,8 @@ Returns:
|
|||
// Verify machine type is supported
|
||||
//
|
||||
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_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&
|
||||
(*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {
|
||||
Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
@ -2826,7 +2927,8 @@ Returns:
|
|||
Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad file between the last file and the VTF file.");
|
||||
goto Finish;
|
||||
}
|
||||
if (!mArm) {
|
||||
|
||||
if (!mArm && !mRiscV) {
|
||||
//
|
||||
// Update reset vector (SALE_ENTRY for IPF)
|
||||
// Now for IA32 and IA64 platform, the fv which has bsf file must have the
|
||||
|
@ -2861,6 +2963,22 @@ Returns:
|
|||
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
|
||||
}
|
||||
|
||||
if (mRiscV) {
|
||||
//
|
||||
// Update RISCV reset vector.
|
||||
//
|
||||
Status = UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector for RISC-V.");
|
||||
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
|
||||
//
|
||||
|
@ -3448,6 +3566,10 @@ Returns:
|
|||
mArm = TRUE;
|
||||
}
|
||||
|
||||
if (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV64) {
|
||||
mRiscV = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Keep Image Context for PE image in FV
|
||||
//
|
||||
|
@ -3601,7 +3723,7 @@ Returns:
|
|||
ImageContext.DestinationAddress = NewPe32BaseAddress;
|
||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
|
||||
Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
|
||||
free ((VOID *) MemoryImagePointer);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ Elf32 Convert solution
|
|||
|
||||
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
@ -141,8 +142,8 @@ InitializeElf32 (
|
|||
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
|
||||
return FALSE;
|
||||
}
|
||||
if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) {
|
||||
Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");
|
||||
if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM) || (mEhdr->e_machine == EM_RISCV))) {
|
||||
Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf32 machine.");
|
||||
return FALSE;
|
||||
}
|
||||
if (mEhdr->e_version != EV_CURRENT) {
|
||||
|
|
|
@ -3,6 +3,7 @@ Elf64 convert solution
|
|||
|
||||
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
@ -122,6 +123,13 @@ STATIC UINT32 mHiiRsrcOffset;
|
|||
STATIC UINT32 mRelocOffset;
|
||||
STATIC UINT32 mDebugOffset;
|
||||
|
||||
//
|
||||
// Used for RISC-V relocations.
|
||||
//
|
||||
STATIC UINT8 *mRiscVPass1Targ = NULL;
|
||||
STATIC Elf_Shdr *mRiscVPass1Sym = NULL;
|
||||
STATIC Elf64_Half mRiscVPass1SymSecIndex = 0;
|
||||
|
||||
//
|
||||
// Initialization Function
|
||||
//
|
||||
|
@ -153,8 +161,8 @@ 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))) {
|
||||
Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64");
|
||||
if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {
|
||||
Error (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");
|
||||
return FALSE;
|
||||
}
|
||||
if (mEhdr->e_version != EV_CURRENT) {
|
||||
|
@ -452,6 +460,147 @@ EmitGOTRelocations (
|
|||
mGOTMaxCoffEntries = 0;
|
||||
mGOTNumCoffEntries = 0;
|
||||
}
|
||||
//
|
||||
// RISC-V 64 specific Elf WriteSection function.
|
||||
//
|
||||
STATIC
|
||||
VOID
|
||||
WriteSectionRiscV64 (
|
||||
Elf_Rela *Rel,
|
||||
UINT8 *Targ,
|
||||
Elf_Shdr *SymShdr,
|
||||
Elf_Sym *Sym
|
||||
)
|
||||
{
|
||||
UINT32 Value;
|
||||
UINT32 Value2;
|
||||
|
||||
switch (ELF_R_TYPE(Rel->r_info)) {
|
||||
case R_RISCV_NONE:
|
||||
break;
|
||||
|
||||
case R_RISCV_32:
|
||||
*(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
|
||||
break;
|
||||
|
||||
case R_RISCV_64:
|
||||
*(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
|
||||
break;
|
||||
|
||||
case R_RISCV_HI20:
|
||||
mRiscVPass1Targ = Targ;
|
||||
mRiscVPass1Sym = SymShdr;
|
||||
mRiscVPass1SymSecIndex = Sym->st_shndx;
|
||||
break;
|
||||
|
||||
case R_RISCV_LO12_I:
|
||||
if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {
|
||||
Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);
|
||||
Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
|
||||
if (Value2 & (RISCV_IMM_REACH/2)) {
|
||||
Value2 |= ~(RISCV_IMM_REACH-1);
|
||||
}
|
||||
Value += Value2;
|
||||
Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
|
||||
Value2 = RISCV_CONST_HIGH_PART (Value);
|
||||
*(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \
|
||||
(RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));
|
||||
*(UINT32 *)Targ = (RV_X (Value, 0, 12) << 20) | \
|
||||
(RV_X (*(UINT32 *)Targ, 0, 20));
|
||||
}
|
||||
mRiscVPass1Sym = NULL;
|
||||
mRiscVPass1Targ = NULL;
|
||||
mRiscVPass1SymSecIndex = 0;
|
||||
break;
|
||||
|
||||
case R_RISCV_LO12_S:
|
||||
if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) {
|
||||
Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12);
|
||||
Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)Targ, 25, 7) << 5));
|
||||
if (Value2 & (RISCV_IMM_REACH/2)) {
|
||||
Value2 |= ~(RISCV_IMM_REACH-1);
|
||||
}
|
||||
Value += Value2;
|
||||
Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
|
||||
Value2 = RISCV_CONST_HIGH_PART (Value);
|
||||
*(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \
|
||||
(RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12));
|
||||
Value2 = *(UINT32 *)Targ & 0x01fff07f;
|
||||
Value &= RISCV_IMM_REACH - 1;
|
||||
*(UINT32 *)Targ = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
|
||||
}
|
||||
mRiscVPass1Sym = NULL;
|
||||
mRiscVPass1Targ = NULL;
|
||||
mRiscVPass1SymSecIndex = 0;
|
||||
break;
|
||||
|
||||
case R_RISCV_PCREL_HI20:
|
||||
mRiscVPass1Targ = Targ;
|
||||
mRiscVPass1Sym = SymShdr;
|
||||
mRiscVPass1SymSecIndex = Sym->st_shndx;
|
||||
|
||||
Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));
|
||||
break;
|
||||
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
if (mRiscVPass1Targ != NULL && mRiscVPass1Sym != NULL && mRiscVPass1SymSecIndex != 0) {
|
||||
int i;
|
||||
Value2 = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20));
|
||||
Value = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
|
||||
if(Value & (RISCV_IMM_REACH/2)) {
|
||||
Value |= ~(RISCV_IMM_REACH-1);
|
||||
}
|
||||
Value = Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOffset[mRiscVPass1SymSecIndex];
|
||||
if(-2048 > (INT32)Value) {
|
||||
i = (((INT32)Value * -1) / 4096);
|
||||
Value2 -= i;
|
||||
Value += 4096 * i;
|
||||
if(-2048 > (INT32)Value) {
|
||||
Value2 -= 1;
|
||||
Value += 4096;
|
||||
}
|
||||
}
|
||||
else if( 2047 < (INT32)Value) {
|
||||
i = (Value / 4096);
|
||||
Value2 += i;
|
||||
Value -= 4096 * i;
|
||||
if(2047 < (INT32)Value) {
|
||||
Value2 += 1;
|
||||
Value -= 4096;
|
||||
}
|
||||
}
|
||||
|
||||
*(UINT32 *)Targ = (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Targ, 0, 20));
|
||||
*(UINT32 *)mRiscVPass1Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)mRiscVPass1Targ, 0, 12));
|
||||
}
|
||||
mRiscVPass1Sym = NULL;
|
||||
mRiscVPass1Targ = NULL;
|
||||
mRiscVPass1SymSecIndex = 0;
|
||||
break;
|
||||
|
||||
case R_RISCV_ADD64:
|
||||
case R_RISCV_SUB64:
|
||||
case R_RISCV_ADD32:
|
||||
case R_RISCV_SUB32:
|
||||
case R_RISCV_BRANCH:
|
||||
case R_RISCV_JAL:
|
||||
case R_RISCV_GPREL_I:
|
||||
case R_RISCV_GPREL_S:
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_RVC_BRANCH:
|
||||
case R_RISCV_RVC_JUMP:
|
||||
case R_RISCV_RELAX:
|
||||
case R_RISCV_SUB6:
|
||||
case R_RISCV_SET6:
|
||||
case R_RISCV_SET8:
|
||||
case R_RISCV_SET16:
|
||||
case R_RISCV_SET32:
|
||||
break;
|
||||
|
||||
default:
|
||||
Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Elf functions interface implementation
|
||||
|
@ -481,6 +630,7 @@ ScanSections64 (
|
|||
switch (mEhdr->e_machine) {
|
||||
case EM_X86_64:
|
||||
case EM_AARCH64:
|
||||
case EM_RISCV64:
|
||||
mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
|
||||
break;
|
||||
default:
|
||||
|
@ -690,6 +840,11 @@ ScanSections64 (
|
|||
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64;
|
||||
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
break;
|
||||
case EM_RISCV64:
|
||||
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
|
||||
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);
|
||||
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;
|
||||
|
@ -894,12 +1049,18 @@ WriteSections64 (
|
|||
SymName = (const UINT8 *)"<unknown>";
|
||||
}
|
||||
|
||||
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.",
|
||||
mInImageName, SymName, Sym->st_value);
|
||||
//
|
||||
// Skip error on EM_RISCV64 becasue no symble name is built
|
||||
// from RISC-V toolchain.
|
||||
//
|
||||
if (mEhdr->e_machine != EM_RISCV64) {
|
||||
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.",
|
||||
mInImageName, SymName, Sym->st_value);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
SymShdr = GetShdrByIndex(Sym->st_shndx);
|
||||
|
||||
|
@ -1151,6 +1312,11 @@ WriteSections64 (
|
|||
default:
|
||||
Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
|
||||
}
|
||||
} else if (mEhdr->e_machine == EM_RISCV64) {
|
||||
//
|
||||
// Write section for RISC-V 64 architecture.
|
||||
//
|
||||
WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
|
||||
} else {
|
||||
Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
|
||||
}
|
||||
|
@ -1170,6 +1336,7 @@ WriteRelocations64 (
|
|||
UINT32 Index;
|
||||
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
|
||||
EFI_IMAGE_DATA_DIRECTORY *Dir;
|
||||
UINT32 RiscVRelType;
|
||||
|
||||
for (Index = 0; Index < mEhdr->e_shnum; Index++) {
|
||||
Elf_Shdr *RelShdr = GetShdrByIndex(Index);
|
||||
|
@ -1276,6 +1443,107 @@ WriteRelocations64 (
|
|||
default:
|
||||
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
|
||||
}
|
||||
} else if (mEhdr->e_machine == EM_RISCV64) {
|
||||
RiscVRelType = ELF_R_TYPE(Rel->r_info);
|
||||
switch (RiscVRelType) {
|
||||
case R_RISCV_NONE:
|
||||
break;
|
||||
|
||||
case R_RISCV_32:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_HIGHLOW);
|
||||
break;
|
||||
|
||||
case R_RISCV_64:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_DIR64);
|
||||
break;
|
||||
|
||||
case R_RISCV_HI20:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_RISCV_HI20);
|
||||
break;
|
||||
|
||||
case R_RISCV_LO12_I:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_RISCV_LOW12I);
|
||||
break;
|
||||
|
||||
case R_RISCV_LO12_S:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_RISCV_LOW12S);
|
||||
break;
|
||||
|
||||
case R_RISCV_ADD64:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_SUB64:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_ADD32:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_SUB32:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_BRANCH:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_JAL:
|
||||
CoffAddFixup(
|
||||
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
|
||||
+ (Rel->r_offset - SecShdr->sh_addr)),
|
||||
EFI_IMAGE_REL_BASED_ABSOLUTE);
|
||||
break;
|
||||
|
||||
case R_RISCV_GPREL_I:
|
||||
case R_RISCV_GPREL_S:
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_RVC_BRANCH:
|
||||
case R_RISCV_RVC_JUMP:
|
||||
case R_RISCV_RELAX:
|
||||
case R_RISCV_SUB6:
|
||||
case R_RISCV_SET6:
|
||||
case R_RISCV_SET8:
|
||||
case R_RISCV_SET16:
|
||||
case R_RISCV_SET32:
|
||||
case R_RISCV_PCREL_HI20:
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
break;
|
||||
|
||||
default:
|
||||
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_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);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,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>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
||||
|
@ -178,6 +179,8 @@ typedef struct {
|
|||
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
|
||||
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
|
||||
#define EM_AARCH64 183 /* ARM 64bit Architecture */
|
||||
#define EM_RISCV64 243 /* 64bit RISC-V Architecture */
|
||||
#define EM_RISCV 244 /* 32bit RISC-V Architecture */
|
||||
|
||||
/* Non-standard or deprecated. */
|
||||
#define EM_486 6 /* Intel i486. */
|
||||
|
@ -979,5 +982,64 @@ typedef struct {
|
|||
#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */
|
||||
#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */
|
||||
|
||||
/*
|
||||
* RISC-V relocation types
|
||||
*/
|
||||
|
||||
/* Relocation types used by the dynamic linker */
|
||||
#define R_RISCV_NONE 0
|
||||
#define R_RISCV_32 1
|
||||
#define R_RISCV_64 2
|
||||
#define R_RISCV_RELATIVE 3
|
||||
#define R_RISCV_COPY 4
|
||||
#define R_RISCV_JUMP_SLOT 5
|
||||
#define R_RISCV_TLS_DTPMOD32 6
|
||||
#define R_RISCV_TLS_DTPMOD64 7
|
||||
#define R_RISCV_TLS_DTPREL32 8
|
||||
#define R_RISCV_TLS_DTPREL64 9
|
||||
#define R_RISCV_TLS_TPREL32 10
|
||||
#define R_RISCV_TLS_TPREL64 11
|
||||
|
||||
/* Relocation types not used by the dynamic linker */
|
||||
#define R_RISCV_BRANCH 16
|
||||
#define R_RISCV_JAL 17
|
||||
#define R_RISCV_CALL 18
|
||||
#define R_RISCV_CALL_PLT 19
|
||||
#define R_RISCV_GOT_HI20 20
|
||||
#define R_RISCV_TLS_GOT_HI20 21
|
||||
#define R_RISCV_TLS_GD_HI20 22
|
||||
#define R_RISCV_PCREL_HI20 23
|
||||
#define R_RISCV_PCREL_LO12_I 24
|
||||
#define R_RISCV_PCREL_LO12_S 25
|
||||
#define R_RISCV_HI20 26
|
||||
#define R_RISCV_LO12_I 27
|
||||
#define R_RISCV_LO12_S 28
|
||||
#define R_RISCV_TPREL_HI20 29
|
||||
#define R_RISCV_TPREL_LO12_I 30
|
||||
#define R_RISCV_TPREL_LO12_S 31
|
||||
#define R_RISCV_TPREL_ADD 32
|
||||
#define R_RISCV_ADD8 33
|
||||
#define R_RISCV_ADD16 34
|
||||
#define R_RISCV_ADD32 35
|
||||
#define R_RISCV_ADD64 36
|
||||
#define R_RISCV_SUB8 37
|
||||
#define R_RISCV_SUB16 38
|
||||
#define R_RISCV_SUB32 39
|
||||
#define R_RISCV_SUB64 40
|
||||
#define R_RISCV_GNU_VTINHERIT 41
|
||||
#define R_RISCV_GNU_VTENTRY 42
|
||||
#define R_RISCV_ALIGN 43
|
||||
#define R_RISCV_RVC_BRANCH 44
|
||||
#define R_RISCV_RVC_JUMP 45
|
||||
#define R_RISCV_RVC_LUI 46
|
||||
#define R_RISCV_GPREL_I 47
|
||||
#define R_RISCV_GPREL_S 48
|
||||
#define R_RISCV_TPREL_I 49
|
||||
#define R_RISCV_TPREL_S 50
|
||||
#define R_RISCV_RELAX 51
|
||||
#define R_RISCV_SUB6 52
|
||||
#define R_RISCV_SET6 53
|
||||
#define R_RISCV_SET8 54
|
||||
#define R_RISCV_SET16 55
|
||||
#define R_RISCV_SET32 56
|
||||
#endif /* !_SYS_ELF_COMMON_H_ */
|
||||
|
|
|
@ -6,6 +6,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>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
|
@ -41,6 +42,7 @@
|
|||
#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
|
||||
|
||||
//
|
||||
// Support old names for backward compatible
|
||||
|
@ -50,6 +52,7 @@
|
|||
#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_DOS_SIGNATURE 0x5A4D // MZ
|
||||
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
|
||||
|
@ -504,7 +507,10 @@ typedef struct {
|
|||
#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
|
||||
|
||||
|
|
Loading…
Reference in New Issue