From fd171542e0aa89ac12a09d79608173f48019b14b Mon Sep 17 00:00:00 2001
From: vanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Fri, 11 Sep 2009 03:14:43 +0000
Subject: Sync basetools' source and binary files with r1707 of the basetools
 project.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9257 6f19259b-4bc3-4df7-8a09-765794883524
---
 BaseTools/Source/Python/GenFds/Capsule.py          |  19 +-
 BaseTools/Source/Python/GenFds/CapsuleData.py      |   7 +-
 BaseTools/Source/Python/GenFds/Fd.py               |  20 +-
 BaseTools/Source/Python/GenFds/FdfParser.py        | 334 +++++++++++++++------
 BaseTools/Source/Python/GenFds/FfsFileStatement.py |   3 +-
 BaseTools/Source/Python/GenFds/Fv.py               |  30 +-
 BaseTools/Source/Python/GenFds/GenFds.py           |  74 ++---
 .../Source/Python/GenFds/GenFdsGlobalVariable.py   |   6 +-
 .../Source/Python/GenFds/OptRomInfStatement.py     |  10 +-
 BaseTools/Source/Python/GenFds/OptionRom.py        |   2 +-
 BaseTools/Source/Python/GenFds/Region.py           | 219 +++++++++-----
 11 files changed, 502 insertions(+), 222 deletions(-)

(limited to 'BaseTools/Source/Python/GenFds')

diff --git a/BaseTools/Source/Python/GenFds/Capsule.py b/BaseTools/Source/Python/GenFds/Capsule.py
index 7f17fcda68..961b88a458 100644
--- a/BaseTools/Source/Python/GenFds/Capsule.py
+++ b/BaseTools/Source/Python/GenFds/Capsule.py
@@ -21,6 +21,7 @@ import os
 import subprocess
 import StringIO
 from Common.Misc import SaveFileOnChange
+from GenFds import GenFds
 
 
 T_CHAR_LF = '\n'
@@ -39,17 +40,26 @@ class Capsule (CapsuleClassObject) :
         self.BlockSize = None
         # For GenFv
         self.BlockNum = None
+        self.CapsuleName = None
 
     ## Generate capsule
     #
     #   @param  self        The object pointer
+    #   @retval string      Generated Capsule file path
     #
     def GenCapsule(self):
+        if self.UiCapsuleName.upper() + 'cap' in GenFds.ImageBinDict.keys():
+            return GenFds.ImageBinDict[self.UiCapsuleName.upper() + 'cap']
+
+        GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" %self.UiCapsuleName)
         CapInfFile = self.GenCapInf()
         CapInfFile.writelines("[files]" + T_CHAR_LF)
-
+        CapFileList = []
         for CapsuleDataObj in self.CapsuleDataList :
+            CapsuleDataObj.CapsuleName = self.CapsuleName
             FileName = CapsuleDataObj.GenCapsuleSubItem()
+            CapsuleDataObj.CapsuleName = None
+            CapFileList.append(FileName)
             CapInfFile.writelines("EFI_FILE_NAME = " + \
                                    FileName      + \
                                    T_CHAR_LF)
@@ -63,9 +73,14 @@ class Capsule (CapsuleClassObject) :
         GenFdsGlobalVariable.GenerateFirmwareVolume(
                                 CapOutputFile,
                                 [self.CapInfFileName],
-                                Capsule=True
+                                Capsule=True,
+                                FfsList=CapFileList
                                 )
+
+        GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule Successfully" %self.UiCapsuleName)
         GenFdsGlobalVariable.SharpCounter = 0
+        GenFds.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] = CapOutputFile
+        return CapOutputFile
 
     ## Generate inf file for capsule
     #
diff --git a/BaseTools/Source/Python/GenFds/CapsuleData.py b/BaseTools/Source/Python/GenFds/CapsuleData.py
index db29737963..0940094de0 100644
--- a/BaseTools/Source/Python/GenFds/CapsuleData.py
+++ b/BaseTools/Source/Python/GenFds/CapsuleData.py
@@ -45,6 +45,7 @@ class CapsuleFfs (CapsuleData):
     #
     def __init_(self) :
         self.Ffs = None
+        self.FvName = None
 
     ## generate FFS capsule data
     #
@@ -64,7 +65,9 @@ class CapsuleFv (CapsuleData):
     #   @param  self        The object pointer
     #
     def __init__(self) :
+        self.Ffs = None
         self.FvName = None
+        self.CapsuleName = None
 
     ## generate FV capsule data
     #
@@ -76,9 +79,11 @@ class CapsuleFv (CapsuleData):
             if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
                 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
                 FdBuffer = StringIO.StringIO('')
+                FvObj.CapsuleName = self.CapsuleName
                 FvFile = FvObj.AddToBuffer(FdBuffer)
+                FvObj.CapsuleName = None
+                FdBuffer.close()
                 return FvFile
-            
         else:
             FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName)
             return FvFile
diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py
index 99baa6abe5..370008c918 100644
--- a/BaseTools/Source/Python/GenFds/Fd.py
+++ b/BaseTools/Source/Python/GenFds/Fd.py
@@ -26,6 +26,7 @@ from CommonDataClass.FdfClass import FDClassObject
 from Common import EdkLogger
 from Common.BuildToolError import *
 from Common.Misc import SaveFileOnChange
+from GenFds import GenFds
 
 ## generate FD
 #
@@ -42,11 +43,12 @@ class FD(FDClassObject):
     #
     #   Generate FD
     #
-    #   @param  self        The object pointer
-    #   @param  FvBinDict   dictionary contains generated FV name and its file name
     #   @retval string      Generated FD file name
     #
-    def GenFd (self, FvBinDict):
+    def GenFd (self):
+        if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys():
+            return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd']
+
         #
         # Print Information
         #
@@ -80,7 +82,7 @@ class FD(FDClassObject):
                 PadRegion = Region.Region()
                 PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
                 PadRegion.Size = RegionObj.Offset - PadRegion.Offset
-                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
+                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
             PreviousRegionStart = RegionObj.Offset
             PreviousRegionSize = RegionObj.Size
             #
@@ -89,23 +91,19 @@ class FD(FDClassObject):
             if PreviousRegionSize > self.Size:
                 EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s size too small' % self.FdUiName)
             GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
-            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, FvBinDict, self.vtfRawDict, self.DefineVarDict)
+            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
         #
         # Create a empty Fd file
         #
         GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file')
-        FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,
-                                  self.FdUiName + '.fd')
-        #FdFile = open(FdFileName, 'wb')
-
+        FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,self.FdUiName + '.fd')
         #
         # Write the buffer contents to Fd file
         #
         GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
         SaveFileOnChange(FdFileName, FdBuffer.getvalue())
-        #FdFile.write(FdBuffer.getvalue());
-        #FdFile.close();
         FdBuffer.close();
+        GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
         return FdFileName
 
     ## generate VTF
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 0bf8f5514b..07de92610a 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -173,7 +173,7 @@ class FileProfile :
 
         self.FdDict = {}
         self.FvDict = {}
-        self.CapsuleList = []
+        self.CapsuleDict = {}
         self.VtfList = []
         self.RuleDict = {}
         self.OptRomDict = {}
@@ -1622,7 +1622,7 @@ class FdfParser:
         if not self.__GetNextWord():
             return True
 
-        if not self.__Token in ("SET", "FV", "FILE", "DATA"):
+        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
             self.__UndoToken()
             RegionObj.PcdOffset = self.__GetNextPcdName()
             self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
@@ -1639,10 +1639,14 @@ class FdfParser:
             if not self.__GetNextWord():
                 return True
 
-        if self.__Token == "FV":
+        elif self.__Token == "FV":
             self.__UndoToken()
             self.__GetRegionFvType( RegionObj)
 
+        elif self.__Token == "CAPSULE":
+            self.__UndoToken()
+            self.__GetRegionCapType( RegionObj)
+
         elif self.__Token == "FILE":
             self.__UndoToken()
             self.__GetRegionFileType( RegionObj)
@@ -1684,6 +1688,37 @@ class FdfParser:
 
             RegionObj.RegionDataList.append(self.__Token)
 
+    ## __GetRegionCapType() method
+    #
+    #   Get region capsule data for region
+    #
+    #   @param  self        The object pointer
+    #   @param  RegionObj   for whom region data is got
+    #
+    def __GetRegionCapType(self, RegionObj):
+
+        if not self.__IsKeyword("CAPSULE"):
+            raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
+
+        if not self.__IsToken("="):
+            raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+        if not self.__GetNextToken():
+            raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
+
+        RegionObj.RegionType = "CAPSULE"
+        RegionObj.RegionDataList.append(self.__Token)
+
+        while self.__IsKeyword("CAPSULE"):
+
+            if not self.__IsToken("="):
+                raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+            if not self.__GetNextToken():
+                raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
+
+            RegionObj.RegionDataList.append(self.__Token)
+
     ## __GetRegionFileType() method
     #
     #   Get region file data for region
@@ -2624,7 +2659,7 @@ class FdfParser:
             CapsuleObj.CreateFile = self.__Token
 
         self.__GetCapsuleStatements(CapsuleObj)
-        self.Profile.CapsuleList.append(CapsuleObj)
+        self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
         return True
 
     ## __GetCapsuleStatements() method
@@ -2638,10 +2673,9 @@ class FdfParser:
         self.__GetCapsuleTokens(Obj)
         self.__GetDefineStatements(Obj)
         self.__GetSetStatements(Obj)
-
         self.__GetCapsuleData(Obj)
 
-    ## __GetCapsuleStatements() method
+    ## __GetCapsuleTokens() method
     #
     #   Get token statements for capsule
     #
@@ -3558,51 +3592,53 @@ class FdfParser:
     def __GetOptRomOverrides(self, Obj):
         if self.__IsToken('{'):
             Overrides = OptionRom.OverrideAttribs()
-            if self.__IsKeyword( "PCI_VENDOR_ID"):
-                if not self.__IsToken( "="):
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-                if not self.__GetNextHexNumber():
-                    raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
-                Overrides.PciVendorId = self.__Token
-    
-            if self.__IsKeyword( "PCI_CLASS_CODE"):
-                if not self.__IsToken( "="):
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-                if not self.__GetNextHexNumber():
-                    raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
-                Overrides.PciClassCode = self.__Token
-    
-            if self.__IsKeyword( "PCI_DEVICE_ID"):
-                if not self.__IsToken( "="):
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-                if not self.__GetNextHexNumber():
-                    raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
-    
-                Overrides.PciDeviceId = self.__Token
-    
-            if self.__IsKeyword( "PCI_REVISION"):
-                if not self.__IsToken( "="):
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-                if not self.__GetNextHexNumber():
-                    raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
-                Overrides.PciRevision = self.__Token
-                    
-            if self.__IsKeyword( "COMPRESS"):
-                if not self.__IsToken( "="):
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-                if not self.__GetNextToken():
-                    raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
-                
-                if self.__Token.upper() == 'TRUE':
-                    Overrides.NeedCompress = True        
-                
-            if not self.__IsToken( "}"):
-                
-                if self.__Token not in ("PCI_CLASS_CODE", "PCI_VENDOR_ID", "PCI_DEVICE_ID", "PCI_REVISION", "COMPRESS"):
-                    raise Warning("unknown attribute %s" % self.__Token, self.FileName, self.CurrentLineNumber)
-                
-                raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
-            
+            while True:
+                if self.__IsKeyword( "PCI_VENDOR_ID"):
+                    if not self.__IsToken( "="):
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+                    if not self.__GetNextHexNumber():
+                        raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
+                    Overrides.PciVendorId = self.__Token
+                    continue
+
+                if self.__IsKeyword( "PCI_CLASS_CODE"):
+                    if not self.__IsToken( "="):
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+                    if not self.__GetNextHexNumber():
+                        raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
+                    Overrides.PciClassCode = self.__Token
+                    continue
+
+                if self.__IsKeyword( "PCI_DEVICE_ID"):
+                    if not self.__IsToken( "="):
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+                    if not self.__GetNextHexNumber():
+                        raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
+
+                    Overrides.PciDeviceId = self.__Token
+                    continue
+
+                if self.__IsKeyword( "PCI_REVISION"):
+                    if not self.__IsToken( "="):
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+                    if not self.__GetNextHexNumber():
+                        raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
+                    Overrides.PciRevision = self.__Token
+                    continue
+
+                if self.__IsKeyword( "COMPRESS"):
+                    if not self.__IsToken( "="):
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+                    if not self.__GetNextToken():
+                        raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
+                    Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
+                    continue
+
+                if self.__IsToken( "}"):
+                    break
+                else:
+                    EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
+
             Obj.OverrideAttribs = Overrides
             
     ## __GetOptRomFileStatement() method
@@ -3635,8 +3671,52 @@ class FdfParser:
         Obj.FfsList.append(FfsFileObj)
 
         return True
-        
-            
+
+    ## __GetCapInFd() method
+    #
+    #   Get Cap list contained in FD
+    #
+    #   @param  self        The object pointer
+    #   @param  FdName      FD name
+    #   @retval CapList     List of Capsule in FD
+    #
+    def __GetCapInFd (self, FdName):
+
+        CapList = []
+        if FdName.upper() in self.Profile.FdDict.keys():
+            FdObj = self.Profile.FdDict[FdName.upper()]
+            for elementRegion in FdObj.RegionList:
+                if elementRegion.RegionType == 'CAPSULE':
+                    for elementRegionData in elementRegion.RegionDataList:
+                        if elementRegionData.endswith(".cap"):
+                            continue
+                        if elementRegionData != None and elementRegionData.upper() not in CapList:
+                            CapList.append(elementRegionData.upper())
+        return CapList
+
+    ## __GetReferencedFdCapTuple() method
+    #
+    #   Get FV and FD list referenced by a capsule image
+    #
+    #   @param  self        The object pointer
+    #   @param  CapObj      Capsule section to be searched
+    #   @param  RefFdList   referenced FD by section
+    #   @param  RefFvList   referenced FV by section
+    #
+    def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
+
+        for CapsuleDataObj in CapObj.CapsuleDataList :
+            if CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
+                RefFvList.append (CapsuleDataObj.FvName.upper())
+            elif CapsuleDataObj.Ffs != None:
+              if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
+                  if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
+                      RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
+                  elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
+                      RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
+                  else:
+                      self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
+
     ## __GetFvInFd() method
     #
     #   Get FV list contained in FD
@@ -3653,6 +3733,8 @@ class FdfParser:
             for elementRegion in FdObj.RegionList:
                 if elementRegion.RegionType == 'FV':
                     for elementRegionData in elementRegion.RegionDataList:
+                        if elementRegionData.endswith(".fv"):
+                            continue
                         if elementRegionData != None and elementRegionData.upper() not in FvList:
                             FvList.append(elementRegionData.upper())
         return FvList
@@ -3711,60 +3793,126 @@ class FdfParser:
     #   @retval False       Not exists cycle reference
     #
     def CycleReferenceCheck(self):
+        #
+        # Check the cycle between FV and FD image
+        #
+        MaxLength = len (self.Profile.FvDict)
+        for FvName in self.Profile.FvDict.keys():
+            LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
+            RefFvStack = []
+            RefFvStack.append(FvName)
+            FdAnalyzedList = []
+            
+            Index = 0
+            while RefFvStack != [] and Index < MaxLength:
+                Index = Index + 1
+                FvNameFromStack = RefFvStack.pop()
+                if FvNameFromStack.upper() in self.Profile.FvDict.keys():
+                    FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
+                else:
+                    continue
 
-        CycleRefExists = False
+                RefFdList = []
+                RefFvList = []
+                self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
 
-        try:
-            for FvName in self.Profile.FvDict.keys():
-                LogStr = "Cycle Reference Checking for FV: %s\n" % FvName
-                RefFvStack = []
-                RefFvStack.append(FvName)
-                FdAnalyzedList = []
-
-                while RefFvStack != []:
-                    FvNameFromStack = RefFvStack.pop()
-                    if FvNameFromStack.upper() in self.Profile.FvDict.keys():
-                        FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
-                    else:
+                for RefFdName in RefFdList:
+                    if RefFdName in FdAnalyzedList:
                         continue
 
-                    RefFdList = []
-                    RefFvList = []
-                    self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
+                    LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
+                    FvInFdList = self.__GetFvInFd(RefFdName)
+                    if FvInFdList != []:
+                        for FvNameInFd in FvInFdList:
+                            LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
+                            if FvNameInFd not in RefFvStack:
+                                RefFvStack.append(FvNameInFd)
+
+                            if FvName in RefFvStack or FvNameFromStack in RefFvStack:
+                                EdkLogger.info(LogStr)
+                                return True
+                    FdAnalyzedList.append(RefFdName)
 
+                for RefFvName in RefFvList:
+                    LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
+                    if RefFvName not in RefFvStack:
+                        RefFvStack.append(RefFvName)
+
+                    if FvName in RefFvStack or FvNameFromStack in RefFvStack:
+                        EdkLogger.info(LogStr)
+                        return True
+
+        #
+        # Check the cycle between Capsule and FD image
+        #
+        MaxLength = len (self.Profile.CapsuleDict)
+        for CapName in self.Profile.CapsuleDict.keys():
+            #
+            # Capsule image to be checked.
+            #
+            LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
+            RefCapStack = []
+            RefCapStack.append(CapName)
+            FdAnalyzedList = []
+            FvAnalyzedList = []
+            
+            Index = 0
+            while RefCapStack != [] and Index < MaxLength:
+                Index = Index + 1
+                CapNameFromStack = RefCapStack.pop()
+                if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
+                    CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
+                else:
+                    continue
+
+                RefFvList = []
+                RefFdList = []
+                self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
+
+                FvListLength = 0
+                FdListLength = 0
+                while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
                     for RefFdName in RefFdList:
                         if RefFdName in FdAnalyzedList:
                             continue
 
-                        LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack)
+                        LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
+                        CapInFdList = self.__GetCapInFd(RefFdName)
+                        if CapInFdList != []:
+                            for CapNameInFd in CapInFdList:
+                                LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
+                                if CapNameInFd not in RefCapStack:
+                                    RefCapStack.append(CapNameInFd)
+
+                                if CapName in RefCapStack or CapNameFromStack in RefCapStack:
+                                    EdkLogger.info(LogStr)
+                                    return True
+
                         FvInFdList = self.__GetFvInFd(RefFdName)
                         if FvInFdList != []:
-                            LogStr += "FD %s contains FV: " % RefFdName
-                            for FvObj in FvInFdList:
-                                LogStr += FvObj
-                                LogStr += ' \n'
-                                if FvObj not in RefFvStack:
-                                    RefFvStack.append(FvObj)
-
-                                if FvName in RefFvStack:
-                                    CycleRefExists = True
-                                    raise Warning(LogStr)
-                        FdAnalyzedList.append(RefFdName)
+                            for FvNameInFd in FvInFdList:
+                                LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
+                                if FvNameInFd not in RefFvList:
+                                    RefFvList.append(FvNameInFd)
 
+                        FdAnalyzedList.append(RefFdName)
+                    #
+                    # the number of the parsed FV and FD image
+                    #
+                    FvListLength = len (RefFvList)
+                    FdListLength = len (RefFdList)
                     for RefFvName in RefFvList:
-                        LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack)
-                        if RefFvName not in RefFvStack:
-                            RefFvStack.append(RefFvName)
-
-                        if FvName in RefFvStack:
-                            CycleRefExists = True
-                            raise Warning(LogStr)
-
-        except Warning:
-            print LogStr
+                        if RefFvName in FvAnalyzedList:
+                            continue
+                        LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
+                        if RefFvName.upper() in self.Profile.FvDict.keys():
+                            FvObj = self.Profile.FvDict[RefFvName.upper()]
+                        else:
+                            continue
+                        self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
+                        FvAnalyzedList.append(RefFvName)
 
-        finally:
-            return CycleRefExists
+        return False
 
 if __name__ == "__main__":
     parser = FdfParser("..\LakeportX64Pkg.fdf")
diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
index ed778f3d44..e3f2e68fb8 100644
--- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py
@@ -78,8 +78,7 @@ class FileStatement (FileStatementClassObject) :
             if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
                 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
             Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
-            FvBin = {}
-            FileName = Fd.GenFd(FvBin)
+            FileName = Fd.GenFd()
             SectionFiles = [FileName]
 
         elif self.FileName != None:
diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py
index 74248f71c3..23ec58200b 100644
--- a/BaseTools/Source/Python/GenFds/Fv.py
+++ b/BaseTools/Source/Python/GenFds/Fv.py
@@ -44,6 +44,7 @@ class FV (FvClassObject):
         self.BaseAddress = None
         self.InfFileName = None
         self.FvAddressFileName = None
+        self.CapsuleName = None
 
     ## AddToBuffer()
     #
@@ -61,10 +62,27 @@ class FV (FvClassObject):
     #
     def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :
 
-        if self.UiFvName.upper() in GenFds.FvBinDict.keys():
-            return GenFds.FvBinDict[self.UiFvName.upper()]
-
-        GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV ..." %self.UiFvName)
+        if self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():
+            return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']
+        
+        #
+        # Check whether FV in Capsule is in FD flash region.
+        # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.
+        #
+        if self.CapsuleName != None:
+            for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
+                FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
+                for RegionObj in FdObj.RegionList:
+                    if RegionObj.RegionType == 'FV':
+                        for RegionData in RegionObj.RegionDataList:
+                            if RegionData.endswith(".fv"):
+                                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)
 
         self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
         #
@@ -115,12 +133,12 @@ class FV (FvClassObject):
         #
         FvFileObj = open ( FvOutputFile,'r+b')
 
-        GenFdsGlobalVariable.InfLogger( "\nGenerate %s FV Successfully" %self.UiFvName)
+        GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName)
         GenFdsGlobalVariable.SharpCounter = 0
 
         Buffer.write(FvFileObj.read())
         FvFileObj.close()
-        GenFds.FvBinDict[self.UiFvName.upper()] = FvOutputFile
+        GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
         return FvOutputFile
 
     ## __InitializeInf__()
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 2bc416f828..1df19100d3 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -20,7 +20,7 @@ import sys
 import os
 import linecache
 import FdfParser
-from Common.BuildToolError import *
+import Common.BuildToolError as BuildToolError
 from GenFdsGlobalVariable import GenFdsGlobalVariable
 from Workspace.WorkspaceDatabase import WorkspaceDatabase
 from Workspace.BuildClassObject import PcdClassObject
@@ -77,10 +77,10 @@ def main():
             EdkLogger.SetLevel(EdkLogger.INFO)
 
         if (Options.Workspace == None):
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "WORKSPACE not defined",
+            EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",
                             ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
         elif not os.path.exists(Options.Workspace):
-            EdkLogger.error("GenFds", BuildToolError.PARAMETER_INVALID, "WORKSPACE is invalid",
+            EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",
                             ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
         else:
             Workspace = os.path.normcase(Options.Workspace)
@@ -95,17 +95,17 @@ def main():
             FdfFilename = Options.filename
             FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)
         else:
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing FDF filename")
+            EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")
 
         if (Options.BuildTarget):
             GenFdsGlobalVariable.TargetName = Options.BuildTarget
         else:
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build target")
+            EdkLogger.error("GenFds", OPTION_MISSING, "Missing build target")
 
         if (Options.ToolChain):
             GenFdsGlobalVariable.ToolChainTag = Options.ToolChain
         else:
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing tool chain tag")
+            EdkLogger.error("GenFds", OPTION_MISSING, "Missing tool chain tag")
 
         if FdfFilename[0:2] == '..':
             FdfFilename = os.path.realpath(FdfFilename)
@@ -113,7 +113,7 @@ def main():
             FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
 
         if not os.path.exists(FdfFilename):
-            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=FdfFilename)
+            EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)
         GenFdsGlobalVariable.FdfFile = FdfFilename
         GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)
 
@@ -128,19 +128,19 @@ def main():
                 ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)
 
             if not os.path.exists(ActivePlatform)  :
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
+                EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
 
             if ActivePlatform.find(Workspace) == -1:
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!")
+                EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist in Workspace!")
 
             ActivePlatform = ActivePlatform.replace(Workspace, '')
             if len(ActivePlatform) > 0 :
                 if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/':
                     ActivePlatform = ActivePlatform[1:]
             else:
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
+                EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
         else :
-            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing active platform")
+            EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")
 
         GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace)
 
@@ -148,26 +148,28 @@ def main():
         if os.path.isfile(BuildConfigurationFile) == True:
             TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)
         else:
-            EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
+            EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
 
         if Options.Macros:
             for Pair in Options.Macros:
                 Pair.strip('"')
                 List = Pair.split('=')
                 if len(List) == 2:
-                    FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
                     if List[0].strip() == "EFI_SOURCE":
                         GlobalData.gEfiSource = List[1].strip()
+                        continue
                     elif List[0].strip() == "EDK_SOURCE":
                         GlobalData.gEdkSource = List[1].strip()
+                        continue
                     else:
                         GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip()
+                        FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
                 else:
-                    FdfParser.InputMacroDict[List[0].strip()] = None
+                    FdfParser.InputMacroDict[List[0].strip()] = ""
 
         """call Workspace build create database"""
         os.environ["WORKSPACE"] = Workspace
-        BuildWorkSpace = WorkspaceDatabase(':memory:', GlobalData.gGlobalDefines)
+        BuildWorkSpace = WorkspaceDatabase(':memory:', FdfParser.InputMacroDict)
         BuildWorkSpace.InitDatabase()
         
         #
@@ -179,7 +181,7 @@ def main():
         if (Options.archList) :
             ArchList = Options.archList.split(',')
         else:
-#            EdkLogger.error("GenFds", BuildToolError.OPTION_MISSING, "Missing build ARCH")
+#            EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
             ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList
 
         TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList)
@@ -206,7 +208,7 @@ def main():
                 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)
 
             if not os.path.exists(OutputDir):
-                EdkLogger.error("GenFds", BuildToolError.FILE_NOT_FOUND, ExtraData=OutputDir)
+                EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)
             GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir
 
         """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
@@ -214,20 +216,20 @@ def main():
         FdfParserObj.ParseFile()
 
         if FdfParserObj.CycleReferenceCheck():
-            EdkLogger.error("GenFds", BuildToolError.FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
+            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
 
         if (Options.uiFdName) :
             if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():
                 GenFds.OnlyGenerateThisFd = Options.uiFdName
             else:
-                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
+                EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
                                 "No such an FD in FDF file: %s" % Options.uiFdName)
 
         if (Options.uiFvName) :
             if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():
                 GenFds.OnlyGenerateThisFv = Options.uiFvName
             else:
-                EdkLogger.error("GenFds", BuildToolError.OPTION_VALUE_INVALID,
+                EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
                                 "No such an FV in FDF file: %s" % Options.uiFvName)
 
         """Modify images from build output if the feature of loading driver at fixed address is on."""
@@ -240,8 +242,8 @@ def main():
         GenFds.DisplayFvSpaceInfo(FdfParserObj)
         
     except FdfParser.Warning, X:
-        EdkLogger.error(X.ToolName, BuildToolError.FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
-        ReturnCode = BuildToolError.FORMAT_INVALID
+        EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False)
+        ReturnCode = FORMAT_INVALID
     except FatalError, X:
         if Options.debug != None:
             import traceback
@@ -309,8 +311,8 @@ def myOptionParser():
 #
 class GenFds :
     FdfParsef = None
-    # FvName in FDF, FvBinFile name
-    FvBinDict = {}
+    # FvName, FdName, CapName in FDF, Image file name
+    ImageBinDict = {}
     OnlyGenerateThisFd = None
     OnlyGenerateThisFv = None
 
@@ -324,17 +326,17 @@ class GenFds :
     def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):
         GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
 
-        GenFdsGlobalVariable.VerboseLogger("   Gen Fd  !")
+        GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
         if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
             FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
             if FdObj != None:
-                FdObj.GenFd(GenFds.FvBinDict)
-        elif GenFds.OnlyGenerateThisFv == None:
+                FdObj.GenFd()
+        elif GenFds.OnlyGenerateThisFd == None:
             for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
                 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
-                FdObj.GenFd(GenFds.FvBinDict)
+                FdObj.GenFd()
 
-        GenFdsGlobalVariable.VerboseLogger(" Gen FV ! ")
+        GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")
         if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
             FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())
             if FvObj != None:
@@ -343,7 +345,7 @@ class GenFds :
                 FvObj.AddToBuffer(Buffer, None, GenFds.GetFvBlockSize(FvObj))
                 Buffer.close()
                 return
-        elif GenFds.OnlyGenerateThisFd == None:
+        elif GenFds.OnlyGenerateThisFv == None:
             for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
                 Buffer = StringIO.StringIO('')
                 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]
@@ -352,12 +354,14 @@ class GenFds :
                 Buffer.close()
 
         if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:
-            GenFdsGlobalVariable.VerboseLogger(" Gen Capsule !")
-            for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleList:
-                CapsuleObj.GenCapsule()
-                
+            if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
+                GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
+                for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
+                    CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]
+                    CapsuleObj.GenCapsule()
+
             if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
-                GenFdsGlobalVariable.VerboseLogger(" Gen Option ROM !")
+                GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
                 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():
                     OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]
                     OptRomObj.AddToBuffer(None)
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index d556ce7ade..77c8821a05 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -360,7 +360,7 @@ class GenFdsGlobalVariable:
         try:
             PopenObject = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr= subprocess.PIPE)
         except Exception, X:
-            EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
+            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
         (out, error) = PopenObject.communicate()
 
         while PopenObject.returncode == None :
@@ -371,7 +371,7 @@ class GenFdsGlobalVariable:
             GenFdsGlobalVariable.InfLogger (error)
             if PopenObject.returncode != 0:
                 print "###", cmd
-                EdkLogger.error("GenFds", BuildToolError.COMMAND_FAILURE, errorMess)
+                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)
 
     def VerboseLogger (msg):
         EdkLogger.verbose(msg)
@@ -380,7 +380,7 @@ class GenFdsGlobalVariable:
         EdkLogger.info(msg)
 
     def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
-        EdkLogger.error('GenFds', BuildToolError.GENFDS_ERROR, msg, File, Line, ExtraData)
+        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
 
     def DebugLogger (Level, msg):
         EdkLogger.debug(Level, msg)
diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
index b9f0af54c9..8cd7429d58 100644
--- a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
@@ -48,7 +48,15 @@ class OptRomInfStatement (FfsInfStatement):
         
         if self.OverrideAttribs == None:
             self.OverrideAttribs = OptionRom.OverrideAttribs()
-        
+
+        if self.OverrideAttribs.NeedCompress == None:
+            self.OverrideAttribs.NeedCompress = self.OptRomDefs.get ('COMPRESS')
+            if self.OverrideAttribs.NeedCompress is not None:
+                if self.OverrideAttribs.NeedCompress.upper() not in ('TRUE', 'FALSE'):
+                    GenFdsGlobalVariable.ErrorLogger( "Expected TRUE/FALSE for COMPRESS: %s" %self.InfFileName)
+                self.OverrideAttribs.NeedCompress = \
+                    self.OverrideAttribs.NeedCompress.upper() == 'TRUE'
+
         if self.OverrideAttribs.PciVendorId == None:
             self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID')
         
diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py
index e102e65f1c..28e77aad5f 100644
--- a/BaseTools/Source/Python/GenFds/OptionRom.py
+++ b/BaseTools/Source/Python/GenFds/OptionRom.py
@@ -135,6 +135,6 @@ class OverrideAttribs:
         self.PciClassCode = None
         self.PciDeviceId = None
         self.PciRevision = None
-        self.NeedCompress = False
+        self.NeedCompress = None
         
         
\ No newline at end of file
diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py
index ed16c6fa98..99f1ac39ac 100644
--- a/BaseTools/Source/Python/GenFds/Region.py
+++ b/BaseTools/Source/Python/GenFds/Region.py
@@ -20,10 +20,10 @@ from GenFdsGlobalVariable import GenFdsGlobalVariable
 import StringIO
 from CommonDataClass.FdfClass import RegionClassObject
 import os
+from stat import *
 from Common import EdkLogger
 from Common.BuildToolError import *
 
-
 ## generate Region
 #
 #
@@ -52,9 +52,9 @@ class Region(RegionClassObject):
     #   @retval string      Generated FV file path
     #
 
-    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}):
+    def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict = None, MacroDict = {}):
         Size = self.Size
-        GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset)
+        GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
         GenFdsGlobalVariable.InfLogger("   Region Size = 0x%X" %Size)
         GenFdsGlobalVariable.SharpCounter = 0
 
@@ -62,15 +62,14 @@ class Region(RegionClassObject):
             #
             # Get Fv from FvDict
             #
-            FvBuffer = StringIO.StringIO('')
             RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList)
             RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize)
 
             self.FvAddress = int(BaseAddress, 16) + self.Offset
-            FvBaseAddress = '0x%X' %self.FvAddress
-
+            FvBaseAddress  = '0x%X' %self.FvAddress
+            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)
@@ -79,83 +78,165 @@ class Region(RegionClassObject):
                     if not os.path.exists(RegionData):
                         EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
 
-                    BinFile = open (RegionData, 'r+b')
-                    FvBuffer.write(BinFile.read())
-                    if FvBuffer.len > Size:
+                    FileName = RegionData
+                elif RegionData.upper() + 'fv' in ImageBinDict.keys():
+                    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')
+                        #
+                        # Call GenFv tool
+                        #
+                        BlockSize = RegionBlockSize
+                        BlockNum = RegionBlockNum
+                        if FvObj.BlockSizeList != []:
+                            if FvObj.BlockSizeList[0][0] != None:
+                                BlockSize = FvObj.BlockSizeList[0][0]
+                            if FvObj.BlockSizeList[0][1] != None:
+                                BlockNum = FvObj.BlockSizeList[0][1]
+                        self.FvAddress = self.FvAddress + FvOffset
+                        FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)
+                        if self.FvAddress % FvAlignValue != 0:
+                            EdkLogger.error("GenFds", GENFDS_ERROR,
+                                            "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
+                        FvBuffer = StringIO.StringIO('')
+                        FvBaseAddress = '0x%X' %self.FvAddress
+                        FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
+                        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))
+                        #
+                        # Put the generated image into FD buffer.
+                        #
+                        Buffer.write(FvBuffer.getvalue())
+                        FvBuffer.close()
+                        FvOffset = FvOffset + FvBuffer.len
+                        Size = Size - FvBuffer.len
+                        continue
+                    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))
-                    break
-
-                if RegionData.upper() in FvBinDict.keys():
-                    continue
+                    BinFile = open (FileName, 'r+b')
+                    Buffer.write(BinFile.read())
+                    BinFile.close()
+                    Size = Size - FileLength
+            #
+            # Pad the left buffer
+            #
+            if Size > 0:
+                if (ErasePolarity == '1') :
+                    PadData = 0xFF
+                else :
+                    PadData = 0
+                for i in range(0, Size):
+                    Buffer.write(pack('B', PadData))
 
-                FvObj = None
-                if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
-                    FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
+        if self.RegionType == 'CAPSULE':
+            #
+            # Get Capsule from Capsule Dict
+            #
+            for RegionData in self.RegionDataList:
+                if RegionData.endswith(".cap"):
+                    RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
+                    GenFdsGlobalVariable.InfLogger('   Region CAPSULE Image Name = .cap : %s'%RegionData)
+                    if RegionData[1] != ':' :
+                        RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
+                    if not os.path.exists(RegionData):
+                        EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
 
-                if FvObj != None :
-                    GenFdsGlobalVariable.InfLogger('   Region Name = FV')
+                    FileName = RegionData
+                elif RegionData.upper() + 'cap' in ImageBinDict.keys():
+                    GenFdsGlobalVariable.InfLogger('   Region Name = CAPSULE')
+                    FileName = ImageBinDict[RegionData.upper() + 'cap']
+                else:
                     #
-                    # Call GenFv tool
+                    # Generate Capsule image and Put it into FD buffer
                     #
-                    BlockSize = RegionBlockSize
-                    BlockNum = RegionBlockNum
-                    if FvObj.BlockSizeList != []:
-                        if FvObj.BlockSizeList[0][0] != None:
-                            BlockSize = FvObj.BlockSizeList[0][0]
-                        if FvObj.BlockSizeList[0][1] != None:
-                            BlockNum = FvObj.BlockSizeList[0][1]
-                    self.FvAddress = self.FvAddress + FvBuffer.len
-                    FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)
-                    if self.FvAddress % FvAlignValue != 0:
-                        EdkLogger.error("GenFds", GENFDS_ERROR,
-                                        "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
-                    FvBaseAddress = '0x%X' %self.FvAddress
-                    FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
-
-                    if FvBuffer.len > Size:
-                        EdkLogger.error("GenFds", GENFDS_ERROR,
-                                        "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
-                else:
-                    EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
+                    CapsuleObj = None
+                    if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
+                        CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[RegionData.upper()]
 
+                    if CapsuleObj != None :
+                        CapsuleObj.CapsuleName = RegionData.upper()
+                        GenFdsGlobalVariable.InfLogger('   Region Name = CAPSULE')
+                        #
+                        # Call GenFv tool to generate Capsule Image
+                        #
+                        FileName = CapsuleObj.GenCapsule()
+                        CapsuleObj.CapsuleName = None
+                    else:
+                        EdkLogger.error("GenFds", GENFDS_ERROR, "Capsule (%s) is NOT described in FDF file!" % (RegionData))
 
-            if FvBuffer.len > 0:
-                Buffer.write(FvBuffer.getvalue())
-            else:
-                BinFile = open (FileName, 'rb')
+                #
+                # Add the capsule image into FD buffer
+                #
+                FileLength = os.stat(FileName)[ST_SIZE]
+                if FileLength > Size:
+                    EdkLogger.error("GenFds", GENFDS_ERROR,
+                                    "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
+                                    % (FileLength, RegionData, Size))
+                BinFile = open (FileName, 'r+b')
                 Buffer.write(BinFile.read())
-
-            FvBuffer.close()
+                BinFile.close()
+                Size = Size - FileLength
+            #
+            # Pad the left buffer
+            #
+            if Size > 0:
+                if (ErasePolarity == '1') :
+                    PadData = 0xFF
+                else :
+                    PadData = 0
+                for i in range(0, Size):
+                    Buffer.write(pack('B', PadData))
 
         if self.RegionType == 'FILE':
-            FvBuffer = StringIO.StringIO('')
             for RegionData in self.RegionDataList:
                 RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
-                GenFdsGlobalVariable.InfLogger('   Region File Name = FILE: %s'%RegionData)
                 if RegionData[1] != ':' :
                     RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
                 if not os.path.exists(RegionData):
                     EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
-
-                BinFile = open (RegionData, 'r+b')
-                FvBuffer.write(BinFile.read())
-                if FvBuffer.len > Size :
+                #
+                # Add the file image into FD buffer
+                #
+                FileLength = os.stat(RegionData)[ST_SIZE]
+                if FileLength > Size:
                     EdkLogger.error("GenFds", GENFDS_ERROR,
-                                    "Size of File (%s) large than Region Size " % RegionData)
-
+                                    "Size of File (%s) is larger than Region Size 0x%X specified." \
+                                    % (RegionData, Size))
+                GenFdsGlobalVariable.InfLogger('   Region File Name = %s'%RegionData)
+                BinFile = open (RegionData, 'r+b')
+                Buffer.write(BinFile.read())
+                BinFile.close()
+                Size = Size - FileLength
             #
-            # If File contents less than region size, append "0xff" after it
+            # Pad the left buffer
             #
-            if FvBuffer.len < Size:
-                for index in range(0, (Size-FvBuffer.len)):
-                    if (ErasePolarity == '1'):
-                        FvBuffer.write(pack('B', int('0xFF', 16)))
-                    else:
-                        FvBuffer.write(pack('B', int('0x00', 16)))
-            Buffer.write(FvBuffer.getvalue())
-            FvBuffer.close()
+            if Size > 0:
+                if (ErasePolarity == '1') :
+                    PadData = 0xFF
+                else :
+                    PadData = 0
+                for i in range(0, Size):
+                    Buffer.write(pack('B', PadData))
 
         if self.RegionType == 'DATA' :
             GenFdsGlobalVariable.InfLogger('   Region Name = DATA')
@@ -168,12 +249,16 @@ class Region(RegionClassObject):
                 else:
                     for item in Data :
                         Buffer.write(pack('B', int(item, 16)))
-            if DataSize < Size:
-                if (ErasePolarity == '1'):
+                Size = Size - DataSize
+            #
+            # Pad the left buffer
+            #
+            if Size > 0:
+                if (ErasePolarity == '1') :
                     PadData = 0xFF
-                else:
+                else :
                     PadData = 0
-                for i in range(Size - DataSize):
+                for i in range(0, Size):
                     Buffer.write(pack('B', PadData))
 
         if self.RegionType == None:
-- 
cgit v1.2.3