public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* Re: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd
       [not found] <163E2552F529AEC6.4805@groups.io>
@ 2020-10-26  3:59 ` Bob Feng
  2020-10-27  6:19   ` 回复: " gaoliming
  0 siblings, 1 reply; 4+ messages in thread
From: Bob Feng @ 2020-10-26  3:59 UTC (permalink / raw)
  To: devel@edk2.groups.io, Feng, Bob C, Liming Gao
  Cc: Chen, Christine, Kinney, Michael D

Liming, would you review this patch?

Thanks,
Bob

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob Feng
Sent: Thursday, October 15, 2020 6:59 PM
To: devel@edk2.groups.io
Cc: Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>
Subject: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd

This patch is to enable the Module scoped Structure Pcd usage.
User can set structure pcd field value in module scope. For example,
under the [components] section of a dsc file, user can override some
field value for a specific module.

  Package/Module.inf{
      <PcdsFixedAtBuild>
      gUefiTokenSpaceGuid.StructurePcdModule.FieldName | 5
  }

Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
---
V2: Fixed the incorrect format in build report.
 BaseTools/Source/Python/AutoGen/DataPipe.py   |   5 +-
 .../Source/Python/AutoGen/ModuleAutoGen.py    |   4 +-
 .../Python/AutoGen/ModuleAutoGenHelper.py     |  10 +-
 .../Source/Python/AutoGen/PlatformAutoGen.py  |   8 +-
 .../Python/Workspace/BuildClassObject.py      |  12 +
 .../Source/Python/Workspace/DscBuildData.py   | 243 ++++++++++++++++--
 BaseTools/Source/Python/build/BuildReport.py  | 109 ++++----
 7 files changed, 319 insertions(+), 72 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/DataPipe.py b/BaseTools/Source/Python/AutoGen/DataPipe.py
index 50403fbfb5..86ac2b928d 100755
--- a/BaseTools/Source/Python/AutoGen/DataPipe.py
+++ b/BaseTools/Source/Python/AutoGen/DataPipe.py
@@ -70,13 +70,14 @@ class MemoryDataPipe(DataPipe):
             }
 
         #Platform Module Pcds
         ModulePcds = {}
         for m in PlatformInfo.Platform.Modules:
-            m_pcds =  PlatformInfo.Platform.Modules[m].Pcds
+            module = PlatformInfo.Platform.Modules[m]
+            m_pcds =  module.Pcds
             if m_pcds:
-                ModulePcds[(m.File,m.Root,m.Arch)] = [PCD_DATA(
+                ModulePcds[module.Guid] = [PCD_DATA(
             pcd.TokenCName,pcd.TokenSpaceGuidCName,pcd.Type,
             pcd.DatumType,pcd.SkuInfoList,pcd.DefaultValue,
             pcd.MaxDatumSize,pcd.UserDefinedDefaultStoresFlag,pcd.validateranges,
                  pcd.validlists,pcd.expressions,pcd.CustomAttribute,pcd.TokenValue)
             for pcd in PlatformInfo.Platform.Modules[m].Pcds.values()]
diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
index eebf6e87f5..d70b0d7ae8 100755
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
@@ -1030,11 +1030,11 @@ class ModuleAutoGen(AutoGen):
     #   @retval     list                    The list of PCD
     #
     @cached_property
     def ModulePcdList(self):
         # apply PCD settings from platform
-        RetVal = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
+        RetVal = self.PlatformInfo.ApplyPcdSetting(self, self.Module.Pcds)
 
         return RetVal
     @cached_property
     def _PcdComments(self):
         ReVal = OrderedListDict()
@@ -1061,11 +1061,11 @@ class ModuleAutoGen(AutoGen):
                 # skip duplicated PCDs
                 if Key in self.Module.Pcds or Key in Pcds:
                     continue
                 Pcds.add(Key)
                 PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
-            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self.Module, PcdsInLibrary, Library=Library))
+            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self, PcdsInLibrary, Library=Library))
         return RetVal
 
     ## Get the GUID value mapping
     #
     #   @retval     dict    The mapping between GUID cname and its value
diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
index 9dd93b9beb..8e60643d1f 100644
--- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
+++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
@@ -477,12 +477,13 @@ class PlatformInfo(AutoGenInfo):
                 SkuName = TAB_DEFAULT
             ToPcd.SkuInfoList = {
                 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
             }
 
-    def ApplyPcdSetting(self, Module, Pcds, Library=""):
+    def ApplyPcdSetting(self, Ma, Pcds, Library=""):
         # for each PCD in module
+        Module=Ma.Module
         for Name, Guid in Pcds:
             PcdInModule = Pcds[Name, Guid]
             # find out the PCD setting in platform
             if (Name, Guid) in self.Pcds:
                 PcdInPlatform = self.Pcds[Name, Guid]
@@ -505,13 +506,16 @@ class PlatformInfo(AutoGenInfo):
                                                         % (Guid, Name, str(Module)),
                                 File=self.MetaFile
                                 )
 
         # override PCD settings with module specific setting
+        ModuleScopePcds = self.DataPipe.Get("MOL_PCDS")
         if Module in self.Platform.Modules:
             PlatformModule = self.Platform.Modules[str(Module)]
-            for Key  in PlatformModule.Pcds:
+            PCD_DATA = ModuleScopePcds.get(Ma.Guid,{})
+            mPcds = {(pcd.TokenCName,pcd.TokenSpaceGuidCName): pcd for pcd in PCD_DATA}
+            for Key  in mPcds:
                 if self.BuildOptionPcd:
                     for pcd in self.BuildOptionPcd:
                         (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
                         if (TokenCName, TokenSpaceGuidCName) == Key and FieldName =="":
                             PlatformModule.Pcds[Key].DefaultValue = pcdvalue
@@ -526,11 +530,11 @@ class PlatformInfo(AutoGenInfo):
                         if PcdItem in Pcds:
                             ToPcd = Pcds[PcdItem]
                             Flag = True
                             break
                 if Flag:
-                    self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module, Msg="DSC Components Module scoped PCD section", Library=Library)
+                    self._OverridePcd(ToPcd, mPcds[Key], Module, Msg="DSC Components Module scoped PCD section", Library=Library)
         # use PCD value to calculate the MaxDatumSize when it is not specified
         for Name, Guid in Pcds:
             Pcd = Pcds[Name, Guid]
             if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize:
                 Pcd.MaxSizeUserSet = None
diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
index 26ab8e7f36..c7a4cb9a08 100644
--- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
@@ -1041,11 +1041,17 @@ class PlatformAutoGen(AutoGen):
             TokenNumber += 1
         return RetVal
 
     @cached_property
     def _MbList(self):
-        return [self.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain] for m in self.Platform.Modules]
+        mlist = []
+        for m in self.Platform.Modules:
+            component = self.Platform.Modules[m]
+            module = self.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain]
+            module.Guid = component.Guid
+            mlist.append(module)
+        return mlist
 
     @cached_property
     def _MaList(self):
         for ModuleFile in self.Platform.Modules:
             Ma = ModuleAutoGen(
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index db40e3b10c..ebb65fc2fe 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -68,10 +68,11 @@ class PcdClassObject(object):
         self.DscRawValueInfo = {}
         if IsDsc:
             self.DscDefaultValue = Value
         self.PcdValueFromComm = ""
         self.PcdValueFromFdf = ""
+        self.PcdValueFromComponents = {} #{ModuleGuid:value, file_path,lineNo}
         self.CustomAttribute = {}
         self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
         self._Capacity = None
 
     @property
@@ -296,10 +297,11 @@ class StructurePcd(PcdClassObject):
         self.DefaultValueFromDecInfo = None
         self.ValueChain = set()
         self.PcdFieldValueFromComm = OrderedDict()
         self.PcdFieldValueFromFdf = OrderedDict()
         self.DefaultFromDSC=None
+        self.PcdFiledValueFromDscComponent = OrderedDict()
     def __repr__(self):
         return self.TypeName
 
     def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0,DimensionAttr ="-1"):
         if DimensionAttr not in self.DefaultValues:
@@ -322,10 +324,16 @@ class StructurePcd(PcdClassObject):
         if FieldName in self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
             del self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
         self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
         return self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldName]
 
+    def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid, FileName="", LineNo=0, DimensionAttr = '-1'):
+        self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid, OrderedDict())
+        self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAttr,OrderedDict())
+        self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName] =  [Value.strip(), FileName, LineNo]
+        return self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldName]
+
     def SetPcdMode (self, PcdMode):
         self.PcdMode = PcdMode
 
     def copy(self, PcdObject):
         self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName
@@ -363,10 +371,11 @@ class StructurePcd(PcdClassObject):
             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
+            self.PcdFiledValueFromDscComponent = PcdObject.PcdFiledValueFromDscComponent if PcdObject.PcdFiledValueFromDscComponent else self.PcdFiledValueFromDscComponent
 
     def __deepcopy__(self,memo):
         new_pcd = StructurePcd()
         self.sharedcopy(new_pcd)
 
@@ -381,10 +390,11 @@ class StructurePcd(PcdClassObject):
         new_pcd.DefaultValues = CopyDict(self.DefaultValues)
         new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
         new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
         new_pcd.PcdFieldValueFromComm = CopyDict(self.PcdFieldValueFromComm)
         new_pcd.PcdFieldValueFromFdf = CopyDict(self.PcdFieldValueFromFdf)
+        new_pcd.PcdFiledValueFromDscComponent = CopyDict(self.PcdFiledValueFromDscComponent)
         new_pcd.ValueChain = {item for item in self.ValueChain}
         return new_pcd
 
 LibraryClassObject = namedtuple('LibraryClassObject', ['LibraryClass','SupModList'])
 
@@ -461,10 +471,12 @@ class ModuleBuildClassObject(object):
         self.Includes                = []
         self.Packages                = []
         self.Pcds                    = {}
         self.BuildOptions            = {}
         self.Depex                   = {}
+        self.StrPcdSet               = []
+        self.StrPcdOverallValue      = {}
 
     ## Convert the class to a string
     #
     #  Convert member MetaFile of the class to a string
     #
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 1ed3d9b909..1bb4fdc183 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -753,13 +753,14 @@ class DscBuildData(PlatformBuildClassObject):
             ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
             if ErrorCode != 0:
                 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
                                 ExtraData=ErrorInfo)
 
+            ModuleBuildData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
             Module = ModuleBuildClassObject()
             Module.MetaFile = ModuleFile
-
+            Module.Guid = ModuleBuildData.Guid
             # get module private library instance
             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
             for Record in RecordList:
                 LibraryClass = Record[0]
                 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
@@ -776,11 +777,11 @@ class DscBuildData(PlatformBuildClassObject):
                     LibraryClass = 'NULL%d' % self._NullLibraryNumber
                     EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
                 Module.LibraryClasses[LibraryClass] = LibraryPath
                 if LibraryPath not in self.LibraryInstances:
                     self.LibraryInstances.append(LibraryPath)
-
+            S_PcdSet = []
             # get module private PCD setting
             for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
                          MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
                 RecordList = self._RawData[Type, self._Arch, None, ModuleId]
                 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
@@ -790,24 +791,35 @@ class DscBuildData(PlatformBuildClassObject):
                     if len(TokenList) > 2:
                         MaxDatumSize = TokenList[2]
                     else:
                         MaxDatumSize = ''
                     TypeString = self._PCD_TYPE_STRING_[Type]
-                    Pcd = PcdClassObject(
-                            PcdCName,
-                            TokenSpaceGuid,
-                            TypeString,
-                            '',
-                            DefaultValue,
-                            '',
-                            MaxDatumSize,
-                            {},
-                            False,
-                            None
-                            )
-                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
 
+                    TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
+
+                    if ("." in TokenSpaceGuid or "[" in PcdCName):
+                        S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
+                        DefaultValue = ''
+                    if ( PCName,TCName) not in Module.Pcds:
+                        Pcd = PcdClassObject(
+                                PCName,
+                                TCName,
+                                TypeString,
+                                '',
+                                DefaultValue,
+                                '',
+                                MaxDatumSize,
+                                {},
+                                False,
+                                None,
+                                IsDsc=True)
+                        Module.Pcds[PCName, TCName] = Pcd
+
+            Module.StrPcdSet = S_PcdSet
+            for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
+                if (PCName,TCName) in Module.Pcds:
+                    Module.StrPcdOverallValue[(PCName,TCName)] = Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
             # get module private build options
             RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
                     Module.BuildOptions[ToolChainFamily, ToolChain] = Option
@@ -820,11 +832,13 @@ class DscBuildData(PlatformBuildClassObject):
                 if len(RecordList) != 1:
                     EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
                                     File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
                 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
                 ModuleFile.Arch = self._Arch
-
+                Module.Guid = RecordList[0][2]
+                for item in Module.StrPcdSet:
+                    item[4] = RecordList[0][2]
             self._Modules[ModuleFile] = Module
         return self._Modules
 
     ## Retrieve all possible library instances used in this platform
     @property
@@ -1497,11 +1511,19 @@ class DscBuildData(PlatformBuildClassObject):
                     EdkLogger.error('build', PARSER_ERROR,
                                 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
                                 File=self.MetaFile, Line = Dummy5)
 
                 S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
-
+        ModuleScopeOverallValue = {}
+        for m in self.Modules.values():
+            mguid = m.Guid
+            if m.StrPcdSet:
+                S_PcdSet.extend(m.StrPcdSet)
+                mguid = m.StrPcdSet[0][4]
+            for (PCName,TCName) in m.StrPcdOverallValue:
+                Value, dsc_file, lineNo = m.StrPcdOverallValue[(PCName,TCName)]
+                ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value, dsc_file, lineNo
         # handle pcd value override
         StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
         S_pcd_set = OrderedDict()
         for str_pcd in StrPcdSet:
             str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
@@ -1515,10 +1537,15 @@ class DscBuildData(PlatformBuildClassObject):
                 else:
                     str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
             for str_pcd_data in StrPcdSet[str_pcd]:
                 if str_pcd_data[4] in SkuIds:
                     str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
+                elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
+                    str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
+                    PcdComponentValue = ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.TokenSpaceGuidCName))
+                    for module_guid in PcdComponentValue:
+                        str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] = PcdComponentValue[module_guid]
             S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
 
         # Add the Structure PCD that only defined in DEC, don't have override in DSC file
         for Pcd in self.DecPcds:
             if isinstance(self._DecPcds[Pcd], StructurePcd):
@@ -1573,11 +1600,14 @@ class DscBuildData(PlatformBuildClassObject):
                         if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
                             stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
                             stru_pcd.ValueChain.add((skuid, defaultstoreid))
         S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
         S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
+
+        # Create a tool to caculate structure pcd value
         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:
                     print(PcdName, PcdGuid)
@@ -1591,10 +1621,18 @@ class DscBuildData(PlatformBuildClassObject):
                         str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
                 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                     if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
                         str_pcd_obj.DefaultValue = PcdValue
+                    else:
+                        #Module Scope Structure Pcd
+                        moduleguid = skuname.replace("S","-")
+                        if GlobalData.gGuidPattern.match(moduleguid):
+                            for component in self.Modules.values():
+                                if component.Guid == moduleguid:
+                                    component.Pcds[(PcdName, PcdGuid)].DefaultValue = PcdValue
+
                 else:
                     if skuname not in str_pcd_obj.SkuInfoList:
                         nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
                         NoDefault = False
                         while nextskuid not in str_pcd_obj.SkuInfoList:
@@ -2339,10 +2377,79 @@ class DscBuildData(PlatformBuildClassObject):
                     else:
                         CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
         CApp = CApp + "}\n"
         return CApp
 
+    def GenerateModuleScopeValue(self, Pcd):
+        CApp = "// Value in Dsc Module scope \n"
+        for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
+
+            CApp = CApp + "void Assign_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, ModuleGuid,Pcd.BaseDatumType)
+            CApp = CApp + '  UINT32  FieldSize;\n'
+            CApp = CApp + '  CHAR8   *Value;\n'
+            pcddefaultvalue, file_path,lineNo = Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
+
+            if pcddefaultvalue:
+                IsArray = _IsFieldValueAnArray(pcddefaultvalue)
+                if IsArray:
+                    try:
+                        FieldList = ValueExpressionEx(pcddefaultvalue, TAB_VOID)(True)
+                    except BadExpression:
+                        EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from %s Line %s: %s" %
+                                        (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
+                Value, ValueSize = ParseFieldValue (FieldList)
+
+                if isinstance(Value, str):
+                    CApp = CApp + '  Pcd = %s; // From %s Line %s \n' % (Value, file_path, lineNo)
+                elif IsArray:
+                #
+                # Use memcpy() to copy value into field
+                #
+                    CApp = CApp + '  Value     = %s; // From %s Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path, lineNo)
+                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+
+
+            PcdFiledValue = Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
+            for index in PcdFiledValue:
+                FieldList = PcdFiledValue[index]
+                if not FieldList:
+                    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.BaseDatumType, 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 + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, 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 '[' in FieldName and ']' in FieldName:
+                            Index = int(FieldName.split('[')[1].split(']')[0])
+                            CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
+                        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 %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+            CApp = CApp + "}\n"
+        return CApp
+
     @staticmethod
     def GenerateCommandLineValueStatement(Pcd):
         CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
         return CApp
     def GenerateFdfValue(self,Pcd):
@@ -2412,10 +2519,88 @@ class DscBuildData(PlatformBuildClassObject):
     @staticmethod
     def GenerateFdfValueStatement(Pcd):
         CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
         return CApp
 
+    @staticmethod
+    def GenerateModuleValueStatement(module_guid, Pcd):
+        CApp = "  Assign_%s_%s_%s_Value(Pcd);\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
+        return CApp
+    def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd,  InitByteValue, CApp):
+        for module_guid in Pcd.PcdFiledValueFromDscComponent:
+            CApp = CApp + 'void\n'
+            CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+            CApp = CApp + '  void\n'
+            CApp = CApp + '  )\n'
+            CApp = CApp + '{\n'
+            CApp = CApp + '  UINT32  Size;\n'
+            CApp = CApp + '  UINT32  FieldSize;\n'
+            CApp = CApp + '  CHAR8   *Value;\n'
+            CApp = CApp + '  UINT32  OriginalSize;\n'
+            CApp = CApp + '  VOID    *OriginalPcd;\n'
+
+            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
+
+            CApp = CApp + '\n'
+
+            PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
+            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
+            #
+            # Get current PCD value and size
+            #
+            CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+            #
+            # Determine the size of the PCD.  For simple structures, sizeof(TYPE) provides
+            # the correct value.  For structures with a flexible array member, the flexible
+            # array member is detected, and the size is based on the highest index used with
+            # the flexible array member.  The flexible array member must be the last field
+            # in a structure.  The size formula for this case is:
+            # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+            #
+            CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_DEFAULT)
+            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+                CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
+                CApp = CApp + '  Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
+
+            #
+            # Allocate and zero buffer for the PCD
+            # Must handle cases where current value is smaller, larger, or same size
+            # Always keep that larger one as the current size
+            #
+            CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
+            CApp = CApp + '  memset (Pcd, 0, Size);\n'
+
+            #
+            # Copy current PCD value into allocated buffer.
+            #
+            CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+
+            #
+            # Assign field values in PCD
+            #
+            CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
+
+            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)
+            CApp = CApp + DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
+            #
+            # Set new PCD value and size
+            #
+            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+            #
+            # Free PCD
+            #
+            CApp = CApp + '  free (Pcd);\n'
+            CApp = CApp + '}\n'
+            CApp = CApp + '\n'
+        return InitByteValue,CApp
+
     def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
         OverrideValues = {DefaultStore:{}}
         if Pcd.SkuOverrideValues:
             OverrideValues = Pcd.SkuOverrideValues[SkuName]
         if not OverrideValues:
@@ -2584,26 +2769,42 @@ class DscBuildData(PlatformBuildClassObject):
         CApp = CApp + '\n'
         for Pcd in StructuredPcds.values():
             CApp = CApp + self.GenerateArrayAssignment(Pcd)
         for PcdName in sorted(StructuredPcds.keys()):
             Pcd = StructuredPcds[PcdName]
+
+            #create void void Cal_tocken_cname_Size functions
             CApp = CApp + self.GenerateSizeFunction(Pcd)
+
+            #create void Assign_ functions
+
+            # From DEC
             CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
+            # From Fdf
             CApp = CApp + self.GenerateFdfValue(Pcd)
+            # From CommandLine
             CApp = CApp + self.GenerateCommandLineValue(Pcd)
+
+            # From Dsc Global setting
             if self.SkuOverrideValuesEmpty(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:
                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                     if SkuName not in Pcd.SkuOverrideValues:
                         continue
                     for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
                         CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
+
+            # From Dsc module scope setting
+            CApp = CApp + self.GenerateModuleScopeValue(Pcd)
+
+            #create Initialize_ functions
             if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
+                InitByteValue, CApp =  self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitByteValue,CApp)
             else:
                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                     if SkuName not in Pcd.SkuOverrideValues:
                         continue
                     for DefaultStoreName in Pcd.DefaultStoreName:
@@ -2616,10 +2817,12 @@ class DscBuildData(PlatformBuildClassObject):
         CApp = CApp + '  )\n'
         CApp = CApp + '{\n'
         for Pcd in StructuredPcds.values():
             if self.SkuOverrideValuesEmpty(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 + '  Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
+                    CApp += "  Initialize_%s_%s_%s_%s();\n" % (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
             else:
                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                     if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
                         continue
                     for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
@@ -2631,10 +2834,11 @@ class DscBuildData(PlatformBuildClassObject):
         if not os.path.exists(self.OutputPath):
             os.makedirs(self.OutputPath)
         CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
         SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
 
+        # start generating makefile
         MakeApp = PcdMakefileHeader
         if sys.platform == "win32":
             MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj %s.obj\n' % (self.OutputPath, PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) + 'INC = '
         else:
             MakeApp = MakeApp + PcdGccMakefile
@@ -2753,19 +2957,22 @@ class DscBuildData(PlatformBuildClassObject):
             MakeApp = MakeApp + '\tcp -f %s %s/PcdValueCommon.c\n' % (PcdValueCommonPath, self.OutputPath)
         MakeFileName = os.path.join(self.OutputPath, 'Makefile')
         MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
         SaveFileOnChange(MakeFileName, MakeApp, False)
 
+        # start generating input file
         InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
         OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
         SaveFileOnChange(InputValueFile, InitByteValue, False)
 
         Dest_PcdValueInitExe = PcdValueInitName
         if not sys.platform == "win32":
             Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName)
         else:
             Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName) +".exe"
+
+        #start building the structure pcd value tool
         Messages = ''
         if sys.platform == "win32":
             MakeCommand = 'nmake -f %s' % (MakeFileName)
             returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
             Messages = StdOut
@@ -2824,17 +3031,19 @@ class DscBuildData(PlatformBuildClassObject):
             if MessageGroup:
                 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
             else:
                 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
 
+        #start executing the structure pcd value tool
         if DscBuildData.NeedUpdateOutput(OutputValueFile, Dest_PcdValueInitExe, InputValueFile):
             Command = Dest_PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
             returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
             EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut, StdErr))
             if returncode != 0:
                 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s\n%s\n' % (Command, StdOut, StdErr))
 
+        #start update structure pcd final value
         File = open (OutputValueFile, 'r')
         FileBuffer = File.readlines()
         File.close()
 
         StructurePcdSet = []
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index 8efa869162..d4de07cae2 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -694,11 +694,11 @@ class ModuleReport(object):
             FileWrite(File, "PCI Class Code:       %s" % self.PciClassCode)
 
         FileWrite(File, gSectionSep)
 
         if "PCD" in ReportType:
-            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet)
+            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet,self.FileGuid)
 
         if "LIBRARY" in ReportType:
             self.LibraryReport.GenerateReport(File)
 
         if "DEPEX" in ReportType:
@@ -879,11 +879,11 @@ class PcdReport(object):
             for (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds:
                 DscDefaultValue = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DscDefaultValue
                 if DscDefaultValue:
                     self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue
 
-    def GenerateReport(self, File, ModulePcdSet):
+    def GenerateReport(self, File, ModulePcdSet,module_guid=None):
         if not ModulePcdSet:
             if self.ConditionalPcds:
                 self.GenerateReportDetail(File, ModulePcdSet, 1)
             if self.UnusedPcds:
                 IsEmpty = True
@@ -895,11 +895,11 @@ class PcdReport(object):
                             break
                     if not IsEmpty:
                         break
                 if not IsEmpty:
                     self.GenerateReportDetail(File, ModulePcdSet, 2)
-        self.GenerateReportDetail(File, ModulePcdSet)
+        self.GenerateReportDetail(File, ModulePcdSet,module_guid = module_guid)
 
     ##
     # Generate report for PCD information
     #
     # This function generates report for separate module expression
@@ -911,11 +911,11 @@ class PcdReport(object):
     #                        platform PCD report
     # @param ReportySubType  0 means platform/module PCD report, 1 means Conditional
     #                        directives section report, 2 means Unused Pcds section report
     # @param DscOverridePcds Module DSC override PCDs set
     #
-    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType = 0):
+    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType = 0,module_guid=None):
         PcdDict = self.AllPcds
         if ReportSubType == 1:
             PcdDict = self.ConditionalPcds
         elif ReportSubType == 2:
             PcdDict = self.UnusedPcds
@@ -991,14 +991,16 @@ class PcdReport(object):
                 if DscDefaultValue:
                     PcdValue = DscDefaultValue
                 #The DefaultValue of StructurePcd already be the latest, no need to update.
                 if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):
                     Pcd.DefaultValue = PcdValue
+                PcdComponentValue = None
                 if ModulePcdSet is not None:
                     if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:
                         continue
-                    InfDefaultValue, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
+                    InfDefaultValue, PcdComponentValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
+                    PcdValue = PcdComponentValue
                     #The DefaultValue of StructurePcd already be the latest, no need to update.
                     if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):
                         Pcd.DefaultValue = PcdValue
                     if InfDefaultValue:
                         try:
@@ -1079,62 +1081,68 @@ class PcdReport(object):
                 if self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):
                     IsStructure = True
                     if TypeName in ('DYNVPD', 'DEXVPD'):
                         SkuInfoList = Pcd.SkuInfoList
                     Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)]
+                    if ModulePcdSet and ModulePcdSet.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type)):
+                        InfDefaultValue, PcdComponentValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
+                        DscDefaultValBak = Pcd.DefaultValue
+                        Pcd.DefaultValue = PcdComponentValue
+
                     Pcd.DatumType = Pcd.StructName
                     if TypeName in ('DYNVPD', 'DEXVPD'):
                         Pcd.SkuInfoList = SkuInfoList
                     if Pcd.PcdValueFromComm or Pcd.PcdFieldValueFromComm:
                         BuildOptionMatch = True
                         DecMatch = False
                     elif Pcd.PcdValueFromFdf or Pcd.PcdFieldValueFromFdf:
                         DscDefaultValue = True
                         DscMatch = True
                         DecMatch = False
-                    elif Pcd.SkuOverrideValues:
-                        DscOverride = False
-                        if Pcd.DefaultFromDSC:
-                            DscOverride = True
-                        else:
-                            DictLen = 0
-                            for item in Pcd.SkuOverrideValues:
-                                DictLen += len(Pcd.SkuOverrideValues[item])
-                            if not DictLen:
-                                DscOverride = False
+                    else:
+                        if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
+                            DscOverride = False
+                            if Pcd.DefaultFromDSC:
+                                DscOverride = True
                             else:
-                                if not Pcd.SkuInfoList:
-                                    OverrideValues = Pcd.SkuOverrideValues
-                                    if OverrideValues:
-                                        for Data in OverrideValues.values():
-                                            Struct = list(Data.values())
-                                            if Struct:
-                                                DscOverride = self.ParseStruct(Struct[0])
-                                                break
+                                DictLen = 0
+                                for item in Pcd.SkuOverrideValues:
+                                    DictLen += len(Pcd.SkuOverrideValues[item])
+                                if not DictLen:
+                                    DscOverride = False
                                 else:
-                                    SkuList = sorted(Pcd.SkuInfoList.keys())
-                                    for Sku in SkuList:
-                                        SkuInfo = Pcd.SkuInfoList[Sku]
-                                        if SkuInfo.DefaultStoreDict:
-                                            DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys())
-                                            for DefaultStore in DefaultStoreList:
-                                                OverrideValues = Pcd.SkuOverrideValues[Sku]
-                                                DscOverride = self.ParseStruct(OverrideValues[DefaultStore])
-                                                if DscOverride:
+                                    if not Pcd.SkuInfoList:
+                                        OverrideValues = Pcd.SkuOverrideValues
+                                        if OverrideValues:
+                                            for Data in OverrideValues.values():
+                                                Struct = list(Data.values())
+                                                if Struct:
+                                                    DscOverride = self.ParseStruct(Struct[0])
                                                     break
-                                        if DscOverride:
-                                            break
-                        if DscOverride:
+                                    else:
+                                        SkuList = sorted(Pcd.SkuInfoList.keys())
+                                        for Sku in SkuList:
+                                            SkuInfo = Pcd.SkuInfoList[Sku]
+                                            if SkuInfo.DefaultStoreDict:
+                                                DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys())
+                                                for DefaultStore in DefaultStoreList:
+                                                    OverrideValues = Pcd.SkuOverrideValues[Sku]
+                                                    DscOverride = self.ParseStruct(OverrideValues[DefaultStore])
+                                                    if DscOverride:
+                                                        break
+                                            if DscOverride:
+                                                break
+                            if DscOverride:
+                                DscDefaultValue = True
+                                DscMatch = True
+                                DecMatch = False
+                            else:
+                                DecMatch = True
+                        else:
                             DscDefaultValue = True
                             DscMatch = True
                             DecMatch = False
-                        else:
-                            DecMatch = True
-                    else:
-                        DscDefaultValue = True
-                        DscMatch = True
-                        DecMatch = False
 
                 #
                 # Report PCD item according to their override relationship
                 #
                 if Pcd.DatumType == 'BOOLEAN':
@@ -1151,17 +1159,18 @@ class PcdReport(object):
                 elif InfDefaultValue and InfMatch:
                     self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')
                 elif BuildOptionMatch:
                     self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*B')
                 else:
-                    if DscDefaultValue and DscMatch:
+                    if PcdComponentValue:
+                        self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, PcdComponentValue, DecMatch, DecDefaultValue, '*M', module_guid)
+                    elif DscDefaultValue and DscMatch:
                         if (Pcd.TokenCName, Key, Field) in self.FdfPcdSet:
                             self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')
                         else:
                             self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')
-                    else:
-                        self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')
+
 
                 if ModulePcdSet is None:
                     if IsStructure:
                         continue
                     if not TypeName in ('PATCH', 'FLAG', 'FIXED'):
@@ -1263,11 +1272,11 @@ class PcdReport(object):
                     self.PrintStructureInfo(File, filedvalues)
         if DecMatch and IsStructure:
             for filedvalues in Pcd.DefaultValues.values():
                 self.PrintStructureInfo(File, filedvalues)
 
-    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, Flag = '  '):
+    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, Flag = '  ',module_guid=None):
         if not Pcd.SkuInfoList:
             Value = Pcd.DefaultValue
             IsByteArray, ArrayList = ByteArrayForamt(Value)
             if IsByteArray:
                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))
@@ -1286,18 +1295,24 @@ class PcdReport(object):
                 FiledOverrideFlag = False
                 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in GlobalData.gPcdSkuOverrides:
                     OverrideValues = GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]
                 else:
                     OverrideValues = Pcd.SkuOverrideValues
+                FieldOverrideValues = None
                 if OverrideValues:
                     for Data in OverrideValues.values():
                         Struct = list(Data.values())
                         if Struct:
-                            OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct[0])
-                            self.PrintStructureInfo(File, OverrideFieldStruct)
+                            FieldOverrideValues = Struct[0]
                             FiledOverrideFlag = True
                             break
+                if Pcd.PcdFiledValueFromDscComponent and module_guid and module_guid.replace("-","S") in Pcd.PcdFiledValueFromDscComponent:
+                    FieldOverrideValues = Pcd.PcdFiledValueFromDscComponent[module_guid.replace("-","S")]
+                if FieldOverrideValues:
+                    OverrideFieldStruct = self.OverrideFieldValue(Pcd, FieldOverrideValues)
+                    self.PrintStructureInfo(File, OverrideFieldStruct)
+
                 if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):
                     OverrideFieldStruct = self.OverrideFieldValue(Pcd, {})
                     self.PrintStructureInfo(File, OverrideFieldStruct)
             self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)
         else:
-- 
2.20.1.windows.1







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

* 回复: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd
  2020-10-26  3:59 ` [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd Bob Feng
@ 2020-10-27  6:19   ` gaoliming
  2020-10-28 15:07     ` Bob Feng
  0 siblings, 1 reply; 4+ messages in thread
From: gaoliming @ 2020-10-27  6:19 UTC (permalink / raw)
  To: 'Feng, Bob C', devel
  Cc: 'Chen, Christine', 'Kinney, Michael D'

Bob:
 I will review this change this week. Can you share your test case? I also
want to check the build output. 

Thanks
Liming
> -----邮件原件-----
> 发件人: Feng, Bob C <bob.c.feng@intel.com>
> 发送时间: 2020年10月26日 12:00
> 收件人: devel@edk2.groups.io; Feng, Bob C <bob.c.feng@intel.com>; Liming
> Gao <gaoliming@byosoft.com.cn>
> 抄送: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> 主题: RE: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> Pcd
> 
> Liming, would you review this patch?
> 
> Thanks,
> Bob
> 
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob Feng
> Sent: Thursday, October 15, 2020 6:59 PM
> To: devel@edk2.groups.io
> Cc: Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine
> <yuwei.chen@intel.com>
> Subject: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> Pcd
> 
> This patch is to enable the Module scoped Structure Pcd usage.
> User can set structure pcd field value in module scope. For example,
> under the [components] section of a dsc file, user can override some
> field value for a specific module.
> 
>   Package/Module.inf{
>       <PcdsFixedAtBuild>
>       gUefiTokenSpaceGuid.StructurePcdModule.FieldName | 5
>   }
> 
> Signed-off-by: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Yuwei Chen <yuwei.chen@intel.com>
> ---
> V2: Fixed the incorrect format in build report.
>  BaseTools/Source/Python/AutoGen/DataPipe.py   |   5 +-
>  .../Source/Python/AutoGen/ModuleAutoGen.py    |   4 +-
>  .../Python/AutoGen/ModuleAutoGenHelper.py     |  10 +-
>  .../Source/Python/AutoGen/PlatformAutoGen.py  |   8 +-
>  .../Python/Workspace/BuildClassObject.py      |  12 +
>  .../Source/Python/Workspace/DscBuildData.py   | 243
> ++++++++++++++++--
>  BaseTools/Source/Python/build/BuildReport.py  | 109 ++++----
>  7 files changed, 319 insertions(+), 72 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/AutoGen/DataPipe.py
> b/BaseTools/Source/Python/AutoGen/DataPipe.py
> index 50403fbfb5..86ac2b928d 100755
> --- a/BaseTools/Source/Python/AutoGen/DataPipe.py
> +++ b/BaseTools/Source/Python/AutoGen/DataPipe.py
> @@ -70,13 +70,14 @@ class MemoryDataPipe(DataPipe):
>              }
> 
>          #Platform Module Pcds
>          ModulePcds = {}
>          for m in PlatformInfo.Platform.Modules:
> -            m_pcds =  PlatformInfo.Platform.Modules[m].Pcds
> +            module = PlatformInfo.Platform.Modules[m]
> +            m_pcds =  module.Pcds
>              if m_pcds:
> -                ModulePcds[(m.File,m.Root,m.Arch)] = [PCD_DATA(
> +                ModulePcds[module.Guid] = [PCD_DATA(
>              pcd.TokenCName,pcd.TokenSpaceGuidCName,pcd.Type,
>              pcd.DatumType,pcd.SkuInfoList,pcd.DefaultValue,
> 
> pcd.MaxDatumSize,pcd.UserDefinedDefaultStoresFlag,pcd.validateranges,
> 
> pcd.validlists,pcd.expressions,pcd.CustomAttribute,pcd.TokenValue)
>              for pcd in PlatformInfo.Platform.Modules[m].Pcds.values()]
> diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> index eebf6e87f5..d70b0d7ae8 100755
> --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> @@ -1030,11 +1030,11 @@ class ModuleAutoGen(AutoGen):
>      #   @retval     list                    The list of PCD
>      #
>      @cached_property
>      def ModulePcdList(self):
>          # apply PCD settings from platform
> -        RetVal = self.PlatformInfo.ApplyPcdSetting(self.Module,
> self.Module.Pcds)
> +        RetVal = self.PlatformInfo.ApplyPcdSetting(self,
self.Module.Pcds)
> 
>          return RetVal
>      @cached_property
>      def _PcdComments(self):
>          ReVal = OrderedListDict()
> @@ -1061,11 +1061,11 @@ class ModuleAutoGen(AutoGen):
>                  # skip duplicated PCDs
>                  if Key in self.Module.Pcds or Key in Pcds:
>                      continue
>                  Pcds.add(Key)
>                  PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
> -            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self.Module,
> PcdsInLibrary, Library=Library))
> +            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self,
> PcdsInLibrary, Library=Library))
>          return RetVal
> 
>      ## Get the GUID value mapping
>      #
>      #   @retval     dict    The mapping between GUID cname and its
> value
> diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> index 9dd93b9beb..8e60643d1f 100644
> --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> @@ -477,12 +477,13 @@ class PlatformInfo(AutoGenInfo):
>                  SkuName = TAB_DEFAULT
>              ToPcd.SkuInfoList = {
>                  SkuName : SkuInfoClass(SkuName,
> self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
>              }
> 
> -    def ApplyPcdSetting(self, Module, Pcds, Library=""):
> +    def ApplyPcdSetting(self, Ma, Pcds, Library=""):
>          # for each PCD in module
> +        Module=Ma.Module
>          for Name, Guid in Pcds:
>              PcdInModule = Pcds[Name, Guid]
>              # find out the PCD setting in platform
>              if (Name, Guid) in self.Pcds:
>                  PcdInPlatform = self.Pcds[Name, Guid]
> @@ -505,13 +506,16 @@ class PlatformInfo(AutoGenInfo):
>                                                          %
> (Guid, Name, str(Module)),
>                                  File=self.MetaFile
>                                  )
> 
>          # override PCD settings with module specific setting
> +        ModuleScopePcds = self.DataPipe.Get("MOL_PCDS")
>          if Module in self.Platform.Modules:
>              PlatformModule = self.Platform.Modules[str(Module)]
> -            for Key  in PlatformModule.Pcds:
> +            PCD_DATA = ModuleScopePcds.get(Ma.Guid,{})
> +            mPcds = {(pcd.TokenCName,pcd.TokenSpaceGuidCName):
> pcd for pcd in PCD_DATA}
> +            for Key  in mPcds:
>                  if self.BuildOptionPcd:
>                      for pcd in self.BuildOptionPcd:
>                          (TokenSpaceGuidCName, TokenCName,
> FieldName, pcdvalue, _) = pcd
>                          if (TokenCName, TokenSpaceGuidCName) ==
> Key and FieldName =="":
>                              PlatformModule.Pcds[Key].DefaultValue
> = pcdvalue
> @@ -526,11 +530,11 @@ class PlatformInfo(AutoGenInfo):
>                          if PcdItem in Pcds:
>                              ToPcd = Pcds[PcdItem]
>                              Flag = True
>                              break
>                  if Flag:
> -                    self._OverridePcd(ToPcd, PlatformModule.Pcds[Key],
> Module, Msg="DSC Components Module scoped PCD section",
> Library=Library)
> +                    self._OverridePcd(ToPcd, mPcds[Key], Module,
> Msg="DSC Components Module scoped PCD section", Library=Library)
>          # use PCD value to calculate the MaxDatumSize when it is not
> specified
>          for Name, Guid in Pcds:
>              Pcd = Pcds[Name, Guid]
>              if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize:
>                  Pcd.MaxSizeUserSet = None
> diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> index 26ab8e7f36..c7a4cb9a08 100644
> --- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> +++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> @@ -1041,11 +1041,17 @@ class PlatformAutoGen(AutoGen):
>              TokenNumber += 1
>          return RetVal
> 
>      @cached_property
>      def _MbList(self):
> -        return [self.BuildDatabase[m, self.Arch, self.BuildTarget,
> self.ToolChain] for m in self.Platform.Modules]
> +        mlist = []
> +        for m in self.Platform.Modules:
> +            component = self.Platform.Modules[m]
> +            module = self.BuildDatabase[m, self.Arch, self.BuildTarget,
> self.ToolChain]
> +            module.Guid = component.Guid
> +            mlist.append(module)
> +        return mlist
> 
>      @cached_property
>      def _MaList(self):
>          for ModuleFile in self.Platform.Modules:
>              Ma = ModuleAutoGen(
> diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> index db40e3b10c..ebb65fc2fe 100644
> --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> @@ -68,10 +68,11 @@ class PcdClassObject(object):
>          self.DscRawValueInfo = {}
>          if IsDsc:
>              self.DscDefaultValue = Value
>          self.PcdValueFromComm = ""
>          self.PcdValueFromFdf = ""
> +        self.PcdValueFromComponents = {} #{ModuleGuid:value,
> file_path,lineNo}
>          self.CustomAttribute = {}
>          self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
>          self._Capacity = None
> 
>      @property
> @@ -296,10 +297,11 @@ class StructurePcd(PcdClassObject):
>          self.DefaultValueFromDecInfo = None
>          self.ValueChain = set()
>          self.PcdFieldValueFromComm = OrderedDict()
>          self.PcdFieldValueFromFdf = OrderedDict()
>          self.DefaultFromDSC=None
> +        self.PcdFiledValueFromDscComponent = OrderedDict()
>      def __repr__(self):
>          return self.TypeName
> 
>      def AddDefaultValue (self, FieldName, Value, FileName="",
> LineNo=0,DimensionAttr ="-1"):
>          if DimensionAttr not in self.DefaultValues:
> @@ -322,10 +324,16 @@ class StructurePcd(PcdClassObject):
>          if FieldName in
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
>              del
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame]
> 
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame] = [Value.strip(), FileName, LineNo]
>          return
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame]
> 
> +    def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid,
> FileName="", LineNo=0, DimensionAttr = '-1'):
> +        self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid,
> OrderedDict())
> +
> self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAtt
> r,OrderedDict())
> +
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> me] =  [Value.strip(), FileName, LineNo]
> +        return
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> me]
> +
>      def SetPcdMode (self, PcdMode):
>          self.PcdMode = PcdMode
> 
>      def copy(self, PcdObject):
>          self.TokenCName = PcdObject.TokenCName if
> PcdObject.TokenCName else self.TokenCName
> @@ -363,10 +371,11 @@ class StructurePcd(PcdClassObject):
>              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
> +            self.PcdFiledValueFromDscComponent =
> PcdObject.PcdFiledValueFromDscComponent if
> PcdObject.PcdFiledValueFromDscComponent else
> self.PcdFiledValueFromDscComponent
> 
>      def __deepcopy__(self,memo):
>          new_pcd = StructurePcd()
>          self.sharedcopy(new_pcd)
> 
> @@ -381,10 +390,11 @@ class StructurePcd(PcdClassObject):
>          new_pcd.DefaultValues = CopyDict(self.DefaultValues)
>          new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
>          new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
>          new_pcd.PcdFieldValueFromComm =
> CopyDict(self.PcdFieldValueFromComm)
>          new_pcd.PcdFieldValueFromFdf =
> CopyDict(self.PcdFieldValueFromFdf)
> +        new_pcd.PcdFiledValueFromDscComponent =
> CopyDict(self.PcdFiledValueFromDscComponent)
>          new_pcd.ValueChain = {item for item in self.ValueChain}
>          return new_pcd
> 
>  LibraryClassObject = namedtuple('LibraryClassObject',
> ['LibraryClass','SupModList'])
> 
> @@ -461,10 +471,12 @@ class ModuleBuildClassObject(object):
>          self.Includes                = []
>          self.Packages                = []
>          self.Pcds                    = {}
>          self.BuildOptions            = {}
>          self.Depex                   = {}
> +        self.StrPcdSet               = []
> +        self.StrPcdOverallValue      = {}
> 
>      ## Convert the class to a string
>      #
>      #  Convert member MetaFile of the class to a string
>      #
> diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
> b/BaseTools/Source/Python/Workspace/DscBuildData.py
> index 1ed3d9b909..1bb4fdc183 100644
> --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> @@ -753,13 +753,14 @@ class DscBuildData(PlatformBuildClassObject):
>              ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
>              if ErrorCode != 0:
>                  EdkLogger.error('build', ErrorCode, File=self.MetaFile,
> Line=LineNo,
>                                  ExtraData=ErrorInfo)
> 
> +            ModuleBuildData = self._Bdb[ModuleFile, self._Arch,
> self._Target, self._Toolchain]
>              Module = ModuleBuildClassObject()
>              Module.MetaFile = ModuleFile
> -
> +            Module.Guid = ModuleBuildData.Guid
>              # get module private library instance
>              RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS,
> self._Arch, None, ModuleId]
>              for Record in RecordList:
>                  LibraryClass = Record[0]
>                  LibraryPath = PathClass(NormPath(Record[1], Macros),
> GlobalData.gWorkspace, Arch=self._Arch)
> @@ -776,11 +777,11 @@ class DscBuildData(PlatformBuildClassObject):
>                      LibraryClass = 'NULL%d' % self._NullLibraryNumber
>                      EdkLogger.verbose("Found forced library
> for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
>                  Module.LibraryClasses[LibraryClass] = LibraryPath
>                  if LibraryPath not in self.LibraryInstances:
>                      self.LibraryInstances.append(LibraryPath)
> -
> +            S_PcdSet = []
>              # get module private PCD setting
>              for Type in [MODEL_PCD_FIXED_AT_BUILD,
> MODEL_PCD_PATCHABLE_IN_MODULE, \
>                           MODEL_PCD_FEATURE_FLAG,
> MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
>                  RecordList = self._RawData[Type, self._Arch, None,
> ModuleId]
>                  for TokenSpaceGuid, PcdCName, Setting, Dummy1,
> Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
> @@ -790,24 +791,35 @@ class DscBuildData(PlatformBuildClassObject):
>                      if len(TokenList) > 2:
>                          MaxDatumSize = TokenList[2]
>                      else:
>                          MaxDatumSize = ''
>                      TypeString = self._PCD_TYPE_STRING_[Type]
> -                    Pcd = PcdClassObject(
> -                            PcdCName,
> -                            TokenSpaceGuid,
> -                            TypeString,
> -                            '',
> -                            DefaultValue,
> -                            '',
> -                            MaxDatumSize,
> -                            {},
> -                            False,
> -                            None
> -                            )
> -                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
> 
> +                    TCName,PCName,DimensionAttr,Field =
> self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
> +
> +                    if ("." in TokenSpaceGuid or "[" in PcdCName):
> +
> S_PcdSet.append([ TCName,PCName,DimensionAttr,Field,
> ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
> +                        DefaultValue = ''
> +                    if ( PCName,TCName) not in Module.Pcds:
> +                        Pcd = PcdClassObject(
> +                                PCName,
> +                                TCName,
> +                                TypeString,
> +                                '',
> +                                DefaultValue,
> +                                '',
> +                                MaxDatumSize,
> +                                {},
> +                                False,
> +                                None,
> +                                IsDsc=True)
> +                        Module.Pcds[PCName, TCName] = Pcd
> +
> +            Module.StrPcdSet = S_PcdSet
> +            for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
> +                if (PCName,TCName) in Module.Pcds:
> +                    Module.StrPcdOverallValue[(PCName,TCName)] =
> Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
>              # get module private build options
>              RecordList =
> self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None,
> ModuleId]
>              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2,
> Dummy3, Dummy4, Dummy5 in RecordList:
>                  if (ToolChainFamily, ToolChain) not in
> Module.BuildOptions:
>                      Module.BuildOptions[ToolChainFamily, ToolChain] =
> Option
> @@ -820,11 +832,13 @@ class DscBuildData(PlatformBuildClassObject):
>                  if len(RecordList) != 1:
>                      EdkLogger.error('build', OPTION_UNKNOWN, 'Only
> FILE_GUID can be listed in <Defines> section.',
>                                      File=self.MetaFile,
> ExtraData=str(ModuleFile), Line=LineNo)
>                  ModuleFile = ProcessDuplicatedInf(ModuleFile,
> RecordList[0][2], GlobalData.gWorkspace)
>                  ModuleFile.Arch = self._Arch
> -
> +                Module.Guid = RecordList[0][2]
> +                for item in Module.StrPcdSet:
> +                    item[4] = RecordList[0][2]
>              self._Modules[ModuleFile] = Module
>          return self._Modules
> 
>      ## Retrieve all possible library instances used in this platform
>      @property
> @@ -1497,11 +1511,19 @@ class DscBuildData(PlatformBuildClassObject):
>                      EdkLogger.error('build', PARSER_ERROR,
>                                  "Pcd (%s.%s) is not declared as
> Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
>                                  File=self.MetaFile, Line = Dummy5)
> 
> 
> S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName,
> default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
> -
> +        ModuleScopeOverallValue = {}
> +        for m in self.Modules.values():
> +            mguid = m.Guid
> +            if m.StrPcdSet:
> +                S_PcdSet.extend(m.StrPcdSet)
> +                mguid = m.StrPcdSet[0][4]
> +            for (PCName,TCName) in m.StrPcdOverallValue:
> +                Value, dsc_file, lineNo =
> m.StrPcdOverallValue[(PCName,TCName)]
> +
> ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value,
> dsc_file, lineNo
>          # handle pcd value override
>          StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
>          S_pcd_set = OrderedDict()
>          for str_pcd in StrPcdSet:
>              str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
> @@ -1515,10 +1537,15 @@ class DscBuildData(PlatformBuildClassObject):
>                  else:
>                      str_pcd_obj_str.DefaultFromDSC =
> {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
>              for str_pcd_data in StrPcdSet[str_pcd]:
>                  if str_pcd_data[4] in SkuIds:
>                      str_pcd_obj_str.AddOverrideValue(str_pcd_data[3],
> str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else
> str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] ==
> TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir
> not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir)
if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> +                elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
> +
> str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3],
> str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File
if
> self.WorkspaceDir not in self.MetaFile.File else
> self.MetaFile.File[len(self.WorkspaceDir) if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> +                    PcdComponentValue =
> ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.
> TokenSpaceGuidCName))
> +                    for module_guid in PcdComponentValue:
> +
> str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] =
> PcdComponentValue[module_guid]
>              S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
> 
>          # Add the Structure PCD that only defined in DEC, don't have
> override in DSC file
>          for Pcd in self.DecPcds:
>              if isinstance(self._DecPcds[Pcd], StructurePcd):
> @@ -1573,11 +1600,14 @@ class DscBuildData(PlatformBuildClassObject):
>                          if defaultstoreid not in
> stru_pcd.SkuOverrideValues[skuid]:
> 
> stru_pcd.SkuOverrideValues[skuid][defaultstoreid] =
> CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
>                              stru_pcd.ValueChain.add((skuid,
> defaultstoreid))
>          S_pcd_set =
> DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
>          S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
> +
> +        # Create a tool to caculate structure pcd value
>          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:
>                      print(PcdName, PcdGuid)
> @@ -1591,10 +1621,18 @@ class DscBuildData(PlatformBuildClassObject):
> 
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdV
> alue})
>                  elif str_pcd_obj.Type in
> [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> 
> self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
>                      if skuname in (self.SkuIdMgr.SystemSkuId,
> TAB_DEFAULT, TAB_COMMON):
>                          str_pcd_obj.DefaultValue = PcdValue
> +                    else:
> +                        #Module Scope Structure Pcd
> +                        moduleguid = skuname.replace("S","-")
> +                        if
> GlobalData.gGuidPattern.match(moduleguid):
> +                            for component in self.Modules.values():
> +                                if component.Guid == moduleguid:
> +                                    component.Pcds[(PcdName,
> PcdGuid)].DefaultValue = PcdValue
> +
>                  else:
>                      if skuname not in str_pcd_obj.SkuInfoList:
>                          nextskuid =
> self.SkuIdMgr.GetNextSkuId(skuname)
>                          NoDefault = False
>                          while nextskuid not in str_pcd_obj.SkuInfoList:
> @@ -2339,10 +2377,79 @@ class DscBuildData(PlatformBuildClassObject):
>                      else:
>                          CApp = CApp + '  Pcd->%s = %d; // From %s
> Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>          CApp = CApp + "}\n"
>          return CApp
> 
> +    def GenerateModuleScopeValue(self, Pcd):
> +        CApp = "// Value in Dsc Module scope \n"
> +        for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
> +
> +            CApp = CApp + "void Assign_%s_%s_%s_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> ModuleGuid,Pcd.BaseDatumType)
> +            CApp = CApp + '  UINT32  FieldSize;\n'
> +            CApp = CApp + '  CHAR8   *Value;\n'
> +            pcddefaultvalue, file_path,lineNo =
> Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
> +
> +            if pcddefaultvalue:
> +                IsArray = _IsFieldValueAnArray(pcddefaultvalue)
> +                if IsArray:
> +                    try:
> +                        FieldList = ValueExpressionEx(pcddefaultvalue,
> TAB_VOID)(True)
> +                    except BadExpression:
> +                        EdkLogger.error("Build", FORMAT_INVALID,
> "Invalid value format for %s.%s, from %s Line %s: %s" %
> +
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
> +                Value, ValueSize = ParseFieldValue (FieldList)
> +
> +                if isinstance(Value, str):
> +                    CApp = CApp + '  Pcd = %s; // From %s Line %s \n' %
> (Value, file_path, lineNo)
> +                elif IsArray:
> +                #
> +                # Use memcpy() to copy value into field
> +                #
> +                    CApp = CApp + '  Value     = %s; // From %s
> Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path,
lineNo)
> +                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' %
> (ValueSize)
> +
> +
> +            PcdFiledValue =
> Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
> +            for index in PcdFiledValue:
> +                FieldList = PcdFiledValue[index]
> +                if not FieldList:
> +                    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.BaseDatumType, 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 + '
> __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) ==
> 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value
%s\n' %
> (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName,
> 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 '[' in FieldName and ']' in FieldName:
> +                            Index =
> int(FieldName.split('[')[1].split(']')[0])
> +                            CApp = CApp + '  __STATIC_ASSERT((%d
> < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index
> exceeds the array number"); // From %s Line %d Index of %s\n' % (Index,
> FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1],
> FieldList[FieldName][2], FieldName)
> +                        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 %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
> +            CApp = CApp + "}\n"
> +        return CApp
> +
>      @staticmethod
>      def GenerateCommandLineValueStatement(Pcd):
>          CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
>          return CApp
>      def GenerateFdfValue(self,Pcd):
> @@ -2412,10 +2519,88 @@ class DscBuildData(PlatformBuildClassObject):
>      @staticmethod
>      def GenerateFdfValueStatement(Pcd):
>          CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
>          return CApp
> 
> +    @staticmethod
> +    def GenerateModuleValueStatement(module_guid, Pcd):
> +        CApp = "  Assign_%s_%s_%s_Value(Pcd);\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
> +        return CApp
> +    def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd,
> InitByteValue, CApp):
> +        for module_guid in Pcd.PcdFiledValueFromDscComponent:
> +            CApp = CApp + 'void\n'
> +            CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (module_guid,
> TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> +            CApp = CApp + '  void\n'
> +            CApp = CApp + '  )\n'
> +            CApp = CApp + '{\n'
> +            CApp = CApp + '  UINT32  Size;\n'
> +            CApp = CApp + '  UINT32  FieldSize;\n'
> +            CApp = CApp + '  CHAR8   *Value;\n'
> +            CApp = CApp + '  UINT32  OriginalSize;\n'
> +            CApp = CApp + '  VOID    *OriginalPcd;\n'
> +
> +            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' %
> (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
> +
> +            CApp = CApp + '\n'
> +
> +            PcdDefaultValue =
> StringToArray(Pcd.DefaultValueFromDec.strip())
> +            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid,
> TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
> +            #
> +            # Get current PCD value and size
> +            #
> +            CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s,
> &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +
> +            #
> +            # Determine the size of the PCD.  For simple structures,
> sizeof(TYPE) provides
> +            # the correct value.  For structures with a flexible array
> member, the flexible
> +            # array member is detected, and the size is based on the
> highest index used with
> +            # the flexible array member.  The flexible array member
> must be the last field
> +            # in a structure.  The size formula for this case is:
> +            # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) *
> (HighestIndex + 1)
> +            #
> +            CApp = CApp +
> DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_D
> EFAULT)
> +            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +                CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s)
> * %d? OriginalSize:sizeof(%s) * %d; \n' %
> (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySiz
> e())
> +                CApp = CApp + '  Size = sizeof(%s) * %d; \n' %
> (Pcd.BaseDatumType,Pcd.PcdArraySize())
> +
> +            #
> +            # Allocate and zero buffer for the PCD
> +            # Must handle cases where current value is smaller, larger,
or
> same size
> +            # Always keep that larger one as the current size
> +            #
> +            CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize :
> Size);\n'
> +            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' %
> (Pcd.BaseDatumType,)
> +            CApp = CApp + '  memset (Pcd, 0, Size);\n'
> +
> +            #
> +            # Copy current PCD value into allocated buffer.
> +            #
> +            CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
> +
> +            #
> +            # Assign field values in PCD
> +            #
> +            CApp = CApp +
> DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
> +
> +            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)
> +            CApp = CApp +
> DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
> +            #
> +            # Set new PCD value and size
> +            #
> +            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void
> *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +
> +            #
> +            # Free PCD
> +            #
> +            CApp = CApp + '  free (Pcd);\n'
> +            CApp = CApp + '}\n'
> +            CApp = CApp + '\n'
> +        return InitByteValue,CApp
> +
>      def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd,
> InitByteValue, CApp):
>          OverrideValues = {DefaultStore:{}}
>          if Pcd.SkuOverrideValues:
>              OverrideValues = Pcd.SkuOverrideValues[SkuName]
>          if not OverrideValues:
> @@ -2584,26 +2769,42 @@ class DscBuildData(PlatformBuildClassObject):
>          CApp = CApp + '\n'
>          for Pcd in StructuredPcds.values():
>              CApp = CApp + self.GenerateArrayAssignment(Pcd)
>          for PcdName in sorted(StructuredPcds.keys()):
>              Pcd = StructuredPcds[PcdName]
> +
> +            #create void void Cal_tocken_cname_Size functions
>              CApp = CApp + self.GenerateSizeFunction(Pcd)
> +
> +            #create void Assign_ functions
> +
> +            # From DEC
>              CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
> +            # From Fdf
>              CApp = CApp + self.GenerateFdfValue(Pcd)
> +            # From CommandLine
>              CApp = CApp + self.GenerateCommandLineValue(Pcd)
> +
> +            # From Dsc Global setting
>              if self.SkuOverrideValuesEmpty(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:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in Pcd.SkuOverrideValues:
>                          continue
>                      for DefaultStoreName in
> Pcd.SkuOverrideValues[SkuName]:
>                          CApp = CApp +
> self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
> +
> +            # From Dsc module scope setting
> +            CApp = CApp + self.GenerateModuleScopeValue(Pcd)
> +
> +            #create Initialize_ functions
>              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or
> Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> 
> self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
>                  InitByteValue, CApp =
> self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId,
> TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
> +                InitByteValue, CApp =
>
self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitBy
> teValue,CApp)
>              else:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in Pcd.SkuOverrideValues:
>                          continue
>                      for DefaultStoreName in Pcd.DefaultStoreName:
> @@ -2616,10 +2817,12 @@ class DscBuildData(PlatformBuildClassObject):
>          CApp = CApp + '  )\n'
>          CApp = CApp + '{\n'
>          for Pcd in StructuredPcds.values():
>              if self.SkuOverrideValuesEmpty(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 + '  Initialize_%s_%s_%s_%s();\n' %
> (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +                for ModuleGuid in
> Pcd.PcdFiledValueFromDscComponent:
> +                    CApp += "  Initialize_%s_%s_%s_%s();\n" %
> (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
>              else:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
>                          continue
>                      for DefaultStoreName in
> Pcd.SkuOverrideValues[SkuName]:
> @@ -2631,10 +2834,11 @@ class DscBuildData(PlatformBuildClassObject):
>          if not os.path.exists(self.OutputPath):
>              os.makedirs(self.OutputPath)
>          CAppBaseFileName = os.path.join(self.OutputPath,
> PcdValueInitName)
>          SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
> 
> +        # start generating makefile
>          MakeApp = PcdMakefileHeader
>          if sys.platform == "win32":
>              MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' %
> (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' %
> (PcdValueInitName) + 'OBJECTS = %s\%s.obj %s.obj\n' % (self.OutputPath,
> PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) +
> 'INC = '
>          else:
>              MakeApp = MakeApp + PcdGccMakefile
> @@ -2753,19 +2957,22 @@ class DscBuildData(PlatformBuildClassObject):
>              MakeApp = MakeApp + '\tcp -f %s %s/PcdValueCommon.c\n' %
> (PcdValueCommonPath, self.OutputPath)
>          MakeFileName = os.path.join(self.OutputPath, 'Makefile')
>          MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
>          SaveFileOnChange(MakeFileName, MakeApp, False)
> 
> +        # start generating input file
>          InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
>          OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
>          SaveFileOnChange(InputValueFile, InitByteValue, False)
> 
>          Dest_PcdValueInitExe = PcdValueInitName
>          if not sys.platform == "win32":
>              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> PcdValueInitName)
>          else:
>              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> PcdValueInitName) +".exe"
> +
> +        #start building the structure pcd value tool
>          Messages = ''
>          if sys.platform == "win32":
>              MakeCommand = 'nmake -f %s' % (MakeFileName)
>              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand
> (MakeCommand)
>              Messages = StdOut
> @@ -2824,17 +3031,19 @@ class DscBuildData(PlatformBuildClassObject):
>              if MessageGroup:
>                  EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR,
> "\n".join(MessageGroup) )
>              else:
>                  EdkLogger.error('Build', COMMAND_FAILURE, 'Can not
> execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
> 
> +        #start executing the structure pcd value tool
>          if DscBuildData.NeedUpdateOutput(OutputValueFile,
> Dest_PcdValueInitExe, InputValueFile):
>              Command = Dest_PcdValueInitExe + ' -i %s -o %s' %
> (InputValueFile, OutputValueFile)
>              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand
> (Command)
>              EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut,
> StdErr))
>              if returncode != 0:
>                  EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not
> collect output from command: %s\n%s\n' % (Command, StdOut, StdErr))
> 
> +        #start update structure pcd final value
>          File = open (OutputValueFile, 'r')
>          FileBuffer = File.readlines()
>          File.close()
> 
>          StructurePcdSet = []
> diff --git a/BaseTools/Source/Python/build/BuildReport.py
> b/BaseTools/Source/Python/build/BuildReport.py
> index 8efa869162..d4de07cae2 100644
> --- a/BaseTools/Source/Python/build/BuildReport.py
> +++ b/BaseTools/Source/Python/build/BuildReport.py
> @@ -694,11 +694,11 @@ class ModuleReport(object):
>              FileWrite(File, "PCI Class Code:       %s" %
> self.PciClassCode)
> 
>          FileWrite(File, gSectionSep)
> 
>          if "PCD" in ReportType:
> -            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet)
> +            GlobalPcdReport.GenerateReport(File,
> self.ModulePcdSet,self.FileGuid)
> 
>          if "LIBRARY" in ReportType:
>              self.LibraryReport.GenerateReport(File)
> 
>          if "DEPEX" in ReportType:
> @@ -879,11 +879,11 @@ class PcdReport(object):
>              for (TokenCName, TokenSpaceGuidCName) in
> Pa.Platform.Pcds:
>                  DscDefaultValue = Pa.Platform.Pcds[(TokenCName,
> TokenSpaceGuidCName)].DscDefaultValue
>                  if DscDefaultValue:
>                      self.DscPcdDefault[(TokenCName,
> TokenSpaceGuidCName)] = DscDefaultValue
> 
> -    def GenerateReport(self, File, ModulePcdSet):
> +    def GenerateReport(self, File, ModulePcdSet,module_guid=None):
>          if not ModulePcdSet:
>              if self.ConditionalPcds:
>                  self.GenerateReportDetail(File, ModulePcdSet, 1)
>              if self.UnusedPcds:
>                  IsEmpty = True
> @@ -895,11 +895,11 @@ class PcdReport(object):
>                              break
>                      if not IsEmpty:
>                          break
>                  if not IsEmpty:
>                      self.GenerateReportDetail(File, ModulePcdSet, 2)
> -        self.GenerateReportDetail(File, ModulePcdSet)
> +        self.GenerateReportDetail(File, ModulePcdSet,module_guid =
> module_guid)
> 
>      ##
>      # Generate report for PCD information
>      #
>      # This function generates report for separate module expression
> @@ -911,11 +911,11 @@ class PcdReport(object):
>      #                        platform PCD report
>      # @param ReportySubType  0 means platform/module PCD report, 1
> means Conditional
>      #                        directives section report, 2 means
> Unused Pcds section report
>      # @param DscOverridePcds Module DSC override PCDs set
>      #
> -    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
0):
> +    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
> 0,module_guid=None):
>          PcdDict = self.AllPcds
>          if ReportSubType == 1:
>              PcdDict = self.ConditionalPcds
>          elif ReportSubType == 2:
>              PcdDict = self.UnusedPcds
> @@ -991,14 +991,16 @@ class PcdReport(object):
>                  if DscDefaultValue:
>                      PcdValue = DscDefaultValue
>                  #The DefaultValue of StructurePcd already be the latest,
> no need to update.
>                  if not self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                      Pcd.DefaultValue = PcdValue
> +                PcdComponentValue = None
>                  if ModulePcdSet is not None:
>                      if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName,
> Type) not in ModulePcdSet:
>                          continue
> -                    InfDefaultValue, PcdValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                    InfDefaultValue, PcdComponentValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                    PcdValue = PcdComponentValue
>                      #The DefaultValue of StructurePcd already be the
> latest, no need to update.
>                      if not self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                          Pcd.DefaultValue = PcdValue
>                      if InfDefaultValue:
>                          try:
> @@ -1079,62 +1081,68 @@ class PcdReport(object):
>                  if self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                      IsStructure = True
>                      if TypeName in ('DYNVPD', 'DEXVPD'):
>                          SkuInfoList = Pcd.SkuInfoList
>                      Pcd =
> GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName)]
> +                    if ModulePcdSet and
> ModulePcdSet.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type)):
> +                        InfDefaultValue, PcdComponentValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                        DscDefaultValBak = Pcd.DefaultValue
> +                        Pcd.DefaultValue = PcdComponentValue
> +
>                      Pcd.DatumType = Pcd.StructName
>                      if TypeName in ('DYNVPD', 'DEXVPD'):
>                          Pcd.SkuInfoList = SkuInfoList
>                      if Pcd.PcdValueFromComm or
> Pcd.PcdFieldValueFromComm:
>                          BuildOptionMatch = True
>                          DecMatch = False
>                      elif Pcd.PcdValueFromFdf or
> Pcd.PcdFieldValueFromFdf:
>                          DscDefaultValue = True
>                          DscMatch = True
>                          DecMatch = False
> -                    elif Pcd.SkuOverrideValues:
> -                        DscOverride = False
> -                        if Pcd.DefaultFromDSC:
> -                            DscOverride = True
> -                        else:
> -                            DictLen = 0
> -                            for item in Pcd.SkuOverrideValues:
> -                                DictLen +=
> len(Pcd.SkuOverrideValues[item])
> -                            if not DictLen:
> -                                DscOverride = False
> +                    else:
> +                        if Pcd.Type in PCD_DYNAMIC_TYPE_SET |
> PCD_DYNAMIC_EX_TYPE_SET:
> +                            DscOverride = False
> +                            if Pcd.DefaultFromDSC:
> +                                DscOverride = True
>                              else:
> -                                if not Pcd.SkuInfoList:
> -                                    OverrideValues =
> Pcd.SkuOverrideValues
> -                                    if OverrideValues:
> -                                        for Data in
> OverrideValues.values():
> -                                            Struct =
> list(Data.values())
> -                                            if Struct:
> -                                                DscOverride =
> self.ParseStruct(Struct[0])
> -                                                break
> +                                DictLen = 0
> +                                for item in Pcd.SkuOverrideValues:
> +                                    DictLen +=
> len(Pcd.SkuOverrideValues[item])
> +                                if not DictLen:
> +                                    DscOverride = False
>                                  else:
> -                                    SkuList =
> sorted(Pcd.SkuInfoList.keys())
> -                                    for Sku in SkuList:
> -                                        SkuInfo =
> Pcd.SkuInfoList[Sku]
> -                                        if
> SkuInfo.DefaultStoreDict:
> -                                            DefaultStoreList =
> sorted(SkuInfo.DefaultStoreDict.keys())
> -                                            for DefaultStore in
> DefaultStoreList:
> -                                                OverrideValues =
> Pcd.SkuOverrideValues[Sku]
> -                                                DscOverride =
> self.ParseStruct(OverrideValues[DefaultStore])
> -                                                if DscOverride:
> +                                    if not Pcd.SkuInfoList:
> +                                        OverrideValues =
> Pcd.SkuOverrideValues
> +                                        if OverrideValues:
> +                                            for Data in
> OverrideValues.values():
> +                                                Struct =
> list(Data.values())
> +                                                if Struct:
> +
> DscOverride = self.ParseStruct(Struct[0])
>                                                      break
> -                                        if DscOverride:
> -                                            break
> -                        if DscOverride:
> +                                    else:
> +                                        SkuList =
> sorted(Pcd.SkuInfoList.keys())
> +                                        for Sku in SkuList:
> +                                            SkuInfo =
> Pcd.SkuInfoList[Sku]
> +                                            if
> SkuInfo.DefaultStoreDict:
> +                                                DefaultStoreList
> = sorted(SkuInfo.DefaultStoreDict.keys())
> +                                                for DefaultStore
> in DefaultStoreList:
> +
> OverrideValues = Pcd.SkuOverrideValues[Sku]
> +
> DscOverride = self.ParseStruct(OverrideValues[DefaultStore])
> +                                                    if
> DscOverride:
> +                                                        break
> +                                            if DscOverride:
> +                                                break
> +                            if DscOverride:
> +                                DscDefaultValue = True
> +                                DscMatch = True
> +                                DecMatch = False
> +                            else:
> +                                DecMatch = True
> +                        else:
>                              DscDefaultValue = True
>                              DscMatch = True
>                              DecMatch = False
> -                        else:
> -                            DecMatch = True
> -                    else:
> -                        DscDefaultValue = True
> -                        DscMatch = True
> -                        DecMatch = False
> 
>                  #
>                  # Report PCD item according to their override
> relationship
>                  #
>                  if Pcd.DatumType == 'BOOLEAN':
> @@ -1151,17 +1159,18 @@ class PcdReport(object):
>                  elif InfDefaultValue and InfMatch:
>                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*M')
>                  elif BuildOptionMatch:
>                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*B')
>                  else:
> -                    if DscDefaultValue and DscMatch:
> +                    if PcdComponentValue:
> +                        self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> PcdComponentValue, DecMatch, DecDefaultValue, '*M', module_guid)
> +                    elif DscDefaultValue and DscMatch:
>                          if (Pcd.TokenCName, Key, Field) in
> self.FdfPcdSet:
>                              self.PrintPcdValue(File, Pcd,
> PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')
>                          else:
>                              self.PrintPcdValue(File, Pcd,
> PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')
> -                    else:
> -                        self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*M')
> +
> 
>                  if ModulePcdSet is None:
>                      if IsStructure:
>                          continue
>                      if not TypeName in ('PATCH', 'FLAG', 'FIXED'):
> @@ -1263,11 +1272,11 @@ class PcdReport(object):
>                      self.PrintStructureInfo(File, filedvalues)
>          if DecMatch and IsStructure:
>              for filedvalues in Pcd.DefaultValues.values():
>                  self.PrintStructureInfo(File, filedvalues)
> 
> -    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
DecMatch,
> DecDefaultValue, Flag = '  '):
> +    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
DecMatch,
> DecDefaultValue, Flag = '  ',module_guid=None):
>          if not Pcd.SkuInfoList:
>              Value = Pcd.DefaultValue
>              IsByteArray, ArrayList = ByteArrayForamt(Value)
>              if IsByteArray:
>                  FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen,
> Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))
> @@ -1286,18 +1295,24 @@ class PcdReport(object):
>                  FiledOverrideFlag = False
>                  if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in
> GlobalData.gPcdSkuOverrides:
>                      OverrideValues =
> GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)
> ]
>                  else:
>                      OverrideValues = Pcd.SkuOverrideValues
> +                FieldOverrideValues = None
>                  if OverrideValues:
>                      for Data in OverrideValues.values():
>                          Struct = list(Data.values())
>                          if Struct:
> -                            OverrideFieldStruct =
> self.OverrideFieldValue(Pcd, Struct[0])
> -                            self.PrintStructureInfo(File,
> OverrideFieldStruct)
> +                            FieldOverrideValues = Struct[0]
>                              FiledOverrideFlag = True
>                              break
> +                if Pcd.PcdFiledValueFromDscComponent and
> module_guid and module_guid.replace("-","S") in
> Pcd.PcdFiledValueFromDscComponent:
> +                    FieldOverrideValues =
> Pcd.PcdFiledValueFromDscComponent[module_guid.replace("-","S")]
> +                if FieldOverrideValues:
> +                    OverrideFieldStruct = self.OverrideFieldValue(Pcd,
> FieldOverrideValues)
> +                    self.PrintStructureInfo(File, OverrideFieldStruct)
> +
>                  if not FiledOverrideFlag and
> (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):
>                      OverrideFieldStruct = self.OverrideFieldValue(Pcd,
> {})
>                      self.PrintStructureInfo(File, OverrideFieldStruct)
>              self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch,
> DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)
>          else:
> --
> 2.20.1.windows.1
> 
> 
> 
> 
> 




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

* Re: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd
  2020-10-27  6:19   ` 回复: " gaoliming
@ 2020-10-28 15:07     ` Bob Feng
  2020-10-30  3:26       ` 回复: " gaoliming
  0 siblings, 1 reply; 4+ messages in thread
From: Bob Feng @ 2020-10-28 15:07 UTC (permalink / raw)
  To: devel@edk2.groups.io, gaoliming@byosoft.com.cn
  Cc: Chen, Christine, Kinney, Michael D

Liming,

You can verify this patch with Mike's case.

Clone Mike's edk2 repo, and checkout the branch Bug_xxx_CryptoPkg_UseModuleScopedPcds
https://github.com/mdkinney/edk2/tree/Bug_xxx_CryptoPkg_UseModuleScopedPcds

Then build the CryptoPkg.

build -p CryptoPkg\CryptoPkg.dsc -a IA32 -y report.txt

Thanks,
Bob

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of gaoliming
Sent: Tuesday, October 27, 2020 2:20 PM
To: Feng, Bob C <bob.c.feng@intel.com>; devel@edk2.groups.io
Cc: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: 回复: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd

Bob:
 I will review this change this week. Can you share your test case? I also
want to check the build output. 

Thanks
Liming
> -----邮件原件-----
> 发件人: Feng, Bob C <bob.c.feng@intel.com>
> 发送时间: 2020年10月26日 12:00
> 收件人: devel@edk2.groups.io; Feng, Bob C <bob.c.feng@intel.com>; Liming
> Gao <gaoliming@byosoft.com.cn>
> 抄送: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> 主题: RE: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> Pcd
> 
> Liming, would you review this patch?
> 
> Thanks,
> Bob
> 
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob Feng
> Sent: Thursday, October 15, 2020 6:59 PM
> To: devel@edk2.groups.io
> Cc: Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine
> <yuwei.chen@intel.com>
> Subject: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> Pcd
> 
> This patch is to enable the Module scoped Structure Pcd usage.
> User can set structure pcd field value in module scope. For example,
> under the [components] section of a dsc file, user can override some
> field value for a specific module.
> 
>   Package/Module.inf{
>       <PcdsFixedAtBuild>
>       gUefiTokenSpaceGuid.StructurePcdModule.FieldName | 5
>   }
> 
> Signed-off-by: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Yuwei Chen <yuwei.chen@intel.com>
> ---
> V2: Fixed the incorrect format in build report.
>  BaseTools/Source/Python/AutoGen/DataPipe.py   |   5 +-
>  .../Source/Python/AutoGen/ModuleAutoGen.py    |   4 +-
>  .../Python/AutoGen/ModuleAutoGenHelper.py     |  10 +-
>  .../Source/Python/AutoGen/PlatformAutoGen.py  |   8 +-
>  .../Python/Workspace/BuildClassObject.py      |  12 +
>  .../Source/Python/Workspace/DscBuildData.py   | 243
> ++++++++++++++++--
>  BaseTools/Source/Python/build/BuildReport.py  | 109 ++++----
>  7 files changed, 319 insertions(+), 72 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/AutoGen/DataPipe.py
> b/BaseTools/Source/Python/AutoGen/DataPipe.py
> index 50403fbfb5..86ac2b928d 100755
> --- a/BaseTools/Source/Python/AutoGen/DataPipe.py
> +++ b/BaseTools/Source/Python/AutoGen/DataPipe.py
> @@ -70,13 +70,14 @@ class MemoryDataPipe(DataPipe):
>              }
> 
>          #Platform Module Pcds
>          ModulePcds = {}
>          for m in PlatformInfo.Platform.Modules:
> -            m_pcds =  PlatformInfo.Platform.Modules[m].Pcds
> +            module = PlatformInfo.Platform.Modules[m]
> +            m_pcds =  module.Pcds
>              if m_pcds:
> -                ModulePcds[(m.File,m.Root,m.Arch)] = [PCD_DATA(
> +                ModulePcds[module.Guid] = [PCD_DATA(
>              pcd.TokenCName,pcd.TokenSpaceGuidCName,pcd.Type,
>              pcd.DatumType,pcd.SkuInfoList,pcd.DefaultValue,
> 
> pcd.MaxDatumSize,pcd.UserDefinedDefaultStoresFlag,pcd.validateranges,
> 
> pcd.validlists,pcd.expressions,pcd.CustomAttribute,pcd.TokenValue)
>              for pcd in PlatformInfo.Platform.Modules[m].Pcds.values()]
> diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> index eebf6e87f5..d70b0d7ae8 100755
> --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> @@ -1030,11 +1030,11 @@ class ModuleAutoGen(AutoGen):
>      #   @retval     list                    The list of PCD
>      #
>      @cached_property
>      def ModulePcdList(self):
>          # apply PCD settings from platform
> -        RetVal = self.PlatformInfo.ApplyPcdSetting(self.Module,
> self.Module.Pcds)
> +        RetVal = self.PlatformInfo.ApplyPcdSetting(self,
self.Module.Pcds)
> 
>          return RetVal
>      @cached_property
>      def _PcdComments(self):
>          ReVal = OrderedListDict()
> @@ -1061,11 +1061,11 @@ class ModuleAutoGen(AutoGen):
>                  # skip duplicated PCDs
>                  if Key in self.Module.Pcds or Key in Pcds:
>                      continue
>                  Pcds.add(Key)
>                  PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
> -            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self.Module,
> PcdsInLibrary, Library=Library))
> +            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self,
> PcdsInLibrary, Library=Library))
>          return RetVal
> 
>      ## Get the GUID value mapping
>      #
>      #   @retval     dict    The mapping between GUID cname and its
> value
> diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> index 9dd93b9beb..8e60643d1f 100644
> --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> @@ -477,12 +477,13 @@ class PlatformInfo(AutoGenInfo):
>                  SkuName = TAB_DEFAULT
>              ToPcd.SkuInfoList = {
>                  SkuName : SkuInfoClass(SkuName,
> self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
>              }
> 
> -    def ApplyPcdSetting(self, Module, Pcds, Library=""):
> +    def ApplyPcdSetting(self, Ma, Pcds, Library=""):
>          # for each PCD in module
> +        Module=Ma.Module
>          for Name, Guid in Pcds:
>              PcdInModule = Pcds[Name, Guid]
>              # find out the PCD setting in platform
>              if (Name, Guid) in self.Pcds:
>                  PcdInPlatform = self.Pcds[Name, Guid]
> @@ -505,13 +506,16 @@ class PlatformInfo(AutoGenInfo):
>                                                          %
> (Guid, Name, str(Module)),
>                                  File=self.MetaFile
>                                  )
> 
>          # override PCD settings with module specific setting
> +        ModuleScopePcds = self.DataPipe.Get("MOL_PCDS")
>          if Module in self.Platform.Modules:
>              PlatformModule = self.Platform.Modules[str(Module)]
> -            for Key  in PlatformModule.Pcds:
> +            PCD_DATA = ModuleScopePcds.get(Ma.Guid,{})
> +            mPcds = {(pcd.TokenCName,pcd.TokenSpaceGuidCName):
> pcd for pcd in PCD_DATA}
> +            for Key  in mPcds:
>                  if self.BuildOptionPcd:
>                      for pcd in self.BuildOptionPcd:
>                          (TokenSpaceGuidCName, TokenCName,
> FieldName, pcdvalue, _) = pcd
>                          if (TokenCName, TokenSpaceGuidCName) ==
> Key and FieldName =="":
>                              PlatformModule.Pcds[Key].DefaultValue
> = pcdvalue
> @@ -526,11 +530,11 @@ class PlatformInfo(AutoGenInfo):
>                          if PcdItem in Pcds:
>                              ToPcd = Pcds[PcdItem]
>                              Flag = True
>                              break
>                  if Flag:
> -                    self._OverridePcd(ToPcd, PlatformModule.Pcds[Key],
> Module, Msg="DSC Components Module scoped PCD section",
> Library=Library)
> +                    self._OverridePcd(ToPcd, mPcds[Key], Module,
> Msg="DSC Components Module scoped PCD section", Library=Library)
>          # use PCD value to calculate the MaxDatumSize when it is not
> specified
>          for Name, Guid in Pcds:
>              Pcd = Pcds[Name, Guid]
>              if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize:
>                  Pcd.MaxSizeUserSet = None
> diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> index 26ab8e7f36..c7a4cb9a08 100644
> --- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> +++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> @@ -1041,11 +1041,17 @@ class PlatformAutoGen(AutoGen):
>              TokenNumber += 1
>          return RetVal
> 
>      @cached_property
>      def _MbList(self):
> -        return [self.BuildDatabase[m, self.Arch, self.BuildTarget,
> self.ToolChain] for m in self.Platform.Modules]
> +        mlist = []
> +        for m in self.Platform.Modules:
> +            component = self.Platform.Modules[m]
> +            module = self.BuildDatabase[m, self.Arch, self.BuildTarget,
> self.ToolChain]
> +            module.Guid = component.Guid
> +            mlist.append(module)
> +        return mlist
> 
>      @cached_property
>      def _MaList(self):
>          for ModuleFile in self.Platform.Modules:
>              Ma = ModuleAutoGen(
> diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> index db40e3b10c..ebb65fc2fe 100644
> --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> @@ -68,10 +68,11 @@ class PcdClassObject(object):
>          self.DscRawValueInfo = {}
>          if IsDsc:
>              self.DscDefaultValue = Value
>          self.PcdValueFromComm = ""
>          self.PcdValueFromFdf = ""
> +        self.PcdValueFromComponents = {} #{ModuleGuid:value,
> file_path,lineNo}
>          self.CustomAttribute = {}
>          self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
>          self._Capacity = None
> 
>      @property
> @@ -296,10 +297,11 @@ class StructurePcd(PcdClassObject):
>          self.DefaultValueFromDecInfo = None
>          self.ValueChain = set()
>          self.PcdFieldValueFromComm = OrderedDict()
>          self.PcdFieldValueFromFdf = OrderedDict()
>          self.DefaultFromDSC=None
> +        self.PcdFiledValueFromDscComponent = OrderedDict()
>      def __repr__(self):
>          return self.TypeName
> 
>      def AddDefaultValue (self, FieldName, Value, FileName="",
> LineNo=0,DimensionAttr ="-1"):
>          if DimensionAttr not in self.DefaultValues:
> @@ -322,10 +324,16 @@ class StructurePcd(PcdClassObject):
>          if FieldName in
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
>              del
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame]
> 
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame] = [Value.strip(), FileName, LineNo]
>          return
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> ame]
> 
> +    def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid,
> FileName="", LineNo=0, DimensionAttr = '-1'):
> +        self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid,
> OrderedDict())
> +
> self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAtt
> r,OrderedDict())
> +
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> me] =  [Value.strip(), FileName, LineNo]
> +        return
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> me]
> +
>      def SetPcdMode (self, PcdMode):
>          self.PcdMode = PcdMode
> 
>      def copy(self, PcdObject):
>          self.TokenCName = PcdObject.TokenCName if
> PcdObject.TokenCName else self.TokenCName
> @@ -363,10 +371,11 @@ class StructurePcd(PcdClassObject):
>              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
> +            self.PcdFiledValueFromDscComponent =
> PcdObject.PcdFiledValueFromDscComponent if
> PcdObject.PcdFiledValueFromDscComponent else
> self.PcdFiledValueFromDscComponent
> 
>      def __deepcopy__(self,memo):
>          new_pcd = StructurePcd()
>          self.sharedcopy(new_pcd)
> 
> @@ -381,10 +390,11 @@ class StructurePcd(PcdClassObject):
>          new_pcd.DefaultValues = CopyDict(self.DefaultValues)
>          new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
>          new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
>          new_pcd.PcdFieldValueFromComm =
> CopyDict(self.PcdFieldValueFromComm)
>          new_pcd.PcdFieldValueFromFdf =
> CopyDict(self.PcdFieldValueFromFdf)
> +        new_pcd.PcdFiledValueFromDscComponent =
> CopyDict(self.PcdFiledValueFromDscComponent)
>          new_pcd.ValueChain = {item for item in self.ValueChain}
>          return new_pcd
> 
>  LibraryClassObject = namedtuple('LibraryClassObject',
> ['LibraryClass','SupModList'])
> 
> @@ -461,10 +471,12 @@ class ModuleBuildClassObject(object):
>          self.Includes                = []
>          self.Packages                = []
>          self.Pcds                    = {}
>          self.BuildOptions            = {}
>          self.Depex                   = {}
> +        self.StrPcdSet               = []
> +        self.StrPcdOverallValue      = {}
> 
>      ## Convert the class to a string
>      #
>      #  Convert member MetaFile of the class to a string
>      #
> diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
> b/BaseTools/Source/Python/Workspace/DscBuildData.py
> index 1ed3d9b909..1bb4fdc183 100644
> --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> @@ -753,13 +753,14 @@ class DscBuildData(PlatformBuildClassObject):
>              ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
>              if ErrorCode != 0:
>                  EdkLogger.error('build', ErrorCode, File=self.MetaFile,
> Line=LineNo,
>                                  ExtraData=ErrorInfo)
> 
> +            ModuleBuildData = self._Bdb[ModuleFile, self._Arch,
> self._Target, self._Toolchain]
>              Module = ModuleBuildClassObject()
>              Module.MetaFile = ModuleFile
> -
> +            Module.Guid = ModuleBuildData.Guid
>              # get module private library instance
>              RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS,
> self._Arch, None, ModuleId]
>              for Record in RecordList:
>                  LibraryClass = Record[0]
>                  LibraryPath = PathClass(NormPath(Record[1], Macros),
> GlobalData.gWorkspace, Arch=self._Arch)
> @@ -776,11 +777,11 @@ class DscBuildData(PlatformBuildClassObject):
>                      LibraryClass = 'NULL%d' % self._NullLibraryNumber
>                      EdkLogger.verbose("Found forced library
> for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
>                  Module.LibraryClasses[LibraryClass] = LibraryPath
>                  if LibraryPath not in self.LibraryInstances:
>                      self.LibraryInstances.append(LibraryPath)
> -
> +            S_PcdSet = []
>              # get module private PCD setting
>              for Type in [MODEL_PCD_FIXED_AT_BUILD,
> MODEL_PCD_PATCHABLE_IN_MODULE, \
>                           MODEL_PCD_FEATURE_FLAG,
> MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
>                  RecordList = self._RawData[Type, self._Arch, None,
> ModuleId]
>                  for TokenSpaceGuid, PcdCName, Setting, Dummy1,
> Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
> @@ -790,24 +791,35 @@ class DscBuildData(PlatformBuildClassObject):
>                      if len(TokenList) > 2:
>                          MaxDatumSize = TokenList[2]
>                      else:
>                          MaxDatumSize = ''
>                      TypeString = self._PCD_TYPE_STRING_[Type]
> -                    Pcd = PcdClassObject(
> -                            PcdCName,
> -                            TokenSpaceGuid,
> -                            TypeString,
> -                            '',
> -                            DefaultValue,
> -                            '',
> -                            MaxDatumSize,
> -                            {},
> -                            False,
> -                            None
> -                            )
> -                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
> 
> +                    TCName,PCName,DimensionAttr,Field =
> self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
> +
> +                    if ("." in TokenSpaceGuid or "[" in PcdCName):
> +
> S_PcdSet.append([ TCName,PCName,DimensionAttr,Field,
> ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
> +                        DefaultValue = ''
> +                    if ( PCName,TCName) not in Module.Pcds:
> +                        Pcd = PcdClassObject(
> +                                PCName,
> +                                TCName,
> +                                TypeString,
> +                                '',
> +                                DefaultValue,
> +                                '',
> +                                MaxDatumSize,
> +                                {},
> +                                False,
> +                                None,
> +                                IsDsc=True)
> +                        Module.Pcds[PCName, TCName] = Pcd
> +
> +            Module.StrPcdSet = S_PcdSet
> +            for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
> +                if (PCName,TCName) in Module.Pcds:
> +                    Module.StrPcdOverallValue[(PCName,TCName)] =
> Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
>              # get module private build options
>              RecordList =
> self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None,
> ModuleId]
>              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2,
> Dummy3, Dummy4, Dummy5 in RecordList:
>                  if (ToolChainFamily, ToolChain) not in
> Module.BuildOptions:
>                      Module.BuildOptions[ToolChainFamily, ToolChain] =
> Option
> @@ -820,11 +832,13 @@ class DscBuildData(PlatformBuildClassObject):
>                  if len(RecordList) != 1:
>                      EdkLogger.error('build', OPTION_UNKNOWN, 'Only
> FILE_GUID can be listed in <Defines> section.',
>                                      File=self.MetaFile,
> ExtraData=str(ModuleFile), Line=LineNo)
>                  ModuleFile = ProcessDuplicatedInf(ModuleFile,
> RecordList[0][2], GlobalData.gWorkspace)
>                  ModuleFile.Arch = self._Arch
> -
> +                Module.Guid = RecordList[0][2]
> +                for item in Module.StrPcdSet:
> +                    item[4] = RecordList[0][2]
>              self._Modules[ModuleFile] = Module
>          return self._Modules
> 
>      ## Retrieve all possible library instances used in this platform
>      @property
> @@ -1497,11 +1511,19 @@ class DscBuildData(PlatformBuildClassObject):
>                      EdkLogger.error('build', PARSER_ERROR,
>                                  "Pcd (%s.%s) is not declared as
> Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
>                                  File=self.MetaFile, Line = Dummy5)
> 
> 
> S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName,
> default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
> -
> +        ModuleScopeOverallValue = {}
> +        for m in self.Modules.values():
> +            mguid = m.Guid
> +            if m.StrPcdSet:
> +                S_PcdSet.extend(m.StrPcdSet)
> +                mguid = m.StrPcdSet[0][4]
> +            for (PCName,TCName) in m.StrPcdOverallValue:
> +                Value, dsc_file, lineNo =
> m.StrPcdOverallValue[(PCName,TCName)]
> +
> ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value,
> dsc_file, lineNo
>          # handle pcd value override
>          StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
>          S_pcd_set = OrderedDict()
>          for str_pcd in StrPcdSet:
>              str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
> @@ -1515,10 +1537,15 @@ class DscBuildData(PlatformBuildClassObject):
>                  else:
>                      str_pcd_obj_str.DefaultFromDSC =
> {skuname:{defaultstore:
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in
> DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
>              for str_pcd_data in StrPcdSet[str_pcd]:
>                  if str_pcd_data[4] in SkuIds:
>                      str_pcd_obj_str.AddOverrideValue(str_pcd_data[3],
> str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else
> str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] ==
> TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir
> not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir)
if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> +                elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
> +
> str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3],
> str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File
if
> self.WorkspaceDir not in self.MetaFile.File else
> self.MetaFile.File[len(self.WorkspaceDir) if
> self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> +                    PcdComponentValue =
> ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.
> TokenSpaceGuidCName))
> +                    for module_guid in PcdComponentValue:
> +
> str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] =
> PcdComponentValue[module_guid]
>              S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
> 
>          # Add the Structure PCD that only defined in DEC, don't have
> override in DSC file
>          for Pcd in self.DecPcds:
>              if isinstance(self._DecPcds[Pcd], StructurePcd):
> @@ -1573,11 +1600,14 @@ class DscBuildData(PlatformBuildClassObject):
>                          if defaultstoreid not in
> stru_pcd.SkuOverrideValues[skuid]:
> 
> stru_pcd.SkuOverrideValues[skuid][defaultstoreid] =
> CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
>                              stru_pcd.ValueChain.add((skuid,
> defaultstoreid))
>          S_pcd_set =
> DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
>          S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
> +
> +        # Create a tool to caculate structure pcd value
>          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:
>                      print(PcdName, PcdGuid)
> @@ -1591,10 +1621,18 @@ class DscBuildData(PlatformBuildClassObject):
> 
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdV
> alue})
>                  elif str_pcd_obj.Type in
> [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> 
> self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
>                      if skuname in (self.SkuIdMgr.SystemSkuId,
> TAB_DEFAULT, TAB_COMMON):
>                          str_pcd_obj.DefaultValue = PcdValue
> +                    else:
> +                        #Module Scope Structure Pcd
> +                        moduleguid = skuname.replace("S","-")
> +                        if
> GlobalData.gGuidPattern.match(moduleguid):
> +                            for component in self.Modules.values():
> +                                if component.Guid == moduleguid:
> +                                    component.Pcds[(PcdName,
> PcdGuid)].DefaultValue = PcdValue
> +
>                  else:
>                      if skuname not in str_pcd_obj.SkuInfoList:
>                          nextskuid =
> self.SkuIdMgr.GetNextSkuId(skuname)
>                          NoDefault = False
>                          while nextskuid not in str_pcd_obj.SkuInfoList:
> @@ -2339,10 +2377,79 @@ class DscBuildData(PlatformBuildClassObject):
>                      else:
>                          CApp = CApp + '  Pcd->%s = %d; // From %s
> Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
>          CApp = CApp + "}\n"
>          return CApp
> 
> +    def GenerateModuleScopeValue(self, Pcd):
> +        CApp = "// Value in Dsc Module scope \n"
> +        for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
> +
> +            CApp = CApp + "void Assign_%s_%s_%s_Value(%s *Pcd){\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> ModuleGuid,Pcd.BaseDatumType)
> +            CApp = CApp + '  UINT32  FieldSize;\n'
> +            CApp = CApp + '  CHAR8   *Value;\n'
> +            pcddefaultvalue, file_path,lineNo =
> Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
> +
> +            if pcddefaultvalue:
> +                IsArray = _IsFieldValueAnArray(pcddefaultvalue)
> +                if IsArray:
> +                    try:
> +                        FieldList = ValueExpressionEx(pcddefaultvalue,
> TAB_VOID)(True)
> +                    except BadExpression:
> +                        EdkLogger.error("Build", FORMAT_INVALID,
> "Invalid value format for %s.%s, from %s Line %s: %s" %
> +
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
> +                Value, ValueSize = ParseFieldValue (FieldList)
> +
> +                if isinstance(Value, str):
> +                    CApp = CApp + '  Pcd = %s; // From %s Line %s \n' %
> (Value, file_path, lineNo)
> +                elif IsArray:
> +                #
> +                # Use memcpy() to copy value into field
> +                #
> +                    CApp = CApp + '  Value     = %s; // From %s
> Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path,
lineNo)
> +                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' %
> (ValueSize)
> +
> +
> +            PcdFiledValue =
> Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
> +            for index in PcdFiledValue:
> +                FieldList = PcdFiledValue[index]
> +                if not FieldList:
> +                    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.BaseDatumType, 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 + '
> __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) ==
> 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value
%s\n' %
> (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName,
> 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 '[' in FieldName and ']' in FieldName:
> +                            Index =
> int(FieldName.split('[')[1].split(']')[0])
> +                            CApp = CApp + '  __STATIC_ASSERT((%d
> < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index
> exceeds the array number"); // From %s Line %d Index of %s\n' % (Index,
> FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1],
> FieldList[FieldName][2], FieldName)
> +                        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 %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> FieldList[FieldName][2], FieldList[FieldName][0])
> +            CApp = CApp + "}\n"
> +        return CApp
> +
>      @staticmethod
>      def GenerateCommandLineValueStatement(Pcd):
>          CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
>          return CApp
>      def GenerateFdfValue(self,Pcd):
> @@ -2412,10 +2519,88 @@ class DscBuildData(PlatformBuildClassObject):
>      @staticmethod
>      def GenerateFdfValueStatement(Pcd):
>          CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
>          return CApp
> 
> +    @staticmethod
> +    def GenerateModuleValueStatement(module_guid, Pcd):
> +        CApp = "  Assign_%s_%s_%s_Value(Pcd);\n" %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
> +        return CApp
> +    def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd,
> InitByteValue, CApp):
> +        for module_guid in Pcd.PcdFiledValueFromDscComponent:
> +            CApp = CApp + 'void\n'
> +            CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (module_guid,
> TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> +            CApp = CApp + '  void\n'
> +            CApp = CApp + '  )\n'
> +            CApp = CApp + '{\n'
> +            CApp = CApp + '  UINT32  Size;\n'
> +            CApp = CApp + '  UINT32  FieldSize;\n'
> +            CApp = CApp + '  CHAR8   *Value;\n'
> +            CApp = CApp + '  UINT32  OriginalSize;\n'
> +            CApp = CApp + '  VOID    *OriginalPcd;\n'
> +
> +            CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' %
> (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
> +
> +            CApp = CApp + '\n'
> +
> +            PcdDefaultValue =
> StringToArray(Pcd.DefaultValueFromDec.strip())
> +            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid,
> TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
> +            #
> +            # Get current PCD value and size
> +            #
> +            CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s,
> &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +
> +            #
> +            # Determine the size of the PCD.  For simple structures,
> sizeof(TYPE) provides
> +            # the correct value.  For structures with a flexible array
> member, the flexible
> +            # array member is detected, and the size is based on the
> highest index used with
> +            # the flexible array member.  The flexible array member
> must be the last field
> +            # in a structure.  The size formula for this case is:
> +            # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) *
> (HighestIndex + 1)
> +            #
> +            CApp = CApp +
> DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_D
> EFAULT)
> +            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +                CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s)
> * %d? OriginalSize:sizeof(%s) * %d; \n' %
> (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySiz
> e())
> +                CApp = CApp + '  Size = sizeof(%s) * %d; \n' %
> (Pcd.BaseDatumType,Pcd.PcdArraySize())
> +
> +            #
> +            # Allocate and zero buffer for the PCD
> +            # Must handle cases where current value is smaller, larger,
or
> same size
> +            # Always keep that larger one as the current size
> +            #
> +            CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize :
> Size);\n'
> +            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' %
> (Pcd.BaseDatumType,)
> +            CApp = CApp + '  memset (Pcd, 0, Size);\n'
> +
> +            #
> +            # Copy current PCD value into allocated buffer.
> +            #
> +            CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
> +
> +            #
> +            # Assign field values in PCD
> +            #
> +            CApp = CApp +
> DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
> +
> +            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)
> +            CApp = CApp +
> DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
> +            #
> +            # Set new PCD value and size
> +            #
> +            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void
> *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +
> +            #
> +            # Free PCD
> +            #
> +            CApp = CApp + '  free (Pcd);\n'
> +            CApp = CApp + '}\n'
> +            CApp = CApp + '\n'
> +        return InitByteValue,CApp
> +
>      def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd,
> InitByteValue, CApp):
>          OverrideValues = {DefaultStore:{}}
>          if Pcd.SkuOverrideValues:
>              OverrideValues = Pcd.SkuOverrideValues[SkuName]
>          if not OverrideValues:
> @@ -2584,26 +2769,42 @@ class DscBuildData(PlatformBuildClassObject):
>          CApp = CApp + '\n'
>          for Pcd in StructuredPcds.values():
>              CApp = CApp + self.GenerateArrayAssignment(Pcd)
>          for PcdName in sorted(StructuredPcds.keys()):
>              Pcd = StructuredPcds[PcdName]
> +
> +            #create void void Cal_tocken_cname_Size functions
>              CApp = CApp + self.GenerateSizeFunction(Pcd)
> +
> +            #create void Assign_ functions
> +
> +            # From DEC
>              CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
> +            # From Fdf
>              CApp = CApp + self.GenerateFdfValue(Pcd)
> +            # From CommandLine
>              CApp = CApp + self.GenerateCommandLineValue(Pcd)
> +
> +            # From Dsc Global setting
>              if self.SkuOverrideValuesEmpty(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:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in Pcd.SkuOverrideValues:
>                          continue
>                      for DefaultStoreName in
> Pcd.SkuOverrideValues[SkuName]:
>                          CApp = CApp +
> self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
> +
> +            # From Dsc module scope setting
> +            CApp = CApp + self.GenerateModuleScopeValue(Pcd)
> +
> +            #create Initialize_ functions
>              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or
> Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> 
> self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
>                  InitByteValue, CApp =
> self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId,
> TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
> +                InitByteValue, CApp =
>
self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitBy
> teValue,CApp)
>              else:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in Pcd.SkuOverrideValues:
>                          continue
>                      for DefaultStoreName in Pcd.DefaultStoreName:
> @@ -2616,10 +2817,12 @@ class DscBuildData(PlatformBuildClassObject):
>          CApp = CApp + '  )\n'
>          CApp = CApp + '{\n'
>          for Pcd in StructuredPcds.values():
>              if self.SkuOverrideValuesEmpty(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 + '  Initialize_%s_%s_%s_%s();\n' %
> (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT,
> Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +                for ModuleGuid in
> Pcd.PcdFiledValueFromDscComponent:
> +                    CApp += "  Initialize_%s_%s_%s_%s();\n" %
> (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
>              else:
>                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
>                      if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
>                          continue
>                      for DefaultStoreName in
> Pcd.SkuOverrideValues[SkuName]:
> @@ -2631,10 +2834,11 @@ class DscBuildData(PlatformBuildClassObject):
>          if not os.path.exists(self.OutputPath):
>              os.makedirs(self.OutputPath)
>          CAppBaseFileName = os.path.join(self.OutputPath,
> PcdValueInitName)
>          SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
> 
> +        # start generating makefile
>          MakeApp = PcdMakefileHeader
>          if sys.platform == "win32":
>              MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' %
> (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' %
> (PcdValueInitName) + 'OBJECTS = %s\%s.obj %s.obj\n' % (self.OutputPath,
> PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) +
> 'INC = '
>          else:
>              MakeApp = MakeApp + PcdGccMakefile
> @@ -2753,19 +2957,22 @@ class DscBuildData(PlatformBuildClassObject):
>              MakeApp = MakeApp + '\tcp -f %s %s/PcdValueCommon.c\n' %
> (PcdValueCommonPath, self.OutputPath)
>          MakeFileName = os.path.join(self.OutputPath, 'Makefile')
>          MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
>          SaveFileOnChange(MakeFileName, MakeApp, False)
> 
> +        # start generating input file
>          InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
>          OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
>          SaveFileOnChange(InputValueFile, InitByteValue, False)
> 
>          Dest_PcdValueInitExe = PcdValueInitName
>          if not sys.platform == "win32":
>              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> PcdValueInitName)
>          else:
>              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> PcdValueInitName) +".exe"
> +
> +        #start building the structure pcd value tool
>          Messages = ''
>          if sys.platform == "win32":
>              MakeCommand = 'nmake -f %s' % (MakeFileName)
>              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand
> (MakeCommand)
>              Messages = StdOut
> @@ -2824,17 +3031,19 @@ class DscBuildData(PlatformBuildClassObject):
>              if MessageGroup:
>                  EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR,
> "\n".join(MessageGroup) )
>              else:
>                  EdkLogger.error('Build', COMMAND_FAILURE, 'Can not
> execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
> 
> +        #start executing the structure pcd value tool
>          if DscBuildData.NeedUpdateOutput(OutputValueFile,
> Dest_PcdValueInitExe, InputValueFile):
>              Command = Dest_PcdValueInitExe + ' -i %s -o %s' %
> (InputValueFile, OutputValueFile)
>              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand
> (Command)
>              EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut,
> StdErr))
>              if returncode != 0:
>                  EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not
> collect output from command: %s\n%s\n' % (Command, StdOut, StdErr))
> 
> +        #start update structure pcd final value
>          File = open (OutputValueFile, 'r')
>          FileBuffer = File.readlines()
>          File.close()
> 
>          StructurePcdSet = []
> diff --git a/BaseTools/Source/Python/build/BuildReport.py
> b/BaseTools/Source/Python/build/BuildReport.py
> index 8efa869162..d4de07cae2 100644
> --- a/BaseTools/Source/Python/build/BuildReport.py
> +++ b/BaseTools/Source/Python/build/BuildReport.py
> @@ -694,11 +694,11 @@ class ModuleReport(object):
>              FileWrite(File, "PCI Class Code:       %s" %
> self.PciClassCode)
> 
>          FileWrite(File, gSectionSep)
> 
>          if "PCD" in ReportType:
> -            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet)
> +            GlobalPcdReport.GenerateReport(File,
> self.ModulePcdSet,self.FileGuid)
> 
>          if "LIBRARY" in ReportType:
>              self.LibraryReport.GenerateReport(File)
> 
>          if "DEPEX" in ReportType:
> @@ -879,11 +879,11 @@ class PcdReport(object):
>              for (TokenCName, TokenSpaceGuidCName) in
> Pa.Platform.Pcds:
>                  DscDefaultValue = Pa.Platform.Pcds[(TokenCName,
> TokenSpaceGuidCName)].DscDefaultValue
>                  if DscDefaultValue:
>                      self.DscPcdDefault[(TokenCName,
> TokenSpaceGuidCName)] = DscDefaultValue
> 
> -    def GenerateReport(self, File, ModulePcdSet):
> +    def GenerateReport(self, File, ModulePcdSet,module_guid=None):
>          if not ModulePcdSet:
>              if self.ConditionalPcds:
>                  self.GenerateReportDetail(File, ModulePcdSet, 1)
>              if self.UnusedPcds:
>                  IsEmpty = True
> @@ -895,11 +895,11 @@ class PcdReport(object):
>                              break
>                      if not IsEmpty:
>                          break
>                  if not IsEmpty:
>                      self.GenerateReportDetail(File, ModulePcdSet, 2)
> -        self.GenerateReportDetail(File, ModulePcdSet)
> +        self.GenerateReportDetail(File, ModulePcdSet,module_guid =
> module_guid)
> 
>      ##
>      # Generate report for PCD information
>      #
>      # This function generates report for separate module expression
> @@ -911,11 +911,11 @@ class PcdReport(object):
>      #                        platform PCD report
>      # @param ReportySubType  0 means platform/module PCD report, 1
> means Conditional
>      #                        directives section report, 2 means
> Unused Pcds section report
>      # @param DscOverridePcds Module DSC override PCDs set
>      #
> -    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
0):
> +    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
> 0,module_guid=None):
>          PcdDict = self.AllPcds
>          if ReportSubType == 1:
>              PcdDict = self.ConditionalPcds
>          elif ReportSubType == 2:
>              PcdDict = self.UnusedPcds
> @@ -991,14 +991,16 @@ class PcdReport(object):
>                  if DscDefaultValue:
>                      PcdValue = DscDefaultValue
>                  #The DefaultValue of StructurePcd already be the latest,
> no need to update.
>                  if not self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                      Pcd.DefaultValue = PcdValue
> +                PcdComponentValue = None
>                  if ModulePcdSet is not None:
>                      if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName,
> Type) not in ModulePcdSet:
>                          continue
> -                    InfDefaultValue, PcdValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                    InfDefaultValue, PcdComponentValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                    PcdValue = PcdComponentValue
>                      #The DefaultValue of StructurePcd already be the
> latest, no need to update.
>                      if not self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                          Pcd.DefaultValue = PcdValue
>                      if InfDefaultValue:
>                          try:
> @@ -1079,62 +1081,68 @@ class PcdReport(object):
>                  if self.IsStructurePcd(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName):
>                      IsStructure = True
>                      if TypeName in ('DYNVPD', 'DEXVPD'):
>                          SkuInfoList = Pcd.SkuInfoList
>                      Pcd =
> GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName)]
> +                    if ModulePcdSet and
> ModulePcdSet.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type)):
> +                        InfDefaultValue, PcdComponentValue =
> ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> +                        DscDefaultValBak = Pcd.DefaultValue
> +                        Pcd.DefaultValue = PcdComponentValue
> +
>                      Pcd.DatumType = Pcd.StructName
>                      if TypeName in ('DYNVPD', 'DEXVPD'):
>                          Pcd.SkuInfoList = SkuInfoList
>                      if Pcd.PcdValueFromComm or
> Pcd.PcdFieldValueFromComm:
>                          BuildOptionMatch = True
>                          DecMatch = False
>                      elif Pcd.PcdValueFromFdf or
> Pcd.PcdFieldValueFromFdf:
>                          DscDefaultValue = True
>                          DscMatch = True
>                          DecMatch = False
> -                    elif Pcd.SkuOverrideValues:
> -                        DscOverride = False
> -                        if Pcd.DefaultFromDSC:
> -                            DscOverride = True
> -                        else:
> -                            DictLen = 0
> -                            for item in Pcd.SkuOverrideValues:
> -                                DictLen +=
> len(Pcd.SkuOverrideValues[item])
> -                            if not DictLen:
> -                                DscOverride = False
> +                    else:
> +                        if Pcd.Type in PCD_DYNAMIC_TYPE_SET |
> PCD_DYNAMIC_EX_TYPE_SET:
> +                            DscOverride = False
> +                            if Pcd.DefaultFromDSC:
> +                                DscOverride = True
>                              else:
> -                                if not Pcd.SkuInfoList:
> -                                    OverrideValues =
> Pcd.SkuOverrideValues
> -                                    if OverrideValues:
> -                                        for Data in
> OverrideValues.values():
> -                                            Struct =
> list(Data.values())
> -                                            if Struct:
> -                                                DscOverride =
> self.ParseStruct(Struct[0])
> -                                                break
> +                                DictLen = 0
> +                                for item in Pcd.SkuOverrideValues:
> +                                    DictLen +=
> len(Pcd.SkuOverrideValues[item])
> +                                if not DictLen:
> +                                    DscOverride = False
>                                  else:
> -                                    SkuList =
> sorted(Pcd.SkuInfoList.keys())
> -                                    for Sku in SkuList:
> -                                        SkuInfo =
> Pcd.SkuInfoList[Sku]
> -                                        if
> SkuInfo.DefaultStoreDict:
> -                                            DefaultStoreList =
> sorted(SkuInfo.DefaultStoreDict.keys())
> -                                            for DefaultStore in
> DefaultStoreList:
> -                                                OverrideValues =
> Pcd.SkuOverrideValues[Sku]
> -                                                DscOverride =
> self.ParseStruct(OverrideValues[DefaultStore])
> -                                                if DscOverride:
> +                                    if not Pcd.SkuInfoList:
> +                                        OverrideValues =
> Pcd.SkuOverrideValues
> +                                        if OverrideValues:
> +                                            for Data in
> OverrideValues.values():
> +                                                Struct =
> list(Data.values())
> +                                                if Struct:
> +
> DscOverride = self.ParseStruct(Struct[0])
>                                                      break
> -                                        if DscOverride:
> -                                            break
> -                        if DscOverride:
> +                                    else:
> +                                        SkuList =
> sorted(Pcd.SkuInfoList.keys())
> +                                        for Sku in SkuList:
> +                                            SkuInfo =
> Pcd.SkuInfoList[Sku]
> +                                            if
> SkuInfo.DefaultStoreDict:
> +                                                DefaultStoreList
> = sorted(SkuInfo.DefaultStoreDict.keys())
> +                                                for DefaultStore
> in DefaultStoreList:
> +
> OverrideValues = Pcd.SkuOverrideValues[Sku]
> +
> DscOverride = self.ParseStruct(OverrideValues[DefaultStore])
> +                                                    if
> DscOverride:
> +                                                        break
> +                                            if DscOverride:
> +                                                break
> +                            if DscOverride:
> +                                DscDefaultValue = True
> +                                DscMatch = True
> +                                DecMatch = False
> +                            else:
> +                                DecMatch = True
> +                        else:
>                              DscDefaultValue = True
>                              DscMatch = True
>                              DecMatch = False
> -                        else:
> -                            DecMatch = True
> -                    else:
> -                        DscDefaultValue = True
> -                        DscMatch = True
> -                        DecMatch = False
> 
>                  #
>                  # Report PCD item according to their override
> relationship
>                  #
>                  if Pcd.DatumType == 'BOOLEAN':
> @@ -1151,17 +1159,18 @@ class PcdReport(object):
>                  elif InfDefaultValue and InfMatch:
>                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*M')
>                  elif BuildOptionMatch:
>                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*B')
>                  else:
> -                    if DscDefaultValue and DscMatch:
> +                    if PcdComponentValue:
> +                        self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> PcdComponentValue, DecMatch, DecDefaultValue, '*M', module_guid)
> +                    elif DscDefaultValue and DscMatch:
>                          if (Pcd.TokenCName, Key, Field) in
> self.FdfPcdSet:
>                              self.PrintPcdValue(File, Pcd,
> PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')
>                          else:
>                              self.PrintPcdValue(File, Pcd,
> PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')
> -                    else:
> -                        self.PrintPcdValue(File, Pcd, PcdTokenCName,
> TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> InfDefaultValue, DecMatch, DecDefaultValue, '*M')
> +
> 
>                  if ModulePcdSet is None:
>                      if IsStructure:
>                          continue
>                      if not TypeName in ('PATCH', 'FLAG', 'FIXED'):
> @@ -1263,11 +1272,11 @@ class PcdReport(object):
>                      self.PrintStructureInfo(File, filedvalues)
>          if DecMatch and IsStructure:
>              for filedvalues in Pcd.DefaultValues.values():
>                  self.PrintStructureInfo(File, filedvalues)
> 
> -    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
DecMatch,
> DecDefaultValue, Flag = '  '):
> +    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
DecMatch,
> DecDefaultValue, Flag = '  ',module_guid=None):
>          if not Pcd.SkuInfoList:
>              Value = Pcd.DefaultValue
>              IsByteArray, ArrayList = ByteArrayForamt(Value)
>              if IsByteArray:
>                  FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen,
> Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))
> @@ -1286,18 +1295,24 @@ class PcdReport(object):
>                  FiledOverrideFlag = False
>                  if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in
> GlobalData.gPcdSkuOverrides:
>                      OverrideValues =
> GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)
> ]
>                  else:
>                      OverrideValues = Pcd.SkuOverrideValues
> +                FieldOverrideValues = None
>                  if OverrideValues:
>                      for Data in OverrideValues.values():
>                          Struct = list(Data.values())
>                          if Struct:
> -                            OverrideFieldStruct =
> self.OverrideFieldValue(Pcd, Struct[0])
> -                            self.PrintStructureInfo(File,
> OverrideFieldStruct)
> +                            FieldOverrideValues = Struct[0]
>                              FiledOverrideFlag = True
>                              break
> +                if Pcd.PcdFiledValueFromDscComponent and
> module_guid and module_guid.replace("-","S") in
> Pcd.PcdFiledValueFromDscComponent:
> +                    FieldOverrideValues =
> Pcd.PcdFiledValueFromDscComponent[module_guid.replace("-","S")]
> +                if FieldOverrideValues:
> +                    OverrideFieldStruct = self.OverrideFieldValue(Pcd,
> FieldOverrideValues)
> +                    self.PrintStructureInfo(File, OverrideFieldStruct)
> +
>                  if not FiledOverrideFlag and
> (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):
>                      OverrideFieldStruct = self.OverrideFieldValue(Pcd,
> {})
>                      self.PrintStructureInfo(File, OverrideFieldStruct)
>              self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch,
> DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)
>          else:
> --
> 2.20.1.windows.1
> 
> 
> 
> 
> 









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

* 回复: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd
  2020-10-28 15:07     ` Bob Feng
@ 2020-10-30  3:26       ` gaoliming
  0 siblings, 0 replies; 4+ messages in thread
From: gaoliming @ 2020-10-30  3:26 UTC (permalink / raw)
  To: devel, bob.c.feng; +Cc: 'Chen, Christine', 'Kinney, Michael D'

Bob:
  I review the generated PcdValueInit.c file and Report.txt. I find two issues. 

PcdValueInit.c:
  Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_Default_Value(Pcd);
// SkuName: DEFAULT,  DefaultStoreName: STANDARD 
  Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_DEFAULT_STANDARD_Value(Pcd);
  Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_Fdf_Value(Pcd);
  Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_CommandLine_Value(Pcd);
  Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_A3542CE8S77F7S49DCSA834S45D37D2EC1FA_Value(Pcd);

  Module level PCD values will have higher priority than the global level PCD setting. 
  But, FDF and Command Line level PCD have higher priority than module level PCD. 
  So, the module level PCD value assignment should be before Assign_gEfiCryptoPkgTokenSpaceGuid_PcdCryptoServiceFamilyEnable_Fdf_Value(Pcd);

Report.txt:
  Pcd value in Module section is always zero. It doesn't match its real value. And, module level PCD setting should be displayed in report. 

gEfiCryptoPkgTokenSpaceGuid
    PcdCryptoServiceFamilyEnable         :  FIXED (PCD_CRYPTO_SERVICE_FAMILY_ENABLE) = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}

Thanks
Liming
> -----邮件原件-----
> 发件人: bounce+27952+66694+4905953+8761045@groups.io
> <bounce+27952+66694+4905953+8761045@groups.io> 代表 Bob Feng
> 发送时间: 2020年10月28日 23:08
> 收件人: devel@edk2.groups.io; gaoliming@byosoft.com.cn
> 抄送: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> 主题: Re: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> Pcd
> 
> Liming,
> 
> You can verify this patch with Mike's case.
> 
> Clone Mike's edk2 repo, and checkout the branch
> Bug_xxx_CryptoPkg_UseModuleScopedPcds
> https://github.com/mdkinney/edk2/tree/Bug_xxx_CryptoPkg_UseModuleSco
> pedPcds
> 
> Then build the CryptoPkg.
> 
> build -p CryptoPkg\CryptoPkg.dsc -a IA32 -y report.txt
> 
> Thanks,
> Bob
> 
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of gaoliming
> Sent: Tuesday, October 27, 2020 2:20 PM
> To: Feng, Bob C <bob.c.feng@intel.com>; devel@edk2.groups.io
> Cc: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: 回复: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope
> Structure Pcd
> 
> Bob:
>  I will review this change this week. Can you share your test case? I also
> want to check the build output.
> 
> Thanks
> Liming
> > -----邮件原件-----
> > 发件人: Feng, Bob C <bob.c.feng@intel.com>
> > 发送时间: 2020年10月26日 12:00
> > 收件人: devel@edk2.groups.io; Feng, Bob C <bob.c.feng@intel.com>;
> Liming
> > Gao <gaoliming@byosoft.com.cn>
> > 抄送: Chen, Christine <yuwei.chen@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>
> > 主题: RE: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope
> Structure
> > Pcd
> >
> > Liming, would you review this patch?
> >
> > Thanks,
> > Bob
> >
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob
> Feng
> > Sent: Thursday, October 15, 2020 6:59 PM
> > To: devel@edk2.groups.io
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>; Chen, Christine
> > <yuwei.chen@intel.com>
> > Subject: [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure
> > Pcd
> >
> > This patch is to enable the Module scoped Structure Pcd usage.
> > User can set structure pcd field value in module scope. For example,
> > under the [components] section of a dsc file, user can override some
> > field value for a specific module.
> >
> >   Package/Module.inf{
> >       <PcdsFixedAtBuild>
> >       gUefiTokenSpaceGuid.StructurePcdModule.FieldName | 5
> >   }
> >
> > Signed-off-by: Bob Feng <bob.c.feng@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Yuwei Chen <yuwei.chen@intel.com>
> > ---
> > V2: Fixed the incorrect format in build report.
> >  BaseTools/Source/Python/AutoGen/DataPipe.py   |   5 +-
> >  .../Source/Python/AutoGen/ModuleAutoGen.py    |   4 +-
> >  .../Python/AutoGen/ModuleAutoGenHelper.py     |  10 +-
> >  .../Source/Python/AutoGen/PlatformAutoGen.py  |   8 +-
> >  .../Python/Workspace/BuildClassObject.py      |  12 +
> >  .../Source/Python/Workspace/DscBuildData.py   | 243
> > ++++++++++++++++--
> >  BaseTools/Source/Python/build/BuildReport.py  | 109 ++++----
> >  7 files changed, 319 insertions(+), 72 deletions(-)
> >
> > diff --git a/BaseTools/Source/Python/AutoGen/DataPipe.py
> > b/BaseTools/Source/Python/AutoGen/DataPipe.py
> > index 50403fbfb5..86ac2b928d 100755
> > --- a/BaseTools/Source/Python/AutoGen/DataPipe.py
> > +++ b/BaseTools/Source/Python/AutoGen/DataPipe.py
> > @@ -70,13 +70,14 @@ class MemoryDataPipe(DataPipe):
> >              }
> >
> >          #Platform Module Pcds
> >          ModulePcds = {}
> >          for m in PlatformInfo.Platform.Modules:
> > -            m_pcds =  PlatformInfo.Platform.Modules[m].Pcds
> > +            module = PlatformInfo.Platform.Modules[m]
> > +            m_pcds =  module.Pcds
> >              if m_pcds:
> > -                ModulePcds[(m.File,m.Root,m.Arch)] = [PCD_DATA(
> > +                ModulePcds[module.Guid] = [PCD_DATA(
> >              pcd.TokenCName,pcd.TokenSpaceGuidCName,pcd.Type,
> >              pcd.DatumType,pcd.SkuInfoList,pcd.DefaultValue,
> >
> > pcd.MaxDatumSize,pcd.UserDefinedDefaultStoresFlag,pcd.validateranges,
> >
> > pcd.validlists,pcd.expressions,pcd.CustomAttribute,pcd.TokenValue)
> >              for pcd in PlatformInfo.Platform.Modules[m].Pcds.values()]
> > diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> > b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> > index eebf6e87f5..d70b0d7ae8 100755
> > --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> > +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGen.py
> > @@ -1030,11 +1030,11 @@ class ModuleAutoGen(AutoGen):
> >      #   @retval     list                    The list of PCD
> >      #
> >      @cached_property
> >      def ModulePcdList(self):
> >          # apply PCD settings from platform
> > -        RetVal = self.PlatformInfo.ApplyPcdSetting(self.Module,
> > self.Module.Pcds)
> > +        RetVal = self.PlatformInfo.ApplyPcdSetting(self,
> self.Module.Pcds)
> >
> >          return RetVal
> >      @cached_property
> >      def _PcdComments(self):
> >          ReVal = OrderedListDict()
> > @@ -1061,11 +1061,11 @@ class ModuleAutoGen(AutoGen):
> >                  # skip duplicated PCDs
> >                  if Key in self.Module.Pcds or Key in Pcds:
> >                      continue
> >                  Pcds.add(Key)
> >                  PcdsInLibrary[Key] = copy.copy(Library.Pcds[Key])
> > -
> RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self.Module,
> > PcdsInLibrary, Library=Library))
> > +            RetVal.extend(self.PlatformInfo.ApplyPcdSetting(self,
> > PcdsInLibrary, Library=Library))
> >          return RetVal
> >
> >      ## Get the GUID value mapping
> >      #
> >      #   @retval     dict    The mapping between GUID cname and
> its
> > value
> > diff --git a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> > b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> > index 9dd93b9beb..8e60643d1f 100644
> > --- a/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> > +++ b/BaseTools/Source/Python/AutoGen/ModuleAutoGenHelper.py
> > @@ -477,12 +477,13 @@ class PlatformInfo(AutoGenInfo):
> >                  SkuName = TAB_DEFAULT
> >              ToPcd.SkuInfoList = {
> >                  SkuName : SkuInfoClass(SkuName,
> > self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue)
> >              }
> >
> > -    def ApplyPcdSetting(self, Module, Pcds, Library=""):
> > +    def ApplyPcdSetting(self, Ma, Pcds, Library=""):
> >          # for each PCD in module
> > +        Module=Ma.Module
> >          for Name, Guid in Pcds:
> >              PcdInModule = Pcds[Name, Guid]
> >              # find out the PCD setting in platform
> >              if (Name, Guid) in self.Pcds:
> >                  PcdInPlatform = self.Pcds[Name, Guid]
> > @@ -505,13 +506,16 @@ class PlatformInfo(AutoGenInfo):
> >                                                          %
> > (Guid, Name, str(Module)),
> >                                  File=self.MetaFile
> >                                  )
> >
> >          # override PCD settings with module specific setting
> > +        ModuleScopePcds = self.DataPipe.Get("MOL_PCDS")
> >          if Module in self.Platform.Modules:
> >              PlatformModule = self.Platform.Modules[str(Module)]
> > -            for Key  in PlatformModule.Pcds:
> > +            PCD_DATA = ModuleScopePcds.get(Ma.Guid,{})
> > +            mPcds = {(pcd.TokenCName,pcd.TokenSpaceGuidCName):
> > pcd for pcd in PCD_DATA}
> > +            for Key  in mPcds:
> >                  if self.BuildOptionPcd:
> >                      for pcd in self.BuildOptionPcd:
> >                          (TokenSpaceGuidCName, TokenCName,
> > FieldName, pcdvalue, _) = pcd
> >                          if (TokenCName, TokenSpaceGuidCName)
> ==
> > Key and FieldName =="":
> >
> PlatformModule.Pcds[Key].DefaultValue
> > = pcdvalue
> > @@ -526,11 +530,11 @@ class PlatformInfo(AutoGenInfo):
> >                          if PcdItem in Pcds:
> >                              ToPcd = Pcds[PcdItem]
> >                              Flag = True
> >                              break
> >                  if Flag:
> > -                    self._OverridePcd(ToPcd,
> PlatformModule.Pcds[Key],
> > Module, Msg="DSC Components Module scoped PCD section",
> > Library=Library)
> > +                    self._OverridePcd(ToPcd, mPcds[Key], Module,
> > Msg="DSC Components Module scoped PCD section", Library=Library)
> >          # use PCD value to calculate the MaxDatumSize when it is not
> > specified
> >          for Name, Guid in Pcds:
> >              Pcd = Pcds[Name, Guid]
> >              if Pcd.DatumType == TAB_VOID and not
> Pcd.MaxDatumSize:
> >                  Pcd.MaxSizeUserSet = None
> > diff --git a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> > b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> > index 26ab8e7f36..c7a4cb9a08 100644
> > --- a/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> > +++ b/BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
> > @@ -1041,11 +1041,17 @@ class PlatformAutoGen(AutoGen):
> >              TokenNumber += 1
> >          return RetVal
> >
> >      @cached_property
> >      def _MbList(self):
> > -        return [self.BuildDatabase[m, self.Arch, self.BuildTarget,
> > self.ToolChain] for m in self.Platform.Modules]
> > +        mlist = []
> > +        for m in self.Platform.Modules:
> > +            component = self.Platform.Modules[m]
> > +            module = self.BuildDatabase[m, self.Arch, self.BuildTarget,
> > self.ToolChain]
> > +            module.Guid = component.Guid
> > +            mlist.append(module)
> > +        return mlist
> >
> >      @cached_property
> >      def _MaList(self):
> >          for ModuleFile in self.Platform.Modules:
> >              Ma = ModuleAutoGen(
> > diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> > b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> > index db40e3b10c..ebb65fc2fe 100644
> > --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> > +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> > @@ -68,10 +68,11 @@ class PcdClassObject(object):
> >          self.DscRawValueInfo = {}
> >          if IsDsc:
> >              self.DscDefaultValue = Value
> >          self.PcdValueFromComm = ""
> >          self.PcdValueFromFdf = ""
> > +        self.PcdValueFromComponents = {} #{ModuleGuid:value,
> > file_path,lineNo}
> >          self.CustomAttribute = {}
> >          self.UserDefinedDefaultStoresFlag =
> UserDefinedDefaultStoresFlag
> >          self._Capacity = None
> >
> >      @property
> > @@ -296,10 +297,11 @@ class StructurePcd(PcdClassObject):
> >          self.DefaultValueFromDecInfo = None
> >          self.ValueChain = set()
> >          self.PcdFieldValueFromComm = OrderedDict()
> >          self.PcdFieldValueFromFdf = OrderedDict()
> >          self.DefaultFromDSC=None
> > +        self.PcdFiledValueFromDscComponent = OrderedDict()
> >      def __repr__(self):
> >          return self.TypeName
> >
> >      def AddDefaultValue (self, FieldName, Value, FileName="",
> > LineNo=0,DimensionAttr ="-1"):
> >          if DimensionAttr not in self.DefaultValues:
> > @@ -322,10 +324,16 @@ class StructurePcd(PcdClassObject):
> >          if FieldName in
> > self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr]:
> >              del
> >
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> > ame]
> >
> >
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> > ame] = [Value.strip(), FileName, LineNo]
> >          return
> >
> self.SkuOverrideValues[SkuName][DefaultStoreName][DimensionAttr][FieldN
> > ame]
> >
> > +    def AddComponentOverrideValue(self,FieldName, Value, ModuleGuid,
> > FileName="", LineNo=0, DimensionAttr = '-1'):
> > +        self.PcdFiledValueFromDscComponent.setdefault(ModuleGuid,
> > OrderedDict())
> > +
> >
> self.PcdFiledValueFromDscComponent[ModuleGuid].setdefault(DimensionAtt
> > r,OrderedDict())
> > +
> >
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> > me] =  [Value.strip(), FileName, LineNo]
> > +        return
> >
> self.PcdFiledValueFromDscComponent[ModuleGuid][DimensionAttr][FieldNa
> > me]
> > +
> >      def SetPcdMode (self, PcdMode):
> >          self.PcdMode = PcdMode
> >
> >      def copy(self, PcdObject):
> >          self.TokenCName = PcdObject.TokenCName if
> > PcdObject.TokenCName else self.TokenCName
> > @@ -363,10 +371,11 @@ class StructurePcd(PcdClassObject):
> >              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
> > +            self.PcdFiledValueFromDscComponent =
> > PcdObject.PcdFiledValueFromDscComponent if
> > PcdObject.PcdFiledValueFromDscComponent else
> > self.PcdFiledValueFromDscComponent
> >
> >      def __deepcopy__(self,memo):
> >          new_pcd = StructurePcd()
> >          self.sharedcopy(new_pcd)
> >
> > @@ -381,10 +390,11 @@ class StructurePcd(PcdClassObject):
> >          new_pcd.DefaultValues = CopyDict(self.DefaultValues)
> >          new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
> >          new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
> >          new_pcd.PcdFieldValueFromComm =
> > CopyDict(self.PcdFieldValueFromComm)
> >          new_pcd.PcdFieldValueFromFdf =
> > CopyDict(self.PcdFieldValueFromFdf)
> > +        new_pcd.PcdFiledValueFromDscComponent =
> > CopyDict(self.PcdFiledValueFromDscComponent)
> >          new_pcd.ValueChain = {item for item in self.ValueChain}
> >          return new_pcd
> >
> >  LibraryClassObject = namedtuple('LibraryClassObject',
> > ['LibraryClass','SupModList'])
> >
> > @@ -461,10 +471,12 @@ class ModuleBuildClassObject(object):
> >          self.Includes                = []
> >          self.Packages                = []
> >          self.Pcds                    = {}
> >          self.BuildOptions            = {}
> >          self.Depex                   = {}
> > +        self.StrPcdSet               = []
> > +        self.StrPcdOverallValue      = {}
> >
> >      ## Convert the class to a string
> >      #
> >      #  Convert member MetaFile of the class to a string
> >      #
> > diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
> > b/BaseTools/Source/Python/Workspace/DscBuildData.py
> > index 1ed3d9b909..1bb4fdc183 100644
> > --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> > +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> > @@ -753,13 +753,14 @@ class DscBuildData(PlatformBuildClassObject):
> >              ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
> >              if ErrorCode != 0:
> >                  EdkLogger.error('build', ErrorCode, File=self.MetaFile,
> > Line=LineNo,
> >                                  ExtraData=ErrorInfo)
> >
> > +            ModuleBuildData = self._Bdb[ModuleFile, self._Arch,
> > self._Target, self._Toolchain]
> >              Module = ModuleBuildClassObject()
> >              Module.MetaFile = ModuleFile
> > -
> > +            Module.Guid = ModuleBuildData.Guid
> >              # get module private library instance
> >              RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS,
> > self._Arch, None, ModuleId]
> >              for Record in RecordList:
> >                  LibraryClass = Record[0]
> >                  LibraryPath = PathClass(NormPath(Record[1],
> Macros),
> > GlobalData.gWorkspace, Arch=self._Arch)
> > @@ -776,11 +777,11 @@ class DscBuildData(PlatformBuildClassObject):
> >                      LibraryClass = 'NULL%d' %
> self._NullLibraryNumber
> >                      EdkLogger.verbose("Found forced library
> > for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
> >                  Module.LibraryClasses[LibraryClass] = LibraryPath
> >                  if LibraryPath not in self.LibraryInstances:
> >                      self.LibraryInstances.append(LibraryPath)
> > -
> > +            S_PcdSet = []
> >              # get module private PCD setting
> >              for Type in [MODEL_PCD_FIXED_AT_BUILD,
> > MODEL_PCD_PATCHABLE_IN_MODULE, \
> >                           MODEL_PCD_FEATURE_FLAG,
> > MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
> >                  RecordList = self._RawData[Type, self._Arch, None,
> > ModuleId]
> >                  for TokenSpaceGuid, PcdCName, Setting, Dummy1,
> > Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
> > @@ -790,24 +791,35 @@ class DscBuildData(PlatformBuildClassObject):
> >                      if len(TokenList) > 2:
> >                          MaxDatumSize = TokenList[2]
> >                      else:
> >                          MaxDatumSize = ''
> >                      TypeString = self._PCD_TYPE_STRING_[Type]
> > -                    Pcd = PcdClassObject(
> > -                            PcdCName,
> > -                            TokenSpaceGuid,
> > -                            TypeString,
> > -                            '',
> > -                            DefaultValue,
> > -                            '',
> > -                            MaxDatumSize,
> > -                            {},
> > -                            False,
> > -                            None
> > -                            )
> > -                    Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
> >
> > +                    TCName,PCName,DimensionAttr,Field =
> > self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
> > +
> > +                    if ("." in TokenSpaceGuid or "[" in PcdCName):
> > +
> > S_PcdSet.append([ TCName,PCName,DimensionAttr,Field,
> > ModuleBuildData.Guid, "", Dummy5, AnalyzePcdExpression(Setting)[0]])
> > +                        DefaultValue = ''
> > +                    if ( PCName,TCName) not in Module.Pcds:
> > +                        Pcd = PcdClassObject(
> > +                                PCName,
> > +                                TCName,
> > +                                TypeString,
> > +                                '',
> > +                                DefaultValue,
> > +                                '',
> > +                                MaxDatumSize,
> > +                                {},
> > +                                False,
> > +                                None,
> > +                                IsDsc=True)
> > +                        Module.Pcds[PCName, TCName] = Pcd
> > +
> > +            Module.StrPcdSet = S_PcdSet
> > +            for TCName,PCName, _,_,_,_,_,_ in S_PcdSet:
> > +                if (PCName,TCName) in Module.Pcds:
> > +                    Module.StrPcdOverallValue[(PCName,TCName)]
> =
> > Module.Pcds[(PCName,TCName)].DefaultValue, self.MetaFile,Dummy5
> >              # get module private build options
> >              RecordList =
> > self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None,
> > ModuleId]
> >              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2,
> > Dummy3, Dummy4, Dummy5 in RecordList:
> >                  if (ToolChainFamily, ToolChain) not in
> > Module.BuildOptions:
> >                      Module.BuildOptions[ToolChainFamily, ToolChain]
> =
> > Option
> > @@ -820,11 +832,13 @@ class DscBuildData(PlatformBuildClassObject):
> >                  if len(RecordList) != 1:
> >                      EdkLogger.error('build', OPTION_UNKNOWN,
> 'Only
> > FILE_GUID can be listed in <Defines> section.',
> >                                      File=self.MetaFile,
> > ExtraData=str(ModuleFile), Line=LineNo)
> >                  ModuleFile = ProcessDuplicatedInf(ModuleFile,
> > RecordList[0][2], GlobalData.gWorkspace)
> >                  ModuleFile.Arch = self._Arch
> > -
> > +                Module.Guid = RecordList[0][2]
> > +                for item in Module.StrPcdSet:
> > +                    item[4] = RecordList[0][2]
> >              self._Modules[ModuleFile] = Module
> >          return self._Modules
> >
> >      ## Retrieve all possible library instances used in this platform
> >      @property
> > @@ -1497,11 +1511,19 @@ class DscBuildData(PlatformBuildClassObject):
> >                      EdkLogger.error('build', PARSER_ERROR,
> >                                  "Pcd (%s.%s) is not declared as
> > Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
> >                                  File=self.MetaFile, Line =
> Dummy5)
> >
> >
> > S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName,
> > default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
> > -
> > +        ModuleScopeOverallValue = {}
> > +        for m in self.Modules.values():
> > +            mguid = m.Guid
> > +            if m.StrPcdSet:
> > +                S_PcdSet.extend(m.StrPcdSet)
> > +                mguid = m.StrPcdSet[0][4]
> > +            for (PCName,TCName) in m.StrPcdOverallValue:
> > +                Value, dsc_file, lineNo =
> > m.StrPcdOverallValue[(PCName,TCName)]
> > +
> > ModuleScopeOverallValue.setdefault((PCName,TCName),{})[mguid] = Value,
> > dsc_file, lineNo
> >          # handle pcd value override
> >          StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
> >          S_pcd_set = OrderedDict()
> >          for str_pcd in StrPcdSet:
> >              str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
> > @@ -1515,10 +1537,15 @@ class DscBuildData(PlatformBuildClassObject):
> >                  else:
> >                      str_pcd_obj_str.DefaultFromDSC =
> > {skuname:{defaultstore:
> > str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore,
> > str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in
> > DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
> >              for str_pcd_data in StrPcdSet[str_pcd]:
> >                  if str_pcd_data[4] in SkuIds:
> >
> str_pcd_obj_str.AddOverrideValue(str_pcd_data[3],
> > str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON
> else
> > str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] ==
> > TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir
> > not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir)
> if
> > self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> > LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> > +                elif GlobalData.gGuidPattern.match(str_pcd_data[4]):
> > +
> > str_pcd_obj_str.AddComponentOverrideValue(str_pcd_data[3],
> > str(str_pcd_data[7]), str_pcd_data[4].replace("-","S"), self.MetaFile.File
> if
> > self.WorkspaceDir not in self.MetaFile.File else
> > self.MetaFile.File[len(self.WorkspaceDir) if
> > self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],
> > LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
> > +                    PcdComponentValue =
> >
> ModuleScopeOverallValue.get((str_pcd_obj_str.TokenCName,str_pcd_obj_str.
> > TokenSpaceGuidCName))
> > +                    for module_guid in PcdComponentValue:
> > +
> > str_pcd_obj_str.PcdValueFromComponents[module_guid.replace("-","S")] =
> > PcdComponentValue[module_guid]
> >              S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
> >
> >          # Add the Structure PCD that only defined in DEC, don't have
> > override in DSC file
> >          for Pcd in self.DecPcds:
> >              if isinstance(self._DecPcds[Pcd], StructurePcd):
> > @@ -1573,11 +1600,14 @@ class DscBuildData(PlatformBuildClassObject):
> >                          if defaultstoreid not in
> > stru_pcd.SkuOverrideValues[skuid]:
> >
> > stru_pcd.SkuOverrideValues[skuid][defaultstoreid] =
> > CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
> >                              stru_pcd.ValueChain.add((skuid,
> > defaultstoreid))
> >          S_pcd_set =
> > DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
> >          S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
> > +
> > +        # Create a tool to caculate structure pcd value
> >          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:
> >                      print(PcdName, PcdGuid)
> > @@ -1591,10 +1621,18 @@ class DscBuildData(PlatformBuildClassObject):
> >
> >
> str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdV
> > alue})
> >                  elif str_pcd_obj.Type in
> > [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> >
> > self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
> >                      if skuname in (self.SkuIdMgr.SystemSkuId,
> > TAB_DEFAULT, TAB_COMMON):
> >                          str_pcd_obj.DefaultValue = PcdValue
> > +                    else:
> > +                        #Module Scope Structure Pcd
> > +                        moduleguid = skuname.replace("S","-")
> > +                        if
> > GlobalData.gGuidPattern.match(moduleguid):
> > +                            for component in self.Modules.values():
> > +                                if component.Guid == moduleguid:
> > +                                    component.Pcds[(PcdName,
> > PcdGuid)].DefaultValue = PcdValue
> > +
> >                  else:
> >                      if skuname not in str_pcd_obj.SkuInfoList:
> >                          nextskuid =
> > self.SkuIdMgr.GetNextSkuId(skuname)
> >                          NoDefault = False
> >                          while nextskuid not in
> str_pcd_obj.SkuInfoList:
> > @@ -2339,10 +2377,79 @@ class DscBuildData(PlatformBuildClassObject):
> >                      else:
> >                          CApp = CApp + '  Pcd->%s = %d; //
> From %s
> > Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> > FieldList[FieldName][2], FieldList[FieldName][0])
> >          CApp = CApp + "}\n"
> >          return CApp
> >
> > +    def GenerateModuleScopeValue(self, Pcd):
> > +        CApp = "// Value in Dsc Module scope \n"
> > +        for ModuleGuid in Pcd.PcdFiledValueFromDscComponent:
> > +
> > +            CApp = CApp + "void Assign_%s_%s_%s_Value(%s
> *Pcd){\n" %
> > (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> > ModuleGuid,Pcd.BaseDatumType)
> > +            CApp = CApp + '  UINT32  FieldSize;\n'
> > +            CApp = CApp + '  CHAR8   *Value;\n'
> > +            pcddefaultvalue, file_path,lineNo =
> > Pcd.PcdValueFromComponents.get(ModuleGuid,(None,None,None))
> > +
> > +            if pcddefaultvalue:
> > +                IsArray = _IsFieldValueAnArray(pcddefaultvalue)
> > +                if IsArray:
> > +                    try:
> > +                        FieldList =
> ValueExpressionEx(pcddefaultvalue,
> > TAB_VOID)(True)
> > +                    except BadExpression:
> > +                        EdkLogger.error("Build", FORMAT_INVALID,
> > "Invalid value format for %s.%s, from %s Line %s: %s" %
> > +
> > (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, file_path, lineNo, FieldList))
> > +                Value, ValueSize = ParseFieldValue (FieldList)
> > +
> > +                if isinstance(Value, str):
> > +                    CApp = CApp + '  Pcd = %s; // From %s Line %s
> \n' %
> > (Value, file_path, lineNo)
> > +                elif IsArray:
> > +                #
> > +                # Use memcpy() to copy value into field
> > +                #
> > +                    CApp = CApp + '  Value     = %s; // From %s
> > Line %s.\n' % (DscBuildData.IntToCString(Value, ValueSize), file_path,
> lineNo)
> > +                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' %
> > (ValueSize)
> > +
> > +
> > +            PcdFiledValue =
> > Pcd.PcdFiledValueFromDscComponent.get(ModuleGuid)
> > +            for index in PcdFiledValue:
> > +                FieldList = PcdFiledValue[index]
> > +                if not FieldList:
> > +                    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.BaseDatumType, 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 + '
> > __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s)
> ==
> > 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value
> %s\n' %
> > (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType,
> FieldName,
> > 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 '[' in FieldName and ']' in FieldName:
> > +                            Index =
> > int(FieldName.split('[')[1].split(']')[0])
> > +                            CApp = CApp + '
> __STATIC_ASSERT((%d
> > < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index
> > exceeds the array number"); // From %s Line %d Index of %s\n' % (Index,
> > FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1],
> > FieldList[FieldName][2], FieldName)
> > +                        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 %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1],
> > FieldList[FieldName][2], FieldList[FieldName][0])
> > +            CApp = CApp + "}\n"
> > +        return CApp
> > +
> >      @staticmethod
> >      def GenerateCommandLineValueStatement(Pcd):
> >          CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' %
> > (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> >          return CApp
> >      def GenerateFdfValue(self,Pcd):
> > @@ -2412,10 +2519,88 @@ class DscBuildData(PlatformBuildClassObject):
> >      @staticmethod
> >      def GenerateFdfValueStatement(Pcd):
> >          CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' %
> > (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> >          return CApp
> >
> > +    @staticmethod
> > +    def GenerateModuleValueStatement(module_guid, Pcd):
> > +        CApp = "  Assign_%s_%s_%s_Value(Pcd);\n" %
> > (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, module_guid)
> > +        return CApp
> > +    def GenerateModuleScopeInitializeFunc(self,SkuName, Pcd,
> > InitByteValue, CApp):
> > +        for module_guid in Pcd.PcdFiledValueFromDscComponent:
> > +            CApp = CApp + 'void\n'
> > +            CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' %
> (module_guid,
> > TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> > Pcd.TokenCName)
> > +            CApp = CApp + '  void\n'
> > +            CApp = CApp + '  )\n'
> > +            CApp = CApp + '{\n'
> > +            CApp = CApp + '  UINT32  Size;\n'
> > +            CApp = CApp + '  UINT32  FieldSize;\n'
> > +            CApp = CApp + '  CHAR8   *Value;\n'
> > +            CApp = CApp + '  UINT32  OriginalSize;\n'
> > +            CApp = CApp + '  VOID    *OriginalPcd;\n'
> > +
> > +            CApp = CApp + '  %s      *Pcd;  // From %s Line %d
> \n' %
> > (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
> > +
> > +            CApp = CApp + '\n'
> > +
> > +            PcdDefaultValue =
> > StringToArray(Pcd.DefaultValueFromDec.strip())
> > +            InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (module_guid,
> > TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName,
> > Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
> > +            #
> > +            # Get current PCD value and size
> > +            #
> > +            CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s,
> > &OriginalSize);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> > Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> > +
> > +            #
> > +            # Determine the size of the PCD.  For simple structures,
> > sizeof(TYPE) provides
> > +            # the correct value.  For structures with a flexible array
> > member, the flexible
> > +            # array member is detected, and the size is based on the
> > highest index used with
> > +            # the flexible array member.  The flexible array member
> > must be the last field
> > +            # in a structure.  The size formula for this case is:
> > +            # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) *
> > (HighestIndex + 1)
> > +            #
> > +            CApp = CApp +
> >
> DscBuildData.GenerateSizeStatments(Pcd,SkuName,TAB_DEFAULT_STORES_D
> > EFAULT)
> > +            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> > +                CApp = CApp + '  OriginalSize = OriginalSize <
> sizeof(%s)
> > * %d? OriginalSize:sizeof(%s) * %d; \n' %
> >
> (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySiz
> > e())
> > +                CApp = CApp + '  Size = sizeof(%s) * %d; \n' %
> > (Pcd.BaseDatumType,Pcd.PcdArraySize())
> > +
> > +            #
> > +            # Allocate and zero buffer for the PCD
> > +            # Must handle cases where current value is smaller, larger,
> or
> > same size
> > +            # Always keep that larger one as the current size
> > +            #
> > +            CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize :
> > Size);\n'
> > +            CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' %
> > (Pcd.BaseDatumType,)
> > +            CApp = CApp + '  memset (Pcd, 0, Size);\n'
> > +
> > +            #
> > +            # Copy current PCD value into allocated buffer.
> > +            #
> > +            CApp = CApp + '  memcpy (Pcd, OriginalPcd,
> OriginalSize);\n'
> > +
> > +            #
> > +            # Assign field values in PCD
> > +            #
> > +            CApp = CApp +
> > DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
> > +
> > +            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)
> > +            CApp = CApp +
> > DscBuildData.GenerateModuleValueStatement(module_guid,Pcd)
> > +            #
> > +            # Set new PCD value and size
> > +            #
> > +            CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void
> > *)Pcd);\n' % (module_guid, TAB_DEFAULT_STORES_DEFAULT,
> > Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> > +
> > +            #
> > +            # Free PCD
> > +            #
> > +            CApp = CApp + '  free (Pcd);\n'
> > +            CApp = CApp + '}\n'
> > +            CApp = CApp + '\n'
> > +        return InitByteValue,CApp
> > +
> >      def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd,
> > InitByteValue, CApp):
> >          OverrideValues = {DefaultStore:{}}
> >          if Pcd.SkuOverrideValues:
> >              OverrideValues = Pcd.SkuOverrideValues[SkuName]
> >          if not OverrideValues:
> > @@ -2584,26 +2769,42 @@ class DscBuildData(PlatformBuildClassObject):
> >          CApp = CApp + '\n'
> >          for Pcd in StructuredPcds.values():
> >              CApp = CApp + self.GenerateArrayAssignment(Pcd)
> >          for PcdName in sorted(StructuredPcds.keys()):
> >              Pcd = StructuredPcds[PcdName]
> > +
> > +            #create void void Cal_tocken_cname_Size functions
> >              CApp = CApp + self.GenerateSizeFunction(Pcd)
> > +
> > +            #create void Assign_ functions
> > +
> > +            # From DEC
> >              CApp = CApp +
> self.GenerateDefaultValueAssignFunction(Pcd)
> > +            # From Fdf
> >              CApp = CApp + self.GenerateFdfValue(Pcd)
> > +            # From CommandLine
> >              CApp = CApp + self.GenerateCommandLineValue(Pcd)
> > +
> > +            # From Dsc Global setting
> >              if self.SkuOverrideValuesEmpty(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:
> >                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
> >                      if SkuName not in Pcd.SkuOverrideValues:
> >                          continue
> >                      for DefaultStoreName in
> > Pcd.SkuOverrideValues[SkuName]:
> >                          CApp = CApp +
> > self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
> > +
> > +            # From Dsc module scope setting
> > +            CApp = CApp + self.GenerateModuleScopeValue(Pcd)
> > +
> > +            #create Initialize_ functions
> >              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or
> > Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
> >
> > self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
> >                  InitByteValue, CApp =
> > self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId,
> > TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
> > +                InitByteValue, CApp =
> >
> self.GenerateModuleScopeInitializeFunc(self.SkuIdMgr.SystemSkuId,Pcd,InitBy
> > teValue,CApp)
> >              else:
> >                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
> >                      if SkuName not in Pcd.SkuOverrideValues:
> >                          continue
> >                      for DefaultStoreName in Pcd.DefaultStoreName:
> > @@ -2616,10 +2817,12 @@ class DscBuildData(PlatformBuildClassObject):
> >          CApp = CApp + '  )\n'
> >          CApp = CApp + '{\n'
> >          for Pcd in StructuredPcds.values():
> >              if self.SkuOverrideValuesEmpty(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 + '  Initialize_%s_%s_%s_%s();\n' %
> > (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT,
> > Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> > +                for ModuleGuid in
> > Pcd.PcdFiledValueFromDscComponent:
> > +                    CApp += "  Initialize_%s_%s_%s_%s();\n" %
> > (ModuleGuid,TAB_DEFAULT_STORES_DEFAULT ,Pcd.TokenSpaceGuidCName,
> > Pcd.TokenCName)
> >              else:
> >                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
> >                      if SkuName not in
> self.SkuIdMgr.AvailableSkuIdSet:
> >                          continue
> >                      for DefaultStoreName in
> > Pcd.SkuOverrideValues[SkuName]:
> > @@ -2631,10 +2834,11 @@ class DscBuildData(PlatformBuildClassObject):
> >          if not os.path.exists(self.OutputPath):
> >              os.makedirs(self.OutputPath)
> >          CAppBaseFileName = os.path.join(self.OutputPath,
> > PcdValueInitName)
> >          SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
> >
> > +        # start generating makefile
> >          MakeApp = PcdMakefileHeader
> >          if sys.platform == "win32":
> >              MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' %
> > (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' %
> > (PcdValueInitName) + 'OBJECTS = %s\%s.obj %s.obj\n' % (self.OutputPath,
> > PcdValueInitName, os.path.join(self.OutputPath, PcdValueCommonName)) +
> > 'INC = '
> >          else:
> >              MakeApp = MakeApp + PcdGccMakefile
> > @@ -2753,19 +2957,22 @@ class DscBuildData(PlatformBuildClassObject):
> >              MakeApp = MakeApp + '\tcp
> -f %s %s/PcdValueCommon.c\n' %
> > (PcdValueCommonPath, self.OutputPath)
> >          MakeFileName = os.path.join(self.OutputPath, 'Makefile')
> >          MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
> >          SaveFileOnChange(MakeFileName, MakeApp, False)
> >
> > +        # start generating input file
> >          InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
> >          OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
> >          SaveFileOnChange(InputValueFile, InitByteValue, False)
> >
> >          Dest_PcdValueInitExe = PcdValueInitName
> >          if not sys.platform == "win32":
> >              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> > PcdValueInitName)
> >          else:
> >              Dest_PcdValueInitExe = os.path.join(self.OutputPath,
> > PcdValueInitName) +".exe"
> > +
> > +        #start building the structure pcd value tool
> >          Messages = ''
> >          if sys.platform == "win32":
> >              MakeCommand = 'nmake -f %s' % (MakeFileName)
> >              returncode, StdOut, StdErr =
> DscBuildData.ExecuteCommand
> > (MakeCommand)
> >              Messages = StdOut
> > @@ -2824,17 +3031,19 @@ class DscBuildData(PlatformBuildClassObject):
> >              if MessageGroup:
> >                  EdkLogger.error("build",
> PCD_STRUCTURE_PCD_ERROR,
> > "\n".join(MessageGroup) )
> >              else:
> >                  EdkLogger.error('Build', COMMAND_FAILURE, 'Can
> not
> > execute command: %s\n%s\n%s' % (MakeCommand, StdOut, StdErr))
> >
> > +        #start executing the structure pcd value tool
> >          if DscBuildData.NeedUpdateOutput(OutputValueFile,
> > Dest_PcdValueInitExe, InputValueFile):
> >              Command = Dest_PcdValueInitExe + ' -i %s -o %s' %
> > (InputValueFile, OutputValueFile)
> >              returncode, StdOut, StdErr =
> DscBuildData.ExecuteCommand
> > (Command)
> >              EdkLogger.verbose ('%s\n%s\n%s' % (Command, StdOut,
> > StdErr))
> >              if returncode != 0:
> >                  EdkLogger.warn('Build', COMMAND_FAILURE, 'Can
> not
> > collect output from command: %s\n%s\n' % (Command, StdOut, StdErr))
> >
> > +        #start update structure pcd final value
> >          File = open (OutputValueFile, 'r')
> >          FileBuffer = File.readlines()
> >          File.close()
> >
> >          StructurePcdSet = []
> > diff --git a/BaseTools/Source/Python/build/BuildReport.py
> > b/BaseTools/Source/Python/build/BuildReport.py
> > index 8efa869162..d4de07cae2 100644
> > --- a/BaseTools/Source/Python/build/BuildReport.py
> > +++ b/BaseTools/Source/Python/build/BuildReport.py
> > @@ -694,11 +694,11 @@ class ModuleReport(object):
> >              FileWrite(File, "PCI Class Code:       %s" %
> > self.PciClassCode)
> >
> >          FileWrite(File, gSectionSep)
> >
> >          if "PCD" in ReportType:
> > -            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet)
> > +            GlobalPcdReport.GenerateReport(File,
> > self.ModulePcdSet,self.FileGuid)
> >
> >          if "LIBRARY" in ReportType:
> >              self.LibraryReport.GenerateReport(File)
> >
> >          if "DEPEX" in ReportType:
> > @@ -879,11 +879,11 @@ class PcdReport(object):
> >              for (TokenCName, TokenSpaceGuidCName) in
> > Pa.Platform.Pcds:
> >                  DscDefaultValue = Pa.Platform.Pcds[(TokenCName,
> > TokenSpaceGuidCName)].DscDefaultValue
> >                  if DscDefaultValue:
> >                      self.DscPcdDefault[(TokenCName,
> > TokenSpaceGuidCName)] = DscDefaultValue
> >
> > -    def GenerateReport(self, File, ModulePcdSet):
> > +    def GenerateReport(self, File, ModulePcdSet,module_guid=None):
> >          if not ModulePcdSet:
> >              if self.ConditionalPcds:
> >                  self.GenerateReportDetail(File, ModulePcdSet, 1)
> >              if self.UnusedPcds:
> >                  IsEmpty = True
> > @@ -895,11 +895,11 @@ class PcdReport(object):
> >                              break
> >                      if not IsEmpty:
> >                          break
> >                  if not IsEmpty:
> >                      self.GenerateReportDetail(File, ModulePcdSet, 2)
> > -        self.GenerateReportDetail(File, ModulePcdSet)
> > +        self.GenerateReportDetail(File, ModulePcdSet,module_guid =
> > module_guid)
> >
> >      ##
> >      # Generate report for PCD information
> >      #
> >      # This function generates report for separate module expression
> > @@ -911,11 +911,11 @@ class PcdReport(object):
> >      #                        platform PCD report
> >      # @param ReportySubType  0 means platform/module PCD report,
> 1
> > means Conditional
> >      #                        directives section report, 2 means
> > Unused Pcds section report
> >      # @param DscOverridePcds Module DSC override PCDs set
> >      #
> > -    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
> 0):
> > +    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType =
> > 0,module_guid=None):
> >          PcdDict = self.AllPcds
> >          if ReportSubType == 1:
> >              PcdDict = self.ConditionalPcds
> >          elif ReportSubType == 2:
> >              PcdDict = self.UnusedPcds
> > @@ -991,14 +991,16 @@ class PcdReport(object):
> >                  if DscDefaultValue:
> >                      PcdValue = DscDefaultValue
> >                  #The DefaultValue of StructurePcd already be the
> latest,
> > no need to update.
> >                  if not self.IsStructurePcd(Pcd.TokenCName,
> > Pcd.TokenSpaceGuidCName):
> >                      Pcd.DefaultValue = PcdValue
> > +                PcdComponentValue = None
> >                  if ModulePcdSet is not None:
> >                      if (Pcd.TokenCName,
> Pcd.TokenSpaceGuidCName,
> > Type) not in ModulePcdSet:
> >                          continue
> > -                    InfDefaultValue, PcdValue =
> > ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> > +                    InfDefaultValue, PcdComponentValue =
> > ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> > +                    PcdValue = PcdComponentValue
> >                      #The DefaultValue of StructurePcd already be
> the
> > latest, no need to update.
> >                      if not self.IsStructurePcd(Pcd.TokenCName,
> > Pcd.TokenSpaceGuidCName):
> >                          Pcd.DefaultValue = PcdValue
> >                      if InfDefaultValue:
> >                          try:
> > @@ -1079,62 +1081,68 @@ class PcdReport(object):
> >                  if self.IsStructurePcd(Pcd.TokenCName,
> > Pcd.TokenSpaceGuidCName):
> >                      IsStructure = True
> >                      if TypeName in ('DYNVPD', 'DEXVPD'):
> >                          SkuInfoList = Pcd.SkuInfoList
> >                      Pcd =
> > GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName,
> > Pcd.TokenSpaceGuidCName)]
> > +                    if ModulePcdSet and
> > ModulePcdSet.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type)):
> > +                        InfDefaultValue, PcdComponentValue =
> > ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
> > +                        DscDefaultValBak = Pcd.DefaultValue
> > +                        Pcd.DefaultValue = PcdComponentValue
> > +
> >                      Pcd.DatumType = Pcd.StructName
> >                      if TypeName in ('DYNVPD', 'DEXVPD'):
> >                          Pcd.SkuInfoList = SkuInfoList
> >                      if Pcd.PcdValueFromComm or
> > Pcd.PcdFieldValueFromComm:
> >                          BuildOptionMatch = True
> >                          DecMatch = False
> >                      elif Pcd.PcdValueFromFdf or
> > Pcd.PcdFieldValueFromFdf:
> >                          DscDefaultValue = True
> >                          DscMatch = True
> >                          DecMatch = False
> > -                    elif Pcd.SkuOverrideValues:
> > -                        DscOverride = False
> > -                        if Pcd.DefaultFromDSC:
> > -                            DscOverride = True
> > -                        else:
> > -                            DictLen = 0
> > -                            for item in Pcd.SkuOverrideValues:
> > -                                DictLen +=
> > len(Pcd.SkuOverrideValues[item])
> > -                            if not DictLen:
> > -                                DscOverride = False
> > +                    else:
> > +                        if Pcd.Type in PCD_DYNAMIC_TYPE_SET |
> > PCD_DYNAMIC_EX_TYPE_SET:
> > +                            DscOverride = False
> > +                            if Pcd.DefaultFromDSC:
> > +                                DscOverride = True
> >                              else:
> > -                                if not Pcd.SkuInfoList:
> > -                                    OverrideValues =
> > Pcd.SkuOverrideValues
> > -                                    if OverrideValues:
> > -                                        for Data in
> > OverrideValues.values():
> > -                                            Struct =
> > list(Data.values())
> > -                                            if Struct:
> > -                                                DscOverride =
> > self.ParseStruct(Struct[0])
> > -                                                break
> > +                                DictLen = 0
> > +                                for item in Pcd.SkuOverrideValues:
> > +                                    DictLen +=
> > len(Pcd.SkuOverrideValues[item])
> > +                                if not DictLen:
> > +                                    DscOverride = False
> >                                  else:
> > -                                    SkuList =
> > sorted(Pcd.SkuInfoList.keys())
> > -                                    for Sku in SkuList:
> > -                                        SkuInfo =
> > Pcd.SkuInfoList[Sku]
> > -                                        if
> > SkuInfo.DefaultStoreDict:
> > -                                            DefaultStoreList =
> > sorted(SkuInfo.DefaultStoreDict.keys())
> > -                                            for DefaultStore in
> > DefaultStoreList:
> > -                                                OverrideValues
> =
> > Pcd.SkuOverrideValues[Sku]
> > -                                                DscOverride =
> > self.ParseStruct(OverrideValues[DefaultStore])
> > -                                                if DscOverride:
> > +                                    if not Pcd.SkuInfoList:
> > +                                        OverrideValues =
> > Pcd.SkuOverrideValues
> > +                                        if OverrideValues:
> > +                                            for Data in
> > OverrideValues.values():
> > +                                                Struct =
> > list(Data.values())
> > +                                                if Struct:
> > +
> > DscOverride = self.ParseStruct(Struct[0])
> >                                                      break
> > -                                        if DscOverride:
> > -                                            break
> > -                        if DscOverride:
> > +                                    else:
> > +                                        SkuList =
> > sorted(Pcd.SkuInfoList.keys())
> > +                                        for Sku in SkuList:
> > +                                            SkuInfo =
> > Pcd.SkuInfoList[Sku]
> > +                                            if
> > SkuInfo.DefaultStoreDict:
> > +
> DefaultStoreList
> > = sorted(SkuInfo.DefaultStoreDict.keys())
> > +                                                for
> DefaultStore
> > in DefaultStoreList:
> > +
> > OverrideValues = Pcd.SkuOverrideValues[Sku]
> > +
> > DscOverride = self.ParseStruct(OverrideValues[DefaultStore])
> > +                                                    if
> > DscOverride:
> > +
> break
> > +                                            if DscOverride:
> > +                                                break
> > +                            if DscOverride:
> > +                                DscDefaultValue = True
> > +                                DscMatch = True
> > +                                DecMatch = False
> > +                            else:
> > +                                DecMatch = True
> > +                        else:
> >                              DscDefaultValue = True
> >                              DscMatch = True
> >                              DecMatch = False
> > -                        else:
> > -                            DecMatch = True
> > -                    else:
> > -                        DscDefaultValue = True
> > -                        DscMatch = True
> > -                        DecMatch = False
> >
> >                  #
> >                  # Report PCD item according to their override
> > relationship
> >                  #
> >                  if Pcd.DatumType == 'BOOLEAN':
> > @@ -1151,17 +1159,18 @@ class PcdReport(object):
> >                  elif InfDefaultValue and InfMatch:
> >                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> > TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> > InfDefaultValue, DecMatch, DecDefaultValue, '*M')
> >                  elif BuildOptionMatch:
> >                      self.PrintPcdValue(File, Pcd, PcdTokenCName,
> > TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> > InfDefaultValue, DecMatch, DecDefaultValue, '*B')
> >                  else:
> > -                    if DscDefaultValue and DscMatch:
> > +                    if PcdComponentValue:
> > +                        self.PrintPcdValue(File, Pcd,
> PcdTokenCName,
> > TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> > PcdComponentValue, DecMatch, DecDefaultValue, '*M', module_guid)
> > +                    elif DscDefaultValue and DscMatch:
> >                          if (Pcd.TokenCName, Key, Field) in
> > self.FdfPcdSet:
> >                              self.PrintPcdValue(File, Pcd,
> > PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> > InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')
> >                          else:
> >                              self.PrintPcdValue(File, Pcd,
> > PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak,
> > InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')
> > -                    else:
> > -                        self.PrintPcdValue(File, Pcd,
> PcdTokenCName,
> > TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch,
> > InfDefaultValue, DecMatch, DecDefaultValue, '*M')
> > +
> >
> >                  if ModulePcdSet is None:
> >                      if IsStructure:
> >                          continue
> >                      if not TypeName in ('PATCH', 'FLAG', 'FIXED'):
> > @@ -1263,11 +1272,11 @@ class PcdReport(object):
> >                      self.PrintStructureInfo(File, filedvalues)
> >          if DecMatch and IsStructure:
> >              for filedvalues in Pcd.DefaultValues.values():
> >                  self.PrintStructureInfo(File, filedvalues)
> >
> > -    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> > IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
> DecMatch,
> > DecDefaultValue, Flag = '  '):
> > +    def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName,
> > IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue,
> DecMatch,
> > DecDefaultValue, Flag = '  ',module_guid=None):
> >          if not Pcd.SkuInfoList:
> >              Value = Pcd.DefaultValue
> >              IsByteArray, ArrayList = ByteArrayForamt(Value)
> >              if IsByteArray:
> >                  FileWrite(File, ' %-*s   : %6s %10s = %s' %
> (self.MaxLen,
> > Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))
> > @@ -1286,18 +1295,24 @@ class PcdReport(object):
> >                  FiledOverrideFlag = False
> >                  if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in
> > GlobalData.gPcdSkuOverrides:
> >                      OverrideValues =
> >
> GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)
> > ]
> >                  else:
> >                      OverrideValues = Pcd.SkuOverrideValues
> > +                FieldOverrideValues = None
> >                  if OverrideValues:
> >                      for Data in OverrideValues.values():
> >                          Struct = list(Data.values())
> >                          if Struct:
> > -                            OverrideFieldStruct =
> > self.OverrideFieldValue(Pcd, Struct[0])
> > -                            self.PrintStructureInfo(File,
> > OverrideFieldStruct)
> > +                            FieldOverrideValues = Struct[0]
> >                              FiledOverrideFlag = True
> >                              break
> > +                if Pcd.PcdFiledValueFromDscComponent and
> > module_guid and module_guid.replace("-","S") in
> > Pcd.PcdFiledValueFromDscComponent:
> > +                    FieldOverrideValues =
> > Pcd.PcdFiledValueFromDscComponent[module_guid.replace("-","S")]
> > +                if FieldOverrideValues:
> > +                    OverrideFieldStruct = self.OverrideFieldValue(Pcd,
> > FieldOverrideValues)
> > +                    self.PrintStructureInfo(File, OverrideFieldStruct)
> > +
> >                  if not FiledOverrideFlag and
> > (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):
> >                      OverrideFieldStruct =
> self.OverrideFieldValue(Pcd,
> > {})
> >                      self.PrintStructureInfo(File, OverrideFieldStruct)
> >              self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch,
> > DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)
> >          else:
> > --
> > 2.20.1.windows.1
> >
> >
> >
> >
> >
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 




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

end of thread, other threads:[~2020-10-30  3:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <163E2552F529AEC6.4805@groups.io>
2020-10-26  3:59 ` [edk2-devel] [Patch V2] BaseTools: Enable Module Scope Structure Pcd Bob Feng
2020-10-27  6:19   ` 回复: " gaoliming
2020-10-28 15:07     ` Bob Feng
2020-10-30  3:26       ` 回复: " gaoliming

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