public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file
@ 2017-11-29 14:02 Yonghong Zhu
  2017-11-29 14:02 ` [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile Yonghong Zhu
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Yonghong Zhu @ 2017-11-29 14:02 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

V3: add a new build option --genfds-multi-thread for this feature, default is
False.

These patches enable multiple thread to generate ffs file by merge FFS file's
generation into Make phase.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>

Yonghong Zhu (4):
  BaseTools: GenFfs support to get alignment value from SectionFile
  BaseTools: Update Trim to generate VfrBinOffset Binary
  BaseTools: Update Gensec to set PROCESSING_REQUIRED value
  BaseTools: Update Makefile to support FFS file generation

 BaseTools/Source/C/GenFfs/GenFfs.c                 | 135 +++++++++++++-
 BaseTools/Source/C/GenSec/GenSec.c                 |  74 ++++++++
 BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
 BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
 BaseTools/Source/Python/Common/GlobalData.py       |   1 +
 BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
 BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
 BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
 BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
 BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
 BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
 BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
 BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202 ++++++++++++---------
 BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
 BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
 BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
 .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174 ++++++++++++++----
 BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++--------
 .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
 .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
 BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
 BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
 BaseTools/Source/Python/GenFds/Section.py          |   4 +-
 BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
 BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
 BaseTools/Source/Python/Trim/Trim.py               |  81 ++++++++-
 BaseTools/Source/Python/build/build.py             |  48 ++++-
 27 files changed, 1077 insertions(+), 417 deletions(-)

-- 
2.6.1.windows.1



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

* [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile
  2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
@ 2017-11-29 14:02 ` Yonghong Zhu
  2017-11-29 14:02 ` [Patch 2/4 V3] BaseTools: Update Trim to generate VfrBinOffset Binary Yonghong Zhu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Yonghong Zhu @ 2017-11-29 14:02 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Update GenFfs tool to get alignment value from SectionFile when use
the new option -n 0.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
 BaseTools/Source/C/GenFfs/GenFfs.c | 135 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 132 insertions(+), 3 deletions(-)

diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c
index cb16f38..e2fb3e0 100644
--- a/BaseTools/Source/C/GenFfs/GenFfs.c
+++ b/BaseTools/Source/C/GenFfs/GenFfs.c
@@ -10,10 +10,17 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 
 **/
 
+#ifndef __GNUC__
+#include <windows.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <Common/UefiBaseTypes.h>
@@ -22,10 +29,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/FfsSectionAlignmentPadding.h>
 
 #include "CommonLib.h"
 #include "ParseInf.h"
 #include "EfiUtilityMsgs.h"
+#include "FvLib.h"
+#include "PeCoffLib.h"
 
 #define UTILITY_NAME            "GenFfs"
 #define UTILITY_MAJOR_VERSION   0
 #define UTILITY_MINOR_VERSION   1
 
@@ -151,12 +160,14 @@ Returns:
                         128K,256K,512K,1M,2M,4M,8M,16M\n");
   fprintf (stdout, "  -i SectionFile, --sectionfile SectionFile\n\
                         Section file will be contained in this FFS file.\n");
   fprintf (stdout, "  -n SectionAlign, --sectionalign SectionAlign\n\
                         SectionAlign points to section alignment, which support\n\
-                        the alignment scope 1~16M. It is specified together\n\
-                        with sectionfile to point its alignment in FFS file.\n");
+                        the alignment scope 0~16M. If SectionAlign is specified\n\
+                        as 0, tool get alignment value from SectionFile. It is\n\
+                        specified together with sectionfile to point its\n\
+                        alignment in FFS file.\n");
   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
   fprintf (stdout, "  --version             Show program's version number and exit.\n");
   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
@@ -455,10 +466,106 @@ Returns:
     *BufferLength = Size;
     return EFI_SUCCESS;
   }
 }
 
+EFI_STATUS
+FfsRebaseImageRead (
+    IN      VOID    *FileHandle,
+    IN      UINTN   FileOffset,
+    IN OUT  UINT32  *ReadSize,
+    OUT     VOID    *Buffer
+    )
+  /*++
+
+    Routine Description:
+
+    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+    Arguments:
+
+   FileHandle - The handle to the PE/COFF file
+
+   FileOffset - The offset, in bytes, into the file to read
+
+   ReadSize   - The number of bytes to read from the file starting at FileOffset
+
+   Buffer     - A pointer to the buffer to read the data into.
+
+   Returns:
+
+   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+   --*/
+{
+  CHAR8   *Destination8;
+  CHAR8   *Source8;
+  UINT32  Length;
+
+  Destination8  = Buffer;
+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+  Length        = *ReadSize;
+  while (Length--) {
+    *(Destination8++) = *(Source8++);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
+  /*++
+    InFile is input file for getting alignment
+    return the alignment
+    --*/
+{
+  FILE                           *InFileHandle;
+  UINT8                          *PeFileBuffer;
+  UINTN                          PeFileSize;
+  UINT32                         CurSecHdrSize;
+  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
+  EFI_COMMON_SECTION_HEADER      *CommonHeader;
+  EFI_STATUS                     Status;
+
+  InFileHandle        = NULL;
+  PeFileBuffer        = NULL;
+
+  memset (&ImageContext, 0, sizeof (ImageContext));
+
+  InFileHandle = fopen(LongFilePath(InFile), "rb");
+  if (InFileHandle == NULL){
+    Error (NULL, 0, 0001, "Error opening file", InFile);
+    return EFI_ABORTED;
+  }
+  PeFileSize = _filelength (fileno(InFileHandle));
+  PeFileBuffer = (UINT8 *) malloc (PeFileSize);
+  if (PeFileBuffer == NULL) {
+    fclose (InFileHandle);
+    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated  of %s", InFileHandle);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
+  fclose (InFileHandle);
+  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
+  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
+  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
+  Status               = PeCoffLoaderGetImageInfo(&ImageContext);
+  if (EFI_ERROR (Status)) {
+    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
+    return Status;
+   }
+  *Alignment = ImageContext.SectionAlignment;
+  // Free the allocated memory resource
+  if (PeFileBuffer != NULL) {
+    free (PeFileBuffer);
+    PeFileBuffer = NULL;
+  }
+  return EFI_SUCCESS;
+}
+
 int
 main (
   int   argc,
   CHAR8 *argv[]
   )
@@ -495,10 +602,12 @@ Returns:
   FILE                    *FfsFile;
   UINT32                  Index;
   UINT64                  LogLevel;
   UINT8                   PeSectionNum;
   UINT32                  HeaderSize;
+  UINT32                  Alignment;
+  CHAR8                   AlignmentBuffer[8];
   
   //
   // Init local variables
   //
   LogLevel       = 0;
@@ -688,11 +797,31 @@ Returns:
       
       //
       // Section File alignment requirement
       //
       if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--sectionalign") == 0)) {
-        Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));
+        if ((argv[1] != NULL) && (stricmp("0", argv[1]) == 0)) {
+          Status = GetAlignmentFromFile(InputFileName[InputFileNum], &Alignment);
+          if (EFI_ERROR(Status)) {
+            Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);
+            goto Finish;
+          }
+          if (Alignment < 0x400){
+            sprintf (AlignmentBuffer, "%d", Alignment);
+          }
+          else if (Alignment >= 0x400) {
+            if (Alignment >= 0x100000) {
+              sprintf (AlignmentBuffer, "%dM", Alignment/0x100000);
+            } else {
+              sprintf (AlignmentBuffer, "%dK", Alignment/0x400);
+            }
+          }
+          Status = StringtoAlignment (AlignmentBuffer, &(InputFileAlign[InputFileNum]));
+        }
+        else {
+          Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileNum]));
+        }
         if (EFI_ERROR (Status)) {
           Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
           goto Finish;
         }
         argc -= 2;
-- 
2.6.1.windows.1



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

* [Patch 2/4 V3] BaseTools: Update Trim to generate VfrBinOffset Binary
  2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
  2017-11-29 14:02 ` [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile Yonghong Zhu
@ 2017-11-29 14:02 ` Yonghong Zhu
  2017-11-29 14:02 ` [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value Yonghong Zhu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Yonghong Zhu @ 2017-11-29 14:02 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Its usage is
"Trim --Vfr-Uni-Offset -o $(OUTPUT_DIR)(+)$(MODULE_NAME)VfrOffset.sec
--ModuleName=$(MODULE_NAME) --DebugDir=$(DEBUG_DIR)"

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/Trim/Trim.py | 81 ++++++++++++++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 3 deletions(-)

diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py
index 9ccc027..d1e40b0 100644
--- a/BaseTools/Source/Python/Trim/Trim.py
+++ b/BaseTools/Source/Python/Trim/Trim.py
@@ -1,9 +1,9 @@
 ## @file
 # Trim files preprocessed by compiler
 #
-# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD License
 # which accompanies this distribution.  The full text of the license may be found at
 # http://opensource.org/licenses/bsd-license.php
 #
@@ -15,10 +15,11 @@
 # Import Modules
 #
 import Common.LongFilePathOs as os
 import sys
 import re
+import StringIO
 
 from optparse import OptionParser
 from optparse import make_option
 from Common.BuildToolError import *
 from Common.Misc import *
@@ -27,11 +28,11 @@ import Common.EdkLogger as EdkLogger
 from Common.LongFilePathSupport import OpenLongFilePath as open
 
 # Version and Copyright
 __version_number__ = ("0.10" + " " + gBUILD_VERSION)
 __version__ = "%prog Version " + __version_number__
-__copyright__ = "Copyright (c) 2007-2016, Intel Corporation. All rights reserved."
+__copyright__ = "Copyright (c) 2007-2017, Intel Corporation. All rights reserved."
 
 ## Regular expression for matching Line Control directive like "#line xxx"
 gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')
 ## Regular expression for matching "typedef struct"
 gTypedefPattern = re.compile("^\s*typedef\s+struct(\s+\w+)?\s*[{]*$", re.MULTILINE)
@@ -428,10 +429,72 @@ def TrimAslFile(Source, Target, IncludePathFile):
         EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)
 
     f.writelines(Lines)
     f.close()
 
+def GenerateVfrBinSec(ModuleName, DebugDir, OutputFile):
+    VfrNameList = []
+    if os.path.isdir(DebugDir):
+        for CurrentDir, Dirs, Files in os.walk(DebugDir):
+            for FileName in Files:
+                Name, Ext = os.path.splitext(FileName)
+                if Ext == '.lst':
+                    VfrNameList.append (Name + 'Bin')
+
+    VfrNameList.append (ModuleName + 'Strings')
+
+    EfiFileName = os.path.join(DebugDir, ModuleName + '.efi')
+    MapFileName = os.path.join(DebugDir, ModuleName + '.map')
+    VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList)
+
+    if not VfrUniOffsetList:
+        return
+
+    try:
+        fInputfile = open(OutputFile, "wb+", 0)
+    except:
+        EdkLogger.error("Trim", FILE_OPEN_FAILURE, "File open failed for %s" %OutputFile, None)
+
+    # Use a instance of StringIO to cache data
+    fStringIO = StringIO.StringIO('')
+
+    for Item in VfrUniOffsetList:
+        if (Item[0].find("Strings") != -1):
+            #
+            # UNI offset in image.
+            # GUID + Offset
+            # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
+            #
+            UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
+            UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
+            fStringIO.write(''.join(UniGuid))
+            UniValue = pack ('Q', int (Item[1], 16))
+            fStringIO.write (UniValue)
+        else:
+            #
+            # VFR binary offset in image.
+            # GUID + Offset
+            # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
+            #
+            VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
+            VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
+            fStringIO.write(''.join(VfrGuid))
+            type (Item[1])
+            VfrValue = pack ('Q', int (Item[1], 16))
+            fStringIO.write (VfrValue)
+
+    #
+    # write data into file.
+    #
+    try :
+        fInputfile.write (fStringIO.getvalue())
+    except:
+        EdkLogger.error("Trim", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %OutputFile, None)
+
+    fStringIO.close ()
+    fInputfile.close ()
+
 ## Trim EDK source code file(s)
 #
 #
 # @param  Source    File or directory to be trimmed
 # @param  Target    File or directory to store the trimmed content
@@ -533,10 +596,12 @@ def Options():
     OptionList = [
         make_option("-s", "--source-code", dest="FileType", const="SourceCode", action="store_const",
                           help="The input file is preprocessed source code, including C or assembly code"),
         make_option("-r", "--vfr-file", dest="FileType", const="Vfr", action="store_const",
                           help="The input file is preprocessed VFR file"),
+        make_option("--Vfr-Uni-Offset", dest="FileType", const="VfrOffsetBin", action="store_const",
+                          help="The input file is EFI image"),
         make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const",
                           help="The input file is ASL file"),
         make_option("-8", "--Edk-source-code", dest="FileType", const="EdkSourceCode", action="store_const",
                           help="The input file is source code for Edk to be trimmed for ECP"),
 
@@ -547,30 +612,38 @@ def Options():
                           help="Remove postfix of long number"),
         make_option("-i", "--include-path-file", dest="IncludePathFile",
                           help="The input file is include path list to search for ASL include file"),
         make_option("-o", "--output", dest="OutputFile",
                           help="File to store the trimmed content"),
+        make_option("--ModuleName", dest="ModuleName", help="The module's BASE_NAME"),
+        make_option("--DebugDir", dest="DebugDir",
+                          help="Debug Output directory to store the output files"),
         make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,
                           help="Run verbosely"),
         make_option("-d", "--debug", dest="LogLevel", type="int",
                           help="Run with debug information"),
         make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,
                           help="Run quietly"),
         make_option("-?", action="help", help="show this help message and exit"),
     ]
 
     # use clearer usage to override default usage message
-    UsageString = "%prog [-s|-r|-a] [-c] [-v|-d <debug_level>|-q] [-i <include_path_file>] [-o <output_file>] <input_file>"
+    UsageString = "%prog [-s|-r|-a|--Vfr-Uni-Offset] [-c] [-v|-d <debug_level>|-q] [-i <include_path_file>] [-o <output_file>] [--ModuleName <ModuleName>] [--DebugDir <DebugDir>] [<input_file>]"
 
     Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)
     Parser.set_defaults(FileType="Vfr")
     Parser.set_defaults(ConvertHex=False)
     Parser.set_defaults(LogLevel=EdkLogger.INFO)
 
     Options, Args = Parser.parse_args()
 
     # error check
+    if Options.FileType == 'VfrOffsetBin':
+        if len(Args) == 0:
+            return Options, ''
+        elif len(Args) > 1:
+            EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())
     if len(Args) == 0:
         EdkLogger.error("Trim", OPTION_MISSING, ExtraData=Parser.get_usage())
     if len(Args) > 1:
         EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())
 
@@ -606,10 +679,12 @@ def Main():
             if CommandOptions.OutputFile == None:
                 CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
             TrimAslFile(InputFile, CommandOptions.OutputFile, CommandOptions.IncludePathFile)
         elif CommandOptions.FileType == "EdkSourceCode":
             TrimEdkSources(InputFile, CommandOptions.OutputFile)
+        elif CommandOptions.FileType == "VfrOffsetBin":
+            GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile)
         else :
             if CommandOptions.OutputFile == None:
                 CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
             TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex, CommandOptions.TrimLong)
     except FatalError, X:
-- 
2.6.1.windows.1



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

* [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value
  2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
  2017-11-29 14:02 ` [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile Yonghong Zhu
  2017-11-29 14:02 ` [Patch 2/4 V3] BaseTools: Update Trim to generate VfrBinOffset Binary Yonghong Zhu
@ 2017-11-29 14:02 ` Yonghong Zhu
  2017-12-05 11:53   ` Leif Lindholm
  2017-11-29 14:02 ` [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation Yonghong Zhu
  2017-12-01  6:13 ` [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Gao, Liming
  4 siblings, 1 reply; 11+ messages in thread
From: Yonghong Zhu @ 2017-11-29 14:02 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Yunhua Feng

This patch add new option --dummy file, and we compare the dummpy file
with input file to decide whether we need to set PROCESSING_REQUIRED
value.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
---
 BaseTools/Source/C/GenSec/GenSec.c | 74 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
index d9cdc1f..904926c 100644
--- a/BaseTools/Source/C/GenSec/GenSec.c
+++ b/BaseTools/Source/C/GenSec/GenSec.c
@@ -185,10 +185,13 @@ Returns:
                         used in Ver section.\n");
   fprintf (stdout, "  --sectionalign SectionAlign\n\
                         SectionAlign points to section alignment, which support\n\
                         the alignment scope 1~16M. It is specified in same\n\
                         order that the section file is input.\n");
+  fprintf (stdout, "  --dummy dummyfile\n\
+                        compare dummpyfile with input_file to decide whether\n\
+                        need to set PROCESSING_REQUIRED attribute.\n");
   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
   fprintf (stdout, "  --version             Show program's version number and exit.\n");
   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
@@ -1026,10 +1029,17 @@ Returns:
   EFI_STATUS                Status;
   UINT64                    LogLevel;
   UINT32                    *InputFileAlign;
   UINT32                    InputFileAlignNum;
   EFI_COMMON_SECTION_HEADER *SectionHeader;
+  CHAR8                     *DummyFileName;
+  FILE                      *DummyFile;
+  UINTN                     DummyFileSize;
+  UINT8                     *DummyFileBuffer;
+  FILE                      *InFile;
+  UINT8                     *InFileBuffer;
+  UINTN                     InFileSize;
 
   InputFileAlign        = NULL;
   InputFileAlignNum     = 0;
   InputFileName         = NULL;
   OutputFileName        = NULL;
@@ -1047,10 +1057,17 @@ Returns:
   Status                = STATUS_SUCCESS;
   LogLevel              = 0;
   SectGuidHeaderLength  = 0;
   VersionSect           = NULL;
   UiSect                = NULL;
+  DummyFileSize         = 0;
+  DummyFileName         = NULL;
+  DummyFile             = NULL;
+  DummyFileBuffer       = NULL;
+  InFile                = NULL;
+  InFileSize            = 0;
+  InFileBuffer          = NULL;
   
   SetUtilityName (UTILITY_NAME);
   
   if (argc == 1) {
     Error (NULL, 0, 1001, "Missing options", "No options input");
@@ -1117,10 +1134,20 @@ Returns:
       }
       argc -= 2;
       argv += 2;
       continue;
     }
+    if (stricmp (argv[0], "--dummy") == 0) {
+      DummyFileName = argv[1];
+      if (DummyFileName == NULL) {
+        Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");
+        goto Finish;
+      }
+      argc -= 2;
+      argv += 2;
+      continue;
+    }
 
     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {
       if (argv[1] == NULL) {
         Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
         goto Finish;
@@ -1290,10 +1317,57 @@ Returns:
     goto Finish;
   }
 
   VerboseMsg ("%s tool start.", UTILITY_NAME);
 
+  if (DummyFileName != NULL) {
+      //
+      // Open file and read contents
+      //
+      DummyFile = fopen (LongFilePath (DummyFileName), "rb");
+      if (DummyFile == NULL) {
+        Error (NULL, 0, 0001, "Error opening file", DummyFileName);
+        return EFI_ABORTED;
+      }
+
+      fseek (DummyFile, 0, SEEK_END);
+      DummyFileSize = ftell (DummyFile);
+      fseek (DummyFile, 0, SEEK_SET);
+      DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);
+      fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);
+      fclose(DummyFile);
+      DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);
+
+      InFile = fopen(LongFilePath(InputFileName[0]), "rb");
+      if (InFile == NULL) {
+        Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);
+        return EFI_ABORTED;
+      }
+
+      fseek (InFile, 0, SEEK_END);
+      InFileSize = ftell (InFile);
+      fseek (InFile, 0, SEEK_SET);
+      InFileBuffer = (UINT8 *) malloc (InFileSize);
+      fread(InFileBuffer, 1, InFileSize, InFile);
+      fclose(InFile);
+      DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);
+      if (InFileSize > DummyFileSize){
+        if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
+          SectGuidHeaderLength = InFileSize - DummyFileSize;
+        }
+      }
+      if (SectGuidHeaderLength == 0) {
+        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
+      }
+      if (DummyFileBuffer != NULL) {
+        free (DummyFileBuffer);
+      }
+      if (InFileBuffer != NULL) {
+        free (InFileBuffer);
+      }
+    }
+
   //
   // Parse all command line parameters to get the corresponding section type.
   //
   VerboseMsg ("Section type is %s", SectionName);
   if (SectionName == NULL) {
-- 
2.6.1.windows.1



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

* [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation
  2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
                   ` (2 preceding siblings ...)
  2017-11-29 14:02 ` [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value Yonghong Zhu
@ 2017-11-29 14:02 ` Yonghong Zhu
  2017-12-06 18:23   ` Leif Lindholm
  2017-12-01  6:13 ` [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Gao, Liming
  4 siblings, 1 reply; 11+ messages in thread
From: Yonghong Zhu @ 2017-11-29 14:02 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Yunhua Feng

Update Makefile to support FFS file generation with new build option
--genfds-multi-thread.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
 BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
 BaseTools/Source/Python/Common/GlobalData.py       |   1 +
 BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
 BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
 BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
 BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
 BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
 BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
 BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
 BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202 ++++++++++++---------
 BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
 BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
 BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
 .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174 ++++++++++++++----
 BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++--------
 .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
 .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
 BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
 BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
 BaseTools/Source/Python/GenFds/Section.py          |   4 +-
 BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
 BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
 BaseTools/Source/Python/build/build.py             |  48 ++++-
 24 files changed, 793 insertions(+), 411 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 008ad8e..1c4c395 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -1305,16 +1305,19 @@ class PlatformAutoGen(AutoGen):
     ## Create makefile for the platform and mdoules in it
     #
     #   @param      CreateModuleMakeFile    Flag indicating if the makefile for
     #                                       modules will be created as well
     #
-    def CreateMakeFile(self, CreateModuleMakeFile=False):
+    def CreateMakeFile(self, CreateModuleMakeFile=False, FfsCommand = {}):
         if CreateModuleMakeFile:
             for ModuleFile in self.Platform.Modules:
                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
                                    self.ToolChain, self.Arch, self.MetaFile)
-                Ma.CreateMakeFile(True)
+                if (ModuleFile.File, self.Arch) in FfsCommand:
+                    Ma.CreateMakeFile(True, FfsCommand[ModuleFile.File, self.Arch])
+                else:
+                    Ma.CreateMakeFile(True)
                 #Ma.CreateAsBuiltInf()
 
         # no need to create makefile for the platform more than once
         if self.IsMakeFileCreated:
             return
@@ -2758,10 +2761,11 @@ class ModuleAutoGen(AutoGen):
         self._CustomMakefile  = None
         self._Macro           = None
 
         self._BuildDir        = None
         self._OutputDir       = None
+        self._FfsOutputDir    = None
         self._DebugDir        = None
         self._MakeFileDir     = None
 
         self._IncludePathList = None
         self._IncludePathLength = 0
@@ -2874,10 +2878,11 @@ class ModuleAutoGen(AutoGen):
             self._Macro["PLATFORM_GUID"         ] = self.PlatformInfo.Guid
             self._Macro["PLATFORM_VERSION"      ] = self.PlatformInfo.Version
             self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir
             self._Macro["PLATFORM_DIR"          ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)
             self._Macro["PLATFORM_OUTPUT_DIR"   ] = self.PlatformInfo.OutputDir
+            self._Macro["FFS_OUTPUT_DIR"        ] = self.FfsOutputDir
         return self._Macro
 
     ## Return the module build data object
     def _GetModule(self):
         if self._Module == None:
@@ -2964,10 +2969,19 @@ class ModuleAutoGen(AutoGen):
         if self._OutputDir == None:
             self._OutputDir = path.join(self.BuildDir, "OUTPUT")
             CreateDirectory(self._OutputDir)
         return self._OutputDir
 
+    ## Return the directory to store ffs file
+    def _GetFfsOutputDir(self):
+        if self._FfsOutputDir == None:
+            if GlobalData.gFdfParser != None:
+                self._FfsOutputDir = path.join(self.PlatformInfo.BuildDir, "FV", "Ffs", self.Guid + self.Name)
+            else:
+                self._FfsOutputDir = ''
+        return self._FfsOutputDir
+
     ## Return the directory to store auto-gened source files of the mdoule
     def _GetDebugDir(self):
         if self._DebugDir == None:
             self._DebugDir = path.join(self.BuildDir, "DEBUG")
             CreateDirectory(self._DebugDir)
@@ -4220,18 +4234,18 @@ class ModuleAutoGen(AutoGen):
     ## Create makefile for the module and its dependent libraries
     #
     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
     #                                       dependent libraries will be created
     #
-    def CreateMakeFile(self, CreateLibraryMakeFile=True):
+    def CreateMakeFile(self, CreateLibraryMakeFile=True, GenFfsList = []):
         # Ignore generating makefile when it is a binary module
         if self.IsBinaryModule:
             return
 
         if self.IsMakeFileCreated:
             return
-
+        self.GenFfsList = GenFfsList
         if not self.IsLibrary and CreateLibraryMakeFile:
             for LibraryAutoGen in self.LibraryAutoGenList:
                 LibraryAutoGen.CreateMakeFile()
 
         if self.CanSkip():
@@ -4455,10 +4469,11 @@ class ModuleAutoGen(AutoGen):
 
     IsLibrary       = property(_IsLibrary)
     IsBinaryModule  = property(_IsBinaryModule)
     BuildDir        = property(_GetBuildDir)
     OutputDir       = property(_GetOutputDir)
+    FfsOutputDir    = property(_GetFfsOutputDir)
     DebugDir        = property(_GetDebugDir)
     MakeFileDir     = property(_GetMakeFileDir)
     CustomMakefile  = property(_GetCustomMakefile)
 
     IncludePathList = property(_GetIncludePathList)
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 942eb44..2abfdb3 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -141,10 +141,15 @@ class BuildFile(object):
     ## directory removal template
     _RD_TEMPLATE_ = {
         "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
         "gmake" :   "$(RD) %(dir)s"
     }
+    ## cp if exist
+    _CP_TEMPLATE_ = {
+        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
+        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
+    }
 
     _CD_TEMPLATE_ = {
         "nmake" :   'if exist %(dir)s cd %(dir)s',
         "gmake" :   "test -e %(dir)s && cd %(dir)s"
     }
@@ -209,10 +214,12 @@ class BuildFile(object):
         else:
             PathLength = len(Path)
             for MacroName in MacroDefinitions:
                 MacroValue = MacroDefinitions[MacroName]
                 MacroValueLength = len(MacroValue)
+                if MacroValueLength == 0:
+                    continue
                 if MacroValueLength <= PathLength and Path.startswith(MacroValue):
                     Path = "$(%s)%s" % (MacroName, Path[MacroValueLength:])
                     break
             return Path
 
@@ -248,10 +255,11 @@ MODULE_FILE = ${module_file}
 MODULE_FILE_BASE_NAME = ${module_file_base_name}
 BASE_NAME = $(MODULE_NAME)
 MODULE_RELATIVE_DIR = ${module_relative_directory}
 PACKAGE_RELATIVE_DIR = ${package_relative_directory}
 MODULE_DIR = ${module_dir}
+FFS_OUTPUT_DIR = ${ffs_output_directory}
 
 MODULE_ENTRY_POINT = ${module_entry_point}
 ARCH_ENTRY_POINT = ${arch_entry_point}
 IMAGE_ENTRY_POINT = ${image_entry_point}
 
@@ -439,10 +447,14 @@ cleanlib:
         self.Macros["DEBUG_DIR"       ] = self._AutoGenObject.Macros["DEBUG_DIR"]
         self.Macros["MODULE_BUILD_DIR"] = self._AutoGenObject.Macros["MODULE_BUILD_DIR"]
         self.Macros["BIN_DIR"         ] = self._AutoGenObject.Macros["BIN_DIR"]
         self.Macros["BUILD_DIR"       ] = self._AutoGenObject.Macros["BUILD_DIR"]
         self.Macros["WORKSPACE"       ] = self._AutoGenObject.Macros["WORKSPACE"]
+        self.Macros["FFS_OUTPUT_DIR"  ] = self._AutoGenObject.Macros["FFS_OUTPUT_DIR"]
+        self.GenFfsList                 = ModuleAutoGen.GenFfsList
+        self.MacroList = ['FFS_OUTPUT_DIR', 'MODULE_GUID', 'OUTPUT_DIR']
+        self.FfsOutputFileList = []
 
     # Compose a dict object containing information used to do replacement in template
     def _CreateTemplateDict(self):
         if self._FileType not in self._SEP_:
             EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
@@ -553,10 +565,11 @@ cleanlib:
         if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                             ExtraData="[%s]" % str(self._AutoGenObject))
 
         self.ProcessBuildTargetList()
+        self.ParserGenerateFfsCmd()
 
         # Generate macros used to represent input files
         FileMacroList = [] # macro name = file list
         for FileListMacro in self.FileListMacros:
             FileMacro = self._FILE_MACRO_TEMPLATE.Replace(
@@ -625,10 +638,11 @@ cleanlib:
             "platform_name"             : self.PlatformInfo.Name,
             "platform_guid"             : self.PlatformInfo.Guid,
             "platform_version"          : self.PlatformInfo.Version,
             "platform_relative_directory": self.PlatformInfo.SourceDir,
             "platform_output_directory" : self.PlatformInfo.OutputDir,
+            "ffs_output_directory"      : self._AutoGenObject.Macros["FFS_OUTPUT_DIR"],
             "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],
 
             "module_name"               : self._AutoGenObject.Name,
             "module_guid"               : self._AutoGenObject.Guid,
             "module_name_guid"          : self._AutoGenObject._GetUniqueBaseName(),
@@ -671,10 +685,83 @@ cleanlib:
             "backward_compatible_target": BcTargetList,
         }
 
         return MakefileTemplateDict
 
+    def ParserGenerateFfsCmd(self):
+        #Add Ffs cmd to self.BuildTargetList
+        OutputFile = ''
+        DepsFileList = []
+
+        for Cmd in self.GenFfsList:
+            if Cmd[2]:
+                for CopyCmd in Cmd[2]:
+                    Src, Dst = CopyCmd
+                    Src = self.ReplaceMacro(Src)
+                    Dst = self.ReplaceMacro(Dst)
+                    if Dst not in self.ResultFileList:
+                        self.ResultFileList.append('%s' % Dst)
+                    if '%s :' %(Dst) not in self.BuildTargetList:
+                        self.BuildTargetList.append("%s :" %(Dst))
+                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
+
+            FfsCmdList = Cmd[0]
+            for index, Str in enumerate(FfsCmdList):
+                if '-o' == Str:
+                    OutputFile = FfsCmdList[index + 1]
+                if '-i' == Str:
+                    if DepsFileList == []:
+                        DepsFileList = [FfsCmdList[index + 1]]
+                    else:
+                        DepsFileList.append(FfsCmdList[index + 1])
+            DepsFileString = ' '.join(DepsFileList).strip()
+            if DepsFileString == '':
+                continue
+            OutputFile = self.ReplaceMacro(OutputFile)
+            self.ResultFileList.append('%s' % OutputFile)
+            DepsFileString = self.ReplaceMacro(DepsFileString)
+            self.BuildTargetList.append('%s : %s' % (OutputFile, DepsFileString))
+            CmdString = ' '.join(FfsCmdList).strip()
+            CmdString = self.ReplaceMacro(CmdString)
+            self.BuildTargetList.append('\t%s' % CmdString)
+
+            self.ParseSecCmd(DepsFileList, Cmd[1])
+            for SecOutputFile, SecDepsFile, SecCmd in self.FfsOutputFileList :
+                self.BuildTargetList.append('%s : %s' % (self.ReplaceMacro(SecOutputFile), self.ReplaceMacro(SecDepsFile)))
+                self.BuildTargetList.append('\t%s' % self.ReplaceMacro(SecCmd))
+            self.FfsOutputFileList = []
+
+    def ParseSecCmd(self, OutputFileList, CmdTuple):
+        for OutputFile in OutputFileList:
+            for SecCmdStr in CmdTuple:
+                SecDepsFileList = []
+                SecCmdList = SecCmdStr.split()
+                CmdName = SecCmdList[0]
+                for index, CmdItem in enumerate(SecCmdList):
+                    if '-o' == CmdItem and OutputFile == SecCmdList[index + 1]:
+                        index = index + 1
+                        while index + 1 < len(SecCmdList):
+                            if not SecCmdList[index+1].startswith('-'):
+                                SecDepsFileList.append(SecCmdList[index + 1])
+                            index = index + 1
+                        if CmdName == 'Trim':
+                            SecDepsFileList.append(os.path.join('$(DEBUG_DIR)', os.path.basename(OutputFile).replace('offset', 'efi')))
+                        if OutputFile.endswith('.ui') or OutputFile.endswith('.ver'):
+                            SecDepsFileList.append(os.path.join('$(MODULE_DIR)','$(MODULE_FILE)'))
+                        self.FfsOutputFileList.append((OutputFile, ' '.join(SecDepsFileList), SecCmdStr))
+                        if len(SecDepsFileList) > 0:
+                            self.ParseSecCmd(SecDepsFileList, CmdTuple)
+                        break
+                    else:
+                        continue
+
+    def ReplaceMacro(self, str):
+        for Macro in self.MacroList:
+            if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:
+                str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')
+        return str
+
     def CommandExceedLimit(self):
         FlagDict = {
                     'CC'    :  { 'Macro' : '$(CC_FLAGS)',    'Value' : False},
                     'PP'    :  { 'Macro' : '$(PP_FLAGS)',    'Value' : False},
                     'APP'   :  { 'Macro' : '$(APP_FLAGS)',   'Value' : False},
@@ -1451,11 +1538,12 @@ class TopLevelMakefile(BuildFile):
         elif LogLevel == EdkLogger.QUIET:
             ExtraOption += " -q"
 
         if GlobalData.gCaseInsensitive:
             ExtraOption += " -c"
-
+        if GlobalData.gEnableGenfdsMultiThread:
+            ExtraOption += " --genfds-multi-thread"
         if GlobalData.gIgnoreSource:
             ExtraOption += " --ignore-sources"
 
         if GlobalData.BuildOptionPcd:
             for index, option in enumerate(GlobalData.gCommand):
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index e348e9a..8b7562d 100644
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -93,5 +93,6 @@ gUseHashCache = None
 gBinCacheDest = None
 gBinCacheSource = None
 gPlatformHash = None
 gPackageHash = {}
 gModuleHash = {}
+gEnableGenfdsMultiThread = False
diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py
index a2306d0..70e2e5a 100644
--- a/BaseTools/Source/Python/GenFds/AprioriSection.py
+++ b/BaseTools/Source/Python/GenFds/AprioriSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process APRIORI file data and generate PEI/DXE APRIORI file
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -45,11 +45,11 @@ class AprioriSection (AprioriSectionClassObject):
     #   @param  self        The object pointer
     #   @param  FvName      for whom apriori file generated
     #   @param  Dict        dictionary contains macro and its value
     #   @retval string      Generated file name
     #
-    def GenFfs (self, FvName, Dict = {}):
+    def GenFfs (self, FvName, Dict = {}, IsMakefile = False):
         DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
         PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6"
         Buffer = StringIO.StringIO('')
         AprioriFileGuid = DXE_GUID
         if self.AprioriType == "PEI":
@@ -64,10 +64,11 @@ class AprioriSection (AprioriSectionClassObject):
                                        AprioriFileGuid + FvName + '.Apri' )
         AprFfsFileName = os.path.join (OutputAprFilePath,\
                                     AprioriFileGuid + FvName + '.Ffs')
 
         Dict.update(self.DefineVarDict)
+        InfFileName = None
         for FfsObj in self.FfsList :
             Guid = ""
             if isinstance(FfsObj, FfsFileStatement.FileStatement):
                 Guid = FfsObj.NameGuid
             else:
@@ -108,11 +109,16 @@ class AprioriSection (AprioriSectionClassObject):
 
         SaveFileOnChange(OutputAprFileName, Buffer.getvalue())
 
         RawSectionFileName = os.path.join( OutputAprFilePath, \
                                        AprioriFileGuid + FvName + '.raw' )
-        GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW')
+        MakefilePath = None
+        if IsMakefile:
+            if not InfFileName:
+                return None
+            MakefilePath = InfFileName, Arch
+        GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile)
         GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName],
-                                         'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid)
+                                        'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath)
 
         return AprFfsFileName
 
diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py
index fac58d1..64ad275 100644
--- a/BaseTools/Source/Python/GenFds/CompressSection.py
+++ b/BaseTools/Source/Python/GenFds/CompressSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process compress section generation
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -51,25 +51,25 @@ class CompressSection (CompressSectionClassObject) :
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False):
 
         if FfsInf != None:
             self.CompType = FfsInf.__ExtendMacro__(self.CompType)
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
 
         SectFiles = tuple()
         Index = 0
         for Sect in self.SectionList:
             Index = Index + 1
             SecIndex = '%s.%d' %(SecNum, Index)
-            ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
+            ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
             if ReturnSectList != []:
                 for FileData in ReturnSectList:
-                   SectFiles += (FileData,)
+                    SectFiles += (FileData,)
 
 
         OutputFile = OutputPath + \
                      os.sep     + \
                      ModuleName + \
@@ -77,11 +77,11 @@ class CompressSection (CompressSectionClassObject) :
                      SecNum     + \
                      Ffs.SectionSuffix['COMPRESS']
         OutputFile = os.path.normpath(OutputFile)
 
         GenFdsGlobalVariable.GenerateSection(OutputFile, SectFiles, Section.Section.SectionType['COMPRESS'],
-                                             CompressionType=self.CompTypeDict[self.CompType])
+                                             CompressionType=self.CompTypeDict[self.CompType], IsMakefile=IsMakefile)
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
 
 
diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py
index 78c0af4..2d2975f 100644
--- a/BaseTools/Source/Python/GenFds/DataSection.py
+++ b/BaseTools/Source/Python/GenFds/DataSection.py
@@ -46,11 +46,11 @@ class DataSection (DataSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsFile != None:
             self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
@@ -67,14 +67,20 @@ class DataSection (DataSectionClassObject):
 
         """Copy Map file to Ffs output"""
         Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName)
         if Filename[(len(Filename)-4):] == '.efi':
             MapFile = Filename.replace('.efi', '.map')
-            if os.path.exists(MapFile):
-                CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
-                if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
-                    CopyLongFilePath(MapFile, CopyMapFile)
+            CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
+            if IsMakefile:
+                if GenFdsGlobalVariable.CopyList == []:
+                    GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
+                else:
+                    GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
+            else:
+                if os.path.exists(MapFile):
+                    if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
+                        CopyLongFilePath(MapFile, CopyMapFile)
 
         #Get PE Section alignment when align is set to AUTO
         if self.Alignment == 'Auto' and self.SecType in ('TE', 'PE32'):
             ImageObj = PeImageClass (Filename)
             if ImageObj.SectionAlignment < 0x400:
@@ -94,26 +100,27 @@ class DataSection (DataSectionClassObject):
             if not os.path.exists(FileBeforeStrip) or \
                 (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)):
                 CopyLongFilePath(self.SectFileName, FileBeforeStrip)
             StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
             GenFdsGlobalVariable.GenerateFirmwareImage(
-                                    StrippedFile,
-                                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
-                                    Strip=True
-                                    )
+                    StrippedFile,
+                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
+                    Strip=True,
+                    IsMakefile = IsMakefile
+                )
             self.SectFileName = StrippedFile
 
         if self.SecType == 'TE':
             TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
             GenFdsGlobalVariable.GenerateFirmwareImage(
-                                    TeFile,
-                                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
-                                    Type='te'
-                                    )
+                    TeFile,
+                    [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
+                    Type='te',
+                    IsMakefile = IsMakefile
+                )
             self.SectFileName = TeFile
 
         OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get(self.SecType))
         OutputFile = os.path.normpath(OutputFile)
-
-        GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType))
+        GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile)
         FileList = [OutputFile]
         return FileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py
index 8f78c0f..1992d2a 100644
--- a/BaseTools/Source/Python/GenFds/DepexSection.py
+++ b/BaseTools/Source/Python/GenFds/DepexSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process depex section generation
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -74,11 +74,11 @@ class DepexSection (DepexSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}, IsMakefile = False):
         
         if self.ExpressionProcessed == False:
             self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")
             ExpList = self.Expression.split()
             ExpGuidDict = {}
@@ -117,8 +117,8 @@ class DepexSection (DepexSectionClassObject):
         Depex.Generate(InputFile)
 
         OutputFile = os.path.join (OutputPath, ModuleName + 'SEC' + SecNum + '.dpx')
         OutputFile = os.path.normpath(OutputFile)
 
-        GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType))
+        GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType), IsMakefile=IsMakefile)
         FileList = [OutputFile]
         return FileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py
index 7da3c1e..7b3b717 100644
--- a/BaseTools/Source/Python/GenFds/EfiSection.py
+++ b/BaseTools/Source/Python/GenFds/EfiSection.py
@@ -51,11 +51,11 @@ class EfiSection (EfiSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name list, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) :
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False) :
         
         if self.FileName != None and self.FileName.startswith('PCD('):
             self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
         """Prepare the parameter of GenSection"""
         if FfsInf != None :
@@ -89,10 +89,12 @@ class EfiSection (EfiSectionClassObject):
 
             if not self.Optional:
                 FileList.append(Filename)
             elif os.path.exists(Filename):
                 FileList.append(Filename)
+            elif '.depex' in FfsInf.FinalTargetSuffixMap or FfsInf.Depex:
+                FileList.append(Filename)
         else:
             FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict)
             if IsSect :
                 return FileList, self.Alignment
 
@@ -117,12 +119,13 @@ class EfiSection (EfiSectionClassObject):
                     BuildNumTuple = tuple()
 
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                     #Ui=StringData, 
-                                                     Ver=BuildNum)
+                                                    #Ui=StringData,
+                                                    Ver=BuildNum,
+                                                    IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             elif FileList != []:
                 for File in FileList:
                     Index = Index + 1
@@ -133,12 +136,13 @@ class EfiSection (EfiSectionClassObject):
                     f.close()
                     BuildNum = VerString
                     if BuildNum != None and BuildNum != '':
                         BuildNumTuple = ('-j', BuildNum)
                     GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                         #Ui=VerString, 
-                                                         Ver=BuildNum)
+                                                        #Ui=VerString,
+                                                        Ver=BuildNum,
+                                                        IsMakefile=IsMakefile)
                     OutputFileList.append(OutputFile)
 
             else:
                 BuildNum = StringData
                 if BuildNum != None and BuildNum != '':
@@ -155,12 +159,13 @@ class EfiSection (EfiSectionClassObject):
                     else:
                         EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                                     #Ui=VerString, 
-                                                     Ver=BuildNum)
+                                                    #Ui=VerString,
+                                                    Ver=BuildNum,
+                                                    IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
         #
         # If Section Type is 'UI'
         #
@@ -173,11 +178,11 @@ class EfiSection (EfiSectionClassObject):
 
             if InfOverrideUiString:
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                     Ui=StringData)
+                                                     Ui=StringData, IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             elif FileList != []:
                 for File in FileList:
                     Index = Index + 1
@@ -185,11 +190,11 @@ class EfiSection (EfiSectionClassObject):
                     OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
                     f = open(File, 'r')
                     UiString = f.read()
                     f.close()
                     GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                         Ui=UiString)
+                                                        Ui=UiString, IsMakefile=IsMakefile)
                     OutputFileList.append(OutputFile)
             else:
                 if StringData != None and len(StringData) > 0:
                     UiTuple = ('-n', '"' + StringData + '"')
                 else:
@@ -202,11 +207,11 @@ class EfiSection (EfiSectionClassObject):
                         EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
 
                 Num = SecNum
                 OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
                 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
-                                                     Ui=StringData)
+                                                     Ui=StringData, IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
 
         else:
             """If File List is empty"""
@@ -236,43 +241,58 @@ class EfiSection (EfiSectionClassObject):
                         else:
                             Align = str (ImageObj.SectionAlignment / 0x100000) + 'M'
 
                     if File[(len(File)-4):] == '.efi':
                         MapFile = File.replace('.efi', '.map')
-                        if os.path.exists(MapFile):
-                            CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
-                            if not os.path.exists(CopyMapFile) or \
-                                   (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
-                                CopyLongFilePath(MapFile, CopyMapFile)
+                        CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
+                        if IsMakefile:
+                            if GenFdsGlobalVariable.CopyList == []:
+                                GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
+                            else:
+                                GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
+                        else:
+                            if os.path.exists(MapFile):
+                                if not os.path.exists(CopyMapFile) or \
+                                       (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
+                                    CopyLongFilePath(MapFile, CopyMapFile)
 
                     if not NoStrip:
                         FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
-                        if not os.path.exists(FileBeforeStrip) or \
-                            (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
-                            CopyLongFilePath(File, FileBeforeStrip)
+                        if IsMakefile:
+                            if GenFdsGlobalVariable.CopyList == []:
+                                GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)]
+                            else:
+                                GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip))
+                        else:
+                            if not os.path.exists(FileBeforeStrip) or \
+                                (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
+                                CopyLongFilePath(File, FileBeforeStrip)
                         StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
                         GenFdsGlobalVariable.GenerateFirmwareImage(
-                                                StrippedFile,
-                                                [File],
-                                                Strip=True
-                                                )
+                                StrippedFile,
+                                [File],
+                                Strip=True,
+                                IsMakefile = IsMakefile
+                            )
                         File = StrippedFile
                     
                     """For TE Section call GenFw to generate TE image"""
 
                     if SectionType == 'TE':
                         TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
                         GenFdsGlobalVariable.GenerateFirmwareImage(
-                                                TeFile,
-                                                [File],
-                                                Type='te'
-                                                )
+                                TeFile,
+                                [File],
+                                Type='te',
+                                IsMakefile = IsMakefile
+                            )
                         File = TeFile
 
                     """Call GenSection"""
                     GenFdsGlobalVariable.GenerateSection(OutputFile,
-                                                         [File],
-                                                         Section.Section.SectionType.get (SectionType)
-                                                         )
+                                                        [File],
+                                                        Section.Section.SectionType.get (SectionType),
+                                                        IsMakefile=IsMakefile
+                                                        )
                     OutputFileList.append(OutputFile)
 
         return OutputFileList, Align
diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py
index f330a7e..f735d3b 100644
--- a/BaseTools/Source/Python/GenFds/Fd.py
+++ b/BaseTools/Source/Python/GenFds/Fd.py
@@ -43,19 +43,20 @@ class FD(FDClassObject):
     #
     #   Generate FD
     #
     #   @retval string      Generated FD file name
     #
-    def GenFd (self):
+    def GenFd (self, Flag = False):
         if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys():
             return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd']
 
         #
         # Print Information
         #
         FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd')
-        GenFdsGlobalVariable.InfLogger("Fd File Name:%s (%s)" %(self.FdUiName, FdFileName))
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName))
 
         Offset = 0x00
         for item in self.BlockSizeList:
             Offset = Offset + item[0]  * item[1]
         if Offset != self.Size:
@@ -83,15 +84,17 @@ class FD(FDClassObject):
                 if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
                     pass
                 elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
                     pass
                 elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
-                    GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
                     PadRegion = Region.Region()
                     PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                     PadRegion.Size = RegionObj.Offset - PadRegion.Offset
-                    PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+                    if not Flag:
+                        PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
                 PreviousRegionStart = RegionObj.Offset
                 PreviousRegionSize = RegionObj.Size
                 #
                 # Call each region's AddToBuffer function
                 #
@@ -111,15 +114,17 @@ class FD(FDClassObject):
             elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
                 EdkLogger.error("GenFds", GENFDS_ERROR,
                                 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
                                 % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
             elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
-                GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
+                if not Flag:
+                    GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
                 PadRegion = Region.Region()
                 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                 PadRegion.Size = RegionObj.Offset - PadRegion.Offset
-                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+                if not Flag:
+                    PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
             PreviousRegionStart = RegionObj.Offset
             PreviousRegionSize = RegionObj.Size
             #
             # Verify current region fits within allocated FD section Size
             #
@@ -129,17 +134,18 @@ class FD(FDClassObject):
                                 % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
             #
             # Call each region's AddToBuffer function
             #
             GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
-            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
+            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict,Flag=Flag)
         #
         # Write the buffer contents to Fd file
         #
         GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
-        SaveFileOnChange(FdFileName, FdBuffer.getvalue())
-        FdBuffer.close();
+        if not Flag:
+            SaveFileOnChange(FdFileName, FdBuffer.getvalue())
+        FdBuffer.close()
         GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
         return FdFileName
 
     ## generate VTF
     #
diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
index f76ddf4..edb1312 100644
--- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process FFS generation from FILE statement
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -55,11 +55,11 @@ class FileStatement (FileStatementClassObject) :
     #   @param  Dict         dictionary contains macro and value pair
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       Generated FFS file name
     #
-    def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None):
+    def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None, IsMakefile=False):
         
         if self.NameGuid != None and self.NameGuid.startswith('PCD('):
             PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
             if len(PcdValue) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index 958cecf..4b47817 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -42,10 +42,12 @@ from Common.Misc import PeImageClass
 from AutoGen.GenDepex import DependencyExpression
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile
 from Common.LongFilePathSupport import CopyLongFilePath
 from Common.LongFilePathSupport import OpenLongFilePath as open
 import Common.GlobalData as GlobalData
+from DepexSection import DepexSection
+from Common.Misc import SaveFileOnChange
 
 ## generate FFS from INF
 #
 #
 class FfsInfStatement(FfsInfStatementClassObject):
@@ -70,10 +72,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.FileName = None
         self.InfFileName = None
         self.OverrideGuid = None
         self.PatchedBinFile = ''
         self.MacroDict = {}
+        self.Depex = False
 
     ## GetFinalTargetSuffixMap() method
     #
     #    Get final build target list
     def GetFinalTargetSuffixMap(self):
@@ -318,10 +321,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
             self.PatchPcds.append((Pcd, DefaultValue))
 
         self.InfModule = Inf
         self.PcdIsDriver = Inf.PcdIsDriver
         self.IsBinaryModule = Inf.IsBinaryModule
+        Inf._GetDepex()
+        Inf._GetDepexExpression()
+        if len(Inf._Depex.data) > 0 and len(Inf._DepexExpression.data) > 0:
+            self.Depex = True
+
         GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
         GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
         GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
         GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
         GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
@@ -333,11 +341,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
                                        self.ModuleGuid + self.BaseName)
         if not os.path.exists(self.OutputPath) :
             os.makedirs(self.OutputPath)
 
-        self.EfiOutputPath = self.__GetEFIOutPutPath__()
+        self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__()
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
 
     ## PatchEfiFile
     #
     #  Patch EFI file with patch PCD
@@ -412,16 +420,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Dict         dictionary contains macro and value pair
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       Generated FFS file name
     #
-    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
+    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None, IsMakefile=False):
         #
         # Parse Inf file get Module related information
         #
 
         self.__InfParse__(Dict)
+        Arch = self.GetCurrentArch()
         SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);
         DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
         
         SrcFileDir = "."
         SrcPath = os.path.dirname(SrcFile)
@@ -449,11 +458,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
         # Allow binary type module not specify override rule in FDF file.
         # 
         if len(self.BinFileList) > 0:
             if self.Rule == None or self.Rule == "":
                 self.Rule = "BINARY"
-                
+
+        if not IsMakefile and GenFdsGlobalVariable.EnableGenfdsMultiThread and self.Rule != 'BINARY':
+            IsMakefile = True
         #
         # Get the rule of how to generate Ffs file
         #
         Rule = self.__GetRule__()
         GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
@@ -470,21 +481,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
         #
         # For the rule only has simpleFile
         #
+        MakefilePath = None
+        if IsMakefile:
+            MakefilePath = self.InfFileName, Arch
         if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
-            SectionOutputList = self.__GenSimpleFileSection__(Rule)
-            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
+            SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
+            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath)
             return FfsOutput
         #
         # For Rule has ComplexFile
         #
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
-            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
-            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
-
+            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile)
+            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath)
             return FfsOutput
 
     ## __ExtendMacro__() method
     #
     #   Replace macro with its value
@@ -649,10 +662,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @retval string      Path that output files from this INF go to
     #
     def __GetEFIOutPutPath__(self):
         Arch = ''
         OutputPath = ''
+        DebugPath = ''
         (ModulePath, FileName) = os.path.split(self.InfFileName)
         Index = FileName.rfind('.')
         FileName = FileName[0:Index]
         if self.OverrideGuid:
             FileName = self.OverrideGuid
@@ -664,22 +678,29 @@ class FfsInfStatement(FfsInfStatementClassObject):
                                   Arch ,
                                   ModulePath,
                                   FileName,
                                   'OUTPUT'
                                   )
+        DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
+                                  Arch ,
+                                  ModulePath,
+                                  FileName,
+                                  'DEBUG'
+                                  )
         OutputPath = os.path.realpath(OutputPath)
-        return OutputPath
+        DebugPath = os.path.realpath(DebugPath)
+        return OutputPath, DebugPath
 
     ## __GenSimpleFileSection__() method
     #
     #   Generate section by specified file name or a list of files with file extension
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenSimpleFileSection__(self, Rule):
+    def __GenSimpleFileSection__(self, Rule, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         FileList = []
         OutputFileList = []
@@ -741,26 +762,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     if not os.path.exists(FileBeforeStrip) or \
                            (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
                         CopyLongFilePath(File, FileBeforeStrip)
                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
                     GenFdsGlobalVariable.GenerateFirmwareImage(
-                                            StrippedFile,
-                                            [File],
-                                            Strip=True
-                                            )
+                            StrippedFile,
+                            [File],
+                            Strip=True,
+                            IsMakefile=IsMakefile
+                        )
                     File = StrippedFile
 
                 if SectionType == 'TE':
                     TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
                     GenFdsGlobalVariable.GenerateFirmwareImage(
-                                            TeFile,
-                                            [File],
-                                            Type='te'
-                                            )
+                            TeFile,
+                            [File],
+                            Type='te',
+                            IsMakefile=IsMakefile
+                        )
                     File = TeFile
-
-                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
         else:
             SecNum = '%d' %Index
             GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
                               Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
@@ -783,26 +805,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
                        (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
                     CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
 
                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
                 GenFdsGlobalVariable.GenerateFirmwareImage(
-                                        StrippedFile,
-                                        [GenSecInputFile],
-                                        Strip=True
-                                        )
+                        StrippedFile,
+                        [GenSecInputFile],
+                        Strip=True,
+                        IsMakefile=IsMakefile
+                    )
                 GenSecInputFile = StrippedFile
 
             if SectionType == 'TE':
                 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
                 GenFdsGlobalVariable.GenerateFirmwareImage(
-                                        TeFile,
-                                        [GenSecInputFile],
-                                        Type='te'
-                                        )
+                        TeFile,
+                        [GenSecInputFile],
+                        Type='te',
+                        IsMakefile=IsMakefile
+                    )
                 GenSecInputFile = TeFile
-
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
+            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
             OutputFileList.append(OutputFile)
 
         return OutputFileList
 
     ## __GenSimpleFileFfs__() method
@@ -812,11 +835,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @param  InputFileList        The output file list from GenSection
     #   @retval string      Generated FFS file name
     #
-    def __GenSimpleFileFfs__(self, Rule, InputFileList):
+    def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None):
         FfsOutput = self.OutputPath                     + \
                     os.sep                              + \
                     self.__ExtendMacro__(Rule.NameGuid) + \
                     '.ffs'
 
@@ -838,16 +861,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
             if len(RegistryGuidStr) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
                             % (Rule.NameGuid))
             self.ModuleGuid = RegistryGuidStr
 
-        GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
-                                         self.ModuleGuid, Fixed=Rule.Fixed,
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
-                                         SectionAlign=SectionAlignments
-                                        )
+            GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
+                                             Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
+                                             self.ModuleGuid, Fixed=Rule.Fixed,
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,
+                                             SectionAlign=SectionAlignments,
+                                             MakefilePath=MakefilePath
+                                             )
         return FfsOutput
 
     ## __GenComplexFileSection__() method
     #
     #   Generate section by sections in Rule
@@ -856,40 +880,42 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Rule         The rule object used to generate section
     #   @param  FvChildAddr  Array of the inside FvImage base address
     #   @param  FvParentAddr Parent Fv base address
     #   @retval string       File name of the generated section file
     #
-    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
+    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False):
         if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
             if Rule.KeepReloc != None:
                 self.KeepRelocFromRule = Rule.KeepReloc
         SectFiles = []
         SectAlignments = []
         Index = 1
-        HasGneratedFlag = False
+        HasGeneratedFlag = False
         if self.PcdIsDriver == 'PEI_PCD_DRIVER':
             if self.IsBinaryModule:
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
             else:
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
             PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
                                                  [PcdExDbFileName],
                                                  "EFI_SECTION_RAW",
+                                                 IsMakefile = IsMakefile
                                                  )
             SectFiles.append(PcdExDbSecName)
             SectAlignments.append(None)
         elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
             if self.IsBinaryModule:
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
             else:
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
             PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
-                                                 [PcdExDbFileName],
-                                                 "EFI_SECTION_RAW",
-                                                 )
+                                                [PcdExDbFileName],
+                                                "EFI_SECTION_RAW",
+                                                IsMakefile = IsMakefile
+                                                )
             SectFiles.append(PcdExDbSecName)
             SectAlignments.append(None)
         for Sect in Rule.SectionList:
             SecIndex = '%d' %Index
             SectList  = []
@@ -915,15 +941,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     Sect.FvAddr = FvChildAddr
             if FvParentAddr != None and isinstance(Sect, GuidSection):
                 Sect.FvParentAddr = FvParentAddr
             
             if Rule.KeyStringList != []:
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
+                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile)
             else :
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
+                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile)
             
-            if not HasGneratedFlag:
+            if not HasGeneratedFlag:
                 UniVfrOffsetFileSection = ""    
                 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
                 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
                 #
                 # Search the source list in InfData to find if there are .vfr file exist.
@@ -942,31 +968,44 @@ class FfsInfStatement(FfsInfStatementClassObject):
                         #
                         VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
                     
                 
                 if len(VfrUniBaseName) > 0:
-                    VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
-                    #
-                    # Generate the Raw data of raw section
-                    #
-                    if VfrUniOffsetList:
-                        os.path.join( self.OutputPath, self.BaseName + '.offset')
-                        UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')
-                        UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
-
-                        self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
-
-                        UniVfrOffsetFileNameList = []
-                        UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
-                        """Call GenSection"""
-                        GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
-                                                             UniVfrOffsetFileNameList,
-                                                             "EFI_SECTION_RAW"
-                                                             )
-                        os.remove(UniVfrOffsetFileName)
+                    if IsMakefile:
+                        if InfData.BuildType != 'UEFI_HII':
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
+                            UniVfrOffsetFileNameList = []
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
+                            TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath)
+                            GenFdsGlobalVariable.SecCmdList.append(TrimCmd)
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
+                                                                [UniVfrOffsetFileName],
+                                                                "EFI_SECTION_RAW",
+                                                                IsMakefile = True
+                                                                )
+                    else:
+                        VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
+                        #
+                        # Generate the Raw data of raw section
+                        #
+                        if VfrUniOffsetList:
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
+                            self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
+                            UniVfrOffsetFileNameList = []
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
+                            """Call GenSection"""
+
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
+                                                                 UniVfrOffsetFileNameList,
+                                                                 "EFI_SECTION_RAW"
+                                                                 )
+                            #os.remove(UniVfrOffsetFileName)
+                    if UniVfrOffsetFileSection:
                         SectList.append(UniVfrOffsetFileSection)
-                        HasGneratedFlag = True
+                        HasGeneratedFlag = True
                 
             for SecName in  SectList :
                 SectFiles.append(SecName)
                 SectAlignments.append(Align)
             Index = Index + 1
@@ -979,11 +1018,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @param  InputFileList        The output file list from GenSection
     #   @retval string      Generated FFS file name
     #
-    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
+    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None):
 
         if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
             if len(PcdValue) == 0:
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
@@ -996,15 +1035,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
                             % (Rule.NameGuid))
             self.ModuleGuid = RegistryGuidStr
 
         FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
-                                         self.ModuleGuid, Fixed=Rule.Fixed,
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
-                                         SectionAlign=Alignments
-                                        )
+                                             Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
+                                             self.ModuleGuid, Fixed=Rule.Fixed,
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,
+                                             SectionAlign=Alignments,
+                                             MakefilePath=MakefilePath
+                                             )
         return FfsOutput
 
     ## __GetGenFfsCmdParameter__() method
     #
     #   Create parameter string for GenFfs
@@ -1046,16 +1086,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self                    The object pointer
     #   @param  VfrUniOffsetList        A list contain the VFR/UNI offsets in the EFI image file.
     #   @param  UniVfrOffsetFileName    The output offset file name.
     #
     def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
-        
-        try:
-            fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
-        except:
-            EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
-            
+
         # Use a instance of StringIO to cache data
         fStringIO = StringIO.StringIO('')  
         
         for Item in VfrUniOffsetList:
             if (Item[0].find("Strings") != -1):
@@ -1083,20 +1118,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 fStringIO.write (VfrValue)
             
         #
         # write data into file.
         #
-        try :  
-            fInputfile.write (fStringIO.getvalue())
+        try :
+            SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue())
         except:
             EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None)
         
         fStringIO.close ()
-        fInputfile.close ()
-        
-                
-                    
-            
-            
-        
-                                
+
         
diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py
index 45f6696..3953756 100644
--- a/BaseTools/Source/Python/GenFds/Fv.py
+++ b/BaseTools/Source/Python/GenFds/Fv.py
@@ -20,10 +20,11 @@ import subprocess
 import StringIO
 from struct import *
 
 import Ffs
 import AprioriSection
+import FfsFileStatement
 from GenFdsGlobalVariable import GenFdsGlobalVariable
 from GenFds import GenFds
 from CommonDataClass.FdfClass import FvClassObject
 from Common.Misc import SaveFileOnChange
 from Common.LongFilePathSupport import CopyLongFilePath
@@ -65,11 +66,11 @@ class FV (FvClassObject):
     #   @param  ErasePolarity      Flash erase polarity
     #   @param  VtfDict     VTF objects
     #   @param  MacroDict   macro value pair
     #   @retval string      Generated FV file path
     #
-    def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :
+    def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}, Flag=False) :
 
         if BaseAddress == None and self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():
             return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']
         
         #
@@ -86,135 +87,145 @@ class FV (FvClassObject):
                                 continue
                             elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():
                                 continue
                             elif self.UiFvName.upper() == RegionData.upper():
                                 GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
-
-        GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
         GenFdsGlobalVariable.LargeFileInFvFlags.append(False)
         FFSGuid = None
         
         if self.FvBaseAddress != None:
             BaseAddress = self.FvBaseAddress
-
-        self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
+        if not Flag:
+            self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
         #
         # First Process the Apriori section
         #
         MacroDict.update(self.DefineVarDict)
 
         GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')
         FfsFileList = []
         for AprSection in self.AprioriSectionList:
-            FileName = AprSection.GenFfs (self.UiFvName, MacroDict)
+            FileName = AprSection.GenFfs (self.UiFvName, MacroDict, IsMakefile=Flag)
             FfsFileList.append(FileName)
             # Add Apriori file name to Inf file
-            self.FvInfFile.writelines("EFI_FILE_NAME = " + \
-                                       FileName          + \
-                                           T_CHAR_LF)
+            if not Flag:
+                self.FvInfFile.writelines("EFI_FILE_NAME = " + \
+                                            FileName          + \
+                                            T_CHAR_LF)
 
         # Process Modules in FfsList
         for FfsFile in self.FfsList :
-            FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress)
+            if Flag:
+                if isinstance(FfsFile, FfsFileStatement.FileStatement):
+                    continue
+            if GenFdsGlobalVariable.EnableGenfdsMultiThread and GenFdsGlobalVariable.ModuleFile and GenFdsGlobalVariable.ModuleFile.Path.find(os.path.normpath(FfsFile.InfFileName)) == -1:
+                continue
+            FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress, IsMakefile=Flag)
             FfsFileList.append(FileName)
-            self.FvInfFile.writelines("EFI_FILE_NAME = " + \
-                                       FileName          + \
-                                       T_CHAR_LF)
-
-        SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)
-        self.FvInfFile.close()
+            if not Flag:
+                self.FvInfFile.writelines("EFI_FILE_NAME = " + \
+                                            FileName          + \
+                                            T_CHAR_LF)
+        if not Flag:
+            SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)
+            self.FvInfFile.close()
         #
         # Call GenFv tool
         #
         FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)
         FvOutputFile = FvOutputFile + '.Fv'
         # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
         if self.CreateFileName != None:
             FvOutputFile = self.CreateFileName
 
+        if Flag:
+            GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
+            return FvOutputFile
+
         FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')
-        CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
-        OrigFvInfo = None
-        if os.path.exists (FvInfoFileName):
-            OrigFvInfo = open(FvInfoFileName, 'r').read()
-        if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
-            FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
-        GenFdsGlobalVariable.GenerateFirmwareVolume(
-                                FvOutputFile,
-                                [self.InfFileName],
-                                AddressFile=FvInfoFileName,
-                                FfsList=FfsFileList,
-                                ForceRebase=self.FvForceRebase,
-                                FileSystemGuid=FFSGuid
-                                )
+        if not Flag:
+            CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
+            OrigFvInfo = None
+            if os.path.exists (FvInfoFileName):
+                OrigFvInfo = open(FvInfoFileName, 'r').read()
+            if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
+                FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID
+            GenFdsGlobalVariable.GenerateFirmwareVolume(
+                                    FvOutputFile,
+                                    [self.InfFileName],
+                                    AddressFile=FvInfoFileName,
+                                    FfsList=FfsFileList,
+                                    ForceRebase=self.FvForceRebase,
+                                    FileSystemGuid=FFSGuid
+                                    )
 
-        NewFvInfo = None
-        if os.path.exists (FvInfoFileName):
-            NewFvInfo = open(FvInfoFileName, 'r').read()
-        if NewFvInfo != None and NewFvInfo != OrigFvInfo:
-            FvChildAddr = []
-            AddFileObj = open(FvInfoFileName, 'r')
-            AddrStrings = AddFileObj.readlines()
-            AddrKeyFound = False
-            for AddrString in AddrStrings:
-                if AddrKeyFound:
-                    #get base address for the inside FvImage
-                    FvChildAddr.append (AddrString)
-                elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:
-                    AddrKeyFound = True
-            AddFileObj.close()
+            NewFvInfo = None
+            if os.path.exists (FvInfoFileName):
+                NewFvInfo = open(FvInfoFileName, 'r').read()
+            if NewFvInfo != None and NewFvInfo != OrigFvInfo:
+                FvChildAddr = []
+                AddFileObj = open(FvInfoFileName, 'r')
+                AddrStrings = AddFileObj.readlines()
+                AddrKeyFound = False
+                for AddrString in AddrStrings:
+                    if AddrKeyFound:
+                        #get base address for the inside FvImage
+                        FvChildAddr.append (AddrString)
+                    elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:
+                        AddrKeyFound = True
+                AddFileObj.close()
 
-            if FvChildAddr != []:
-                # Update Ffs again
-                for FfsFile in self.FfsList :
-                    FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress)
-                
-                if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
-                    FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
-                #Update GenFv again
-                GenFdsGlobalVariable.GenerateFirmwareVolume(
-                                        FvOutputFile,
-                                        [self.InfFileName],
-                                        AddressFile=FvInfoFileName,
-                                        FfsList=FfsFileList,
-                                        ForceRebase=self.FvForceRebase,
-                                        FileSystemGuid=FFSGuid
-                                        )
+                if FvChildAddr != []:
+                    # Update Ffs again
+                    for FfsFile in self.FfsList :
+                        FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress, IsMakefile=Flag)
 
-        #
-        # Write the Fv contents to Buffer
-        #
-        if os.path.isfile(FvOutputFile):
-            FvFileObj = open ( FvOutputFile,'rb')
+                    if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
+                        FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
+                    #Update GenFv again
+                        GenFdsGlobalVariable.GenerateFirmwareVolume(
+                                                FvOutputFile,
+                                                [self.InfFileName],
+                                                AddressFile=FvInfoFileName,
+                                                FfsList=FfsFileList,
+                                                ForceRebase=self.FvForceRebase,
+                                                FileSystemGuid=FFSGuid
+                                                )
 
-            GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName)
-            GenFdsGlobalVariable.SharpCounter = 0
+            #
+            # Write the Fv contents to Buffer
+            #
+            if os.path.isfile(FvOutputFile):
+                FvFileObj = open(FvOutputFile, 'rb')
+                GenFdsGlobalVariable.VerboseLogger("\nGenerate %s FV Successfully" % self.UiFvName)
+                GenFdsGlobalVariable.SharpCounter = 0
 
-            Buffer.write(FvFileObj.read())
-            FvFileObj.seek(0)
-            # PI FvHeader is 0x48 byte
-            FvHeaderBuffer = FvFileObj.read(0x48)
-            # FV alignment position.
-            FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
-            # FvAlignmentValue is larger than or equal to 1K
-            if FvAlignmentValue >= 0x400:
-                if FvAlignmentValue >= 0x100000:
-                    #The max alignment supported by FFS is 16M.
-                    if FvAlignmentValue >= 0x1000000:
-                        self.FvAlignment = "16M"
+                Buffer.write(FvFileObj.read())
+                FvFileObj.seek(0)
+                # PI FvHeader is 0x48 byte
+                FvHeaderBuffer = FvFileObj.read(0x48)
+                # FV alignment position.
+                FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
+                if FvAlignmentValue >= 0x400:
+                    if FvAlignmentValue >= 0x100000:
+                        if FvAlignmentValue >= 0x1000000:
+                        #The max alignment supported by FFS is 16M.
+                            self.FvAlignment = "16M"
+                        else:
+                            self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
                     else:
-                        self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
+                        self.FvAlignment = str(FvAlignmentValue / 0x400) + "K"
                 else:
-                    self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"
+                    # FvAlignmentValue is less than 1K
+                    self.FvAlignment = str (FvAlignmentValue)
+                FvFileObj.close()
+                GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
+                GenFdsGlobalVariable.LargeFileInFvFlags.pop()
             else:
-                # FvAlignmentValue is less than 1K
-                self.FvAlignment = str (FvAlignmentValue)
-            FvFileObj.close()
-            GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
-            GenFdsGlobalVariable.LargeFileInFvFlags.pop()
-        else:
-            GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName)
+                GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName)
         return FvOutputFile
 
     ## _GetBlockSize()
     #
     #   Calculate FV's block size
diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py
index 68f17c3..916ff91 100644
--- a/BaseTools/Source/Python/GenFds/FvImageSection.py
+++ b/BaseTools/Source/Python/GenFds/FvImageSection.py
@@ -48,11 +48,11 @@ class FvImageSection(FvImageSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False):
 
         OutputFileList = []
         if self.FvFileType != None:
             FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
             if IsSect :
@@ -73,11 +73,11 @@ class FvImageSection(FvImageSectionClassObject):
                     FvFileObj.close()
                 if FvAlignmentValue > MaxFvAlignment:
                     MaxFvAlignment = FvAlignmentValue
 
                 OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE"))
-                GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
                 OutputFileList.append(OutputFile)
 
             # MaxFvAlignment is larger than or equal to 1K
             if MaxFvAlignment >= 0x400:
                 if MaxFvAlignment >= 0x100000:
@@ -99,11 +99,11 @@ class FvImageSection(FvImageSectionClassObject):
         if self.FvName != None:
             Buffer = StringIO.StringIO('')
             Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
             if Fv != None:
                 self.Fv = Fv
-                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict)
+                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile)
                 if Fv.FvAlignment != None:
                     if self.Alignment == None:
                         self.Alignment = Fv.FvAlignment
                     else:
                         if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
@@ -137,9 +137,9 @@ class FvImageSection(FvImageSectionClassObject):
 
             #
             # Prepare the parameter of GenSection
             #
             OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE"))
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE')
+            GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
             OutputFileList.append(OutputFile)
 
             return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index c19dc40..4a5d6f4 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -97,10 +97,12 @@ def main():
             GenFdsGlobalVariable.WorkSpaceDir = Workspace
             if 'EDK_SOURCE' in os.environ.keys():
                 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])
             if (Options.debug):
                 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)
+            if Options.GenfdsMultiThread:
+                GenFdsGlobalVariable.EnableGenfdsMultiThread = True
         os.chdir(GenFdsGlobalVariable.WorkSpaceDir)
         
         # set multiple workspace
         PackagesPath = os.getenv("PACKAGES_PATH")
         mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)
@@ -536,10 +538,11 @@ def myOptionParser():
     Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
     Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
     Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
     Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
     Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
+    Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")
 
     (Options, args) = Parser.parse_args()
     return Options
 
 ## The class implementing the EDK2 flash image generation process
@@ -609,10 +612,27 @@ class GenFds :
             if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
                 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
                     OptRomObj.AddToBuffer(None)
+    @staticmethod
+    def GenFfsMakefile(OutputDir, FdfParser, WorkSpace, ArchList, GlobalData):
+        GenFdsGlobalVariable.SetEnv(FdfParser, WorkSpace, ArchList, GlobalData)
+        for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+            FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
+            FdObj.GenFd(Flag=True)
+
+        for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
+            FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
+            FvObj.AddToBuffer(Buffer=None, Flag=True)
+
+        if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
+            for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
+                OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
+                OptRomObj.AddToBuffer(Buffer=None, Flag=True)
+
+        return GenFdsGlobalVariable.FfsCmdDict
 
     ## GetFvBlockSize()
     #
     #   @param  FvObj           Whose block size to get
     #   @retval int             Block size value
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index 83996be..371d5a8 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -67,10 +67,15 @@ class GenFdsGlobalVariable:
     
     BuildRuleFamily = "MSFT"
     ToolChainFamily = "MSFT"
     __BuildRuleDatabase = None
     GuidToolDefinition = {}
+    FfsCmdDict = {}
+    SecCmdList = []
+    CopyList   = []
+    ModuleFile = ''
+    EnableGenfdsMultiThread = False
     
     #
     # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
     # At the beginning of each generation of FV, false flag is appended to the list,
     # after the call to GenerateSection returns, check the size of the output file,
@@ -262,10 +267,14 @@ class GenFdsGlobalVariable:
     
                 RuleChain.append(FileType)
                 SourceList.extend(Target.Outputs)
                 LastTarget = Target
                 FileType = DataType.TAB_UNKNOWN_FILE
+                for Cmd in Target.Commands:
+                    if "$(CP)" == Cmd.split()[0]:
+                        CpTarget = Cmd.split()[2]
+                        TargetList.add(CpTarget)
 
         return list(TargetList)
 
     ## SetDir()
     #
@@ -315,10 +324,77 @@ class GenFdsGlobalVariable:
                                        RtAddress + \
                                        T_CHAR_LF)
 
         FvAddressFile.close()
 
+    def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):
+        GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile
+        GenFdsGlobalVariable.FdfParser = FdfParser
+        GenFdsGlobalVariable.WorkSpace = WorkSpace.Db
+        GenFdsGlobalVariable.ArchList = ArchList
+        GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]
+        GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]
+        GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform
+        GenFdsGlobalVariable.EdkSourceDir = GlobalData.gGlobalDefines["EDK_SOURCE"]
+        GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory
+        GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread
+        for Arch in ArchList:
+            GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(
+                os.path.join(GlobalData.gWorkspace,
+                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,GlobalData.gGlobalDefines['TARGET'],
+                             GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,
+                             GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))
+            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(
+                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                             GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)
+            GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                                                                      GlobalData.gGlobalDefines['TARGET'],
+                                                                      GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName
+        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], 'FV')
+        if not os.path.exists(GenFdsGlobalVariable.FvDir):
+            os.makedirs(GenFdsGlobalVariable.FvDir)
+        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
+        if not os.path.exists(GenFdsGlobalVariable.FfsDir):
+            os.makedirs(GenFdsGlobalVariable.FfsDir)
+
+        T_CHAR_LF = '\n'
+        #
+        # Create FV Address inf file
+        #
+        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
+        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
+        #
+        # Add [Options]
+        #
+        FvAddressFile.writelines("[options]" + T_CHAR_LF)
+        BsAddress = '0'
+        for Arch in ArchList:
+            BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
+                                                                   GlobalData.gGlobalDefines['TARGET'],
+                                                                   GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress
+            if BsAddress:
+                break
+
+        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
+                                 BsAddress + \
+                                 T_CHAR_LF)
+
+        RtAddress = '0'
+        for Arch in ArchList:
+            if GenFdsGlobalVariable.WorkSpace.BuildObject[
+                GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
+                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress:
+                RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[
+                    GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
+                    GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress
+
+        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
+                                 RtAddress + \
+                                 T_CHAR_LF)
+
+        FvAddressFile.close()
+
     ## ReplaceWorkspaceMacro()
     #
     #   @param  String           String that may contain macro
     #
     def ReplaceWorkspaceMacro(String):
@@ -361,18 +437,20 @@ class GenFdsGlobalVariable:
                 return True
         return False
 
     @staticmethod
     def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
-                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None):
+                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None, BuildNumber=None, DummyFile=None, IsMakefile=False):
         Cmd = ["GenSec"]
         if Type not in [None, '']:
             Cmd += ["-s", Type]
         if CompressionType not in [None, '']:
             Cmd += ["-c", CompressionType]
         if Guid != None:
             Cmd += ["-g", Guid]
+        if DummyFile != None:
+            Cmd += ["--dummy", DummyFile]
         if GuidHdrLen not in [None, '']:
             Cmd += ["-l", GuidHdrLen]
         if len(GuidAttr) != 0:
             #Add each guided attribute
             for Attr in GuidAttr:
@@ -383,40 +461,53 @@ class GenFdsGlobalVariable:
                 Cmd += ["--sectionalign", SecAlign]
 
         CommandFile = Output + '.txt'
         if Ui not in [None, '']:
             #Cmd += ["-n", '"' + Ui + '"']
-            SectionData = array.array('B', [0, 0, 0, 0])
-            SectionData.fromstring(Ui.encode("utf_16_le"))
-            SectionData.append(0)
-            SectionData.append(0)
-            Len = len(SectionData)
-            GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
-            SaveFileOnChange(Output, SectionData.tostring())
+            if IsMakefile:
+                Cmd += ["-n", "$(MODULE_NAME)"]
+                Cmd += ["-o", Output]
+                #SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            else:
+                SectionData = array.array('B', [0, 0, 0, 0])
+                SectionData.fromstring(Ui.encode("utf_16_le"))
+                SectionData.append(0)
+                SectionData.append(0)
+                Len = len(SectionData)
+                GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
+                SaveFileOnChange(Output, SectionData.tostring())
+
         elif Ver not in [None, '']:
             Cmd += ["-n", Ver]
             if BuildNumber:
                 Cmd += ["-j", BuildNumber]
             Cmd += ["-o", Output]
 
             SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
-                return
-
-            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
+            if IsMakefile:
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            else:
+                if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+                    return
+                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
         else:
             Cmd += ["-o", Output]
             Cmd += Input
 
             SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-            if GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
+            if IsMakefile:
+                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
+            elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)):
                 GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
                 GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
-
-            if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
-                GenFdsGlobalVariable.LargeFileInFvFlags):
-                GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True 
+                if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
+                    GenFdsGlobalVariable.LargeFileInFvFlags):
+                    GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True
 
     @staticmethod
     def GetAlignment (AlignString):
         if AlignString == None:
             return 0
@@ -427,11 +518,11 @@ class GenFdsGlobalVariable:
         else:
             return int (AlignString)
 
     @staticmethod
     def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
-                    SectionAlign=None):
+                    SectionAlign=None, MakefilePath=None):
         Cmd = ["GenFfs", "-t", Type, "-g", Guid]
         mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
         if Fixed == True:
             Cmd += ["-x"]
         if CheckSum:
@@ -451,15 +542,21 @@ class GenFdsGlobalVariable:
             if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
                 Cmd += ("-n", SectionAlign[I])
 
         CommandFile = Output + '.txt'
         SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
-            return
-        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
+        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
+        if MakefilePath:
+            if (tuple(Cmd),tuple(GenFdsGlobalVariable.SecCmdList),tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict.keys():
+                GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath
+            GenFdsGlobalVariable.SecCmdList = []
+            GenFdsGlobalVariable.CopyList = []
+        else:
+            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input)):
+                return
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
 
     @staticmethod
     def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
                                AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
         if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
@@ -509,12 +606,12 @@ class GenFdsGlobalVariable:
         GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate VTF")
 
     @staticmethod
     def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
                               Strip=False, Replace=False, TimeStamp=None, Join=False,
-                              Align=None, Padding=None, Convert=False):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
+                              Align=None, Padding=None, Convert=False, IsMakefile=False):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
         Cmd = ["GenFw"]
         if Type.lower() == "te":
@@ -537,16 +634,19 @@ class GenFdsGlobalVariable:
             Cmd += ["-j"]
         if Convert:
             Cmd += ["-m"]
         Cmd += ["-o", Output]
         Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
 
     @staticmethod
     def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
-                        Revision=None, DeviceId=None, VendorId=None):
+                        Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):
         InputList = []   
         Cmd = ["EfiRom"]
         if len(EfiInput) > 0:
             
             if Compress:
@@ -563,11 +663,11 @@ class GenFdsGlobalVariable:
             for BinFile in BinaryInput:
                 Cmd += [BinFile]
                 InputList.append (BinFile)
 
         # Check List
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
                         
         if ClassCode != None:
             Cmd += ["-l", ClassCode]
@@ -577,24 +677,31 @@ class GenFdsGlobalVariable:
             Cmd += ["-i", DeviceId]
         if VendorId != None:
             Cmd += ["-f", VendorId]
 
         Cmd += ["-o", Output]
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
 
     @staticmethod
-    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[]):
-        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
+    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):
+        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
 
         Cmd = [ToolPath, ]
         Cmd += Options.split(' ')
         Cmd += ["-o", Output]
         Cmd += Input
-
-        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
+        if IsMakefile:
+            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
+                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
+        else:
+            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
 
     def CallExternalTool (cmd, errorMess, returnValue=[]):
 
         if type(cmd) not in (tuple, list):
             GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")
@@ -725,10 +832,11 @@ class GenFdsGlobalVariable:
                         return PcdValue
 
         return PcdValue
 
     SetDir = staticmethod(SetDir)
+    SetEnv = staticmethod(SetEnv)
     ReplaceWorkspaceMacro = staticmethod(ReplaceWorkspaceMacro)
     CallExternalTool = staticmethod(CallExternalTool)
     VerboseLogger = staticmethod(VerboseLogger)
     InfLogger = staticmethod(InfLogger)
     ErrorLogger = staticmethod(ErrorLogger)
diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py
index f199dcd..ea737bb 100644
--- a/BaseTools/Source/Python/GenFds/GuidSection.py
+++ b/BaseTools/Source/Python/GenFds/GuidSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process GUIDed section generation
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -52,11 +52,11 @@ class GuidSection(GuidSectionClassObject) :
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False):
         #
         # Generate all section
         #
         self.KeyStringList = KeyStringList
         self.CurrentArchList = GenFdsGlobalVariable.ArchList
@@ -92,11 +92,11 @@ class GuidSection(GuidSectionClassObject) :
                     Sect.FvAddr = self.FvAddr.pop(0)
                 self.IncludeFvSection = True
             elif isinstance(Sect, GuidSection):
                 Sect.FvAddr = self.FvAddr
                 Sect.FvParentAddr = self.FvParentAddr
-            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict)
+            ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
             if isinstance(Sect, GuidSection):
                 if Sect.IncludeFvSection:
                     self.IncludeFvSection = Sect.IncludeFvSection
 
             if align != None:
@@ -135,11 +135,11 @@ class GuidSection(GuidSectionClassObject) :
         # If not have GUID , call default
         # GENCRC32 section
         #
         if self.NameGuid == None :
             GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
-            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)
+            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile)
             OutputFileList = []
             OutputFileList.append(OutputFile)
             return OutputFileList, self.Alignment
         #or GUID not in External Tool List
         elif ExternalTool == None:
@@ -147,11 +147,11 @@ class GuidSection(GuidSectionClassObject) :
         else:
             DummyFile = OutputFile + ".dummy"
             #
             # Call GenSection with DUMMY section type.
             #
-            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign)
+            GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile)
             #
             # Use external tool process the Output
             #
             TempFile = OutputPath + \
                        os.sep + \
@@ -170,79 +170,103 @@ class GuidSection(GuidSectionClassObject) :
 
             FirstCall = False
             CmdOption = '-e'
             if ExternalOption != None:
                 CmdOption = CmdOption + ' ' + ExternalOption
-            if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
-                #FirstCall is only set for the encapsulated flash FV image without process required attribute.
-                FirstCall = True
-            #
-            # Call external tool
-            #
-            ReturnValue = [1]
-            if FirstCall:
-                #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
+            if not GenFdsGlobalVariable.EnableGenfdsMultiThread:
+                if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None:
+                    #FirstCall is only set for the encapsulated flash FV image without process required attribute.
+                    FirstCall = True
+                #
+                # Call external tool
+                #
+                ReturnValue = [1]
+                if FirstCall:
+                    #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
+                    GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
 
-            #
-            # when no call or first call failed, ReturnValue are not 1.
-            # Call the guided tool with CmdOption
-            #
-            if ReturnValue[0] != 0:
-                FirstCall = False
-                ReturnValue[0] = 0
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
-            #
-            # There is external tool which does not follow standard rule which return nonzero if tool fails
-            # The output file has to be checked
-            #
-            if not os.path.exists(TempFile):
-                EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
-
-            FileHandleIn = open(DummyFile, 'rb')
-            FileHandleIn.seek(0, 2)
-            InputFileSize = FileHandleIn.tell()
-
-            FileHandleOut = open(TempFile, 'rb')
-            FileHandleOut.seek(0, 2)
-            TempFileSize = FileHandleOut.tell()
-
-            Attribute = []
-            HeaderLength = None
-            if self.ExtraHeaderSize != -1:
-                HeaderLength = str(self.ExtraHeaderSize)
-
-            if self.ProcessRequired == "NONE" and HeaderLength == None:
-                if TempFileSize > InputFileSize:
-                    FileHandleIn.seek(0)
-                    BufferIn = FileHandleIn.read()
-                    FileHandleOut.seek(0)
-                    BufferOut = FileHandleOut.read()
-                    if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
-                        HeaderLength = str(TempFileSize - InputFileSize)
-                #auto sec guided attribute with process required
-                if HeaderLength == None:
-                    Attribute.append('PROCESSING_REQUIRED')
-
-            FileHandleIn.close()
-            FileHandleOut.close()
-
-            if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
-                # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
-                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
+                #
+                # when no call or first call failed, ReturnValue are not 1.
+                # Call the guided tool with CmdOption
+                #
+                if ReturnValue[0] != 0:
+                    FirstCall = False
+                    ReturnValue[0] = 0
+                    GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
+                #
+                # There is external tool which does not follow standard rule which return nonzero if tool fails
+                # The output file has to be checked
+                #
+
+                if not os.path.exists(TempFile) :
+                    EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
+
+                FileHandleIn = open(DummyFile, 'rb')
+                FileHandleIn.seek(0, 2)
+                InputFileSize = FileHandleIn.tell()
+
+                FileHandleOut = open(TempFile, 'rb')
+                FileHandleOut.seek(0, 2)
+                TempFileSize = FileHandleOut.tell()
+
+                Attribute = []
+                HeaderLength = None
+                if self.ExtraHeaderSize != -1:
+                    HeaderLength = str(self.ExtraHeaderSize)
+
+                if self.ProcessRequired == "NONE" and HeaderLength == None:
+                    if TempFileSize > InputFileSize:
+                        FileHandleIn.seek(0)
+                        BufferIn = FileHandleIn.read()
+                        FileHandleOut.seek(0)
+                        BufferOut = FileHandleOut.read()
+                        if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
+                            HeaderLength = str(TempFileSize - InputFileSize)
+                    #auto sec guided attribute with process required
+                    if HeaderLength == None:
+                        Attribute.append('PROCESSING_REQUIRED')
+
+                FileHandleIn.close()
+                FileHandleOut.close()
+
+                if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
+                    # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
+                    GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
+
+                #
+                # Call Gensection Add Section Header
+                #
+                if self.ProcessRequired in ("TRUE", "1"):
+                    if 'PROCESSING_REQUIRED' not in Attribute:
+                        Attribute.append('PROCESSING_REQUIRED')
+
+                if self.AuthStatusValid in ("TRUE", "1"):
+                    Attribute.append('AUTH_STATUS_VALID')
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
+                                                     Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
+
+            else:
+                #add input file for GenSec get PROCESSING_REQUIRED
+                GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile)
+                Attribute = []
+                HeaderLength = None
+                if self.ExtraHeaderSize != -1:
+                    HeaderLength = str(self.ExtraHeaderSize)
+                if self.AuthStatusValid in ("TRUE", "1"):
+                    Attribute.append('AUTH_STATUS_VALID')
+                if self.ProcessRequired == "NONE" and HeaderLength == None:
+                    GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
+                                                         Guid=self.NameGuid, GuidAttr=Attribute,
+                                                         GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile)
+                else:
+                    if self.ProcessRequired in ("TRUE", "1"):
+                        if 'PROCESSING_REQUIRED' not in Attribute:
+                            Attribute.append('PROCESSING_REQUIRED')
+                    GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
+                                                         Guid=self.NameGuid, GuidAttr=Attribute,
+                                                         GuidHdrLen=HeaderLength, IsMakefile=IsMakefile)
 
-            #
-            # Call Gensection Add Section Header
-            #
-            if self.ProcessRequired in ("TRUE", "1"):
-                if 'PROCESSING_REQUIRED' not in Attribute:
-                    Attribute.append('PROCESSING_REQUIRED')
-
-            if self.AuthStatusValid in ("TRUE", "1"):
-                Attribute.append('AUTH_STATUS_VALID')
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
-                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
             OutputFileList = []
             OutputFileList.append(OutputFile)
             if 'PROCESSING_REQUIRED' in Attribute:
                 # reset guided section alignment to none for the processed required guided data
                 self.Alignment = None
diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
index 5e3273d..ab4fae6 100644
--- a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation from FILE statement
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -37,11 +37,11 @@ class OptRomFileStatement:
     #
     #   @param  self        The object pointer
     #   @param  Dict        dictionary contains macro and value pair
     #   @retval string      Generated FFS file name
     #
-    def GenFfs(self, Dict = {}):
+    def GenFfs(self, Dict = {}, IsMakefile=False):
         
         if self.FileName != None:
             self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
         
         return self.FileName
diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
index 069414d..80c4bba 100644
--- a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation from INF statement
 #
-#  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -79,11 +79,11 @@ class OptRomInfStatement (FfsInfStatement):
     #   Generate FFS
     #
     #   @param  self        The object pointer
     #   @retval string      Generated .efi file name
     #
-    def GenFfs(self):
+    def GenFfs(self, IsMakefile=False):
         #
         # Parse Inf file get Module related information
         #
 
         self.__InfParse__()
@@ -96,28 +96,28 @@ class OptRomInfStatement (FfsInfStatement):
         #FileType = Ffs.Ffs.ModuleTypeToFileType[Rule.ModuleType]
         #
         # For the rule only has simpleFile
         #
         if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
-            EfiOutputList = self.__GenSimpleFileSection__(Rule)
+            EfiOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
             return EfiOutputList
         #
         # For Rule has ComplexFile
         #
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
-            EfiOutputList = self.__GenComplexFileSection__(Rule)
+            EfiOutputList = self.__GenComplexFileSection__(Rule, IsMakefile=IsMakefile)
             return EfiOutputList
 
     ## __GenSimpleFileSection__() method
     #
     #   Get .efi files according to simple rule.
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenSimpleFileSection__(self, Rule):
+    def __GenSimpleFileSection__(self, Rule, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
 
         OutputFileList = []
@@ -136,11 +136,11 @@ class OptRomInfStatement (FfsInfStatement):
     #
     #   @param  self        The object pointer
     #   @param  Rule        The rule object used to generate section
     #   @retval string      File name of the generated section file
     #
-    def __GenComplexFileSection__(self, Rule):
+    def __GenComplexFileSection__(self, Rule, IsMakefile=False):
 
         OutputFileList = []
         for Sect in Rule.SectionList:
             if Sect.SectionType == 'PE32':
                 if Sect.FileName != None:
diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py
index 7886a7c..2e61a38 100644
--- a/BaseTools/Source/Python/GenFds/OptionRom.py
+++ b/BaseTools/Source/Python/GenFds/OptionRom.py
@@ -1,9 +1,9 @@
 ## @file
 # process OptionROM generation
 #
-#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -47,22 +47,22 @@ class OPTIONROM (OptionRomClassObject):
     #
     #   @param  self        The object pointer
     #   @param  Buffer      The buffer generated OptROM data will be put
     #   @retval string      Generated OptROM file path
     #
-    def AddToBuffer (self, Buffer) :
-
-        GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
+    def AddToBuffer (self, Buffer, Flag=False) :
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
 
         EfiFileList = []
         BinFileList = []
 
         # Process Modules in FfsList
         for FfsFile in self.FfsList :
             
             if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement):
-                FilePathNameList = FfsFile.GenFfs()
+                FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag)
                 if len(FilePathNameList) == 0:
                     EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName))
                 if FfsFile.OverrideAttribs == None:
                     EfiFileList.extend(FilePathNameList)
                 else:
@@ -77,14 +77,15 @@ class OPTIONROM (OptionRomClassObject):
                                                            [], 
                                                            FfsFile.OverrideAttribs.NeedCompress, 
                                                            FfsFile.OverrideAttribs.PciClassCode, 
                                                            FfsFile.OverrideAttribs.PciRevision, 
                                                            FfsFile.OverrideAttribs.PciDeviceId, 
-                                                           FfsFile.OverrideAttribs.PciVendorId)
+                                                           FfsFile.OverrideAttribs.PciVendorId,
+                                                           IsMakefile = Flag)
                     BinFileList.append(TmpOutputFile)
             else:
-                FilePathName = FfsFile.GenFfs()
+                FilePathName = FfsFile.GenFfs(IsMakefile=Flag)
                 if FfsFile.OverrideAttribs != None:
                     FileName = os.path.basename(FilePathName)
                     TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
                     if not os.path.exists(TmpOutputDir) :
                         os.makedirs(TmpOutputDir)
@@ -95,11 +96,12 @@ class OPTIONROM (OptionRomClassObject):
                                                            [], 
                                                            FfsFile.OverrideAttribs.NeedCompress, 
                                                            FfsFile.OverrideAttribs.PciClassCode, 
                                                            FfsFile.OverrideAttribs.PciRevision, 
                                                            FfsFile.OverrideAttribs.PciDeviceId, 
-                                                           FfsFile.OverrideAttribs.PciVendorId)
+                                                           FfsFile.OverrideAttribs.PciVendorId,
+                                                           IsMakefile=Flag)
                     BinFileList.append(TmpOutputFile)
                 else:
                     if FfsFile.FileType == 'EFI':
                         EfiFileList.append(FilePathName)
                     else:
@@ -112,14 +114,15 @@ class OPTIONROM (OptionRomClassObject):
         OutputFile = OutputFile + '.rom'
         
         GenFdsGlobalVariable.GenerateOptionRom(
                                 OutputFile,
                                 EfiFileList,
-                                BinFileList
-                                )
+                                BinFileList,
+                                IsMakefile=Flag)
 
-        GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
         GenFdsGlobalVariable.SharpCounter = 0
         
         return OutputFile
 
 class OverrideAttribs:
diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py
index 945c548..c946758 100644
--- a/BaseTools/Source/Python/GenFds/Region.py
+++ b/BaseTools/Source/Python/GenFds/Region.py
@@ -1,9 +1,9 @@
 ## @file
 # process FD Region generation
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -72,15 +72,18 @@ class Region(RegionClassObject):
     #   @param  VtfDict     VTF objects
     #   @param  MacroDict   macro value pair
     #   @retval string      Generated FV file path
     #
 
-    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}):
+    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}, Flag=False):
         Size = self.Size
-        GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
-        GenFdsGlobalVariable.InfLogger("   Region Size = 0x%X" % Size)
+        if not Flag:
+            GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
+            GenFdsGlobalVariable.InfLogger("   Region Size = 0x%X" % Size)
         GenFdsGlobalVariable.SharpCounter = 0
+        if Flag and (self.RegionType != 'FV'):
+            return
 
         if self.RegionType == 'FV':
             #
             # Get Fv from FvDict
             #
@@ -89,30 +92,33 @@ class Region(RegionClassObject):
             FvOffset = 0
             for RegionData in self.RegionDataList:
                 FileName = None
                 if RegionData.endswith(".fv"):
                     RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
-                    GenFdsGlobalVariable.InfLogger('   Region FV File Name = .fv : %s' % RegionData)
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('   Region FV File Name = .fv : %s' % RegionData)
                     if RegionData[1] != ':' :
                         RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
                     if not os.path.exists(RegionData):
                         EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
 
                     FileName = RegionData
                 elif RegionData.upper() + 'fv' in ImageBinDict.keys():
-                    GenFdsGlobalVariable.InfLogger('   Region Name = FV')
+                    if not Flag:
+                        GenFdsGlobalVariable.InfLogger('   Region Name = FV')
                     FileName = ImageBinDict[RegionData.upper() + 'fv']
                 else:
                     #
                     # Generate FvImage.
                     #
                     FvObj = None
                     if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
                         FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
 
                     if FvObj != None :
-                        GenFdsGlobalVariable.InfLogger('   Region Name = FV')
+                        if not Flag:
+                            GenFdsGlobalVariable.InfLogger('   Region Name = FV')
                         #
                         # Call GenFv tool
                         #
                         self.BlockInfoOfRegion(BlockSizeList, FvObj)
                         self.FvAddress = self.FvAddress + FvOffset
@@ -122,11 +128,14 @@ class Region(RegionClassObject):
                                             "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
                         FvBuffer = StringIO.StringIO('')
                         FvBaseAddress = '0x%X' % self.FvAddress
                         BlockSize = None
                         BlockNum = None
-                        FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
+                        FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict, Flag=Flag)
+                        if Flag:
+                            continue
+
                         if FvBuffer.len > Size:
                             FvBuffer.close()
                             EdkLogger.error("GenFds", GENFDS_ERROR,
                                             "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
                         #
@@ -140,24 +149,26 @@ class Region(RegionClassObject):
                     else:
                         EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
                 #
                 # Add the exist Fv image into FD buffer
                 #
-                if FileName != None:
-                    FileLength = os.stat(FileName)[ST_SIZE]
-                    if FileLength > Size:
-                        EdkLogger.error("GenFds", GENFDS_ERROR,
-                                        "Size of FV File (%s) is larger than Region Size 0x%X specified." \
-                                        % (RegionData, Size))
-                    BinFile = open(FileName, 'rb')
-                    Buffer.write(BinFile.read())
-                    BinFile.close()
-                    Size = Size - FileLength
+                if not Flag:
+                    if FileName != None:
+                        FileLength = os.stat(FileName)[ST_SIZE]
+                        if FileLength > Size:
+                            EdkLogger.error("GenFds", GENFDS_ERROR,
+                                            "Size of FV File (%s) is larger than Region Size 0x%X specified." \
+                                            % (RegionData, Size))
+                        BinFile = open(FileName, 'rb')
+                        Buffer.write(BinFile.read())
+                        BinFile.close()
+                        Size = Size - FileLength
             #
             # Pad the left buffer
             #
-            self.PadBuffer(Buffer, ErasePolarity, Size)
+            if not Flag:
+                self.PadBuffer(Buffer, ErasePolarity, Size)
 
         if self.RegionType == 'CAPSULE':
             #
             # Get Capsule from Capsule Dict
             #
diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py
index 942dd5c..4c1aaac 100644
--- a/BaseTools/Source/Python/GenFds/Section.py
+++ b/BaseTools/Source/Python/GenFds/Section.py
@@ -1,9 +1,9 @@
 ## @file
 # section base class
 #
-#  Copyright (c) 2007-2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007-2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -139,11 +139,11 @@ class Section (SectionClassObject):
                     else:
                         GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType))
                 else:
                     GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName))
 
-        if Suffix != None and os.path.exists(FfsInf.EfiOutputPath):
+        if Suffix != None:
             #
             # Get Makefile path and time stamp
             #
             MakefileDir = FfsInf.EfiOutputPath[:-len('OUTPUT')]
             Makefile = os.path.join(MakefileDir, 'Makefile')
diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py
index 419e1ee..4f6926f 100644
--- a/BaseTools/Source/Python/GenFds/UiSection.py
+++ b/BaseTools/Source/Python/GenFds/UiSection.py
@@ -46,11 +46,11 @@ class UiSection (UiSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsInf != None:
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
@@ -67,11 +67,10 @@ class UiSection (UiSectionClassObject):
             FileObj = open(FileNameStr, 'r')
             NameString = FileObj.read()
             FileObj.close()
         else:
             NameString = ''
-
-        GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString)
+        GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString, IsMakefile=IsMakefile)
 
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py
index ad995d3..e290299 100644
--- a/BaseTools/Source/Python/GenFds/VerSection.py
+++ b/BaseTools/Source/Python/GenFds/VerSection.py
@@ -1,9 +1,9 @@
 ## @file
 # process Version section generation
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -46,11 +46,11 @@ class VerSection (VerSectionClassObject):
     #   @param  KeyStringList  Filter for inputs of section generation
     #   @param  FfsInf      FfsInfStatement object that contains this section data
     #   @param  Dict        dictionary contains macro and its value
     #   @retval tuple       (Generated file name, section alignment)
     #
-    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}):
+    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile = False):
         #
         # Prepare the parameter of GenSection
         #
         if FfsInf != None:
             self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
@@ -63,21 +63,20 @@ class VerSection (VerSectionClassObject):
         OutputFile = os.path.normpath(OutputFile)
 
         # Get String Data
         StringData = ''
         if self.StringData != None:
-             StringData = self.StringData
+            StringData = self.StringData
         elif self.FileName != None:
             FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
             FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
             FileObj = open(FileNameStr, 'r')
             StringData = FileObj.read()
             StringData = '"' + StringData + '"'
             FileObj.close()
         else:
             StringData = ''
-
         GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
-                                             Ver=StringData, BuildNumber=self.BuildNum)
+                                             Ver=StringData, BuildNumber=self.BuildNum, IsMakefile=IsMakefile)
         OutputFileList = []
         OutputFileList.append(OutputFile)
         return OutputFileList, self.Alignment
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 53f1245..f94285a 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -48,10 +48,11 @@ from BuildReport import BuildReport
 from GenPatchPcdTable.GenPatchPcdTable import *
 from PatchPcdValue.PatchPcdValue import *
 
 import Common.EdkLogger
 import Common.GlobalData as GlobalData
+from GenFds.GenFds import GenFds
 
 # Version and Copyright
 VersionNumber = "0.60" + ' ' + gBUILD_VERSION
 __version__ = "%prog Version " + VersionNumber
 __copyright__ = "Copyright (c) 2007 - 2017, Intel Corporation  All rights reserved."
@@ -772,10 +773,11 @@ class Build():
         #Set global flag for build mode
         GlobalData.gIgnoreSource = BuildOptions.IgnoreSources
         GlobalData.gUseHashCache = BuildOptions.UseHashCache
         GlobalData.gBinCacheDest   = BuildOptions.BinCacheDest
         GlobalData.gBinCacheSource = BuildOptions.BinCacheSource
+        GlobalData.gEnableGenfdsMultiThread = BuildOptions.GenfdsMultiThread
 
         if GlobalData.gBinCacheDest and not GlobalData.gUseHashCache:
             EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination must be used together with --hash.")
 
         if GlobalData.gBinCacheSource and not GlobalData.gUseHashCache:
@@ -1206,11 +1208,11 @@ class Build():
     #   @param  CreateDepModuleCodeFile     Flag used to indicate creating code
     #                                       for dependent modules/Libraries
     #   @param  CreateDepModuleMakeFile     Flag used to indicate creating makefile
     #                                       for dependent modules/Libraries
     #
-    def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False):
+    def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand={}):
         if AutoGenObject == None:
             return False
 
         # skip file generation for cleanxxx targets, run and fds target
         if Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
@@ -1222,11 +1224,11 @@ class Build():
             if Target == "genc":
                 return True
 
             if not self.SkipAutoGen or Target == 'genmake':
                 self.Progress.Start("Generating makefile")
-                AutoGenObject.CreateMakeFile(CreateDepsMakeFile)
+                AutoGenObject.CreateMakeFile(CreateDepsMakeFile, FfsCommand)
                 self.Progress.Stop("done!")
             if Target == "genmake":
                 return True
         else:
             # always recreate top/platform makefile when clean, just in case of inconsistency
@@ -1729,20 +1731,26 @@ class Build():
                         )
                 self.Fdf = Wa.FdfFile
                 self.LoadFixAddress = Wa.Platform.LoadFixAddress
                 self.BuildReport.AddPlatformReport(Wa)
                 self.Progress.Stop("done!")
+
+                # Add ffs build to makefile
+                CmdListDict = {}
+                if GlobalData.gEnableGenfdsMultiThread and self.Fdf:
+                    CmdListDict = self._GenFfsCmd()
+
                 for Arch in Wa.ArchList:
                     GlobalData.gGlobalDefines['ARCH'] = Arch
                     Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch)
                     for Module in Pa.Platform.Modules:
                         # Get ModuleAutoGen object to generate C code file and makefile
                         Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile)
                         if Ma == None:
                             continue
                         self.BuildModules.append(Ma)
-                    self._BuildPa(self.Target, Pa)
+                    self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict)
 
                 # Create MAP file when Load Fix Address is enabled.
                 if self.Target in ["", "all", "fds"]:
                     for Arch in Wa.ArchList:
                         GlobalData.gGlobalDefines['ARCH'] = Arch
@@ -1817,10 +1825,14 @@ class Build():
                         self.ModuleFile
                         )
                 self.Fdf = Wa.FdfFile
                 self.LoadFixAddress = Wa.Platform.LoadFixAddress
                 Wa.CreateMakeFile(False)
+                # Add ffs build to makefile
+                CmdListDict = None
+                if GlobalData.gEnableGenfdsMultiThread and self.Fdf:
+                    CmdListDict = self._GenFfsCmd()
                 self.Progress.Stop("done!")
                 MaList = []
                 ExitFlag = threading.Event()
                 ExitFlag.clear()
                 self.AutoGenTime += int(round((time.time() - WorkspaceAutoGenTime)))
@@ -1836,11 +1848,15 @@ class Build():
                             if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
                                 # for target which must generate AutoGen code and makefile
                                 if not self.SkipAutoGen or self.Target == 'genc':
                                     Ma.CreateCodeFile(True)
                                 if not self.SkipAutoGen or self.Target == 'genmake':
-                                    Ma.CreateMakeFile(True)
+                                    if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict:
+                                        Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch])
+                                        del CmdListDict[Module.File, Arch]
+                                    else:
+                                        Ma.CreateMakeFile(True)
                             MaList.append(Ma)
                             self.BuildModules.append(Ma)
                     self.AutoGenTime += int(round((time.time() - AutoGenStart)))
                     MakeStart = time.time()
                     for Ma in self.BuildModules:
@@ -1920,10 +1936,21 @@ class Build():
                     #
                     # Save MAP buffer into MAP file.
                     #
                     self._SaveMapFile (MapBuffer, Wa)
 
+    def _GenFfsCmd(self):
+        CmdListDict = {}
+        GenFfsDict = GenFds.GenFfsMakefile('', GlobalData.gFdfParser, self, self.ArchList, GlobalData)
+        for Cmd in GenFfsDict:
+            tmpInf, tmpArch = GenFfsDict[Cmd]
+            if (tmpInf, tmpArch) not in CmdListDict.keys():
+                CmdListDict[tmpInf, tmpArch] = [Cmd]
+            else:
+                CmdListDict[tmpInf, tmpArch].append(Cmd)
+        return CmdListDict
+
     ## Build a platform in multi-thread mode
     #
     def _MultiThreadBuildPlatform(self):
         SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)
         for BuildTarget in self.BuildTargetList:
@@ -1955,10 +1982,15 @@ class Build():
                 self.Fdf = Wa.FdfFile
                 self.LoadFixAddress = Wa.Platform.LoadFixAddress
                 self.BuildReport.AddPlatformReport(Wa)
                 Wa.CreateMakeFile(False)
 
+                # Add ffs build to makefile
+                CmdListDict = None
+                if GlobalData.gEnableGenfdsMultiThread and self.Fdf:
+                    CmdListDict = self._GenFfsCmd()
+
                 # multi-thread exit flag
                 ExitFlag = threading.Event()
                 ExitFlag.clear()
                 self.AutoGenTime += int(round((time.time() - WorkspaceAutoGenTime)))
                 for Arch in Wa.ArchList:
@@ -1993,11 +2025,15 @@ class Build():
                                 Ma.CreateCodeFile(True)
                             if self.Target == "genc":
                                 continue
 
                             if not self.SkipAutoGen or self.Target == 'genmake':
-                                Ma.CreateMakeFile(True)
+                                if CmdListDict and self.Fdf and (Module.File, Arch) in CmdListDict:
+                                    Ma.CreateMakeFile(True, CmdListDict[Module.File, Arch])
+                                    del CmdListDict[Module.File, Arch]
+                                else:
+                                    Ma.CreateMakeFile(True)
                             if self.Target == "genmake":
                                 continue
                         self.BuildModules.append(Ma)
                     self.Progress.Stop("done!")
                     self.AutoGenTime += int(round((time.time() - AutoGenStart)))
@@ -2309,11 +2345,11 @@ def MyOptionParser():
     Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
     Parser.add_option("-l", "--cmd-len", action="store", type="int", dest="CommandLength", help="Specify the maximum line length of build command. Default is 4096.")
     Parser.add_option("--hash", action="store_true", dest="UseHashCache", default=False, help="Enable hash-based caching during build process.")
     Parser.add_option("--binary-destination", action="store", type="string", dest="BinCacheDest", help="Generate a cache of binary files in the specified directory.")
     Parser.add_option("--binary-source", action="store", type="string", dest="BinCacheSource", help="Consume a cache of binary files from the specified directory.")
-
+    Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")
     (Opt, Args) = Parser.parse_args()
     return (Opt, Args)
 
 ## Tool entrance method
 #
-- 
2.6.1.windows.1



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

* Re: [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file
  2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
                   ` (3 preceding siblings ...)
  2017-11-29 14:02 ` [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation Yonghong Zhu
@ 2017-12-01  6:13 ` Gao, Liming
  4 siblings, 0 replies; 11+ messages in thread
From: Gao, Liming @ 2017-12-01  6:13 UTC (permalink / raw)
  To: Zhu, Yonghong, edk2-devel@lists.01.org

Reviewed-by: Liming Gao <liming.gao@intel.com>

>-----Original Message-----
>From: Zhu, Yonghong
>Sent: Wednesday, November 29, 2017 10:02 PM
>To: edk2-devel@lists.01.org
>Cc: Gao, Liming <liming.gao@intel.com>
>Subject: [edk2] [Patch 0/4 V3] BaseTools: Enable multiple thread to generate
>FFS file
>
>V3: add a new build option --genfds-multi-thread for this feature, default is
>False.
>
>These patches enable multiple thread to generate ffs file by merge FFS file's
>generation into Make phase.
>
>Cc: Liming Gao <liming.gao@intel.com>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
>
>Yonghong Zhu (4):
>  BaseTools: GenFfs support to get alignment value from SectionFile
>  BaseTools: Update Trim to generate VfrBinOffset Binary
>  BaseTools: Update Gensec to set PROCESSING_REQUIRED value
>  BaseTools: Update Makefile to support FFS file generation
>
> BaseTools/Source/C/GenFfs/GenFfs.c                 | 135 +++++++++++++-
> BaseTools/Source/C/GenSec/GenSec.c                 |  74 ++++++++
> BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
> BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
> BaseTools/Source/Python/Common/GlobalData.py       |   1 +
> BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
> BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
> BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
> BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
> BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
> BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
> BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
> BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202
>++++++++++++---------
> BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
> BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
> BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
> .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174
>++++++++++++++----
> BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++-------
>-
> .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
> .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
> BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
> BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
> BaseTools/Source/Python/GenFds/Section.py          |   4 +-
> BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
> BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
> BaseTools/Source/Python/Trim/Trim.py               |  81 ++++++++-
> BaseTools/Source/Python/build/build.py             |  48 ++++-
> 27 files changed, 1077 insertions(+), 417 deletions(-)
>
>--
>2.6.1.windows.1



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

* Re: [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value
  2017-11-29 14:02 ` [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value Yonghong Zhu
@ 2017-12-05 11:53   ` Leif Lindholm
  2017-12-05 13:56     ` Zhu, Yonghong
  0 siblings, 1 reply; 11+ messages in thread
From: Leif Lindholm @ 2017-12-05 11:53 UTC (permalink / raw)
  To: Yonghong Zhu; +Cc: edk2-devel, Yunhua Feng, Liming Gao

This patch has broken BaseTools build with GCC on master:

make -C GenSec
make[2]: Entering directory '/work/git/edk2/BaseTools/Source/C/GenSec'
gcc  -c -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-unused-result -nostdlib -c -g  -I .. -I ../Include/Common -I ../Include/ -I ../Include/IndustryStandard -I ../Common/ -I .. -I . -I ../Include/X64/  -O2 GenSec.c -o GenSec.o
In file included from ../Include/Common/UefiBaseTypes.h:19:0,
                 from GenSec.c:20:
GenSec.c: In function ‘main’:
../Include/Common/BaseTypes.h:178:38: error: overflow in implicit constant conversion [-Werror=overflow]
 #define ENCODE_ERROR(a)              (MAX_BIT | (a))
                                      ^
../Include/Common/BaseTypes.h:204:38: note: in expansion of macro ‘ENCODE_ERROR’
 #define RETURN_ABORTED               ENCODE_ERROR (21)
                                      ^~~~~~~~~~~~
../Include/Common/UefiBaseTypes.h:119:35: note: in expansion of macro ‘RETURN_ABORTED’
 #define EFI_ABORTED               RETURN_ABORTED              
                                   ^~~~~~~~~~~~~~
GenSec.c:1329:16: note: in expansion of macro ‘EFI_ABORTED’
         return EFI_ABORTED;
                ^~~~~~~~~~~
../Include/Common/BaseTypes.h:178:38: error: overflow in implicit constant conversion [-Werror=overflow]
 #define ENCODE_ERROR(a)              (MAX_BIT | (a))
                                      ^
../Include/Common/BaseTypes.h:204:38: note: in expansion of macro ‘ENCODE_ERROR’
 #define RETURN_ABORTED               ENCODE_ERROR (21)
                                      ^~~~~~~~~~~~
../Include/Common/UefiBaseTypes.h:119:35: note: in expansion of macro ‘RETURN_ABORTED’
 #define EFI_ABORTED               RETURN_ABORTED              
                                   ^~~~~~~~~~~~~~
GenSec.c:1343:16: note: in expansion of macro ‘EFI_ABORTED’
         return EFI_ABORTED;
                ^~~~~~~~~~~
GenSec.c:1354:21: error: pointer targets in passing argument 1 of ‘strcasecmp’ differ in signedness [-Werror=pointer-sign]
         if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
                     ^~~~~~~~~~~~~~~
In file included from GenSec.c:17:0:
/usr/include/string.h:529:12: note: expected ‘const char *’ but argument is of type ‘UINT8 * {aka unsigned char *}’
 extern int strcasecmp (const char *__s1, const char *__s2)
            ^~~~~~~~~~
GenSec.c:1354:38: error: pointer targets in passing argument 2 of ‘strcasecmp’ differ in signedness [-Werror=pointer-sign]
         if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
                                      ^~~~~~~~~~~~
In file included from GenSec.c:17:0:
/usr/include/string.h:529:12: note: expected ‘const char *’ but argument is of type ‘UINT8 * {aka unsigned char *}’
 extern int strcasecmp (const char *__s1, const char *__s2)
            ^~~~~~~~~~
cc1: all warnings being treated as errors
../Makefiles/footer.makefile:27: recipe for target 'GenSec.o' failed
make[2]: *** [GenSec.o] Error 1
make[2]: Leaving directory '/work/git/edk2/BaseTools/Source/C/GenSec'
GNUmakefile:84: recipe for target 'GenSec' failed
make[1]: *** [GenSec] Error 2
make[1]: Leaving directory '/work/git/edk2/BaseTools/Source/C'
GNUmakefile:25: recipe for target 'Source/C' failed
make: *** [Source/C] Error 2
make: Leaving directory '/work/git/edk2/BaseTools'


On Wed, Nov 29, 2017 at 10:02:05PM +0800, Yonghong Zhu wrote:
> This patch add new option --dummy file, and we compare the dummpy file
> with input file to decide whether we need to set PROCESSING_REQUIRED
> value.
> 
> Cc: Liming Gao <liming.gao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
> ---
>  BaseTools/Source/C/GenSec/GenSec.c | 74 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 74 insertions(+)
> 
> diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
> index d9cdc1f..904926c 100644
> --- a/BaseTools/Source/C/GenSec/GenSec.c
> +++ b/BaseTools/Source/C/GenSec/GenSec.c
> @@ -185,10 +185,13 @@ Returns:
>                          used in Ver section.\n");
>    fprintf (stdout, "  --sectionalign SectionAlign\n\
>                          SectionAlign points to section alignment, which support\n\
>                          the alignment scope 1~16M. It is specified in same\n\
>                          order that the section file is input.\n");
> +  fprintf (stdout, "  --dummy dummyfile\n\
> +                        compare dummpyfile with input_file to decide whether\n\
> +                        need to set PROCESSING_REQUIRED attribute.\n");
>    fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
>    fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
>    fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
>    fprintf (stdout, "  --version             Show program's version number and exit.\n");
>    fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
> @@ -1026,10 +1029,17 @@ Returns:
>    EFI_STATUS                Status;
>    UINT64                    LogLevel;
>    UINT32                    *InputFileAlign;
>    UINT32                    InputFileAlignNum;
>    EFI_COMMON_SECTION_HEADER *SectionHeader;
> +  CHAR8                     *DummyFileName;
> +  FILE                      *DummyFile;
> +  UINTN                     DummyFileSize;
> +  UINT8                     *DummyFileBuffer;
> +  FILE                      *InFile;
> +  UINT8                     *InFileBuffer;
> +  UINTN                     InFileSize;
>  
>    InputFileAlign        = NULL;
>    InputFileAlignNum     = 0;
>    InputFileName         = NULL;
>    OutputFileName        = NULL;
> @@ -1047,10 +1057,17 @@ Returns:
>    Status                = STATUS_SUCCESS;
>    LogLevel              = 0;
>    SectGuidHeaderLength  = 0;
>    VersionSect           = NULL;
>    UiSect                = NULL;
> +  DummyFileSize         = 0;
> +  DummyFileName         = NULL;
> +  DummyFile             = NULL;
> +  DummyFileBuffer       = NULL;
> +  InFile                = NULL;
> +  InFileSize            = 0;
> +  InFileBuffer          = NULL;
>    
>    SetUtilityName (UTILITY_NAME);
>    
>    if (argc == 1) {
>      Error (NULL, 0, 1001, "Missing options", "No options input");
> @@ -1117,10 +1134,20 @@ Returns:
>        }
>        argc -= 2;
>        argv += 2;
>        continue;
>      }
> +    if (stricmp (argv[0], "--dummy") == 0) {
> +      DummyFileName = argv[1];
> +      if (DummyFileName == NULL) {
> +        Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");
> +        goto Finish;
> +      }
> +      argc -= 2;
> +      argv += 2;
> +      continue;
> +    }
>  
>      if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {
>        if (argv[1] == NULL) {
>          Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
>          goto Finish;
> @@ -1290,10 +1317,57 @@ Returns:
>      goto Finish;
>    }
>  
>    VerboseMsg ("%s tool start.", UTILITY_NAME);
>  
> +  if (DummyFileName != NULL) {
> +      //
> +      // Open file and read contents
> +      //
> +      DummyFile = fopen (LongFilePath (DummyFileName), "rb");
> +      if (DummyFile == NULL) {
> +        Error (NULL, 0, 0001, "Error opening file", DummyFileName);
> +        return EFI_ABORTED;
> +      }
> +
> +      fseek (DummyFile, 0, SEEK_END);
> +      DummyFileSize = ftell (DummyFile);
> +      fseek (DummyFile, 0, SEEK_SET);
> +      DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);
> +      fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);
> +      fclose(DummyFile);
> +      DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);
> +
> +      InFile = fopen(LongFilePath(InputFileName[0]), "rb");
> +      if (InFile == NULL) {
> +        Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);
> +        return EFI_ABORTED;
> +      }
> +
> +      fseek (InFile, 0, SEEK_END);
> +      InFileSize = ftell (InFile);
> +      fseek (InFile, 0, SEEK_SET);
> +      InFileBuffer = (UINT8 *) malloc (InFileSize);
> +      fread(InFileBuffer, 1, InFileSize, InFile);
> +      fclose(InFile);
> +      DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);
> +      if (InFileSize > DummyFileSize){
> +        if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
> +          SectGuidHeaderLength = InFileSize - DummyFileSize;
> +        }
> +      }
> +      if (SectGuidHeaderLength == 0) {
> +        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
> +      }
> +      if (DummyFileBuffer != NULL) {
> +        free (DummyFileBuffer);
> +      }
> +      if (InFileBuffer != NULL) {
> +        free (InFileBuffer);
> +      }
> +    }
> +
>    //
>    // Parse all command line parameters to get the corresponding section type.
>    //
>    VerboseMsg ("Section type is %s", SectionName);
>    if (SectionName == NULL) {
> -- 
> 2.6.1.windows.1
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


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

* Re: [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value
  2017-12-05 11:53   ` Leif Lindholm
@ 2017-12-05 13:56     ` Zhu, Yonghong
  0 siblings, 0 replies; 11+ messages in thread
From: Zhu, Yonghong @ 2017-12-05 13:56 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel@lists.01.org, Feng, YunhuaX, Gao, Liming,
	Zhu, Yonghong

Hi Leif,

Thanks. I just sent out the patch to fix this bug. Could you help to try it?

Best Regards,
Zhu Yonghong


-----Original Message-----
From: Leif Lindholm [mailto:leif.lindholm@linaro.org] 
Sent: Tuesday, December 05, 2017 7:53 PM
To: Zhu, Yonghong <yonghong.zhu@intel.com>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: Re: [edk2] [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value

This patch has broken BaseTools build with GCC on master:

make -C GenSec
make[2]: Entering directory '/work/git/edk2/BaseTools/Source/C/GenSec'
gcc  -c -MD -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-deprecated-declarations -Wno-unused-result -nostdlib -c -g  -I .. -I ../Include/Common -I ../Include/ -I ../Include/IndustryStandard -I ../Common/ -I .. -I . -I ../Include/X64/  -O2 GenSec.c -o GenSec.o In file included from ../Include/Common/UefiBaseTypes.h:19:0,
                 from GenSec.c:20:
GenSec.c: In function ‘main’:
../Include/Common/BaseTypes.h:178:38: error: overflow in implicit constant conversion [-Werror=overflow]
 #define ENCODE_ERROR(a)              (MAX_BIT | (a))
                                      ^
../Include/Common/BaseTypes.h:204:38: note: in expansion of macro ‘ENCODE_ERROR’
 #define RETURN_ABORTED               ENCODE_ERROR (21)
                                      ^~~~~~~~~~~~
../Include/Common/UefiBaseTypes.h:119:35: note: in expansion of macro ‘RETURN_ABORTED’
 #define EFI_ABORTED               RETURN_ABORTED              
                                   ^~~~~~~~~~~~~~
GenSec.c:1329:16: note: in expansion of macro ‘EFI_ABORTED’
         return EFI_ABORTED;
                ^~~~~~~~~~~
../Include/Common/BaseTypes.h:178:38: error: overflow in implicit constant conversion [-Werror=overflow]
 #define ENCODE_ERROR(a)              (MAX_BIT | (a))
                                      ^
../Include/Common/BaseTypes.h:204:38: note: in expansion of macro ‘ENCODE_ERROR’
 #define RETURN_ABORTED               ENCODE_ERROR (21)
                                      ^~~~~~~~~~~~
../Include/Common/UefiBaseTypes.h:119:35: note: in expansion of macro ‘RETURN_ABORTED’
 #define EFI_ABORTED               RETURN_ABORTED              
                                   ^~~~~~~~~~~~~~
GenSec.c:1343:16: note: in expansion of macro ‘EFI_ABORTED’
         return EFI_ABORTED;
                ^~~~~~~~~~~
GenSec.c:1354:21: error: pointer targets in passing argument 1 of ‘strcasecmp’ differ in signedness [-Werror=pointer-sign]
         if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
                     ^~~~~~~~~~~~~~~
In file included from GenSec.c:17:0:
/usr/include/string.h:529:12: note: expected ‘const char *’ but argument is of type ‘UINT8 * {aka unsigned char *}’
 extern int strcasecmp (const char *__s1, const char *__s2)
            ^~~~~~~~~~
GenSec.c:1354:38: error: pointer targets in passing argument 2 of ‘strcasecmp’ differ in signedness [-Werror=pointer-sign]
         if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
                                      ^~~~~~~~~~~~ In file included from GenSec.c:17:0:
/usr/include/string.h:529:12: note: expected ‘const char *’ but argument is of type ‘UINT8 * {aka unsigned char *}’
 extern int strcasecmp (const char *__s1, const char *__s2)
            ^~~~~~~~~~
cc1: all warnings being treated as errors
../Makefiles/footer.makefile:27: recipe for target 'GenSec.o' failed
make[2]: *** [GenSec.o] Error 1
make[2]: Leaving directory '/work/git/edk2/BaseTools/Source/C/GenSec'
GNUmakefile:84: recipe for target 'GenSec' failed
make[1]: *** [GenSec] Error 2
make[1]: Leaving directory '/work/git/edk2/BaseTools/Source/C'
GNUmakefile:25: recipe for target 'Source/C' failed
make: *** [Source/C] Error 2
make: Leaving directory '/work/git/edk2/BaseTools'


On Wed, Nov 29, 2017 at 10:02:05PM +0800, Yonghong Zhu wrote:
> This patch add new option --dummy file, and we compare the dummpy file 
> with input file to decide whether we need to set PROCESSING_REQUIRED 
> value.
> 
> Cc: Liming Gao <liming.gao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
> ---
>  BaseTools/Source/C/GenSec/GenSec.c | 74 
> ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 74 insertions(+)
> 
> diff --git a/BaseTools/Source/C/GenSec/GenSec.c 
> b/BaseTools/Source/C/GenSec/GenSec.c
> index d9cdc1f..904926c 100644
> --- a/BaseTools/Source/C/GenSec/GenSec.c
> +++ b/BaseTools/Source/C/GenSec/GenSec.c
> @@ -185,10 +185,13 @@ Returns:
>                          used in Ver section.\n");
>    fprintf (stdout, "  --sectionalign SectionAlign\n\
>                          SectionAlign points to section alignment, which support\n\
>                          the alignment scope 1~16M. It is specified in same\n\
>                          order that the section file is input.\n");
> +  fprintf (stdout, "  --dummy dummyfile\n\
> +                        compare dummpyfile with input_file to decide whether\n\
> +                        need to set PROCESSING_REQUIRED 
> + attribute.\n");
>    fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");
>    fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");
>    fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");
>    fprintf (stdout, "  --version             Show program's version number and exit.\n");
>    fprintf (stdout, "  -h, --help            Show this help message and exit.\n");
> @@ -1026,10 +1029,17 @@ Returns:
>    EFI_STATUS                Status;
>    UINT64                    LogLevel;
>    UINT32                    *InputFileAlign;
>    UINT32                    InputFileAlignNum;
>    EFI_COMMON_SECTION_HEADER *SectionHeader;
> +  CHAR8                     *DummyFileName;
> +  FILE                      *DummyFile;
> +  UINTN                     DummyFileSize;
> +  UINT8                     *DummyFileBuffer;
> +  FILE                      *InFile;
> +  UINT8                     *InFileBuffer;
> +  UINTN                     InFileSize;
>  
>    InputFileAlign        = NULL;
>    InputFileAlignNum     = 0;
>    InputFileName         = NULL;
>    OutputFileName        = NULL;
> @@ -1047,10 +1057,17 @@ Returns:
>    Status                = STATUS_SUCCESS;
>    LogLevel              = 0;
>    SectGuidHeaderLength  = 0;
>    VersionSect           = NULL;
>    UiSect                = NULL;
> +  DummyFileSize         = 0;
> +  DummyFileName         = NULL;
> +  DummyFile             = NULL;
> +  DummyFileBuffer       = NULL;
> +  InFile                = NULL;
> +  InFileSize            = 0;
> +  InFileBuffer          = NULL;
>    
>    SetUtilityName (UTILITY_NAME);
>    
>    if (argc == 1) {
>      Error (NULL, 0, 1001, "Missing options", "No options input"); @@ 
> -1117,10 +1134,20 @@ Returns:
>        }
>        argc -= 2;
>        argv += 2;
>        continue;
>      }
> +    if (stricmp (argv[0], "--dummy") == 0) {
> +      DummyFileName = argv[1];
> +      if (DummyFileName == NULL) {
> +        Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");
> +        goto Finish;
> +      }
> +      argc -= 2;
> +      argv += 2;
> +      continue;
> +    }
>  
>      if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {
>        if (argv[1] == NULL) {
>          Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");
>          goto Finish;
> @@ -1290,10 +1317,57 @@ Returns:
>      goto Finish;
>    }
>  
>    VerboseMsg ("%s tool start.", UTILITY_NAME);
>  
> +  if (DummyFileName != NULL) {
> +      //
> +      // Open file and read contents
> +      //
> +      DummyFile = fopen (LongFilePath (DummyFileName), "rb");
> +      if (DummyFile == NULL) {
> +        Error (NULL, 0, 0001, "Error opening file", DummyFileName);
> +        return EFI_ABORTED;
> +      }
> +
> +      fseek (DummyFile, 0, SEEK_END);
> +      DummyFileSize = ftell (DummyFile);
> +      fseek (DummyFile, 0, SEEK_SET);
> +      DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);
> +      fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);
> +      fclose(DummyFile);
> +      DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s 
> + and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);
> +
> +      InFile = fopen(LongFilePath(InputFileName[0]), "rb");
> +      if (InFile == NULL) {
> +        Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);
> +        return EFI_ABORTED;
> +      }
> +
> +      fseek (InFile, 0, SEEK_END);
> +      InFileSize = ftell (InFile);
> +      fseek (InFile, 0, SEEK_SET);
> +      InFileBuffer = (UINT8 *) malloc (InFileSize);
> +      fread(InFileBuffer, 1, InFileSize, InFile);
> +      fclose(InFile);
> +      DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);
> +      if (InFileSize > DummyFileSize){
> +        if (stricmp(DummyFileBuffer, InFileBuffer + (InFileSize - DummyFileSize)) == 0){
> +          SectGuidHeaderLength = InFileSize - DummyFileSize;
> +        }
> +      }
> +      if (SectGuidHeaderLength == 0) {
> +        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;
> +      }
> +      if (DummyFileBuffer != NULL) {
> +        free (DummyFileBuffer);
> +      }
> +      if (InFileBuffer != NULL) {
> +        free (InFileBuffer);
> +      }
> +    }
> +
>    //
>    // Parse all command line parameters to get the corresponding section type.
>    //
>    VerboseMsg ("Section type is %s", SectionName);
>    if (SectionName == NULL) {
> --
> 2.6.1.windows.1
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

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

* Re: [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation
  2017-11-29 14:02 ` [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation Yonghong Zhu
@ 2017-12-06 18:23   ` Leif Lindholm
  2017-12-07  0:59     ` Zhu, Yonghong
  0 siblings, 1 reply; 11+ messages in thread
From: Leif Lindholm @ 2017-12-06 18:23 UTC (permalink / raw)
  To: Yonghong Zhu; +Cc: edk2-devel, Yunhua Feng, Liming Gao

Hi Yonghong,

I'm afraid I have come across an issue with this one as well:
When trying to build OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b
into a platform (edk2-platforms/Platform/Hisilicon/HiKey/), GenSec
fails with:

Generating FVMAIN FV
####################################
########################################
########Return Value = 2
GenSec: ERROR 0001: Error opening file
  /work/git/tianocore/Build/HiKey/RELEASE_GCC5/AARCH64/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b/OUTPUT/Ax88772b.depex
GenSec: ERROR 2000: Status is not successful

If I revert commit 37de70b7, the platform builds successfully again.
D03 and D05 platforms also appear to have issues with this, but in
that case due to drivers in edk2-non-osi.

/
    Leif

On Wed, Nov 29, 2017 at 10:02:06PM +0800, Yonghong Zhu wrote:
> Update Makefile to support FFS file generation with new build option
> --genfds-multi-thread.
> 
> Cc: Liming Gao <liming.gao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
> ---
>  BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
>  BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
>  BaseTools/Source/Python/Common/GlobalData.py       |   1 +
>  BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
>  BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
>  BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
>  BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
>  BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
>  BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
>  BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
>  BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202 ++++++++++++---------
>  BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
>  BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
>  BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
>  .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174 ++++++++++++++----
>  BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++--------
>  .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
>  .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
>  BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
>  BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
>  BaseTools/Source/Python/GenFds/Section.py          |   4 +-
>  BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
>  BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
>  BaseTools/Source/Python/build/build.py             |  48 ++++-
>  24 files changed, 793 insertions(+), 411 deletions(-)


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

* Re: [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation
  2017-12-06 18:23   ` Leif Lindholm
@ 2017-12-07  0:59     ` Zhu, Yonghong
  2017-12-07  9:59       ` Zhu, Yonghong
  0 siblings, 1 reply; 11+ messages in thread
From: Zhu, Yonghong @ 2017-12-07  0:59 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: edk2-devel@lists.01.org, Feng, YunhuaX, Gao, Liming,
	Zhu, Yonghong

Thanks Leif.  I will provide patch to fix it soon.

Best Regards,
Zhu Yonghong


-----Original Message-----
From: Leif Lindholm [mailto:leif.lindholm@linaro.org] 
Sent: Thursday, December 07, 2017 2:24 AM
To: Zhu, Yonghong <yonghong.zhu@intel.com>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: Re: [edk2] [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation

Hi Yonghong,

I'm afraid I have come across an issue with this one as well:
When trying to build OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b
into a platform (edk2-platforms/Platform/Hisilicon/HiKey/), GenSec fails with:

Generating FVMAIN FV
####################################
########################################
########Return Value = 2
GenSec: ERROR 0001: Error opening file
  /work/git/tianocore/Build/HiKey/RELEASE_GCC5/AARCH64/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b/OUTPUT/Ax88772b.depex
GenSec: ERROR 2000: Status is not successful

If I revert commit 37de70b7, the platform builds successfully again.
D03 and D05 platforms also appear to have issues with this, but in that case due to drivers in edk2-non-osi.

/
    Leif

On Wed, Nov 29, 2017 at 10:02:06PM +0800, Yonghong Zhu wrote:
> Update Makefile to support FFS file generation with new build option 
> --genfds-multi-thread.
> 
> Cc: Liming Gao <liming.gao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
> ---
>  BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
>  BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
>  BaseTools/Source/Python/Common/GlobalData.py       |   1 +
>  BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
>  BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
>  BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
>  BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
>  BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
>  BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
>  BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
>  BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202 ++++++++++++---------
>  BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
>  BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
>  BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
>  .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174 ++++++++++++++----
>  BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++--------
>  .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
>  .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
>  BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
>  BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
>  BaseTools/Source/Python/GenFds/Section.py          |   4 +-
>  BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
>  BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
>  BaseTools/Source/Python/build/build.py             |  48 ++++-
>  24 files changed, 793 insertions(+), 411 deletions(-)


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

* Re: [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation
  2017-12-07  0:59     ` Zhu, Yonghong
@ 2017-12-07  9:59       ` Zhu, Yonghong
  0 siblings, 0 replies; 11+ messages in thread
From: Zhu, Yonghong @ 2017-12-07  9:59 UTC (permalink / raw)
  To: 'Leif Lindholm'
  Cc: 'edk2-devel@lists.01.org', Feng, YunhuaX, Gao, Liming,
	Zhu, Yonghong

Hi Leif,

Please help to check whether this patch " [edk2] [PATCH] BaseTools: Fix GenSec can't found the depex file" can fix it. thanks a lot.

Best Regards,
Zhu Yonghong

-----Original Message-----
From: Zhu, Yonghong 
Sent: Thursday, December 07, 2017 9:00 AM
To: Leif Lindholm <leif.lindholm@linaro.org>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Gao, Liming <liming.gao@intel.com>; Zhu, Yonghong <yonghong.zhu@intel.com>
Subject: RE: [edk2] [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation

Thanks Leif.  I will provide patch to fix it soon.

Best Regards,
Zhu Yonghong


-----Original Message-----
From: Leif Lindholm [mailto:leif.lindholm@linaro.org]
Sent: Thursday, December 07, 2017 2:24 AM
To: Zhu, Yonghong <yonghong.zhu@intel.com>
Cc: edk2-devel@lists.01.org; Feng, YunhuaX <yunhuax.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: Re: [edk2] [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation

Hi Yonghong,

I'm afraid I have come across an issue with this one as well:
When trying to build OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b
into a platform (edk2-platforms/Platform/Hisilicon/HiKey/), GenSec fails with:

Generating FVMAIN FV
####################################
########################################
########Return Value = 2
GenSec: ERROR 0001: Error opening file
  /work/git/tianocore/Build/HiKey/RELEASE_GCC5/AARCH64/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b/OUTPUT/Ax88772b.depex
GenSec: ERROR 2000: Status is not successful

If I revert commit 37de70b7, the platform builds successfully again.
D03 and D05 platforms also appear to have issues with this, but in that case due to drivers in edk2-non-osi.

/
    Leif

On Wed, Nov 29, 2017 at 10:02:06PM +0800, Yonghong Zhu wrote:
> Update Makefile to support FFS file generation with new build option 
> --genfds-multi-thread.
> 
> Cc: Liming Gao <liming.gao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
> Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
> ---
>  BaseTools/Source/Python/AutoGen/AutoGen.py         |  23 ++-
>  BaseTools/Source/Python/AutoGen/GenMake.py         |  90 ++++++++-
>  BaseTools/Source/Python/Common/GlobalData.py       |   1 +
>  BaseTools/Source/Python/GenFds/AprioriSection.py   |  14 +-
>  BaseTools/Source/Python/GenFds/CompressSection.py  |  10 +-
>  BaseTools/Source/Python/GenFds/DataSection.py      |  37 ++--
>  BaseTools/Source/Python/GenFds/DepexSection.py     |   6 +-
>  BaseTools/Source/Python/GenFds/EfiSection.py       |  78 +++++---
>  BaseTools/Source/Python/GenFds/Fd.py               |  24 ++-
>  BaseTools/Source/Python/GenFds/FfsFileStatement.py |   4 +-
>  BaseTools/Source/Python/GenFds/FfsInfStatement.py  | 202 ++++++++++++---------
>  BaseTools/Source/Python/GenFds/Fv.py               | 189 ++++++++++---------
>  BaseTools/Source/Python/GenFds/FvImageSection.py   |   8 +-
>  BaseTools/Source/Python/GenFds/GenFds.py           |  20 ++
>  .../Source/Python/GenFds/GenFdsGlobalVariable.py   | 174 ++++++++++++++----
>  BaseTools/Source/Python/GenFds/GuidSection.py      | 168 +++++++++--------
>  .../Source/Python/GenFds/OptRomFileStatement.py    |   4 +-
>  .../Source/Python/GenFds/OptRomInfStatement.py     |  12 +-
>  BaseTools/Source/Python/GenFds/OptionRom.py        |  25 +--
>  BaseTools/Source/Python/GenFds/Region.py           |  49 +++--
>  BaseTools/Source/Python/GenFds/Section.py          |   4 +-
>  BaseTools/Source/Python/GenFds/UiSection.py        |   5 +-
>  BaseTools/Source/Python/GenFds/VerSection.py       |   9 +-
>  BaseTools/Source/Python/build/build.py             |  48 ++++-
>  24 files changed, 793 insertions(+), 411 deletions(-)


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

end of thread, other threads:[~2017-12-07  9:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-29 14:02 [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Yonghong Zhu
2017-11-29 14:02 ` [Patch 1/4 V3] BaseTools: GenFfs support to get alignment value from SectionFile Yonghong Zhu
2017-11-29 14:02 ` [Patch 2/4 V3] BaseTools: Update Trim to generate VfrBinOffset Binary Yonghong Zhu
2017-11-29 14:02 ` [Patch 3/4 V3] BaseTools: Update Gensec to set PROCESSING_REQUIRED value Yonghong Zhu
2017-12-05 11:53   ` Leif Lindholm
2017-12-05 13:56     ` Zhu, Yonghong
2017-11-29 14:02 ` [Patch 4/4 V3] BaseTools: Update Makefile to support FFS file generation Yonghong Zhu
2017-12-06 18:23   ` Leif Lindholm
2017-12-07  0:59     ` Zhu, Yonghong
2017-12-07  9:59       ` Zhu, Yonghong
2017-12-01  6:13 ` [Patch 0/4 V3] BaseTools: Enable multiple thread to generate FFS file Gao, Liming

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