public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc
@ 2022-11-16  1:58 Rahul R Kumar
  2022-11-21 23:10 ` Bob Feng
  0 siblings, 1 reply; 2+ messages in thread
From: Rahul R Kumar @ 2022-11-16  1:58 UTC (permalink / raw)
  To: devel, bob.c.feng, gaoliming, yuwei.chen, isaac.w.oram,
	rangasai.v.chaganty, catharine.west
  Cc: Rahul R Kumar

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.kumar@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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc
  2022-11-16  1:58 [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc Rahul R Kumar
@ 2022-11-21 23:10 ` Bob Feng
  0 siblings, 0 replies; 2+ messages in thread
From: Bob Feng @ 2022-11-21 23:10 UTC (permalink / raw)
  To: Kumar, Rahul R, devel@edk2.groups.io, Gao, Liming,
	Chen, Christine, Oram, Isaac W, Chaganty, Rangasai V,
	West, Catharine

Reviewed-by: Bob Feng <bob.c.feng@intel.com>

-----Original Message-----
From: Kumar, Rahul R <rahul.r.kumar@intel.com> 
Sent: Wednesday, November 16, 2022 9:58 AM
To: devel@edk2.groups.io; Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>; Oram, Isaac W <isaac.w.oram@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; West, Catharine <catharine.west@intel.com>
Cc: Kumar, Rahul R <rahul.r.kumar@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.kumar@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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-11-21 23:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-16  1:58 [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc Rahul R Kumar
2022-11-21 23:10 ` Bob Feng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox