Add support feature to covert MicroCode.txt to MicroCode.bin file into GenFw tool.
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 30 Jul 2007 05:24:42 +0000 (05:24 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 30 Jul 2007 05:24:42 +0000 (05:24 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@438 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/Common/FvLib.c
Source/C/Common/ParseInf.c
Source/C/GenFw/GenFw.c

index a208172..c2807e8 100644 (file)
@@ -390,6 +390,91 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+SearchSectionByType (\r
+  IN EFI_FILE_SECTION_POINTER  FirstSection,\r
+  IN UINT8                     *SearchEnd,\r
+  IN EFI_SECTION_TYPE          SectionType,\r
+  IN OUT UINTN                 *StartIndex,\r
+  IN UINTN                     Instance,\r
+  OUT EFI_FILE_SECTION_POINTER *Section\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Helper function to search a sequence of sections from the section pointed\r
+  by FirstSection to SearchEnd for the Instance-th section of type SectionType.\r
+  The current counter is saved in StartIndex and when the section is found, it's\r
+  saved in Section. GUID-defined sections, if special processing is not required,\r
+  are searched recursively in a depth-first manner.\r
+\r
+Arguments:\r
+\r
+  FirstSection The first section to start searching from.\r
+  SearchEnd    The end address to stop search.\r
+  SectionType  The type of section to search.\r
+  StartIndex   The current counter is saved.\r
+  Instance     The requested n-th section number.\r
+  Section      The found section returned.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             The function completed successfully.\r
+  EFI_NOT_FOUND           The section is not found.\r
+--*/\r
+{\r
+  EFI_FILE_SECTION_POINTER  CurrentSection;\r
+  EFI_FILE_SECTION_POINTER  InnerSection;\r
+  EFI_STATUS                Status;\r
+  UINTN                     SectionSize;\r
+\r
+  CurrentSection = FirstSection;\r
+\r
+  while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {\r
+    if (CurrentSection.CommonHeader->Type == SectionType) {\r
+      (*StartIndex)++;\r
+    }\r
+\r
+    if (*StartIndex == Instance) {\r
+      *Section = CurrentSection;\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // If the requesting section is not GUID-defined and\r
+    // we find a GUID-defined section that doesn't need\r
+    // special processing, go ahead to search the requesting\r
+    // section inside the GUID-defined section.\r
+    //\r
+    if (SectionType != EFI_SECTION_GUID_DEFINED &&\r
+        CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&\r
+        !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {\r
+      InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)\r
+        ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);\r
+      SectionSize = CurrentSection.CommonHeader->Size[0] +\r
+        (CurrentSection.CommonHeader->Size[1] << 8) + \r
+        (CurrentSection.CommonHeader->Size[2] << 16);\r
+      Status = SearchSectionByType (\r
+                 InnerSection,\r
+                 (UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),\r
+                 SectionType,\r
+                 StartIndex,\r
+                 Instance,\r
+                 Section\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+    //\r
+    // Find next section (including compensating for alignment issues.\r
+    //\r
+    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
 EFI_STATUS\r
 GetSectionByType (\r
   IN EFI_FFS_FILE_HEADER          *File,\r
@@ -403,7 +488,8 @@ Routine Description:
 \r
   Find a section in a file by type and instance.  An instance of 1 is the first \r
   instance.  The function will return NULL if a matching section cannot be found.\r
-  The function will not handle encapsulating sections.\r
+  GUID-defined sections, if special processing is not needed, are handled in a\r
+  depth-first manner.\r
 \r
 Arguments:\r
 \r
@@ -447,29 +533,28 @@ Returns:
   // Get the first section\r
   //\r
   CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));\r
-\r
+  \r
   //\r
-  // Loop as long as we have a valid file\r
+  // Depth-first manner to find section file.\r
   //\r
-  while ((UINTN) CurrentSection.CommonHeader < (UINTN) File + GetLength (File->Size)) {\r
-    if (CurrentSection.CommonHeader->Type == SectionType) {\r
-      SectionCount++;\r
-    }\r
+  Status = SearchSectionByType (\r
+             CurrentSection,\r
+             (UINT8 *) ((UINTN) File + GetLength (File->Size)),\r
+             SectionType,\r
+             &SectionCount,\r
+             Instance,\r
+             Section\r
+             );\r
 \r
-    if (SectionCount == Instance) {\r
-      *Section = CurrentSection;\r
-      return EFI_SUCCESS;\r
-    }\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  } else {\r
     //\r
-    // Find next section (including compensating for alignment issues.\r
+    // Section not found\r
     //\r
-    CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));\r
+    (*Section).Code16Section = NULL;\r
+    return EFI_NOT_FOUND;\r
   }\r
-  //\r
-  // Section not found\r
-  //\r
-  (*Section).Code16Section = NULL;\r
-  return EFI_NOT_FOUND;\r
 }\r
 //\r
 // will not parse compressed sections\r
index 6f5900e..5460abe 100644 (file)
@@ -465,12 +465,18 @@ Returns:
   UINT8   Index;\r
   UINT64  HexNumber;\r
   CHAR8   CurrentChar;\r
-\r
+  \r
   //\r
   // Initialize the result\r
   //\r
   HexNumber = 0;\r
-\r
+  \r
+  //\r
+  // Check input paramter\r
+  //\r
+  if (AsciiString == NULL || ReturnValue == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
   //\r
   // Add each character to the result\r
   //\r
@@ -518,7 +524,7 @@ Returns:
   }\r
 \r
   return EFI_SUCCESS;\r
-};\r
+}\r
 \r
 CHAR8 *\r
 ReadLineInStream (\r
index 036d688..53ef981 100644 (file)
@@ -73,12 +73,32 @@ UINT8 *InImageName;
 #define FW_BIN_IMAGE         4\r
 #define FW_ZERO_DEBUG_IMAGE  5\r
 #define FW_SET_STAMP_IMAGE   6\r
+#define FW_MCI_IMAGE         7\r
+#define FW_MERGE_IMAGE       8\r
 \r
 #define DUMP_TE_HEADER       0x11\r
 #define FW_REPLACE_IMAGE     0x100\r
 \r
\r
-#define MAX_STRING_LENGTH 100\r
+#define DEFAULT_MC_PAD_BYTE_VALUE  0xFF\r
+#define DEFAULT_MC_ALIGNMENT       16\r
+#define MAXIMUM_INPUT_FILE_NUM     10\r
+#define MAX_STRING_LENGTH          100\r
+\r
+//\r
+// Structure definition for a microcode header\r
+//\r
+typedef struct {\r
+  UINTN  HeaderVersion;\r
+  UINTN  PatchId;\r
+  UINTN  Date;\r
+  UINTN  CpuId;\r
+  UINTN  Checksum;\r
+  UINTN  LoaderVersion;\r
+  UINTN  PlatformId;\r
+  UINTN  DataSize;   // if 0, then TotalSize = 2048, and TotalSize field is invalid\r
+  UINTN  TotalSize;  // number of bytes\r
+  UINTN  Reserved[3];\r
+} MICROCODE_IMAGE_HEADER;\r
 \r
 STATIC\r
 EFI_STATUS\r
@@ -124,6 +144,10 @@ Usage (
         -b, --exe2bin\n\\r
         -r, --replace\n\\r
         -s, --stamp [time-data] <NOW|\"####-##-## ##:##:##\">\n\\r
+        -m, --mcifile\n\\r
+        -j, --join\n\\r
+        -a, --align <HEX|DEC>\n\\r
+        -p, --pad  [padvalue] <HEX|DEC>\n\\r
         -h, --help\n\\r
         -V, --version\n");\r
 }\r
@@ -892,6 +916,8 @@ Returns:
 --*/\r
 {\r
   UINT32            Type;\r
+  UINT32            InputFileNum;\r
+  CHAR8             **InputFileName;\r
   UINT8             *OutImageName;\r
   UINT8             *ModuleType;\r
   CHAR8             *TimeStamp;\r
@@ -900,12 +926,18 @@ Returns:
   FILE              *fpIn;\r
   FILE              *fpOut;\r
   FILE              *fpInOut;\r
+  UINTN             Data;\r
+  UINTN             *DataPointer;\r
+  UINTN             CheckSum;\r
   UINT32            Index;\r
   UINT32            Index1;\r
   UINT32            Index2;\r
-  UINTN             AllignedRelocSize;\r
+  UINT64            Temp64;\r
+  UINT32            MciAlignment;\r
+  UINT8             MciPadValue;\r
+  UINT32            AllignedRelocSize;\r
   UINT8             *FileBuffer;\r
-  UINT            FileLength;\r
+  UINT32            FileLength;\r
   RUNTIME_FUNCTION  *RuntimeFunction;\r
   UNWIND_INFO       *UnwindInfo;\r
   STATUS            Status;  \r
@@ -916,6 +948,7 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER32  *Optional32;\r
   EFI_IMAGE_OPTIONAL_HEADER64  *Optional64;\r
   EFI_IMAGE_DOS_HEADER         BackupDosHdr;\r
+  MICROCODE_IMAGE_HEADER       *MciHeader; \r
 \r
   fprintf (stdout, "GenFw tool start.\n");\r
 \r
@@ -924,6 +957,8 @@ Returns:
   //\r
   // Assign to fix compile warning\r
   //\r
+  InputFileNum      = 0; \r
+  InputFileName     = NULL;\r
   InImageName       = NULL;\r
   OutImageName      = NULL;\r
   ModuleType        = NULL;\r
@@ -935,6 +970,11 @@ Returns:
   fpOut             = NULL;\r
   fpInOut           = NULL;\r
   TimeStamp         = NULL;\r
+  MciAlignment      = DEFAULT_MC_ALIGNMENT;\r
+  MciPadValue       = DEFAULT_MC_PAD_BYTE_VALUE;\r
+  FileLength        = 0;\r
+  MciHeader         = NULL;\r
+  CheckSum          = 0;\r
 \r
   if (argc == 1) {\r
     Usage();\r
@@ -1022,45 +1062,101 @@ Returns:
       continue;\r
     }\r
 \r
-    InImageName = argv[0];\r
+    if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) {\r
+      OutImageType = FW_MCI_IMAGE;\r
+      argc --;\r
+      argv ++;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) {\r
+      OutImageType = FW_MERGE_IMAGE;\r
+      argc --;\r
+      argv ++;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {\r
+      if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {\r
+        Error (NULL, 0, 0, NULL, "Your input alginment is incorrect format.\n");\r
+        goto Finish;\r
+      }\r
+      MciAlignment = (UINT32) Temp64;\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) {\r
+      if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {\r
+        Error (NULL, 0, 0, NULL, "Incorrect format of PadValue\n");\r
+        goto Finish;\r
+      }\r
+      MciPadValue = (UINT8) Temp64;\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Get Input file name\r
+    //\r
+    if ((InputFileNum == 0) && (InputFileName == NULL)) {\r
+      InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
+      if (InputFileName == NULL) {\r
+        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
+    } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
+      //\r
+      // InputFileName buffer too small, need to realloc\r
+      //\r
+      InputFileName = (CHAR8 **) realloc (\r
+                                  InputFileName,\r
+                                  (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
+                                  );\r
+\r
+      if (InputFileName == NULL) {\r
+        Error (__FILE__, __LINE__, 0, "application error", "failed to allocate memory");\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
+    }\r
+\r
+    InputFileName [InputFileNum ++] = argv[0];\r
     argc --;\r
     argv ++;\r
   }\r
-  \r
+\r
   if (OutImageType == FW_DUMMY_IMAGE) {\r
     Error (NULL, 0, 0, NULL, "No action specified, such as -e, -c or -t\n");\r
-    return STATUS_ERROR;    \r
+    goto Finish;\r
   }\r
 \r
-\r
   //\r
-  // get InImageName from stdin\r
+  // check input files\r
   //\r
-  if (InImageName == NULL) {\r
-    fprintf (stdout, "Please describe input file name!!!\n");\r
-    fscanf (stdin, "%s", FileName);\r
-    InImageName = (UINT8 *) FileName;\r
+  if (InputFileNum == 0) {\r
+    Error (NULL, 0, 0, NULL, "No input files\n");\r
+    goto Finish;\r
   }\r
 \r
   //\r
-  // Open input file and read file data into file buffer.\r
+  // Combine MciBinary files to one file\r
   //\r
-  fpIn = fopen (InImageName, "rb");\r
-  if (!fpIn) {\r
-    Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
-    goto Finish;\r
-  }\r
-\r
-  FileLength = _filelength (fileno (fpIn));\r
-  FileBuffer = malloc (FileLength);\r
-  if (FileBuffer == NULL) {\r
-    Error (NULL, 0, 0, NULL, "can't allocate enough memory space");\r
-    fclose (fpIn);\r
+  if (OutImageType == (FW_MERGE_IMAGE | FW_REPLACE_IMAGE)) {\r
+    Error (NULL, 0, 0, NULL, "-r replace parameter can't be input together with -j merge files");\r
     goto Finish;\r
   }\r
+   \r
   \r
-  fread (FileBuffer, 1, FileLength, fpIn);\r
-  fclose (fpIn);\r
+  //\r
+  // One input file\r
+  //\r
+  InImageName = InputFileName [InputFileNum - 1];\r
 \r
   //\r
   // Open output file and Write image into the output file.\r
@@ -1097,6 +1193,192 @@ Returns:
     }\r
   }
 \r
+  //\r
+  // Combine MciBinary files to one file\r
+  //\r
+  if (OutImageType == FW_MERGE_IMAGE) {\r
+    for (Index = 0; Index < InputFileNum; Index ++) {\r
+      fpIn = fopen (InputFileName [Index], "rb");\r
+      if (!fpIn) {\r
+        Error (NULL, 0, 0, InputFileName [Index], "failed to open input file for reading");\r
+        goto Finish;\r
+      }\r
+    \r
+      FileLength = _filelength (fileno (fpIn));\r
+      FileBuffer = malloc (FileLength);\r
+      if (FileBuffer == NULL) {\r
+        Error (NULL, 0, 0, NULL, "can't allocate enough memory space");\r
+        fclose (fpIn);\r
+        goto Finish;\r
+      }\r
+      \r
+      fread (FileBuffer, 1, FileLength, fpIn);\r
+      fclose (fpIn);\r
+      //\r
+      // write input file to out file\r
+      //\r
+      fwrite (FileBuffer, 1, FileLength, fpOut);\r
+      //\r
+      // write pad value to out file.\r
+      //\r
+      while (FileLength ++ % MciAlignment != 0) {\r
+        fwrite (&MciPadValue, 1, 1, fpOut);\r
+      }\r
+      //\r
+      // free allcoated memory space\r
+      //\r
+      free (FileBuffer);\r
+    }\r
+    // \r
+    // Done successfully\r
+    //\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Conver MicroCode.txt file to MicroCode.bin file\r
+  //\r
+  if (OutImageType == FW_MCI_IMAGE) {\r
+    fpIn = fopen (InImageName, "r");\r
+    if (!fpIn) {\r
+      Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
+      goto Finish;\r
+    }\r
+    \r
+    //\r
+    // The first pass is to determine \r
+    // how much data is in the file so we can allocate a working buffer. \r
+    //\r
+    FileLength = 0;\r
+    do {\r
+      Status = MicrocodeReadData (fpIn, &Data);\r
+      if (Status == STATUS_SUCCESS) {\r
+        FileLength += sizeof (Data);\r
+      }\r
+    } while (Status == STATUS_SUCCESS);\r
+\r
+    //\r
+    // Error if no data.\r
+    //\r
+    if (FileLength == 0) {\r
+      Error (NULL, 0, 0, InImageName, "no parse-able data found in file");\r
+      goto Finish;\r
+    }\r
+    if (FileLength < sizeof (MICROCODE_IMAGE_HEADER)) {\r
+      Error (NULL, 0, 0, InImageName, "amount of parse-able data is insufficient to contain a microcode header");\r
+      goto Finish;\r
+    }\r
+\r
+    //\r
+    // Allocate a buffer for the data\r
+    //\r
+    FileBuffer = malloc (FileLength);\r
+    if (FileBuffer == NULL) {\r
+      Error (NULL, 0, 0, NULL, "can't allocate enough memory space");\r
+      goto Finish;\r
+    }\r
+    //\r
+    // Re-read the file, storing the data into our buffer\r
+    //\r
+    fseek (fpIn, 0, SEEK_SET);\r
+    DataPointer = (UINTN *) FileBuffer;\r
+    do {\r
+      Status = MicrocodeReadData (fpIn, DataPointer++);\r
+    } while (Status == STATUS_SUCCESS);\r
+    //\r
+    // close input file after read data\r
+    //\r
+    fclose (fpIn);\r
+\r
+    //\r
+    // Can't do much checking on the header because, per the spec, the\r
+    // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,\r
+    // and the TotalSize field is invalid (actually missing). Thus we can't\r
+    // even verify the Reserved fields are 0.\r
+    //\r
+    MciHeader = (MICROCODE_IMAGE_HEADER *) FileBuffer;\r
+    if (MciHeader->DataSize == 0) {\r
+      Index = 2048;\r
+    } else {\r
+      Index = MciHeader->TotalSize;\r
+    }\r
+\r
+    if (Index != FileLength) {\r
+      Error (NULL, 0, 0, InImageName, "file contents do not contain expected TotalSize 0x%04X", Index);\r
+      goto Finish;\r
+    }\r
+\r
+    //\r
+    // Checksum the contents\r
+    //\r
+    DataPointer = (UINTN *) FileBuffer;\r
+    CheckSum  = 0;\r
+    Index     = 0;\r
+    while (Index < FileLength) {\r
+      CheckSum    += *DataPointer;\r
+      DataPointer ++;\r
+      Index       += sizeof (UINTN);\r
+    }\r
+    if (CheckSum != 0) {\r
+      Error (NULL, 0, 0, InImageName, "checksum failed on file contents");\r
+      goto Finish;\r
+    }\r
+    //\r
+    // Open the output file and write the buffer contents\r
+    //\r
+    if (fwrite (FileBuffer, FileLength, 1, fpOut) != 1) {\r
+      Error (NULL, 0, 0, OutImageName, "failed to write microcode data to output file");\r
+      goto Finish;\r
+    }\r
+    //\r
+    //  Convert Mci.TXT to Mci.bin file successfully\r
+    //\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Open input file and read file data into file buffer.\r
+  //\r
+  fpIn = fopen (InImageName, "rb");\r
+  if (!fpIn) {\r
+    Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
+    goto Finish;\r
+  }\r
+\r
+  FileLength = _filelength (fileno (fpIn));\r
+  FileBuffer = malloc (FileLength);\r
+  if (FileBuffer == NULL) {\r
+    Error (NULL, 0, 0, NULL, "can't allocate enough memory space");\r
+    fclose (fpIn);\r
+    goto Finish;\r
+  }\r
+  \r
+  fread (FileBuffer, 1, FileLength, fpIn);\r
+  fclose (fpIn);\r
\r
+  //\r
+  // Dump TeImage Header into output file.\r
+  //\r
+  if (OutImageType == DUMP_TE_HEADER) {\r
+    memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));\r
+    if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+      Error (NULL, 0, 0, InImageName, "TE header signature is not correct");\r
+      goto Finish;      \r
+    }\r
+    fprintf (fpOut, "Dump of file %s\n\n", InImageName);\r
+    fprintf (fpOut, "TE IMAGE HEADER VALUES\n");\r
+    fprintf (fpOut, "%17X machine\n", TEImageHeader.Machine);\r
+    fprintf (fpOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);\r
+    fprintf (fpOut, "%17X subsystems\n", TEImageHeader.Subsystem);\r
+    fprintf (fpOut, "%17X stripped size\n", TEImageHeader.StrippedSize);\r
+    fprintf (fpOut, "%17X entry point\n", TEImageHeader.AddressOfEntryPoint);\r
+    fprintf (fpOut, "%17X base of code\n", TEImageHeader.BaseOfCode);\r
+    fprintf (fpOut, "%17X image base\n", TEImageHeader.ImageBase);\r
+    fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", TEImageHeader.DataDirectory[0].VirtualAddress, TEImageHeader.DataDirectory[0].Size);\r
+    fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", TEImageHeader.DataDirectory[1].VirtualAddress, TEImageHeader.DataDirectory[1].Size);\r
+    goto Finish;\r
+  }\r
+\r
   //\r
   // Following code to convert dll to efi image or te image.\r
   // Get new image type\r
@@ -1146,29 +1428,6 @@ Returns:
       }\r
     }\r
   }\r
\r
-  //\r
-  // Dump TeImage Header into output file.\r
-  //\r
-  if (OutImageType == DUMP_TE_HEADER) {\r
-    memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));\r
-    if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
-      Error (NULL, 0, 0, InImageName, "TE header signature is not correct");\r
-      goto Finish;      \r
-    }\r
-    fprintf (fpOut, "Dump of file %s\n\n", InImageName);\r
-    fprintf (fpOut, "TE IMAGE HEADER VALUES\n");\r
-    fprintf (fpOut, "%17X machine\n", TEImageHeader.Machine);\r
-    fprintf (fpOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);\r
-    fprintf (fpOut, "%17X subsystems\n", TEImageHeader.Subsystem);\r
-    fprintf (fpOut, "%17X stripped size\n", TEImageHeader.StrippedSize);\r
-    fprintf (fpOut, "%17X entry point\n", TEImageHeader.AddressOfEntryPoint);\r
-    fprintf (fpOut, "%17X base of code\n", TEImageHeader.BaseOfCode);\r
-    fprintf (fpOut, "%17X image base\n", TEImageHeader.ImageBase);\r
-    fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", TEImageHeader.DataDirectory[0].VirtualAddress, TEImageHeader.DataDirectory[0].Size);\r
-    fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", TEImageHeader.DataDirectory[1].VirtualAddress, TEImageHeader.DataDirectory[1].Size);\r
-    goto Finish;\r
-  }\r
 \r
   //\r
   // Convert EFL image to PeImage\r
@@ -1513,6 +1772,10 @@ Finish:
   if (FileBuffer != NULL) {\r
     free (FileBuffer);\r
   }\r
+  \r
+  if (InputFileName != NULL) {\r
+    free (InputFileName);\r
+  }\r
 \r
   if (fpOut != NULL) {\r
     //\r
@@ -1782,4 +2045,68 @@ SetStamp (
   }\r
   \r
   return EFI_SUCCESS;\r
-}
\ No newline at end of file
+}\r
+\r
+STATIC\r
+STATUS\r
+MicrocodeReadData (\r
+  FILE          *InFptr,\r
+  UINTN         *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Read a 32-bit microcode data value from a text file and convert to raw binary form.\r
+\r
+Arguments:\r
+  InFptr    - file pointer to input text file\r
+  Data      - pointer to where to return the data parsed\r
+\r
+Returns:\r
+  STATUS_SUCCESS    - no errors or warnings, Data contains valid information\r
+  STATUS_ERROR      - errors were encountered\r
+\r
+--*/\r
+{\r
+  CHAR8  Line[MAX_LINE_LEN];\r
+  CHAR8  *cptr;\r
+\r
+  Line[MAX_LINE_LEN - 1]  = 0;\r
+  *Data                   = 0;\r
+  if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+  //\r
+  // If it was a binary file, then it may have overwritten our null terminator\r
+  //\r
+  if (Line[MAX_LINE_LEN - 1] != 0) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Look for\r
+  // dd 000000001h ; comment\r
+  // dd XXXXXXXX\r
+  // DD  XXXXXXXXX\r
+  //  DD XXXXXXXXX\r
+  //\r
+  for (cptr = Line; *cptr && isspace(*cptr); cptr++) {\r
+  }\r
+\r
+  if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {\r
+    //\r
+    // Skip blanks and look for a hex digit\r
+    //\r
+    cptr += 3;\r
+    for (; *cptr && isspace(*cptr); cptr++) {\r
+    }\r
+    if (isxdigit (*cptr)) {\r
+      if (sscanf (cptr, "%X", Data) != 1) {\r
+        return STATUS_ERROR;\r
+      }\r
+    }\r
+    return STATUS_SUCCESS;\r
+  }\r
+\r
+  return STATUS_ERROR;\r
+}\r