Reviewed-by: Bob Feng <bob.c.f...@intel.com> -----Original Message----- From: Kumar, Rahul R <rahul.r.ku...@intel.com> Sent: Wednesday, November 16, 2022 9:58 AM To: devel@edk2.groups.io; Feng, Bob C <bob.c.f...@intel.com>; Gao, Liming <gaolim...@byosoft.com.cn>; Chen, Christine <yuwei.c...@intel.com>; Oram, Isaac W <isaac.w.o...@intel.com>; Chaganty, Rangasai V <rangasai.v.chaga...@intel.com>; West, Catharine <catharine.w...@intel.com> Cc: Kumar, Rahul R <rahul.r.ku...@intel.com> Subject: [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4155 With new implementation, FITGEN will populate info needed for the PROT assisted BootGuard solution and TXT on servers using FIT 4 Entry. FitGen based on the CPU FMS FITGEN will decide to call one of the two Type 2 FIT entry. Signed-off-by: Rahul R Kumar <rahul.r.ku...@intel.com> --- Silicon/Intel/Tools/FitGen/FitGen.c | 1186 ++++++++++++++++----------- Silicon/Intel/Tools/FitGen/FitGen.h | 7 +- 2 files changed, 722 insertions(+), 471 deletions(-) diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c b/Silicon/Intel/Tools/FitGen/FitGen.c index 87123f9922..4ba07945a6 100644 --- a/Silicon/Intel/Tools/FitGen/FitGen.c +++ b/Silicon/Intel/Tools/FitGen/FitGen.c @@ -44,11 +44,18 @@ typedef struct { #define BIOS_MODULE_ALIGNMENT 0x3F // 64 bytes for AnC #define MICROCODE_ALIGNMENT 0x7FF +#define MICROCODE_EXTERNAL_HEADER_SIZE 0x30 + #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_HEADER_VERSION_0 (0) +#define ACM_XMSS_PUBLIC_KEY_SIZE 64 +#define ACM_XMSS_SIGNATURE_SIZE 2692 + +#define ACM_HEADER_VERSION_5 0x50004 +#define ACM_HEADER_VERSION_4 (4 << 16) +#define ACM_HEADER_VERSION_3 (3 << 16) +#define ACM_HEADER_VERSION_0 (0) #define ACM_MODULE_TYPE_CHIPSET_ACM 2 #define ACM_MODULE_SUBTYPE_CAPABLE_OF_EXECUTE_AT_RESET 0x1 #define ACM_MODULE_SUBTYPE_ANC_MODULE 0x2 @@ -56,6 +63,37 @@ typedef struct { #define ACM_MODULE_FLAG_DEBUG_SIGN 0x8000 #define NIBBLES_TO_BYTE(A, B) (UINT8)(((A & (0x0F)) << 4) | (B & 0x0F)) +// +//Flash Map 0 Register (Flash Descriptor Records) +// +typedef struct { + UINT32 Fcba : 8; //Bits[7:0]: Flash Component Base Address + UINT32 Nc : 2; //Bits[9:8]: Number of Components + UINT32 Rsvd0: 1; //Bit10: Reserved + UINT32 Rsvd1: 1; //Bit11: Reserved + UINT32 Rsvd2: 1; //Bit12: Reserved + UINT32 Rsvd3: 3; //Bits[15:13]: Reserved + UINT32 Frba : 8; //Bits[23:16]: Flash Region Base Address + UINT32 Rsvd4: 3; //Bits[26:24]: Reserved + UINT32 Rsvd5: 5; //Bits[31:27]: Reserved +} FLASH_MAP_0_REGISTER; + +// +//Flash Region 1 (BIOS) Register (Flash Descriptor Records) +// +typedef struct { + UINT32 RegionBase : 15; //Bits[14:0]: Region base + UINT32 Rsvd : 1; //Bit15: Reserved + UINT32 RegionLimit: 15; //Bits[30:16]: Region limit + UINT32 Rsvd1 : 1; //Bit31: Reserved +} FLASH_REGION_1_BIOS_REGISTER; + +#define FLASH_VALID_SIGNATURE 0x0FF0A55A //Flash Valid Signature (Flash Descriptor Records) +#define FLVALSIG_BASE_OFFSET 0x10 //Flash Valid Signature Base Offset +#define FLMAP0_BASE_OFFSET 0x14 //Flash Map 0 Register Base Offset + +#define ACMFV_GUID \ + { 0x8a4b197f, 0x1113, 0x43d0, { 0xa2, 0x3f, 0x26, 0xf3, 0x69, 0xb2, 0xb8, 0x41 }} typedef struct { UINT16 ModuleType; @@ -98,6 +136,8 @@ typedef struct { #define CHIPSET_ACM_TYPE_BIOS 0 #define CHIPSET_ACM_TYPE_SINIT 1 +#define DEFAULT_ACM_EXTENDED_MASK 0x00FFFFFF + typedef struct { UINT32 Guid0; UINT32 Guid1; @@ -238,6 +278,7 @@ typedef struct { #define FIT_TABLE_TYPE_MICROCODE 1 #define FIT_TABLE_TYPE_STARTUP_ACM 2 #define FIT_TABLE_TYPE_DIAGNST_ACM 3 +#define FIT_TABLE_TYPE_PROT_BOOT_POLICY 4 #define FIT_TABLE_TYPE_BIOS_MODULE 7 #define FIT_TABLE_TYPE_TPM_POLICY 8 #define FIT_TABLE_TYPE_BIOS_POLICY 9 @@ -252,7 +293,6 @@ typedef struct { #define FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST 27 #define FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST 28 - // // With OptionalModule Address isn't known until free space has been // identified and the optional module has been copied into the FLASH @@ -284,9 +324,10 @@ typedef struct { UINT32 GlobalVersion; UINT32 FitHeaderVersion; FIT_TABLE_CONTEXT_ENTRY StartupAcm[MAX_STARTUP_ACM_ENTRY]; - UINT32 StartupAcmVersion[MAX_STARTUP_ACM_ENTRY]; + UINT32 StartupAcmFvSize; FIT_TABLE_CONTEXT_ENTRY DiagnstAcm; UINT32 DiagnstAcmVersion; + FIT_TABLE_CONTEXT_ENTRY ProtBootPolicy; FIT_TABLE_CONTEXT_ENTRY BiosModule[MAX_BIOS_MODULE_ENTRY]; UINT32 BiosModuleVersion; FIT_TABLE_CONTEXT_ENTRY Microcode[MAX_MICROCODE_ENTRY]; @@ -305,25 +346,87 @@ xtoi ( char *str ); -VOID -PrintUtilityInfo ( - VOID - ) -/*++ +/** + Pass in supported CPU extended family/extended model/type + /family/model without stepping or CPU FMS >> 4. + + @param FitEntry Pointer to Fit Entry table. + @param AcmFamilyModel Acm Family Model stepping. + @param AcmMask ACM mask. + + @return STATUS_SUCCESS The file found and data read. +**/ +STATUS +SetFirmwareInterfaceTableEntryAcmFms( + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry, + UINT32 AcmFamilyModel, + UINT32 AcmMask +) +{ + if (FitEntry == NULL) { + return STATUS_ERROR; + } + + FitEntry->Checksum = (UINT8)(((AcmFamilyModel & 0x000F0000) >> 16) | (((AcmMask & 0x000F0000) >> 16) << 4)); + FitEntry->Rsvd = (UINT8)((AcmMask & 0x0000FF00) >> 8); + FitEntry->Size[2] = (UINT8)(AcmMask & 0x000000FF); + FitEntry->Size[1] = (UINT8)((AcmFamilyModel & 0x0000FF00) >> 8); + FitEntry->Size[0] = (UINT8)(AcmFamilyModel & 0x000000FF); + return STATUS_SUCCESS; +} + +/** + Set the FIT Entry Size. + + @param FitEntry Pointer to Fit Entry table. + @param SizeEntry Size of FIT entry. -Routine Description: + @return STATUS_SUCCESS The file found and data read. +**/ +STATUS +SetFirmwareInterfaceTableEntrySize ( + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry, + UINT32 SizeEntry +) +{ + if (FitEntry == NULL) { + return STATUS_ERROR; + } + FitEntry->Size[2] = (UINT8)((SizeEntry & 0x00FF0000) >> 16); + FitEntry->Size[1] = (UINT8)((SizeEntry & 0x0000FF00) >> 8); + FitEntry->Size[0] = (UINT8)(SizeEntry & 0x000000FF); + return STATUS_SUCCESS; +} - Displays the standard utility information to STDOUT +/** + Get the FIT Entry Size. -Arguments: + @param FitEntry Pointer to Fit Entry table. - None + @return FitEntry pointer +**/ +UINT32 +GetFirmwareInterfaceTableEntrySize ( + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry +) +{ + if (FitEntry == NULL) { + return 0; + } + return (((UINT32)FitEntry->Size[2] << 16) | ((UINT32)FitEntry->Size[1] << 8) | (UINT32)FitEntry->Size[0]); +} -Returns: +/** + Displays the FIT utility info - None + @param None ---*/ + @return None +**/ +VOID +PrintUtilityInfo ( + VOID + ) { printf ( "%s - Tiano IA32/X64 FIT table generation Utility for FIT spec revision %i.%i."" Version %i.%i\n\n", @@ -335,25 +438,17 @@ Returns: ); } +/** + Displays the utility usage syntax to STDOUT. + + @param None + + @return None +**/ VOID PrintUsage ( VOID ) -/*++ - -Routine Description: - - Displays the utility usage syntax to STDOUT - -Arguments: - - None - -Returns: - - None - ---*/ { printf ("Usage (generate): %s [-D] InputFvRecoveryFile OutputFvRecoveryFile\n" "\t[-V <FitEntryDefaultVersion>]\n" @@ -371,6 +466,7 @@ Returns: "\t[-M <MicrocodeAddress MicrocodeSize>] [-M ...]|[-U <MicrocodeFv MicrocodeBase>|<MicrocodeRegionOffset MicrocodeRegionSize>|<MicrocodeGuid>] [-V <MicrocodeVersion>]\n" "\t[-O RecordType <RecordDataAddress RecordDataSize>|<RESERVE RecordDataSize>|<RecordDataGuid>|<RecordBinFile>|<CseRecordSubType RecordBinFile> [-V <RecordVersion>]] [-O ... [-V ...]]\n" "\t[-P RecordType <IndexPort DataPort Width Bit Index> [-V <RecordVersion>]] [-P ... [-V ...]]\n" + "\t[-BP <BootPolicySize>[-V <BootPolicyVersion>]\n" "\t[-T <FixedFitLocation>]\n" , UTILITY_NAME); printf (" Where:\n"); @@ -407,12 +503,14 @@ Returns: printf ("\tRecordDataGuid - FIT entry record data GUID.\n"); printf ("\tRecordBinFile - FIT entry record data binary file.\n"); printf ("\tCseRecordSubType - FIT entry record subtype. Use to further distinguish CSE entries (see FIT spec revision 1.2 chapter 4.12).\n"); + printf ("\tBootPolicySize - FIT entry size for type 04 boot policy.\n"); printf ("\tFitEntryDefaultVersion - The default version for all FIT table entries. 0x%04x is used if this is not specified.\n", DEFAULT_FIT_ENTRY_VERSION); printf ("\tFitHeaderVersion - The version for FIT header. (Override default version)\n"); printf ("\tStartupAcmVersion - The version for StartupAcm. (Override default version)\n"); printf ("\tBiosModuleVersion - The version for BiosModule. (Override default version)\n"); printf ("\tMicrocodeVersion - The version for Microcode. (Override default version)\n"); printf ("\tRecordVersion - The version for Record. (Override default version)\n"); + printf ("\tBootPolicyVersion - The version for BootPolicy. (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"); @@ -427,11 +525,20 @@ Returns: printf ("\tSTATUS_SUCCESS=%d, STATUS_WARNING=%d, STATUS_ERROR=%d\n", STATUS_SUCCESS, STATUS_WARNING, STATUS_ERROR); } +/** + Set Value of memory. + + @param Buffer The pointer where we need to set the memory. + @param Length Size of memory to be set. + @param Value Value of memory to be set. + + @return Buffer The pointer address. +**/ VOID * SetMem ( - OUT VOID *Buffer, - IN UINTN Length, - IN UINT8 Value + OUT VOID *Buffer, + IN UINTN Length, + IN UINT8 Value ) { // @@ -448,6 +555,14 @@ SetMem ( return Buffer; } +/** + check the input Path. + + @param String Passed input path. + + @return TRUE If the input path is correct. + @return FLASE if the input path is not correct. +**/ BOOLEAN CheckPath ( IN CHAR8 * String @@ -476,28 +591,20 @@ CheckPath ( return TRUE; } +/** + Get fixed FIT location from argument. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings. + + @return FitLocation The FIT location specified by Argument. + @return 0 Argument parse fail. +**/ UINT32 GetFixedFitLocation ( IN INTN argc, IN CHAR8 **argv ) -/*++ - -Routine Description: - - Get fixed FIT location from argument - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to parameter strings. - -Returns: - - FitLocation - The FIT location specified by Argument - 0 - Argument parse fail - -*/ { UINT32 FitLocation; INTN Index; @@ -516,6 +623,18 @@ Returns: return FitLocation; } +/** + Read input file. + + @param FileName The input file name. + @param FileData The input file data, the memory is aligned. + @param FileSize The input file size. + @param FileBufferRaw The memory to hold input file data. The caller must free the memory. + + @return STATUS_SUCCESS The file found and data read. + @return STATUS_ERROR The file data is not read. + @return STATUS_WARNING The file is not found. +**/ STATUS ReadInputFile ( IN CHAR8 *FileName, @@ -523,26 +642,6 @@ ReadInputFile ( OUT UINT32 *FileSize, OUT UINT8 **FileBufferRaw OPTIONAL ) -/*++ - -Routine Description: - - Read input file - -Arguments: - - FileName - The input file name - FileData - The input file data, the memory is aligned. - FileSize - The input file size - FileBufferRaw - The memory to hold input file data. The caller must free the memory. - -Returns: - - STATUS_SUCCESS - The file found and data read - STATUS_ERROR - The file data is not read - STATUS_WARNING - The file is not found - ---*/ { FILE *FpIn; UINT32 TempResult; @@ -612,24 +711,20 @@ Returns: return STATUS_SUCCESS; } +/** + Find next FvHeader in the FileBuffer. + + @param FileBuffer The start FileBuffer which needs to be searched. + @param FileLength The whole File Length. + + @return FvHeader The FvHeader is found successfully. + @return NULL The FvHeader is not found. +**/ UINT8 * FindNextFvHeader ( IN UINT8 *FileBuffer, IN UINTN FileLength ) -/*++ - - Routine Description: - Find next FvHeader in the FileBuffer - - Parameters: - FileBuffer - The start FileBuffer which needs to be searched - FileLength - The whole File Length. - Return: - FvHeader - The FvHeader is found successfully. - NULL - The FvHeader is not found. - ---*/ { UINT8 *FileHeader; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; @@ -679,6 +774,17 @@ FindNextFvHeader ( return NULL; } +/** + Find File with GUID in an FV. + + @param FvBuffer FV binary buffer. + @param FvSize FV size. + @param Guid File GUID value to be searched. + @param FileSize Guid File size. + + @return FileLocation Guid File location. + @return NULL Guid File is not found. +**/ UINT8 * FindFileFromFvByGuid ( IN UINT8 *FvBuffer, @@ -686,25 +792,6 @@ FindFileFromFvByGuid ( 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; @@ -783,28 +870,20 @@ Returns: return NULL; } +/** + Check whether a string is a GUID. + + @param StringData The String. + @param Guid Guid to hold the value + + @return TRUE StringData is a GUID, and Guid field is filled. + @return FALSE StringData is not a GUID. +**/ BOOLEAN IsGuidData ( IN CHAR8 *StringData, OUT EFI_GUID *Guid ) -/*++ - -Routine Description: - - Check whether a string is a GUID - -Arguments: - - StringData - the String - Guid - Guid to hold the value - -Returns: - - TRUE - StringData is a GUID, and Guid field is filled. - FALSE - StringData is not a GUID - ---*/ { if (strlen (StringData) != strlen ("00000000-0000-0000-0000-000000000000")) { return FALSE; @@ -821,6 +900,17 @@ Returns: return TRUE; } +/** + Get FIT entry number and fill global FIT table context, from argument. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings. + @param FdBuffer FD binary buffer. + @param FdSize FD size. + + @return FitEntryNumber The FIT entry number. + @return 0 Argument parse fail. +**/ VOID CheckOverlap ( IN UINT32 Address, @@ -875,6 +965,17 @@ CheckOverlap ( } } +/** + Get FIT entry number and fill global FIT table context, from argument. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings. + @param FdBuffer FD binary buffer. + @param FdSize FD size. + + @return FitEntryNumber The FIT entry number. + @return 0 Argument parse fail. +**/ UINT8 * GetMicrocodeBufferFromFv ( EFI_FIRMWARE_VOLUME_HEADER *FvHeader @@ -906,6 +1007,17 @@ GetMicrocodeBufferFromFv ( return MicrocodeBuffer; } +/** + Get FIT entry number and fill global FIT table context, from argument. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings. + @param FdBuffer FD binary buffer. + @param FdSize FD size. + + @return FitEntryNumber The FIT entry number. + @return 0 Argument parse fail. +**/ UINT32 GetFitEntryNumber ( IN INTN argc, @@ -913,25 +1025,6 @@ GetFitEntryNumber ( 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; EFI_GUID MicrocodeFfsGuid; @@ -1188,7 +1281,7 @@ Returns: gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type = FIT_TABLE_TYPE_STARTUP_ACM; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = (UINT32)BiosInfoStruct[BiosInfoIndex].Address; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size = (UINT32)BiosInfoStruct[BiosInfoIndex].Size; - gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = BiosInfoStruct[BiosInfoIndex].Version; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = BiosInfoStruct[BiosInfoIndex].Version; gFitTableContext.StartupAcmNumber ++; gFitTableContext.FitEntryNumber ++; break; @@ -1203,6 +1296,13 @@ Returns: gFitTableContext.DiagnstAcmVersion = DEFAULT_FIT_ENTRY_VERSION; gFitTableContext.FitEntryNumber ++; break; + case FIT_TABLE_TYPE_PROT_BOOT_POLICY: + gFitTableContext.ProtBootPolicy.Type = FIT_TABLE_TYPE_PROT_BOOT_POLICY; + gFitTableContext.ProtBootPolicy.Address = (UINT32)BiosInfoStruct[BiosInfoIndex].Address; + gFitTableContext.ProtBootPolicy.Size = (UINT32)BiosInfoStruct[BiosInfoIndex].Size; + gFitTableContext.ProtBootPolicy.Version = DEFAULT_FIT_ENTRY_VERSION; + gFitTableContext.FitEntryNumber ++; + break; case FIT_TABLE_TYPE_BIOS_MODULE: if ((BiosInfoStruct[BiosInfoIndex].Attributes & BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB) != 0) { continue; @@ -1402,7 +1502,8 @@ Returns: // not found return 0; } - FileBuffer = (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdSize); + gFitTableContext.StartupAcmFvSize = FdSize; + FileBuffer = (UINT8 *)MEMORY_TO_FLASH(FileBuffer, FdBuffer, FdSize); Index += 2; } else { if (Index + 2 >= argc) { @@ -1431,7 +1532,7 @@ Returns: // // Bypass // - gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = gFitTableContext.GlobalVersion; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = gFitTableContext.GlobalVersion; } else { if (Index + 2 >= argc) { // @@ -1443,7 +1544,7 @@ Returns: // // With the -I parameter should assign the type 2 entry version as 0x200 format // - gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = STARTUP_ACM_FIT_ENTRY_200_VERSION; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = STARTUP_ACM_FIT_ENTRY_200_VERSION; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS = (UINT32)xtoi (argv[Index + 1]); gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask = (UINT32)xtoi (argv[Index + 2]); @@ -1464,7 +1565,8 @@ Returns: // // Get offset from parameter // - gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = xtoi (argv[Index + 1]); + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = gFitTableContext.GlobalVersion; + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = xtoi (argv[Index + 1]); Index += 2; } @@ -1942,7 +2044,7 @@ Returns: // // Get offset from parameter // - gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version = xtoi (argv[Index + 1]); + gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version = xtoi(argv[Index + 1]); Index += 2; } @@ -1950,6 +2052,69 @@ Returns: gFitTableContext.FitEntryNumber++; } + // + // 6th, try FIT boot policy data + // + if ((Index < argc) && + ((strcmp(argv[Index], "-BP") == 0) || + (strcmp(argv[Index], "-bp") == 0))) { + + if (Index + 1 >= argc) { + Error(NULL, 0, 0, "-BP: Invalid Parameters.", NULL); + FitEntryNumber = 0; + } + + gFitTableContext.StartupAcmFvSize = GetFvAcmSizeFromFd(FdBuffer, FdSize); + if (gFitTableContext.StartupAcmFvSize == 0) { + Error(NULL, 0, 0, "FV_ACM not found in Fd file!", NULL); + } + + // + // FIT type 04 record shares FV allocated space with FV_ACM. + // + FileSize = xtoi(argv[Index + 1]); + + if (gFitTableContext.StartupAcm[0].Size + FileSize > gFitTableContext.StartupAcmFvSize) { + Error(NULL, 0, 0, "Error: not enough FV_ACM room for FIT type 04 record!", NULL); + FitEntryNumber = 0; + } + + FileBuffer = malloc(FileSize); + if (FileBuffer == NULL) { + Error(NULL, 0, 0, "No sufficient memory to allocate!", NULL); + FitEntryNumber = 0; + } + + SetMem(FileBuffer, FileSize, 0xFF); + + gFitTableContext.ProtBootPolicy.Type = FIT_TABLE_TYPE_PROT_BOOT_POLICY; + gFitTableContext.ProtBootPolicy.Address = gFitTableContext.StartupAcm[0].Address + gFitTableContext.StartupAcm[0].Size; + gFitTableContext.ProtBootPolicy.Size = FileSize; + gFitTableContext.ProtBootPolicy.Version = 0; + + Index += 2; + + // + // 6.1 PROT Module version + // + if ((Index + 1 >= argc) || + ((strcmp (argv[Index], "-V") != 0) && + (strcmp (argv[Index], "-v") != 0)) ) { + // + // Bypass + // + gFitTableContext.ProtBootPolicy.Version = gFitTableContext.GlobalVersion; + } else { + // + // Get offset from parameter + // + gFitTableContext.ProtBootPolicy.Version = xtoi(argv[Index + 1]); + Index += 2; + } + + gFitTableContext.FitEntryNumber++; + } + // // Final: Check StartupAcm in BiosModule. // @@ -1974,31 +2139,23 @@ Returns: return FitEntryNumber; } +/** + No enough space - it might happen that it is occupied by AP wake vector. + Last chance - skip this and search again. + + @param FvBuffer FvRecovery binary buffer. + @param Address Address to be searched from. + @param Size Size need to be filled. + + @return FitTableOffset The FIT table offset. + @return NULL No enough space for FIT table. +**/ VOID * FindSpaceSkipApVector ( IN UINT8 *FvBuffer, IN UINT8 *Address, IN UINTN Size ) -/*++ - -Routine Description: - - No enough space - it might happen that it is occupied by AP wake vector. - Last chance - skip this and search again. - -Arguments: - - FvBuffer - FvRecovery binary buffer - Address - Address to be searched from - Size - Size need to be filled - -Returns: - - FitTableOffset - The FIT table offset - NULL - No enough space for FIT table - -*/ { UINT8 *ApVector; UINT8 *NewAddress; @@ -2018,6 +2175,17 @@ Returns: return NewAddress; } +/** + Get free space for FIT table from FvRecovery. + + @param FvBuffer FvRecovery binary buffer. + @param FvSize FvRecovery size. + @param FitTableSize The FIT table size. + @param FixedFitLocation Fixed FIT location provided by argument. + + @return FitTableOffset The offset of FIT table in FvRecovery file. + @return NULL Free space not found. +**/ VOID * GetFreeSpaceForFit ( IN UINT8 *FvBuffer, @@ -2025,25 +2193,6 @@ GetFreeSpaceForFit ( IN UINT32 FitTableSize, IN UINT32 FixedFitLocation ) -/*++ - -Routine Description: - - Get free space for FIT table from FvRecovery - -Arguments: - - FvBuffer - FvRecovery binary buffer - FvSize - FvRecovery size - FitTableSize - The FIT table size - FixedFitLocation - Fixed FIT location provided by argument - -Returns: - - FitTableOffset - The offset of FIT table in FvRecovery file - NULL - Free space not found - ---*/ { UINT8 *FitTableOffset; INTN Index; @@ -2167,7 +2316,7 @@ Returns: (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_PROVISION_TABLE) || (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) || (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) { - // Let it 64 byte align + // Let it 64 byte align AlignedSize += BIOS_MODULE_ALIGNMENT; AlignedSize &= ~BIOS_MODULE_ALIGNMENT; } @@ -2228,25 +2377,17 @@ Returns: return FitTableOffset; } +/** + Output FIT table information. + + @param None + + @return None +**/ VOID PrintFitData ( VOID ) -/*++ - -Routine Description: - - Output FIT table information - -Arguments: - - None - -Returns: - - None - ---*/ { UINT32 Index; @@ -2257,11 +2398,15 @@ Returns: printf ("Total FIT Entry number: 0x%x\n", gFitTableContext.FitEntryNumber); printf ("FitHeader version: 0x%04x\n", gFitTableContext.FitHeaderVersion); for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) { - printf ("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, gFitTableContext.StartupAcm[Index].Address, gFitTableContext.StartupAcm[Index].Size, gFitTableContext.StartupAcmVersion[Index]); + printf("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, gFitTableContext.StartupAcm[Index].Address, gFitTableContext.StartupAcm[Index].Size, gFitTableContext.StartupAcm[Index].Version); } if (gFitTableContext.DiagnstAcm.Address != 0) { printf ("DiagnosticAcm - (0x%08x, 0x%08x, 0x%04x)\n", gFitTableContext.DiagnstAcm.Address, gFitTableContext.DiagnstAcm.Size, gFitTableContext.DiagnstAcmVersion); } + + if (gFitTableContext.ProtBootPolicy.Address != 0) { + printf ("ProtBootPolicy - (0x%08x, 0x%08x, 0x%04x)\n", gFitTableContext.ProtBootPolicy.Address, gFitTableContext.ProtBootPolicy.Size, gFitTableContext.ProtBootPolicy.Version); + } for (Index = 0; Index < gFitTableContext.BiosModuleNumber; Index++) { printf ("BiosModule[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, gFitTableContext.BiosModule[Index].Address, gFitTableContext.BiosModule[Index].Size, gFitTableContext.BiosModuleVersion); } @@ -2304,8 +2449,7 @@ CHAR8 *mFitTypeStr[] = { "MICROCODE ", "STARTUP_ACM", "DIAGNST_ACM", - " ", - " ", + "BOOT_POLICY", " ", " ", "BIOS_MODULE", @@ -2320,27 +2464,19 @@ CHAR8 *mFitTypeStr[] = { "CSE_SECUREB" }; +/** + Convert FitEntry type to a string. + + @param FitEntry Fit entry + + @return String +**/ CHAR8 mFitSignature[] = "'_FIT_ ' "; CHAR8 mFitSignatureInHeader[] = "' ' "; CHAR8 * FitTypeToStr ( IN FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry ) -/*++ - -Routine Description: - - Convert FitEntry type to a string - -Arguments: - - FitEntry - Fit entry - -Returns: - - String - ---*/ { if (FitEntry->Type == FIT_TABLE_TYPE_HEADER) { CopyMem (&mFitSignatureInHeader[1], &FitEntry->Address, sizeof(FitEntry->Address)); @@ -2361,27 +2497,19 @@ Returns: } } +/** + Print Fit table in flash image. + + @param FvBuffer FvRecovery binary buffer. + @param FvSize FvRecovery size. + + @return None +**/ 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; @@ -2460,11 +2588,12 @@ Returns: } /** - This function dump raw data. - @param Data raw data - @param Size raw data size + @param Data Raw data. + @param Size Raw data size. + + @return none **/ VOID @@ -2480,12 +2609,12 @@ DumpData ( } /** - This function dump raw data with colume format. - @param Data raw data - @param Size raw data size + @param Data Raw data + @param Size Raw data size + @return none **/ VOID DumpHex ( @@ -2532,25 +2661,17 @@ CHAR8 *mCapabilityStr[] = { "STM support ", }; +/** + DumpAcm information + + @param Acm - ACM buffer + + @retval None +**/ 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; @@ -2600,23 +2721,21 @@ Returns: printf (" RSAPubKey - \n"); DumpHex (Buffer, Acm->KeySize * 4); printf ("\n"); - Buffer += Acm->KeySize * 4; - // - // To simplify the tool and making it independent of ACM header change, - // the rest of ACM parsing will be skipped starting ACM_HEADER_VERSION4 - // - if((Acm->HeaderVersion != ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != ACM_HEADER_VERSION_0)){ - printf ( - "*****************************************************************************\n\n" - ); - return; - } + Buffer += Acm->KeySize * 4; //add public key size (taken from header variable * 4) to buffer. + + //add signature size to pointer. if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) { printf (" RSASig - \n"); DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE); // PKCS #1.5 RSA Signature printf ("\n"); Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; - } else { + } + else if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == ACM_HEADER_VERSION_5)) { + Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; + Buffer += ACM_XMSS_PUBLIC_KEY_SIZE; + Buffer += ACM_XMSS_SIGNATURE_SIZE; + } + else { printf (" RSAPubExp - %08x\n", *(UINT32 *)Buffer); Buffer += 4; @@ -2627,6 +2746,10 @@ Returns: } Buffer += Acm->ScratchSize * 4; + if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == ACM_HEADER_VERSION_5)) { + Buffer += 60; //add reserved bytes. + } + if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) == 0) { ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE *)Buffer; printf ("Chipset ACM info:\n"); @@ -2697,28 +2820,77 @@ End: ); } -BOOLEAN -CheckAcm ( - IN ACM_FORMAT *Acm, - IN UINTN AcmMaxSize - ) -/*++ +/** + Get ACM FMS information. + + @param Acm ACM buffer. + @param AcmFms Get ACM FMS. + @param AcmMask Get ACM Mask. + + @retval NULL +**/ +VOID +GetAcmFms( + IN ACM_FORMAT *Acm, + OUT UINT32 *AcmFms, + OUT UINT32 *AcmMask +) +{ + UINT32 FmsOffset = 0; + UINT32 TmpFms = 0; + UINT32 TmpMask = 0; + UINT32 Index = 0; + PROCESSOR_ID_LIST *ProcessorIdList = NULL; + + if ((Acm == NULL) || (AcmFms == NULL) || (AcmMask == NULL)) + return; + + *AcmFms = 0; + *AcmMask = 0; + + switch (Acm->HeaderVersion) { + case ACM_HEADER_VERSION_3: + FmsOffset = *(UINT32*)((UINT8*)Acm + 0x6E8); //AcmInfoTable at 0x6C0, +0x28 for ProcessorIdList + break; + case ACM_HEADER_VERSION_4: + case ACM_HEADER_VERSION_5: + FmsOffset = *(UINT32*)((UINT8*)Acm + 0x1CA8); //AcmInfoTable at 0x1C80, +0x28 for ProcessorIdList + break; + default: + return; + } -Routine Description: + ProcessorIdList = (PROCESSOR_ID_LIST *)((UINT8*)Acm + FmsOffset); - Check Acm information + if (ProcessorIdList->Count > 0) { + TmpFms = ProcessorIdList->ProcessorID[0].FMS; + *AcmFms = TmpFms; + *AcmMask = DEFAULT_ACM_EXTENDED_MASK; + } -Arguments: + for (Index = 1; Index < ProcessorIdList->Count; Index++) { + TmpMask = (TmpFms ^ ProcessorIdList->ProcessorID[Index].FMS); + TmpFms &= ProcessorIdList->ProcessorID[Index].FMS; + } - Acm - ACM buffer - AcmMaxSize - ACM max size + *AcmMask = ~TmpMask; + return; +} -Returns: +/** + Check Acm information. - TRUE - ACM is valid - FALSE - ACM is invalid + @param Acm ACM buffer. + @param AcmMaxSize ACM max size. ---*/ + @retval TRUE ACM is valid. + @retval FALSE ACM is invalid. +**/ +BOOLEAN +CheckAcm ( + IN ACM_FORMAT *Acm, + IN UINTN AcmMaxSize + ) { CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable; CHIPSET_ID_LIST *ChipsetIdList; @@ -2734,24 +2906,27 @@ Returns: return FALSE; } - // - // To simplify the tool and making it independent of ACM header change, - // the following check will be skipped starting ACM_HEADER_VERSION3 - // - if((Acm->HeaderVersion != ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != ACM_HEADER_VERSION_0)){ - printf ("ACM header Version 4 or higher, bypassing other checks!\n"); - return TRUE; - } + //move buffer pointer to address past generic ACM header (post scratchsize) Buffer = (UINT8 *)(Acm + 1); Buffer += Acm->KeySize * 4; if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) { Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; - } else { + } + else if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == ACM_HEADER_VERSION_5)) { + Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE; + Buffer += ACM_XMSS_PUBLIC_KEY_SIZE; + Buffer += ACM_XMSS_SIGNATURE_SIZE; + } + else { Buffer += 4; Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE; } Buffer += Acm->ScratchSize * 4; + if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == ACM_HEADER_VERSION_5)) { + Buffer += 60; //add reserved bytes. + } + if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) == 0) { ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE *)Buffer; if ((UINTN)ChipsetAcmInformationTable >= (UINTN)Acm + AcmMaxSize) { @@ -2814,29 +2989,21 @@ End: return TRUE; } +/** + Fill the FIT table information to FvRecovery. + + @param FvBuffer FvRecovery binary buffer. + @param FvSize FvRecovery size. + @param FitTableOffset The offset of FIT table in FvRecovery file. + + @retval None +**/ 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; @@ -2899,15 +3066,18 @@ Returns: // 4. StartupAcm // for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) { - if (gFitTableContext.StartupAcmVersion[Index] == STARTUP_ACM_FIT_ENTRY_200_VERSION) { + if (gFitTableContext.StartupAcm[Index].Version == STARTUP_ACM_FIT_ENTRY_200_VERSION) { + printf("ACM version 0x200\n"); FMS.Uint32 = gFitTableContext.StartupAcm[Index].FMS; FMSMask.Uint32 = gFitTableContext.StartupAcm[Index].FMSMask; + printf("ACM FMS:%08x\n", FMS.Uint32); + printf("ACM FMSMask:%08x\n", FMSMask.Uint32); FitEntry[FitIndex].Address = gFitTableContext.StartupAcm[Index].Address; FitEntry[FitIndex].Size[0] = NIBBLES_TO_BYTE (FMS.Bits.Family, FMS.Bits.Model); FitEntry[FitIndex].Size[1] = NIBBLES_TO_BYTE (FMS.Bits.ExtendedModel, FMS.Bits.Type); FitEntry[FitIndex].Size[2] = NIBBLES_TO_BYTE (FMSMask.Bits.Family, FMSMask.Bits.Model); FitEntry[FitIndex].Rsvd = NIBBLES_TO_BYTE (FMSMask.Bits.ExtendedModel, FMSMask.Bits.Type); - FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcmVersion[Index]; + FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcm[Index].Version; FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM; FitEntry[FitIndex].C_V = 0; FitEntry[FitIndex].Checksum = NIBBLES_TO_BYTE (FMSMask.Bits.ExtendedFamily, FMS.Bits.ExtendedFamily); @@ -2918,7 +3088,7 @@ Returns: FitEntry[FitIndex].Size[1] = (UINT8)(FitEntrySizeValue >> 8); FitEntry[FitIndex].Size[2] = (UINT8)(FitEntrySizeValue >> 16); FitEntry[FitIndex].Rsvd = 0; - FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcmVersion[Index]; + FitEntry[FitIndex].Version = (UINT16)gFitTableContext.StartupAcm[Index].Version; FitEntry[FitIndex].Type = FIT_TABLE_TYPE_STARTUP_ACM; FitEntry[FitIndex].C_V = 0; FitEntry[FitIndex].Checksum = 0; @@ -2943,7 +3113,23 @@ Returns: FitIndex++; } // - // 5. BiosModule + // 5. (4) Bootable BootPolicy Data + // + if (gFitTableContext.ProtBootPolicy.Address != 0) { + FitEntry[FitIndex].Address = gFitTableContext.ProtBootPolicy.Address; + FitEntry[FitIndex].Size[0] = (UINT8) (gFitTableContext.ProtBootPolicy.Size); + FitEntry[FitIndex].Size[1] = (UINT8) (gFitTableContext.ProtBootPolicy.Size >> 8); + FitEntry[FitIndex].Size[2] = (UINT8) (gFitTableContext.ProtBootPolicy.Size >> 16); + FitEntry[FitIndex].Rsvd = 0; + FitEntry[FitIndex].Version = (UINT16)gFitTableContext.ProtBootPolicy.Version; + FitEntry[FitIndex].Type = FIT_TABLE_TYPE_PROT_BOOT_POLICY; + FitEntry[FitIndex].C_V = 0; + FitEntry[FitIndex].Checksum = 0; + FitIndex++; + } + + // + // 6. BiosModule // // // BiosModule segments order needs to be put from low address to high for Btg requirement @@ -2974,7 +3160,7 @@ Returns: } // - // 6. Optional module + // 7. Optional module // for (Index = 0; Index < gFitTableContext.OptionalModuleNumber; Index++) { FitEntrySizeValue = gFitTableContext.OptionalModule[Index].Size; @@ -2993,7 +3179,7 @@ Returns: } // - // 7. Port module + // 8. Port module // for (Index = 0; Index < gFitTableContext.PortModuleNumber; Index++) { FitEntrySizeValue = 0; @@ -3029,27 +3215,19 @@ Returns: FitEntry[0].Checksum = Checksum; } +/** + Clear the FIT table information to Fvrecovery. + + @param FvBuffer - Fvrecovery binary buffer. + @param FvSize - Fvrecovery size. + + @retval None +**/ 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; @@ -3097,30 +3275,22 @@ Returns: } } +/** + Read input file. + + @param FileName The input file name. + @param FileData The input file data. + @paramFileSize The input file size. + + @retval STATUS_SUCCESS Write file data successfully. + @retval STATUS_ERROR The file data is not written. +**/ 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; @@ -3157,28 +3327,78 @@ Returns: return STATUS_SUCCESS; } + UINT32 -GetFvRecoveryInfoFromFd ( +GetFvAcmSizeFromFd( IN UINT8 *FdBuffer, - IN UINT32 FdFileSize, - OUT UINT8 **FvRecovery - ) -/*++ + IN UINT32 FdFileSize +) +/** + Get FV_ACM Size information from Fd file. -Routine Description: + @param FdBuffer Fd file buffer. + @param FdFileSize Fd file size. - Get FvRecovery information from Fd file. + @retval FvACM size + +**/ +{ + UINT8 *FileBuffer = NULL; + UINT32 FvAcmSize = 0; + EFI_GUID ACMGuid = ACMFV_GUID; + UINT32 FvLength; + UINT32 FileLength; + + //*FvRecovery = NULL; + FileBuffer = FindNextFvHeader(FdBuffer, FdFileSize); + if (FileBuffer == NULL) { + return 0; + } -Arguments: + while ((UINTN)FileBuffer < (UINTN)FdBuffer + FdFileSize) { + FvLength = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer)->FvLength; - FdBuffer - Fd file buffer. - FdFileSize - Fd file size. - FvRecovery - FvRecovery pointer in Fd file buffer + if (FindFileFromFvByGuid(FileBuffer, FvLength, &ACMGuid, &FileLength) != NULL) { + // + // Found the ACM + // + FvAcmSize = FvLength; + } -Returns: - FvRecovery file size + // + // Next fv + // + FileBuffer = (UINT8 *)FileBuffer + FvLength; + if ((UINTN)FileBuffer >= (UINTN)FdBuffer + FdFileSize) { + break; + } + FileBuffer = FindNextFvHeader(FileBuffer, (UINTN)FdBuffer + FdFileSize - (UINTN)FileBuffer); + if (FileBuffer == NULL) { + break; + } ---*/ + } + + return FvAcmSize; +} + +/** + + Get FvRecovery information from Fd file. + + @param FdBuffer Fd file buffer. + @param FdFileSize Fd file size. + @param FvRecovery FvRecovery pointer in Fd file buffer + + @retval FvRecovery file size + +**/ +UINT32 +GetFvRecoveryInfoFromFd ( + IN UINT8 *FdBuffer, + IN UINT32 FdFileSize, + OUT UINT8 **FvRecovery + ) { UINT8 *FileBuffer = NULL; UINT32 FvRecoveryFileSize =0; @@ -3223,16 +3443,7 @@ Returns: return FvRecoveryFileSize; } -void -GetFMSFromFitEntry ( - IN FIRMWARE_INTERFACE_TABLE_ENTRY FitEntry, - IN OUT PROCESSOR_ID *FMS, - IN OUT PROCESSOR_ID *FMSMask - ) -/*++ - -Routine Description: - +/** Get FMS information from FIT Entry. Note: Since FIT entry not record all the processor ID information. @@ -3260,17 +3471,18 @@ Routine Description: | | Family | Model | ExtModel | Type | Family | Model | | +----------+-----------------------+-----------------------+-----------------------+-----------------------+ + @param FitEntry FIT entry information. + @param FMS Processor ID information. + @param FMSMask Processor ID mask information. -Arguments: - - FitEntry - FIT entry information. - FMS - Processor ID information. - FMSMask - Processor ID mask information. - -Returns: - None - ---*/ + @retval None +**/ +void +GetFMSFromFitEntry ( + IN FIRMWARE_INTERFACE_TABLE_ENTRY FitEntry, + IN OUT PROCESSOR_ID *FMS, + IN OUT PROCESSOR_ID *FMSMask + ) { FMS->Bits.Family = (FitEntry.Size[0] & 0xF0) >> 4; @@ -3286,27 +3498,19 @@ Returns: FMSMask->Bits.ExtendedFamily = (FitEntry.Checksum & 0xF0) >> 4; } +/** + Get the FIT table information from Fvrecovery. + + @param FvBuffer Fvrecovery binary buffer. + @param FvSize Fvrecovery size. + + @retval 0 - Fit Table not found +**/ UINT32 GetFitEntryInfo ( IN UINT8 *FvBuffer, IN UINT32 FvSize ) -/*++ - -Routine Description: - - Get the FIT table information from Fvrecovery - -Arguments: - - FvBuffer - Fvrecovery binary buffer - FvSize - Fvrecovery size - -Returns: - - 0 - Fit Table not found - ---*/ { FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; UINT32 FitEntrySizeValue; @@ -3360,14 +3564,20 @@ Returns: gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = (UINT32)FitEntry[FitIndex].Address; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size = FitEntrySizeValue; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type = FitEntry[FitIndex].Type; - gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = FitEntry[FitIndex].Version; - if (gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] == STARTUP_ACM_FIT_ENTRY_200_VERSION) { + gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = FitEntry[FitIndex].Version; + + if (gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version == STARTUP_ACM_FIT_ENTRY_200_VERSION) { GetFMSFromFitEntry (FitEntry[FitIndex], &FMS, &FMSMask); gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS = FMS.Uint32; gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask = FMSMask.Uint32; } gFitTableContext.StartupAcmNumber++; break; + case FIT_TABLE_TYPE_PROT_BOOT_POLICY: + gFitTableContext.ProtBootPolicy.Address = (UINT32)FitEntry[FitIndex].Address; + gFitTableContext.ProtBootPolicy.Version = FitEntry[FitIndex].Version; + gFitTableContext.ProtBootPolicy.Size = GetFirmwareInterfaceTableEntrySize (&FitEntry[FitIndex]); + break; case FIT_TABLE_TYPE_BIOS_MODULE: gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Address = (UINT32)FitEntry[FitIndex].Address; gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size = FitEntrySizeValue * 16; @@ -3398,27 +3608,20 @@ Returns: return gFitTableContext.FitEntryNumber; } +/** + Main function for FitGen. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings. + + @retval STATUS_SUCCESS Utility exits successfully. + @retval STATUS_ERROR Some error occurred during execution. +**/ 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; @@ -3433,7 +3636,7 @@ Returns: UINT32 FdFileSize; UINT8 *AcmBuffer; - INTN Index; + INTN Index = 0; UINT32 FixedFitLocation; FileBufferRaw = NULL; @@ -3514,6 +3717,7 @@ Returns: FitTableOffset = GetFreeSpaceForFit (FileBuffer, FvRecoveryFileSize, FitTableSize, FixedFitLocation); if (FitTableOffset == NULL) { + printf ("Error - FitTableOffset is NULL\n"); return STATUS_ERROR; } @@ -3526,7 +3730,10 @@ Returns: // Get ACM buffer // for (Index = 0; Index < (INTN)gFitTableContext.StartupAcmNumber; Index ++) { + printf("ACM address:%08x\n", gFitTableContext.StartupAcm[Index].Address); + printf("ACM size:%08x\n", gFitTableContext.StartupAcm[Index].Size); if (gFitTableContext.StartupAcm[Index].Address != 0) { + printf("get AcmBuffer\n"); AcmBuffer = FLASH_TO_MEMORY(gFitTableContext.StartupAcm[Index].Address, FdFileBuffer, FdFileSize); if ((AcmBuffer < FdFileBuffer) || (AcmBuffer + gFitTableContext.StartupAcm[Index].Size > FdFileBuffer + FdFileSize)) { printf ("ACM out of range - can not validate it\n"); @@ -3534,11 +3741,20 @@ Returns: } if (AcmBuffer != NULL) { - if (CheckAcm ((ACM_FORMAT *)AcmBuffer, gFitTableContext.StartupAcm[Index].Size)) { - DumpAcm ((ACM_FORMAT *)AcmBuffer); - } else { - Status = STATUS_ERROR; - goto exitFunc; + if (CheckAcm((ACM_FORMAT *)AcmBuffer, gFitTableContext.StartupAcm[Index].Size)) { + DumpAcm((ACM_FORMAT *)AcmBuffer); + + if (gFitTableContext.StartupAcm[Index].Version >= 0x200) { + GetAcmFms((ACM_FORMAT *)AcmBuffer, &gFitTableContext.StartupAcm[Index].FMS, &gFitTableContext.StartupAcm[Index].FMSMask); + printf("ACM FMS:%08x\n", gFitTableContext.StartupAcm[Index].FMS); + printf("ACM FMS Mask:%08x\n", gFitTableContext.StartupAcm[Index].FMSMask); + } + } + else { + if (Index == 0) { + Status = STATUS_ERROR; + goto exitFunc; + } } } } @@ -3592,32 +3808,31 @@ exitFunc: return Status; } +/** + View function for FitGen. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings + + @retval STATUS_SUCCESS Utility exits successfully. + @retval STATUS_ERROR Some error occurred during execution. +**/ STATUS FitView ( IN INTN argc, IN CHAR8 **argv ) -/*++ - -Routine Description: - - View function for FitGen. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ { - UINT32 FvRecoveryFileSize; - UINT8 *FileBuffer; - UINT8 *FileBufferRaw = NULL; - STATUS Status; + UINT32 FvRecoveryFileSize; + UINT8 *FileBuffer; + UINT8 *FileBufferRaw = NULL; + STATUS Status; + FILE *FpIn; + UINT32 FlashValidSig = 0; + UINT32 Frba; + UINT32 BiosRegionBaseOffset; + FLASH_MAP_0_REGISTER FlashMap0; + FLASH_REGION_1_BIOS_REGISTER FlashRegion1; // // Step 1: Read input file @@ -3642,13 +3857,57 @@ Returns: gFitTableContext.FitTablePointerOffset = xtoi (argv[3 + 1]); } else { Error (NULL, 0, 0, "FIT offset not specified!", NULL); + Status = STATUS_ERROR; goto exitFunc; } } else { Error (NULL, 0, 0, "Invalid view option: ", "%s", argv[3]); + Status = STATUS_ERROR; goto exitFunc; } + // + //Check the File Path + // + if (!CheckPath (argv[2])) { + Error (NULL, 0, 0, "File path is invalid!", NULL); + Status = STATUS_ERROR; + goto exitFunc; + } + // + // Open the Input file + // + if ((FpIn = fopen (argv[2], "rb")) == NULL) { + Error (NULL, 0, 0, "Unable open the file!", NULL); + Status = STATUS_WARNING; + goto exitFunc; + } + // + //Seek and read the Flash Valid Signature; + // + fseek (FpIn, FLVALSIG_BASE_OFFSET, SEEK_SET); + fread (&FlashValidSig, 4, 1, FpIn); + if (FlashValidSig == FLASH_VALID_SIGNATURE) { + // + //Seek and read the Flash Map 0 Register; + // + fseek (FpIn, FLMAP0_BASE_OFFSET, SEEK_SET); + fread (&FlashMap0, 4, 1, FpIn); + Frba = FlashMap0.Frba << 4 & 0xFF0; //FRBA identifies address bits [11:4] for the region portion of the flashdescriptor, bits [26:12] and bits [3:0] are 0 + // + //Seek and read the Flash Region 1 (BIOS) Register; + // + BiosRegionBaseOffset = Frba + 0x4; + fseek (FpIn, BiosRegionBaseOffset, SEEK_SET); + fread (&FlashRegion1, 4, 1, FpIn); + FileBuffer = (UINT8 *)(FileBuffer + (FlashRegion1.RegionBase << 12)); // RegionBase specifies address bits [26:12] for the Region Base. + FvRecoveryFileSize = ((FlashRegion1.RegionLimit << 12 | 0xFFF) + 1) - (FlashRegion1.RegionBase << 12); //RegionLimit specifies bits [26:12] of the ending address for this region, bits [11:0] are assumed to be FFFh. + } + // + // Close the Input file + // + fclose (FpIn); + // // For debug // @@ -3661,27 +3920,20 @@ exitFunc: return Status; } +/** + Main function. + + @param argc Number of command line parameters. + @param argv Array of pointers to parameter strings + + @retval STATUS_SUCCESS Utility exits successfully. + @retval STATUS_ERROR Some error occurred during execution. +**/ 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); @@ -3703,24 +3955,18 @@ Returns: return STATUS_ERROR; } } +/** + Convert hex string to uint + + @param str The string + @retval Integer value + +**/ unsigned int xtoi ( char *str ) -/*++ - -Routine Description: - - Convert hex string to uint - -Arguments: - - str - The string - -Returns: - ---*/ { unsigned int u; char c; diff --git a/Silicon/Intel/Tools/FitGen/FitGen.h b/Silicon/Intel/Tools/FitGen/FitGen.h index 511ab652ab..2d24ecb584 100644 --- a/Silicon/Intel/Tools/FitGen/FitGen.h +++ b/Silicon/Intel/Tools/FitGen/FitGen.h @@ -36,7 +36,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define FIT_SPEC_VERSION_MAJOR 1 #define FIT_SPEC_VERSION_MINOR 4 - // // The minimum number of arguments accepted from the command line. // @@ -50,4 +49,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define ROUNDUP(Size, Alignment) (((Size) + (Alignment) - 1) / (Alignment) * (Alignment)) +UINT32 +GetFvAcmSizeFromFd( +IN UINT8 *FdBuffer, +IN UINT32 FdFileSize +); + #endif -- 2.30.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#96525): https://edk2.groups.io/g/devel/message/96525 Mute This Topic: https://groups.io/mt/95067601/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-