From: "Liming Gao" <liming.gao@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
"Zhang, Shenglei" <shenglei.zhang@intel.com>
Cc: "Feng, Bob C" <bob.c.feng@intel.com>
Subject: Re: [edk2-devel] [edk2-platform patch 5/6] Silicon\Tools: Add a tool FitGen
Date: Wed, 26 Jun 2019 02:03:23 +0000 [thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E48D5DE@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20190621012643.9352-6-shenglei.zhang@intel.com>
Shenglei:
The patch is good to me. Reviewed-by: Liming Gao <liming.gao@intel.com>
Thanks
Liming
>-----Original Message-----
>From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>Zhang, Shenglei
>Sent: Friday, June 21, 2019 9:27 AM
>To: devel@edk2.groups.io
>Cc: Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
>Subject: [edk2-devel] [edk2-platform patch 5/6] Silicon\Tools: Add a tool
>FitGen
>
>The utility of this tool is part of build process for IA32/X64 FD.
>It generates FIT table.
>https://bugzilla.tianocore.org/show_bug.cgi?id=1849
>
>Cc: Bob Feng <bob.c.feng@intel.com>
>Cc: Liming Gao <liming.gao@intel.com>
>Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
>---
> Silicon/Intel/Tools/FitGen/FitGen.c | 3137 ++++++++++++++++++++++++
> Silicon/Intel/Tools/FitGen/FitGen.h | 48 +
> Silicon/Intel/Tools/FitGen/GNUmakefile | 16 +
> Silicon/Intel/Tools/FitGen/Makefile | 17 +
> 4 files changed, 3218 insertions(+)
> create mode 100644 Silicon/Intel/Tools/FitGen/FitGen.c
> create mode 100644 Silicon/Intel/Tools/FitGen/FitGen.h
> create mode 100644 Silicon/Intel/Tools/FitGen/GNUmakefile
> create mode 100644 Silicon/Intel/Tools/FitGen/Makefile
>
>diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c
>b/Silicon/Intel/Tools/FitGen/FitGen.c
>new file mode 100644
>index 0000000000..faf9880060
>--- /dev/null
>+++ b/Silicon/Intel/Tools/FitGen/FitGen.c
>@@ -0,0 +1,3137 @@
>+/**@file
>+This utility is part of build process for IA32/X64 FD.
>+It generates FIT table.
>+
>+Copyright (c) 2010-2019, Intel Corporation. All rights reserved.<BR>
>+SPDX-License-Identifier: BSD-2-Clause-Patent
>+
>+**/
>+
>+#include "FitGen.h"
>+
>+//
>+// FIT spec
>+//
>+#pragma pack (1)
>+typedef struct {
>+ UINT64 Address;
>+ UINT8 Size[3];
>+ UINT8 Rsvd;
>+ UINT16 Version;
>+ UINT8 Type:7;
>+ UINT8 C_V:1;
>+ UINT8 Checksum;
>+} FIRMWARE_INTERFACE_TABLE_ENTRY;
>+
>+//
>+// Struct for policy
>+//
>+typedef struct {
>+ UINT16 IndexPort;
>+ UINT16 DataPort;
>+ UINT8 Width;
>+ UINT8 Bit;
>+ UINT16 Index;
>+ UINT8 Size[3];
>+ UINT8 Rsvd;
>+ UINT16 Version; // == 0
>+ UINT8 Type:7;
>+ UINT8 C_V:1;
>+ UINT8 Checksum;
>+} FIRMWARE_INTERFACE_TABLE_ENTRY_PORT;
>+
>+#define FIT_ALIGNMENT 0x3F // 0xF is required previously, but if we
>need exclude FIT, we must set 64 bytes alignment.
>+#define BIOS_MODULE_ALIGNMENT 0x3F // 64 bytes for AnC
>+#define MICROCODE_ALIGNMENT 0x7FF
>+
>+#define ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE 256
>+#define ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE 384
>+
>+#define ACM_HEADER_VERSION_3 (3 << 16)
>+#define ACM_MODULE_TYPE_CHIPSET_ACM 2
>+#define ACM_MODULE_SUBTYPE_CAPABLE_OF_EXECUTE_AT_RESET 0x1
>+#define ACM_MODULE_SUBTYPE_ANC_MODULE 0x2
>+#define ACM_MODULE_FLAG_PREPRODUCTION 0x4000
>+#define ACM_MODULE_FLAG_DEBUG_SIGN 0x8000
>+
>+
>+typedef struct {
>+ UINT16 ModuleType;
>+ UINT16 ModuleSubType;
>+ UINT32 HeaderLen;
>+ UINT32 HeaderVersion;
>+ UINT16 ChipsetID;
>+ UINT16 Flags;
>+ UINT32 ModuleVendor;
>+ UINT32 Date;
>+ UINT32 Size;
>+ UINT16 TxtSvn;
>+ UINT16 SeSvn;
>+ UINT32 CodeControl;
>+ UINT32 ErrorEntryPoint;
>+ UINT32 GDTLimit;
>+ UINT32 GDTBasePtr;
>+ UINT32 SegSel;
>+ UINT32 EntryPoint;
>+ UINT8 Rsvd2[64];
>+ UINT32 KeySize; // 64
>+ UINT32 ScratchSize; // 2 * KeySize + 15
>+//UINT8 RSAPubKey[64 * 4]; // KeySize * 4
>+//UINT32 RSAPubExp;
>+//UINT8 RSASig[256];
>+ // End of AC module header
>+//UINT8 Scratch[(64 * 2 + 15) * 4]; // ScratchSize * 4
>+ // User Area
>+//UINT8 UserArea[1];
>+} ACM_FORMAT;
>+
>+#define CHIPSET_ACM_INFORMATION_TABLE_VERSION_3 0x03
>+#define CHIPSET_ACM_INFORMATION_TABLE_VERSION_4 0x04
>+
>+#define CHIPSET_ACM_INFORMATION_TABLE_VERSION
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_3
>+
>+#define CHIPSET_ACM_INFORMATION_TABLE_GUID_V03 \
>+ { 0x7FC03AAA, 0x18DB46A7, 0x8F69AC2E, 0x5A7F418D }
>+
>+#define CHIPSET_ACM_TYPE_BIOS 0
>+#define CHIPSET_ACM_TYPE_SINIT 1
>+
>+typedef struct {
>+ UINT32 Guid0;
>+ UINT32 Guid1;
>+ UINT32 Guid2;
>+ UINT32 Guid3;
>+} ACM_GUID;
>+
>+typedef struct {
>+ ACM_GUID Guid;
>+ UINT8 ChipsetACMType;
>+ UINT8 Version;
>+ UINT16 Length;
>+ UINT32 ChipsetIDList;
>+ UINT32 OsSinitTableVer;
>+ UINT32 MinMleHeaderVer;
>+//#if (CHIPSET_ACM_INFORMATION_TABLE_VERSION >=
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_3)
>+ UINT32 Capabilities;
>+ UINT8 AcmVersion;
>+ UINT8 AcmRevision[3];
>+//#if (CHIPSET_ACM_INFORMATION_TABLE_VERSION >=
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_4)
>+ UINT32 ProcessorIDList;
>+//#endif
>+//#endif
>+} CHIPSET_ACM_INFORMATION_TABLE;
>+
>+#define ACM_CHIPSET_ID_REVISION_ID_MAKE 0x1
>+
>+typedef struct {
>+ UINT32 Flags;
>+ UINT16 VendorID;
>+ UINT16 DeviceID;
>+ UINT16 RevisionID;
>+ UINT8 Reserved[6];
>+} ACM_CHIPSET_ID;
>+
>+typedef struct {
>+ UINT32 Count;
>+ ACM_CHIPSET_ID ChipsetID[1];
>+} CHIPSET_ID_LIST;
>+
>+typedef struct {
>+ UINT32 FMS;
>+ UINT32 FMSMask;
>+ UINT64 PlatformID;
>+ UINT64 PlatformMask;
>+} ACM_PROCESSOR_ID;
>+
>+typedef struct {
>+ UINT32 Count;
>+ ACM_PROCESSOR_ID ProcessorID[1];
>+} PROCESSOR_ID_LIST;
>+
>+#pragma pack ()
>+
>+
>+ACM_GUID mChipsetAcmInformationTableGuid03 =
>CHIPSET_ACM_INFORMATION_TABLE_GUID_V03;
>+
>+
>+//
>+// BIOS INFO data structure
>+// This is self contained data structure for BIOS info
>+//
>+#pragma pack (1)
>+#define BIOS_INFO_SIGNATURE SIGNATURE_64 ('$', 'B', 'I', 'O', 'S', 'I', 'F', '$')
>+typedef struct {
>+ UINT64 Signature;
>+ UINT32 EntryCount;
>+ UINT32 Reserved;
>+//BIOS_INFO_STRUCT Struct[EntryCount];
>+} BIOS_INFO_HEADER;
>+
>+//
>+// BIOS_INFO_STRUCT attributes
>+// bits[0:3] means general attributes
>+// bits[4:7] means type specific attributes
>+//
>+#define BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT
>0x01
>+#define BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION
>0x10
>+#define BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB 0x10
>+
>+typedef struct {
>+ //
>+ // FitTable entry type
>+ //
>+ UINT8 Type;
>+ //
>+ // BIOS_INFO_STRUCT attributes
>+ //
>+ UINT8 Attributes;
>+ //
>+ // FitTable entry version
>+ //
>+ UINT16 Version;
>+ //
>+ // FitTable entry real size
>+ //
>+ UINT32 Size;
>+ //
>+ // FitTable entry address
>+ //
>+ UINT64 Address;
>+} BIOS_INFO_STRUCT;
>+
>+#pragma pack ()
>+
>+#define MAX_BIOS_MODULE_ENTRY 0x20
>+#define MAX_MICROCODE_ENTRY 0x20
>+#define MAX_OPTIONAL_ENTRY 0x20
>+#define MAX_PORT_ENTRY 0x20
>+
>+#define DEFAULT_FIT_TABLE_POINTER_OFFSET 0x40
>+#define DEFAULT_FIT_ENTRY_VERSION 0x0100
>+
>+#define MEMORY_TO_FLASH(FileBuffer, FvBuffer, FvSize) \
>+ (UINTN)(0x100000000 - ((UINTN)(FvBuffer) + (UINTN)(FvSize) -
>(UINTN)(FileBuffer)))
>+#define FLASH_TO_MEMORY(Address, FvBuffer, FvSize) \
>+ (VOID *)(UINTN)((UINTN)(FvBuffer) + (UINTN)(FvSize) -
>(0x100000000 - (UINTN)(Address)))
>+
>+#define FIT_TABLE_TYPE_HEADER 0
>+#define FIT_TABLE_TYPE_MICROCODE 1
>+#define FIT_TABLE_TYPE_STARTUP_ACM 2
>+#define FIT_TABLE_TYPE_BIOS_MODULE 7
>+#define FIT_TABLE_TYPE_TPM_POLICY 8
>+#define FIT_TABLE_TYPE_BIOS_POLICY 9
>+#define FIT_TABLE_TYPE_TXT_POLICY 10
>+#define FIT_TABLE_TYPE_KEY_MANIFEST 11
>+#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST 12
>+#define FIT_TABLE_TYPE_BIOS_DATA_AREA 13
>+#define FIT_TABLE_TYPE_CSE_SECURE_BOOT 16
>+
>+typedef struct {
>+ UINT32 Type;
>+ UINT32 Address;
>+ UINT32 Size;
>+ UINT32 Version; // Used by OptionalModule and PortModule only
>+} FIT_TABLE_CONTEXT_ENTRY;
>+
>+typedef struct {
>+ BOOLEAN Clear;
>+ UINT32 FitTablePointerOffset;
>+ UINT32 FitTablePointerOffset2;
>+ UINT32 FitEntryNumber;
>+ UINT32 BiosModuleNumber;
>+ UINT32 MicrocodeNumber;
>+ UINT32 OptionalModuleNumber;
>+ UINT32 PortModuleNumber;
>+ UINT32 GlobalVersion;
>+ UINT32 FitHeaderVersion;
>+ FIT_TABLE_CONTEXT_ENTRY StartupAcm;
>+ UINT32 StartupAcmVersion;
>+ FIT_TABLE_CONTEXT_ENTRY BiosModule[MAX_BIOS_MODULE_ENTRY];
>+ UINT32 BiosModuleVersion;
>+ FIT_TABLE_CONTEXT_ENTRY Microcode[MAX_MICROCODE_ENTRY];
>+ BOOLEAN MicrocodeAlignment;
>+ UINT32 MicrocodeVersion;
>+ FIT_TABLE_CONTEXT_ENTRY OptionalModule[MAX_OPTIONAL_ENTRY];
>+ FIT_TABLE_CONTEXT_ENTRY PortModule[MAX_PORT_ENTRY];
>+} FIT_TABLE_CONTEXT;
>+
>+FIT_TABLE_CONTEXT gFitTableContext = {0};
>+
>+unsigned int
>+xtoi (
>+ char *str
>+ );
>+
>+VOID
>+PrintUtilityInfo (
>+ VOID
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Displays the standard utility information to STDOUT
>+
>+Arguments:
>+
>+ None
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ printf (
>+ "%s - Tiano IA32/X64 FIT table generation Utility."" Version %i.%i\n\n",
>+ UTILITY_NAME,
>+ UTILITY_MAJOR_VERSION,
>+ UTILITY_MINOR_VERSION
>+ );
>+}
>+
>+VOID
>+PrintUsage (
>+ VOID
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Displays the utility usage syntax to STDOUT
>+
>+Arguments:
>+
>+ None
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ printf ("Usage (generate): %s [-D] InputFvRecoveryFile
>OutputFvRecoveryFile\n"
>+ "\t[-V <FitEntryDefaultVersion>]\n"
>+ "\t[-F <FitTablePointerOffset>] [-F <FitTablePointerOffset>] [-V
><FitHeaderVersion>]\n"
>+ "\t[-NA]\n"
>+ "\t[-CLEAR]\n"
>+ "\t[-I <BiosInfoGuid>]\n"
>+ "\t[-S <StartupAcmAddress StartupAcmSize>|<StartupAcmGuid>] [-V
><StartupAcmVersion>]\n"
>+ "\t[-B <BiosModuleAddress BiosModuleSize>] [-B ...] [-V
><BiosModuleVersion>]\n"
>+ "\t[-M <MicrocodeAddress MicrocodeSize>] [-M ...]|[-U <MicrocodeFv
>MicrocodeBase>|<MicrocodeRegionOffset
>MicrocodeRegionSize>|<MicrocodeGuid>] [-V <MicrocodeVersion>]\n"
>+ "\t[-O RecordType <RecordDataAddress RecordDataSize>|<RESERVE
>RecordDataSize>|<RecordDataGuid>|<RecordBinFile> [-V <RecordVersion>]]
>[-O ... [-V ...]]\n"
>+ "\t[-P RecordType <IndexPort DataPort Width Bit Index> [-V
><RecordVersion>]] [-P ... [-V ...]]\n"
>+ , UTILITY_NAME);
>+ printf (" Where:\n");
>+ printf ("\t-D - It is FD file instead of FV file. (The tool will search FV
>file)\n");
>+ printf ("\tInputFvRecoveryFile - Name of the input FvRecovery.fv file.\n");
>+ printf ("\tOutputFvRecoveryFile - Name of the output FvRecovery.fv
>file.\n");
>+ printf ("\tFitTablePointerOffset - FIT table pointer offset. 0x%x as default.
>0x18 for current soon to be obsoleted CPUs. User can set both.\n",
>DEFAULT_FIT_TABLE_POINTER_OFFSET);
>+ printf ("\tBiosInfoGuid - Guid of BiosInfo Module. If this module exists,
>StartupAcm/Bios/Microcode can be optional.\n");
>+ printf ("\tStartupAcmAddress - Address of StartupAcm.\n");
>+ printf ("\tStartupAcmSize - Size of StartupAcm.\n");
>+ printf ("\tStartupAcmGuid - Guid of StartupAcm Module, if StartupAcm
>is in a BiosModule, it will be excluded form that.\n");
>+ printf ("\tBiosModuleAddress - Address of BiosModule. User should
>ensure there is no overlap.\n");
>+ printf ("\tBiosModuleSize - Size of BiosModule.\n");
>+ printf ("\tMicrocodeAddress - Address of Microcode.\n");
>+ printf ("\tMicrocodeSize - Size of Microcode.\n");
>+ printf ("\tMicrocodeFv - Name of Microcode.fv file.\n");
>+ printf ("\tMicrocodeBase - The base address of Microcode.fv in final FD
>image.\n");
>+ printf ("\tMicrocodeRegionOffset - Offset of Microcode region in input FD
>image.\n");
>+ printf ("\tMicrocodeRegionSize - Size of Microcode region in input FD
>image.\n");
>+ printf ("\tMicrocodeGuid - Guid of Microcode Module.\n");
>+ printf ("\t-NA - No 0x800 aligned Microcode requirement. No -NA
>means Microcode is 0x800 aligned.\n");
>+ printf ("\tRecordType - FIT entry record type. User should ensure it is
>ordered.\n");
>+ printf ("\tRecordDataAddress - FIT entry record data address.\n");
>+ printf ("\tRecordDataSize - FIT entry record data size.\n");
>+ printf ("\tRecordDataGuid - FIT entry record data GUID.\n");
>+ printf ("\tRecordBinFile - FIT entry record data binary file.\n");
>+ printf ("\tFitEntryDefaultVersion - The default version for all FIT table
>entries. 0x%04x is used if this is not specified.\n",
>DEFAULT_FIT_ENTRY_VERSION);
>+ printf ("\tFitHeaderVersion - The version for FIT header. (Override
>default version)\n");
>+ printf ("\tStartupAcmVersion - The version for StartupAcm. (Override
>default version)\n");
>+ printf ("\tBiosModuleVersion - The version for BiosModule. (Override
>default version)\n");
>+ printf ("\tMicrocodeVersion - The version for Microcode. (Override
>default version)\n");
>+ printf ("\tRecordVersion - The version for Record. (Override default
>version)\n");
>+ printf ("\tIndexPort - The Index Port Number.\n");
>+ printf ("\tDataPort - The Data Port Number.\n");
>+ printf ("\tWidth - The Width of the port.\n");
>+ printf ("\tBit - The Bit Number of the port.\n");
>+ printf ("\tIndex - The Index Number of the port.\n");
>+ printf ("\nUsage (view): %s [-view] InputFile -F <FitTablePointerOffset>\n",
>UTILITY_NAME);
>+ printf (" Where:\n");
>+ printf ("\tInputFile - Name of the input file.\n");
>+ printf ("\tFitTablePointerOffset - FIT table pointer offset from end of file.
>0x%x as default.\n", DEFAULT_FIT_TABLE_POINTER_OFFSET);
>+ printf ("\nTool return values:\n");
>+ printf ("\tSTATUS_SUCCESS=%d, STATUS_WARNING=%d,
>STATUS_ERROR=%d\n", STATUS_SUCCESS, STATUS_WARNING,
>STATUS_ERROR);
>+}
>+
>+VOID *
>+SetMem (
>+ OUT VOID *Buffer,
>+ IN UINTN Length,
>+ IN UINT8 Value
>+ )
>+{
>+ //
>+ // Declare the local variables that actually move the data elements as
>+ // volatile to prevent the optimizer from replacing this function with
>+ // the intrinsic memset()
>+ //
>+ volatile UINT8 *Pointer;
>+
>+ Pointer = (UINT8*)Buffer;
>+ while (Length-- > 0) {
>+ *(Pointer++) = Value;
>+ }
>+ return Buffer;
>+}
>+
>+STATUS
>+ReadInputFile (
>+ IN CHAR8 *FileName,
>+ OUT UINT8 **FileData,
>+ OUT UINT32 *FileSize,
>+ OUT UINT8 **FileBufferRaw OPTIONAL
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Read input file
>+
>+Arguments:
>+
>+ FileName - The input file name
>+ FileData - The input file data, the memory is aligned.
>+ FileSize - The input file size
>+ FileBufferRaw - The memory to hold input file data. The caller must free the
>memory.
>+
>+Returns:
>+
>+ STATUS_SUCCESS - The file found and data read
>+ STATUS_ERROR - The file data is not read
>+ STATUS_WARNING - The file is not found
>+
>+--*/
>+{
>+ FILE *FpIn;
>+ UINT32 TempResult;
>+
>+ //
>+ // Open the Input FvRecovery.fv file
>+ //
>+ if ((FpIn = fopen (FileName, "rb")) == NULL) {
>+ //
>+ // Return WARNING, let caller make decision
>+ //
>+// Error (NULL, 0, 0, "Unable to open file", FileName);
>+ return STATUS_WARNING;
>+ }
>+ //
>+ // Get the Input FvRecovery.fv file size
>+ //
>+ fseek (FpIn, 0, SEEK_END);
>+ *FileSize = ftell (FpIn);
>+ //
>+ // Read the contents of input file to memory buffer
>+ //
>+ if (FileBufferRaw != NULL) {
>+ *FileBufferRaw = (UINT8 *) malloc (*FileSize + 0x10000);
>+ if (NULL == *FileBufferRaw) {
>+ Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
>+ fclose (FpIn);
>+ return STATUS_ERROR;
>+ }
>+ TempResult = 0x10000 - (UINT32) ((UINTN)*FileBufferRaw & 0x0FFFF);
>+ *FileData = (UINT8 *)((UINTN)*FileBufferRaw + TempResult);
>+ } else {
>+ *FileData = (UINT8 *) malloc (*FileSize);
>+ if (NULL == *FileData) {
>+ Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
>+ fclose (FpIn);
>+ return STATUS_ERROR;
>+ }
>+ }
>+ fseek (FpIn, 0, SEEK_SET);
>+ TempResult = fread (*FileData, 1, *FileSize, FpIn);
>+ if (TempResult != *FileSize) {
>+ Error (NULL, 0, 0, "Read input file error!", NULL);
>+ if (FileBufferRaw != NULL) {
>+ free ((VOID *)*FileBufferRaw);
>+ } else {
>+ free ((VOID *)*FileData);
>+ }
>+ fclose (FpIn);
>+ return STATUS_ERROR;
>+ }
>+
>+ //
>+ // Close the input FvRecovery.fv file
>+ //
>+ fclose (FpIn);
>+
>+ return STATUS_SUCCESS;
>+}
>+
>+UINT8 *
>+FindNextFvHeader (
>+ IN UINT8 *FileBuffer,
>+ IN UINTN FileLength
>+ )
>+/*++
>+
>+ Routine Description:
>+ Find next FvHeader in the FileBuffer
>+
>+ Parameters:
>+ FileBuffer - The start FileBuffer which needs to be searched
>+ FileLength - The whole File Length.
>+ Return:
>+ FvHeader - The FvHeader is found successfully.
>+ NULL - The FvHeader is not found.
>+
>+--*/
>+{
>+ UINT8 *FileHeader;
>+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
>+ UINT16 FileChecksum;
>+
>+ FileHeader = FileBuffer;
>+ for (; (UINTN)FileBuffer < (UINTN)FileHeader + FileLength; FileBuffer += 8) {
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer;
>+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
>+ //
>+ // potential candidate
>+ //
>+
>+ //
>+ // Check checksum
>+ //
>+ if (FvHeader->FvLength > FileLength) {
>+ continue;
>+ }
>+ if (FvHeader->HeaderLength >= FileLength) {
>+ continue;
>+ }
>+ FileChecksum = CalculateChecksum16 ((UINT16 *)FileBuffer, FvHeader-
>>HeaderLength / sizeof (UINT16));
>+ if (FileChecksum != 0) {
>+ continue;
>+ }
>+
>+ //
>+ // Check revision and reserved field
>+ //
>+#if (PI_SPECIFICATION_VERSION < 0x00010000)
>+ if ((FvHeader->Revision == EFI_FVH_REVISION) &&
>+ (FvHeader->Reserved[0] == 0) &&
>+ (FvHeader->Reserved[1] == 0) &&
>+ (FvHeader->Reserved[2] == 0) ){
>+ return FileBuffer;
>+ }
>+#else
>+ if ((FvHeader->Revision == EFI_FVH_PI_REVISION) &&
>+ (FvHeader->Reserved[0] == 0) ){
>+ return FileBuffer;
>+ }
>+#endif
>+ }
>+ }
>+
>+ return NULL;
>+}
>+
>+UINT8 *
>+FindFileFromFvByGuid (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize,
>+ IN EFI_GUID *Guid,
>+ OUT UINT32 *FileSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Find File with GUID in an FV
>+
>+Arguments:
>+
>+ FvBuffer - FV binary buffer
>+ FvSize - FV size
>+ Guid - File GUID value to be searched
>+ FileSize - Guid File size
>+
>+Returns:
>+
>+ FileLocation - Guid File location.
>+ NULL - Guid File is not found.
>+
>+--*/
>+{
>+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
>+ EFI_FFS_FILE_HEADER *FileHeader;
>+ UINT64 FvLength;
>+ EFI_GUID *TempGuid;
>+ UINT8 *FixPoint;
>+ UINT32 Offset;
>+ UINT32 FileLength;
>+ UINT32 FileOccupiedSize;
>+
>+ //
>+ // Find the FFS file
>+ //
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FindNextFvHeader
>(FvBuffer, FvSize);
>+ if (NULL == FvHeader) {
>+ return NULL;
>+ }
>+ while (TRUE) {
>+ FvLength = FvHeader->FvLength;
>+
>+ //
>+ // Prepare to walk the FV image
>+ //
>+ InitializeFvLib (FvHeader, (UINT32)FvLength);
>+
>+ FileHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FvHeader + FvHeader-
>>HeaderLength);
>+ Offset = (UINT32) (UINTN) FileHeader - (UINT32) (UINTN) FvHeader;
>+
>+ while (Offset < FvLength) {
>+ TempGuid = (EFI_GUID *)&(FileHeader->Name);
>+ FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
>+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
>+ if ((CompareGuid (TempGuid, Guid)) == 0) {
>+ //
>+ // Good! Find it.
>+ //
>+ FixPoint = ((UINT8 *)FileHeader + sizeof(EFI_FFS_FILE_HEADER));
>+ //
>+ // Find the position of file module, the offset
>+ // between the position and the end of FvRecovery.fv file
>+ // should not exceed 128kB to prevent reset vector from
>+ // outside legacy E and F segment
>+ //
>+ if ((UINTN)FvHeader + FvLength - (UINTN)FixPoint > 0x20000) {
>+ // printf ("WARNING: The position of file module is not in E and F
>segment!\n");
>+ // return NULL;
>+ }
>+ *FileSize = FileLength - sizeof(EFI_FFS_FILE_HEADER);
>+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
>+ if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
>+ *FileSize -= sizeof(EFI_FFS_FILE_TAIL);
>+ }
>+ #endif
>+ return FixPoint;
>+ }
>+ FileHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FileHeader +
>FileOccupiedSize);
>+ Offset = (UINT32) (UINTN) FileHeader - (UINT32) (UINTN) FvHeader;
>+ }
>+
>+ //
>+ // Not found, check next FV
>+ //
>+ if ((UINTN)FvBuffer + FvSize > (UINTN)FvHeader + FvLength) {
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FindNextFvHeader
>((UINT8 *)FvHeader + (UINTN)FvLength, (UINTN)FvBuffer + FvSize -
>((UINTN)FvHeader + (UINTN)FvLength));
>+ if (FvHeader == NULL) {
>+ break;
>+ }
>+ } else {
>+ break;
>+ }
>+ }
>+
>+ //
>+ // Not found
>+ //
>+ return NULL;
>+}
>+
>+BOOLEAN
>+IsGuidData (
>+ IN CHAR8 *StringData,
>+ OUT EFI_GUID *Guid
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Check whether a string is a GUID
>+
>+Arguments:
>+
>+ StringData - the String
>+ Guid - Guid to hold the value
>+
>+Returns:
>+
>+ TRUE - StringData is a GUID, and Guid field is filled.
>+ FALSE - StringData is not a GUID
>+
>+--*/
>+{
>+ if (strlen (StringData) != strlen ("00000000-0000-0000-0000-000000000000"))
>{
>+ return FALSE;
>+ }
>+ if ((StringData[8] != '-') ||
>+ (StringData[13] != '-') ||
>+ (StringData[18] != '-') ||
>+ (StringData[23] != '-') ) {
>+ return FALSE;
>+ }
>+
>+ StringToGuid (StringData, Guid);
>+
>+ return TRUE;
>+}
>+
>+VOID
>+CheckOverlap (
>+ IN UINT32 Address,
>+ IN UINT32 Size
>+ )
>+{
>+ INTN Index;
>+
>+ for (Index = 0; Index < (INTN)gFitTableContext.BiosModuleNumber; Index
>++) {
>+ if ((gFitTableContext.BiosModule[Index].Address <= Address) &&
>+ ((gFitTableContext.BiosModule[Index].Size - Size) >= (Address -
>gFitTableContext.BiosModule[Index].Address))) {
>+ UINT32 TempSize;
>+ INT32 SubIndex;
>+
>+ //
>+ // Found overlap, split BiosModuleEntry
>+ // Currently only support StartupAcm in 1 BiosModule. It does not
>support StartupAcm across 2 BiosModule or more.
>+ //
>+ if (gFitTableContext.BiosModuleNumber >= MAX_BIOS_MODULE_ENTRY)
>{
>+ Error (NULL, 0, 0, "Too many Bios Module!", NULL);
>+ return ;
>+ }
>+
>+ if (Address != gFitTableContext.BiosModule[Index].Address) {
>+ //
>+ // Skip the entry whose start address is same as StartupAcm
>+ //
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type
>= FIT_TABLE_TYPE_BIOS_MODULE;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres
>s = gFitTableContext.BiosModule[Index].Address;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size =
>Address - gFitTableContext.BiosModule[Index].Address;
>+ gFitTableContext.BiosModuleNumber ++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+
>+ TempSize = gFitTableContext.BiosModule[Index].Address +
>gFitTableContext.BiosModule[Index].Size;
>+ gFitTableContext.BiosModule[Index].Address = Address + Size;
>+ gFitTableContext.BiosModule[Index].Size = TempSize -
>gFitTableContext.BiosModule[Index].Address;
>+
>+ if (gFitTableContext.BiosModule[Index].Size == 0) {
>+ //
>+ // remove the entry if size is 0
>+ //
>+ for (SubIndex = Index; SubIndex <
>(INTN)gFitTableContext.BiosModuleNumber - 1; SubIndex ++) {
>+ gFitTableContext.BiosModule[SubIndex].Address =
>gFitTableContext.BiosModule[SubIndex + 1].Address;
>+ gFitTableContext.BiosModule[SubIndex].Size =
>gFitTableContext.BiosModule[SubIndex + 1].Size;
>+ }
>+ gFitTableContext.BiosModuleNumber --;
>+ gFitTableContext.FitEntryNumber--;
>+ }
>+ break;
>+ }
>+ }
>+}
>+
>+UINT32
>+GetFitEntryNumber (
>+ IN INTN argc,
>+ IN CHAR8 **argv,
>+ IN UINT8 *FdBuffer,
>+ IN UINT32 FdSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Get FIT entry number and fill global FIT table context, from argument
>+
>+Arguments:
>+
>+ argc - Number of command line parameters.
>+ argv - Array of pointers to parameter strings.
>+ FdBuffer - FD binary buffer
>+ FdSize - FD size
>+
>+Returns:
>+
>+ FitEntryNumber - The FIT entry number
>+ 0 - Argument parse fail
>+
>+*/
>+{
>+ EFI_GUID Guid;
>+ INTN Index;
>+ UINT8 *FileBuffer;
>+ UINT32 FileSize;
>+ UINT32 Type;
>+ UINT8 *MicrocodeFileBuffer;
>+ UINT8 *MicrocodeFileBufferRaw;
>+ UINT32 MicrocodeFileSize;
>+ UINT32 MicrocodeBase;
>+ UINT32 MicrocodeSize;
>+ UINT8 *MicrocodeBuffer;
>+ UINT32 MicrocodeRegionOffset;
>+ UINT32 MicrocodeRegionSize;
>+ STATUS Status;
>+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
>+ UINTN FitEntryNumber;
>+ BOOLEAN BiosInfoExist;
>+ BIOS_INFO_HEADER *BiosInfo;
>+ BIOS_INFO_STRUCT *BiosInfoStruct;
>+ UINTN BiosInfoIndex;
>+
>+ //
>+ // Init index
>+ //
>+ Index = 3;
>+ if (((strcmp (argv[1], "-D") == 0) ||
>+ (strcmp (argv[1], "-d") == 0)) ) {
>+ Index ++;
>+ }
>+
>+ //
>+ // Fill Global Version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ gFitTableContext.GlobalVersion = DEFAULT_FIT_ENTRY_VERSION;
>+ } else {
>+ gFitTableContext.GlobalVersion = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ //
>+ // 0. FIT Header
>+ //
>+ gFitTableContext.FitEntryNumber = 1;
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-F") != 0) &&
>+ (strcmp (argv[Index], "-f") != 0)) ) {
>+ //
>+ // Use default address
>+ //
>+ gFitTableContext.FitTablePointerOffset =
>DEFAULT_FIT_TABLE_POINTER_OFFSET;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.FitTablePointerOffset = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ //
>+ // 0.1 FIT Header 2
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-F") != 0) &&
>+ (strcmp (argv[Index], "-f") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ gFitTableContext.FitTablePointerOffset2 = 0;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.FitTablePointerOffset2 = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ //
>+ // 0.2 FIT Header version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ gFitTableContext.FitHeaderVersion = gFitTableContext.GlobalVersion;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.FitHeaderVersion = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ //
>+ // 0.3 Microcode alignment
>+ //
>+ if ((Index >= argc) ||
>+ ((strcmp (argv[Index], "-NA") != 0) &&
>+ (strcmp (argv[Index], "-na") != 0)) ) {
>+ //
>+ // by pass
>+ //
>+ gFitTableContext.MicrocodeAlignment = TRUE;
>+ } else {
>+ //
>+ // no alignment
>+ //
>+ gFitTableContext.MicrocodeAlignment = FALSE;
>+ Index += 1;
>+ }
>+
>+ //
>+ // 0.4 Clear FIT table related memory
>+ //
>+ if ((Index >= argc) ||
>+ ((strcmp (argv[Index], "-CLEAR") != 0) &&
>+ (strcmp (argv[Index], "-clear") != 0)) ) {
>+ //
>+ // by pass
>+ //
>+ gFitTableContext.Clear = FALSE;
>+ } else {
>+ //
>+ // Clear FIT table
>+ //
>+ gFitTableContext.Clear = TRUE;
>+ //
>+ // Do not parse any more
>+ //
>+ return 0;
>+ }
>+
>+ //
>+ // 0.5 BiosInfo
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-I") != 0) &&
>+ (strcmp (argv[Index], "-i") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ BiosInfoExist = FALSE;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ BiosInfoExist = TRUE;
>+ if (IsGuidData (argv[Index + 1], &Guid)) {
>+ FileBuffer = FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &FileSize);
>+ if (FileBuffer == NULL) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, GUID not found!", "%s",
>argv[Index + 1]);
>+ // not found
>+ return 0;
>+ }
>+ BiosInfo = (BIOS_INFO_HEADER *)FileBuffer;
>+ for (BiosInfoIndex = 0; BiosInfoIndex < FileSize; BiosInfoIndex++) {
>+ if (((BIOS_INFO_HEADER *)(FileBuffer + BiosInfoIndex))->Signature ==
>BIOS_INFO_SIGNATURE) {
>+ BiosInfo = (BIOS_INFO_HEADER *)(FileBuffer + BiosInfoIndex);
>+ }
>+ }
>+ if (BiosInfo->Signature != BIOS_INFO_SIGNATURE) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Signature Error!", NULL);
>+ // not found
>+ return 0;
>+ }
>+ BiosInfoStruct = (BIOS_INFO_STRUCT *)(BiosInfo + 1);
>+
>+ for (BiosInfoIndex = 0; BiosInfoIndex < BiosInfo->EntryCount;
>BiosInfoIndex++) {
>+ if ((BiosInfoStruct[BiosInfoIndex].Attributes &
>BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT) != 0) {
>+ continue;
>+ }
>+ switch (BiosInfoStruct[BiosInfoIndex].Type) {
>+ case FIT_TABLE_TYPE_HEADER:
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Header Type unsupported!",
>NULL);
>+ return 0;
>+ case FIT_TABLE_TYPE_STARTUP_ACM:
>+ if (gFitTableContext.StartupAcm.Type != 0) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Duplicated StartupAcm!",
>NULL);
>+ return 0;
>+ }
>+ gFitTableContext.StartupAcm.Type =
>FIT_TABLE_TYPE_STARTUP_ACM;
>+ gFitTableContext.StartupAcm.Address =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+ gFitTableContext.StartupAcm.Size =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Size;
>+ gFitTableContext.StartupAcmVersion =
>BiosInfoStruct[BiosInfoIndex].Version;
>+ gFitTableContext.FitEntryNumber ++;
>+ break;
>+ case FIT_TABLE_TYPE_BIOS_MODULE:
>+ if ((BiosInfoStruct[BiosInfoIndex].Attributes &
>BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB) != 0) {
>+ continue;
>+ }
>+ if (gFitTableContext.BiosModuleNumber >=
>MAX_BIOS_MODULE_ENTRY) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Bios Module!",
>NULL);
>+ return 0;
>+ }
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type
>= FIT_TABLE_TYPE_BIOS_MODULE;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres
>s = (UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Size;
>+ gFitTableContext.BiosModuleVersion =
>BiosInfoStruct[BiosInfoIndex].Version;
>+ gFitTableContext.BiosModuleNumber ++;
>+ gFitTableContext.FitEntryNumber ++;
>+ break;
>+ case FIT_TABLE_TYPE_MICROCODE:
>+ if ((BiosInfoStruct[BiosInfoIndex].Attributes &
>BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION) == 0) {
>+ if (gFitTableContext.MicrocodeNumber >= MAX_MICROCODE_ENTRY)
>{
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Microcode!",
>NULL);
>+ return 0;
>+ }
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type =
>FIT_TABLE_TYPE_MICROCODE;
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Size;
>+ gFitTableContext.MicrocodeVersion =
>BiosInfoStruct[BiosInfoIndex].Version;
>+ gFitTableContext.MicrocodeNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+ } else {
>+ MicrocodeRegionOffset =
>(UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+ MicrocodeRegionSize = (UINT32)BiosInfoStruct[BiosInfoIndex].Size;
>+ if (MicrocodeRegionOffset == 0) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegionOffset is 0",
>NULL);
>+ return 0;
>+ }
>+ if (MicrocodeRegionSize == 0) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegionSize is 0",
>NULL);
>+ return 0;
>+ }
>+ if (MicrocodeRegionSize > FdSize) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegionSize too
>large", NULL);
>+ return 0;
>+ }
>+
>+ MicrocodeFileBuffer = FLASH_TO_MEMORY (MicrocodeRegionOffset,
>FdBuffer, FdSize);
>+ MicrocodeFileSize = MicrocodeRegionSize;
>+ MicrocodeBase = MicrocodeRegionOffset;
>+
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER
>*)MicrocodeFileBuffer;
>+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
>+ // Skip FV header + FFS header
>+ MicrocodeBuffer = MicrocodeFileBuffer +
>sizeof(EFI_FIRMWARE_VOLUME_HEADER) +
>sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER);
>+ } else {
>+ MicrocodeBuffer = MicrocodeFileBuffer;
>+ }
>+ while ((UINT32)(MicrocodeBuffer - MicrocodeFileBuffer) <
>MicrocodeFileSize) {
>+ if (*(UINT32 *)(MicrocodeBuffer) != 0x1) { // HeaderVersion
>+ break;
>+ }
>+ if (*(UINT32 *)(MicrocodeBuffer + 20) != 0x1) { // LoaderVersion
>+ break;
>+ }
>+ if (*(UINT32 *)(MicrocodeBuffer + 28) == 0) { // DataSize
>+ MicrocodeSize = 2048;
>+ } else {
>+ //
>+ // MCU might be put at 2KB alignment, if so, we need to adjust the
>size as 2KB alignment.
>+ //
>+ if (gFitTableContext.MicrocodeAlignment) {
>+ MicrocodeSize = (*(UINT32 *)(MicrocodeBuffer + 32) +
>MICROCODE_ALIGNMENT) & ~MICROCODE_ALIGNMENT;
>+ } else {
>+ MicrocodeSize = (*(UINT32 *)(MicrocodeBuffer + 32));
>+ }
>+ }
>+
>+ //
>+ // Add Microcode
>+ //
>+ if (gFitTableContext.MicrocodeNumber >= MAX_MICROCODE_ENTRY)
>{
>+ printf ("-I Parameter incorrect, Too many Microcode!\n");
>+ return 0;
>+ }
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type =
>FIT_TABLE_TYPE_MICROCODE;
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =
>MicrocodeBase + ((UINT32) (UINTN) MicrocodeBuffer - (UINT32) (UINTN)
>MicrocodeFileBuffer);
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =
>MicrocodeSize;
>+ gFitTableContext.MicrocodeNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+
>+ MicrocodeBuffer += MicrocodeSize;
>+ }
>+ }
>+ break;
>+ case FIT_TABLE_TYPE_TPM_POLICY:
>+ case FIT_TABLE_TYPE_BIOS_POLICY:
>+ case FIT_TABLE_TYPE_TXT_POLICY:
>+ case FIT_TABLE_TYPE_KEY_MANIFEST:
>+ case FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST:
>+ case FIT_TABLE_TYPE_BIOS_DATA_AREA:
>+ case FIT_TABLE_TYPE_CSE_SECURE_BOOT:
>+ default :
>+ if (BiosInfoStruct[BiosInfoIndex].Version != 0) {
>+ if (gFitTableContext.OptionalModuleNumber >=
>MAX_OPTIONAL_ENTRY) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Optional
>Module!", NULL);
>+ return 0;
>+ }
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Type = BiosInfoStruct[BiosInfoIndex].Type;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Address = (UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Size = (UINT32)BiosInfoStruct[BiosInfoIndex].Size;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Version = BiosInfoStruct[BiosInfoIndex].Version;
>+ gFitTableContext.OptionalModuleNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+ } else {
>+ if (gFitTableContext.PortModuleNumber >= MAX_PORT_ENTRY) {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Port Module!",
>NULL);
>+ return 0;
>+ }
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type
>= BiosInfoStruct[BiosInfoIndex].Type;
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres
>s = (UINT32)BiosInfoStruct[BiosInfoIndex].Address;
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size =
>(UINT32)(BiosInfoStruct[BiosInfoIndex].Address >> 32);
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version
>= BiosInfoStruct[BiosInfoIndex].Version;
>+ gFitTableContext.PortModuleNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+ break;
>+ }
>+ }
>+
>+ } else {
>+ Error (NULL, 0, 0, "-I Parameter incorrect, expect GUID!", NULL);
>+ return 0;
>+ }
>+ Index += 2;
>+ }
>+
>+ //
>+ // 1. StartupAcm
>+ //
>+ do {
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-S") != 0) &&
>+ (strcmp (argv[Index], "-s") != 0)) ) {
>+ if (BiosInfoExist && (gFitTableContext.StartupAcm.Type ==
>FIT_TABLE_TYPE_STARTUP_ACM)) {
>+ break;
>+ }
>+// Error (NULL, 0, 0, "-S Parameter incorrect, expect -S!", NULL);
>+// return 0;
>+ printf ("-S not found. WARNING!\n");
>+ break;
>+ }
>+ if (IsGuidData (argv[Index + 1], &Guid)) {
>+ FileBuffer = FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &FileSize);
>+ if (FileBuffer == NULL) {
>+ Error (NULL, 0, 0, "-S Parameter incorrect, GUID not found!", "%s",
>argv[Index + 1]);
>+ // not found
>+ return 0;
>+ }
>+ FileBuffer = (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdSize);
>+ Index += 2;
>+ } else {
>+ if (Index + 2 >= argc) {
>+ Error (NULL, 0, 0, "-S Parameter incorrect, expect Address Size!", NULL);
>+ return 0;
>+ }
>+ FileBuffer = (UINT8 *) (UINTN) xtoi (argv[Index + 1]);
>+ FileSize = xtoi (argv[Index + 2]);
>+ Index += 3;
>+ }
>+ if (gFitTableContext.StartupAcm.Type != 0) {
>+ Error (NULL, 0, 0, "-S Parameter incorrect, Duplicated StartupAcm!", NULL);
>+ return 0;
>+ }
>+ gFitTableContext.StartupAcm.Type = FIT_TABLE_TYPE_STARTUP_ACM;
>+ gFitTableContext.StartupAcm.Address = (UINT32) (UINTN) FileBuffer;
>+ gFitTableContext.StartupAcm.Size = FileSize;
>+ gFitTableContext.FitEntryNumber ++;
>+
>+ //
>+ // 1.1 StartupAcm version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ gFitTableContext.StartupAcmVersion = gFitTableContext.GlobalVersion;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.StartupAcmVersion = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+ } while (FALSE);
>+
>+ //
>+ // 2. BiosModule
>+ //
>+ do {
>+ if ((Index + 2 >= argc) ||
>+ ((strcmp (argv[Index], "-B") != 0) &&
>+ (strcmp (argv[Index], "-b") != 0)) ) {
>+ if (BiosInfoExist && (gFitTableContext.BiosModuleNumber != 0)) {
>+ break;
>+ }
>+// Error (NULL, 0, 0, "-B Parameter incorrect, expect -B!", NULL);
>+// return 0;
>+ printf ("-B not found. WARNING!\n");
>+ break;
>+ }
>+
>+ FileBuffer = (UINT8 *) (UINTN) xtoi (argv[Index + 1]);
>+ FileSize = xtoi (argv[Index + 2]);
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type =
>FIT_TABLE_TYPE_BIOS_MODULE;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres
>s = (UINT32) (UINTN) FileBuffer;
>+ gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size
>= FileSize;
>+ gFitTableContext.BiosModuleNumber ++;
>+ gFitTableContext.FitEntryNumber ++;
>+
>+ while (TRUE) {
>+ Index += 3;
>+ if (Index + 2 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index], "-B") != 0) &&
>+ (strcmp (argv[Index], "-b") != 0) ) {
>+ break;
>+ }
>+ if (gFitTableContext.BiosModuleNumber >= MAX_BIOS_MODULE_ENTRY)
>{
>+ Error (NULL, 0, 0, "-B Parameter incorrect, Too many Bios Module!",
>NULL);
>+ return 0;
>+ }
>+ FileBuffer = (UINT8 *) (UINTN) xtoi (argv[Index + 1]);
>+ FileSize = xtoi (argv[Index + 2]);
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type =
>FIT_TABLE_TYPE_BIOS_MODULE;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres
>s = (UINT32) (UINTN) FileBuffer;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size =
>FileSize;
>+ gFitTableContext.BiosModuleNumber ++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+
>+ //
>+ // 2.1 BiosModule version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ gFitTableContext.BiosModuleVersion = gFitTableContext.GlobalVersion;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.BiosModuleVersion = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+ } while (FALSE);
>+
>+ //
>+ // 3. Microcode
>+ //
>+ while (TRUE) {
>+ if (Index + 1 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index], "-M") != 0) &&
>+ (strcmp (argv[Index], "-m") != 0) ) {
>+ break;
>+ }
>+ if (IsGuidData (argv[Index + 2], &Guid)) {
>+ Error (NULL, 0, 0, "-M Parameter incorrect, GUID unsupported!", NULL);
>+ return 0;
>+ } else {
>+ if (Index + 2 >= argc) {
>+ break;
>+ }
>+ FileBuffer = (UINT8 *) (UINTN) xtoi (argv[Index + 1]);
>+ FileSize = xtoi (argv[Index + 2]);
>+ Index += 3;
>+ }
>+ if (gFitTableContext.MicrocodeNumber >= MAX_MICROCODE_ENTRY) {
>+ Error (NULL, 0, 0, "-M Parameter incorrect, Too many Microcode!", NULL);
>+ return 0;
>+ }
>+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type =
>FIT_TABLE_TYPE_MICROCODE;
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =
>(UINT32) (UINTN) FileBuffer;
>+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =
>FileSize;
>+ gFitTableContext.MicrocodeNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+
>+ //
>+ // 3.1 MicrocodeFv
>+ //
>+ while (TRUE) {
>+ if (Index + 1 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index], "-U") != 0) &&
>+ (strcmp (argv[Index], "-u") != 0) ) {
>+ break;
>+ }
>+ //
>+ // Get Fv
>+ //
>+ if (IsGuidData (argv[Index + 1], &Guid)) {
>+ MicrocodeFileBuffer = FindFileFromFvByGuid (FdBuffer, FdSize, &Guid,
>&MicrocodeFileSize);
>+ if (MicrocodeFileBuffer == NULL) {
>+ Error (NULL, 0, 0, "-U Parameter incorrect, GUID not found!", "%s",
>argv[Index + 1]);
>+ // not found
>+ return 0;
>+ }
>+ Index += 2;
>+
>+ MicrocodeBuffer = MicrocodeFileBuffer;
>+ MicrocodeFileBufferRaw = NULL;
>+ MicrocodeRegionOffset = MEMORY_TO_FLASH (MicrocodeFileBuffer,
>FdBuffer, FdSize);
>+ MicrocodeRegionSize = 0;
>+ MicrocodeBase = MicrocodeRegionOffset;
>+
>+ } else {
>+ if (Index + 2 >= argc) {
>+ break;
>+ }
>+ Status = ReadInputFile (argv[Index + 1], &MicrocodeFileBuffer,
>&MicrocodeFileSize, &MicrocodeFileBufferRaw);
>+ if (Status != STATUS_SUCCESS) {
>+ MicrocodeRegionOffset = xtoi (argv[Index + 1]);
>+ MicrocodeRegionSize = xtoi (argv[Index + 2]);
>+
>+ if (MicrocodeRegionOffset == 0) {
>+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionOffset is 0,
>or unable to open file", "%s", argv[Index + 1]);
>+ return 0;
>+ }
>+ if (MicrocodeRegionSize == 0) {
>+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionSize is 0",
>NULL);
>+ return 0;
>+ }
>+ if (MicrocodeRegionSize > FdSize) {
>+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionSize too
>large", NULL);
>+ return 0;
>+ }
>+
>+ Index += 3;
>+
>+ MicrocodeFileBufferRaw = NULL;
>+ MicrocodeFileBuffer = FLASH_TO_MEMORY (MicrocodeRegionOffset,
>FdBuffer, FdSize);
>+ MicrocodeFileSize = MicrocodeRegionSize;
>+ MicrocodeBase = MicrocodeRegionOffset;
>+
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)MicrocodeFileBuffer;
>+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
>+ // Skip FV header + FFS header
>+ MicrocodeBuffer = MicrocodeFileBuffer +
>sizeof(EFI_FIRMWARE_VOLUME_HEADER) +
>sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER);
>+ } else {
>+ MicrocodeBuffer = MicrocodeFileBuffer;
>+ }
>+ } else {
>+ MicrocodeBase = xtoi (argv[Index + 2]);
>+ Index += 3;
>+ MicrocodeRegionOffset = 0;
>+ MicrocodeRegionSize = 0;
>+
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)MicrocodeFileBuffer;
>+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
>+ // Skip FV header + FFS header
>+ MicrocodeBuffer = MicrocodeFileBuffer +
>sizeof(EFI_FIRMWARE_VOLUME_HEADER) +
>sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER);
>+ } else {
>+ MicrocodeBuffer = MicrocodeFileBuffer;
>+ }
>+ }
>+ }
>+ while ((UINT32)(MicrocodeBuffer - MicrocodeFileBuffer) <
>MicrocodeFileSize) {
>+ if (*(UINT32 *)(MicrocodeBuffer) != 0x1) { // HeaderVersion
>+ break;
>+ }
>+ if (*(UINT32 *)(MicrocodeBuffer + 20) != 0x1) { // LoaderVersion
>+ break;
>+ }
>+ if (*(UINT32 *)(MicrocodeBuffer + 28) == 0) { // DataSize
>+ MicrocodeSize = 2048;
>+ } else {
>+ //
>+ // MCU might be put at 2KB alignment, if so, we need to adjust the size
>as 2KB alignment.
>+ //
>+ if (gFitTableContext.MicrocodeAlignment) {
>+ MicrocodeSize = (*(UINT32 *)(MicrocodeBuffer + 32) +
>MICROCODE_ALIGNMENT) & ~MICROCODE_ALIGNMENT;
>+ } else {
>+ MicrocodeSize = (*(UINT32 *)(MicrocodeBuffer + 32));
>+ }
>+ }
>+
>+ //
>+ // Add Microcode
>+ //
>+ if (gFitTableContext.MicrocodeNumber >= MAX_MICROCODE_ENTRY) {
>+ printf ("-U Parameter incorrect, Too many Microcode!\n");
>+ return 0;
>+ }
>+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type
>= FIT_TABLE_TYPE_MICROCODE;
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =
>MicrocodeBase + ((UINT32) (UINTN) MicrocodeBuffer - (UINT32) (UINTN)
>MicrocodeFileBuffer);
>+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =
>MicrocodeSize;
>+ gFitTableContext.MicrocodeNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+
>+ MicrocodeBuffer += MicrocodeSize;
>+ }
>+
>+ if (MicrocodeFileBufferRaw != NULL) {
>+ free ((VOID *)MicrocodeFileBufferRaw);
>+ MicrocodeFileBufferRaw = NULL;
>+ }
>+ }
>+
>+ //
>+ // 3.3 Microcode version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+ gFitTableContext.MicrocodeVersion = gFitTableContext.GlobalVersion;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.MicrocodeVersion = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ //
>+ // 4. Optional type
>+ //
>+ while (TRUE) {
>+ if (Index + 2 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index], "-O") != 0) &&
>+ (strcmp (argv[Index], "-o") != 0) ) {
>+ break;
>+ }
>+ Type = xtoi (argv[Index + 1]);
>+ //
>+ // 1st, try GUID
>+ //
>+ if (IsGuidData (argv[Index + 2], &Guid)) {
>+ FileBuffer = FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &FileSize);
>+ if (FileBuffer == NULL) {
>+ Error (NULL, 0, 0, "-O Parameter incorrect, GUID not found!", "%s",
>argv[Index + 2]);
>+ // not found
>+ return 0;
>+ }
>+ if (FileSize >= 0x80000000) {
>+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too large!", NULL);
>+ return 0;
>+ }
>+ FileBuffer = (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdSize);
>+ Index += 3;
>+ } else {
>+ //
>+ // 2nd, try file
>+ //
>+ Status = ReadInputFile (argv[Index + 2], &FileBuffer, &FileSize, NULL);
>+ if (Status == STATUS_SUCCESS) {
>+ if (FileSize >= 0x80000000) {
>+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too large!", NULL);
>+ free (FileBuffer);
>+ return 0;
>+ }
>+ //
>+ // Set the most significant bit
>+ // It means the data in memory, not in flash yet.
>+ // Assume the file size should < 2G.
>+ //
>+ FileSize |= 0x80000000;
>+ Index += 3;
>+ } else {
>+ //
>+ // 3rd, try <RESERVE, Length>
>+ //
>+ if (Index + 3 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index + 2], "RESERVE") == 0) ||
>+ (strcmp (argv[Index + 2], "reserve") == 0)) {
>+ FileSize = xtoi (argv[Index + 3]);
>+ if (FileSize >= 0x80000000) {
>+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too large!", NULL);
>+ return 0;
>+ }
>+ FileBuffer = malloc (FileSize);
>+ if (FileBuffer == NULL) {
>+ Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL);
>+ return 0;
>+ }
>+ SetMem (FileBuffer, FileSize, 0xFF);
>+ //
>+ // Set the most significant bit
>+ // It means the data in memory, not in flash yet.
>+ // Assume the file size should < 2G.
>+ //
>+ FileSize |= 0x80000000;
>+ Index += 4;
>+ } else {
>+ //
>+ // 4th, try <Address, Length>
>+ //
>+ if (Index + 3 >= argc) {
>+ break;
>+ }
>+ FileBuffer = (UINT8 *) (UINTN) xtoi (argv[Index + 2]);
>+ FileSize = xtoi (argv[Index + 3]);
>+ if (FileSize >= 0x80000000) {
>+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too large!", NULL);
>+ return 0;
>+ }
>+ Index += 4;
>+ }
>+ }
>+ }
>+ if (gFitTableContext.OptionalModuleNumber >= MAX_OPTIONAL_ENTRY)
>{
>+ Error (NULL, 0, 0, "-O Parameter incorrect, Too many Optional Module!",
>NULL);
>+ free (FileBuffer);
>+ return 0;
>+ }
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Type = Type;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Address = (UINT32) (UINTN) FileBuffer;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Size = FileSize;
>+
>+ //
>+ // 4.1 Optional Module version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Version = gFitTableContext.GlobalVersion;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Version = xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ gFitTableContext.OptionalModuleNumber ++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+
>+ //
>+ // 5. Port type
>+ //
>+ while (TRUE) {
>+ if (Index + 6 >= argc) {
>+ break;
>+ }
>+ if ((strcmp (argv[Index], "-P") != 0) &&
>+ (strcmp (argv[Index], "-p") != 0) ) {
>+ break;
>+ }
>+
>+ Type = xtoi (argv[Index + 1]);
>+ if (gFitTableContext.PortModuleNumber >= MAX_PORT_ENTRY) {
>+ printf ("-P Parameter incorrect, Too many Port Module!\n");
>+ return 0;
>+ }
>+
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type =
>Type;
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres
>s = (UINT16)xtoi (argv[Index + 2]) + ((UINT16)xtoi (argv[Index + 3]) << 16);
>+ gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size
>= (UINT8)xtoi (argv[Index + 4]) + ((UINT8)xtoi (argv[Index + 5]) << 8) +
>((UINT16)xtoi (argv[Index + 6]) << 16);
>+ Index += 7;
>+
>+ //
>+ // 5.1 Port Module version
>+ //
>+ if ((Index + 1 >= argc) ||
>+ ((strcmp (argv[Index], "-V") != 0) &&
>+ (strcmp (argv[Index], "-v") != 0)) ) {
>+ //
>+ // Bypass
>+ //
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version
>= 0;
>+ } else {
>+ //
>+ // Get offset from parameter
>+ //
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version
>= xtoi (argv[Index + 1]);
>+ Index += 2;
>+ }
>+
>+ gFitTableContext.PortModuleNumber++;
>+ gFitTableContext.FitEntryNumber++;
>+ }
>+
>+ //
>+ // Final: Check StartupAcm in BiosModule.
>+ //
>+ CheckOverlap (gFitTableContext.StartupAcm.Address,
>gFitTableContext.StartupAcm.Size);
>+ FitEntryNumber = gFitTableContext.FitEntryNumber;
>+ for (Index = 0; Index < (INTN)gFitTableContext.OptionalModuleNumber;
>Index++) {
>+ if ((gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_POLICY) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_KEY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_DATA_AREA) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {
>+ // NOTE: It might be virtual address now. Just put a place holder.
>+ FitEntryNumber ++;
>+ }
>+ }
>+
>+ return FitEntryNumber;
>+}
>+
>+VOID *
>+FindSpaceSkipApVector (
>+ IN UINT8 *FvBuffer,
>+ IN UINT8 *Address,
>+ IN UINTN Size
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ No enough space - it might happen that it is occupied by AP wake vector.
>+ Last chance - skip this and search again.
>+
>+Arguments:
>+
>+ FvBuffer - FvRecovery binary buffer
>+ Address - Address to be searched from
>+ Size - Size need to be filled
>+
>+Returns:
>+
>+ FitTableOffset - The FIT table offset
>+ NULL - No enough space for FIT table
>+
>+*/
>+{
>+ UINT8 *ApVector;
>+ UINT8 *NewAddress;
>+ UINTN Index;
>+
>+ ApVector = (UINT8 *)((UINTN)Address & ~0xFFF);
>+ if ((UINTN)ApVector <= (UINTN)FvBuffer) {
>+ return NULL;
>+ }
>+
>+ NewAddress = (UINT8 *)(ApVector - Size);
>+ for (Index = 0; Index < Size; Index ++) {
>+ if (NewAddress[Index] != 0xFF) {
>+ return NULL;
>+ }
>+ }
>+ return NewAddress;
>+}
>+
>+VOID *
>+GetFreeSpaceFromFv (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize,
>+ IN UINT32 FitEntryNumber
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Get free space for FIT table from FvRecovery
>+
>+Arguments:
>+
>+ FvBuffer - FvRecovery binary buffer
>+ FvSize - FvRecovery size
>+ FitEntryNumber - The FIT entry number
>+
>+Returns:
>+
>+ FitTableOffset - The offset of FIT table in FvRecovery file
>+ NULL - Free space not found
>+
>+--*/
>+{
>+ UINT8 *FitTableOffset;
>+ INTN Index;
>+ INTN SubIndex;
>+ UINT8 *OptionalModuleAddress;
>+ EFI_GUID VTFGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
>+ UINT32 AlignedSize;
>+ UINT32 FitTableSize;
>+
>+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
>+ EFI_FFS_FILE_HEADER *FileHeader;
>+ UINT64 FvLength;
>+ UINT32 Offset;
>+ UINT32 FileLength;
>+ UINT32 FileOccupiedSize;
>+
>+ //
>+ // Check 4G - FitTablePointerOffset
>+ //
>+ if ((*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset) != 0xFFFFFFFFFFFFFFFFull) &&
>+ (*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset) != 0) &&
>+ (*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset) != 0xEEEEEEEEEEEEEEEEull)) {
>+ Error (NULL, 0, 0, "4G - FitTablePointerOffset is occupied!", NULL);
>+ return NULL;
>+ }
>+ if (gFitTableContext.FitTablePointerOffset2 != 0) {
>+ if ((*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset2) != 0xFFFFFFFFFFFFFFFFull) &&
>+ (*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset2) != 0) &&
>+ (*(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset2) != 0xEEEEEEEEEEEEEEEEull)) {
>+ Error (NULL, 0, 0, "4G - FitTablePointerOffset is occupied!", NULL);
>+ return NULL;
>+ }
>+ }
>+
>+ //
>+ // Get EFI_FFS_VOLUME_TOP_FILE_GUID location
>+ //
>+ FitTableOffset = NULL;
>+
>+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvBuffer;
>+ FvLength = FvHeader->FvLength;
>+ FileHeader = (EFI_FFS_FILE_HEADER *)(FvBuffer + FvHeader-
>>HeaderLength);
>+ Offset = (UINTN)FileHeader - (UINTN)FvBuffer;
>+
>+ while (Offset < FvLength) {
>+ FileLength = (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF;
>+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
>+ if ((CompareGuid (&(FileHeader->Name), &VTFGuid)) == 0) {
>+ // find it
>+ FitTableOffset = (UINT8 *)FileHeader;
>+ break;
>+ }
>+ FileHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FileHeader +
>FileOccupiedSize);
>+ Offset = (UINTN)FileHeader - (UINTN)FvBuffer;
>+ }
>+
>+ if (FitTableOffset == NULL) {
>+ Error (NULL, 0, 0, "EFI_FFS_VOLUME_TOP_FILE_GUID not found!", NULL);
>+ return NULL;
>+ }
>+
>+ FitTableSize = FitEntryNumber *
>sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY);
>+ FitTableSize += FIT_ALIGNMENT;
>+ FitTableSize &= ~FIT_ALIGNMENT;
>+
>+ FitTableOffset = (UINT8 *)((UINTN)FitTableOffset & ~FIT_ALIGNMENT);
>+ FitTableOffset = (UINT8 *)(FitTableOffset - FitTableSize);
>+
>+ //
>+ // Check it
>+ //
>+ for (Index = 0; Index < (INTN)(FitTableSize); Index ++) {
>+ if (FitTableOffset[Index] != 0xFF) {
>+ //
>+ // No enough space - it might happen that it is occupied by AP wake
>vector.
>+ // Last chance - skip this and search again.
>+ //
>+ FitTableOffset = FindSpaceSkipApVector (FvBuffer,
>&FitTableOffset[Index], FitTableSize);
>+ if (FitTableOffset == NULL) {
>+ Error (NULL, 0, 0, "No enough space for FIT table!", NULL);
>+ return NULL;
>+ }
>+ }
>+ }
>+
>+ //
>+ // Check space for Optional module
>+ //
>+ OptionalModuleAddress = FitTableOffset;
>+ for (Index = 0; Index < (INTN)gFitTableContext.OptionalModuleNumber;
>Index++) {
>+ AlignedSize = gFitTableContext.OptionalModule[Index].Size;
>+ if ((gFitTableContext.OptionalModule[Index].Size & 0x80000000) != 0) {
>+
>+ //
>+ // Need copy binary to file.
>+ //
>+ gFitTableContext.OptionalModule[Index].Size &= ~0x80000000;
>+
>+ AlignedSize = gFitTableContext.OptionalModule[Index].Size;
>+ if ((gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_POLICY) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_KEY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_DATA_AREA) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {
>+ // Let it 64 byte align
>+ AlignedSize += BIOS_MODULE_ALIGNMENT;
>+ AlignedSize &= ~BIOS_MODULE_ALIGNMENT;
>+ }
>+
>+ OptionalModuleAddress -= AlignedSize;
>+
>+ if ((gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_POLICY) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_KEY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_DATA_AREA) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {
>+ // Let it 64 byte align
>+ OptionalModuleAddress = (UINT8 *)((UINTN)OptionalModuleAddress &
>~BIOS_MODULE_ALIGNMENT);
>+ }
>+
>+ for (SubIndex = 0; SubIndex < (INTN)(AlignedSize); SubIndex ++) {
>+ if (OptionalModuleAddress[SubIndex] != 0xFF) {
>+ //
>+ // No enough space - it might happen that it is occupied by AP wake
>vector.
>+ // Last chance - skip this and search again.
>+ //
>+ OptionalModuleAddress = FindSpaceSkipApVector (FvBuffer,
>&OptionalModuleAddress[SubIndex], AlignedSize);
>+ if (OptionalModuleAddress == NULL) {
>+ Error (NULL, 0, 0, "No enough space for OptionalModule!", NULL);
>+ return NULL;
>+ }
>+ }
>+ }
>+ memcpy (OptionalModuleAddress, (VOID *) (UINTN)
>gFitTableContext.OptionalModule[Index].Address,
>gFitTableContext.OptionalModule[Index].Size);
>+ free ((VOID *) (UINTN)
>gFitTableContext.OptionalModule[Index].Address);
>+ gFitTableContext.OptionalModule[Index].Address = MEMORY_TO_FLASH
>(OptionalModuleAddress, FvBuffer, FvSize);
>+ }
>+ //
>+ // Final: Check BiosPolicyData in BiosModule.
>+ //
>+ if ((gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_POLICY) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_KEY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_BIOS_DATA_AREA) ||
>+ (gFitTableContext.OptionalModule[Index].Type ==
>FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {
>+ CheckOverlap (gFitTableContext.OptionalModule[Index].Address,
>AlignedSize);
>+ }
>+ }
>+
>+ return FitTableOffset;
>+}
>+
>+VOID
>+PrintFitData (
>+ VOID
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Output FIT table information
>+
>+Arguments:
>+
>+ None
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ UINT32 Index;
>+
>+ printf ("FIT Table Pointer Offset: 0x%x\n",
>gFitTableContext.FitTablePointerOffset);
>+ if (gFitTableContext.FitTablePointerOffset2 != 0) {
>+ printf ("FIT Table Pointer Offset: 0x%x\n",
>gFitTableContext.FitTablePointerOffset2);
>+ }
>+ printf ("Total FIT Entry number: 0x%x\n",
>gFitTableContext.FitEntryNumber);
>+ printf ("FitHeader version: 0x%04x\n", gFitTableContext.FitHeaderVersion);
>+ if (gFitTableContext.StartupAcm.Address != 0) {
>+ printf ("StartupAcm - (0x%08x, 0x%08x, 0x%04x)\n",
>gFitTableContext.StartupAcm.Address, gFitTableContext.StartupAcm.Size,
>gFitTableContext.StartupAcmVersion);
>+ }
>+ for (Index = 0; Index < gFitTableContext.BiosModuleNumber; Index++) {
>+ printf ("BiosModule[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index,
>gFitTableContext.BiosModule[Index].Address,
>gFitTableContext.BiosModule[Index].Size,
>gFitTableContext.BiosModuleVersion);
>+ }
>+ for (Index = 0; Index < gFitTableContext.MicrocodeNumber; Index++) {
>+ printf ("Microcode[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index,
>gFitTableContext.Microcode[Index].Address,
>gFitTableContext.Microcode[Index].Size,
>gFitTableContext.MicrocodeVersion);
>+ }
>+ for (Index = 0; Index < gFitTableContext.OptionalModuleNumber; Index++)
>{
>+ printf ("OptionalModule[%d] - (0x%08x, 0x%08x, 0x%02x, 0x%04x)\n",
>Index, gFitTableContext.OptionalModule[Index].Address,
>gFitTableContext.OptionalModule[Index].Size,
>gFitTableContext.OptionalModule[Index].Type,
>gFitTableContext.OptionalModule[Index].Version);
>+ }
>+ for (Index = 0; Index < gFitTableContext.PortModuleNumber; Index++) {
>+ printf ("PortModule[%d] - (0x%04x, 0x%04x, 0x%02x, 0x%02x, 0x%04x,
>0x%02x, 0x%04x)\n", Index,
>+ (UINT16)gFitTableContext.PortModule[Index].Address,
>(UINT16)(gFitTableContext.PortModule[Index].Address >> 16),
>+ (UINT8)gFitTableContext.PortModule[Index].Size,
>(UINT8)(gFitTableContext.PortModule[Index].Size >> 8),
>(UINT16)(gFitTableContext.PortModule[Index].Size >> 16),
>+ gFitTableContext.PortModule[Index].Type,
>gFitTableContext.PortModule[Index].Version);
>+ }
>+
>+ printf ("\n");
>+ return ;
>+}
>+
>+CHAR8 *mFitTypeStr[] = {
>+ " ",
>+ "MICROCODE ",
>+ "STARTUP_ACM",
>+ " ",
>+ " ",
>+ " ",
>+ " ",
>+ "BIOS_MODULE",
>+ "TPM_POLICY ",
>+ "BIOS_POLICY",
>+ "TXT_POLICY ",
>+ "KEYMANIFEST",
>+ "BP_MANIFEST",
>+ "BIOS_DATA_A",
>+ " ",
>+ " ",
>+ "CSE_SECUREB"
>+};
>+
>+CHAR8 mFitSignature[] = "'_FIT_ ' ";
>+CHAR8 mFitSignatureInHeader[] = "' ' ";
>+CHAR8 *
>+FitTypeToStr (
>+ IN FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Convert FitEntry type to a string
>+
>+Arguments:
>+
>+ FitEntry - Fit entry
>+
>+Returns:
>+
>+ String
>+
>+--*/
>+{
>+ if (FitEntry->Type == FIT_TABLE_TYPE_HEADER) {
>+ CopyMem (&mFitSignatureInHeader[1], &FitEntry->Address,
>sizeof(FitEntry->Address));
>+ return mFitSignatureInHeader;
>+ }
>+ if (FitEntry->Type < sizeof (mFitTypeStr)/sizeof(mFitTypeStr[0])) {
>+ return mFitTypeStr[FitEntry->Type];
>+ } else {
>+ return " ";
>+ }
>+}
>+
>+VOID
>+PrintFitTable (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Print Fit table in flash image
>+
>+Arguments:
>+
>+ FvBuffer - FvRecovery binary buffer
>+ FvSize - FvRecovery size
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;
>+ UINT32 EntryNum;
>+ UINT32 Index;
>+ UINT32 FitTableOffset;
>+ FIRMWARE_INTERFACE_TABLE_ENTRY_PORT *FitEntryPort;
>+
>+ printf ("##############\n");
>+ printf ("# FIT Table: #\n");
>+ printf ("##############\n");
>+
>+ printf ("FIT Pointer Offset: 0x%x\n",
>gFitTableContext.FitTablePointerOffset);
>+ FitTableOffset = *(UINT32 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset);
>+ printf ("FIT Table Address: 0x%x\n", FitTableOffset);
>+ FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY
>*)FLASH_TO_MEMORY(FitTableOffset, FvBuffer, FvSize);
>+
>+ //
>+ // Check FitEntry is 16 byte aligned
>+ //
>+ if (((UINTN)FitEntry & 0xF) != 0) {
>+ printf("ERROR: invalid FitEntry address 0x%X!\n", (UINT32) (UINTN)
>FitEntry);
>+ return;
>+ }
>+
>+ EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF;
>+ printf ("====== ================ ====== ======== ==============
>==== ======== (====== ==== ====== ==== ======)\n");
>+ printf ("Index: Address Size Version Type C_V Checksum (Index
>Data Width Bit Offset)\n");
>+ printf ("====== ================ ====== ======== ==============
>==== ======== (====== ==== ====== ==== ======)\n");
>+ for (Index = 0; Index < EntryNum; Index++) {
>+ printf (" %02d: %016llx %06x %04x %02x-%s %02x %02x ",
>+ Index,
>+ (unsigned long long) FitEntry[Index].Address,
>+ *(UINT32 *)(&FitEntry[Index].Size[0]) & 0xFFFFFF,
>+ FitEntry[Index].Version,
>+ FitEntry[Index].Type,
>+ FitTypeToStr(&FitEntry[Index]),
>+ FitEntry[Index].C_V,
>+ FitEntry[Index].Checksum
>+ );
>+
>+ if (Index == 0) {
>+ if (FitEntry[Index].Type != FIT_TABLE_TYPE_HEADER) {
>+ printf("ERROR: FIT Entry 0 is not Header Type %d!\n",
>FIT_TABLE_TYPE_HEADER);
>+ return;
>+ }
>+ if (strcmp(mFitSignatureInHeader, mFitSignature) != 0) {
>+ printf("ERROR: FIT Entry 0 signature invalid (%s, expected %s)!\n",
>mFitSignatureInHeader, mFitSignature);
>+ return;
>+ }
>+
>+ }
>+
>+ switch (FitEntry[Index].Type) {
>+ case FIT_TABLE_TYPE_TPM_POLICY:
>+ case FIT_TABLE_TYPE_TXT_POLICY:
>+ if (FitEntry[Index].Version == 0) {
>+ FitEntryPort = (FIRMWARE_INTERFACE_TABLE_ENTRY_PORT
>*)&FitEntry[Index];
>+ printf (" ( %04x %04x %02x %02x %04x )\n",
>+ FitEntryPort->IndexPort,
>+ FitEntryPort->DataPort,
>+ FitEntryPort->Width,
>+ FitEntryPort->Bit,
>+ FitEntryPort->Index
>+ );
>+ break;
>+ }
>+ // Not Port Configure, pass through
>+ default:
>+ printf ("\n");
>+ break;
>+ }
>+ }
>+ printf ("====== ================ ====== ======== ==============
>==== ======== (====== ==== ====== ==== ======)\n");
>+ printf ("Index: Address Size Version Type C_V Checksum (Index
>Data Width Bit Offset)\n");
>+ printf ("====== ================ ====== ======== ==============
>==== ======== (====== ==== ====== ==== ======)\n");
>+}
>+
>+/**
>+
>+ This function dump raw data.
>+
>+ @param Data raw data
>+ @param Size raw data size
>+
>+**/
>+VOID
>+DumpData (
>+ IN UINT8 *Data,
>+ IN UINT32 Size
>+ )
>+{
>+ UINT32 Index;
>+ for (Index = 0; Index < Size; Index++) {
>+ printf ("%02x", Data[Index]);
>+ }
>+}
>+
>+/**
>+
>+ This function dump raw data with colume format.
>+
>+ @param Data raw data
>+ @param Size raw data size
>+
>+**/
>+VOID
>+DumpHex (
>+ IN UINT8 *Data,
>+ IN UINT32 Size
>+ )
>+{
>+ UINT32 Index;
>+ UINT32 Count;
>+ UINT32 Left;
>+
>+#define COLUME_SIZE (16 * 2)
>+
>+ Count = Size / COLUME_SIZE;
>+ Left = Size % COLUME_SIZE;
>+ for (Index = 0; Index < Count; Index++) {
>+ printf ("%04x: ", Index * COLUME_SIZE);
>+ DumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
>+ printf ("\n");
>+ }
>+
>+ if (Left != 0) {
>+ printf ("%04x: ", Index * COLUME_SIZE);
>+ DumpData (Data + Index * COLUME_SIZE, Left);
>+ printf ("\n");
>+ }
>+}
>+
>+//
>+// This table defines the ACM type string
>+//
>+CHAR8 *mAcmTypeStr[] = {
>+ "BIOS ACM",
>+ "SINIT ACM",
>+};
>+
>+//
>+// This table defines the ACM capability string
>+//
>+CHAR8 *mCapabilityStr[] = {
>+ "GETSEC[WAKEUP] for RLP ",
>+ "MONITOR address for RLP ",
>+ "ECX for MLE PageTable ",
>+ "STM support ",
>+};
>+
>+VOID
>+DumpAcm (
>+ IN ACM_FORMAT *Acm
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ DumpAcm information
>+
>+Arguments:
>+
>+ Acm - ACM buffer
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable;
>+ CHIPSET_ID_LIST *ChipsetIdList;
>+ PROCESSOR_ID_LIST *ProcessorIdList;
>+ UINT32 Index;
>+ UINT8 *Buffer;
>+
>+ printf (
>+
>"**********************************************************
>*******************\n"
>+ "* ACM *\n"
>+
>"**********************************************************
>*******************\n"
>+ );
>+
>+ printf ("ACM: (%08x)\n", (UINT32) (UINTN) Acm);
>+ printf (" ModuleType - %04x\n", Acm->ModuleType);
>+ if (Acm->ModuleType == ACM_MODULE_TYPE_CHIPSET_ACM) {
>+ printf (" Chipset ACM\n");
>+ }
>+ printf (" ModuleSubType - %04x\n", Acm->ModuleSubType);
>+ if ((Acm->ModuleSubType &
>ACM_MODULE_SUBTYPE_CAPABLE_OF_EXECUTE_AT_RESET) != 0) {
>+ printf (" Capable of be Executed at Reset\n");
>+ }
>+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) != 0)
>{
>+ printf (" AnC Module\n");
>+ }
>+ printf (" HeaderLen - %08x\n", Acm->HeaderLen);
>+ printf (" HeaderVersion - %08x\n", Acm->HeaderVersion);
>+ printf (" ChipsetID - %04x\n", Acm->ChipsetID);
>+ printf (" Flags - %04x\n", Acm->Flags);
>+ printf (" PreProduction - %04x\n", Acm->Flags &
>ACM_MODULE_FLAG_PREPRODUCTION);
>+ printf (" Debug Signed - %04x\n", Acm->Flags &
>ACM_MODULE_FLAG_DEBUG_SIGN);
>+ printf (" ModuleVendor - %08x\n", Acm->ModuleVendor);
>+ printf (" Date - %08x\n", Acm->Date);
>+ printf (" Size - %08x\n", Acm->Size);
>+ printf (" TxtSvn - %04x\n", Acm->TxtSvn);
>+ printf (" SeSvn - %04x\n", Acm->SeSvn);
>+ printf (" CodeControl - %08x\n", Acm->CodeControl);
>+ printf (" ErrorEntryPoint - %08x\n", Acm->ErrorEntryPoint);
>+ printf (" GDTLimit - %08x\n", Acm->GDTLimit);
>+ printf (" GDTBasePtr - %08x\n", Acm->GDTBasePtr);
>+ printf (" SegSel - %08x\n", Acm->SegSel);
>+ printf (" EntryPoint - %08x\n", Acm->EntryPoint);
>+ printf (" KeySize - %08x\n", Acm->KeySize);
>+ printf (" ScratchSize - %08x\n", Acm->ScratchSize);
>+
>+ Buffer = (UINT8 *)(Acm + 1);
>+ printf (" RSAPubKey - \n");
>+ DumpHex (Buffer, Acm->KeySize * 4);
>+ printf ("\n");
>+ Buffer += Acm->KeySize * 4;
>+
>+ if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {
>+ printf (" RSASig - \n");
>+ DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE); //
>PKCS #1.5 RSA Signature
>+ printf ("\n");
>+ Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;
>+ } else {
>+ printf (" RSAPubExp - %08x\n", *(UINT32 *)Buffer);
>+ Buffer += 4;
>+
>+ printf (" RSASig - \n");
>+ DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE); //
>PKCS #1.5 RSA Signature
>+ printf ("\n");
>+ Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE;
>+ }
>+ Buffer += Acm->ScratchSize * 4;
>+
>+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) ==
>0) {
>+ ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE
>*)Buffer;
>+ printf ("Chipset ACM info:\n");
>+ printf (
>+ " Guid - {%08x-%08x-%08x-%08x}\n",
>+ ChipsetAcmInformationTable->Guid.Guid0,
>+ ChipsetAcmInformationTable->Guid.Guid1,
>+ ChipsetAcmInformationTable->Guid.Guid2,
>+ ChipsetAcmInformationTable->Guid.Guid3
>+ );
>+ printf (" ChipsetACMType - %02x\n", ChipsetAcmInformationTable-
>>ChipsetACMType);
>+ if (ChipsetAcmInformationTable->ChipsetACMType <
>sizeof(mAcmTypeStr)/sizeof(mAcmTypeStr[0])) {
>+ printf (" %s\n", mAcmTypeStr[ChipsetAcmInformationTable-
>>ChipsetACMType]);
>+ }
>+ printf (" Version - %02x\n", ChipsetAcmInformationTable-
>>Version);
>+ printf (" Length - %04x\n", ChipsetAcmInformationTable-
>>Length);
>+ printf (" ChipsetIDList - %08x\n", ChipsetAcmInformationTable-
>>ChipsetIDList);
>+ printf (" OsSinitTableVer - %08x\n", ChipsetAcmInformationTable-
>>OsSinitTableVer);
>+ printf (" MinMleHeaderVer - %08x\n", ChipsetAcmInformationTable-
>>MinMleHeaderVer);
>+ if (ChipsetAcmInformationTable->Version >=
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_3) {
>+ printf (" Capabilities - %08x\n", ChipsetAcmInformationTable-
>>Capabilities);
>+ for (Index = 0; Index < sizeof(mCapabilityStr)/sizeof(mCapabilityStr[0]);
>Index++) {
>+ if (mCapabilityStr[Index] == NULL) {
>+ continue;
>+ }
>+ printf (
>+ " %s- %08x\n",
>+ mCapabilityStr[Index],
>+ (ChipsetAcmInformationTable->Capabilities & (1 << Index))
>+ );
>+ }
>+ printf (" AcmVersion - %02x\n", ChipsetAcmInformationTable-
>>AcmVersion);
>+ printf (" AcmRevision - %02x.%02x.%02x\n",
>ChipsetAcmInformationTable->AcmRevision[0],
>ChipsetAcmInformationTable->AcmRevision[1],
>ChipsetAcmInformationTable->AcmRevision[2]);
>+ }
>+ if (ChipsetAcmInformationTable->Version >=
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_4) {
>+ printf (" ProcessorIDList - %08x\n", ChipsetAcmInformationTable-
>>ProcessorIDList);
>+ }
>+
>+ ChipsetIdList = (CHIPSET_ID_LIST *)((UINTN)Acm +
>ChipsetAcmInformationTable->ChipsetIDList);
>+ printf ("Chipset ID List info:\n");
>+ printf (" Count - %08x\n", ChipsetIdList->Count);
>+ for (Index = 0; Index < ChipsetIdList->Count; Index++) {
>+ printf (" ID[%d]:\n", Index);
>+ printf (" Flags - %08x\n", ChipsetIdList-
>>ChipsetID[Index].Flags);
>+ printf (" RevisionIdMask - %08x\n", ChipsetIdList-
>>ChipsetID[Index].Flags & ACM_CHIPSET_ID_REVISION_ID_MAKE);
>+ printf (" VendorID - %04x\n", ChipsetIdList-
>>ChipsetID[Index].VendorID);
>+ printf (" DeviceID - %04x\n", ChipsetIdList-
>>ChipsetID[Index].DeviceID);
>+ printf (" RevisionID - %04x\n", ChipsetIdList-
>>ChipsetID[Index].RevisionID);
>+ }
>+ if (ChipsetAcmInformationTable->Version <
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_4) {
>+ goto End;
>+ }
>+ ProcessorIdList = (PROCESSOR_ID_LIST *)((UINTN)Acm +
>ChipsetAcmInformationTable->ProcessorIDList);
>+ printf ("Processor ID List info:\n");
>+ printf (" Count - %08x\n", ProcessorIdList->Count);
>+ for (Index = 0; Index < ProcessorIdList->Count; Index++) {
>+ printf (" ID[%d]:\n", Index);
>+ printf (" FMS - %08x\n", ProcessorIdList-
>>ProcessorID[Index].FMS);
>+ printf (" FMSMask - %08x\n", ProcessorIdList-
>>ProcessorID[Index].FMSMask);
>+ printf (" PlatformID - %016llx\n", (unsigned long long)
>ProcessorIdList->ProcessorID[Index].PlatformID);
>+ printf (" PlatformMask - %016llx\n", (unsigned long long)
>ProcessorIdList->ProcessorID[Index].PlatformMask);
>+ }
>+ }
>+
>+End:
>+ printf (
>+
>"**********************************************************
>*******************\n\n"
>+ );
>+}
>+
>+BOOLEAN
>+CheckAcm (
>+ IN ACM_FORMAT *Acm,
>+ IN UINTN AcmMaxSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Check Acm information
>+
>+Arguments:
>+
>+ Acm - ACM buffer
>+ AcmMaxSize - ACM max size
>+
>+Returns:
>+
>+ TRUE - ACM is valid
>+ FALSE - ACM is invalid
>+
>+--*/
>+{
>+ CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable;
>+ CHIPSET_ID_LIST *ChipsetIdList;
>+ PROCESSOR_ID_LIST *ProcessorIdList;
>+ UINT8 *Buffer;
>+
>+ if (Acm->ModuleType != ACM_MODULE_TYPE_CHIPSET_ACM) {
>+ printf ("ACM invalid : ModuleType!\n");
>+ return FALSE;
>+ }
>+ if (Acm->Size * 4 > AcmMaxSize) {
>+ printf ("ACM invalid : Size!\n");
>+ return FALSE;
>+ }
>+
>+ Buffer = (UINT8 *)(Acm + 1);
>+ Buffer += Acm->KeySize * 4;
>+ if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {
>+ Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;
>+ } else {
>+ Buffer += 4;
>+ Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE;
>+ }
>+ Buffer += Acm->ScratchSize * 4;
>+
>+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) ==
>0) {
>+ ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE
>*)Buffer;
>+ if ((UINTN)ChipsetAcmInformationTable >= (UINTN)Acm + AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetAcmInformationTable!\n");
>+ return FALSE;
>+ }
>+
>+ if (CompareGuid ((EFI_GUID *)&ChipsetAcmInformationTable->Guid,
>(EFI_GUID *)&mChipsetAcmInformationTableGuid03) != 0) {
>+ printf ("ACM invalid : ChipsetACMGuid!\n");
>+ return FALSE;
>+ }
>+ if (ChipsetAcmInformationTable->ChipsetACMType !=
>CHIPSET_ACM_TYPE_BIOS) {
>+ printf ("ACM invalid : ChipsetACMType!\n");
>+ return FALSE;
>+ }
>+ if (ChipsetAcmInformationTable->Version <
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_3) {
>+ printf ("ACM invalid : ChipsetACMVersion!\n");
>+ return FALSE;
>+ }
>+ if ((UINTN)ChipsetAcmInformationTable + ChipsetAcmInformationTable-
>>Length > (UINTN)Acm + AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetACMLength!\n");
>+ return FALSE;
>+ }
>+
>+ if (ChipsetAcmInformationTable->ChipsetIDList >= AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetACMChipsetIDList!\n");
>+ return FALSE;
>+ }
>+ ChipsetIdList = (CHIPSET_ID_LIST *)((UINTN)Acm +
>ChipsetAcmInformationTable->ChipsetIDList);
>+ if (ChipsetIdList->Count == 0) {
>+ printf ("ACM invalid : ChipsetACMChipsetIDListCount!\n");
>+ return FALSE;
>+ }
>+ if (ChipsetAcmInformationTable->ChipsetIDList + sizeof(CHIPSET_ID_LIST)
>+ (ChipsetIdList->Count - 1) * sizeof(ACM_CHIPSET_ID) > AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetACMChipsetIDList!\n");
>+ return FALSE;
>+ }
>+
>+ if (ChipsetAcmInformationTable->Version <
>CHIPSET_ACM_INFORMATION_TABLE_VERSION_4) {
>+ goto End;
>+ }
>+
>+ if (ChipsetAcmInformationTable->ProcessorIDList >= AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetACMProcessorIDList!\n");
>+ return FALSE;
>+ }
>+ ProcessorIdList = (PROCESSOR_ID_LIST *)((UINTN)Acm +
>ChipsetAcmInformationTable->ProcessorIDList);
>+ if (ProcessorIdList->Count == 0) {
>+ printf ("ACM invalid : ChipsetACMProcessorIdListCount!\n");
>+ return FALSE;
>+ }
>+ if (ChipsetAcmInformationTable->ChipsetIDList +
>sizeof(PROCESSOR_ID_LIST) + (ChipsetIdList->Count - 1) *
>sizeof(ACM_PROCESSOR_ID) > AcmMaxSize) {
>+ printf ("ACM invalid : ChipsetACMProcessorIdList!\n");
>+ return FALSE;
>+ }
>+ }
>+
>+End:
>+
>+ return TRUE;
>+}
>+
>+VOID
>+FillFitTable (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize,
>+ IN UINT8 *FitTableOffset
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Fill the FIT table information to FvRecovery
>+
>+Arguments:
>+
>+ FvBuffer - FvRecovery binary buffer
>+ FvSize - FvRecovery size
>+ FitTableOffset - The offset of FIT table in FvRecovery file
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;
>+ UINT32 FitIndex;
>+ UINT32 Index;
>+ UINT8 Checksum;
>+ UINTN SubIndex;
>+ FIT_TABLE_CONTEXT_ENTRY TempContextEntry;
>+ FIRMWARE_INTERFACE_TABLE_ENTRY TempTableEntry;
>+
>+ //
>+ // 1. FitPointer
>+ //
>+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffset) =
>(UINT64)(UINTN)MEMORY_TO_FLASH (FitTableOffset, FvBuffer, FvSize);
>+ if (gFitTableContext.FitTablePointerOffset2 != 0) {
>+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffset2)
>= (UINT64)(UINTN)MEMORY_TO_FLASH (FitTableOffset, FvBuffer, FvSize);
>+ }
>+
>+ FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *)FitTableOffset;
>+ FitIndex = 0;
>+
>+ //
>+ // 2. FitHeader
>+ //
>+ FitEntry[FitIndex].Address = *(UINT64 *)"_FIT_ ";
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] = gFitTableContext.FitEntryNumber;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.FitHeaderVersion;
>+ FitEntry[FitIndex].Type = FIT_TABLE_TYPE_HEADER;
>+ FitEntry[FitIndex].C_V = 1;
>+ //
>+ // Checksum will be updated later...
>+ //
>+ FitEntry[FitIndex].Checksum = 0;
>+
>+ //
>+ // 3. Microcode
>+ //
>+ FitIndex++;
>+ for (Index = 0; Index < gFitTableContext.MicrocodeNumber; Index++) {
>+ FitEntry[FitIndex].Address =
>gFitTableContext.Microcode[Index].Address;
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] = 0;
>//gFitTableContext.Microcode[Index].Size / 16;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.MicrocodeVersion;
>+ FitEntry[FitIndex].Type = FIT_TABLE_TYPE_MICROCODE;
>+ FitEntry[FitIndex].C_V = 0;
>+ FitEntry[FitIndex].Checksum = 0;
>+ FitIndex++;
>+ }
>+
>+ //
>+ // 4. StartupAcm
>+ //
>+ if (gFitTableContext.StartupAcm.Address != 0) {
>+ FitEntry[FitIndex].Address = gFitTableContext.StartupAcm.Address;
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] = 0;
>//gFitTableContext.StartupAcm.Size / 16;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.StartupAcmVersion;
>+ FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM;
>+ FitEntry[FitIndex].C_V = 0;
>+ FitEntry[FitIndex].Checksum = 0;
>+ FitIndex++;
>+ }
>+
>+ //
>+ // 5. BiosModule
>+ //
>+ //
>+ // BiosModule segments order needs to be put from low addresss to high
>for Btg requirement
>+ //
>+ if (gFitTableContext.BiosModuleNumber > 1) {
>+ for (Index = 0; Index < (UINTN)gFitTableContext.BiosModuleNumber - 1;
>Index++){
>+ for (SubIndex = 0; SubIndex < gFitTableContext.BiosModuleNumber -
>Index - 1; SubIndex++) {
>+ if (gFitTableContext.BiosModule[SubIndex].Address >
>gFitTableContext.BiosModule[SubIndex + 1].Address) {
>+ CopyMem (&TempContextEntry,
>&gFitTableContext.BiosModule[SubIndex],
>sizeof(FIT_TABLE_CONTEXT_ENTRY));
>+ CopyMem (&gFitTableContext.BiosModule[SubIndex],
>&gFitTableContext.BiosModule[SubIndex + 1],
>sizeof(FIT_TABLE_CONTEXT_ENTRY));
>+ CopyMem (&gFitTableContext.BiosModule[SubIndex + 1],
>&TempContextEntry, sizeof(FIT_TABLE_CONTEXT_ENTRY));
>+ }
>+ }
>+ }
>+ }
>+ for (Index = 0; Index < gFitTableContext.BiosModuleNumber; Index++) {
>+ FitEntry[FitIndex].Address =
>gFitTableContext.BiosModule[Index].Address;
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =
>gFitTableContext.BiosModule[Index].Size / 16;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.BiosModuleVersion;
>+ FitEntry[FitIndex].Type = FIT_TABLE_TYPE_BIOS_MODULE;
>+ FitEntry[FitIndex].C_V = 0;
>+ FitEntry[FitIndex].Checksum = 0;
>+ FitIndex++;
>+ }
>+
>+ //
>+ // 6. Optional module
>+ //
>+ for (Index = 0; Index < gFitTableContext.OptionalModuleNumber; Index++)
>{
>+ FitEntry[FitIndex].Address =
>gFitTableContext.OptionalModule[Index].Address;
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =
>gFitTableContext.OptionalModule[Index].Size;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.OptionalModule[Index].Version;
>+ FitEntry[FitIndex].Type =
>(UINT8)gFitTableContext.OptionalModule[Index].Type;
>+ FitEntry[FitIndex].C_V = 0;
>+ FitEntry[FitIndex].Checksum = 0;
>+ FitIndex++;
>+ }
>+
>+ //
>+ // 7. Port module
>+ //
>+ for (Index = 0; Index < gFitTableContext.PortModuleNumber; Index++) {
>+ FitEntry[FitIndex].Address =
>gFitTableContext.PortModule[Index].Address +
>((UINT64)gFitTableContext.PortModule[Index].Size << 32);
>+ *(UINT32 *)&FitEntry[FitIndex].Size[0] = 0;
>+ FitEntry[FitIndex].Version =
>(UINT16)gFitTableContext.PortModule[Index].Version;
>+ FitEntry[FitIndex].Type =
>(UINT8)gFitTableContext.PortModule[Index].Type;
>+ FitEntry[FitIndex].C_V = 0;
>+ FitEntry[FitIndex].Checksum = 0;
>+ FitIndex++;
>+ }
>+
>+ //
>+ // The FIT records must always be arranged in the ascending order of their
>type attribute in the FIT.
>+ //
>+ for (Index = 0; Index < (UINTN)FitIndex - 1; Index++){
>+ for (SubIndex = 0; SubIndex < FitIndex - Index - 1; SubIndex++) {
>+ if (FitEntry[SubIndex].Type > FitEntry[SubIndex + 1].Type) {
>+ CopyMem (&TempTableEntry, &FitEntry[SubIndex],
>sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY));
>+ CopyMem (&FitEntry[SubIndex], &FitEntry[SubIndex + 1],
>sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY));
>+ CopyMem (&FitEntry[SubIndex + 1], &TempTableEntry,
>sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY));
>+ }
>+ }
>+ }
>+
>+ //
>+ // Update FIT header signature as final step
>+ //
>+ Checksum = CalculateChecksum8 ((UINT8 *)&FitEntry[0], sizeof
>(FIRMWARE_INTERFACE_TABLE_ENTRY) * FitIndex);
>+ FitEntry[0].Checksum = Checksum;
>+}
>+
>+VOID
>+ClearFitTable (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Clear the FIT table information to Fvrecovery
>+
>+Arguments:
>+
>+ FvBuffer - Fvrecovery binary buffer
>+ FvSize - Fvrecovery size
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;
>+ UINT32 EntryNum;
>+ UINT32 FitIndex;
>+ UINT64 FitTablePointer;
>+ UINT8 *Buffer;
>+ UINT32 BufferSize;
>+
>+ FitTablePointer = *(UINT64 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset);
>+ FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *)FLASH_TO_MEMORY
>(FitTablePointer, FvBuffer, FvSize);
>+
>+ //
>+ // Clear FIT pointer
>+ //
>+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffset) =
>0xEEEEEEEEEEEEEEEEull;
>+ if (gFitTableContext.FitTablePointerOffset2 != 0) {
>+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffset2)
>= 0xEEEEEEEEEEEEEEEEull;
>+ }
>+
>+ //
>+ // Clear FIT table
>+ //
>+ EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF;
>+ for (FitIndex = 0; FitIndex < EntryNum; FitIndex++) {
>+ switch (FitEntry[FitIndex].Type) {
>+ case FIT_TABLE_TYPE_BIOS_POLICY:
>+ case FIT_TABLE_TYPE_KEY_MANIFEST:
>+ case FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST:
>+ case FIT_TABLE_TYPE_BIOS_DATA_AREA:
>+ case FIT_TABLE_TYPE_CSE_SECURE_BOOT:
>+ //
>+ // Clear FIT table data buffer
>+ //
>+ Buffer = FLASH_TO_MEMORY (FitEntry[FitIndex].Address, FvBuffer,
>FvSize);
>+ BufferSize = (*(UINT32 *)FitEntry[FitIndex].Size) & 0xFFFFFF;
>+ SetMem (Buffer, BufferSize, 0xFF);
>+ break;
>+ default:
>+ break;
>+ }
>+ //
>+ // Clear FIT table itself
>+ //
>+ SetMem (&FitEntry[FitIndex], sizeof(FitEntry[FitIndex]), 0xFF);
>+ }
>+}
>+
>+STATUS
>+WriteOutputFile (
>+ IN CHAR8 *FileName,
>+ IN UINT8 *FileData,
>+ IN UINT32 FileSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Read input file
>+
>+Arguments:
>+
>+ FileName - The input file name
>+ FileData - The input file data
>+ FileSize - The input file size
>+
>+Returns:
>+
>+ STATUS_SUCCESS - Write file data successfully
>+ STATUS_ERROR - The file data is not written
>+
>+--*/
>+{
>+ FILE *FpOut;
>+
>+ //
>+ // Open the output FvRecovery.fv file
>+ //
>+ if ((FpOut = fopen (FileName, "w+b")) == NULL) {
>+ Error (NULL, 0, 0, "Unable to open file", "%s", FileName);
>+ return STATUS_ERROR;
>+ }
>+ //
>+ // Write the output FvRecovery.fv file
>+ //
>+ if ((fwrite (FileData, 1, FileSize, FpOut)) != FileSize) {
>+ Error (NULL, 0, 0, "Write output file error!", NULL);
>+ fclose (FpOut);
>+ return STATUS_ERROR;
>+ }
>+
>+ //
>+ // Close the output FvRecovery.fv file
>+ //
>+ fclose (FpOut);
>+
>+ return STATUS_SUCCESS;
>+}
>+
>+UINT32
>+GetFvRecoveryInfoFromFd (
>+ IN UINT8 *FdBuffer,
>+ IN UINT32 FdFileSize,
>+ OUT UINT8 **FvRecovery
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Get FvRecovery information from Fd file.
>+
>+Arguments:
>+
>+ FdBuffer - Fd file buffer.
>+ FdFileSize - Fd file size.
>+ FvRecovery - FvRecovery pointer in Fd file buffer
>+
>+Returns:
>+ FvRecovery file size
>+
>+--*/
>+{
>+ UINT8 *FileBuffer = NULL;
>+ UINT32 FvRecoveryFileSize =0;
>+ EFI_GUID VTFGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;
>+ UINT32 FvLength;
>+ UINT32 FileLength;
>+
>+ *FvRecovery = NULL;
>+ FileBuffer = FindNextFvHeader (FdBuffer, FdFileSize);
>+ if (FileBuffer == NULL) {
>+ return 0;
>+ }
>+
>+ while ((UINTN)FileBuffer < (UINTN)FdBuffer + FdFileSize) {
>+ FvLength = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER
>*)FileBuffer)->FvLength;
>+
>+ if (FindFileFromFvByGuid (FileBuffer, FvLength, &VTFGuid, &FileLength) !=
>NULL) {
>+ //
>+ // Found the VTF
>+ //
>+ FvRecoveryFileSize = FvLength;
>+ *FvRecovery = FileBuffer;
>+ }
>+
>+ //
>+ // Next fv
>+ //
>+ FileBuffer = (UINT8 *)FileBuffer + FvLength;
>+ if ((UINTN)FileBuffer >= (UINTN)FdBuffer + FdFileSize) {
>+ break;
>+ }
>+ FileBuffer = FindNextFvHeader (FileBuffer, (UINTN)FdBuffer + FdFileSize -
>(UINTN)FileBuffer);
>+ if (FileBuffer == NULL) {
>+ break;
>+ }
>+
>+ }
>+
>+ //
>+ // Return
>+ //
>+ return FvRecoveryFileSize;
>+}
>+
>+UINT32
>+GetFitEntryInfo (
>+ IN UINT8 *FvBuffer,
>+ IN UINT32 FvSize
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Fill the FIT table information to Fvrecovery
>+
>+Arguments:
>+
>+ FvBuffer - Fvrecovery binary buffer
>+ FvSize - Fvrecovery size
>+
>+Returns:
>+
>+ 0 - Fit Table not found
>+
>+--*/
>+{
>+ FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;
>+ UINT32 FitIndex;
>+ UINT32 FitTableOffset;
>+
>+ //
>+ // 1. FitPointer
>+ //
>+ if (gFitTableContext.FitTablePointerOffset == 0) {
>+ gFitTableContext.FitTablePointerOffset =
>DEFAULT_FIT_TABLE_POINTER_OFFSET;
>+ }
>+ gFitTableContext.FitTablePointerOffset2 = 0;
>+
>+ FitTableOffset = *(UINT32 *)(FvBuffer + FvSize -
>gFitTableContext.FitTablePointerOffset);
>+
>+ FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY
>*)FLASH_TO_MEMORY(FitTableOffset, FvBuffer, FvSize);
>+ FitIndex = 0;
>+
>+ //
>+ // 2. FitHeader
>+ //
>+ if (FitEntry[FitIndex].Address != *(UINT64 *)"_FIT_ ") {
>+ return 0;
>+ }
>+ if (FitEntry[FitIndex].Type != FIT_TABLE_TYPE_HEADER) {
>+ return 0;
>+ }
>+ gFitTableContext.FitEntryNumber = *(UINT32 *)&FitEntry[FitIndex].Size[0];
>+ gFitTableContext.FitHeaderVersion = FitEntry[FitIndex].Version;
>+
>+ //
>+ // 3. FitEntry
>+ //
>+ FitIndex++;
>+ for (; FitIndex < gFitTableContext.FitEntryNumber; FitIndex++) {
>+ switch (FitEntry[FitIndex].Type) {
>+ case FIT_TABLE_TYPE_MICROCODE:
>+
>gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =
>(UINT32)FitEntry[FitIndex].Address;
>+ gFitTableContext.MicrocodeVersion =
>FitEntry[FitIndex].Version;
>+ gFitTableContext.MicrocodeNumber ++;
>+ break;
>+ case FIT_TABLE_TYPE_STARTUP_ACM:
>+ gFitTableContext.StartupAcm.Address =
>(UINT32)FitEntry[FitIndex].Address;
>+ gFitTableContext.StartupAcmVersion = FitEntry[FitIndex].Version;
>+ break;
>+ case FIT_TABLE_TYPE_BIOS_MODULE:
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres
>s = (UINT32)FitEntry[FitIndex].Address;
>+
>gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size =
>*(UINT32 *)&FitEntry[FitIndex].Size[0] * 16;
>+ gFitTableContext.BiosModuleVersion =
>FitEntry[FitIndex].Version;
>+ gFitTableContext.BiosModuleNumber ++;
>+ break;
>+ case FIT_TABLE_TYPE_TPM_POLICY:
>+ case FIT_TABLE_TYPE_TXT_POLICY:
>+ if (FitEntry[FitIndex].Version == 0) {
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres
>s = (UINT32)FitEntry[FitIndex].Address;
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size =
>(UINT32)(FitEntry[FitIndex].Address >> 32);
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version
>= FitEntry[FitIndex].Version;
>+
>gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type
>= FitEntry[FitIndex].Type;
>+ gFitTableContext.PortModuleNumber ++;
>+ break;
>+ }
>+ // Not Port Configure, pass through
>+ default: // Others
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Address = (UINT32)FitEntry[FitIndex].Address;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Size = *(UINT32 *)&FitEntry[FitIndex].Size[0];
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Version = FitEntry[FitIndex].Version;
>+
>gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber
>].Type = FitEntry[FitIndex].Type;
>+ gFitTableContext.OptionalModuleNumber ++;
>+ break;
>+ }
>+ }
>+
>+ return gFitTableContext.FitEntryNumber;
>+}
>+
>+STATUS
>+FitGen (
>+ IN INTN argc,
>+ IN CHAR8 **argv
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Main function for FitGen.
>+
>+Arguments:
>+
>+ argc - Number of command line parameters.
>+ argv - Array of pointers to parameter strings.
>+
>+Returns:
>+ STATUS_SUCCESS - Utility exits successfully.
>+ STATUS_ERROR - Some error occurred during execution.
>+
>+--*/
>+{
>+ UINT32 FvRecoveryFileSize;
>+ UINT8 *FileBuffer;
>+ UINT8 *FileBufferRaw;
>+ UINTN FitEntryNumber;
>+ UINT8 *FitTableOffset;
>+ STATUS Status;
>+ UINT32 FitTableSize;
>+
>+ BOOLEAN IsFv;
>+ UINT8 *FdFileBuffer;
>+ UINT32 FdFileSize;
>+
>+ UINT8 *AcmBuffer;
>+
>+ //
>+ // Step 0: Check FV or FD
>+ //
>+ if (((strcmp (argv[1], "-D") == 0) ||
>+ (strcmp (argv[1], "-d") == 0)) ) {
>+ IsFv = FALSE;
>+ } else {
>+ IsFv = TRUE;
>+ }
>+
>+ //
>+ // Step 1: Read InputFvRecovery.fv data
>+ //
>+ if (IsFv) {
>+ Status = ReadInputFile (argv[1], &FileBuffer, &FvRecoveryFileSize,
>&FileBufferRaw);
>+ if (Status != STATUS_SUCCESS) {
>+ Error (NULL, 0, 0, "Unable to open file", "%s", argv[1]);
>+ goto exitFunc;
>+ }
>+ FdFileBuffer = FileBuffer;
>+ FdFileSize = FvRecoveryFileSize;
>+ } else {
>+ Status = ReadInputFile (argv[2], &FdFileBuffer, &FdFileSize,
>&FileBufferRaw);
>+ if (Status != STATUS_SUCCESS) {
>+ Error (NULL, 0, 0, "Unable to open file", "%s", argv[2]);
>+ goto exitFunc;
>+ }
>+
>+ //
>+ // Get Fvrecovery information
>+ //
>+ FvRecoveryFileSize = GetFvRecoveryInfoFromFd (FdFileBuffer, FdFileSize,
>&FileBuffer);
>+ if ((FvRecoveryFileSize == 0) || (FileBuffer == NULL)) {
>+ Error (NULL, 0, 0, "FvRecovery not found in Fd file!", NULL);
>+ Status = STATUS_ERROR;
>+ goto exitFunc;
>+ }
>+ }
>+
>+ //
>+ // Step 2: Calculate FIT entry number.
>+ //
>+ FitEntryNumber = GetFitEntryNumber (argc, argv, FdFileBuffer, FdFileSize);
>+ if (!gFitTableContext.Clear) {
>+ if (FitEntryNumber == 0) {
>+ Status = STATUS_ERROR;
>+ goto exitFunc;
>+ }
>+
>+ //
>+ // For debug
>+ //
>+ PrintFitData ();
>+
>+ //
>+ // Add 1 more FitEntry as place holder, because we need exclude FIT table
>itself
>+ //
>+ FitEntryNumber++;
>+
>+ //
>+ // Step 3: Get enough space in FvRecovery.fv
>+ //
>+ FitTableOffset = GetFreeSpaceFromFv (FileBuffer, FvRecoveryFileSize,
>FitEntryNumber);
>+ if (FitTableOffset == NULL) {
>+ return STATUS_ERROR;
>+ }
>+ FitTableSize = FitEntryNumber *
>sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY);
>+ FitTableSize += FIT_ALIGNMENT;
>+ FitTableSize &= ~FIT_ALIGNMENT;
>+
>+ CheckOverlap (
>+ MEMORY_TO_FLASH (FitTableOffset, FdFileBuffer, FdFileSize),
>+ FitTableSize
>+ );
>+
>+ //
>+ // Get ACM buffer
>+ //
>+ if (gFitTableContext.StartupAcm.Address != 0) {
>+ AcmBuffer = FLASH_TO_MEMORY(gFitTableContext.StartupAcm.Address,
>FdFileBuffer, FdFileSize);
>+ if ((AcmBuffer < FdFileBuffer) || (AcmBuffer +
>gFitTableContext.StartupAcm.Size > FdFileBuffer + FdFileSize)) {
>+ printf ("ACM out of range - can not validate it\n");
>+ AcmBuffer = NULL;
>+ }
>+
>+ if (AcmBuffer != NULL) {
>+ if (CheckAcm ((ACM_FORMAT *)AcmBuffer,
>gFitTableContext.StartupAcm.Size)) {
>+ DumpAcm ((ACM_FORMAT *)AcmBuffer);
>+ } else {
>+ Status = STATUS_ERROR;
>+ goto exitFunc;
>+ }
>+ }
>+
>+ }
>+
>+ //
>+ // Step 4: Fill the FIT table one by one
>+ //
>+ FillFitTable (FdFileBuffer, FdFileSize, FitTableOffset);
>+
>+ //
>+ // For debug
>+ //
>+ PrintFitTable (FdFileBuffer, FdFileSize);
>+ } else {
>+ printf ("Clear FIT table ...\n");
>+ //
>+ // Step 3: Get FIT table info
>+ //
>+ FitEntryNumber = GetFitEntryInfo (FdFileBuffer, FdFileSize);
>+ if (FitEntryNumber == 0) {
>+ Error (NULL, 0, 0, "No FIT table found", NULL);
>+ return STATUS_ERROR;
>+ }
>+
>+ //
>+ // For debug
>+ //
>+ PrintFitTable (FdFileBuffer, FdFileSize);
>+
>+ //
>+ // Step 4: Clear FIT table
>+ //
>+ ClearFitTable (FdFileBuffer, FdFileSize);
>+ printf ("Clear FIT table Done!\n");
>+ }
>+
>+ //
>+ // Step 5: Write OutputFvRecovery.fv data
>+ //
>+ if (IsFv) {
>+ Status = WriteOutputFile (argv[2], FileBuffer, FvRecoveryFileSize);
>+ } else {
>+ Status = WriteOutputFile (argv[3], FdFileBuffer, FdFileSize);
>+ }
>+
>+exitFunc:
>+ if (FileBufferRaw != NULL) {
>+ free ((VOID *)FileBufferRaw);
>+ }
>+ return Status;
>+}
>+
>+STATUS
>+FitView (
>+ IN INTN argc,
>+ IN CHAR8 **argv
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ View function for FitGen.
>+
>+Arguments:
>+
>+ argc - Number of command line parameters.
>+ argv - Array of pointers to parameter strings.
>+
>+Returns:
>+ STATUS_SUCCESS - Utility exits successfully.
>+ STATUS_ERROR - Some error occurred during execution.
>+
>+--*/
>+{
>+ UINT32 FvRecoveryFileSize;
>+ UINT8 *FileBuffer;
>+ UINT8 *FileBufferRaw = NULL;
>+ STATUS Status;
>+
>+ //
>+ // Step 1: Read input file
>+ //
>+ Status = ReadInputFile (argv[2], &FileBuffer, &FvRecoveryFileSize,
>&FileBufferRaw);
>+ if (Status != STATUS_SUCCESS) {
>+ Error (NULL, 0, 0, "Unable to open file", "%s", argv[2]);
>+ goto exitFunc;
>+ }
>+
>+ // no -f option, use default FIT pointer offset
>+ if (argc == 3) {
>+ //
>+ // Use default address
>+ //
>+ gFitTableContext.FitTablePointerOffset =
>DEFAULT_FIT_TABLE_POINTER_OFFSET;
>+ } else if (stricmp (argv[3], "-f") == 0) {
>+ if (argc == 5) {
>+ //
>+ // Get offset from parameter
>+ //
>+ gFitTableContext.FitTablePointerOffset = xtoi (argv[3 + 1]);
>+ } else {
>+ Error (NULL, 0, 0, "FIT offset not specified!", NULL);
>+ goto exitFunc;
>+ }
>+ } else {
>+ Error (NULL, 0, 0, "Invalid view option: ", "%s", argv[3]);
>+ goto exitFunc;
>+ }
>+
>+ //
>+ // For debug
>+ //
>+ PrintFitTable (FileBuffer, FvRecoveryFileSize);
>+
>+exitFunc:
>+ if (FileBufferRaw != NULL) {
>+ free ((VOID *)FileBufferRaw);
>+ }
>+ return Status;
>+}
>+
>+int
>+main (
>+ int argc,
>+ char **argv
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Main function.
>+
>+Arguments:
>+
>+ argc - Number of command line parameters.
>+ argv - Array of pointers to parameter strings.
>+
>+Returns:
>+ STATUS_SUCCESS - Utility exits successfully.
>+ STATUS_ERROR - Some error occurred during execution.
>+
>+--*/
>+{
>+ SetUtilityName (UTILITY_NAME);
>+
>+ //
>+ // Display utility information
>+ //
>+ PrintUtilityInfo ();
>+
>+ //
>+ // Verify the correct number of arguments
>+ //
>+ if (argc >= MIN_VIEW_ARGS && stricmp (argv[1], "-view") == 0) {
>+ return FitView (argc, argv);
>+ } else if (argc >= MIN_ARGS) {
>+ return FitGen (argc, argv);
>+ } else {
>+ Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);
>+ PrintUsage ();
>+ return STATUS_ERROR;
>+ }
>+}
>+
>+unsigned int
>+xtoi (
>+ char *str
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Convert hex string to uint
>+
>+Arguments:
>+
>+ str - The string
>+
>+Returns:
>+
>+--*/
>+{
>+ unsigned int u;
>+ char c;
>+ unsigned int m;
>+
>+ if (str == NULL) {
>+ return 0;
>+ }
>+
>+ m = (unsigned int) -1 >> 4;
>+ //
>+ // skip preceeding white space
>+ //
>+ while (*str && *str == ' ') {
>+ str += 1;
>+ }
>+ //
>+ // skip preceeding zeros
>+ //
>+ while (*str && *str == '0') {
>+ str += 1;
>+ }
>+ //
>+ // skip preceeding x/X character
>+ //
>+ if (*str && (*str == 'x' || *str == 'X')) {
>+ str += 1;
>+ }
>+ //
>+ // convert hex digits
>+ //
>+ u = 0;
>+ c = *(str++);
>+ while (c) {
>+ if (c >= 'a' && c <= 'f') {
>+ c -= 'a' - 'A';
>+ }
>+
>+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
>+ if (u > m) {
>+ return (unsigned int) -1;
>+ }
>+
>+ u = (u << 4) | (c - (c >= 'A' ? 'A' - 10 : '0'));
>+ } else {
>+ //
>+ // Let application exit immediately
>+ //
>+ Error (NULL, 0, 0, "Hex value is expected!", NULL);
>+ exit (0);
>+ break;
>+ }
>+
>+ c = *(str++);
>+ }
>+
>+ return u;
>+}
>+
>diff --git a/Silicon/Intel/Tools/FitGen/FitGen.h
>b/Silicon/Intel/Tools/FitGen/FitGen.h
>new file mode 100644
>index 0000000000..9bd3f6824b
>--- /dev/null
>+++ b/Silicon/Intel/Tools/FitGen/FitGen.h
>@@ -0,0 +1,48 @@
>+/**@file
>+Definitions for the FitGen utility.
>+
>+Copyright (c) 2010-2019, Intel Corporation. All rights reserved.<BR>
>+SPDX-License-Identifier: BSD-2-Clause-Patent
>+
>+**/
>+
>+#ifndef _FIT_GEN_H
>+#define _FIT_GEN_H
>+
>+#include <stdio.h>
>+#include <stdlib.h>
>+#define PI_SPECIFICATION_VERSION 0x00010000
>+#define EFI_FVH_PI_REVISION EFI_FVH_REVISION
>+#include <Common/UefiBaseTypes.h>
>+#include <Common/PiFirmwareFile.h>
>+#include <Common/PiFirmwareVolume.h>
>+#include <Guid/PiFirmwareFileSystem.h>
>+#include "EfiUtilityMsgs.c"
>+#include "CommonLib.h"
>+#include "ParseInf.h"
>+#include "FvLib.h"
>+
>+//
>+// Utility Name
>+//
>+#define UTILITY_NAME "FitGen"
>+
>+//
>+// Utility version information
>+//
>+#define UTILITY_MAJOR_VERSION 0
>+#define UTILITY_MINOR_VERSION 56
>+#define UTILITY_DATE __DATE__
>+
>+//
>+// The minimum number of arguments accepted from the command line.
>+//
>+#define MIN_VIEW_ARGS 3
>+#define MIN_ARGS 4
>+#define BUF_SIZE (8 * 1024)
>+
>+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
>+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) &
>((Alignment) - 1))
>+;
>+
>+#endif
>diff --git a/Silicon/Intel/Tools/FitGen/GNUmakefile
>b/Silicon/Intel/Tools/FitGen/GNUmakefile
>new file mode 100644
>index 0000000000..00a99bb0c7
>--- /dev/null
>+++ b/Silicon/Intel/Tools/FitGen/GNUmakefile
>@@ -0,0 +1,16 @@
>+# @file
>+# GNUmakefile for building the FitGen utility.
>+#
>+# Copyright (c) 2010-2019, Intel Corporation. All rights reserved.<BR>
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
>+
>+APPNAME = FitGen
>+
>+OBJECTS = FitGen.o
>+
>+include $(MAKEROOT)/Makefiles/app.makefile
>+
>+LIBS = -lCommon
>+
>diff --git a/Silicon/Intel/Tools/FitGen/Makefile
>b/Silicon/Intel/Tools/FitGen/Makefile
>new file mode 100644
>index 0000000000..fd286b26be
>--- /dev/null
>+++ b/Silicon/Intel/Tools/FitGen/Makefile
>@@ -0,0 +1,17 @@
>+# @file
>+# makefile for building the FitGen utility.
>+#
>+# Copyright (c) 2010-2019, Intel Corporation. All rights reserved.<BR>
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+
>+!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.common
>+
>+APPNAME = FitGen
>+
>+LIBS = $(LIB_PATH)\Common.lib
>+
>+OBJECTS = FitGen.obj
>+
>+!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.app
>+
>--
>2.18.0.windows.1
>
>
>
next prev parent reply other threads:[~2019-06-26 2:03 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-21 1:26 [edk2-platform patch 0/6] Add tools FMMT FCE and FitGen Zhang, Shenglei
2019-06-21 1:26 ` [edk2-platform patch 1/6] Platform\Tools: Add a tool FMMT Zhang, Shenglei
2019-06-21 1:26 ` [edk2-platform patch 2/6] Platform\Tools: Add a tool BfmLib Zhang, Shenglei
2019-06-21 1:26 ` [edk2-platform patch 3/6] BaseTools\FCE: Add a tool FCE Zhang, Shenglei
2019-06-21 1:26 ` [edk2-platform patch 4/6] Platform\Tools: Add top level Makefile and GNUMakefile Zhang, Shenglei
2019-06-21 1:26 ` [edk2-platform patch 5/6] Silicon\Tools: Add a tool FitGen Zhang, Shenglei
2019-06-26 2:03 ` Liming Gao [this message]
2019-06-21 1:26 ` [edk2-platform patch 6/6] Silicon\Tools: Add top level Makefile and GNUMakefile Zhang, Shenglei
2019-06-26 2:04 ` Liming Gao
2019-06-21 2:25 ` [edk2-devel] [edk2-platform patch 0/6] Add tools FMMT FCE and FitGen Yao, Jiewen
2019-06-21 2:31 ` Liming Gao
2019-06-21 3:34 ` Yao, Jiewen
2019-06-25 14:09 ` Liming Gao
2019-06-25 14:14 ` Yao, Jiewen
2019-06-25 15:20 ` Liming Gao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14E48D5DE@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox