From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: liming.gao@intel.com) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by groups.io with SMTP; Tue, 25 Jun 2019 19:03:28 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jun 2019 19:03:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,418,1557212400"; d="scan'208";a="163789250" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga007.fm.intel.com with ESMTP; 25 Jun 2019 19:03:28 -0700 Received: from fmsmsx602.amr.corp.intel.com (10.18.126.82) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 25 Jun 2019 19:03:28 -0700 Received: from fmsmsx602.amr.corp.intel.com (10.18.126.82) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 25 Jun 2019 19:03:27 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 25 Jun 2019 19:03:26 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.185]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.225]) with mapi id 14.03.0439.000; Wed, 26 Jun 2019 10:03:24 +0800 From: "Liming Gao" To: "devel@edk2.groups.io" , "Zhang, Shenglei" CC: "Feng, Bob C" Subject: Re: [edk2-devel] [edk2-platform patch 5/6] Silicon\Tools: Add a tool FitGen Thread-Topic: [edk2-devel] [edk2-platform patch 5/6] Silicon\Tools: Add a tool FitGen Thread-Index: AQHVJ9Byp/7aDFP1kkqE1pUX2284AKatNsgw Date: Wed, 26 Jun 2019 02:03:23 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E48D5DE@SHSMSX104.ccr.corp.intel.com> References: <20190621012643.9352-1-shenglei.zhang@intel.com> <20190621012643.9352-6-shenglei.zhang@intel.com> In-Reply-To: <20190621012643.9352-6-shenglei.zhang@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: liming.gao@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Shenglei: The patch is good to me. Reviewed-by: Liming Gao 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 ; Gao, Liming >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=3D1849 > >Cc: Bob Feng >Cc: Liming Gao >Signed-off-by: Shenglei Zhang >--- > 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.
>+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; // =3D=3D 0 >+ UINT8 Type:7; >+ UINT8 C_V:1; >+ UINT8 Checksum; >+} FIRMWARE_INTERFACE_TABLE_ENTRY_PORT; >+ >+#define FIT_ALIGNMENT 0x3F // 0xF is required previously, but i= f 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 >=3D >CHIPSET_ACM_INFORMATION_TABLE_VERSION_3) >+ UINT32 Capabilities; >+ UINT8 AcmVersion; >+ UINT8 AcmRevision[3]; >+//#if (CHIPSET_ACM_INFORMATION_TABLE_VERSION >=3D >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 =3D >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)(FvSi= ze) - >(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 =3D {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 ]\n" >+ "\t[-F ] [-F ] [= -V >]\n" >+ "\t[-NA]\n" >+ "\t[-CLEAR]\n" >+ "\t[-I ]\n" >+ "\t[-S |] [-= V >]\n" >+ "\t[-B ] [-B ...] [-V >]\n" >+ "\t[-M ] [-M ...]|[-U MicrocodeBase>|MicrocodeRegionSize>|] [-V ]\n" >+ "\t[-O RecordType |RecordDataSize>|| [-V ]] >[-O ... [-V ...]]\n" >+ "\t[-P RecordType [-V >]] [-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 fi= le.\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 m= odule 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 Star= tupAcm >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 i= n final FD >image.\n"); >+ printf ("\tMicrocodeRegionOffset - Offset of Microcode region in inpu= t 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 require= ment. 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 ta= ble >entries. 0x%04x is used if this is not specified.\n", >DEFAULT_FIT_ENTRY_VERSION); >+ printf ("\tFitHeaderVersion - The version for FIT header. (Overr= ide >default version)\n"); >+ printf ("\tStartupAcmVersion - The version for StartupAcm. (Overr= ide >default version)\n"); >+ printf ("\tBiosModuleVersion - The version for BiosModule. (Overr= ide >default version)\n"); >+ printf ("\tMicrocodeVersion - The version for Microcode. (Overri= de >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 \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=3D%d, STATUS_WARNING=3D%d, >STATUS_ERROR=3D%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 =3D (UINT8*)Buffer; >+ while (Length-- > 0) { >+ *(Pointer++) =3D 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 fr= ee 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 =3D fopen (FileName, "rb")) =3D=3D 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 =3D ftell (FpIn); >+ // >+ // Read the contents of input file to memory buffer >+ // >+ if (FileBufferRaw !=3D NULL) { >+ *FileBufferRaw =3D (UINT8 *) malloc (*FileSize + 0x10000); >+ if (NULL =3D=3D *FileBufferRaw) { >+ Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL); >+ fclose (FpIn); >+ return STATUS_ERROR; >+ } >+ TempResult =3D 0x10000 - (UINT32) ((UINTN)*FileBufferRaw & 0x0FFFF); >+ *FileData =3D (UINT8 *)((UINTN)*FileBufferRaw + TempResult); >+ } else { >+ *FileData =3D (UINT8 *) malloc (*FileSize); >+ if (NULL =3D=3D *FileData) { >+ Error (NULL, 0, 0, "No sufficient memory to allocate!", NULL); >+ fclose (FpIn); >+ return STATUS_ERROR; >+ } >+ } >+ fseek (FpIn, 0, SEEK_SET); >+ TempResult =3D fread (*FileData, 1, *FileSize, FpIn); >+ if (TempResult !=3D *FileSize) { >+ Error (NULL, 0, 0, "Read input file error!", NULL); >+ if (FileBufferRaw !=3D 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 searche= d >+ 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 =3D FileBuffer; >+ for (; (UINTN)FileBuffer < (UINTN)FileHeader + FileLength; FileBuffer = +=3D 8) { >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer; >+ if (FvHeader->Signature =3D=3D EFI_FVH_SIGNATURE) { >+ // >+ // potential candidate >+ // >+ >+ // >+ // Check checksum >+ // >+ if (FvHeader->FvLength > FileLength) { >+ continue; >+ } >+ if (FvHeader->HeaderLength >=3D FileLength) { >+ continue; >+ } >+ FileChecksum =3D CalculateChecksum16 ((UINT16 *)FileBuffer, FvHead= er- >>HeaderLength / sizeof (UINT16)); >+ if (FileChecksum !=3D 0) { >+ continue; >+ } >+ >+ // >+ // Check revision and reserved field >+ // >+#if (PI_SPECIFICATION_VERSION < 0x00010000) >+ if ((FvHeader->Revision =3D=3D EFI_FVH_REVISION) && >+ (FvHeader->Reserved[0] =3D=3D 0) && >+ (FvHeader->Reserved[1] =3D=3D 0) && >+ (FvHeader->Reserved[2] =3D=3D 0) ){ >+ return FileBuffer; >+ } >+#else >+ if ((FvHeader->Revision =3D=3D EFI_FVH_PI_REVISION) && >+ (FvHeader->Reserved[0] =3D=3D 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 =3D (EFI_FIRMWARE_VOLUME_HEADER *)FindNextFvHeader >(FvBuffer, FvSize); >+ if (NULL =3D=3D FvHeader) { >+ return NULL; >+ } >+ while (TRUE) { >+ FvLength =3D FvHeader->FvLength; >+ >+ // >+ // Prepare to walk the FV image >+ // >+ InitializeFvLib (FvHeader, (UINT32)FvLength); >+ >+ FileHeader =3D (EFI_FFS_FILE_HEADER *)((UINTN)FvHeader + FvHea= der- >>HeaderLength); >+ Offset =3D (UINT32) (UINTN) FileHeader - (UINT32) (UINTN) = FvHeader; >+ >+ while (Offset < FvLength) { >+ TempGuid =3D (EFI_GUID *)&(FileHeader->Name); >+ FileLength =3D (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; >+ FileOccupiedSize =3D GETOCCUPIEDSIZE(FileLength, 8); >+ if ((CompareGuid (TempGuid, Guid)) =3D=3D 0) { >+ // >+ // Good! Find it. >+ // >+ FixPoint =3D ((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 an= d F >segment!\n"); >+ // return NULL; >+ } >+ *FileSize =3D FileLength - sizeof(EFI_FFS_FILE_HEADER); >+ #if (PI_SPECIFICATION_VERSION < 0x00010000) >+ if (FileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { >+ *FileSize -=3D sizeof(EFI_FFS_FILE_TAIL); >+ } >+ #endif >+ return FixPoint; >+ } >+ FileHeader =3D (EFI_FFS_FILE_HEADER *)((UINTN)FileHeader + >FileOccupiedSize); >+ Offset =3D (UINT32) (UINTN) FileHeader - (UINT32) (UINTN) FvHeader= ; >+ } >+ >+ // >+ // Not found, check next FV >+ // >+ if ((UINTN)FvBuffer + FvSize > (UINTN)FvHeader + FvLength) { >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)FindNextFvHeader >((UINT8 *)FvHeader + (UINTN)FvLength, (UINTN)FvBuffer + FvSize - >((UINTN)FvHeader + (UINTN)FvLength)); >+ if (FvHeader =3D=3D 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) !=3D strlen ("00000000-0000-0000-0000-00000000= 0000")) >{ >+ return FALSE; >+ } >+ if ((StringData[8] !=3D '-') || >+ (StringData[13] !=3D '-') || >+ (StringData[18] !=3D '-') || >+ (StringData[23] !=3D '-') ) { >+ return FALSE; >+ } >+ >+ StringToGuid (StringData, Guid); >+ >+ return TRUE; >+} >+ >+VOID >+CheckOverlap ( >+ IN UINT32 Address, >+ IN UINT32 Size >+ ) >+{ >+ INTN Index; >+ >+ for (Index =3D 0; Index < (INTN)gFitTableContext.BiosModuleNumber; Ind= ex >++) { >+ if ((gFitTableContext.BiosModule[Index].Address <=3D Address) && >+ ((gFitTableContext.BiosModule[Index].Size - Size) >=3D (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 >=3D MAX_BIOS_MODULE_ENTRY) >{ >+ Error (NULL, 0, 0, "Too many Bios Module!", NULL); >+ return ; >+ } >+ >+ if (Address !=3D gFitTableContext.BiosModule[Index].Address) { >+ // >+ // Skip the entry whose start address is same as StartupAcm >+ // >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type >=3D FIT_TABLE_TYPE_BIOS_MODULE; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres >s =3D gFitTableContext.BiosModule[Index].Address; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size = =3D >Address - gFitTableContext.BiosModule[Index].Address; >+ gFitTableContext.BiosModuleNumber ++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ >+ TempSize =3D gFitTableContext.BiosModule[Index].Address + >gFitTableContext.BiosModule[Index].Size; >+ gFitTableContext.BiosModule[Index].Address =3D Address + Size; >+ gFitTableContext.BiosModule[Index].Size =3D TempSize - >gFitTableContext.BiosModule[Index].Address; >+ >+ if (gFitTableContext.BiosModule[Index].Size =3D=3D 0) { >+ // >+ // remove the entry if size is 0 >+ // >+ for (SubIndex =3D Index; SubIndex < >(INTN)gFitTableContext.BiosModuleNumber - 1; SubIndex ++) { >+ gFitTableContext.BiosModule[SubIndex].Address =3D >gFitTableContext.BiosModule[SubIndex + 1].Address; >+ gFitTableContext.BiosModule[SubIndex].Size =3D >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 =3D 3; >+ if (((strcmp (argv[1], "-D") =3D=3D 0) || >+ (strcmp (argv[1], "-d") =3D=3D 0)) ) { >+ Index ++; >+ } >+ >+ // >+ // Fill Global Version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ gFitTableContext.GlobalVersion =3D DEFAULT_FIT_ENTRY_VERSION; >+ } else { >+ gFitTableContext.GlobalVersion =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ // >+ // 0. FIT Header >+ // >+ gFitTableContext.FitEntryNumber =3D 1; >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-F") !=3D 0) && >+ (strcmp (argv[Index], "-f") !=3D 0)) ) { >+ // >+ // Use default address >+ // >+ gFitTableContext.FitTablePointerOffset =3D >DEFAULT_FIT_TABLE_POINTER_OFFSET; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.FitTablePointerOffset =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ // >+ // 0.1 FIT Header 2 >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-F") !=3D 0) && >+ (strcmp (argv[Index], "-f") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ gFitTableContext.FitTablePointerOffset2 =3D 0; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.FitTablePointerOffset2 =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ // >+ // 0.2 FIT Header version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ gFitTableContext.FitHeaderVersion =3D gFitTableContext.GlobalVersion= ; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.FitHeaderVersion =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ // >+ // 0.3 Microcode alignment >+ // >+ if ((Index >=3D argc) || >+ ((strcmp (argv[Index], "-NA") !=3D 0) && >+ (strcmp (argv[Index], "-na") !=3D 0)) ) { >+ // >+ // by pass >+ // >+ gFitTableContext.MicrocodeAlignment =3D TRUE; >+ } else { >+ // >+ // no alignment >+ // >+ gFitTableContext.MicrocodeAlignment =3D FALSE; >+ Index +=3D 1; >+ } >+ >+ // >+ // 0.4 Clear FIT table related memory >+ // >+ if ((Index >=3D argc) || >+ ((strcmp (argv[Index], "-CLEAR") !=3D 0) && >+ (strcmp (argv[Index], "-clear") !=3D 0)) ) { >+ // >+ // by pass >+ // >+ gFitTableContext.Clear =3D FALSE; >+ } else { >+ // >+ // Clear FIT table >+ // >+ gFitTableContext.Clear =3D TRUE; >+ // >+ // Do not parse any more >+ // >+ return 0; >+ } >+ >+ // >+ // 0.5 BiosInfo >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-I") !=3D 0) && >+ (strcmp (argv[Index], "-i") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ BiosInfoExist =3D FALSE; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ BiosInfoExist =3D TRUE; >+ if (IsGuidData (argv[Index + 1], &Guid)) { >+ FileBuffer =3D FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &Fil= eSize); >+ if (FileBuffer =3D=3D NULL) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, GUID not found!", "%= s", >argv[Index + 1]); >+ // not found >+ return 0; >+ } >+ BiosInfo =3D (BIOS_INFO_HEADER *)FileBuffer; >+ for (BiosInfoIndex =3D 0; BiosInfoIndex < FileSize; BiosInfoIndex+= +) { >+ if (((BIOS_INFO_HEADER *)(FileBuffer + BiosInfoIndex))->Signatur= e =3D=3D >BIOS_INFO_SIGNATURE) { >+ BiosInfo =3D (BIOS_INFO_HEADER *)(FileBuffer + BiosInfoIndex); >+ } >+ } >+ if (BiosInfo->Signature !=3D BIOS_INFO_SIGNATURE) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, Signature Error!", N= ULL); >+ // not found >+ return 0; >+ } >+ BiosInfoStruct =3D (BIOS_INFO_STRUCT *)(BiosInfo + 1); >+ >+ for (BiosInfoIndex =3D 0; BiosInfoIndex < BiosInfo->EntryCount; >BiosInfoIndex++) { >+ if ((BiosInfoStruct[BiosInfoIndex].Attributes & >BIOS_INFO_STRUCT_ATTRIBUTE_GENERAL_EXCLUDE_FROM_FIT) !=3D 0) { >+ continue; >+ } >+ switch (BiosInfoStruct[BiosInfoIndex].Type) { >+ case FIT_TABLE_TYPE_HEADER: >+ Error (NULL, 0, 0, "-I Parameter incorrect, Header Type unsupp= orted!", >NULL); >+ return 0; >+ case FIT_TABLE_TYPE_STARTUP_ACM: >+ if (gFitTableContext.StartupAcm.Type !=3D 0) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, Duplicated Start= upAcm!", >NULL); >+ return 0; >+ } >+ gFitTableContext.StartupAcm.Type =3D >FIT_TABLE_TYPE_STARTUP_ACM; >+ gFitTableContext.StartupAcm.Address =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ gFitTableContext.StartupAcm.Size =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Size; >+ gFitTableContext.StartupAcmVersion =3D >BiosInfoStruct[BiosInfoIndex].Version; >+ gFitTableContext.FitEntryNumber ++; >+ break; >+ case FIT_TABLE_TYPE_BIOS_MODULE: >+ if ((BiosInfoStruct[BiosInfoIndex].Attributes & >BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB) !=3D 0) { >+ continue; >+ } >+ if (gFitTableContext.BiosModuleNumber >=3D >MAX_BIOS_MODULE_ENTRY) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Bios Mo= dule!", >NULL); >+ return 0; >+ } >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type >=3D FIT_TABLE_TYPE_BIOS_MODULE; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres >s =3D (UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size = =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Size; >+ gFitTableContext.BiosModuleVersion =3D >BiosInfoStruct[BiosInfoIndex].Version; >+ gFitTableContext.BiosModuleNumber ++; >+ gFitTableContext.FitEntryNumber ++; >+ break; >+ case FIT_TABLE_TYPE_MICROCODE: >+ if ((BiosInfoStruct[BiosInfoIndex].Attributes & >BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION) =3D=3D 0) { >+ if (gFitTableContext.MicrocodeNumber >=3D MAX_MICROCODE_ENTR= Y) >{ >+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Micro= code!", >NULL); >+ return 0; >+ } >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type =3D >FIT_TABLE_TYPE_MICROCODE; >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Size; >+ gFitTableContext.MicrocodeVersion =3D >BiosInfoStruct[BiosInfoIndex].Version; >+ gFitTableContext.MicrocodeNumber++; >+ gFitTableContext.FitEntryNumber++; >+ } else { >+ MicrocodeRegionOffset =3D >(UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ MicrocodeRegionSize =3D (UINT32)BiosInfoStruct[BiosInfoInd= ex].Size; >+ if (MicrocodeRegionOffset =3D=3D 0) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegio= nOffset is 0", >NULL); >+ return 0; >+ } >+ if (MicrocodeRegionSize =3D=3D 0) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegio= nSize is 0", >NULL); >+ return 0; >+ } >+ if (MicrocodeRegionSize > FdSize) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, MicrocodeRegio= nSize too >large", NULL); >+ return 0; >+ } >+ >+ MicrocodeFileBuffer =3D FLASH_TO_MEMORY (MicrocodeRegionOffs= et, >FdBuffer, FdSize); >+ MicrocodeFileSize =3D MicrocodeRegionSize; >+ MicrocodeBase =3D MicrocodeRegionOffset; >+ >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER >*)MicrocodeFileBuffer; >+ if (FvHeader->Signature =3D=3D EFI_FVH_SIGNATURE) { >+ // Skip FV header + FFS header >+ MicrocodeBuffer =3D MicrocodeFileBuffer + >sizeof(EFI_FIRMWARE_VOLUME_HEADER) + >sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER); >+ } else { >+ MicrocodeBuffer =3D MicrocodeFileBuffer; >+ } >+ while ((UINT32)(MicrocodeBuffer - MicrocodeFileBuffer) < >MicrocodeFileSize) { >+ if (*(UINT32 *)(MicrocodeBuffer) !=3D 0x1) { // HeaderVers= ion >+ break; >+ } >+ if (*(UINT32 *)(MicrocodeBuffer + 20) !=3D 0x1) { // Loade= rVersion >+ break; >+ } >+ if (*(UINT32 *)(MicrocodeBuffer + 28) =3D=3D 0) { // DataS= ize >+ MicrocodeSize =3D 2048; >+ } else { >+ // >+ // MCU might be put at 2KB alignment, if so, we need to = adjust the >size as 2KB alignment. >+ // >+ if (gFitTableContext.MicrocodeAlignment) { >+ MicrocodeSize =3D (*(UINT32 *)(MicrocodeBuffer + 32) + >MICROCODE_ALIGNMENT) & ~MICROCODE_ALIGNMENT; >+ } else { >+ MicrocodeSize =3D (*(UINT32 *)(MicrocodeBuffer + 32)); >+ } >+ } >+ >+ // >+ // Add Microcode >+ // >+ if (gFitTableContext.MicrocodeNumber >=3D MAX_MICROCODE_EN= TRY) >{ >+ printf ("-I Parameter incorrect, Too many Microcode!\n")= ; >+ return 0; >+ } >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type =3D >FIT_TABLE_TYPE_MICROCODE; >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =3D >MicrocodeBase + ((UINT32) (UINTN) MicrocodeBuffer - (UINT32) (UINTN) >MicrocodeFileBuffer); >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size =3D >MicrocodeSize; >+ gFitTableContext.MicrocodeNumber++; >+ gFitTableContext.FitEntryNumber++; >+ >+ MicrocodeBuffer +=3D 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 !=3D 0) { >+ if (gFitTableContext.OptionalModuleNumber >=3D >MAX_OPTIONAL_ENTRY) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Optio= nal >Module!", NULL); >+ return 0; >+ } >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Type =3D BiosInfoStruct[BiosInfoIndex].Type; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Address =3D (UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Size =3D (UINT32)BiosInfoStruct[BiosInfoIndex].Size; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Version =3D BiosInfoStruct[BiosInfoIndex].Version; >+ gFitTableContext.OptionalModuleNumber++; >+ gFitTableContext.FitEntryNumber++; >+ } else { >+ if (gFitTableContext.PortModuleNumber >=3D MAX_PORT_ENTRY) { >+ Error (NULL, 0, 0, "-I Parameter incorrect, Too many Port = Module!", >NULL); >+ return 0; >+ } >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type >=3D BiosInfoStruct[BiosInfoIndex].Type; >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres >s =3D (UINT32)BiosInfoStruct[BiosInfoIndex].Address; >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size = =3D >(UINT32)(BiosInfoStruct[BiosInfoIndex].Address >> 32); >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version >=3D BiosInfoStruct[BiosInfoIndex].Version; >+ gFitTableContext.PortModuleNumber++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ break; >+ } >+ } >+ >+ } else { >+ Error (NULL, 0, 0, "-I Parameter incorrect, expect GUID!", NULL); >+ return 0; >+ } >+ Index +=3D 2; >+ } >+ >+ // >+ // 1. StartupAcm >+ // >+ do { >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-S") !=3D 0) && >+ (strcmp (argv[Index], "-s") !=3D 0)) ) { >+ if (BiosInfoExist && (gFitTableContext.StartupAcm.Type =3D=3D >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 =3D FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &Fil= eSize); >+ if (FileBuffer =3D=3D NULL) { >+ Error (NULL, 0, 0, "-S Parameter incorrect, GUID not found!", "%= s", >argv[Index + 1]); >+ // not found >+ return 0; >+ } >+ FileBuffer =3D (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdS= ize); >+ Index +=3D 2; >+ } else { >+ if (Index + 2 >=3D argc) { >+ Error (NULL, 0, 0, "-S Parameter incorrect, expect Address Size!= ", NULL); >+ return 0; >+ } >+ FileBuffer =3D (UINT8 *) (UINTN) xtoi (argv[Index + 1]); >+ FileSize =3D xtoi (argv[Index + 2]); >+ Index +=3D 3; >+ } >+ if (gFitTableContext.StartupAcm.Type !=3D 0) { >+ Error (NULL, 0, 0, "-S Parameter incorrect, Duplicated StartupAcm!= ", NULL); >+ return 0; >+ } >+ gFitTableContext.StartupAcm.Type =3D FIT_TABLE_TYPE_STARTUP_ACM; >+ gFitTableContext.StartupAcm.Address =3D (UINT32) (UINTN) FileBuffer; >+ gFitTableContext.StartupAcm.Size =3D FileSize; >+ gFitTableContext.FitEntryNumber ++; >+ >+ // >+ // 1.1 StartupAcm version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ gFitTableContext.StartupAcmVersion =3D gFitTableContext.GlobalVers= ion; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.StartupAcmVersion =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ } while (FALSE); >+ >+ // >+ // 2. BiosModule >+ // >+ do { >+ if ((Index + 2 >=3D argc) || >+ ((strcmp (argv[Index], "-B") !=3D 0) && >+ (strcmp (argv[Index], "-b") !=3D 0)) ) { >+ if (BiosInfoExist && (gFitTableContext.BiosModuleNumber !=3D 0)) { >+ break; >+ } >+// Error (NULL, 0, 0, "-B Parameter incorrect, expect -B!", NULL); >+// return 0; >+ printf ("-B not found. WARNING!\n"); >+ break; >+ } >+ >+ FileBuffer =3D (UINT8 *) (UINTN) xtoi (argv[Index + 1]); >+ FileSize =3D xtoi (argv[Index + 2]); >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type =3D >FIT_TABLE_TYPE_BIOS_MODULE; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres >s =3D (UINT32) (UINTN) FileBuffer; >+ gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size >=3D FileSize; >+ gFitTableContext.BiosModuleNumber ++; >+ gFitTableContext.FitEntryNumber ++; >+ >+ while (TRUE) { >+ Index +=3D 3; >+ if (Index + 2 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index], "-B") !=3D 0) && >+ (strcmp (argv[Index], "-b") !=3D 0) ) { >+ break; >+ } >+ if (gFitTableContext.BiosModuleNumber >=3D MAX_BIOS_MODULE_ENTRY) >{ >+ Error (NULL, 0, 0, "-B Parameter incorrect, Too many Bios Module= !", >NULL); >+ return 0; >+ } >+ FileBuffer =3D (UINT8 *) (UINTN) xtoi (argv[Index + 1]); >+ FileSize =3D xtoi (argv[Index + 2]); >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Type =3D >FIT_TABLE_TYPE_BIOS_MODULE; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres >s =3D (UINT32) (UINTN) FileBuffer; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size =3D >FileSize; >+ gFitTableContext.BiosModuleNumber ++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ >+ // >+ // 2.1 BiosModule version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ gFitTableContext.BiosModuleVersion =3D gFitTableContext.GlobalVers= ion; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.BiosModuleVersion =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ } while (FALSE); >+ >+ // >+ // 3. Microcode >+ // >+ while (TRUE) { >+ if (Index + 1 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index], "-M") !=3D 0) && >+ (strcmp (argv[Index], "-m") !=3D 0) ) { >+ break; >+ } >+ if (IsGuidData (argv[Index + 2], &Guid)) { >+ Error (NULL, 0, 0, "-M Parameter incorrect, GUID unsupported!", NU= LL); >+ return 0; >+ } else { >+ if (Index + 2 >=3D argc) { >+ break; >+ } >+ FileBuffer =3D (UINT8 *) (UINTN) xtoi (argv[Index + 1]); >+ FileSize =3D xtoi (argv[Index + 2]); >+ Index +=3D 3; >+ } >+ if (gFitTableContext.MicrocodeNumber >=3D MAX_MICROCODE_ENTRY) { >+ Error (NULL, 0, 0, "-M Parameter incorrect, Too many Microcode!", = NULL); >+ return 0; >+ } >+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type = =3D >FIT_TABLE_TYPE_MICROCODE; >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =3D >(UINT32) (UINTN) FileBuffer; >+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size = =3D >FileSize; >+ gFitTableContext.MicrocodeNumber++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ >+ // >+ // 3.1 MicrocodeFv >+ // >+ while (TRUE) { >+ if (Index + 1 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index], "-U") !=3D 0) && >+ (strcmp (argv[Index], "-u") !=3D 0) ) { >+ break; >+ } >+ // >+ // Get Fv >+ // >+ if (IsGuidData (argv[Index + 1], &Guid)) { >+ MicrocodeFileBuffer =3D FindFileFromFvByGuid (FdBuffer, FdSize, &G= uid, >&MicrocodeFileSize); >+ if (MicrocodeFileBuffer =3D=3D NULL) { >+ Error (NULL, 0, 0, "-U Parameter incorrect, GUID not found!", "%= s", >argv[Index + 1]); >+ // not found >+ return 0; >+ } >+ Index +=3D 2; >+ >+ MicrocodeBuffer =3D MicrocodeFileBuffer; >+ MicrocodeFileBufferRaw =3D NULL; >+ MicrocodeRegionOffset =3D MEMORY_TO_FLASH (MicrocodeFileBuffer, >FdBuffer, FdSize); >+ MicrocodeRegionSize =3D 0; >+ MicrocodeBase =3D MicrocodeRegionOffset; >+ >+ } else { >+ if (Index + 2 >=3D argc) { >+ break; >+ } >+ Status =3D ReadInputFile (argv[Index + 1], &MicrocodeFileBuffer, >&MicrocodeFileSize, &MicrocodeFileBufferRaw); >+ if (Status !=3D STATUS_SUCCESS) { >+ MicrocodeRegionOffset =3D xtoi (argv[Index + 1]); >+ MicrocodeRegionSize =3D xtoi (argv[Index + 2]); >+ >+ if (MicrocodeRegionOffset =3D=3D 0) { >+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionOff= set is 0, >or unable to open file", "%s", argv[Index + 1]); >+ return 0; >+ } >+ if (MicrocodeRegionSize =3D=3D 0) { >+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionSiz= e is 0", >NULL); >+ return 0; >+ } >+ if (MicrocodeRegionSize > FdSize) { >+ Error (NULL, 0, 0, "-U Parameter incorrect, MicrocodeRegionSiz= e too >large", NULL); >+ return 0; >+ } >+ >+ Index +=3D 3; >+ >+ MicrocodeFileBufferRaw =3D NULL; >+ MicrocodeFileBuffer =3D FLASH_TO_MEMORY (MicrocodeRegionOffset, >FdBuffer, FdSize); >+ MicrocodeFileSize =3D MicrocodeRegionSize; >+ MicrocodeBase =3D MicrocodeRegionOffset; >+ >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)MicrocodeFileBuffer; >+ if (FvHeader->Signature =3D=3D EFI_FVH_SIGNATURE) { >+ // Skip FV header + FFS header >+ MicrocodeBuffer =3D MicrocodeFileBuffer + >sizeof(EFI_FIRMWARE_VOLUME_HEADER) + >sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER); >+ } else { >+ MicrocodeBuffer =3D MicrocodeFileBuffer; >+ } >+ } else { >+ MicrocodeBase =3D xtoi (argv[Index + 2]); >+ Index +=3D 3; >+ MicrocodeRegionOffset =3D 0; >+ MicrocodeRegionSize =3D 0; >+ >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)MicrocodeFileBuffer; >+ if (FvHeader->Signature =3D=3D EFI_FVH_SIGNATURE) { >+ // Skip FV header + FFS header >+ MicrocodeBuffer =3D MicrocodeFileBuffer + >sizeof(EFI_FIRMWARE_VOLUME_HEADER) + >sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(EFI_FFS_FILE_HEADER); >+ } else { >+ MicrocodeBuffer =3D MicrocodeFileBuffer; >+ } >+ } >+ } >+ while ((UINT32)(MicrocodeBuffer - MicrocodeFileBuffer) < >MicrocodeFileSize) { >+ if (*(UINT32 *)(MicrocodeBuffer) !=3D 0x1) { // HeaderVersion >+ break; >+ } >+ if (*(UINT32 *)(MicrocodeBuffer + 20) !=3D 0x1) { // LoaderVersion >+ break; >+ } >+ if (*(UINT32 *)(MicrocodeBuffer + 28) =3D=3D 0) { // DataSize >+ MicrocodeSize =3D 2048; >+ } else { >+ // >+ // MCU might be put at 2KB alignment, if so, we need to adjust t= he size >as 2KB alignment. >+ // >+ if (gFitTableContext.MicrocodeAlignment) { >+ MicrocodeSize =3D (*(UINT32 *)(MicrocodeBuffer + 32) + >MICROCODE_ALIGNMENT) & ~MICROCODE_ALIGNMENT; >+ } else { >+ MicrocodeSize =3D (*(UINT32 *)(MicrocodeBuffer + 32)); >+ } >+ } >+ >+ // >+ // Add Microcode >+ // >+ if (gFitTableContext.MicrocodeNumber >=3D MAX_MICROCODE_ENTRY) { >+ printf ("-U Parameter incorrect, Too many Microcode!\n"); >+ return 0; >+ } >+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Type >=3D FIT_TABLE_TYPE_MICROCODE; >+ >gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Address =3D >MicrocodeBase + ((UINT32) (UINTN) MicrocodeBuffer - (UINT32) (UINTN) >MicrocodeFileBuffer); >+ gFitTableContext.Microcode[gFitTableContext.MicrocodeNumber].Size = = =3D >MicrocodeSize; >+ gFitTableContext.MicrocodeNumber++; >+ gFitTableContext.FitEntryNumber++; >+ >+ MicrocodeBuffer +=3D MicrocodeSize; >+ } >+ >+ if (MicrocodeFileBufferRaw !=3D NULL) { >+ free ((VOID *)MicrocodeFileBufferRaw); >+ MicrocodeFileBufferRaw =3D NULL; >+ } >+ } >+ >+ // >+ // 3.3 Microcode version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ gFitTableContext.MicrocodeVersion =3D gFitTableContext.GlobalVersion= ; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.MicrocodeVersion =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ // >+ // 4. Optional type >+ // >+ while (TRUE) { >+ if (Index + 2 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index], "-O") !=3D 0) && >+ (strcmp (argv[Index], "-o") !=3D 0) ) { >+ break; >+ } >+ Type =3D xtoi (argv[Index + 1]); >+ // >+ // 1st, try GUID >+ // >+ if (IsGuidData (argv[Index + 2], &Guid)) { >+ FileBuffer =3D FindFileFromFvByGuid (FdBuffer, FdSize, &Guid, &Fil= eSize); >+ if (FileBuffer =3D=3D NULL) { >+ Error (NULL, 0, 0, "-O Parameter incorrect, GUID not found!", "%= s", >argv[Index + 2]); >+ // not found >+ return 0; >+ } >+ if (FileSize >=3D 0x80000000) { >+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too large!"= , NULL); >+ return 0; >+ } >+ FileBuffer =3D (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdS= ize); >+ Index +=3D 3; >+ } else { >+ // >+ // 2nd, try file >+ // >+ Status =3D ReadInputFile (argv[Index + 2], &FileBuffer, &FileSize,= NULL); >+ if (Status =3D=3D STATUS_SUCCESS) { >+ if (FileSize >=3D 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 |=3D 0x80000000; >+ Index +=3D 3; >+ } else { >+ // >+ // 3rd, try >+ // >+ if (Index + 3 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index + 2], "RESERVE") =3D=3D 0) || >+ (strcmp (argv[Index + 2], "reserve") =3D=3D 0)) { >+ FileSize =3D xtoi (argv[Index + 3]); >+ if (FileSize >=3D 0x80000000) { >+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too lar= ge!", NULL); >+ return 0; >+ } >+ FileBuffer =3D malloc (FileSize); >+ if (FileBuffer =3D=3D 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 |=3D 0x80000000; >+ Index +=3D 4; >+ } else { >+ // >+ // 4th, try >+ // >+ if (Index + 3 >=3D argc) { >+ break; >+ } >+ FileBuffer =3D (UINT8 *) (UINTN) xtoi (argv[Index + 2]); >+ FileSize =3D xtoi (argv[Index + 3]); >+ if (FileSize >=3D 0x80000000) { >+ Error (NULL, 0, 0, "-O Parameter incorrect, FileSize too lar= ge!", NULL); >+ return 0; >+ } >+ Index +=3D 4; >+ } >+ } >+ } >+ if (gFitTableContext.OptionalModuleNumber >=3D MAX_OPTIONAL_ENTRY) >{ >+ Error (NULL, 0, 0, "-O Parameter incorrect, Too many Optional Modu= le!", >NULL); >+ free (FileBuffer); >+ return 0; >+ } >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Type =3D Type; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Address =3D (UINT32) (UINTN) FileBuffer; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Size =3D FileSize; >+ >+ // >+ // 4.1 Optional Module version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Version =3D gFitTableContext.GlobalVersion; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Version =3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ gFitTableContext.OptionalModuleNumber ++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ >+ // >+ // 5. Port type >+ // >+ while (TRUE) { >+ if (Index + 6 >=3D argc) { >+ break; >+ } >+ if ((strcmp (argv[Index], "-P") !=3D 0) && >+ (strcmp (argv[Index], "-p") !=3D 0) ) { >+ break; >+ } >+ >+ Type =3D xtoi (argv[Index + 1]); >+ if (gFitTableContext.PortModuleNumber >=3D MAX_PORT_ENTRY) { >+ printf ("-P Parameter incorrect, Too many Port Module!\n"); >+ return 0; >+ } >+ >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type =3D >Type; >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres >s =3D (UINT16)xtoi (argv[Index + 2]) + ((UINT16)xtoi (argv[Index + 3]) <<= 16); >+ gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size >=3D (UINT8)xtoi (argv[Index + 4]) + ((UINT8)xtoi (argv[Index + 5]) << 8) = + >((UINT16)xtoi (argv[Index + 6]) << 16); >+ Index +=3D 7; >+ >+ // >+ // 5.1 Port Module version >+ // >+ if ((Index + 1 >=3D argc) || >+ ((strcmp (argv[Index], "-V") !=3D 0) && >+ (strcmp (argv[Index], "-v") !=3D 0)) ) { >+ // >+ // Bypass >+ // >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version >=3D 0; >+ } else { >+ // >+ // Get offset from parameter >+ // >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version >=3D xtoi (argv[Index + 1]); >+ Index +=3D 2; >+ } >+ >+ gFitTableContext.PortModuleNumber++; >+ gFitTableContext.FitEntryNumber++; >+ } >+ >+ // >+ // Final: Check StartupAcm in BiosModule. >+ // >+ CheckOverlap (gFitTableContext.StartupAcm.Address, >gFitTableContext.StartupAcm.Size); >+ FitEntryNumber =3D gFitTableContext.FitEntryNumber; >+ for (Index =3D 0; Index < (INTN)gFitTableContext.OptionalModuleNumber; >Index++) { >+ if ((gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_POLICY) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_KEY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_DATA_AREA) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >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 vecto= r. >+ 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 =3D (UINT8 *)((UINTN)Address & ~0xFFF); >+ if ((UINTN)ApVector <=3D (UINTN)FvBuffer) { >+ return NULL; >+ } >+ >+ NewAddress =3D (UINT8 *)(ApVector - Size); >+ for (Index =3D 0; Index < Size; Index ++) { >+ if (NewAddress[Index] !=3D 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 =3D 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) !=3D 0xFFFFFFFFFFFFFFFFull) && >+ (*(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset) !=3D 0) && >+ (*(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset) !=3D 0xEEEEEEEEEEEEEEEEull)) { >+ Error (NULL, 0, 0, "4G - FitTablePointerOffset is occupied!", NULL); >+ return NULL; >+ } >+ if (gFitTableContext.FitTablePointerOffset2 !=3D 0) { >+ if ((*(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset2) !=3D 0xFFFFFFFFFFFFFFFFull) && >+ (*(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset2) !=3D 0) && >+ (*(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset2) !=3D 0xEEEEEEEEEEEEEEEEull)) { >+ Error (NULL, 0, 0, "4G - FitTablePointerOffset is occupied!", NULL= ); >+ return NULL; >+ } >+ } >+ >+ // >+ // Get EFI_FFS_VOLUME_TOP_FILE_GUID location >+ // >+ FitTableOffset =3D NULL; >+ >+ FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)FvBuffer; >+ FvLength =3D FvHeader->FvLength; >+ FileHeader =3D (EFI_FFS_FILE_HEADER *)(FvBuffer + FvHeader- >>HeaderLength); >+ Offset =3D (UINTN)FileHeader - (UINTN)FvBuffer; >+ >+ while (Offset < FvLength) { >+ FileLength =3D (*(UINT32 *)(FileHeader->Size)) & 0x00FFFFFF; >+ FileOccupiedSize =3D GETOCCUPIEDSIZE(FileLength, 8); >+ if ((CompareGuid (&(FileHeader->Name), &VTFGuid)) =3D=3D 0) { >+ // find it >+ FitTableOffset =3D (UINT8 *)FileHeader; >+ break; >+ } >+ FileHeader =3D (EFI_FFS_FILE_HEADER *)((UINTN)FileHeader + >FileOccupiedSize); >+ Offset =3D (UINTN)FileHeader - (UINTN)FvBuffer; >+ } >+ >+ if (FitTableOffset =3D=3D NULL) { >+ Error (NULL, 0, 0, "EFI_FFS_VOLUME_TOP_FILE_GUID not found!", NULL); >+ return NULL; >+ } >+ >+ FitTableSize =3D FitEntryNumber * >sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY); >+ FitTableSize +=3D FIT_ALIGNMENT; >+ FitTableSize &=3D ~FIT_ALIGNMENT; >+ >+ FitTableOffset =3D (UINT8 *)((UINTN)FitTableOffset & ~FIT_ALIGNMENT); >+ FitTableOffset =3D (UINT8 *)(FitTableOffset - FitTableSize); >+ >+ // >+ // Check it >+ // >+ for (Index =3D 0; Index < (INTN)(FitTableSize); Index ++) { >+ if (FitTableOffset[Index] !=3D 0xFF) { >+ // >+ // No enough space - it might happen that it is occupied by AP wak= e >vector. >+ // Last chance - skip this and search again. >+ // >+ FitTableOffset =3D FindSpaceSkipApVector (FvBuffer, >&FitTableOffset[Index], FitTableSize); >+ if (FitTableOffset =3D=3D NULL) { >+ Error (NULL, 0, 0, "No enough space for FIT table!", NULL); >+ return NULL; >+ } >+ } >+ } >+ >+ // >+ // Check space for Optional module >+ // >+ OptionalModuleAddress =3D FitTableOffset; >+ for (Index =3D 0; Index < (INTN)gFitTableContext.OptionalModuleNumber; >Index++) { >+ AlignedSize =3D gFitTableContext.OptionalModule[Index].Size; >+ if ((gFitTableContext.OptionalModule[Index].Size & 0x80000000) !=3D = 0) { >+ >+ // >+ // Need copy binary to file. >+ // >+ gFitTableContext.OptionalModule[Index].Size &=3D ~0x80000000; >+ >+ AlignedSize =3D gFitTableContext.OptionalModule[Index].Size; >+ if ((gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_POLICY) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_KEY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_DATA_AREA) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_CSE_SECURE_BOOT)) { >+ // Let it 64 byte align >+ AlignedSize +=3D BIOS_MODULE_ALIGNMENT; >+ AlignedSize &=3D ~BIOS_MODULE_ALIGNMENT; >+ } >+ >+ OptionalModuleAddress -=3D AlignedSize; >+ >+ if ((gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_POLICY) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_KEY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_DATA_AREA) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_CSE_SECURE_BOOT)) { >+ // Let it 64 byte align >+ OptionalModuleAddress =3D (UINT8 *)((UINTN)OptionalModuleAddress= & >~BIOS_MODULE_ALIGNMENT); >+ } >+ >+ for (SubIndex =3D 0; SubIndex < (INTN)(AlignedSize); SubIndex ++) = { >+ if (OptionalModuleAddress[SubIndex] !=3D 0xFF) { >+ // >+ // No enough space - it might happen that it is occupied by AP= wake >vector. >+ // Last chance - skip this and search again. >+ // >+ OptionalModuleAddress =3D FindSpaceSkipApVector (FvBuffer, >&OptionalModuleAddress[SubIndex], AlignedSize); >+ if (OptionalModuleAddress =3D=3D NULL) { >+ Error (NULL, 0, 0, "No enough space for OptionalModule!", NU= LL); >+ 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 =3D MEMORY_TO_FLASH >(OptionalModuleAddress, FvBuffer, FvSize); >+ } >+ // >+ // Final: Check BiosPolicyData in BiosModule. >+ // >+ if ((gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_POLICY) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_KEY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >FIT_TABLE_TYPE_BIOS_DATA_AREA) || >+ (gFitTableContext.OptionalModule[Index].Type =3D=3D >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 !=3D 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.FitHeaderVersi= on); >+ if (gFitTableContext.StartupAcm.Address !=3D 0) { >+ printf ("StartupAcm - (0x%08x, 0x%08x, 0x%04x)\n", >gFitTableContext.StartupAcm.Address, gFitTableContext.StartupAcm.Size, >gFitTableContext.StartupAcmVersion); >+ } >+ for (Index =3D 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 =3D 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 =3D 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 =3D 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[] =3D { >+ " ", >+ "MICROCODE ", >+ "STARTUP_ACM", >+ " ", >+ " ", >+ " ", >+ " ", >+ "BIOS_MODULE", >+ "TPM_POLICY ", >+ "BIOS_POLICY", >+ "TXT_POLICY ", >+ "KEYMANIFEST", >+ "BP_MANIFEST", >+ "BIOS_DATA_A", >+ " ", >+ " ", >+ "CSE_SECUREB" >+}; >+ >+CHAR8 mFitSignature[] =3D "'_FIT_ ' "; >+CHAR8 mFitSignatureInHeader[] =3D "' ' "; >+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 =3D=3D 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 =3D *(UINT32 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset); >+ printf ("FIT Table Address: 0x%x\n", FitTableOffset); >+ FitEntry =3D (FIRMWARE_INTERFACE_TABLE_ENTRY >*)FLASH_TO_MEMORY(FitTableOffset, FvBuffer, FvSize); >+ >+ // >+ // Check FitEntry is 16 byte aligned >+ // >+ if (((UINTN)FitEntry & 0xF) !=3D 0) { >+ printf("ERROR: invalid FitEntry address 0x%X!\n", (UINT32) (UINTN) >FitEntry); >+ return; >+ } >+ >+ EntryNum =3D *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; >+ printf ("=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D >=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D (=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D = =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D)\n"); >+ printf ("Index: Address Size Version Type C_V C= hecksum (Index >Data Width Bit Offset)\n"); >+ printf ("=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D >=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D (=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D = =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D)\n"); >+ for (Index =3D 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 =3D=3D 0) { >+ if (FitEntry[Index].Type !=3D FIT_TABLE_TYPE_HEADER) { >+ printf("ERROR: FIT Entry 0 is not Header Type %d!\n", >FIT_TABLE_TYPE_HEADER); >+ return; >+ } >+ if (strcmp(mFitSignatureInHeader, mFitSignature) !=3D 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 =3D=3D 0) { >+ FitEntryPort =3D (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 ("=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D >=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D (=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D = =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D)\n"); >+ printf ("Index: Address Size Version Type C_V C= hecksum (Index >Data Width Bit Offset)\n"); >+ printf ("=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= = =3D=3D =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D >=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D (=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D = =3D=3D=3D=3D=3D=3D =3D=3D=3D=3D =3D=3D=3D=3D=3D=3D)\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 =3D 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 =3D Size / COLUME_SIZE; >+ Left =3D Size % COLUME_SIZE; >+ for (Index =3D 0; Index < Count; Index++) { >+ printf ("%04x: ", Index * COLUME_SIZE); >+ DumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); >+ printf ("\n"); >+ } >+ >+ if (Left !=3D 0) { >+ printf ("%04x: ", Index * COLUME_SIZE); >+ DumpData (Data + Index * COLUME_SIZE, Left); >+ printf ("\n"); >+ } >+} >+ >+// >+// This table defines the ACM type string >+// >+CHAR8 *mAcmTypeStr[] =3D { >+ "BIOS ACM", >+ "SINIT ACM", >+}; >+ >+// >+// This table defines the ACM capability string >+// >+CHAR8 *mCapabilityStr[] =3D { >+ "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 =3D=3D 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) !=3D 0) { >+ printf (" Capable of be Executed at Reset\n"); >+ } >+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) !=3D 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 =3D (UINT8 *)(Acm + 1); >+ printf (" RSAPubKey - \n"); >+ DumpHex (Buffer, Acm->KeySize * 4); >+ printf ("\n"); >+ Buffer +=3D Acm->KeySize * 4; >+ >+ if (Acm->HeaderVersion =3D=3D 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 +=3D ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; >+ } else { >+ printf (" RSAPubExp - %08x\n", *(UINT32 *)Buffer); >+ Buffer +=3D 4; >+ >+ printf (" RSASig - \n"); >+ DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE); // >PKCS #1.5 RSA Signature >+ printf ("\n"); >+ Buffer +=3D ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE; >+ } >+ Buffer +=3D Acm->ScratchSize * 4; >+ >+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) =3D=3D >0) { >+ ChipsetAcmInformationTable =3D (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", ChipsetAcmInformati= onTable- >>ChipsetACMType); >+ if (ChipsetAcmInformationTable->ChipsetACMType < >sizeof(mAcmTypeStr)/sizeof(mAcmTypeStr[0])) { >+ printf (" %s\n", mAcmTypeStr[ChipsetAcmInformationTable- >>ChipsetACMType]); >+ } >+ printf (" Version - %02x\n", ChipsetAcmInformati= onTable- >>Version); >+ printf (" Length - %04x\n", ChipsetAcmInformati= onTable- >>Length); >+ printf (" ChipsetIDList - %08x\n", ChipsetAcmInformati= onTable- >>ChipsetIDList); >+ printf (" OsSinitTableVer - %08x\n", ChipsetAcmInformati= onTable- >>OsSinitTableVer); >+ printf (" MinMleHeaderVer - %08x\n", ChipsetAcmInformati= onTable- >>MinMleHeaderVer); >+ if (ChipsetAcmInformationTable->Version >=3D >CHIPSET_ACM_INFORMATION_TABLE_VERSION_3) { >+ printf (" Capabilities - %08x\n", ChipsetAcmInforma= tionTable- >>Capabilities); >+ for (Index =3D 0; Index < sizeof(mCapabilityStr)/sizeof(mCapabilit= yStr[0]); >Index++) { >+ if (mCapabilityStr[Index] =3D=3D NULL) { >+ continue; >+ } >+ printf ( >+ " %s- %08x\n", >+ mCapabilityStr[Index], >+ (ChipsetAcmInformationTable->Capabilities & (1 << Index)) >+ ); >+ } >+ printf (" AcmVersion - %02x\n", ChipsetAcmInforma= tionTable- >>AcmVersion); >+ printf (" AcmRevision - %02x.%02x.%02x\n", >ChipsetAcmInformationTable->AcmRevision[0], >ChipsetAcmInformationTable->AcmRevision[1], >ChipsetAcmInformationTable->AcmRevision[2]); >+ } >+ if (ChipsetAcmInformationTable->Version >=3D >CHIPSET_ACM_INFORMATION_TABLE_VERSION_4) { >+ printf (" ProcessorIDList - %08x\n", ChipsetAcmInforma= tionTable- >>ProcessorIDList); >+ } >+ >+ ChipsetIdList =3D (CHIPSET_ID_LIST *)((UINTN)Acm + >ChipsetAcmInformationTable->ChipsetIDList); >+ printf ("Chipset ID List info:\n"); >+ printf (" Count - %08x\n", ChipsetIdList->Coun= t); >+ for (Index =3D 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 =3D (PROCESSOR_ID_LIST *)((UINTN)Acm + >ChipsetAcmInformationTable->ProcessorIDList); >+ printf ("Processor ID List info:\n"); >+ printf (" Count - %08x\n", ProcessorIdList->Co= unt); >+ for (Index =3D 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 !=3D 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 =3D (UINT8 *)(Acm + 1); >+ Buffer +=3D Acm->KeySize * 4; >+ if (Acm->HeaderVersion =3D=3D ACM_HEADER_VERSION_3) { >+ Buffer +=3D ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; >+ } else { >+ Buffer +=3D 4; >+ Buffer +=3D ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE; >+ } >+ Buffer +=3D Acm->ScratchSize * 4; >+ >+ if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) =3D=3D >0) { >+ ChipsetAcmInformationTable =3D (CHIPSET_ACM_INFORMATION_TABLE >*)Buffer; >+ if ((UINTN)ChipsetAcmInformationTable >=3D (UINTN)Acm + AcmMaxSize) = { >+ printf ("ACM invalid : ChipsetAcmInformationTable!\n"); >+ return FALSE; >+ } >+ >+ if (CompareGuid ((EFI_GUID *)&ChipsetAcmInformationTable->Guid, >(EFI_GUID *)&mChipsetAcmInformationTableGuid03) !=3D 0) { >+ printf ("ACM invalid : ChipsetACMGuid!\n"); >+ return FALSE; >+ } >+ if (ChipsetAcmInformationTable->ChipsetACMType !=3D >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 >=3D AcmMaxSize) { >+ printf ("ACM invalid : ChipsetACMChipsetIDList!\n"); >+ return FALSE; >+ } >+ ChipsetIdList =3D (CHIPSET_ID_LIST *)((UINTN)Acm + >ChipsetAcmInformationTable->ChipsetIDList); >+ if (ChipsetIdList->Count =3D=3D 0) { >+ printf ("ACM invalid : ChipsetACMChipsetIDListCount!\n"); >+ return FALSE; >+ } >+ if (ChipsetAcmInformationTable->ChipsetIDList + sizeof(CHIPSET_ID_LI= ST) >+ (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 >=3D AcmMaxSize) { >+ printf ("ACM invalid : ChipsetACMProcessorIDList!\n"); >+ return FALSE; >+ } >+ ProcessorIdList =3D (PROCESSOR_ID_LIST *)((UINTN)Acm + >ChipsetAcmInformationTable->ProcessorIDList); >+ if (ProcessorIdList->Count =3D=3D 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= ) =3D >(UINT64)(UINTN)MEMORY_TO_FLASH (FitTableOffset, FvBuffer, FvSize); >+ if (gFitTableContext.FitTablePointerOffset2 !=3D 0) { >+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffs= et2) >=3D (UINT64)(UINTN)MEMORY_TO_FLASH (FitTableOffset, FvBuffer, FvSize); >+ } >+ >+ FitEntry =3D (FIRMWARE_INTERFACE_TABLE_ENTRY *)FitTableOffset; >+ FitIndex =3D 0; >+ >+ // >+ // 2. FitHeader >+ // >+ FitEntry[FitIndex].Address =3D *(UINT64 *)"_FIT_ "; >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D gFitTableContext.FitEntryNu= mber; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.FitHeaderVersion; >+ FitEntry[FitIndex].Type =3D FIT_TABLE_TYPE_HEADER; >+ FitEntry[FitIndex].C_V =3D 1; >+ // >+ // Checksum will be updated later... >+ // >+ FitEntry[FitIndex].Checksum =3D 0; >+ >+ // >+ // 3. Microcode >+ // >+ FitIndex++; >+ for (Index =3D 0; Index < gFitTableContext.MicrocodeNumber; Index++) { >+ FitEntry[FitIndex].Address =3D >gFitTableContext.Microcode[Index].Address; >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D 0; >//gFitTableContext.Microcode[Index].Size / 16; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.MicrocodeVersion; >+ FitEntry[FitIndex].Type =3D FIT_TABLE_TYPE_MICROCODE; >+ FitEntry[FitIndex].C_V =3D 0; >+ FitEntry[FitIndex].Checksum =3D 0; >+ FitIndex++; >+ } >+ >+ // >+ // 4. StartupAcm >+ // >+ if (gFitTableContext.StartupAcm.Address !=3D 0) { >+ FitEntry[FitIndex].Address =3D gFitTableContext.StartupA= cm.Address; >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D 0; >//gFitTableContext.StartupAcm.Size / 16; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.StartupAcmVersion; >+ FitEntry[FitIndex].Type =3D FIT_TABLE_TYPE_STARTUP_AC= M; >+ FitEntry[FitIndex].C_V =3D 0; >+ FitEntry[FitIndex].Checksum =3D 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 =3D 0; Index < (UINTN)gFitTableContext.BiosModuleNumber -= 1; >Index++){ >+ for (SubIndex =3D 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 =3D 0; Index < gFitTableContext.BiosModuleNumber; Index++) = { >+ FitEntry[FitIndex].Address =3D >gFitTableContext.BiosModule[Index].Address; >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D >gFitTableContext.BiosModule[Index].Size / 16; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.BiosModuleVersion; >+ FitEntry[FitIndex].Type =3D FIT_TABLE_TYPE_BIOS_MODUL= E; >+ FitEntry[FitIndex].C_V =3D 0; >+ FitEntry[FitIndex].Checksum =3D 0; >+ FitIndex++; >+ } >+ >+ // >+ // 6. Optional module >+ // >+ for (Index =3D 0; Index < gFitTableContext.OptionalModuleNumber; Index= ++) >{ >+ FitEntry[FitIndex].Address =3D >gFitTableContext.OptionalModule[Index].Address; >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D >gFitTableContext.OptionalModule[Index].Size; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.OptionalModule[Index].Version; >+ FitEntry[FitIndex].Type =3D >(UINT8)gFitTableContext.OptionalModule[Index].Type; >+ FitEntry[FitIndex].C_V =3D 0; >+ FitEntry[FitIndex].Checksum =3D 0; >+ FitIndex++; >+ } >+ >+ // >+ // 7. Port module >+ // >+ for (Index =3D 0; Index < gFitTableContext.PortModuleNumber; Index++) = { >+ FitEntry[FitIndex].Address =3D >gFitTableContext.PortModule[Index].Address + >((UINT64)gFitTableContext.PortModule[Index].Size << 32); >+ *(UINT32 *)&FitEntry[FitIndex].Size[0] =3D 0; >+ FitEntry[FitIndex].Version =3D >(UINT16)gFitTableContext.PortModule[Index].Version; >+ FitEntry[FitIndex].Type =3D >(UINT8)gFitTableContext.PortModule[Index].Type; >+ FitEntry[FitIndex].C_V =3D 0; >+ FitEntry[FitIndex].Checksum =3D 0; >+ FitIndex++; >+ } >+ >+ // >+ // The FIT records must always be arranged in the ascending order of t= heir >type attribute in the FIT. >+ // >+ for (Index =3D 0; Index < (UINTN)FitIndex - 1; Index++){ >+ for (SubIndex =3D 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 =3D CalculateChecksum8 ((UINT8 *)&FitEntry[0], sizeof >(FIRMWARE_INTERFACE_TABLE_ENTRY) * FitIndex); >+ FitEntry[0].Checksum =3D 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 =3D *(UINT64 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset); >+ FitEntry =3D (FIRMWARE_INTERFACE_TABLE_ENTRY *)FLASH_TO_MEMORY >(FitTablePointer, FvBuffer, FvSize); >+ >+ // >+ // Clear FIT pointer >+ // >+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffset= ) =3D >0xEEEEEEEEEEEEEEEEull; >+ if (gFitTableContext.FitTablePointerOffset2 !=3D 0) { >+ *(UINT64 *)(FvBuffer + FvSize - gFitTableContext.FitTablePointerOffs= et2) >=3D 0xEEEEEEEEEEEEEEEEull; >+ } >+ >+ // >+ // Clear FIT table >+ // >+ EntryNum =3D *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; >+ for (FitIndex =3D 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 =3D FLASH_TO_MEMORY (FitEntry[FitIndex].Address, FvBuffer, >FvSize); >+ BufferSize =3D (*(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 =3D fopen (FileName, "w+b")) =3D=3D 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)) !=3D 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 =3D NULL; >+ UINT32 FvRecoveryFileSize =3D0; >+ EFI_GUID VTFGuid =3D EFI_FFS_VOLUME_TOP_FILE_GUID= ; >+ UINT32 FvLength; >+ UINT32 FileLength; >+ >+ *FvRecovery =3D NULL; >+ FileBuffer =3D FindNextFvHeader (FdBuffer, FdFileSize); >+ if (FileBuffer =3D=3D NULL) { >+ return 0; >+ } >+ >+ while ((UINTN)FileBuffer < (UINTN)FdBuffer + FdFileSize) { >+ FvLength =3D (UINT32)((EFI_FIRMWARE_VOLUME_HEADER >*)FileBuffer)->FvLength; >+ >+ if (FindFileFromFvByGuid (FileBuffer, FvLength, &VTFGuid, &FileLengt= h) !=3D >NULL) { >+ // >+ // Found the VTF >+ // >+ FvRecoveryFileSize =3D FvLength; >+ *FvRecovery =3D FileBuffer; >+ } >+ >+ // >+ // Next fv >+ // >+ FileBuffer =3D (UINT8 *)FileBuffer + FvLength; >+ if ((UINTN)FileBuffer >=3D (UINTN)FdBuffer + FdFileSize) { >+ break; >+ } >+ FileBuffer =3D FindNextFvHeader (FileBuffer, (UINTN)FdBuffer + FdFil= eSize - >(UINTN)FileBuffer); >+ if (FileBuffer =3D=3D 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 =3D=3D 0) { >+ gFitTableContext.FitTablePointerOffset =3D >DEFAULT_FIT_TABLE_POINTER_OFFSET; >+ } >+ gFitTableContext.FitTablePointerOffset2 =3D 0; >+ >+ FitTableOffset =3D *(UINT32 *)(FvBuffer + FvSize - >gFitTableContext.FitTablePointerOffset); >+ >+ FitEntry =3D (FIRMWARE_INTERFACE_TABLE_ENTRY >*)FLASH_TO_MEMORY(FitTableOffset, FvBuffer, FvSize); >+ FitIndex =3D 0; >+ >+ // >+ // 2. FitHeader >+ // >+ if (FitEntry[FitIndex].Address !=3D *(UINT64 *)"_FIT_ ") { >+ return 0; >+ } >+ if (FitEntry[FitIndex].Type !=3D FIT_TABLE_TYPE_HEADER) { >+ return 0; >+ } >+ gFitTableContext.FitEntryNumber =3D *(UINT32 *)&FitEntry[FitIndex].Siz= e[0]; >+ gFitTableContext.FitHeaderVersion =3D 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 =3D >(UINT32)FitEntry[FitIndex].Address; >+ gFitTableContext.MicrocodeVersion = =3D >FitEntry[FitIndex].Version; >+ gFitTableContext.MicrocodeNumber ++; >+ break; >+ case FIT_TABLE_TYPE_STARTUP_ACM: >+ gFitTableContext.StartupAcm.Address =3D >(UINT32)FitEntry[FitIndex].Address; >+ gFitTableContext.StartupAcmVersion =3D FitEntry[FitIndex].Version= ; >+ break; >+ case FIT_TABLE_TYPE_BIOS_MODULE: >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Addres >s =3D (UINT32)FitEntry[FitIndex].Address; >+ >gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size = =3D >*(UINT32 *)&FitEntry[FitIndex].Size[0] * 16; >+ gFitTableContext.BiosModuleVersion = =3D >FitEntry[FitIndex].Version; >+ gFitTableContext.BiosModuleNumber ++; >+ break; >+ case FIT_TABLE_TYPE_TPM_POLICY: >+ case FIT_TABLE_TYPE_TXT_POLICY: >+ if (FitEntry[FitIndex].Version =3D=3D 0) { >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Addres >s =3D (UINT32)FitEntry[FitIndex].Address; >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Size = =3D >(UINT32)(FitEntry[FitIndex].Address >> 32); >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version >=3D FitEntry[FitIndex].Version; >+ >gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Type >=3D FitEntry[FitIndex].Type; >+ gFitTableContext.PortModuleNumber ++; >+ break; >+ } >+ // Not Port Configure, pass through >+ default: // Others >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Address =3D (UINT32)FitEntry[FitIndex].Address; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Size =3D *(UINT32 *)&FitEntry[FitIndex].Size[0]; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Version =3D FitEntry[FitIndex].Version; >+ >gFitTableContext.OptionalModule[gFitTableContext.OptionalModuleNumber >].Type =3D 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") =3D=3D 0) || >+ (strcmp (argv[1], "-d") =3D=3D 0)) ) { >+ IsFv =3D FALSE; >+ } else { >+ IsFv =3D TRUE; >+ } >+ >+ // >+ // Step 1: Read InputFvRecovery.fv data >+ // >+ if (IsFv) { >+ Status =3D ReadInputFile (argv[1], &FileBuffer, &FvRecoveryFileSize, >&FileBufferRaw); >+ if (Status !=3D STATUS_SUCCESS) { >+ Error (NULL, 0, 0, "Unable to open file", "%s", argv[1]); >+ goto exitFunc; >+ } >+ FdFileBuffer =3D FileBuffer; >+ FdFileSize =3D FvRecoveryFileSize; >+ } else { >+ Status =3D ReadInputFile (argv[2], &FdFileBuffer, &FdFileSize, >&FileBufferRaw); >+ if (Status !=3D STATUS_SUCCESS) { >+ Error (NULL, 0, 0, "Unable to open file", "%s", argv[2]); >+ goto exitFunc; >+ } >+ >+ // >+ // Get Fvrecovery information >+ // >+ FvRecoveryFileSize =3D GetFvRecoveryInfoFromFd (FdFileBuffer, FdFile= Size, >&FileBuffer); >+ if ((FvRecoveryFileSize =3D=3D 0) || (FileBuffer =3D=3D NULL)) { >+ Error (NULL, 0, 0, "FvRecovery not found in Fd file!", NULL); >+ Status =3D STATUS_ERROR; >+ goto exitFunc; >+ } >+ } >+ >+ // >+ // Step 2: Calculate FIT entry number. >+ // >+ FitEntryNumber =3D GetFitEntryNumber (argc, argv, FdFileBuffer, FdFile= Size); >+ if (!gFitTableContext.Clear) { >+ if (FitEntryNumber =3D=3D 0) { >+ Status =3D 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 =3D GetFreeSpaceFromFv (FileBuffer, FvRecoveryFileSiz= e, >FitEntryNumber); >+ if (FitTableOffset =3D=3D NULL) { >+ return STATUS_ERROR; >+ } >+ FitTableSize =3D FitEntryNumber * >sizeof(FIRMWARE_INTERFACE_TABLE_ENTRY); >+ FitTableSize +=3D FIT_ALIGNMENT; >+ FitTableSize &=3D ~FIT_ALIGNMENT; >+ >+ CheckOverlap ( >+ MEMORY_TO_FLASH (FitTableOffset, FdFileBuffer, FdFileSize), >+ FitTableSize >+ ); >+ >+ // >+ // Get ACM buffer >+ // >+ if (gFitTableContext.StartupAcm.Address !=3D 0) { >+ AcmBuffer =3D 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 =3D NULL; >+ } >+ >+ if (AcmBuffer !=3D NULL) { >+ if (CheckAcm ((ACM_FORMAT *)AcmBuffer, >gFitTableContext.StartupAcm.Size)) { >+ DumpAcm ((ACM_FORMAT *)AcmBuffer); >+ } else { >+ Status =3D 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 =3D GetFitEntryInfo (FdFileBuffer, FdFileSize); >+ if (FitEntryNumber =3D=3D 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 =3D WriteOutputFile (argv[2], FileBuffer, FvRecoveryFileSize)= ; >+ } else { >+ Status =3D WriteOutputFile (argv[3], FdFileBuffer, FdFileSize); >+ } >+ >+exitFunc: >+ if (FileBufferRaw !=3D 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 =3D NULL; >+ STATUS Status; >+ >+ // >+ // Step 1: Read input file >+ // >+ Status =3D ReadInputFile (argv[2], &FileBuffer, &FvRecoveryFileSize, >&FileBufferRaw); >+ if (Status !=3D 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 =3D=3D 3) { >+ // >+ // Use default address >+ // >+ gFitTableContext.FitTablePointerOffset =3D >DEFAULT_FIT_TABLE_POINTER_OFFSET; >+ } else if (stricmp (argv[3], "-f") =3D=3D 0) { >+ if (argc =3D=3D 5) { >+ // >+ // Get offset from parameter >+ // >+ gFitTableContext.FitTablePointerOffset =3D 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 !=3D 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 >=3D MIN_VIEW_ARGS && stricmp (argv[1], "-view") =3D=3D 0) { >+ return FitView (argc, argv); >+ } else if (argc >=3D MIN_ARGS) { >+ return FitGen (argc, argv); >+ } else { >+ Error (NULL, 0, 0, "invalid number of input parameters specified", N= ULL); >+ 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 =3D=3D NULL) { >+ return 0; >+ } >+ >+ m =3D (unsigned int) -1 >> 4; >+ // >+ // skip preceeding white space >+ // >+ while (*str && *str =3D=3D ' ') { >+ str +=3D 1; >+ } >+ // >+ // skip preceeding zeros >+ // >+ while (*str && *str =3D=3D '0') { >+ str +=3D 1; >+ } >+ // >+ // skip preceeding x/X character >+ // >+ if (*str && (*str =3D=3D 'x' || *str =3D=3D 'X')) { >+ str +=3D 1; >+ } >+ // >+ // convert hex digits >+ // >+ u =3D 0; >+ c =3D *(str++); >+ while (c) { >+ if (c >=3D 'a' && c <=3D 'f') { >+ c -=3D 'a' - 'A'; >+ } >+ >+ if ((c >=3D '0' && c <=3D '9') || (c >=3D 'A' && c <=3D 'F')) { >+ if (u > m) { >+ return (unsigned int) -1; >+ } >+ >+ u =3D (u << 4) | (c - (c >=3D 'A' ? 'A' - 10 : '0')); >+ } else { >+ // >+ // Let application exit immediately >+ // >+ Error (NULL, 0, 0, "Hex value is expected!", NULL); >+ exit (0); >+ break; >+ } >+ >+ c =3D *(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.
>+SPDX-License-Identifier: BSD-2-Clause-Patent >+ >+**/ >+ >+#ifndef _FIT_GEN_H >+#define _FIT_GEN_H >+ >+#include >+#include >+#define PI_SPECIFICATION_VERSION 0x00010000 >+#define EFI_FVH_PI_REVISION EFI_FVH_REVISION >+#include >+#include >+#include >+#include >+#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.
>+# SPDX-License-Identifier: BSD-2-Clause-Patent >+# >+MAKEROOT ?=3D $(EDK_TOOLS_PATH)/Source/C >+ >+APPNAME =3D FitGen >+ >+OBJECTS =3D FitGen.o >+ >+include $(MAKEROOT)/Makefiles/app.makefile >+ >+LIBS =3D -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.
>+# SPDX-License-Identifier: BSD-2-Clause-Patent >+# >+ >+!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.common >+ >+APPNAME =3D FitGen >+ >+LIBS =3D $(LIB_PATH)\Common.lib >+ >+OBJECTS =3D FitGen.obj >+ >+!INCLUDE $(EDK_TOOLS_PATH)\Source\C\Makefiles\ms.app >+ >-- >2.18.0.windows.1 > > >