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

-----Original Message-----
From: Kumar, Rahul R <rahul.r.ku...@intel.com> 
Sent: Wednesday, November 16, 2022 9:58 AM
To: devel@edk2.groups.io; Feng, Bob C <bob.c.f...@intel.com>; Gao, Liming 
<gaolim...@byosoft.com.cn>; Chen, Christine <yuwei.c...@intel.com>; Oram, Isaac 
W <isaac.w.o...@intel.com>; Chaganty, Rangasai V 
<rangasai.v.chaga...@intel.com>; West, Catharine <catharine.w...@intel.com>
Cc: Kumar, Rahul R <rahul.r.ku...@intel.com>
Subject: [PATCH] Silicon/Intel/FitGen:FitGen Supporting MultiFIT 2 rc

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4155

With new implementation, FITGEN will populate info needed
for the PROT assisted BootGuard solution and TXT on servers
using FIT 4 Entry. FitGen based on the CPU FMS FITGEN will
decide to call one of the two Type 2 FIT entry.

Signed-off-by: Rahul R Kumar <rahul.r.ku...@intel.com>
---
 Silicon/Intel/Tools/FitGen/FitGen.c | 1186 ++++++++++++++++-----------
 Silicon/Intel/Tools/FitGen/FitGen.h |    7 +-
 2 files changed, 722 insertions(+), 471 deletions(-)

diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c 
b/Silicon/Intel/Tools/FitGen/FitGen.c
index 87123f9922..4ba07945a6 100644
--- a/Silicon/Intel/Tools/FitGen/FitGen.c
+++ b/Silicon/Intel/Tools/FitGen/FitGen.c
@@ -44,11 +44,18 @@ typedef struct {
 #define BIOS_MODULE_ALIGNMENT  0x3F  // 64 bytes for AnC

 #define MICROCODE_ALIGNMENT    0x7FF

 

+#define MICROCODE_EXTERNAL_HEADER_SIZE 0x30

+

 #define ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE          256

 #define ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE          384

 

-#define ACM_HEADER_VERSION_3  (3 << 16)

-#define ACM_HEADER_VERSION_0  (0)

+#define ACM_XMSS_PUBLIC_KEY_SIZE                        64

+#define ACM_XMSS_SIGNATURE_SIZE                         2692

+

+#define ACM_HEADER_VERSION_5                            0x50004

+#define ACM_HEADER_VERSION_4                            (4 << 16)

+#define ACM_HEADER_VERSION_3                            (3 << 16)

+#define ACM_HEADER_VERSION_0                            (0)

 #define ACM_MODULE_TYPE_CHIPSET_ACM                     2

 #define ACM_MODULE_SUBTYPE_CAPABLE_OF_EXECUTE_AT_RESET  0x1

 #define ACM_MODULE_SUBTYPE_ANC_MODULE                   0x2

@@ -56,6 +63,37 @@ typedef struct {
 #define ACM_MODULE_FLAG_DEBUG_SIGN                      0x8000

 

 #define NIBBLES_TO_BYTE(A, B)  (UINT8)(((A & (0x0F)) << 4) | (B & 0x0F))

+//

+//Flash Map 0 Register (Flash Descriptor Records)

+//

+typedef struct {

+  UINT32      Fcba : 8;  //Bits[7:0]: Flash Component Base Address

+  UINT32      Nc   : 2;  //Bits[9:8]: Number of Components

+  UINT32      Rsvd0: 1;  //Bit10: Reserved

+  UINT32      Rsvd1: 1;  //Bit11: Reserved

+  UINT32      Rsvd2: 1;  //Bit12: Reserved

+  UINT32      Rsvd3: 3;  //Bits[15:13]: Reserved

+  UINT32      Frba : 8;  //Bits[23:16]: Flash Region Base Address

+  UINT32      Rsvd4: 3;  //Bits[26:24]: Reserved

+  UINT32      Rsvd5: 5;  //Bits[31:27]: Reserved

+} FLASH_MAP_0_REGISTER;

+

+//

+//Flash Region 1 (BIOS) Register (Flash Descriptor Records)

+//

+typedef struct {

+  UINT32      RegionBase : 15;  //Bits[14:0]: Region base

+  UINT32      Rsvd       : 1;   //Bit15: Reserved

+  UINT32      RegionLimit: 15;  //Bits[30:16]: Region limit

+  UINT32      Rsvd1      : 1;   //Bit31: Reserved

+} FLASH_REGION_1_BIOS_REGISTER;

+

+#define FLASH_VALID_SIGNATURE                           0x0FF0A55A   //Flash 
Valid Signature (Flash Descriptor Records)

+#define FLVALSIG_BASE_OFFSET                            0x10         //Flash 
Valid Signature Base Offset

+#define FLMAP0_BASE_OFFSET                              0x14         //Flash 
Map 0 Register Base Offset

+

+#define ACMFV_GUID \

+  { 0x8a4b197f, 0x1113, 0x43d0, { 0xa2, 0x3f, 0x26, 0xf3, 0x69, 0xb2, 0xb8, 
0x41 }}

 

 typedef struct {

   UINT16     ModuleType;

@@ -98,6 +136,8 @@ typedef struct {
 #define CHIPSET_ACM_TYPE_BIOS   0

 #define CHIPSET_ACM_TYPE_SINIT  1

 

+#define DEFAULT_ACM_EXTENDED_MASK 0x00FFFFFF

+

 typedef struct {

   UINT32    Guid0;

   UINT32    Guid1;

@@ -238,6 +278,7 @@ typedef struct {
 #define FIT_TABLE_TYPE_MICROCODE                   1

 #define FIT_TABLE_TYPE_STARTUP_ACM                 2

 #define FIT_TABLE_TYPE_DIAGNST_ACM                 3

+#define FIT_TABLE_TYPE_PROT_BOOT_POLICY            4

 #define FIT_TABLE_TYPE_BIOS_MODULE                 7

 #define FIT_TABLE_TYPE_TPM_POLICY                  8

 #define FIT_TABLE_TYPE_BIOS_POLICY                 9

@@ -252,7 +293,6 @@ typedef struct {
 #define FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST     27

 #define FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST       28

 

-

 //

 // With OptionalModule Address isn't known until free space has been

 // identified and the optional module has been copied into the FLASH

@@ -284,9 +324,10 @@ typedef struct {
   UINT32                     GlobalVersion;

   UINT32                     FitHeaderVersion;

   FIT_TABLE_CONTEXT_ENTRY    StartupAcm[MAX_STARTUP_ACM_ENTRY];

-  UINT32                     StartupAcmVersion[MAX_STARTUP_ACM_ENTRY];

+  UINT32                     StartupAcmFvSize;

   FIT_TABLE_CONTEXT_ENTRY    DiagnstAcm;

   UINT32                     DiagnstAcmVersion;

+  FIT_TABLE_CONTEXT_ENTRY    ProtBootPolicy;

   FIT_TABLE_CONTEXT_ENTRY    BiosModule[MAX_BIOS_MODULE_ENTRY];

   UINT32                     BiosModuleVersion;

   FIT_TABLE_CONTEXT_ENTRY    Microcode[MAX_MICROCODE_ENTRY];

@@ -305,25 +346,87 @@ xtoi (
   char  *str

   );

 

-VOID

-PrintUtilityInfo (

-  VOID

-  )

-/*++

+/**

+  Pass in supported CPU extended family/extended model/type

+  /family/model without stepping or CPU FMS >> 4.

+

+  @param FitEntry               Pointer to Fit Entry table.

+  @param AcmFamilyModel         Acm Family Model stepping.

+  @param AcmMask                ACM mask.

+

+  @return STATUS_SUCCESS  The file found and data read.

+**/

+STATUS

+SetFirmwareInterfaceTableEntryAcmFms(

+  FIRMWARE_INTERFACE_TABLE_ENTRY  *FitEntry,

+  UINT32                          AcmFamilyModel,

+  UINT32                          AcmMask

+)

+{

+  if (FitEntry == NULL) {

+    return STATUS_ERROR;

+  }

+

+  FitEntry->Checksum = (UINT8)(((AcmFamilyModel & 0x000F0000) >> 16) | 
(((AcmMask & 0x000F0000) >> 16) << 4));

+  FitEntry->Rsvd = (UINT8)((AcmMask & 0x0000FF00) >> 8);

+  FitEntry->Size[2] = (UINT8)(AcmMask & 0x000000FF);

+  FitEntry->Size[1] = (UINT8)((AcmFamilyModel & 0x0000FF00) >> 8);

+  FitEntry->Size[0] = (UINT8)(AcmFamilyModel & 0x000000FF);

+  return STATUS_SUCCESS;

+}

+

+/**

+  Set the FIT Entry Size.

+

+  @param FitEntry                Pointer to Fit Entry table.

+  @param SizeEntry               Size of FIT entry.

 

-Routine Description:

+  @return STATUS_SUCCESS  The file found and data read.

+**/

+STATUS

+SetFirmwareInterfaceTableEntrySize (

+  FIRMWARE_INTERFACE_TABLE_ENTRY  *FitEntry,

+  UINT32                          SizeEntry

+)

+{

+  if (FitEntry == NULL) {

+    return STATUS_ERROR;

+  }

+  FitEntry->Size[2] = (UINT8)((SizeEntry & 0x00FF0000) >> 16);

+  FitEntry->Size[1] = (UINT8)((SizeEntry & 0x0000FF00) >> 8);

+  FitEntry->Size[0] = (UINT8)(SizeEntry  & 0x000000FF);

+  return STATUS_SUCCESS;

+}

 

-  Displays the standard utility information to STDOUT

+/**

+  Get the FIT Entry Size.

 

-Arguments:

+  @param  FitEntry                Pointer to Fit Entry table.

 

-  None

+  @return FitEntry pointer

+**/

+UINT32

+GetFirmwareInterfaceTableEntrySize (

+  FIRMWARE_INTERFACE_TABLE_ENTRY  *FitEntry

+)

+{

+  if (FitEntry == NULL) {

+    return 0;

+  }

+  return (((UINT32)FitEntry->Size[2] << 16) | ((UINT32)FitEntry->Size[1] << 8) 
| (UINT32)FitEntry->Size[0]);

+}

 

-Returns:

+/**

+  Displays the FIT utility info

 

-  None

+  @param                           None

 

---*/

+  @return None

+**/

+VOID

+PrintUtilityInfo (

+  VOID

+  )

 {

   printf (

     "%s - Tiano IA32/X64 FIT table generation Utility for FIT spec revision 
%i.%i."" Version %i.%i\n\n",

@@ -335,25 +438,17 @@ Returns:
     );

 }

 

+/**

+  Displays the utility usage syntax to STDOUT.

+

+  @param  None

+

+  @return None

+**/

 VOID

 PrintUsage (

   VOID

   )

-/*++

-

-Routine Description:

-

-  Displays the utility usage syntax to STDOUT

-

-Arguments:

-

-  None

-

-Returns:

-

-  None

-

---*/

 {

   printf ("Usage (generate): %s [-D] InputFvRecoveryFile 
OutputFvRecoveryFile\n"

           "\t[-V <FitEntryDefaultVersion>]\n"

@@ -371,6 +466,7 @@ Returns:
           "\t[-M <MicrocodeAddress MicrocodeSize>] [-M ...]|[-U <MicrocodeFv 
MicrocodeBase>|<MicrocodeRegionOffset MicrocodeRegionSize>|<MicrocodeGuid>] [-V 
<MicrocodeVersion>]\n"

           "\t[-O RecordType <RecordDataAddress RecordDataSize>|<RESERVE 
RecordDataSize>|<RecordDataGuid>|<RecordBinFile>|<CseRecordSubType 
RecordBinFile> [-V <RecordVersion>]] [-O ... [-V ...]]\n"

           "\t[-P RecordType <IndexPort DataPort Width Bit Index> [-V 
<RecordVersion>]] [-P ... [-V ...]]\n"

+          "\t[-BP <BootPolicySize>[-V <BootPolicyVersion>]\n"

           "\t[-T <FixedFitLocation>]\n"

           , UTILITY_NAME);

   printf ("  Where:\n");

@@ -407,12 +503,14 @@ Returns:
   printf ("\tRecordDataGuid         - FIT entry record data GUID.\n");

   printf ("\tRecordBinFile          - FIT entry record data binary file.\n");

   printf ("\tCseRecordSubType       - FIT entry record subtype. Use to further 
distinguish CSE entries (see FIT spec revision 1.2 chapter 4.12).\n");

+  printf ("\tBootPolicySize         - FIT entry size for type 04 boot 
policy.\n");

   printf ("\tFitEntryDefaultVersion - The default version for all FIT table 
entries. 0x%04x is used if this is not specified.\n", 
DEFAULT_FIT_ENTRY_VERSION);

   printf ("\tFitHeaderVersion       - The version for FIT header. (Override 
default version)\n");

   printf ("\tStartupAcmVersion      - The version for StartupAcm. (Override 
default version)\n");

   printf ("\tBiosModuleVersion      - The version for BiosModule. (Override 
default version)\n");

   printf ("\tMicrocodeVersion       - The version for Microcode. (Override 
default version)\n");

   printf ("\tRecordVersion          - The version for Record. (Override 
default version)\n");

+  printf ("\tBootPolicyVersion      - The version for BootPolicy.     
(Override default version)\n");

   printf ("\tIndexPort              - The Index Port Number.\n");

   printf ("\tDataPort               - The Data Port Number.\n");

   printf ("\tWidth                  - The Width of the port.\n");

@@ -427,11 +525,20 @@ Returns:
   printf ("\tSTATUS_SUCCESS=%d, STATUS_WARNING=%d, STATUS_ERROR=%d\n", 
STATUS_SUCCESS, STATUS_WARNING, STATUS_ERROR);

 }

 

+/**

+  Set Value of memory.

+

+  @param Buffer                    The pointer where we need to set the memory.

+  @param Length                    Size of memory to be set.

+  @param Value                     Value of memory to be set.

+

+  @return Buffer  The pointer address.

+**/

 VOID *

 SetMem (

-  OUT     VOID                      *Buffer,

-  IN      UINTN                     Length,

-  IN      UINT8                     Value

+  OUT VOID                 *Buffer,

+  IN UINTN                 Length,

+  IN UINT8                 Value

   )

 {

   //

@@ -448,6 +555,14 @@ SetMem (
   return Buffer;

 }

 

+/**

+  check the input Path.

+

+  @param String         Passed input path.

+

+  @return TRUE          If the input path is correct.

+  @return FLASE         if the input path is not correct.

+**/

 BOOLEAN

 CheckPath (

   IN CHAR8 * String

@@ -476,28 +591,20 @@ CheckPath (
   return TRUE;

 }

 

+/**

+  Get fixed FIT location from argument.

+

+  @param argc                Number of command line parameters.

+  @param argv                Array of pointers to parameter strings.

+

+  @return FitLocation        The FIT location specified by Argument.

+  @return 0                  Argument parse fail.

+**/

 UINT32

 GetFixedFitLocation (

   IN INTN   argc,

   IN CHAR8  **argv

   )

-/*++

-

-Routine Description:

-

-  Get fixed FIT location from argument

-

-Arguments:

-

-  argc           - Number of command line parameters.

-  argv           - Array of pointers to parameter strings.

-

-Returns:

-

-  FitLocation - The FIT location specified by Argument

-  0           - Argument parse fail

-

-*/

 {

   UINT32                      FitLocation;

   INTN                        Index;

@@ -516,6 +623,18 @@ Returns:
   return FitLocation;

 }

 

+/**

+  Read input file.

+

+  @param FileName                    The input file name.

+  @param FileData                    The input file data, the memory is 
aligned.

+  @param FileSize                    The input file size.

+  @param FileBufferRaw               The memory to hold input file data. The 
caller must free the memory.

+

+  @return STATUS_SUCCESS             The file found and data read.

+  @return STATUS_ERROR               The file data is not read.

+  @return STATUS_WARNING             The file is not found.

+**/

 STATUS

 ReadInputFile (

   IN CHAR8    *FileName,

@@ -523,26 +642,6 @@ ReadInputFile (
   OUT UINT32  *FileSize,

   OUT UINT8   **FileBufferRaw OPTIONAL

   )

-/*++

-

-Routine Description:

-

-  Read input file

-

-Arguments:

-

-  FileName      - The input file name

-  FileData      - The input file data, the memory is aligned.

-  FileSize      - The input file size

-  FileBufferRaw - The memory to hold input file data. The caller must free the 
memory.

-

-Returns:

-

-  STATUS_SUCCESS - The file found and data read

-  STATUS_ERROR   - The file data is not read

-  STATUS_WARNING - The file is not found

-

---*/

 {

   FILE                        *FpIn;

   UINT32                      TempResult;

@@ -612,24 +711,20 @@ Returns:
   return STATUS_SUCCESS;

 }

 

+/**

+    Find next FvHeader in the FileBuffer.

+

+    @param FileBuffer            The start FileBuffer which needs to be 
searched.

+    @param FileLength            The whole File Length.

+

+    @return FvHeader             The FvHeader is found successfully.

+    @return NULL                 The FvHeader is not found.

+**/

 UINT8 *

 FindNextFvHeader (

   IN UINT8 *FileBuffer,

   IN UINTN  FileLength

   )

-/*++

-

-  Routine Description:

-    Find next FvHeader in the FileBuffer

-

-  Parameters:

-    FileBuffer        -   The start FileBuffer which needs to be searched

-    FileLength        -   The whole File Length.

-  Return:

-    FvHeader          -   The FvHeader is found successfully.

-    NULL              -   The FvHeader is not found.

-

---*/

 {

   UINT8                       *FileHeader;

   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

@@ -679,6 +774,17 @@ FindNextFvHeader (
   return NULL;

 }

 

+/**

+  Find File with GUID in an FV.

+

+  @param FvBuffer         FV binary buffer.

+  @param FvSize           FV size.

+  @param Guid             File GUID value to be searched.

+  @param FileSize         Guid File size.

+

+  @return FileLocation    Guid File location.

+  @return NULL            Guid File is not found.

+**/

 UINT8  *

 FindFileFromFvByGuid (

   IN UINT8     *FvBuffer,

@@ -686,25 +792,6 @@ FindFileFromFvByGuid (
   IN EFI_GUID  *Guid,

   OUT UINT32   *FileSize

   )

-/*++

-

-Routine Description:

-

-  Find File with GUID in an FV

-

-Arguments:

-

-  FvBuffer       - FV binary buffer

-  FvSize         - FV size

-  Guid           - File GUID value to be searched

-  FileSize       - Guid File size

-

-Returns:

-

-  FileLocation   - Guid File location.

-  NULL           - Guid File is not found.

-

---*/

 {

   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;

   EFI_FFS_FILE_HEADER         *FileHeader;

@@ -783,28 +870,20 @@ Returns:
   return NULL;

 }

 

+/**

+  Check whether a string is a GUID.

+

+  @param StringData    The String.

+  @param Guid          Guid to hold the value

+

+  @return TRUE         StringData is a GUID, and Guid field is filled.

+  @return FALSE        StringData is not a GUID.

+**/

 BOOLEAN

 IsGuidData (

   IN CHAR8     *StringData,

   OUT EFI_GUID *Guid

   )

-/*++

-

-Routine Description:

-

-  Check whether a string is a GUID

-

-Arguments:

-

-  StringData  - the String

-  Guid        - Guid to hold the value

-

-Returns:

-

-  TRUE  - StringData is a GUID, and Guid field is filled.

-  FALSE - StringData is not a GUID

-

---*/

 {

   if (strlen (StringData) != strlen ("00000000-0000-0000-0000-000000000000")) {

     return FALSE;

@@ -821,6 +900,17 @@ Returns:
   return TRUE;

 }

 

+/**

+  Get FIT entry number and fill global FIT table context, from argument.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings.

+  @param FdBuffer         FD binary buffer.

+  @param FdSize           FD size.

+

+  @return FitEntryNumber  The FIT entry number.

+  @return 0               Argument parse fail.

+**/

 VOID

 CheckOverlap (

   IN UINT32 Address,

@@ -875,6 +965,17 @@ CheckOverlap (
   }

 }

 

+/**

+  Get FIT entry number and fill global FIT table context, from argument.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings.

+  @param FdBuffer         FD binary buffer.

+  @param FdSize           FD size.

+

+  @return FitEntryNumber  The FIT entry number.

+  @return 0               Argument parse fail.

+**/

 UINT8 *

 GetMicrocodeBufferFromFv (

   EFI_FIRMWARE_VOLUME_HEADER *FvHeader

@@ -906,6 +1007,17 @@ GetMicrocodeBufferFromFv (
   return MicrocodeBuffer;

 }

 

+/**

+  Get FIT entry number and fill global FIT table context, from argument.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings.

+  @param FdBuffer         FD binary buffer.

+  @param FdSize           FD size.

+

+  @return FitEntryNumber  The FIT entry number.

+  @return 0               Argument parse fail.

+**/

 UINT32

 GetFitEntryNumber (

   IN INTN   argc,

@@ -913,25 +1025,6 @@ GetFitEntryNumber (
   IN UINT8  *FdBuffer,

   IN UINT32 FdSize

   )

-/*++

-

-Routine Description:

-

-  Get FIT entry number and fill global FIT table context, from argument

-

-Arguments:

-

-  argc           - Number of command line parameters.

-  argv           - Array of pointers to parameter strings.

-  FdBuffer       - FD binary buffer

-  FdSize         - FD size

-

-Returns:

-

-  FitEntryNumber - The FIT entry number

-  0              - Argument parse fail

-

-*/

 {

   EFI_GUID  Guid;

   EFI_GUID  MicrocodeFfsGuid;

@@ -1188,7 +1281,7 @@ Returns:
           gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type  
  = FIT_TABLE_TYPE_STARTUP_ACM;

           
gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = 
(UINT32)BiosInfoStruct[BiosInfoIndex].Address;

           gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size  
  = (UINT32)BiosInfoStruct[BiosInfoIndex].Size;

-          
gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber]  = 
BiosInfoStruct[BiosInfoIndex].Version;

+          
gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = 
BiosInfoStruct[BiosInfoIndex].Version;

           gFitTableContext.StartupAcmNumber ++;

           gFitTableContext.FitEntryNumber ++;

           break;

@@ -1203,6 +1296,13 @@ Returns:
           gFitTableContext.DiagnstAcmVersion  = DEFAULT_FIT_ENTRY_VERSION;

           gFitTableContext.FitEntryNumber ++;

           break;

+        case FIT_TABLE_TYPE_PROT_BOOT_POLICY:

+          gFitTableContext.ProtBootPolicy.Type     = 
FIT_TABLE_TYPE_PROT_BOOT_POLICY;

+          gFitTableContext.ProtBootPolicy.Address  = 
(UINT32)BiosInfoStruct[BiosInfoIndex].Address;

+          gFitTableContext.ProtBootPolicy.Size     = 
(UINT32)BiosInfoStruct[BiosInfoIndex].Size;

+          gFitTableContext.ProtBootPolicy.Version  = DEFAULT_FIT_ENTRY_VERSION;

+          gFitTableContext.FitEntryNumber ++;

+          break;

         case FIT_TABLE_TYPE_BIOS_MODULE:

           if ((BiosInfoStruct[BiosInfoIndex].Attributes & 
BIOS_INFO_STRUCT_ATTRIBUTE_BIOS_POST_IBB) != 0) {

             continue;

@@ -1402,7 +1502,8 @@ Returns:
         // not found

         return 0;

       }

-      FileBuffer = (UINT8 *)MEMORY_TO_FLASH (FileBuffer, FdBuffer, FdSize);

+      gFitTableContext.StartupAcmFvSize = FdSize;

+      FileBuffer = (UINT8 *)MEMORY_TO_FLASH(FileBuffer, FdBuffer, FdSize);

       Index += 2;

     } else {

       if (Index + 2 >= argc) {

@@ -1431,7 +1532,7 @@ Returns:
       //

       // Bypass

       //

-      gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = 
gFitTableContext.GlobalVersion;

+      gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = 
gFitTableContext.GlobalVersion;

     } else {

       if (Index + 2 >= argc) {

         //

@@ -1443,7 +1544,7 @@ Returns:
         //

         // With the -I parameter should assign the type 2 entry version as 
0x200 format

         //

-        gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] 
= STARTUP_ACM_FIT_ENTRY_200_VERSION;

+        gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version 
= STARTUP_ACM_FIT_ENTRY_200_VERSION;

         gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS = 
(UINT32)xtoi (argv[Index + 1]);

         gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask 
= (UINT32)xtoi (argv[Index + 2]);

 

@@ -1464,7 +1565,8 @@ Returns:
       //

       // Get offset from parameter

       //

-      gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] = 
xtoi (argv[Index + 1]);

+      gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = 
gFitTableContext.GlobalVersion;

+      gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = 
xtoi (argv[Index + 1]);

       Index += 2;

     }

 

@@ -1942,7 +2044,7 @@ Returns:
       //

       // Get offset from parameter

       //

-      gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version = 
xtoi (argv[Index + 1]);

+      gFitTableContext.PortModule[gFitTableContext.PortModuleNumber].Version = 
xtoi(argv[Index + 1]);

       Index += 2;

     }

 

@@ -1950,6 +2052,69 @@ Returns:
     gFitTableContext.FitEntryNumber++;

   }

 

+  //

+  // 6th, try FIT boot policy data

+  //

+  if ((Index < argc) &&

+      ((strcmp(argv[Index], "-BP") == 0) ||

+      (strcmp(argv[Index], "-bp") == 0))) {

+

+    if (Index + 1 >= argc) {

+      Error(NULL, 0, 0, "-BP: Invalid Parameters.", NULL);

+      FitEntryNumber = 0;

+    }

+

+    gFitTableContext.StartupAcmFvSize = GetFvAcmSizeFromFd(FdBuffer, FdSize);

+    if (gFitTableContext.StartupAcmFvSize == 0) {

+      Error(NULL, 0, 0, "FV_ACM not found in Fd file!", NULL);

+    }

+

+    //

+    // FIT type 04 record shares FV allocated space with FV_ACM.

+    //

+    FileSize = xtoi(argv[Index + 1]);

+

+    if (gFitTableContext.StartupAcm[0].Size + FileSize > 
gFitTableContext.StartupAcmFvSize) {

+      Error(NULL, 0, 0, "Error: not enough FV_ACM room for FIT type 04 
record!", NULL);

+      FitEntryNumber = 0;

+    }

+

+    FileBuffer = malloc(FileSize);

+    if (FileBuffer == NULL) {

+      Error(NULL, 0, 0, "No sufficient memory to allocate!", NULL);

+      FitEntryNumber = 0;

+    }

+

+    SetMem(FileBuffer, FileSize, 0xFF);

+

+    gFitTableContext.ProtBootPolicy.Type = FIT_TABLE_TYPE_PROT_BOOT_POLICY;

+    gFitTableContext.ProtBootPolicy.Address = 
gFitTableContext.StartupAcm[0].Address + gFitTableContext.StartupAcm[0].Size;

+    gFitTableContext.ProtBootPolicy.Size = FileSize;

+    gFitTableContext.ProtBootPolicy.Version = 0;

+

+    Index += 2;

+

+    //

+    // 6.1 PROT Module version

+    //

+    if ((Index + 1 >= argc) ||

+        ((strcmp (argv[Index], "-V") != 0) &&

+         (strcmp (argv[Index], "-v") != 0)) ) {

+      //

+      // Bypass

+      //

+      gFitTableContext.ProtBootPolicy.Version = gFitTableContext.GlobalVersion;

+    } else {

+      //

+      // Get offset from parameter

+      //

+      gFitTableContext.ProtBootPolicy.Version = xtoi(argv[Index + 1]);

+      Index += 2;

+    }

+

+    gFitTableContext.FitEntryNumber++;

+  }

+

   //

   // Final: Check StartupAcm in BiosModule.

   //

@@ -1974,31 +2139,23 @@ Returns:
   return FitEntryNumber;

 }

 

+/**

+  No enough space - it might happen that it is occupied by AP wake vector.

+  Last chance - skip this and search again.

+

+  @param FvBuffer         FvRecovery binary buffer.

+  @param Address          Address to be searched from.

+  @param Size             Size need to be filled.

+

+  @return FitTableOffset  The FIT table offset.

+  @return NULL            No enough space for FIT table.

+**/

 VOID *

 FindSpaceSkipApVector (

   IN UINT8     *FvBuffer,

   IN UINT8     *Address,

   IN UINTN     Size

   )

-/*++

-

-Routine Description:

-

-  No enough space - it might happen that it is occupied by AP wake vector.

-  Last chance - skip this and search again.

-

-Arguments:

-

-  FvBuffer       - FvRecovery binary buffer

-  Address        - Address to be searched from

-  Size           - Size need to be filled

-

-Returns:

-

-  FitTableOffset - The FIT table offset

-  NULL           - No enough space for FIT table

-

-*/

 {

   UINT8        *ApVector;

   UINT8        *NewAddress;

@@ -2018,6 +2175,17 @@ Returns:
   return NewAddress;

 }

 

+/**

+  Get free space for FIT table from FvRecovery.

+

+  @param FvBuffer           FvRecovery binary buffer.

+  @param FvSize             FvRecovery size.

+  @param FitTableSize       The FIT table size.

+  @param FixedFitLocation   Fixed FIT location provided by argument.

+

+  @return FitTableOffset    The offset of FIT table in FvRecovery file.

+  @return NULL              Free space not found.

+**/

 VOID *

 GetFreeSpaceForFit (

   IN UINT8     *FvBuffer,

@@ -2025,25 +2193,6 @@ GetFreeSpaceForFit (
   IN UINT32    FitTableSize,

   IN UINT32    FixedFitLocation

   )

-/*++

-

-Routine Description:

-

-  Get free space for FIT table from FvRecovery

-

-Arguments:

-

-  FvBuffer         - FvRecovery binary buffer

-  FvSize           - FvRecovery size

-  FitTableSize     - The FIT table size

-  FixedFitLocation - Fixed FIT location provided by argument

-

-Returns:

-

-  FitTableOffset - The offset of FIT table in FvRecovery file

-  NULL           - Free space not found

-

---*/

 {

   UINT8       *FitTableOffset;

   INTN        Index;

@@ -2167,7 +2316,7 @@ Returns:
           (gFitTableContext.OptionalModule[Index].Type == 
FIT_TABLE_TYPE_VAB_PROVISION_TABLE) ||

           (gFitTableContext.OptionalModule[Index].Type == 
FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) ||

           (gFitTableContext.OptionalModule[Index].Type == 
FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) {

-          // Let it 64 byte align

+        // Let it 64 byte align

         AlignedSize += BIOS_MODULE_ALIGNMENT;

         AlignedSize &= ~BIOS_MODULE_ALIGNMENT;

       }

@@ -2228,25 +2377,17 @@ Returns:
   return FitTableOffset;

 }

 

+/**

+  Output FIT table information.

+

+  @param None

+

+  @return None

+**/

 VOID

 PrintFitData (

   VOID

   )

-/*++

-

-Routine Description:

-

-  Output FIT table information

-

-Arguments:

-

-  None

-

-Returns:

-

-  None

-

---*/

 {

   UINT32                          Index;

 

@@ -2257,11 +2398,15 @@ Returns:
   printf ("Total FIT Entry number: 0x%x\n", gFitTableContext.FitEntryNumber);

   printf ("FitHeader version: 0x%04x\n", gFitTableContext.FitHeaderVersion);

   for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) {

-    printf ("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, 
gFitTableContext.StartupAcm[Index].Address, 
gFitTableContext.StartupAcm[Index].Size, 
gFitTableContext.StartupAcmVersion[Index]);

+    printf("StartupAcm[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, 
gFitTableContext.StartupAcm[Index].Address, 
gFitTableContext.StartupAcm[Index].Size, 
gFitTableContext.StartupAcm[Index].Version);

   }

   if (gFitTableContext.DiagnstAcm.Address != 0) {

     printf ("DiagnosticAcm - (0x%08x, 0x%08x, 0x%04x)\n", 
gFitTableContext.DiagnstAcm.Address, gFitTableContext.DiagnstAcm.Size, 
gFitTableContext.DiagnstAcmVersion);

   }

+

+  if (gFitTableContext.ProtBootPolicy.Address != 0) {

+    printf ("ProtBootPolicy - (0x%08x, 0x%08x, 0x%04x)\n", 
gFitTableContext.ProtBootPolicy.Address, gFitTableContext.ProtBootPolicy.Size, 
gFitTableContext.ProtBootPolicy.Version);

+  }

   for (Index = 0; Index < gFitTableContext.BiosModuleNumber; Index++) {

     printf ("BiosModule[%d] - (0x%08x, 0x%08x, 0x%04x)\n", Index, 
gFitTableContext.BiosModule[Index].Address, 
gFitTableContext.BiosModule[Index].Size, gFitTableContext.BiosModuleVersion);

   }

@@ -2304,8 +2449,7 @@ CHAR8 *mFitTypeStr[] = {
   "MICROCODE  ",

   "STARTUP_ACM",

   "DIAGNST_ACM",

-  "           ",

-  "           ",

+  "BOOT_POLICY",

   "           ",

   "           ",

   "BIOS_MODULE",

@@ -2320,27 +2464,19 @@ CHAR8 *mFitTypeStr[] = {
   "CSE_SECUREB"

 };

 

+/**

+  Convert FitEntry type to a string.

+

+  @param FitEntry     Fit entry

+

+  @return String

+**/

 CHAR8  mFitSignature[] = "'_FIT_   ' ";

 CHAR8  mFitSignatureInHeader[] = "'        ' ";

 CHAR8 *

 FitTypeToStr (

   IN FIRMWARE_INTERFACE_TABLE_ENTRY  *FitEntry

   )

-/*++

-

-Routine Description:

-

-  Convert FitEntry type to a string

-

-Arguments:

-

-  FitEntry - Fit entry

-

-Returns:

-

-  String

-

---*/

 {

   if (FitEntry->Type == FIT_TABLE_TYPE_HEADER) {

     CopyMem (&mFitSignatureInHeader[1], &FitEntry->Address, 
sizeof(FitEntry->Address));

@@ -2361,27 +2497,19 @@ Returns:
   }

 }

 

+/**

+  Print Fit table in flash image.

+

+  @param FvBuffer               FvRecovery binary buffer.

+  @param FvSize                 FvRecovery size.

+

+  @return None

+**/

 VOID

 PrintFitTable (

   IN UINT8                       *FvBuffer,

   IN UINT32                      FvSize

   )

-/*++

-

-Routine Description:

-

-  Print Fit table in flash image

-

-Arguments:

-

-  FvBuffer       - FvRecovery binary buffer

-  FvSize         - FvRecovery size

-

-Returns:

-

-  None

-

---*/

 {

   FIRMWARE_INTERFACE_TABLE_ENTRY  *FitEntry;

   UINT32                          EntryNum;

@@ -2460,11 +2588,12 @@ Returns:
 }

 

 /**

-

   This function dump raw data.

 

-  @param  Data  raw data

-  @param  Size  raw data size

+  @param  Data    Raw data.

+  @param  Size    Raw data size.

+

+ @return none

 

 **/

 VOID

@@ -2480,12 +2609,12 @@ DumpData (
 }

 

 /**

-

   This function dump raw data with colume format.

 

-  @param  Data  raw data

-  @param  Size  raw data size

+  @param  Data     Raw data

+  @param  Size     Raw data size

 

+ @return  none

 **/

 VOID

 DumpHex (

@@ -2532,25 +2661,17 @@ CHAR8 *mCapabilityStr[] = {
   "STM support              ",

 };

 

+/**

+  DumpAcm information

+

+  @param Acm       - ACM buffer

+

+  @retval None

+**/

 VOID

 DumpAcm (

   IN ACM_FORMAT                    *Acm

   )

-/*++

-

-Routine Description:

-

-  DumpAcm information

-

-Arguments:

-

-  Acm       - ACM buffer

-

-Returns:

-

-  None

-

---*/

 {

   CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable;

   CHIPSET_ID_LIST               *ChipsetIdList;

@@ -2600,23 +2721,21 @@ Returns:
   printf ("  RSAPubKey                  - \n");

   DumpHex (Buffer, Acm->KeySize * 4);

   printf ("\n");

-  Buffer += Acm->KeySize * 4;

-  //

-  // To simplify the tool and making it independent of ACM header change,

-  // the rest of ACM parsing  will be skipped starting ACM_HEADER_VERSION4

-  //

-  if((Acm->HeaderVersion != ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != 
ACM_HEADER_VERSION_0)){

-     printf (

-        
"*****************************************************************************\n\n"

-        );

-    return;

-  }

+  Buffer += Acm->KeySize * 4;  //add public key size (taken from header 
variable * 4) to buffer.

+

+  //add signature size to pointer.

   if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {

     printf ("  RSASig                     - \n");

     DumpHex (Buffer, ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE); // PKCS #1.5 RSA 
Signature

     printf ("\n");

     Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;

-  } else {

+  }

+  else if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion 
== ACM_HEADER_VERSION_5)) {

+    Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;

+    Buffer += ACM_XMSS_PUBLIC_KEY_SIZE;

+    Buffer += ACM_XMSS_SIGNATURE_SIZE;

+  }

+  else {

     printf ("  RSAPubExp                  - %08x\n", *(UINT32 *)Buffer);

     Buffer += 4;

 

@@ -2627,6 +2746,10 @@ Returns:
   }

   Buffer += Acm->ScratchSize * 4;

 

+  if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == 
ACM_HEADER_VERSION_5)) {

+    Buffer += 60;  //add reserved bytes.

+  }

+

   if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) == 0) {

     ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE *)Buffer;

     printf ("Chipset ACM info:\n");

@@ -2697,28 +2820,77 @@ End:
     );

 }

 

-BOOLEAN

-CheckAcm (

-  IN ACM_FORMAT                        *Acm,

-  IN UINTN                             AcmMaxSize

-  )

-/*++

+/**

+  Get ACM FMS information.

+

+  @param Acm          ACM buffer.

+  @param AcmFms       Get ACM FMS.

+  @param AcmMask      Get ACM Mask.

+

+  @retval NULL

+**/

+VOID

+GetAcmFms(

+  IN ACM_FORMAT *Acm,

+  OUT UINT32 *AcmFms,

+  OUT UINT32 *AcmMask

+)

+{

+  UINT32 FmsOffset = 0;

+  UINT32 TmpFms = 0;

+  UINT32 TmpMask = 0;

+  UINT32 Index = 0;

+  PROCESSOR_ID_LIST *ProcessorIdList = NULL;

+

+  if ((Acm == NULL) || (AcmFms == NULL) || (AcmMask == NULL))

+    return;

+

+  *AcmFms = 0;

+  *AcmMask = 0;

+

+  switch (Acm->HeaderVersion) {

+  case ACM_HEADER_VERSION_3:

+    FmsOffset = *(UINT32*)((UINT8*)Acm + 0x6E8); //AcmInfoTable at 0x6C0, 
+0x28 for ProcessorIdList

+    break;

+  case ACM_HEADER_VERSION_4:

+  case ACM_HEADER_VERSION_5:

+    FmsOffset = *(UINT32*)((UINT8*)Acm + 0x1CA8); //AcmInfoTable at 0x1C80, 
+0x28 for ProcessorIdList

+    break;

+  default:

+    return;

+  }

 

-Routine Description:

+  ProcessorIdList = (PROCESSOR_ID_LIST *)((UINT8*)Acm + FmsOffset);

 

-  Check Acm information

+  if (ProcessorIdList->Count > 0) {

+    TmpFms = ProcessorIdList->ProcessorID[0].FMS;

+    *AcmFms = TmpFms;

+    *AcmMask = DEFAULT_ACM_EXTENDED_MASK;

+  }

 

-Arguments:

+  for (Index = 1; Index < ProcessorIdList->Count; Index++) {

+    TmpMask = (TmpFms ^ ProcessorIdList->ProcessorID[Index].FMS);

+    TmpFms &= ProcessorIdList->ProcessorID[Index].FMS;

+  }

 

-  Acm        - ACM buffer

-  AcmMaxSize - ACM max size

+  *AcmMask = ~TmpMask;

+  return;

+}

 

-Returns:

+/**

+  Check Acm information.

 

-  TRUE  - ACM is valid

-  FALSE - ACM is invalid

+  @param Acm          ACM buffer.

+  @param AcmMaxSize   ACM max size.

 

---*/

+  @retval TRUE    ACM is valid.

+  @retval FALSE   ACM is invalid.

+**/

+BOOLEAN

+CheckAcm (

+  IN ACM_FORMAT                        *Acm,

+  IN UINTN                             AcmMaxSize

+  )

 {

   CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable;

   CHIPSET_ID_LIST               *ChipsetIdList;

@@ -2734,24 +2906,27 @@ Returns:
     return FALSE;

   }

 

-  //

-  // To simplify the tool and making it independent of ACM header change,

-  // the following check will be skipped starting ACM_HEADER_VERSION3

-  //

-  if((Acm->HeaderVersion != ACM_HEADER_VERSION_3) && (Acm->HeaderVersion != 
ACM_HEADER_VERSION_0)){

-    printf ("ACM header Version 4 or higher, bypassing other checks!\n");

-    return TRUE;

-  }

+  //move buffer pointer to address past generic ACM header (post scratchsize)

   Buffer = (UINT8 *)(Acm + 1);

   Buffer += Acm->KeySize * 4;

   if (Acm->HeaderVersion == ACM_HEADER_VERSION_3) {

     Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;

-  } else {

+  }

+  else if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion 
== ACM_HEADER_VERSION_5)) {

+    Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA384_SIZE;

+    Buffer += ACM_XMSS_PUBLIC_KEY_SIZE;

+    Buffer += ACM_XMSS_SIGNATURE_SIZE;

+  }

+  else {

     Buffer += 4;

     Buffer += ACM_PKCS_1_5_RSA_SIGNATURE_SHA256_SIZE;

   }

   Buffer += Acm->ScratchSize * 4;

 

+  if ((Acm->HeaderVersion == ACM_HEADER_VERSION_4) || (Acm->HeaderVersion == 
ACM_HEADER_VERSION_5)) {

+    Buffer += 60;  //add reserved bytes.

+  }

+

   if ((Acm->ModuleSubType & ACM_MODULE_SUBTYPE_ANC_MODULE) == 0) {

     ChipsetAcmInformationTable = (CHIPSET_ACM_INFORMATION_TABLE *)Buffer;

     if ((UINTN)ChipsetAcmInformationTable >= (UINTN)Acm + AcmMaxSize) {

@@ -2814,29 +2989,21 @@ End:
   return TRUE;

 }

 

+/**

+  Fill the FIT table information to FvRecovery.

+

+  @param FvBuffer         FvRecovery binary buffer.

+  @param FvSize           FvRecovery size.

+  @param FitTableOffset   The offset of FIT table in FvRecovery file.

+

+  @retval None

+**/

 VOID

 FillFitTable (

   IN UINT8     *FvBuffer,

   IN UINT32    FvSize,

   IN UINT8     *FitTableOffset

   )

-/*++

-

-Routine Description:

-

-  Fill the FIT table information to FvRecovery

-

-Arguments:

-

-  FvBuffer       - FvRecovery binary buffer

-  FvSize         - FvRecovery size

-  FitTableOffset - The offset of FIT table in FvRecovery file

-

-Returns:

-

-  None

-

---*/

 {

   FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;

   UINT32                          FitIndex;

@@ -2899,15 +3066,18 @@ Returns:
   // 4. StartupAcm

   //

   for (Index = 0; Index < gFitTableContext.StartupAcmNumber; Index++) {

-    if (gFitTableContext.StartupAcmVersion[Index] == 
STARTUP_ACM_FIT_ENTRY_200_VERSION) {

+    if (gFitTableContext.StartupAcm[Index].Version == 
STARTUP_ACM_FIT_ENTRY_200_VERSION) {

+      printf("ACM version 0x200\n");

       FMS.Uint32 = gFitTableContext.StartupAcm[Index].FMS;

       FMSMask.Uint32 = gFitTableContext.StartupAcm[Index].FMSMask;

+      printf("ACM FMS:%08x\n", FMS.Uint32);

+      printf("ACM FMSMask:%08x\n", FMSMask.Uint32);

       FitEntry[FitIndex].Address  = gFitTableContext.StartupAcm[Index].Address;

       FitEntry[FitIndex].Size[0]  = NIBBLES_TO_BYTE (FMS.Bits.Family, 
FMS.Bits.Model);

       FitEntry[FitIndex].Size[1]  = NIBBLES_TO_BYTE (FMS.Bits.ExtendedModel, 
FMS.Bits.Type);

       FitEntry[FitIndex].Size[2]  = NIBBLES_TO_BYTE (FMSMask.Bits.Family, 
FMSMask.Bits.Model);

       FitEntry[FitIndex].Rsvd     = NIBBLES_TO_BYTE 
(FMSMask.Bits.ExtendedModel, FMSMask.Bits.Type);

-      FitEntry[FitIndex].Version  = 
(UINT16)gFitTableContext.StartupAcmVersion[Index];

+      FitEntry[FitIndex].Version = 
(UINT16)gFitTableContext.StartupAcm[Index].Version;

       FitEntry[FitIndex].Type     = FIT_TABLE_TYPE_STARTUP_ACM;

       FitEntry[FitIndex].C_V      = 0;

       FitEntry[FitIndex].Checksum = NIBBLES_TO_BYTE 
(FMSMask.Bits.ExtendedFamily, FMS.Bits.ExtendedFamily);

@@ -2918,7 +3088,7 @@ Returns:
       FitEntry[FitIndex].Size[1]  = (UINT8)(FitEntrySizeValue >> 8);

       FitEntry[FitIndex].Size[2]  = (UINT8)(FitEntrySizeValue >> 16);

       FitEntry[FitIndex].Rsvd     = 0;

-      FitEntry[FitIndex].Version  = 
(UINT16)gFitTableContext.StartupAcmVersion[Index];

+      FitEntry[FitIndex].Version = 
(UINT16)gFitTableContext.StartupAcm[Index].Version;

       FitEntry[FitIndex].Type     = FIT_TABLE_TYPE_STARTUP_ACM;

       FitEntry[FitIndex].C_V      = 0;

       FitEntry[FitIndex].Checksum = 0;

@@ -2943,7 +3113,23 @@ Returns:
     FitIndex++;

   }

   //

-  // 5. BiosModule

+  // 5. (4) Bootable BootPolicy Data

+  //

+  if (gFitTableContext.ProtBootPolicy.Address != 0) {

+    FitEntry[FitIndex].Address                 = 
gFitTableContext.ProtBootPolicy.Address;

+    FitEntry[FitIndex].Size[0]                 = (UINT8) 
(gFitTableContext.ProtBootPolicy.Size);

+    FitEntry[FitIndex].Size[1]                 = (UINT8) 
(gFitTableContext.ProtBootPolicy.Size >> 8);

+    FitEntry[FitIndex].Size[2]                 = (UINT8) 
(gFitTableContext.ProtBootPolicy.Size >> 16);

+    FitEntry[FitIndex].Rsvd                    = 0;

+    FitEntry[FitIndex].Version                 = 
(UINT16)gFitTableContext.ProtBootPolicy.Version;

+    FitEntry[FitIndex].Type                    = 
FIT_TABLE_TYPE_PROT_BOOT_POLICY;

+    FitEntry[FitIndex].C_V                     = 0;

+    FitEntry[FitIndex].Checksum                = 0;

+    FitIndex++;

+  }

+

+  //

+  // 6. BiosModule

   //

   //

   // BiosModule segments order needs to be put from low address to high for 
Btg requirement

@@ -2974,7 +3160,7 @@ Returns:
   }

 

   //

-  // 6. Optional module

+  // 7. Optional module

   //

   for (Index = 0; Index < gFitTableContext.OptionalModuleNumber; Index++) {

     FitEntrySizeValue           = gFitTableContext.OptionalModule[Index].Size;

@@ -2993,7 +3179,7 @@ Returns:
   }

 

   //

-  // 7. Port module

+  // 8. Port module

   //

   for (Index = 0; Index < gFitTableContext.PortModuleNumber; Index++) {

     FitEntrySizeValue           = 0;

@@ -3029,27 +3215,19 @@ Returns:
   FitEntry[0].Checksum = Checksum;

 }

 

+/**

+  Clear the FIT table information to Fvrecovery.

+

+  @param FvBuffer       - Fvrecovery binary buffer.

+  @param FvSize         - Fvrecovery size.

+

+  @retval None

+**/

 VOID

 ClearFitTable (

   IN UINT8     *FvBuffer,

   IN UINT32    FvSize

   )

-/*++

-

-Routine Description:

-

-  Clear the FIT table information to Fvrecovery

-

-Arguments:

-

-  FvBuffer       - Fvrecovery binary buffer

-  FvSize         - Fvrecovery size

-

-Returns:

-

-  None

-

---*/

 {

   FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;

   UINT32                          EntryNum;

@@ -3097,30 +3275,22 @@ Returns:
   }

 }

 

+/**

+  Read input file.

+

+  @param FileName          The input file name.

+  @param FileData          The input file data.

+  @paramFileSize           The input file size.

+

+  @retval STATUS_SUCCESS   Write file data successfully.

+  @retval STATUS_ERROR     The file data is not written.

+**/

 STATUS

 WriteOutputFile (

   IN CHAR8   *FileName,

   IN UINT8   *FileData,

   IN UINT32  FileSize

   )

-/*++

-

-Routine Description:

-

-  Read input file

-

-Arguments:

-

-  FileName      - The input file name

-  FileData      - The input file data

-  FileSize      - The input file size

-

-Returns:

-

-  STATUS_SUCCESS - Write file data successfully

-  STATUS_ERROR   - The file data is not written

-

---*/

 {

   FILE                        *FpOut;

 

@@ -3157,28 +3327,78 @@ Returns:
   return STATUS_SUCCESS;

 }

 

+

 UINT32

-GetFvRecoveryInfoFromFd (

+GetFvAcmSizeFromFd(

   IN UINT8                       *FdBuffer,

-  IN UINT32                      FdFileSize,

-  OUT UINT8                      **FvRecovery

-  )

-/*++

+  IN UINT32                      FdFileSize

+)

+/**

+  Get FV_ACM Size information from Fd file.

 

-Routine Description:

+  @param FdBuffer       Fd file buffer.

+  @param FdFileSize     Fd file size.

 

-  Get FvRecovery information from Fd file.

+  @retval FvACM size

+

+**/

+{

+  UINT8                         *FileBuffer = NULL;

+  UINT32                        FvAcmSize = 0;

+  EFI_GUID                      ACMGuid = ACMFV_GUID;

+  UINT32                        FvLength;

+  UINT32                        FileLength;

+

+  //*FvRecovery = NULL;

+  FileBuffer = FindNextFvHeader(FdBuffer, FdFileSize);

+  if (FileBuffer == NULL) {

+    return 0;

+  }

 

-Arguments:

+  while ((UINTN)FileBuffer < (UINTN)FdBuffer + FdFileSize) {

+    FvLength = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)FileBuffer)->FvLength;

 

-  FdBuffer     - Fd file buffer.

-  FdFileSize   - Fd file size.

-  FvRecovery   - FvRecovery pointer in Fd file buffer

+    if (FindFileFromFvByGuid(FileBuffer, FvLength, &ACMGuid, &FileLength) != 
NULL) {

+      //

+      // Found the ACM

+      //

+      FvAcmSize = FvLength;

+    }

 

-Returns:

-  FvRecovery file size

+    //

+    // Next fv

+    //

+    FileBuffer = (UINT8 *)FileBuffer + FvLength;

+    if ((UINTN)FileBuffer >= (UINTN)FdBuffer + FdFileSize) {

+      break;

+    }

+    FileBuffer = FindNextFvHeader(FileBuffer, (UINTN)FdBuffer + FdFileSize - 
(UINTN)FileBuffer);

+    if (FileBuffer == NULL) {

+      break;

+    }

 

---*/

+  }

+

+  return FvAcmSize;

+}

+

+/**

+

+  Get FvRecovery information from Fd file.

+

+  @param FdBuffer               Fd file buffer.

+  @param FdFileSize             Fd file size.

+  @param FvRecovery             FvRecovery pointer in Fd file buffer

+

+  @retval FvRecovery file size

+

+**/

+UINT32

+GetFvRecoveryInfoFromFd (

+  IN UINT8                       *FdBuffer,

+  IN UINT32                      FdFileSize,

+  OUT UINT8                      **FvRecovery

+  )

 {

   UINT8                         *FileBuffer = NULL;

   UINT32                        FvRecoveryFileSize =0;

@@ -3223,16 +3443,7 @@ Returns:
   return FvRecoveryFileSize;

 }

 

-void

-GetFMSFromFitEntry (

-  IN      FIRMWARE_INTERFACE_TABLE_ENTRY   FitEntry,

-  IN OUT  PROCESSOR_ID                     *FMS,

-  IN OUT  PROCESSOR_ID                     *FMSMask

-  )

-/*++

-

-Routine Description:

-

+/**

   Get FMS information from FIT Entry.

 

   Note: Since FIT entry not record all the processor ID information.

@@ -3260,17 +3471,18 @@ Routine Description:
   |          |   Family  |   Model   |  ExtModel |    Type   |   Family  |   
Model   |                       |

   
+----------+-----------------------+-----------------------+-----------------------+-----------------------+

 

+  @param  FitEntry  FIT entry information.

+  @param  FMS       Processor ID information.

+  @param  FMSMask   Processor ID mask information.

 

-Arguments:

-

-  FitEntry - FIT entry information.

-  FMS      - Processor ID information.

-  FMSMask  - Processor ID mask information.

-

-Returns:

-  None

-

---*/

+  @retval None

+**/

+void

+GetFMSFromFitEntry (

+  IN      FIRMWARE_INTERFACE_TABLE_ENTRY   FitEntry,

+  IN OUT  PROCESSOR_ID                     *FMS,

+  IN OUT  PROCESSOR_ID                     *FMSMask

+  )

 {

 

   FMS->Bits.Family         = (FitEntry.Size[0]  & 0xF0) >> 4;

@@ -3286,27 +3498,19 @@ Returns:
   FMSMask->Bits.ExtendedFamily = (FitEntry.Checksum & 0xF0) >> 4;

 }

 

+/**

+  Get the FIT table information from Fvrecovery.

+

+  @param FvBuffer         Fvrecovery binary buffer.

+  @param FvSize           Fvrecovery size.

+

+  @retval 0 - Fit Table not found

+**/

 UINT32

 GetFitEntryInfo (

   IN UINT8     *FvBuffer,

   IN UINT32    FvSize

   )

-/*++

-

-Routine Description:

-

-  Get the FIT table information from Fvrecovery

-

-Arguments:

-

-  FvBuffer       - Fvrecovery binary buffer

-  FvSize         - Fvrecovery size

-

-Returns:

-

-  0 - Fit Table not found

-

---*/

 {

   FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry;

   UINT32                          FitEntrySizeValue;

@@ -3360,14 +3564,20 @@ Returns:
       gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Address = 
(UINT32)FitEntry[FitIndex].Address;

       gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Size    = 
FitEntrySizeValue;

       gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Type    = 
FitEntry[FitIndex].Type;

-      gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber]  = 
FitEntry[FitIndex].Version;

-      if 
(gFitTableContext.StartupAcmVersion[gFitTableContext.StartupAcmNumber] == 
STARTUP_ACM_FIT_ENTRY_200_VERSION) {

+      gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version = 
FitEntry[FitIndex].Version;

+

+      if 
(gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].Version == 
STARTUP_ACM_FIT_ENTRY_200_VERSION) {

         GetFMSFromFitEntry (FitEntry[FitIndex], &FMS, &FMSMask);

         gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMS     
= FMS.Uint32;

         gFitTableContext.StartupAcm[gFitTableContext.StartupAcmNumber].FMSMask 
= FMSMask.Uint32;

       }

       gFitTableContext.StartupAcmNumber++;

       break;

+    case FIT_TABLE_TYPE_PROT_BOOT_POLICY:

+      gFitTableContext.ProtBootPolicy.Address = 
(UINT32)FitEntry[FitIndex].Address;

+      gFitTableContext.ProtBootPolicy.Version = FitEntry[FitIndex].Version;

+      gFitTableContext.ProtBootPolicy.Size = 
GetFirmwareInterfaceTableEntrySize (&FitEntry[FitIndex]);

+      break;

     case FIT_TABLE_TYPE_BIOS_MODULE:

       gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Address = 
(UINT32)FitEntry[FitIndex].Address;

       gFitTableContext.BiosModule[gFitTableContext.BiosModuleNumber].Size    = 
FitEntrySizeValue * 16;

@@ -3398,27 +3608,20 @@ Returns:
   return gFitTableContext.FitEntryNumber;

 }

 

+/**

+  Main function for FitGen.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings.

+

+  @retval STATUS_SUCCESS  Utility exits successfully.

+  @retval STATUS_ERROR    Some error occurred during execution.

+**/

 STATUS

 FitGen (

   IN INTN   argc,

   IN CHAR8  **argv

   )

-/*++

-

-Routine Description:

-

-  Main function for FitGen.

-

-Arguments:

-

-  argc - Number of command line parameters.

-  argv - Array of pointers to parameter strings.

-

-Returns:

-  STATUS_SUCCESS - Utility exits successfully.

-  STATUS_ERROR   - Some error occurred during execution.

-

---*/

 {

   UINT32                      FvRecoveryFileSize;

   UINT8                       *FileBuffer;

@@ -3433,7 +3636,7 @@ Returns:
   UINT32                      FdFileSize;

 

   UINT8                       *AcmBuffer;

-  INTN                        Index;

+  INTN                        Index = 0;

   UINT32                      FixedFitLocation;

 

   FileBufferRaw = NULL;

@@ -3514,6 +3717,7 @@ Returns:
 

     FitTableOffset = GetFreeSpaceForFit (FileBuffer, FvRecoveryFileSize, 
FitTableSize, FixedFitLocation);

     if (FitTableOffset == NULL) {

+      printf ("Error - FitTableOffset is NULL\n");

       return STATUS_ERROR;

     }

 

@@ -3526,7 +3730,10 @@ Returns:
     // Get ACM buffer

     //

     for (Index = 0; Index < (INTN)gFitTableContext.StartupAcmNumber; Index ++) 
{

+      printf("ACM address:%08x\n", gFitTableContext.StartupAcm[Index].Address);

+      printf("ACM size:%08x\n", gFitTableContext.StartupAcm[Index].Size);

       if (gFitTableContext.StartupAcm[Index].Address != 0) {

+        printf("get AcmBuffer\n");

         AcmBuffer = 
FLASH_TO_MEMORY(gFitTableContext.StartupAcm[Index].Address, FdFileBuffer, 
FdFileSize);

         if ((AcmBuffer < FdFileBuffer) || (AcmBuffer + 
gFitTableContext.StartupAcm[Index].Size > FdFileBuffer + FdFileSize)) {

           printf ("ACM out of range - can not validate it\n");

@@ -3534,11 +3741,20 @@ Returns:
         }

 

         if (AcmBuffer != NULL) {

-          if (CheckAcm ((ACM_FORMAT *)AcmBuffer, 
gFitTableContext.StartupAcm[Index].Size)) {

-            DumpAcm ((ACM_FORMAT *)AcmBuffer);

-          } else {

-            Status = STATUS_ERROR;

-            goto exitFunc;

+          if (CheckAcm((ACM_FORMAT *)AcmBuffer, 
gFitTableContext.StartupAcm[Index].Size)) {

+            DumpAcm((ACM_FORMAT *)AcmBuffer);

+

+            if (gFitTableContext.StartupAcm[Index].Version >= 0x200) {

+              GetAcmFms((ACM_FORMAT *)AcmBuffer, 
&gFitTableContext.StartupAcm[Index].FMS, 
&gFitTableContext.StartupAcm[Index].FMSMask);

+              printf("ACM FMS:%08x\n", gFitTableContext.StartupAcm[Index].FMS);

+              printf("ACM FMS Mask:%08x\n", 
gFitTableContext.StartupAcm[Index].FMSMask);

+            }

+          }

+          else {

+            if (Index == 0) {

+              Status = STATUS_ERROR;

+              goto exitFunc;

+            }

           }

         }

       }

@@ -3592,32 +3808,31 @@ exitFunc:
   return Status;

 }

 

+/**

+  View function for FitGen.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings

+

+  @retval STATUS_SUCCESS  Utility exits successfully.

+  @retval STATUS_ERROR    Some error occurred during execution.

+**/

 STATUS

 FitView (

   IN INTN   argc,

   IN CHAR8  **argv

   )

-/*++

-

-Routine Description:

-

-  View function for FitGen.

-

-Arguments:

-

-  argc - Number of command line parameters.

-  argv - Array of pointers to parameter strings.

-

-Returns:

-  STATUS_SUCCESS - Utility exits successfully.

-  STATUS_ERROR   - Some error occurred during execution.

-

---*/

 {

-  UINT32                      FvRecoveryFileSize;

-  UINT8                       *FileBuffer;

-  UINT8                       *FileBufferRaw = NULL;

-  STATUS                      Status;

+  UINT32                        FvRecoveryFileSize;

+  UINT8                         *FileBuffer;

+  UINT8                         *FileBufferRaw = NULL;

+  STATUS                        Status;

+  FILE                          *FpIn;

+  UINT32                        FlashValidSig = 0;

+  UINT32                        Frba;

+  UINT32                        BiosRegionBaseOffset;

+  FLASH_MAP_0_REGISTER          FlashMap0;

+  FLASH_REGION_1_BIOS_REGISTER  FlashRegion1;

 

   //

   // Step 1: Read input file

@@ -3642,13 +3857,57 @@ Returns:
       gFitTableContext.FitTablePointerOffset = xtoi (argv[3 + 1]);

     } else {

       Error (NULL, 0, 0, "FIT offset not specified!", NULL);

+      Status = STATUS_ERROR;

       goto exitFunc;

     }

   } else {

     Error (NULL, 0, 0, "Invalid view option: ", "%s", argv[3]);

+    Status = STATUS_ERROR;

     goto exitFunc;

   }

 

+  //

+  //Check the File Path

+  //

+  if (!CheckPath (argv[2])) {

+    Error (NULL, 0, 0, "File path is invalid!", NULL);

+    Status = STATUS_ERROR;

+    goto exitFunc;

+  }

+  //

+  // Open the Input file

+  //

+  if ((FpIn = fopen (argv[2], "rb")) == NULL) {

+    Error (NULL, 0, 0, "Unable open the file!", NULL);

+    Status = STATUS_WARNING;

+    goto exitFunc;

+  }

+  //

+  //Seek and read the Flash Valid Signature;

+  //

+  fseek (FpIn, FLVALSIG_BASE_OFFSET, SEEK_SET);

+  fread (&FlashValidSig, 4, 1, FpIn);

+  if (FlashValidSig == FLASH_VALID_SIGNATURE) {

+    //

+    //Seek and read the Flash Map 0 Register;

+    //

+    fseek (FpIn, FLMAP0_BASE_OFFSET, SEEK_SET);

+    fread (&FlashMap0, 4, 1, FpIn);

+    Frba = FlashMap0.Frba << 4 & 0xFF0;  //FRBA identifies address bits [11:4] 
for the region portion of the flashdescriptor, bits [26:12] and bits [3:0] are 0

+    //

+    //Seek and read the Flash Region 1 (BIOS) Register;

+    //

+    BiosRegionBaseOffset = Frba + 0x4;

+    fseek (FpIn, BiosRegionBaseOffset, SEEK_SET);

+    fread (&FlashRegion1, 4, 1, FpIn);

+    FileBuffer = (UINT8 *)(FileBuffer + (FlashRegion1.RegionBase << 12));  // 
RegionBase specifies address bits [26:12] for the Region Base.

+    FvRecoveryFileSize = ((FlashRegion1.RegionLimit << 12 | 0xFFF) + 1) - 
(FlashRegion1.RegionBase << 12);  //RegionLimit specifies bits [26:12] of the 
ending address for this region, bits [11:0] are assumed to be FFFh.

+  }

+  //

+  // Close the Input file

+  //

+  fclose (FpIn);

+

   //

   // For debug

   //

@@ -3661,27 +3920,20 @@ exitFunc:
   return Status;

 }

 

+/**

+  Main function.

+

+  @param argc             Number of command line parameters.

+  @param argv             Array of pointers to parameter strings

+

+  @retval STATUS_SUCCESS  Utility exits successfully.

+  @retval STATUS_ERROR    Some error occurred during execution.

+**/

 int

 main (

   int   argc,

   char  **argv

   )

-/*++

-

-Routine Description:

-

-  Main function.

-

-Arguments:

-

-  argc - Number of command line parameters.

-  argv - Array of pointers to parameter strings.

-

-Returns:

-  STATUS_SUCCESS - Utility exits successfully.

-  STATUS_ERROR   - Some error occurred during execution.

-

---*/

 {

   SetUtilityName (UTILITY_NAME);

 

@@ -3703,24 +3955,18 @@ Returns:
     return STATUS_ERROR;

   }

 }

+/**

+  Convert hex string to uint

+

+  @param str          The string

 

+  @retval   Integer value

+

+**/

 unsigned int

 xtoi (

   char  *str

   )

-/*++

-

-Routine Description:

-

-  Convert hex string to uint

-

-Arguments:

-

-  str  -  The string

-

-Returns:

-

---*/

 {

   unsigned int u;

   char         c;

diff --git a/Silicon/Intel/Tools/FitGen/FitGen.h 
b/Silicon/Intel/Tools/FitGen/FitGen.h
index 511ab652ab..2d24ecb584 100644
--- a/Silicon/Intel/Tools/FitGen/FitGen.h
+++ b/Silicon/Intel/Tools/FitGen/FitGen.h
@@ -36,7 +36,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 

 #define FIT_SPEC_VERSION_MAJOR 1

 #define FIT_SPEC_VERSION_MINOR 4

-

 //

 // The minimum number of arguments accepted from the command line.

 //

@@ -50,4 +49,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 

 #define ROUNDUP(Size, Alignment) (((Size) + (Alignment) - 1) / (Alignment) * 
(Alignment))

 

+UINT32

+GetFvAcmSizeFromFd(

+IN UINT8                       *FdBuffer,

+IN UINT32                      FdFileSize

+);

+

 #endif

-- 
2.30.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#96525): https://edk2.groups.io/g/devel/message/96525
Mute This Topic: https://groups.io/mt/95067601/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to