diff --git a/BaseTools/Source/Python/AutoGen/GenVar.py b/BaseTools/Source/Python/AutoGen/GenVar.py index 1389d7ff62..d222e6ed5e 100644 --- a/BaseTools/Source/Python/AutoGen/GenVar.py +++ b/BaseTools/Source/Python/AutoGen/GenVar.py @@ -104,10 +104,27 @@ class VariableMgr(object): for data_byte in pack(data_flag,int(data,16) if data.upper().startswith('0X') else int(data)): value_list += [hex(unpack("B",data_byte)[0])] newvalue[int(item.var_offset,16) if item.var_offset.upper().startswith("0X") else int(item.var_offset)] = value_list - newvaluestr = "{" + ",".join(reduce(lambda x,y: x+y, [newvalue[k] for k in sorted(newvalue.keys())] )) +"}" + try: + newvaluestr = "{" + ",".join(self.assemble_variable(newvalue)) +"}" + except: + EdkLogger.error("build", AUTOGEN_ERROR, "Variable offset conflict in PCDs: %s \n" % (" and ".join([item.pcdname for item in sku_var_info_offset_list]))) n = sku_var_info_offset_list[0] indexedvarinfo[key] = [var_info(n.pcdindex,n.pcdname,n.defaultstoragename,n.skuname,n.var_name, n.var_guid, "0x00",n.var_attribute,newvaluestr , newvaluestr , "VOID*")] self.VarInfo = [item[0] for item in indexedvarinfo.values()] + + def assemble_variable(self, valuelist): + ordered_value = [valuelist[k] for k in sorted(valuelist.keys())] + ordered_offset = sorted(valuelist.keys()) + var_value = [] + num = 0 + for offset in ordered_offset: + if offset < len(var_value): + raise + for _ in xrange(offset - len(var_value)): + var_value.append('0x00') + var_value += ordered_value[num] + num +=1 + return var_value def process_variable_data(self): var_data = dict() diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py index 0e1161c96f..f499cbd58b 100644 --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -114,6 +114,7 @@ class StructurePcd(PcdClassObject): if validateranges is None: validateranges=[] if validlists is None: validlists=[] if expressions is None : expressions=[] + if Packages is None : Packages = [] super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions) self.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile self.PackageDecs = Packages diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py index 2266b0b7a6..99c3bf14f1 100644 --- a/BaseTools/Source/Python/Workspace/DecBuildData.py +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py @@ -389,6 +389,8 @@ class DecBuildData(PackageBuildClassObject): struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue,self.MetaFile.File,LineNo) struct_pcd.PackageDecs = dep_pkgs + if not struct_pcd.StructuredPcdIncludeFile: + EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName,self.MetaFile.File,LineNo )) str_pcd_set.append(struct_pcd) @@ -423,11 +425,6 @@ class DecBuildData(PackageBuildClassObject): continue DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting) - if DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: - StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$') - if StructPattern.match(DatumType) == None: - EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", File=self.MetaFile, Line=LineNo) - validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName) PcdObj = PcdClassObject( PcdCName, diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index d9165f2ac7..01592e147e 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -1584,6 +1584,7 @@ class DscBuildData(PlatformBuildClassObject): # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1) # CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType) + CApp = CApp + "// Default Value in Dec \n" for FieldList in [Pcd.DefaultValues]: if not FieldList: continue @@ -1611,31 +1612,34 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) for skuname in self.SkuIdMgr.GetSkuChain(SkuName): inherit_OverrideValues = Pcd.SkuOverrideValues[skuname] - for FieldList in [inherit_OverrideValues.get(DefaultStoreName)]: - if not FieldList: - continue - for FieldName in FieldList: - FieldName = "." + FieldName - IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) - if IsArray: - try: - Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) - except BadExpression: - EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % - (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) - Value, ValueSize = ParseFieldValue(Value) - CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); - else: - NewFieldName = '' - FieldName_ori = FieldName.strip('.') - while '[' in FieldName: - NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' - ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) - FieldName = FieldName.split(']', 1)[1] - FieldName = NewFieldName + FieldName - while '[' in FieldName: - FieldName = FieldName.rsplit('[', 1)[0] - CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) + storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName] + for defaultstorenameitem in storeset: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) + for FieldList in [inherit_OverrideValues.get(defaultstorenameitem)]: + if not FieldList: + continue + for FieldName in FieldList: + FieldName = "." + FieldName + IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) + if IsArray: + try: + Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) + except BadExpression: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % + (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2])) + Value, ValueSize = ParseFieldValue(Value) + CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]); + else: + NewFieldName = '' + FieldName_ori = FieldName.strip('.') + while '[' in FieldName: + NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' + ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) + FieldName = FieldName.split(']', 1)[1] + FieldName = NewFieldName + FieldName + while '[' in FieldName: + FieldName = FieldName.rsplit('[', 1)[0] + CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0]) if skuname == SkuName: break @@ -1656,6 +1660,7 @@ class DscBuildData(PlatformBuildClassObject): # # Assign field values in PCD # + CApp = CApp + "// Default value in Dec \n" for FieldList in [Pcd.DefaultValues]: if not FieldList: continue @@ -1688,56 +1693,56 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) for skuname in self.SkuIdMgr.GetSkuChain(SkuName): inherit_OverrideValues = Pcd.SkuOverrideValues[skuname] - for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(DefaultStoreName)]: - if not FieldList: - continue - if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: - IsArray = self.IsFieldValueAnArray(FieldList) - if IsArray: + storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName] + for defaultstorenameitem in storeset: + CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem) + for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(defaultstorenameitem)]: + if not FieldList: + continue + if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: + IsArray = self.IsFieldValueAnArray(FieldList) + if IsArray: + try: + FieldList = ValueExpressionEx(FieldList, "VOID*")(True) + except BadExpression: + EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % + (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList)) + Value, ValueSize = ParseFieldValue (FieldList) + if isinstance(Value, str): + CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) + elif IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC) + CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) + continue + for FieldName in FieldList: + IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + if IsArray: + try: + FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "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])) try: - FieldList = ValueExpressionEx(FieldList, "VOID*")(True) - except BadExpression: - EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % - (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList)) - - Value, ValueSize = ParseFieldValue (FieldList) - if isinstance(Value, str): - CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) - elif IsArray: - # - # Use memcpy() to copy value into field - # - CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC) - CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) - continue - - for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) - if IsArray: - try: - FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "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])) - - try: - Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) - except Exception: - EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2])) - if isinstance(Value, str): - CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) - elif IsArray: - # - # Use memcpy() to copy value into field - # - CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) - CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) - CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) - else: - if ValueSize > 4: - CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) + except Exception: + EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2])) + if isinstance(Value, str): + CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + elif IsArray: + # + # Use memcpy() to copy value into field + # + CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) + CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) else: - CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + 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]) if skuname == SkuName: break # @@ -2350,6 +2355,7 @@ class DscBuildData(PlatformBuildClassObject): for pcd in Pcds.values(): SkuInfoObj = pcd.SkuInfoList.values()[0] pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName] + pcd.DatumType = pcdDecObject.DatumType # Only fix the value while no value provided in DSC file. for sku in pcd.SkuInfoList.values(): if (sku.DefaultValue == "" or sku.DefaultValue==None):