[edk2] [Patch] BaseTool: Fixed Pcd issues.

BobCF posted 1 patch 6 years, 2 months ago
Failed in applying to current master (apply log)
BaseTools/Source/Python/AutoGen/GenVar.py          |  19 ++-
.../Source/Python/Workspace/BuildClassObject.py    |   1 +
BaseTools/Source/Python/Workspace/DecBuildData.py  |   7 +-
BaseTools/Source/Python/Workspace/DscBuildData.py  | 152 +++++++++++----------
4 files changed, 100 insertions(+), 79 deletions(-)
[edk2] [Patch] BaseTool: Fixed Pcd issues.
Posted by BobCF 6 years, 2 months ago
1. Check variable offset when merging Hii Pcds
2. Fixed the issue of Hii value inherit with default store.
3. Error handling for incorrect structure pcd declare.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/AutoGen/GenVar.py          |  19 ++-
 .../Source/Python/Workspace/BuildClassObject.py    |   1 +
 BaseTools/Source/Python/Workspace/DecBuildData.py  |   7 +-
 BaseTools/Source/Python/Workspace/DscBuildData.py  | 152 +++++++++++----------
 4 files changed, 100 insertions(+), 79 deletions(-)

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
@@ -102,14 +102,31 @@ class VariableMgr(object):
                     data = value_list[0]
                     value_list = []
                     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()
 
         indexedvarinfo = collections.OrderedDict()
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
@@ -112,10 +112,11 @@ class StructurePcd(PcdClassObject):
     def __init__(self, StructuredPcdIncludeFile=None, Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False, GuidValue=None, validateranges=None, validlists=None, expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
         if SkuInfoList is None: SkuInfoList={}
         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
         self.DefaultStoreName = [default_store]
         self.DefaultValues = collections.OrderedDict({})
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
@@ -387,10 +387,12 @@ class DecBuildData(PackageBuildClassObject):
                     struct_pcd.PkgPath = self.MetaFile.File
                 else:
                     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)
 
         return str_pcd_set
 
@@ -421,15 +423,10 @@ class DecBuildData(PackageBuildClassObject):
             Setting,LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
             if Setting == None:
                 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,
                                         TokenSpaceGuid,
                                         self._PCD_TYPE_STRING_[Type],
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 6e3cd0f3f1..87e79e8f92 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -1520,10 +1520,11 @@ class DscBuildData(PlatformBuildClassObject):
             # 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 + '  Size = sizeof(%s);\n' % (Pcd.DatumType)
+            CApp = CApp + "// Default Value in Dec \n"
             for FieldList in [Pcd.DefaultValues]:
                 if not FieldList:
                     continue
                 for FieldName in FieldList:
                     FieldName = "." + FieldName
@@ -1547,35 +1548,38 @@ class DscBuildData(PlatformBuildClassObject):
                         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])
             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
 
             #
             # Allocate and zero buffer for the PCD
@@ -1592,10 +1596,11 @@ class DscBuildData(PlatformBuildClassObject):
             CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
 
             #
             # Assign field values in PCD
             #
+            CApp = CApp + "// Default value in Dec \n"
             for FieldList in [Pcd.DefaultValues]:
                 if not FieldList:
                     continue
                 for FieldName in FieldList:
                     IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
@@ -1624,60 +1629,60 @@ class DscBuildData(PlatformBuildClassObject):
                             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])
             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:
-                            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:
+                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[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
             #
             # Set new PCD value and size
             #
@@ -2290,10 +2295,11 @@ class DscBuildData(PlatformBuildClassObject):
                                                 None,
                                                 IsDsc=True)
         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):
                     sku.DefaultValue = pcdDecObject.DefaultValue
             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
-- 
2.14.3.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch] BaseTool: Fixed Pcd issues.
Posted by Gao, Liming 6 years, 2 months ago
Reviewed-by: Liming Gao <liming.gao@intel.com>

>-----Original Message-----
>From: Feng, Bob C
>Sent: Wednesday, February 07, 2018 10:02 AM
>To: edk2-devel@lists.01.org
>Cc: Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
>Subject: [Patch] BaseTool: Fixed Pcd issues.
>
>1. Check variable offset when merging Hii Pcds
>2. Fixed the issue of Hii value inherit with default store.
>3. Error handling for incorrect structure pcd declare.
>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Bob Feng <bob.c.feng@intel.com>
>Cc: Liming Gao <liming.gao@intel.com>
>---
> BaseTools/Source/Python/AutoGen/GenVar.py          |  19 ++-
> .../Source/Python/Workspace/BuildClassObject.py    |   1 +
> BaseTools/Source/Python/Workspace/DecBuildData.py  |   7 +-
> BaseTools/Source/Python/Workspace/DscBuildData.py  | 152 +++++++++++-
>---------
> 4 files changed, 100 insertions(+), 79 deletions(-)
>
>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
>@@ -102,14 +102,31 @@ class VariableMgr(object):
>                     data = value_list[0]
>                     value_list = []
>                     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_na
>me, 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()
>
>         indexedvarinfo = collections.OrderedDict()
>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
>@@ -112,10 +112,11 @@ class StructurePcd(PcdClassObject):
>     def __init__(self, StructuredPcdIncludeFile=None, Packages=None,
>Name=None, Guid=None, Type=None, DatumType=None, Value=None,
>Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False,
>GuidValue=None, validateranges=None, validlists=None,
>expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
>         if SkuInfoList is None: SkuInfoList={}
>         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
>         self.DefaultStoreName = [default_store]
>         self.DefaultValues = collections.OrderedDict({})
>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
>@@ -387,10 +387,12 @@ class DecBuildData(PackageBuildClassObject):
>                     struct_pcd.PkgPath = self.MetaFile.File
>                 else:
>                     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)
>
>         return str_pcd_set
>
>@@ -421,15 +423,10 @@ class DecBuildData(PackageBuildClassObject):
>             Setting,LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
>             if Setting == None:
>                 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,
>                                         TokenSpaceGuid,
>                                         self._PCD_TYPE_STRING_[Type],
>diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
>b/BaseTools/Source/Python/Workspace/DscBuildData.py
>index 6e3cd0f3f1..87e79e8f92 100644
>--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
>+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
>@@ -1520,10 +1520,11 @@ class DscBuildData(PlatformBuildClassObject):
>             # 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 + '  Size = sizeof(%s);\n' % (Pcd.DatumType)
>+            CApp = CApp + "// Default Value in Dec \n"
>             for FieldList in [Pcd.DefaultValues]:
>                 if not FieldList:
>                     continue
>                 for FieldName in FieldList:
>                     FieldName = "." + FieldName
>@@ -1547,35 +1548,38 @@ class DscBuildData(PlatformBuildClassObject):
>                         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])
>             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
>
>             #
>             # Allocate and zero buffer for the PCD
>@@ -1592,10 +1596,11 @@ class DscBuildData(PlatformBuildClassObject):
>             CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
>
>             #
>             # Assign field values in PCD
>             #
>+            CApp = CApp + "// Default value in Dec \n"
>             for FieldList in [Pcd.DefaultValues]:
>                 if not FieldList:
>                     continue
>                 for FieldName in FieldList:
>                     IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
>@@ -1624,60 +1629,60 @@ class DscBuildData(PlatformBuildClassObject):
>                             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])
>             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:
>-                            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:
>+                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[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)),FieldLis
>t[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)),FieldLis
>t[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
>             #
>             # Set new PCD value and size
>             #
>@@ -2290,10 +2295,11 @@ class DscBuildData(PlatformBuildClassObject):
>                                                 None,
>                                                 IsDsc=True)
>         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):
>                     sku.DefaultValue = pcdDecObject.DefaultValue
>             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in
>pcd.SkuInfoList.keys():
>--
>2.14.3.windows.1

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