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