BaseTools: Update GenFw/GenFv to support 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>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
Chao Li
2022-09-06 21:00:07 +08:00
committed by mergify[bot]
parent 082b563fc4
commit 1aa311d175
7 changed files with 636 additions and 33 deletions

View File

@@ -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] |= 0x50000000; /* b 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
//