X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=Tools%2FCCode%2FSource%2FGenFvImage%2FGenFvImageLib.c;fp=Tools%2FCCode%2FSource%2FGenFvImage%2FGenFvImageLib.c;h=0000000000000000000000000000000000000000;hp=dfed0aefa2fb058a66984e2efceaec5dd5de0ce4;hb=808def96aa4589fba9c2d0ea55837754a3b7a4f7;hpb=9216450d1143056a50a5f916984a2d7faf590488 diff --git a/Tools/CCode/Source/GenFvImage/GenFvImageLib.c b/Tools/CCode/Source/GenFvImage/GenFvImageLib.c deleted file mode 100644 index dfed0aefa2..0000000000 --- a/Tools/CCode/Source/GenFvImage/GenFvImageLib.c +++ /dev/null @@ -1,2762 +0,0 @@ -/*++ -i - -Copyright (c) 2004, 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 -// -#ifdef __GNUC__ -#include -#include -#endif -#include -#ifndef __GNUC__ -#include -#endif -#include - -#include -#include -#include -#include -#include - -#include "GenFvImageLib.h" -#include "GenFvImageLibInternal.h" -#include "CommonLib.h" -#include "Crc32.h" -#include "EfiUtilityMsgs.h" -#include "FvLib.h" -#include "Compress.h" -#include "WinNtInclude.h" - -// -// Different file separater for Linux and Windows -// -#ifdef __GNUC__ -#define FILE_SEP_CHAR '/' -#define FILE_SEP_STRING "/" -#else -#define FILE_SEP_CHAR '\\' -#define FILE_SEP_STRING "\\" -#endif - -static UINT32 MaxFfsAlignment = 0; -// -// Local function prototypes -// -EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, - OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, - OUT UINT16 *MachineType - ); - -// -// Local function implementations. -// -EFI_GUID FfsGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID; -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; - } - // - // 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; - } - // - // 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) { - // - // 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; - // - // Read component FV_VARIABLE - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_VARIABLE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_VARIABLE_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_VARIABLE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_VARIABLE_STRING); - } - - Index++; - // - // Read component FV_EVENT_LOG - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_EVENT_LOG_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_EVENT_LOG_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_EVENT_LOG_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_EVENT_LOG_STRING); - } - - Index++; - // - // Read component FV_FTW_WORKING - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_WORKING_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_WORKING_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_WORKING_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_WORKING_STRING); - } - - Index++; - // - // Read component FV_FTW_SPARE - // - Status = FindToken (InfFile, COMPONENT_SECTION_STRING, EFI_NV_FTW_SPARE_STRING, 0, Value); - - if (Status == EFI_SUCCESS) { - // - // Add the component - // - strcpy (FvInfo->FvComponents[Index].ComponentName, EFI_NV_FTW_SPARE_STRING); - Status = AsciiStringToUint64 (Value, FALSE, &Value64); - if (EFI_ERROR (Status)) { - printf ("ERROR: %s is not a valid integer.\n", EFI_NV_FTW_SPARE_STRING); - return EFI_ABORTED; - } - - FvInfo->FvComponents[Index].Size = (UINTN) Value64; - } else { - printf ("WARNING: Could not read %s.\n", EFI_NV_FTW_SPARE_STRING); - } - } - // - // Compute size for easy access later - // - FvInfo->Size = 0; - for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) { - FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].BlockLength; - } - - 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: - // - // 8 byte alignment, mini alignment requirement for FFS file. - // - *Alignment = (1 << 3); - 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; - EFI_GUID 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; - } - -#ifdef __GNUC__ - { - uuid_t tmp_id; - uuid_generate (tmp_id); - memcpy (&PadFileGuid, tmp_id, sizeof (EFI_GUID)); - } -#else - UuidCreate (&PadFileGuid); -#endif - 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) { - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, PadFileSize); - } 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 -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, FILE_SEP_CHAR); - 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, FILE_SEP_CHAR); - 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) { - // - // For PIC, hardcode. - // - 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 { - // - // For PIC hardcoded. - // - 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 -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 - ) -/*++ - -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. - -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; - EFI_FFS_FILE_TAIL TailValue; - UINT32 TailSize; - // - // 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) { - free (FileBuffer); - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "failed to read input file contents"); - return EFI_ABORTED; - } - // - // Verify space exists to add the file - // - if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { - Error (NULL, 0, 0, FvInfo->FvFiles[Index], "insufficient space remains to add the file"); - return EFI_OUT_OF_RESOURCES; - } - // - // 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) { - VtfFileChecksum = CalculateChecksum8 ((UINT8 *) *VtfFileImage, FileSize - TailSize); - (*VtfFileImage)->IntegrityCheck.Checksum.File = VtfFileChecksum; - } else { - (*VtfFileImage)->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - // - // 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; - } - (*VtfFileImage)->State = FileState; - free (FileBuffer); - return EFI_SUCCESS; - } else { - // - // Already found a VTF file. - // - Error (NULL, 0, 0, "multiple VTF files are illegal in a single FV", NULL); - free (FileBuffer); - return EFI_ABORTED; - } - } - // - // 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]); - free (FileBuffer); - return EFI_ABORTED; - } - - // - // Find the largest alignment of all the FFS files in the FV - // - if (CurrentFileAlignment > MaxFfsAlignment) { - MaxFfsAlignment = CurrentFileAlignment; - } - // - // Add pad file if necessary - // - Status = AddPadFile (FvImage, CurrentFileAlignment); - if (EFI_ERROR (Status)) { - printf ("ERROR: Could not align the file data properly.\n"); - free (FileBuffer); - return EFI_ABORTED; - } - // - // Add file - // - if ((FvImage->CurrentFilePointer + FileSize) < FvImage->Eof) { - // - // 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; - } else { - printf ("ERROR: The firmware volume is out of space, could not add file %s.\n", FvInfo->FvFiles[Index]); - return EFI_ABORTED; - } - // - // Make next file start at QWord Boundry - // - while (((UINTN) FvImage->CurrentFilePointer & 0x07) != 0) { - FvImage->CurrentFilePointer++; - } - // - // Free allocated memory. - // - free (FileBuffer); - - return EFI_SUCCESS; -} - -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 ("Error. Unknown Non-FFS block %s \n", FvInfo->FvComponents[Index].ComponentName); - return EFI_ABORTED; - } - - 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) { - PadFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ((UINT8 *) PadFile, FileSize); - } 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; - EFI_FFS_FILE_TAIL TailValue; - UINT32 TailSize; - UINT64 FitAddress; - FIT_TABLE *FitTablePtr; - - // - // 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 |= 0x8000000000000000ULL; - - // - // 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 |= 0x8000000000000000ULL; - - // - // 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) { - // - // 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) { - VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) VtfFile, - GetLength (VtfFile->Size) - TailSize - ); - } else { - VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; - } - - VtfFile->State = SavedState; - - // - // 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; - } - - 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 TeImage. - 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 - // First 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 && *MachineType != EFI_IMAGE_MACHINE_EBC) { - 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; - - // - // 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 - // - *FvImageSize = FvInfo.Size; - - // - // Allocate the FV - // - *FvImage = malloc (*FvImageSize); - 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, *FvImageSize); - } else { - memset (*FvImage, 0, *FvImageSize); - } - // - // 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; - FvHeader->Revision = EFI_FVH_REVISION; - FvHeader->Reserved[0] = 0; - FvHeader->Reserved[1] = 0; - FvHeader->Reserved[2] = 0; - - // - // 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, FvInfo.Size); - - // - // 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); - - // - // 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 + FvInfo.Size) == 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; - - // - // Update FV Alignment attribute to the largest alignment of all the FFS files in the FV - // - if (FvHeader->Attributes | EFI_FVB_ALIGNMENT_CAP) { - for (Index = 1; Index <= 16; Index ++) { - if ((1 << Index) < MaxFfsAlignment) { - // - // Unset the unsupported alignment attribute. - // - FvHeader->Attributes = FvHeader->Attributes & ~((1 << Index) * EFI_FVB_ALIGNMENT_CAP); - } else { - // - // Set the supported alignment attribute. - // - FvHeader->Attributes = FvHeader->Attributes | ((1 << Index) * EFI_FVB_ALIGNMENT_CAP); - } - } - - // - // Update Checksum for FvHeader - // - FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); - } - - 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); - } -}