X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FGenFvImage%2FGenFvImageLib.c;fp=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FGenFvImage%2FGenFvImageLib.c;h=0000000000000000000000000000000000000000;hp=f356229d438e28e19b6db8d17d9e7ba0521f68f9;hb=c455bc8c8d78ad51c24426a500914ea32504bf06;hpb=5bca07268acabe7f31407358e875ccf89cb5e386 diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.c deleted file mode 100644 index f356229d43..0000000000 --- a/EdkCompatibilityPkg/Sample/Tools/Source/GenFvImage/GenFvImageLib.c +++ /dev/null @@ -1,3221 +0,0 @@ -/*++ - -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - GenFvImageLib.c - -Abstract: - - This file contains functions required to generate a Firmware Volume. - ---*/ - -// -// Include files -// -#include "GenFvImageLib.h" -#include "GenFvImageLibInternal.h" -#include -#include EFI_GUID_DEFINITION (PeiPeCoffLoader) -#include "EfiFirmwareFileSystem.h" -#include "EfiWorkingBlockHeader.h" -#include "EfiVariable.h" -#include -#include -#include "CommonLib.h" -#include "FvLib.h" -#include "EfiImage.h" -#include "crc32.h" -#include "EfiUtilityMsgs.h" -#include EFI_GUID_DEFINITION (FirmwareFileSystem) -#include EFI_GUID_DEFINITION (FirmwareFileSystem2) - -// -// Define the PE/COFF loader -// -extern EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader; - -// -// Local function prototypes -// -EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, - OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, - OUT UINT16 *MachineType - ); - -// -// Local function implementations. -// -#if (PI_SPECIFICATION_VERSION < 0x00010000) -EFI_GUID FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; -#else -EFI_GUID FfsGuid = EFI_FIRMWARE_FILE_SYSTEM2_GUID; -#endif - -EFI_GUID DefaultFvPadFileNameGuid = { 0x78f54d4, 0xcc22, 0x4048, 0x9e, 0x94, 0x87, 0x9c, 0x21, 0x4d, 0x56, 0x2f }; - -// -// This data array will be located at the base of the Firmware Volume Header (FVH) -// in the boot block. It must not exceed 14 bytes of code. The last 2 bytes -// will be used to keep the FVH checksum consistent. -// This code will be run in response to a starutp IPI for HT-enabled systems. -// -#define SIZEOF_STARTUP_DATA_ARRAY 0x10 - -UINT8 m128kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { - // - // EA D0 FF 00 F0 ; far jmp F000:FFD0 - // 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes - // 0, 0 ; Checksum Padding - // - 0xEA, - 0xD0, - 0xFF, - 0x0, - 0xF0, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -UINT8 m64kRecoveryStartupApDataArray[SIZEOF_STARTUP_DATA_ARRAY] = { - // - // EB CE ; jmp short ($-0x30) - // ; (from offset 0x0 to offset 0xFFD0) - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; Reserved bytes - // 0, 0 ; Checksum Padding - // - 0xEB, - 0xCE, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -EFI_STATUS -ParseFvInf ( - IN MEMORY_FILE *InfFile, - IN FV_INFO *FvInfo - ) -/*++ - -Routine Description: - - This function parses a FV.INF file and copies info into a FV_INFO structure. - -Arguments: - - InfFile Memory file image. - FvInfo Information read from INF file. - -Returns: - - EFI_SUCCESS INF file information successfully retrieved. - EFI_ABORTED INF file has an invalid format. - EFI_NOT_FOUND A required string was not found in the INF file. ---*/ -{ - CHAR8 Value[_MAX_PATH]; - UINT64 Value64; - UINTN Index; - EFI_STATUS Status; - - // - // Initialize FV info - // - memset (FvInfo, 0, sizeof (FV_INFO)); - - // - // Read the FV base address - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_BASE_ADDRESS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Get the base address - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "invalid value"); - return EFI_ABORTED; - } - - FvInfo->BaseAddress = Value64; - } else { - Error (NULL, 0, 0, EFI_FV_BASE_ADDRESS_STRING, "could not find value"); - return EFI_ABORTED; - } - // - // Read the FV Guid - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_GUID_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Get the guid value - // - Status = StringToGuid (Value, &FvInfo->FvGuid); - if (EFI_ERROR (Status)) { - memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); - } - } else { - memcpy (&FvInfo->FvGuid, &FfsGuid, sizeof (EFI_GUID)); - } - // - // Read the FV file name - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_FV_FILE_NAME_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // copy the file name - // - strcpy (FvInfo->FvName, Value); - } else { - Error (NULL, 0, 0, EFI_FV_FILE_NAME_STRING, "value not specified"); - return EFI_ABORTED; - } - // - // Read the Sym file name - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_SYM_FILE_NAME_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // copy the file name - // - strcpy (FvInfo->SymName, Value); - } else { - // - // Symbols not required, so init to NULL. - // - strcpy (FvInfo->SymName, ""); - } - // - // Read the read disabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_DISABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_DISABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_DISABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the read enabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_ENABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_ENABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_ENABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the read status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the read disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_READ_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the write disabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_DISABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_DISABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_DISABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the write enabled capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_ENABLED_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_ENABLED_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_ENABLED_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the write status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the write disabled flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_WRITE_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the lock capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_LOCK_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_LOCK_CAP_STRING, "value not specified"); - return Status; - } - // - // Read the lock status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_LOCK_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_LOCK_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_LOCK_STATUS_STRING, "value not specified"); - return Status; - } - // - // Read the sticky write attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_STICKY_WRITE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_STICKY_WRITE; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_STICKY_WRITE_STRING, "value not specified"); - return Status; - } - // - // Read the memory mapped attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_MEMORY_MAPPED_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_MEMORY_MAPPED; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_MEMORY_MAPPED_STRING, "value not specified"); - return Status; - } - // - // Read the erase polarity attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ERASE_POLARITY_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the attribute flag - // - if (strcmp (Value, ONE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ERASE_POLARITY; - } else if (strcmp (Value, ZERO_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ERASE_POLARITY_STRING, "value not specified"); - return Status; - } - -#if (PI_SPECIFICATION_VERSION >= 0x00010000) - // - // Read the read lock capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_LOCK_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_READ_LOCK_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_LOCK_CAP_STRING, "value not specified"); - return Status; - } - - // - // Read the read lock status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_READ_LOCK_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_READ_LOCK_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_READ_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_READ_LOCK_STATUS_STRING, "value not specified"); - return Status; - } - - // - // Read the write lock capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_LOCK_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_WRITE_LOCK_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_LOCK_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_LOCK_CAP_STRING, "value not specified"); - return Status; - } - - // - // Read the write lock status attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_WRITE_LOCK_STATUS_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_WRITE_LOCK_STATUS; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_WRITE_LOCK_STATUS_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_WRITE_LOCK_STATUS_STRING, "value not specified"); - return Status; - } -#endif - -#if (PI_SPECIFICATION_VERSION < 0x00010000) - // - // Read the alignment capabilities attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_CAP_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_CAP; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_CAP_STRING, "value not specified"); - return Status; - } - - // - // Read the word alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2_STRING, "value not specified"); - return Status; - } - - - // - // Read the dword alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4_STRING, "value not specified"); - return Status; - } - // - // Read the word alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8_STRING, "value not specified"); - return Status; - } - // - // Read the qword alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16_STRING, "value not specified"); - return Status; - } - // - // Read the 32 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32_STRING, "value not specified"); - return Status; - } - // - // Read the 64 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64_STRING, "value not specified"); - return Status; - } - // - // Read the 128 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_128_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_128; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_128_STRING, "value not specified"); - return Status; - } - // - // Read the 256 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_256_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_256; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_256_STRING, "value not specified"); - return Status; - } - // - // Read the 512 byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_512_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_512; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_512_STRING, "value not specified"); - return Status; - } - // - // Read the 1K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_1K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_1K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_1K_STRING, "value not specified"); - return Status; - } - // - // Read the 2K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_2K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_2K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_2K_STRING, "value not specified"); - return Status; - } - // - // Read the 4K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_4K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_4K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_4K_STRING, "value not specified"); - return Status; - } - // - // Read the 8K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_8K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_8K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_8K_STRING, "value not specified"); - return Status; - } - // - // Read the 16K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_16K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_16K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_16K_STRING, "value not specified"); - return Status; - } - // - // Read the 32K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_32K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_32K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_32K_STRING, "value not specified"); - return Status; - } - // - // Read the 64K byte alignment capability attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB_ALIGNMENT_64K_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, TRUE_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB_ALIGNMENT_64K; - } else if (strcmp (Value, FALSE_STRING) != 0) { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "expected %s | %s", TRUE_STRING, FALSE_STRING); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB_ALIGNMENT_64K_STRING, "value not specified"); - return Status; - } - - if (!(FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_CAP) && - ( - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_128) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_256) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_512) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_1K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_2K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_4K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_8K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_16K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_32K) || - (FvInfo->FvAttributes & EFI_FVB_ALIGNMENT_64K) - ) - ){ - Error ( - NULL, - 0, - 0, - "illegal combination of alignment attributes", - "if %s is not %s, no individual alignments can be %s", - EFI_FVB_ALIGNMENT_CAP_STRING, - TRUE_STRING, - TRUE_STRING - ); - return EFI_ABORTED; - } -#else - // - // Read the PI1.0 FVB2 Alignment Capabilities Attribute - // - Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FVB2_ALIGNMENT_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Update attribute - // - if (strcmp (Value, EFI_FVB2_ALIGNMENT_1_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_1; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_2_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_2; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_4_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_4; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_8_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_8; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_16_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_16; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_32_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_32; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_64_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_64; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_128_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_128; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_256_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_256; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_512_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_512; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_1K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_1K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_2K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_2K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_4K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_4K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_8K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_8K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_16K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_16K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_32K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_32K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_64K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_64K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_128K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_128K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_256K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_256K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_512K_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_512K; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_1M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_1M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_2M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_2M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_4M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_4M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_8M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_8M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_16M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_16M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_32M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_32M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_64M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_64M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_128M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_128M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_256M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_256M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_512M_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_512M; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_1G_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_1G; - } else if (strcmp (Value, EFI_FVB2_ALIGNMENT_2G_STRING) == 0) { - FvInfo->FvAttributes |= EFI_FVB2_ALIGNMENT_2G; - } else { - Error (NULL, 0, 0, EFI_FVB2_ALIGNMENT_STRING, "value not correct!"); - return EFI_ABORTED; - } - } else { - Error (NULL, 0, 0, EFI_FVB2_ALIGNMENT_STRING, "value not specified"); - return Status; - } - -#endif - // - // Read block maps - // - for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) { - // - // Read the number of blocks - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - if (strcmp (Value, AUTO_STRING) == 0) { - Value64 = (UINT64) -1; - } else { - // - // Update the number of blocks - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, Value, "invalid value for %s", EFI_NUM_BLOCKS_STRING); - return EFI_ABORTED; - } - } - - FvInfo->FvBlocks[Index].NumBlocks = (UINT32) Value64; - } else { - // - // If there is no number of blocks, but there is a size, then we have a mismatched pair - // and should return an error. - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); - if (!EFI_ERROR (Status)) { - Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } else { - // - // We are done - // - break; - } - } - // - // Read the size of blocks - // - Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - // - // Update the number of blocks - // - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, Value, "invalid value specified for %s", EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvBlocks[Index].BlockLength = (UINT32) Value64; - } else { - // - // There is a number of blocks, but there is no size, so we have a mismatched pair - // and should return an error. - // - Error (NULL, 0, 0, "must specify both", "%s and %s", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING); - return EFI_ABORTED; - } - } - // - // Read files - // - for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) { - // - // Read the number of blocks - // - Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the file - // - strcpy (FvInfo->FvFiles[Index], Value); - } else { - break; - } - } - - if (FindSection (InfFile, COMPONENT_SECTION_STRING)) { - Index = 0; - while (TRUE) { - Status = FindTokenInstanceInSection ( - InfFile, - COMPONENT_SECTION_STRING, - Index, - FvInfo->FvComponents[Index].ComponentName, - Value - ); - if (EFI_ERROR (Status)) { - break; - } - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, Value, "not a valid integer"); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - Index++; - } - } - // - // Compute size for easy access later - // - FvInfo->Size = 0; - for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) { - if ((FvInfo->Size == (UINTN) -1 && Index > 0) || - (FvInfo->FvBlocks[Index].NumBlocks == (UINT32) -1 && Index > 0) - ) { - // - // Error 1. more pairs after AUTO - // Error 2. AUTO appear in non-first position - // - Error (NULL, 0, 0, NULL, "cannot have more than one pair of %s and %s if %s is set to %s", - EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING, - EFI_NUM_BLOCKS_STRING, AUTO_STRING - ); - return EFI_ABORTED; - } - - if (FvInfo->FvBlocks[Index].NumBlocks == (UINT32) -1) { - FvInfo->Size = (UINTN) -1; - } else { - FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength; - } - } - - if (FvInfo->Size == (UINTN) -1 && FvInfo->FvFiles[0][0] == 0) { - // - // Non FFS FV cannot set block number to AUTO - // - Error (NULL, 0, 0, "non-FFS FV", "cannot set %s to %s", EFI_NUM_BLOCKS_STRING, AUTO_STRING); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -VOID -UpdateFfsFileState ( - IN EFI_FFS_FILE_HEADER *FfsFile, - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ) -/*++ - -Routine Description: - - This function changes the FFS file attributes based on the erase polarity - of the FV. - -Arguments: - - FfsFile File header. - FvHeader FV header. - -Returns: - - None - ---*/ -{ - if (FvHeader->Attributes & EFI_FVB_ERASE_POLARITY) { - FfsFile->State = (UINT8)~(FfsFile->State); - } -} - -EFI_STATUS -ReadFfsAlignment ( - IN EFI_FFS_FILE_HEADER *FfsFile, - IN OUT UINT32 *Alignment - ) -/*++ - -Routine Description: - - This function determines the alignment of the FFS input file from the file - attributes. - -Arguments: - - FfsFile FFS file to parse - Alignment The minimum required alignment of the FFS file, in bytes - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - ---*/ -{ - // - // Verify input parameters. - // - if (FfsFile == NULL || Alignment == NULL) { - return EFI_INVALID_PARAMETER; - } - - switch ((FfsFile->Attributes >> 3) & 0x07) { - - case 0: - // - // 1 byte alignment - // - *Alignment = (1 << 0); - break; - - case 1: - // - // 16 byte alignment - // - *Alignment = (1 << 4); - break; - - case 2: - // - // 128 byte alignment - // - *Alignment = (1 << 7); - break; - - case 3: - // - // 512 byte alignment - // - *Alignment = (1 << 9); - break; - - case 4: - // - // 1K byte alignment - // - *Alignment = (1 << 10); - break; - - case 5: - // - // 4K byte alignment - // - *Alignment = (1 << 12); - break; - - case 6: - // - // 32K byte alignment - // - *Alignment = (1 << 15); - break; - - case 7: - // - // 64K byte alignment - // - *Alignment = (1 << 16); - break; - - default: - Error (NULL, 0, 0, "nvalid file attribute calculated, this is most likely a utility error", NULL); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -AddPadFile ( - IN OUT MEMORY_FILE *FvImage, - IN UINT32 DataAlignment - ) -/*++ - -Routine Description: - - This function adds a pad file to the FV image if it required to align the - data of the next file. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - DataAlignment The data alignment of the next FFS file. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_OUT_OF_RESOURCES Insufficient resources exist in the FV to complete - the pad file add. - ---*/ -{ - EFI_FFS_FILE_HEADER *PadFile; - UUID PadFileGuid; - UINTN PadFileSize; - - // - // Verify input parameters. - // - if (FvImage == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Basic assumption is we start from an 8 byte aligned address - // and our file header is a multiple of 8 bytes - // - assert ((UINTN) FvImage->CurrentFilePointer % 8 == 0); - assert (sizeof (EFI_FFS_FILE_HEADER) % 8 == 0); - - // - // Check if a pad file is necessary - // - if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0) { - return EFI_SUCCESS; - } - // - // Write pad file header - // - PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; - - // - // Verify that we have enough space for the file header - // - if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { - return EFI_OUT_OF_RESOURCES; - } - - UuidCreate (&PadFileGuid); - memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&PadFile->Name, &PadFileGuid, sizeof (EFI_GUID)); - PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; - PadFile->Attributes = 0; - - // - // Calculate the pad file size - // - // - // This is the earliest possible valid offset (current plus pad file header - // plus the next file header) - // - PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2); - - // - // Add whatever it takes to get to the next aligned address - // - while ((PadFileSize % DataAlignment) != 0) { - PadFileSize++; - } - // - // Subtract the next file header size - // - PadFileSize -= sizeof (EFI_FFS_FILE_HEADER); - - // - // Subtract the starting offset to get size - // - PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage; - - // - // Write pad file size (calculated size minus next file header size) - // - PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF); - PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF); - PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF); - - // - // Fill in checksums and state, they must be 0 for checksumming. - // - PadFile->IntegrityCheck.Checksum.Header = 0; - PadFile->IntegrityCheck.Checksum.File = 0; - PadFile->State = 0; - PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); - if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { -#if (PI_SPECIFICATION_VERSION < 0x00010000) - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize); -#else - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) ((UINTN)PadFile + sizeof (EFI_FFS_FILE_HEADER)), PadFileSize - sizeof (EFI_FFS_FILE_HEADER)); -#endif - } else { - PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) PadFile, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - - // - // Verify that we have enough space (including the padding - // - if ((UINTN) (PadFile + sizeof (EFI_FFS_FILE_HEADER)) >= (UINTN) FvImage->Eof) { - return EFI_OUT_OF_RESOURCES; - } - // - // Update the current FV pointer - // - FvImage->CurrentFilePointer += PadFileSize; - - return EFI_SUCCESS; -} - -BOOLEAN -IsVtfFile ( - IN EFI_FFS_FILE_HEADER *FileBuffer - ) -/*++ - -Routine Description: - - This function checks the header to validate if it is a VTF file - -Arguments: - - FileBuffer Buffer in which content of a file has been read. - -Returns: - - TRUE If this is a VTF file - FALSE If this is not a VTF file - ---*/ -{ - EFI_GUID VtfGuid = EFI_FFS_VOLUME_TOP_FILE_GUID; - if (!memcmp (&FileBuffer->Name, &VtfGuid, sizeof (EFI_GUID))) { - return TRUE; - } else { - return FALSE; - } -} - -EFI_STATUS -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -RebaseFfsFile ( - IN OUT EFI_FFS_FILE_HEADER *FfsFile, - IN EFI_PHYSICAL_ADDRESS BaseAddress - ) -/*++ - -Routine Description: - - This function determines if a file is XIP and should be rebased. It will - rebase any PE32 sections found in the file using the base address. - -Arguments: - - FfsFile A pointer to Ffs file image. - BaseAddress The base address to use for rebasing the file image. - -Returns: - - EFI_SUCCESS The image was properly rebased. - EFI_INVALID_PARAMETER An input parameter is invalid. - EFI_ABORTED An error occurred while rebasing the input file image. - EFI_OUT_OF_RESOURCES Could not allocate a required resource. - ---*/ -{ - EFI_STATUS Status; - EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN MemoryImagePointer; - UINTN MemoryImagePointerAligned; - - EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - EFI_PHYSICAL_ADDRESS EntryPoint; - - UINT32 Pe32FileSize; - UINT32 NewPe32BaseAddress; - - UINTN Index; - EFI_FILE_SECTION_POINTER CurrentPe32Section; - UINT8 FileGuidString[80]; - - // - // Verify input parameters - // - if (FfsFile == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Convert the GUID to a string so we can at least report which file - // if we find an error. - // - PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE); - - // - // Do some nominal checks on the file, then check for XIP. - // - Status = VerifyFfsFile (FfsFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "invalid FFS file", FileGuidString); - return EFI_INVALID_PARAMETER; - } - - if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && - FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && - FfsFile->Type != EFI_FV_FILETYPE_PEIM - ) { - // - // File is not XIP, so don't rebase - // - return EFI_SUCCESS; - } - // - // Rebase each PE32 section - // - for (Index = 1;; Index++) { - Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); - if (EFI_ERROR (Status)) { - break; - } - // - // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section - // - NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section - (UINTN) FfsFile); - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION)); - ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - - Status = mPeCoffLoader.GetImageInfo (&mPeCoffLoader, &ImageContext); - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "GetImageInfo() failed", FileGuidString); - return Status; - } - // - // Allocate a buffer for the image to be loaded into. - // - Pe32FileSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size); - MemoryImagePointer = (UINTN) (malloc (Pe32FileSize + 0x1000)); - MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12); - if (MemoryImagePointerAligned == 0) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return EFI_OUT_OF_RESOURCES; - } - - // - // bugbug - // - ImageContext.ImageAddress = MemoryImagePointerAligned; - Status = mPeCoffLoader.LoadImage (&mPeCoffLoader, &ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "LoadImage() failure", FileGuidString); - free ((VOID *) MemoryImagePointer); - return Status; - } - - Status = mPeCoffLoader.RelocateImage (&mPeCoffLoader, &ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "RelocateImage() failure", FileGuidString); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageAddress = ImageContext.ImageAddress; - ImageSize = ImageContext.ImageSize; - EntryPoint = ImageContext.EntryPoint; - - if (ImageSize > Pe32FileSize) { - Error ( - NULL, - 0, - 0, - "rebased PE32 is larger than original PE32 image", - "0x%X > 0x%X on file %s", - ImageSize, - Pe32FileSize, - FileGuidString - ); - free ((VOID *) MemoryImagePointer); - return EFI_ABORTED; - } - - memcpy (CurrentPe32Section.Pe32Section, (VOID *) MemoryImagePointerAligned, Pe32FileSize); - - free ((VOID *) MemoryImagePointer); - } - // - // the above for loop will always exit with EFI_NOT_FOUND if it completes - // normally. If Index == 1 at exit, then no PE32 sections were found. If it - // exits with any other error code, then something broke... - // - if (Status != EFI_NOT_FOUND) { - Error (NULL, 0, 0, "failed to parse PE32 section", FileGuidString); - return Status; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -AddSymFile ( - IN UINT64 BaseAddress, - IN EFI_FFS_FILE_HEADER *FfsFile, - IN OUT MEMORY_FILE *SymImage, - IN CHAR8 *SourceFileName - ) -/*++ - -Routine Description: - - This function adds the SYM tokens in the source file to the destination file. - The SYM tokens are updated to reflect the base address. - -Arguments: - - BaseAddress The base address for the new SYM tokens. - FfsFile Pointer to the beginning of the FFS file in question. - SymImage The memory file to update with symbol information. - SourceFileName The source file. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - ---*/ -{ - FILE *SourceFile; - - CHAR8 Buffer[_MAX_PATH]; - CHAR8 Type[_MAX_PATH]; - CHAR8 Address[_MAX_PATH]; - CHAR8 Section[_MAX_PATH]; - CHAR8 Token[_MAX_PATH]; - CHAR8 SymFileName[_MAX_PATH]; - CHAR8 CodeModuleName[_MAX_PATH]; - CHAR8 *Ptr; - - UINT64 TokenAddress; - - EFI_STATUS Status; - EFI_FILE_SECTION_POINTER Pe32Section; - UINT32 EntryPoint; - UINT32 BaseOfCode; - UINT16 MachineType; - - // - // Verify input parameters. - // - if (BaseAddress == 0 || FfsFile == NULL || SymImage == NULL || SourceFileName == NULL) { - Error (NULL, 0, 0, "invalid parameter passed to AddSymFile()", NULL); - return EFI_INVALID_PARAMETER; - } - // - // Check if we want to add this file - // - // - // Get the file name - // - strcpy (Buffer, SourceFileName); - - // - // Copy the file name for the path of the sym file and truncate the name portion. - // - strcpy (SymFileName, Buffer); - Ptr = strrchr (SymFileName, '\\'); - assert (Ptr); - Ptr[0] = 0; - - // - // Find the file extension and make it lower case - // - Ptr = strrchr (SymFileName, '.'); - if (Ptr != NULL) { - _strlwr (Ptr); - } - // - // Check if it is PEI file - // - if (strstr (Buffer, ".pei") != NULL) { - // - // Find the human readable portion - // - if (!strtok (Buffer, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strtok (NULL, "-") || - !strcpy (Buffer, strtok (NULL, ".")) - ) { - Error (NULL, 0, 0, "failed to find human readable portion of the file name in AddSymFile()", NULL); - return EFI_ABORTED; - } - // - // Save code module name - // - strcpy (CodeModuleName, Buffer); - - // - // Add the symbol file name and extension to the file path. - // - strcat (Buffer, ".sym"); - strcat (SymFileName, "\\"); - strcat (SymFileName, Buffer); - } else { - // - // Only handle PEIM files. - // - return EFI_SUCCESS; - } - // - // Find PE32 section - // - Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, 1, &Pe32Section); - - // - // BUGBUG: Assume if no PE32 section it is PIC and hardcode base address - // - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (FfsFile, EFI_SECTION_TE, 1, &Pe32Section); - } - - if (Status == EFI_SUCCESS) { - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - } else { - if (Status == EFI_NOT_FOUND) { - BaseOfCode = 0x60; - Status = EFI_SUCCESS; - } else { - Error (NULL, 0, 0, "could not parse a PE32 section from the PEI file", NULL); - return Status; - } - } - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "GetPe32Info() could not get PE32 entry point for PEI file", NULL); - return Status; - } - - // - // Open the source file - // - SourceFile = fopen (SymFileName, "r"); - if (SourceFile == NULL) { - // - // SYM files are not required. - // - return EFI_SUCCESS; - } - // - // Read the first line - // - if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) { - Buffer[0] = 0; - } - // - // Make sure it matches the expected sym format - // - if (strcmp (Buffer, "TEXTSYM format | V1.0\n")) { - fclose (SourceFile); - Error (NULL, 0, 0, "AddSymFile() found unexpected sym format in input file", NULL); - return EFI_ABORTED; - } - // - // Read in the file - // - while (feof (SourceFile) == 0) { - // - // Read a line - // - if (fscanf ( - SourceFile, - "%s | %s | %s | %s\n", - Type, - Address, - Section, - Token - ) == 4) { - // - // If the token starts with "??" ignore it - // - if (Token[0] == '?' && Token[1] == '?') { - continue; - } - // - // Get the token address - // - AsciiStringToUint64 (Address, TRUE, &TokenAddress); - - // - // Add the base address - // - TokenAddress += BaseAddress; - - // - // If PE32 or TE section then find the start of code. For PIC it is hardcoded. - // - if (Pe32Section.Pe32Section) { - // - // Add the offset of the PE32 section - // - TokenAddress += (UINTN) Pe32Section.Pe32Section - (UINTN) FfsFile; - - // - // Add the size of the PE32 section header - // - TokenAddress += sizeof (EFI_PE32_SECTION); - } else { - // - // BUGBUG: Don't know why this is 0x28 bytes. - // - TokenAddress += 0x28; - } - // - // Add the beginning of the code - // - TokenAddress += BaseOfCode; - - sprintf ( - Buffer, - "%s | %016I64X | %s | _%s%s\n", - Type, - TokenAddress, - Section, - CodeModuleName, - Token - ); - memcpy (SymImage->CurrentFilePointer, Buffer, strlen (Buffer) + 1); - SymImage->CurrentFilePointer = (UINT8 *) (((UINTN) SymImage->CurrentFilePointer) + strlen (Buffer) + 1); - } - } - - fclose (SourceFile); - return EFI_SUCCESS; -} - -EFI_STATUS -ReallocateFvImage ( - IN OUT MEMORY_FILE *FvImage, - IN OUT FV_INFO *FvInfo, - IN OUT EFI_FFS_FILE_HEADER **VtfFileImage, - IN OUT UINTN *FvImageCapacity - ) -/*++ -Routine Description: - Increase the size of FV image by 1 block. The routine may reallocate memory - depending on the capacity of the FV image. - -Arguments: - FvImage The memory image of the FV to add it to. The current offset - must be valid. - FvInfo Pointer to information about the FV. - VtfFileImage A pointer to the VTF file within the FvImage. If this is equal - to the end of the FvImage then no VTF previously found. - FvImageCapacity Capacity of image buffer for FV. - -Returns: - EFI_SUCCESS The function completed successfully. - EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the reallocation. - ---*/ -{ - CHAR8 *FileImage; - UINTN OldSize; - UINTN IncreaseSize; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - BOOLEAN AllocateNewMemory; - EFI_FFS_FILE_HEADER *NewVtfFileImage; - UINT32 VtfFileLength; - UINT8 TempByte; - - OldSize = (UINTN) FvImage->Eof - (UINTN) FvImage->FileImage; - IncreaseSize = FvInfo->FvBlocks[0].BlockLength; - assert (OldSize == FvInfo->FvBlocks[0].NumBlocks * FvInfo->FvBlocks[0].BlockLength); - - // - // Assume we have enough capacity - // - AllocateNewMemory = FALSE; - - - if (OldSize + IncreaseSize > *FvImageCapacity) { - AllocateNewMemory = TRUE; - // - // Increase capacity by one unit - // - *FvImageCapacity = OldSize + FV_CAPACITY_INCREASE_UNIT; - FileImage = malloc (*FvImageCapacity); - - if (FileImage == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return EFI_OUT_OF_RESOURCES; - } - - // - // Initialize the content per FV polarity - // - if (FvInfo->FvAttributes & EFI_FVB_ERASE_POLARITY) { - memset (FileImage, -1, *FvImageCapacity); - } else { - memset (FileImage, 0, *FvImageCapacity); - } - - // - // Copy the FV content before VTF - // - memcpy (FileImage, FvImage->FileImage, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage); - } else { - FileImage = FvImage->FileImage; - } - - // - // Move VTF if it exists - // - NewVtfFileImage = (EFI_FFS_FILE_HEADER *) (FileImage + ((UINTN) *VtfFileImage - (UINTN) FvImage->FileImage) + IncreaseSize); - if ((UINTN) *VtfFileImage != (UINTN) FvImage->Eof) { - // - // Exchange the VTF buffer from end to start for two purpose: - // 1. Exchange: Preserve the default value per FV polarity - // 2. End->Start: Avoid destroying the VTF data during exchanging - // - VtfFileLength = GetLength ((*VtfFileImage)->Size); - while (VtfFileLength-- != 0) { - TempByte = ((UINT8 *) VtfFileImage)[VtfFileLength]; - ((UINT8 *) VtfFileImage)[VtfFileLength] = ((UINT8 *) NewVtfFileImage)[VtfFileLength]; - ((UINT8 *) NewVtfFileImage)[VtfFileLength] = TempByte; - } - } - - // - // Update VTF Pointer - // - *VtfFileImage = NewVtfFileImage; - - // - // Update FvInfo - // - FvInfo->FvBlocks[0].NumBlocks ++; - - // - // Update FV Header - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FileImage; - FvHeader->FvBlockMap[0].NumBlocks = FvInfo->FvBlocks[0].NumBlocks; - FvHeader->FvLength = OldSize + IncreaseSize; - FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - // - // Update FvImage - // - if (AllocateNewMemory) { - free (FvImage->FileImage); - FvImage->CurrentFilePointer = FileImage + (FvImage->CurrentFilePointer - FvImage->FileImage); - FvImage->FileImage = FileImage; - } - FvImage->Eof = FvImage->FileImage + OldSize + IncreaseSize; - - InitializeFvLib (FvImage->FileImage, OldSize + IncreaseSize); - return EFI_SUCCESS; -} - -EFI_STATUS -AddFile ( - IN OUT MEMORY_FILE *FvImage, - IN FV_INFO *FvInfo, - IN UINTN Index, - IN OUT EFI_FFS_FILE_HEADER **VtfFileImage, - IN OUT MEMORY_FILE *SymImage, - IN OUT UINTN *FvImageCapacity - ) -/*++ - -Routine Description: - - This function adds a file to the FV image. The file will pad to the - appropriate alignment if required. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - FvInfo Pointer to information about the FV. - Index The file in the FvInfo file list to add. - VtfFileImage A pointer to the VTF file within the FvImage. If this is equal - to the end of the FvImage then no VTF previously found. - SymImage The memory image of the Sym file to update if symbols are present. - The current offset must be valid. - FvImageCapacity Capacity of image buffer for FV. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. - ---*/ -{ - FILE *NewFile; - UINTN FileSize; - UINT8 *FileBuffer; - UINTN NumBytesRead; - UINT32 CurrentFileAlignment; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS CurrentFileBaseAddress; - UINT8 VtfHeaderChecksum; - UINT8 VtfFileChecksum; - UINT8 FileState; - UINT32 TailSize; -#if (PI_SPECIFICATION_VERSION < 0x00010000) - EFI_FFS_FILE_TAIL TailValue; -#endif - // - // Verify input parameters. - // - if (FvImage == NULL || FvInfo == NULL || FvInfo->FvFiles[Index][0] == 0 || VtfFileImage == NULL || SymImage == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Read the file to add - // - NewFile = fopen (FvInfo->FvFiles[Index], "rb"); - - if (NewFile == NULL) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to open file for reading"); - return EFI_ABORTED; - } - // - // Get the file size - // - FileSize = _filelength (_fileno (NewFile)); - - // - // Read the file into a buffer - // - FileBuffer = malloc (FileSize); - if (FileBuffer == NULL) { - Error (NULL, 0, 0, "memory allocation failure", NULL); - return EFI_OUT_OF_RESOURCES; - } - - NumBytesRead = fread (FileBuffer, sizeof (UINT8), FileSize, NewFile); - - // - // Done with the file, from this point on we will just use the buffer read. - // - fclose (NewFile); - - // - // Verify read successful - // - if (NumBytesRead != sizeof (UINT8) * FileSize) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to read input file contents"); - Status = EFI_ABORTED; - goto Exit; - } - // - // Verify space exists to add the file - // - while (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { - if (FvInfo->Size != (UINTN) -1) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient space remains to add the file"); - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } else { - // - // FV Size is AUTO, increase by one block - // - Status = ReallocateFvImage (FvImage, FvInfo, VtfFileImage, FvImageCapacity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient resources to add the file"); - goto Exit; - } - } - } - // - // Update the file state based on polarity of the FV. - // - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) FileBuffer, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - - // - // If we have a VTF file, add it at the top. - // - if (IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer)) { - if ((UINTN) *VtfFileImage == (UINTN) FvImage->Eof) { - // - // No previous VTF, add this one. - // - *VtfFileImage = (EFI_FFS_FILE_HEADER *) (UINTN) ((UINTN) FvImage->FileImage + FvInfo->Size - FileSize); - // - // Sanity check. The file MUST align appropriately - // - if ((((UINTN) *VtfFileImage) & 0x07) != 0) { - Error (NULL, 0, 0, "VTF file does not align on 8-byte boundary", NULL); - } - // - // copy VTF File Header - // - memcpy (*VtfFileImage, FileBuffer, sizeof (EFI_FFS_FILE_HEADER)); - - // - // Copy VTF body - // - memcpy ( - (UINT8 *) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER), - FileBuffer + sizeof (EFI_FFS_FILE_HEADER), - FileSize - sizeof (EFI_FFS_FILE_HEADER) - ); - - // - // re-calculate the VTF File Header - // - FileState = (*VtfFileImage)->State; - (*VtfFileImage)->State = 0; - *(UINT32 *) ((*VtfFileImage)->Size) = FileSize; - (*VtfFileImage)->IntegrityCheck.Checksum.Header = 0; - (*VtfFileImage)->IntegrityCheck.Checksum.File = 0; - - VtfHeaderChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, sizeof (EFI_FFS_FILE_HEADER)); - (*VtfFileImage)->IntegrityCheck.Checksum.Header = VtfHeaderChecksum; - // - // Determine if it has a tail - // - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_CHECKSUM) { - #if (PI_SPECIFICATION_VERSION < 0x00010000) - VtfFileChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, FileSize - TailSize); - #else - VtfFileChecksum = CalculateChecksum8 ((UINT8 *) ((UINTN)*VtfFileImage + sizeof (EFI_FFS_FILE_HEADER)), FileSize - TailSize - sizeof(EFI_FFS_FILE_HEADER)); - #endif - (*VtfFileImage)->IntegrityCheck.Checksum.File = VtfFileChecksum; - } else { - (*VtfFileImage)->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - #if (PI_SPECIFICATION_VERSION < 0x00010000) - // - // If it has a file tail, update it - // - if ((*VtfFileImage)->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~((*VtfFileImage)->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) (*VtfFileImage) + GetLength ((*VtfFileImage)->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } - #endif - (*VtfFileImage)->State = FileState; - Status = EFI_SUCCESS; - goto Exit; - } else { - // - // Already found a VTF file. - // - Error (NULL, 0, 0, "multiple VTF files are illegal in a single FV", NULL); - Status = EFI_ABORTED; - goto Exit; - } - } - // - // Check if alignment is required - // - Status = ReadFfsAlignment ((EFI_FFS_FILE_HEADER *) FileBuffer, &CurrentFileAlignment); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not determine alignment of file %s.\n", FvInfo->FvFiles[Index]); - Status = EFI_ABORTED; - goto Exit; - } - // - // Add pad file if necessary - // - while (EFI_ERROR (AddPadFile (FvImage, CurrentFileAlignment))) { - if (FvInfo->Size != (UINTN) -1) { - printf ("ERROR: Could not align the file data properly.\n"); - Status = EFI_ABORTED; - goto Exit; - } else { - // - // FV Size is AUTO, increase by one block - // - Status = ReallocateFvImage (FvImage, FvInfo, VtfFileImage, FvImageCapacity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient resources to add the file"); - goto Exit; - } - } - } - - // - // Add file - // - while (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { - if (FvInfo->Size != (UINTN) -1) { - printf ("ERROR: The firmware volume is out of space, could not add file %s.\n", FvInfo->FvFiles[Index]); - Status = EFI_ABORTED; - goto Exit; - } else { - // - // FV Size is AUTO, increase by one one block - // - Status = ReallocateFvImage (FvImage, FvInfo, VtfFileImage, FvImageCapacity); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient resources to add the file"); - goto Exit; - } - } - } - - // - // Copy the file - // - memcpy (FvImage->CurrentFilePointer, FileBuffer, FileSize); - - // - // If the file is XIP, rebase - // - CurrentFileBaseAddress = FvInfo->BaseAddress + ((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage); - // - // Status = RebaseFfsFile ((EFI_FFS_FILE_HEADER*) FvImage->CurrentFilePointer, CurrentFileBaseAddress); - // if (EFI_ERROR(Status)) { - // printf ("ERROR: Could not rebase the file %s.\n", FvInfo->FvFiles[Index]); - // return EFI_ABORTED; - // } - // - // Update Symbol file - // - Status = AddSymFile ( - CurrentFileBaseAddress, - (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer, - SymImage, - FvInfo->FvFiles[Index] - ); - assert (!EFI_ERROR (Status)); - - // - // Update the current pointer in the FV image - // - FvImage->CurrentFilePointer += FileSize; - - // - // Make next file start at QWord Boundry - // - while (((UINTN) FvImage->CurrentFilePointer & 0x07) != 0) { - FvImage->CurrentFilePointer++; - } - -Exit: - // - // Free allocated memory. - // - free (FileBuffer); - return Status; -} - -EFI_STATUS -AddVariableBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - VARIABLE_STORE_HEADER *VarStoreHeader; - // - // Variable block should exclude FvHeader. Since the length of - // FvHeader depends on the block map, which is variable length, - // we could only decide the actual variable block length here. - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; - FvImage = FvImage + FvHeader->HeaderLength; - - VarStoreHeader = (VARIABLE_STORE_HEADER *) FvImage; - - VarStoreHeader->Signature = VARIABLE_STORE_SIGNATURE; - VarStoreHeader->Size = Size - FvHeader->HeaderLength; - VarStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VarStoreHeader->State = VARIABLE_STORE_HEALTHY; - VarStoreHeader->Reserved = 0; - VarStoreHeader->Reserved1 = 0; - - return EFI_SUCCESS; -} - -EFI_STATUS -AddEventLogBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - return EFI_SUCCESS; -} - -EFI_STATUS -AddFTWWorkingBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *FTWHeader; - UINT32 Crc32; - - Crc32 = 0; - FTWHeader = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) FvImage; - memcpy (&FTWHeader->Signature, &(FvInfo->FvGuid), sizeof (EFI_GUID)); - FTWHeader->WriteQueueSize = Size - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER); - CalculateCrc32 (FvImage, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER), &Crc32); - FTWHeader->Crc = Crc32; - if (FvInfo->FvAttributes & EFI_FVB_ERASE_POLARITY) { - FTWHeader->WorkingBlockValid = 0; - FTWHeader->WorkingBlockInvalid = 1; - } else { - FTWHeader->WorkingBlockValid = 1; - FTWHeader->WorkingBlockInvalid = 0; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -AddFTWSpareBlock ( - IN UINT8 *FvImage, - IN UINTN Size, - IN FV_INFO *FvInfo - ) -{ - return EFI_SUCCESS; -} - -EFI_STATUS -GenNonFFSFv ( - IN UINT8 *FvImage, - IN FV_INFO *FvInfo - ) -/*++ - -Routine Description: - - This function generate the non FFS FV image, such as the working block - and spare block. How each component of the FV is built is component - specific. - -Arguments: - - FvImage The memory image of the FV to add it to. The current offset - must be valid. - FvInfo Pointer to information about the FV. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the add. - ---*/ -{ - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - UINT64 TotalSize; - - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvImage; - TotalSize = 0; - - for (Index = 0; FvInfo->FvComponents[Index].Size != 0; Index++) { - if (_stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING) == 0) { - AddVariableBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (_stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING) == 0) { - AddEventLogBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (_stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING) == 0) { - AddFTWWorkingBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else if (_stricmp (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING) == 0) { - AddFTWSpareBlock (FvImage, FvInfo->FvComponents[Index].Size, FvInfo); - } else { - printf ("Warning: Unknown Non-FFS block %s \n", FvInfo->FvComponents[Index].ComponentName); - } - - FvImage = FvImage + FvInfo->FvComponents[Index].Size; - TotalSize = TotalSize + FvInfo->FvComponents[Index].Size; - } - // - // Index and TotalSize is zero mean there's no component, so this is an empty fv - // - if ((Index != 0 || TotalSize != 0) && TotalSize != FvInfo->Size) { - printf ("Error. Component size does not sum up to FV size.\n"); - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PadFvImage ( - IN MEMORY_FILE *FvImage, - IN EFI_FFS_FILE_HEADER *VtfFileImage - ) -/*++ - -Routine Description: - - This function places a pad file between the last file in the FV and the VTF - file if the VTF file exists. - -Arguments: - - FvImage Memory file for the FV memory image - VtfFileImage The address of the VTF file. If this is the end of the FV - image, no VTF exists and no pad file is needed. - -Returns: - - EFI_SUCCESS Completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was NULL. - ---*/ -{ - EFI_FFS_FILE_HEADER *PadFile; - UINTN FileSize; - - // - // If there is no VTF or the VTF naturally follows the previous file without a - // pad file, then there's nothing to do - // - if ((UINTN) VtfFileImage == (UINTN) FvImage->Eof || (void *) FvImage->CurrentFilePointer == (void *) VtfFileImage) { - return EFI_SUCCESS; - } - // - // Pad file starts at beginning of free space - // - PadFile = (EFI_FFS_FILE_HEADER *) FvImage->CurrentFilePointer; - - // - // write header - // - memset (PadFile, 0, sizeof (EFI_FFS_FILE_HEADER)); - memcpy (&PadFile->Name, &DefaultFvPadFileNameGuid, sizeof (EFI_GUID)); - PadFile->Type = EFI_FV_FILETYPE_FFS_PAD; - PadFile->Attributes = 0; - - // - // FileSize includes the EFI_FFS_FILE_HEADER - // - FileSize = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer; - PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF); - PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8); - PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16); - - // - // Fill in checksums and state, must be zero during checksum calculation. - // - PadFile->IntegrityCheck.Checksum.Header = 0; - PadFile->IntegrityCheck.Checksum.File = 0; - PadFile->State = 0; - PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER)); - if (PadFile->Attributes & FFS_ATTRIB_CHECKSUM) { -#if (PI_SPECIFICATION_VERSION < 0x00010000) - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, FileSize); -#else - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) ((UINTN) PadFile + sizeof (EFI_FFS_FILE_HEADER)), FileSize - sizeof (EFI_FFS_FILE_HEADER)); -#endif - } else { - PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID; - - UpdateFfsFileState ( - (EFI_FFS_FILE_HEADER *) PadFile, - (EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage - ); - // - // Update the current FV pointer - // - FvImage->CurrentFilePointer = FvImage->Eof; - - return EFI_SUCCESS; -} - -EFI_STATUS -UpdateResetVector ( - IN MEMORY_FILE *FvImage, - IN FV_INFO *FvInfo, - IN EFI_FFS_FILE_HEADER *VtfFile - ) -/*++ - -Routine Description: - - This parses the FV looking for the PEI core and then plugs the address into - the SALE_ENTRY point of the BSF/VTF for IPF and does BUGBUG TBD action to - complete an IA32 Bootstrap FV. - -Arguments: - - FvImage Memory file for the FV memory image - FvInfo Information read from INF file. - VtfFile Pointer to the VTF file in the FV image. - -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_FFS_FILE_HEADER *PeiCoreFile; - EFI_FFS_FILE_HEADER *SecCoreFile; - EFI_STATUS Status; - EFI_FILE_SECTION_POINTER Pe32Section; - UINT32 EntryPoint; - UINT32 BaseOfCode; - UINT16 MachineType; - EFI_PHYSICAL_ADDRESS PeiCorePhysicalAddress; - EFI_PHYSICAL_ADDRESS SecCorePhysicalAddress; - EFI_PHYSICAL_ADDRESS *SecCoreEntryAddressPtr; - UINT32 *Ia32ResetAddressPtr; - UINT8 *BytePointer; - UINT8 *BytePointer2; - UINT16 *WordPointer; - UINT16 CheckSum; - UINTN Index; - EFI_FFS_FILE_STATE SavedState; - UINT32 TailSize; - UINT64 FitAddress; - FIT_TABLE *FitTablePtr; -#if (PI_SPECIFICATION_VERSION < 0x00010000) - EFI_FFS_FILE_TAIL TailValue; -#endif - // - // Verify input parameters - // - if (FvImage == NULL || FvInfo == NULL || VtfFile == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize FV library - // - InitializeFvLib (FvImage->FileImage, (UINTN) FvImage->Eof - (UINTN) FvImage->FileImage); - - // - // Verify VTF file - // - Status = VerifyFfsFile (VtfFile); - if (EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - // - // Find the PEI Core - // - Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile); - if (EFI_ERROR (Status) || PeiCoreFile == NULL) { - Error (NULL, 0, 0, "could not find the PEI core in the FV", NULL); - return EFI_ABORTED; - } - // - // PEI Core found, now find PE32 or TE section - // - Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section); - } - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not find PE32 or TE section in PEI core file", NULL); - return EFI_ABORTED; - } - - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not get PE32 entry point for PEI core", NULL); - return EFI_ABORTED; - } - // - // Physical address is FV base + offset of PE32 + offset of the entry point - // - PeiCorePhysicalAddress = FvInfo->BaseAddress; - PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; - PeiCorePhysicalAddress += EntryPoint; - - if (MachineType == EFI_IMAGE_MACHINE_IA64) { - // - // Update PEI_CORE address - // - // - // Set the uncached attribute bit in the physical address - // - PeiCorePhysicalAddress |= 0x8000000000000000; - - // - // Check if address is aligned on a 16 byte boundary - // - if (PeiCorePhysicalAddress & 0xF) { - printf ( - "ERROR: PEI_CORE entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", - PeiCorePhysicalAddress - ); - return EFI_ABORTED; - } - // - // First Get the FIT table address - // - FitAddress = (*(UINT64 *) (FvImage->Eof - IPF_FIT_ADDRESS_OFFSET)) & 0xFFFFFFFF; - - FitTablePtr = (FIT_TABLE *) (FvImage->FileImage + (FitAddress - FvInfo->BaseAddress)); - - Status = UpdatePeiCoreEntryInFit (FitTablePtr, PeiCorePhysicalAddress); - - if (!EFI_ERROR (Status)) { - UpdateFitCheckSum (FitTablePtr); - } - // - // Find the Sec Core - // - Status = GetFileByType (EFI_FV_FILETYPE_SECURITY_CORE, 1, &SecCoreFile); - if (EFI_ERROR (Status) || SecCoreFile == NULL) { - Error (NULL, 0, 0, "could not find the Sec core in the FV", NULL); - return EFI_ABORTED; - } - // - // Sec Core found, now find PE32 section - // - Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not find PE32 section in SEC core file", NULL); - return EFI_ABORTED; - } - - Status = GetPe32Info ( - (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)), - &EntryPoint, - &BaseOfCode, - &MachineType - ); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 0, "could not get PE32 entry point for SEC core", NULL); - return EFI_ABORTED; - } - // - // Physical address is FV base + offset of PE32 + offset of the entry point - // - SecCorePhysicalAddress = FvInfo->BaseAddress; - SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage; - SecCorePhysicalAddress += EntryPoint; - - // - // Update SEC_CORE address - // - // - // Set the uncached attribute bit in the physical address - // - SecCorePhysicalAddress |= 0x8000000000000000; - - // - // Update the address - // - SecCoreEntryAddressPtr = (EFI_PHYSICAL_ADDRESS *) ((UINTN) FvImage->Eof - IPF_SALE_ENTRY_ADDRESS_OFFSET); - *SecCoreEntryAddressPtr = SecCorePhysicalAddress; - - // - // Check if address is aligned on a 16 byte boundary - // - if (SecCorePhysicalAddress & 0xF) { - printf ( - "ERROR: SALE_ENTRY entry point is not aligned on a 16 byte boundary, address specified is %Xh.\n", - SecCorePhysicalAddress - ); - return EFI_ABORTED; - } - } else if ((MachineType == EFI_IMAGE_MACHINE_IA32) || - (MachineType == EFI_IMAGE_MACHINE_X64)) { - // - // Get the location to update - // - Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - IA32_PEI_CORE_ENTRY_OFFSET); - - // - // Write lower 32 bits of physical address - // - *Ia32ResetAddressPtr = (UINT32) PeiCorePhysicalAddress; - - // - // Update the BFV base address - // - Ia32ResetAddressPtr = (UINT32 *) ((UINTN) FvImage->Eof - 4); - *Ia32ResetAddressPtr = (UINT32) (FvInfo->BaseAddress); - - CheckSum = 0x0000; - - // - // Update the Startup AP in the FVH header block ZeroVector region. - // - BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); - BytePointer2 = (FvInfo->Size == 0x10000) ? m64kRecoveryStartupApDataArray : m128kRecoveryStartupApDataArray; - for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY; Index++) { - *BytePointer++ = *BytePointer2++; - } - // - // Calculate the checksum - // - WordPointer = (UINT16 *) ((UINTN) FvImage->FileImage); - for (Index = 0; Index < SIZEOF_STARTUP_DATA_ARRAY / 2; Index++) { - CheckSum = (UINT16) (CheckSum + ((UINT16) *WordPointer)); - WordPointer++; - } - // - // Update the checksum field - // - BytePointer = (UINT8 *) ((UINTN) FvImage->FileImage); - BytePointer += (SIZEOF_STARTUP_DATA_ARRAY - 2); - WordPointer = (UINT16 *) BytePointer; - *WordPointer = (UINT16) (0x10000 - (UINT32) CheckSum); - } else { - Error (NULL, 0, 0, "invalid machine type in PEI core", "machine type=0x%X", (UINT32) MachineType); - return EFI_ABORTED; - } - // - // Determine if it has an FFS file tail. - // - if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailSize = sizeof (EFI_FFS_FILE_TAIL); - } else { - TailSize = 0; - } - // - // Now update file checksum - // - SavedState = VtfFile->State; - VtfFile->IntegrityCheck.Checksum.File = 0; - VtfFile->State = 0; - if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) { -#if (PI_SPECIFICATION_VERSION < 0x00010000) - VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) VtfFile, - GetLength (VtfFile->Size) - TailSize - ); - -#else - VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) ((UINTN)VtfFile + sizeof (EFI_FFS_FILE_HEADER)), - GetLength (VtfFile->Size) - TailSize - sizeof (EFI_FFS_FILE_HEADER) - ); -#endif - } else { - VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - VtfFile->State = SavedState; - -#if (PI_SPECIFICATION_VERSION < 0x00010000) - // - // Update tail if present - // - if (VtfFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) { - TailValue = (EFI_FFS_FILE_TAIL) (~(VtfFile->IntegrityCheck.TailReference)); - *(EFI_FFS_FILE_TAIL *) (((UINTN) (VtfFile) + GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue; - } -#endif - return EFI_SUCCESS; -} - -EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, - OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, - OUT UINT16 *MachineType - ) -/*++ - -Routine Description: - - Retrieves the PE32 entry point offset and machine type from PE image or TE image. - See EfiImage.h for machine types. The entry point offset is from the beginning - of the PE32 buffer passed in. - -Arguments: - - Pe32 Beginning of the PE32. - EntryPoint Offset from the beginning of the PE32 to the image entry point. - BaseOfCode Base address of code. - MachineType Magic number for the machine type. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - EFI_UNSUPPORTED The operation is unsupported. - ---*/ -{ - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_NT_HEADERS *NtHeader; - EFI_TE_IMAGE_HEADER *TeHeader; - - // - // Verify input parameters - // - if (Pe32 == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // First check whether it is one TE Image. - // - TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32; - if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - // - // By TeImage Header to get output - // - *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *BaseOfCode = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *MachineType = TeHeader->Machine; - } else { - // - // Then check whether - // is the DOS header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; - - // - // Verify DOS header is expected - // - if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - printf ("ERROR: Unknown magic number in the DOS header, 0x%04X.\n", DosHeader->e_magic); - return EFI_UNSUPPORTED; - } - // - // Immediately following is the NT header. - // - NtHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32 + DosHeader->e_lfanew); - - // - // Verify NT header is expected - // - if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) { - printf ("ERROR: Unrecognized image signature 0x%08X.\n", NtHeader->Signature); - return EFI_UNSUPPORTED; - } - // - // Get output - // - *EntryPoint = NtHeader->OptionalHeader.AddressOfEntryPoint; - *BaseOfCode = NtHeader->OptionalHeader.BaseOfCode; - *MachineType = NtHeader->FileHeader.Machine; - } - - // - // Verify machine type is supported - // - if (*MachineType != EFI_IMAGE_MACHINE_IA32 && - *MachineType != EFI_IMAGE_MACHINE_IA64 && - *MachineType != EFI_IMAGE_MACHINE_X64) { - printf ("ERROR: Unrecognized machine type in the PE32 file.\n"); - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} -// -// Exposed function implementations (prototypes are defined in GenFvImageLib.h) -// -EFI_STATUS -GenerateFvImage ( - IN CHAR8 *InfFileImage, - IN UINTN InfFileSize, - OUT UINT8 **FvImage, - OUT UINTN *FvImageSize, - OUT CHAR8 **FvFileName, - OUT UINT8 **SymImage, - OUT UINTN *SymImageSize, - OUT CHAR8 **SymFileName - ) -/*++ - -Routine Description: - - This is the main function which will be called from application. - -Arguments: - - InfFileImage Buffer containing the INF file contents. - InfFileSize Size of the contents of the InfFileImage buffer. - FvImage Pointer to the FV image created. - FvImageSize Size of the FV image created and pointed to by FvImage. - FvFileName Requested name for the FV file. - SymImage Pointer to the Sym image created. - SymImageSize Size of the Sym image created and pointed to by SymImage. - SymFileName Requested name for the Sym file. - -Returns: - - EFI_SUCCESS Function completed successfully. - EFI_OUT_OF_RESOURCES Could not allocate required resources. - EFI_ABORTED Error encountered. - EFI_INVALID_PARAMETER A required parameter was NULL. - ---*/ -{ - EFI_STATUS Status; - MEMORY_FILE InfMemoryFile; - MEMORY_FILE FvImageMemoryFile; - MEMORY_FILE SymImageMemoryFile; - FV_INFO FvInfo; - UINTN Index; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_FFS_FILE_HEADER *VtfFileImage; - UINTN FvImageCapacity; - - // - // Check for invalid parameter - // - if (InfFileImage == NULL || FvImage == NULL || FvImageSize == NULL || FvFileName == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize file structures - // - InfMemoryFile.FileImage = InfFileImage; - InfMemoryFile.CurrentFilePointer = InfFileImage; - InfMemoryFile.Eof = InfFileImage + InfFileSize; - - // - // Parse the FV inf file for header information - // - Status = ParseFvInf (&InfMemoryFile, &FvInfo); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not parse the input INF file.\n"); - return EFI_ABORTED; - } - // - // Update the file name return values - // - strcpy (*FvFileName, FvInfo.FvName); - strcpy (*SymFileName, FvInfo.SymName); - - // - // Calculate the FV size - // - if (FvInfo.Size != (UINTN) -1) { - *FvImageSize = FvInfo.Size; - FvImageCapacity = FvInfo.Size; - } else { - // - // For auto size, set default as one block - // - FvInfo.FvBlocks[0].NumBlocks = 1; - *FvImageSize = FvInfo.FvBlocks[0].BlockLength; - FvImageCapacity = FV_CAPACITY_INCREASE_UNIT; - } - - // - // Allocate the FV - // - *FvImage = malloc (FvImageCapacity); - if (*FvImage == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Allocate space for symbol file storage - // - *SymImage = malloc (SYMBOL_FILE_SIZE); - if (*SymImage == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Initialize the FV to the erase polarity - // - if (FvInfo.FvAttributes & EFI_FVB_ERASE_POLARITY) { - memset (*FvImage, -1, FvImageCapacity); - } else { - memset (*FvImage, 0, FvImageCapacity); - } - // - // Initialize FV header - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) *FvImage; - - // - // Initialize the zero vector to all zeros. - // - memset (FvHeader->ZeroVector, 0, 16); - - // - // Copy the FFS GUID - // - memcpy (&FvHeader->FileSystemGuid, &FvInfo.FvGuid, sizeof (EFI_GUID)); - - FvHeader->FvLength = *FvImageSize; - FvHeader->Signature = EFI_FVH_SIGNATURE; - FvHeader->Attributes = FvInfo.FvAttributes; -#if (PI_SPECIFICATION_VERSION < 0x00010000) - FvHeader->Revision = EFI_FVH_REVISION; - FvHeader->Reserved[0] = 0; - FvHeader->Reserved[1] = 0; - FvHeader->Reserved[2] = 0; -#else - FvHeader->Revision = EFI_FVH_PI_REVISION; - FvHeader->ExtHeaderOffset = 0; - FvHeader->Reserved[0] = 0; -#endif - // - // Copy firmware block map - // - for (Index = 0; FvInfo.FvBlocks[Index].NumBlocks != 0; Index++) { - FvHeader->FvBlockMap[Index].NumBlocks = FvInfo.FvBlocks[Index].NumBlocks; - FvHeader->FvBlockMap[Index].BlockLength = FvInfo.FvBlocks[Index].BlockLength; - } - // - // Add block map terminator - // - FvHeader->FvBlockMap[Index].NumBlocks = 0; - FvHeader->FvBlockMap[Index].BlockLength = 0; - - // - // Complete the header - // - FvHeader->HeaderLength = (UINT16) (((UINTN) &(FvHeader->FvBlockMap[Index + 1])) - (UINTN) *FvImage); - FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - - // - // If there is no FFS file, find and generate each components of the FV - // - if (FvInfo.FvFiles[0][0] == 0) { - Status = GenNonFFSFv (*FvImage, &FvInfo); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not generate NonFFS FV.\n"); - free (*FvImage); - return EFI_ABORTED; - } - - return EFI_SUCCESS; - } - // - // Initialize our "file" view of the buffer - // - FvImageMemoryFile.FileImage = *FvImage; - FvImageMemoryFile.CurrentFilePointer = *FvImage + FvHeader->HeaderLength; - FvImageMemoryFile.Eof = *FvImage +*FvImageSize; - - // - // Initialize our "file" view of the symbol file. - // - SymImageMemoryFile.FileImage = *SymImage; - SymImageMemoryFile.CurrentFilePointer = *SymImage; - SymImageMemoryFile.Eof = *FvImage + SYMBOL_FILE_SIZE; - - // - // Initialize the FV library. - // - InitializeFvLib (FvImageMemoryFile.FileImage, *FvImageSize); - - // - // Files start on 8 byte alignments, so move to the next 8 byte aligned - // address. For now, just assert if it isn't. Currently FV header is - // always a multiple of 8 bytes. - // BUGBUG: Handle this better - // - assert ((((UINTN) FvImageMemoryFile.CurrentFilePointer) % 8) == 0); - - // - // Initialize the VTF file address. - // - VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof; - - // - // Add files to FV - // - for (Index = 0; FvInfo.FvFiles[Index][0] != 0; Index++) { - // - // Add the file - // - Status = AddFile (&FvImageMemoryFile, &FvInfo, Index, &VtfFileImage, &SymImageMemoryFile, &FvImageCapacity); - - // - // Update FvImageSize and FvImage as they may be changed in AddFile routine - // - if (FvInfo.Size == (UINTN) -1) { - *FvImageSize = FvInfo.FvBlocks[0].NumBlocks * FvInfo.FvBlocks[0].BlockLength; - *FvImage = FvImageMemoryFile.FileImage; - } - - // - // Exit if error detected while adding the file - // - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not add file %s.\n", FvInfo.FvFiles[Index]); - free (*FvImage); - return EFI_ABORTED; - } - } - // - // If there is a VTF file, some special actions need to occur. - // - if ((UINTN) VtfFileImage != (UINTN) FvImageMemoryFile.Eof) { - // - // Pad from the end of the last file to the beginning of the VTF file. - // - Status = PadFvImage (&FvImageMemoryFile, VtfFileImage); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not create the pad file between the last file and the VTF file.\n"); - free (*FvImage); - return EFI_ABORTED; - } - // - // Update reset vector (SALE_ENTRY for IPF) - // Now for IA32 and IA64 platform, the fv which has bsf file must have the - // EndAddress of 0xFFFFFFFF. Thus, only this type fv needs to update the - // reset vector. If the PEI Core is found, the VTF file will probably get - // corrupted by updating the entry point. - // - if ((FvInfo.BaseAddress + *FvImageSize) == FV_IMAGES_TOP_ADDRESS) { - Status = UpdateResetVector (&FvImageMemoryFile, &FvInfo, VtfFileImage); - if (EFI_ERROR(Status)) { - printf ("ERROR: Could not update the reset vector.\n"); - free (*FvImage); - return EFI_ABORTED; - } - } - } - // - // Determine final Sym file size - // - *SymImageSize = SymImageMemoryFile.CurrentFilePointer - SymImageMemoryFile.FileImage; - - return EFI_SUCCESS; -} - -EFI_STATUS -UpdatePeiCoreEntryInFit ( - IN FIT_TABLE *FitTablePtr, - IN UINT64 PeiCorePhysicalAddress - ) -/*++ - -Routine Description: - - This function is used to update the Pei Core address in FIT, this can be used by Sec core to pass control from - Sec to Pei Core - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - PeiCorePhysicalAddress - The address of Pei Core entry. - -Returns: - - EFI_SUCCESS - The PEI_CORE FIT entry was updated successfully. - EFI_NOT_FOUND - Not found the PEI_CORE FIT entry. - ---*/ -{ - FIT_TABLE *TmpFitPtr; - UINTN Index; - UINTN NumFitComponents; - - TmpFitPtr = FitTablePtr; - NumFitComponents = TmpFitPtr->CompSize; - - for (Index = 0; Index < NumFitComponents; Index++) { - if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_PEICORE) { - TmpFitPtr->CompAddress = PeiCorePhysicalAddress; - return EFI_SUCCESS; - } - - TmpFitPtr++; - } - - return EFI_NOT_FOUND; -} - -VOID -UpdateFitCheckSum ( - IN FIT_TABLE *FitTablePtr - ) -/*++ - -Routine Description: - - This function is used to update the checksum for FIT. - - -Arguments: - - FitTablePtr - The pointer of FIT_TABLE. - -Returns: - - None. - ---*/ -{ - if ((FitTablePtr->CvAndType & CHECKSUM_BIT_MASK) >> 7) { - FitTablePtr->CheckSum = 0; - FitTablePtr->CheckSum = CalculateChecksum8 ((UINT8 *) FitTablePtr, FitTablePtr->CompSize * 16); - } -}