[edk2] [Patch] BaseTools: Enable structure pcd in FDF file

BobCF posted 1 patch 5 years, 9 months ago
Failed in applying to current master (apply log)
BaseTools/Source/Python/AutoGen/AutoGen.py         |   3 +-
BaseTools/Source/Python/AutoGen/GenC.py            |   4 +
BaseTools/Source/Python/GenFds/FdfParser.py        |  81 ++++++++--
.../Source/Python/Workspace/BuildClassObject.py    |  14 ++
BaseTools/Source/Python/Workspace/DscBuildData.py  | 171 ++++++++++++++++++++-
BaseTools/Source/Python/build/BuildReport.py       |   3 +
6 files changed, 256 insertions(+), 20 deletions(-)
[edk2] [Patch] BaseTools: Enable structure pcd in FDF file
Posted by BobCF 5 years, 9 months ago
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py         |   3 +-
 BaseTools/Source/Python/AutoGen/GenC.py            |   4 +
 BaseTools/Source/Python/GenFds/FdfParser.py        |  81 ++++++++--
 .../Source/Python/Workspace/BuildClassObject.py    |  14 ++
 BaseTools/Source/Python/Workspace/DscBuildData.py  | 171 ++++++++++++++++++++-
 BaseTools/Source/Python/build/BuildReport.py       |   3 +
 6 files changed, 256 insertions(+), 20 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index ed0be3bc74..e3f404bd6b 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -565,11 +565,11 @@ class WorkspaceAutoGen(AutoGen):
                 for Pcd in Pkg.Pcds:
                     DecPcds.add((Pcd[0], Pcd[1]))
                     DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))
 
             Platform.SkuName = self.SkuId
-            for Name, Guid in PcdSet:
+            for Name, Guid,Fileds in PcdSet:
                 if (Name, Guid) not in DecPcds:
                     EdkLogger.error(
                         'build',
                         PARSER_ERROR,
                         "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),
@@ -579,11 +579,10 @@ class WorkspaceAutoGen(AutoGen):
                 else:
                     # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.
                     if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \
                         or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \
                         or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:
-                        Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
                         continue
                     elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:
                         EdkLogger.error(
                                 'build',
                                 PARSER_ERROR,
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index ae3af085a1..d186f399ba 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -888,10 +888,12 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
     FixPcdSizeTokenName = '_PCD_SIZE_' + TokenCName
     FixedPcdSizeVariableName = '_gPcd_FixedAtBuild_Size_' + TokenCName
 
     if Pcd.PcdValueFromComm:
         Pcd.DefaultValue = Pcd.PcdValueFromComm
+    elif Pcd.PcdValueFromFdf:
+        Pcd.DefaultValue = Pcd.PcdValueFromFdf
     
     if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
         TokenNumber = int(Pcd.TokenValue, 0)
         # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with 
         # different Guids but same TokenCName
@@ -1181,10 +1183,12 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     PatchPcdMaxSizeVariable = '_gPcd_BinaryPatch_MaxSize_' + TokenCName
     FixedPcdSizeVariableName = '_gPcd_FixedAtBuild_Size_' + TokenCName
 
     if Pcd.PcdValueFromComm:
         Pcd.DefaultValue = Pcd.PcdValueFromComm
+    elif Pcd.PcdValueFromFdf:
+        Pcd.DefaultValue = Pcd.PcdValueFromFdf
     #
     # Write PCDs
     #
     if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
         TokenNumber = int(Pcd.TokenValue, 0)
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 78cb049c61..a8a2e7d70e 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -80,17 +80,16 @@ T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_
 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
 
 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
 
 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
-RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
-RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")
+RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
+RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
 ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
 BaseAddrValuePattern = re.compile('^0[xX][0-9a-fA-F]+')
 FileExtensionPattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
 TokenFindPattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
-
 AllIncludeFileList = []
 
 # Get the closest parent
 def GetParentAtLine (Line):
     for Profile in AllIncludeFileList:
@@ -223,12 +222,13 @@ class FileProfile :
                 fsock.close()
 
         except:
             EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
 
-
+        self.FileName = FileName
         self.PcdDict = {}
+        self.PcdLocalDict = {}
         self.InfList = []
         self.InfDict = {'ArchTBD':[]}
         # ECC will use this Dict and List information
         self.PcdFileLineDict = {}
         self.InfFileLineList = []
@@ -784,21 +784,22 @@ class FdfParser:
             elif self.__Token == 'SET':
                 if not self.__GetIfListCurrentItemStat(IfList):
                     continue
                 SetLine = self.CurrentLineNumber - 1
                 SetOffset = self.CurrentOffsetWithinLine - len('SET')
-                PcdPair = self.__GetNextPcdName()
+                PcdPair = self.__GetNextPcdSettings()
                 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
                 if not self.__IsToken( "="):
                     raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
 
                 Value = self.__GetExpression()
                 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
 
                 self.__PcdDict[PcdName] = Value
 
                 self.Profile.PcdDict[PcdPair] = Value
+                self.SetPcdLocalation(PcdPair)
                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
 
                 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
             elif self.__Token in ('!ifdef', '!ifndef', '!if'):
@@ -1046,10 +1047,33 @@ class FdfParser:
             self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
             return True
 
         return False
 
+    def __GetNextPcdWord(self):
+        self.__SkipWhiteSpace()
+        if self.__EndOfFile():
+            return False
+
+        TempChar = self.__CurrentChar()
+        StartPos = self.CurrentOffsetWithinLine
+        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == '[' or TempChar == ']':
+            self.__GetOneChar()
+            while not self.__EndOfLine():
+                TempChar = self.__CurrentChar()
+                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
+                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == '[' or TempChar == ']':
+                    self.__GetOneChar()
+
+                else:
+                    break
+
+            self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine]
+            return True
+
+        return False
+
     ## __GetNextToken() method
     #
     #   Get next token unit before a seperator
     #   If found, the string value is put into self.__Token
     #
@@ -1237,10 +1261,30 @@ class FdfParser:
             raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
         pcdCName = self.__Token
 
         return (pcdCName, pcdTokenSpaceCName)
 
+    def __GetNextPcdSettings(self):
+        if not self.__GetNextWord():
+            raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
+        pcdTokenSpaceCName = self.__Token
+
+        if not self.__IsToken( "."):
+            raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
+
+        if not self.__GetNextWord():
+            raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
+        pcdCName = self.__Token
+        
+        Fields = []
+        while self.__IsToken("."):
+            if not self.__GetNextPcdWord():
+                raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber)
+            Fields.append(self.__Token)
+
+        return (pcdCName, pcdTokenSpaceCName,".".join(Fields))
+
     ## __GetStringData() method
     #
     #   Get string contents quoted in ""
     #   If found, the decimal data is put into self.__Token
     #
@@ -1552,10 +1596,13 @@ class FdfParser:
             FileName = self.__Token
             Obj.CreateFileName = FileName
 
         return True
 
+    def SetPcdLocalation(self,pcdpair):
+        self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)
+
     ## __GetTokenStatements() method
     #
     #   Get token statements
     #
     #   @param  self        The object pointer
@@ -1570,13 +1617,14 @@ class FdfParser:
                 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
     
             Obj.BaseAddress = self.__Token
     
             if self.__IsToken( "|"):
-                pcdPair = self.__GetNextPcdName()
+                pcdPair = self.__GetNextPcdSettings()
                 Obj.BaseAddressPcd = pcdPair
                 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
+                self.SetPcdLocalation(pcdPair)
                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
             return True
 
         if self.__IsKeyword( "Size"):
@@ -1586,13 +1634,14 @@ class FdfParser:
             if not self.__GetNextHexNumber():
                 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
 
             Size = self.__Token
             if self.__IsToken( "|"):
-                pcdPair = self.__GetNextPcdName()
+                pcdPair = self.__GetNextPcdSettings()
                 Obj.SizePcd = pcdPair
                 self.Profile.PcdDict[pcdPair] = Size
+                self.SetPcdLocalation(pcdPair)
                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
             Obj.Size = long(Size, 0)
             return True
 
@@ -1679,13 +1728,14 @@ class FdfParser:
             raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
 
         BlockSize = self.__Token
         BlockSizePcd = None
         if self.__IsToken( "|"):
-            PcdPair = self.__GetNextPcdName()
+            PcdPair = self.__GetNextPcdSettings()
             BlockSizePcd = PcdPair
             self.Profile.PcdDict[PcdPair] = BlockSize
+            self.SetPcdLocalation(PcdPair)
             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
         BlockSize = long(BlockSize, 0)
 
         BlockNumber = None
@@ -1762,21 +1812,22 @@ class FdfParser:
     #   @retval True        Successfully find
     #   @retval False       Not able to find
     #
     def __GetSetStatement(self, Obj):
         if self.__IsKeyword("SET"):
-            PcdPair = self.__GetNextPcdName()
+            PcdPair = self.__GetNextPcdSettings()
 
             if not self.__IsToken( "="):
                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
 
             Value = self.__GetExpression()
             Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
 
             if Obj:
                 Obj.SetVarDict[PcdPair] = Value
             self.Profile.PcdDict[PcdPair] = Value
+            self.SetPcdLocalation(PcdPair)
             FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
             self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
             return True
 
         return False
@@ -1849,18 +1900,20 @@ class FdfParser:
             #
             self.__UndoToken()
             IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
                            RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
             if IsRegionPcd:
-                RegionObj.PcdOffset = self.__GetNextPcdName()
+                RegionObj.PcdOffset = self.__GetNextPcdSettings()
                 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
+                self.SetPcdLocalation(RegionObj.PcdOffset)
                 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
                 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
                 if self.__IsToken( "|"):
-                    RegionObj.PcdSize = self.__GetNextPcdName()
+                    RegionObj.PcdSize = self.__GetNextPcdSettings()
                     self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
+                    self.SetPcdLocalation(RegionObj.PcdSize)
                     self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
                     FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                     self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
 
             if not self.__GetNextWord():
@@ -2594,11 +2647,11 @@ class FdfParser:
             if not self.__GetNextWord():
                 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
             if self.__Token == 'PCD':
                 if not self.__IsToken( "("):
                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
-                PcdPair = self.__GetNextPcdName()
+                PcdPair = self.__GetNextPcdSettings()
                 if not self.__IsToken( ")"):
                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
                 
         FfsFileObj.NameGuid = self.__Token
@@ -3682,11 +3735,11 @@ class FdfParser:
             if not self.__GetNextWord():
                 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
             if self.__Token == 'PCD':
                 if not self.__IsToken( "("):
                     raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
-                PcdPair = self.__GetNextPcdName()
+                PcdPair = self.__GetNextPcdSettings()
                 if not self.__IsToken( ")"):
                     raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
                 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
             
         NameGuid = self.__Token
@@ -3956,11 +4009,11 @@ class FdfParser:
                     self.__GetNextWord()
                 
                     if self.__Token == 'PCD':
                         if not self.__IsToken( "("):
                             raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
-                        PcdPair = self.__GetNextPcdName()
+                        PcdPair = self.__GetNextPcdSettings()
                         if not self.__IsToken( ")"):
                             raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
                         self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
                         
                 EfiSectionObj.FileName = self.__Token        
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index 209315d901..59b7f5fe20 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -68,18 +68,29 @@ class PcdClassObject(object):
         self.DscDefaultValue = None
         self.DscRawValue = None
         if IsDsc:
             self.DscDefaultValue = Value
         self.PcdValueFromComm = ""
+        self.PcdValueFromFdf = ""
         self.DefinitionPosition = ("","")
 
     ## Get the maximum number of bytes
     def GetPcdMaxSize(self):
         if self.DatumType in TAB_PCD_NUMERIC_TYPES:
             return MAX_SIZE_TYPE[self.DatumType]
 
         MaxSize = int(self.MaxDatumSize,10) if self.MaxDatumSize else 0
+        if self.PcdValueFromFdf:
+            if self.PcdValueFromFdf.startswith("{") and self.PcdValueFromFdf.endswith("}"):
+                MaxSize =  max([len(self.PcdValueFromFdf.split(",")),MaxSize])
+            elif self.PcdValueFromFdf.startswith("\"") or self.PcdValueFromFdf.startswith("\'"):
+                MaxSize =  max([len(self.PcdValueFromFdf)-2+1,MaxSize])
+            elif self.PcdValueFromFdf.startswith("L\""):
+                MaxSize =  max([2*(len(self.PcdValueFromFdf)-3+1),MaxSize])
+            else:
+                MaxSize = max([len(self.PcdValueFromFdf),MaxSize])
+
         if self.PcdValueFromComm:
             if self.PcdValueFromComm.startswith("{") and self.PcdValueFromComm.endswith("}"):
                 return max([len(self.PcdValueFromComm.split(",")),MaxSize])
             elif self.PcdValueFromComm.startswith("\"") or self.PcdValueFromComm.startswith("\'"):
                 return max([len(self.PcdValueFromComm)-2+1,MaxSize])
@@ -167,10 +178,11 @@ class StructurePcd(PcdClassObject):
         self.PcdDefineLineNo = 0
         self.PkgPath = ""
         self.DefaultValueFromDec = ""
         self.ValueChain = set()
         self.PcdFieldValueFromComm = collections.OrderedDict()
+        self.PcdFieldValueFromFdf = collections.OrderedDict()
     def __repr__(self):
         return self.TypeName
 
     def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
         if FieldName in self.DefaultValues:
@@ -214,10 +226,11 @@ class StructurePcd(PcdClassObject):
         self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
         self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
         self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
         self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
         self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
+        self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
         self.DefinitionPosition = PcdObject.DefinitionPosition if PcdObject.DefinitionPosition else self.DefinitionPosition
         if type(PcdObject) is StructurePcd:
             self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
             self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
             self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
@@ -229,10 +242,11 @@ class StructurePcd(PcdClassObject):
             self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
             self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
             self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
             self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
             self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
+            self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
 
 ## LibraryClassObject
 #
 # This Class defines LibraryClassObject used in BuildDatabase
 #
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 1ed7eb1c2c..c3d40f7daf 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -1128,11 +1128,12 @@ class DscBuildData(PlatformBuildClassObject):
             self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
             self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
 
             self._Pcds = self.CompletePcdValues(self._Pcds)
-            self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)
+            self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
+            self._Pcds = self.OverrideByCommOverAll(self._Pcds)
             self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
             self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
             self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
 
             self.RecoverCommandLinePcd()
@@ -1188,11 +1189,38 @@ class DscBuildData(PlatformBuildClassObject):
             structure_pcd_data[(item[0],item[1])].append(item)
 
         return structure_pcd_data
 
     @staticmethod
-    def OverrideByFdfComm(StruPcds):
+    def OverrideByFdf(StruPcds,workspace):
+        if GlobalData.gFdfParser is None:
+            return StruPcds
+        StructurePcdInFdf = OrderedDict()
+        fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
+        fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
+        for item in fdfpcd :
+            if len(item[2]) and (item[0],item[1]) in StruPcds:
+                StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
+        GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
+        for Pcd in StruPcds.values():
+            if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
+                continue
+            FieldValues = OrderedDict()
+            for item in StructurePcdInFdf:
+                if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
+                    FieldValues[item[2]] = StructurePcdInFdf[item]
+            for field in FieldValues:
+                if field not in Pcd.PcdFieldValueFromFdf:
+                    Pcd.PcdFieldValueFromFdf[field] = ["","",""]
+                Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
+                Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
+                Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
+
+        return StruPcds
+
+    @staticmethod
+    def OverrideByComm(StruPcds):
         StructurePcdInCom = OrderedDict()
         for item in GlobalData.BuildOptionPcd:
             if len(item) == 5 and (item[1],item[0]) in StruPcds:
                 StructurePcdInCom[(item[0],item[1],item[2] )] = (item[3],item[4])
         GlobalPcds = {(item[0],item[1]) for item in StructurePcdInCom}
@@ -1209,11 +1237,11 @@ class DscBuildData(PlatformBuildClassObject):
                 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
                 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
                 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
         return StruPcds
 
-    def OverrideByFdfCommOverAll(self,AllPcds):
+    def OverrideByCommOverAll(self,AllPcds):
         def CheckStructureInComm(commpcds):
             if not commpcds:
                 return False
             if len(commpcds[0]) == 5:
                 return True
@@ -1256,10 +1284,54 @@ class DscBuildData(PlatformBuildClassObject):
                                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
                                         self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
                         self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
                         self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]
         return AllPcds
+
+    def OverrideByFdfOverAll(self,AllPcds):
+
+        if GlobalData.gFdfParser is None:
+            return
+        NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
+        for Guid,Name,Field in NoFiledValues:
+            if len(Field):
+                continue
+            Value = NoFiledValues[(Guid,Name,Field)]
+            if (Name,Guid) in AllPcds:
+                Pcd = AllPcds.get((Name,Guid))
+                if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
+                    self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
+                else:
+                    Pcd.PcdValueFromComm = Value
+                    Pcd.DefaultValue = Value
+                    for sku in Pcd.SkuInfoList:
+                        SkuInfo = Pcd.SkuInfoList[sku]
+                        if SkuInfo.DefaultValue:
+                            SkuInfo.DefaultValue = Value
+                        else:
+                            SkuInfo.HiiDefaultValue = Value
+                            for defaultstore in SkuInfo.DefaultStoreDict:
+                                SkuInfo.DefaultStoreDict[defaultstore] = Value
+                    if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
+                        if Pcd.DatumType == TAB_VOID:
+                            if not Pcd.MaxDatumSize:
+                                Pcd.MaxDatumSize = '0'
+                            CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
+                            OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
+                            MaxSize = max(CurrentSize, OptionSize)
+                            Pcd.MaxDatumSize = str(MaxSize)
+            else:
+                PcdInDec = self.DecPcds.get((Name,Guid))
+                if PcdInDec:
+                    PcdInDec.PcdValueFromComm = Value
+                    if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+                                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
+                                        self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
+                        self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
+                        self.Pcds[Name, Guid].DefaultValue = Value
+        return AllPcds
+
     def UpdateStructuredPcds(self, TypeList, AllPcds):
 
         DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
@@ -1365,11 +1437,12 @@ class DscBuildData(PlatformBuildClassObject):
 
                     for defaultstoreid in DefaultStores:
                         if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
                             stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
                             stru_pcd.ValueChain.add((skuid,defaultstoreid))
-        S_pcd_set = DscBuildData.OverrideByFdfComm(S_pcd_set)
+        S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
+        S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
         Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
         if Str_Pcd_Values:
             for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:
                 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
                 if str_pcd_obj is None:
@@ -1591,10 +1664,34 @@ class DscBuildData(PlatformBuildClassObject):
                                 FieldName = FieldName.split(']', 1)[1]
                             FieldName = NewFieldName + FieldName
                             while '[' in FieldName:
                                 FieldName = FieldName.rsplit('[', 1)[0]
                                 CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+        if Pcd.PcdFieldValueFromFdf:
+            CApp = CApp + "// From fdf \n"
+        for FieldName in Pcd.PcdFieldValueFromFdf:
+            FieldName = "." + FieldName
+            IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
+            if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
+                try:
+                    Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
+                except BadExpression:
+                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+                                    (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
+                Value, ValueSize = ParseFieldValue(Value)
+                CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]);
+            else:
+                NewFieldName = ''
+                FieldName_ori = FieldName.strip('.')
+                while '[' in  FieldName:
+                    NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                    FieldName = FieldName.split(']', 1)[1]
+                FieldName = NewFieldName + FieldName
+                while '[' in FieldName:
+                    FieldName = FieldName.rsplit('[', 1)[0]
+                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
         if Pcd.PcdFieldValueFromComm:
             CApp = CApp + "// From Command Line \n"
         for FieldName in Pcd.PcdFieldValueFromComm:
             FieldName = "." + FieldName
             IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
@@ -1832,10 +1929,74 @@ class DscBuildData(PlatformBuildClassObject):
 
     @staticmethod
     def GenerateCommandLineValueStatement(Pcd):
         CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
         return CApp
+    def GenerateFdfValue(self,Pcd):
+        CApp = "// Value in Fdf\n"
+        CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
+        CApp = CApp + '  UINT32  FieldSize;\n'
+        CApp = CApp + '  CHAR8   *Value;\n'
+
+        pcddefaultvalue = Pcd.PcdValueFromFdf
+        for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
+            if not FieldList:
+                continue
+            if pcddefaultvalue and FieldList == pcddefaultvalue:
+                IsArray = IsFieldValueAnArray(FieldList)
+                if IsArray:
+                    try:
+                        FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
+                    except BadExpression:
+                        EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
+                                        (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
+                Value, ValueSize = ParseFieldValue (FieldList)
+
+                if isinstance(Value, str):
+                    CApp = CApp + '  Pcd = %s; // From Fdf \n' % (Value)
+                elif IsArray:
+                #
+                # Use memcpy() to copy value into field
+                #
+                    CApp = CApp + '  Value     = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
+                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+                continue
+            for FieldName in FieldList:
+                IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
+                if IsArray:
+                    try:
+                        FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
+                    except BadExpression:
+                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
+                                        (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
+                    except:
+                        print "error"
+                try:
+                    Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+                except Exception:
+                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
+                if isinstance(Value, str):
+                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                elif IsArray:
+                #
+                # Use memcpy() to copy value into field
+                #
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
+                    CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                    CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+                else:
+                    if ValueSize > 4:
+                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+                    else:
+                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+        CApp = CApp + "}\n"
+        return CApp
+
+    @staticmethod
+    def GenerateFdfValueStatement(Pcd):
+        CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+        return CApp
 
     def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
         OverrideValues = {DefaultStore:""}
         if Pcd.SkuOverrideValues:
             OverrideValues = Pcd.SkuOverrideValues[SkuName]
@@ -1904,10 +2065,11 @@ class DscBuildData(PlatformBuildClassObject):
                     if skuname == SkuName:
                         break
             else:
                 CApp = CApp + "// SkuName: %s,  DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
                 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd,self.SkuIdMgr.SystemSkuId,TAB_DEFAULT_STORES_DEFAULT)
+            CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
             CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
             #
             # Set new PCD value and size
             #
             CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
@@ -1940,10 +2102,11 @@ class DscBuildData(PlatformBuildClassObject):
         CApp = CApp + '\n'
         for PcdName in StructuredPcds:
             Pcd = StructuredPcds[PcdName]
             CApp = CApp + self.GenerateSizeFunction(Pcd)
             CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
+            CApp = CApp + self.GenerateFdfValue(Pcd)
             CApp = CApp + self.GenerateCommandLineValue(Pcd)
             if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                 CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
             else:
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index 324b6ff6aa..bc0b6e5d68 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -1329,10 +1329,13 @@ class PcdReport(object):
         OverrideFieldStruct = collections.OrderedDict()
         if OverrideStruct:
             for Key, Values in OverrideStruct.items():
                 if Values[1] and Values[1].endswith('.dsc'):
                     OverrideFieldStruct[Key] = Values
+        if Pcd.PcdFieldValueFromFdf:
+            for Key, Values in Pcd.PcdFieldValueFromFdf.items():
+                OverrideFieldStruct[Key] = Values
         if Pcd.PcdFieldValueFromComm:
             for Key, Values in Pcd.PcdFieldValueFromComm.items():
                 OverrideFieldStruct[Key] = Values
         return OverrideFieldStruct
 
-- 
2.16.2.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel