Hi Bob, I think the behavior of this patch looks correct.
However, when I generate a build report, it does not show the module scope PCD values used by a module. It only shows the platform scoped values. Mike > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bob Feng > Sent: Monday, August 10, 2020 2:10 AM > To: devel@edk2.groups.io > Cc: Gao, Liming <liming....@intel.com>; Chen, Christine <yuwei.c...@intel.com> > Subject: [edk2-devel] [Patch] 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.f...@intel.com> > Cc: Liming Gao <liming....@intel.com> > Cc: Yuwei Chen <yuwei.c...@intel.com> > > --- > 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 | 242 ++++++++++++++++-- > 6 files changed, 256 insertions(+), 25 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 dc8b1fe3d1..273bde117f 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 af66c48c7d..b64dce86bf 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 1afbd3eefc..14ba0a6cd5 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 > + ) > + 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,10 +1600,12 @@ 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: > @@ -1591,10 +1620,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 +2376,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 +2518,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 +2768,42 @@ class DscBuildData(PlatformBuildClassObject): > CApp = CApp + '\n' > for Pcd in StructuredPcds.values(): > CApp = CApp + self.GenerateArrayAssignment(Pcd) > for PcdName in StructuredPcds: > 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 +2816,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 +2833,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 +2956,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 +3030,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 = [] > -- > 2.20.1.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#64271): https://edk2.groups.io/g/devel/message/64271 Mute This Topic: https://groups.io/mt/76101016/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-