]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FdfParser.py
Sync basetools' source and binary files with r1707 of the basetools project.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
index 0bf8f5514bf7e779dd663605a62a5e6cafa335ab..07de92610a463912edccdbf4fa9d4c988d5b4113 100644 (file)
@@ -173,7 +173,7 @@ class FileProfile :
 \r
         self.FdDict = {}\r
         self.FvDict = {}\r
-        self.CapsuleList = []\r
+        self.CapsuleDict = {}\r
         self.VtfList = []\r
         self.RuleDict = {}\r
         self.OptRomDict = {}\r
@@ -1622,7 +1622,7 @@ class FdfParser:
         if not self.__GetNextWord():\r
             return True\r
 \r
-        if not self.__Token in ("SET", "FV", "FILE", "DATA"):\r
+        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):\r
             self.__UndoToken()\r
             RegionObj.PcdOffset = self.__GetNextPcdName()\r
             self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
@@ -1639,10 +1639,14 @@ class FdfParser:
             if not self.__GetNextWord():\r
                 return True\r
 \r
-        if self.__Token == "FV":\r
+        elif self.__Token == "FV":\r
             self.__UndoToken()\r
             self.__GetRegionFvType( RegionObj)\r
 \r
+        elif self.__Token == "CAPSULE":\r
+            self.__UndoToken()\r
+            self.__GetRegionCapType( RegionObj)\r
+\r
         elif self.__Token == "FILE":\r
             self.__UndoToken()\r
             self.__GetRegionFileType( RegionObj)\r
@@ -1684,6 +1688,37 @@ class FdfParser:
 \r
             RegionObj.RegionDataList.append(self.__Token)\r
 \r
+    ## __GetRegionCapType() method\r
+    #\r
+    #   Get region capsule data for region\r
+    #\r
+    #   @param  self        The object pointer\r
+    #   @param  RegionObj   for whom region data is got\r
+    #\r
+    def __GetRegionCapType(self, RegionObj):\r
+\r
+        if not self.__IsKeyword("CAPSULE"):\r
+            raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
+\r
+        if not self.__IsToken("="):\r
+            raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+\r
+        if not self.__GetNextToken():\r
+            raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
+\r
+        RegionObj.RegionType = "CAPSULE"\r
+        RegionObj.RegionDataList.append(self.__Token)\r
+\r
+        while self.__IsKeyword("CAPSULE"):\r
+\r
+            if not self.__IsToken("="):\r
+                raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+\r
+            if not self.__GetNextToken():\r
+                raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)\r
+\r
+            RegionObj.RegionDataList.append(self.__Token)\r
+\r
     ## __GetRegionFileType() method\r
     #\r
     #   Get region file data for region\r
@@ -2624,7 +2659,7 @@ class FdfParser:
             CapsuleObj.CreateFile = self.__Token\r
 \r
         self.__GetCapsuleStatements(CapsuleObj)\r
-        self.Profile.CapsuleList.append(CapsuleObj)\r
+        self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
         return True\r
 \r
     ## __GetCapsuleStatements() method\r
@@ -2638,10 +2673,9 @@ class FdfParser:
         self.__GetCapsuleTokens(Obj)\r
         self.__GetDefineStatements(Obj)\r
         self.__GetSetStatements(Obj)\r
-\r
         self.__GetCapsuleData(Obj)\r
 \r
-    ## __GetCapsuleStatements() method\r
+    ## __GetCapsuleTokens() method\r
     #\r
     #   Get token statements for capsule\r
     #\r
@@ -3558,51 +3592,53 @@ class FdfParser:
     def __GetOptRomOverrides(self, Obj):\r
         if self.__IsToken('{'):\r
             Overrides = OptionRom.OverrideAttribs()\r
-            if self.__IsKeyword( "PCI_VENDOR_ID"):\r
-                if not self.__IsToken( "="):\r
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
-                if not self.__GetNextHexNumber():\r
-                    raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)\r
-                Overrides.PciVendorId = self.__Token\r
-    \r
-            if self.__IsKeyword( "PCI_CLASS_CODE"):\r
-                if not self.__IsToken( "="):\r
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
-                if not self.__GetNextHexNumber():\r
-                    raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)\r
-                Overrides.PciClassCode = self.__Token\r
-    \r
-            if self.__IsKeyword( "PCI_DEVICE_ID"):\r
-                if not self.__IsToken( "="):\r
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
-                if not self.__GetNextHexNumber():\r
-                    raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)\r
-    \r
-                Overrides.PciDeviceId = self.__Token\r
-    \r
-            if self.__IsKeyword( "PCI_REVISION"):\r
-                if not self.__IsToken( "="):\r
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
-                if not self.__GetNextHexNumber():\r
-                    raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)\r
-                Overrides.PciRevision = self.__Token\r
-                    \r
-            if self.__IsKeyword( "COMPRESS"):\r
-                if not self.__IsToken( "="):\r
-                    raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
-                if not self.__GetNextToken():\r
-                    raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
-                \r
-                if self.__Token.upper() == 'TRUE':\r
-                    Overrides.NeedCompress = True        \r
-                \r
-            if not self.__IsToken( "}"):\r
-                \r
-                if self.__Token not in ("PCI_CLASS_CODE", "PCI_VENDOR_ID", "PCI_DEVICE_ID", "PCI_REVISION", "COMPRESS"):\r
-                    raise Warning("unknown attribute %s" % self.__Token, self.FileName, self.CurrentLineNumber)\r
-                \r
-                raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
-            \r
+            while True:\r
+                if self.__IsKeyword( "PCI_VENDOR_ID"):\r
+                    if not self.__IsToken( "="):\r
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+                    if not self.__GetNextHexNumber():\r
+                        raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)\r
+                    Overrides.PciVendorId = self.__Token\r
+                    continue\r
+\r
+                if self.__IsKeyword( "PCI_CLASS_CODE"):\r
+                    if not self.__IsToken( "="):\r
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+                    if not self.__GetNextHexNumber():\r
+                        raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)\r
+                    Overrides.PciClassCode = self.__Token\r
+                    continue\r
+\r
+                if self.__IsKeyword( "PCI_DEVICE_ID"):\r
+                    if not self.__IsToken( "="):\r
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+                    if not self.__GetNextHexNumber():\r
+                        raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)\r
+\r
+                    Overrides.PciDeviceId = self.__Token\r
+                    continue\r
+\r
+                if self.__IsKeyword( "PCI_REVISION"):\r
+                    if not self.__IsToken( "="):\r
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+                    if not self.__GetNextHexNumber():\r
+                        raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)\r
+                    Overrides.PciRevision = self.__Token\r
+                    continue\r
+\r
+                if self.__IsKeyword( "COMPRESS"):\r
+                    if not self.__IsToken( "="):\r
+                        raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+                    if not self.__GetNextToken():\r
+                        raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
+                    Overrides.NeedCompress = self.__Token.upper() == 'TRUE'\r
+                    continue\r
+\r
+                if self.__IsToken( "}"):\r
+                    break\r
+                else:\r
+                    EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
+\r
             Obj.OverrideAttribs = Overrides\r
             \r
     ## __GetOptRomFileStatement() method\r
@@ -3635,8 +3671,52 @@ class FdfParser:
         Obj.FfsList.append(FfsFileObj)\r
 \r
         return True\r
-        \r
-            \r
+\r
+    ## __GetCapInFd() method\r
+    #\r
+    #   Get Cap list contained in FD\r
+    #\r
+    #   @param  self        The object pointer\r
+    #   @param  FdName      FD name\r
+    #   @retval CapList     List of Capsule in FD\r
+    #\r
+    def __GetCapInFd (self, FdName):\r
+\r
+        CapList = []\r
+        if FdName.upper() in self.Profile.FdDict.keys():\r
+            FdObj = self.Profile.FdDict[FdName.upper()]\r
+            for elementRegion in FdObj.RegionList:\r
+                if elementRegion.RegionType == 'CAPSULE':\r
+                    for elementRegionData in elementRegion.RegionDataList:\r
+                        if elementRegionData.endswith(".cap"):\r
+                            continue\r
+                        if elementRegionData != None and elementRegionData.upper() not in CapList:\r
+                            CapList.append(elementRegionData.upper())\r
+        return CapList\r
+\r
+    ## __GetReferencedFdCapTuple() method\r
+    #\r
+    #   Get FV and FD list referenced by a capsule image\r
+    #\r
+    #   @param  self        The object pointer\r
+    #   @param  CapObj      Capsule section to be searched\r
+    #   @param  RefFdList   referenced FD by section\r
+    #   @param  RefFvList   referenced FV by section\r
+    #\r
+    def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
+\r
+        for CapsuleDataObj in CapObj.CapsuleDataList :\r
+            if CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
+                RefFvList.append (CapsuleDataObj.FvName.upper())\r
+            elif CapsuleDataObj.Ffs != None:\r
+              if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):\r
+                  if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
+                      RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
+                  elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
+                      RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
+                  else:\r
+                      self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
+\r
     ## __GetFvInFd() method\r
     #\r
     #   Get FV list contained in FD\r
@@ -3653,6 +3733,8 @@ class FdfParser:
             for elementRegion in FdObj.RegionList:\r
                 if elementRegion.RegionType == 'FV':\r
                     for elementRegionData in elementRegion.RegionDataList:\r
+                        if elementRegionData.endswith(".fv"):\r
+                            continue\r
                         if elementRegionData != None and elementRegionData.upper() not in FvList:\r
                             FvList.append(elementRegionData.upper())\r
         return FvList\r
@@ -3711,60 +3793,126 @@ class FdfParser:
     #   @retval False       Not exists cycle reference\r
     #\r
     def CycleReferenceCheck(self):\r
+        #\r
+        # Check the cycle between FV and FD image\r
+        #\r
+        MaxLength = len (self.Profile.FvDict)\r
+        for FvName in self.Profile.FvDict.keys():\r
+            LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
+            RefFvStack = []\r
+            RefFvStack.append(FvName)\r
+            FdAnalyzedList = []\r
+            \r
+            Index = 0\r
+            while RefFvStack != [] and Index < MaxLength:\r
+                Index = Index + 1\r
+                FvNameFromStack = RefFvStack.pop()\r
+                if FvNameFromStack.upper() in self.Profile.FvDict.keys():\r
+                    FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
+                else:\r
+                    continue\r
 \r
-        CycleRefExists = False\r
+                RefFdList = []\r
+                RefFvList = []\r
+                self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
 \r
-        try:\r
-            for FvName in self.Profile.FvDict.keys():\r
-                LogStr = "Cycle Reference Checking for FV: %s\n" % FvName\r
-                RefFvStack = []\r
-                RefFvStack.append(FvName)\r
-                FdAnalyzedList = []\r
-\r
-                while RefFvStack != []:\r
-                    FvNameFromStack = RefFvStack.pop()\r
-                    if FvNameFromStack.upper() in self.Profile.FvDict.keys():\r
-                        FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
-                    else:\r
+                for RefFdName in RefFdList:\r
+                    if RefFdName in FdAnalyzedList:\r
                         continue\r
 \r
-                    RefFdList = []\r
-                    RefFvList = []\r
-                    self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
+                    LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
+                    FvInFdList = self.__GetFvInFd(RefFdName)\r
+                    if FvInFdList != []:\r
+                        for FvNameInFd in FvInFdList:\r
+                            LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
+                            if FvNameInFd not in RefFvStack:\r
+                                RefFvStack.append(FvNameInFd)\r
+\r
+                            if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
+                                EdkLogger.info(LogStr)\r
+                                return True\r
+                    FdAnalyzedList.append(RefFdName)\r
 \r
+                for RefFvName in RefFvList:\r
+                    LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
+                    if RefFvName not in RefFvStack:\r
+                        RefFvStack.append(RefFvName)\r
+\r
+                    if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
+                        EdkLogger.info(LogStr)\r
+                        return True\r
+\r
+        #\r
+        # Check the cycle between Capsule and FD image\r
+        #\r
+        MaxLength = len (self.Profile.CapsuleDict)\r
+        for CapName in self.Profile.CapsuleDict.keys():\r
+            #\r
+            # Capsule image to be checked.\r
+            #\r
+            LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
+            RefCapStack = []\r
+            RefCapStack.append(CapName)\r
+            FdAnalyzedList = []\r
+            FvAnalyzedList = []\r
+            \r
+            Index = 0\r
+            while RefCapStack != [] and Index < MaxLength:\r
+                Index = Index + 1\r
+                CapNameFromStack = RefCapStack.pop()\r
+                if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():\r
+                    CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
+                else:\r
+                    continue\r
+\r
+                RefFvList = []\r
+                RefFdList = []\r
+                self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
+\r
+                FvListLength = 0\r
+                FdListLength = 0\r
+                while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
                     for RefFdName in RefFdList:\r
                         if RefFdName in FdAnalyzedList:\r
                             continue\r
 \r
-                        LogStr += "FD %s is referenced by FV %s\n" % (RefFdName, FvNameFromStack)\r
+                        LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
+                        CapInFdList = self.__GetCapInFd(RefFdName)\r
+                        if CapInFdList != []:\r
+                            for CapNameInFd in CapInFdList:\r
+                                LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)\r
+                                if CapNameInFd not in RefCapStack:\r
+                                    RefCapStack.append(CapNameInFd)\r
+\r
+                                if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
+                                    EdkLogger.info(LogStr)\r
+                                    return True\r
+\r
                         FvInFdList = self.__GetFvInFd(RefFdName)\r
                         if FvInFdList != []:\r
-                            LogStr += "FD %s contains FV: " % RefFdName\r
-                            for FvObj in FvInFdList:\r
-                                LogStr += FvObj\r
-                                LogStr += ' \n'\r
-                                if FvObj not in RefFvStack:\r
-                                    RefFvStack.append(FvObj)\r
-\r
-                                if FvName in RefFvStack:\r
-                                    CycleRefExists = True\r
-                                    raise Warning(LogStr)\r
-                        FdAnalyzedList.append(RefFdName)\r
+                            for FvNameInFd in FvInFdList:\r
+                                LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)\r
+                                if FvNameInFd not in RefFvList:\r
+                                    RefFvList.append(FvNameInFd)\r
 \r
+                        FdAnalyzedList.append(RefFdName)\r
+                    #\r
+                    # the number of the parsed FV and FD image\r
+                    #\r
+                    FvListLength = len (RefFvList)\r
+                    FdListLength = len (RefFdList)\r
                     for RefFvName in RefFvList:\r
-                        LogStr += "FV %s is referenced by FV %s\n" % (RefFvName, FvNameFromStack)\r
-                        if RefFvName not in RefFvStack:\r
-                            RefFvStack.append(RefFvName)\r
-\r
-                        if FvName in RefFvStack:\r
-                            CycleRefExists = True\r
-                            raise Warning(LogStr)\r
-\r
-        except Warning:\r
-            print LogStr\r
+                        if RefFvName in FvAnalyzedList:\r
+                            continue\r
+                        LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
+                        if RefFvName.upper() in self.Profile.FvDict.keys():\r
+                            FvObj = self.Profile.FvDict[RefFvName.upper()]\r
+                        else:\r
+                            continue\r
+                        self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
+                        FvAnalyzedList.append(RefFvName)\r
 \r
-        finally:\r
-            return CycleRefExists\r
+        return False\r
 \r
 if __name__ == "__main__":\r
     parser = FdfParser("..\LakeportX64Pkg.fdf")\r