]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Fixed Pcd value override issue.
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
index a5089a900b255a41b1afd4185793b5783fee1e4d..239531cd1c7a98addcc99ee211c40621c2c1f311 100644 (file)
@@ -1133,10 +1133,11 @@ class DscBuildData(PlatformBuildClassObject):
             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
 \r
             self._Pcds = self.CompletePcdValues(self._Pcds)\r
+            self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)\r
             self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
             self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
             self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
-            self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)\r
+\r
             self.RecoverCommandLinePcd()\r
         return self._Pcds\r
 \r
@@ -1203,20 +1204,24 @@ class DscBuildData(PlatformBuildClassObject):
 \r
         return structure_pcd_data\r
     def OverrideByFdfComm(self,StruPcds):\r
-        StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd if len(item) == 5 and (item[1],item[0]) in StruPcds } if GlobalData.BuildOptionPcd else {}\r
+        StructurePcdInCom = OrderedDict()\r
+        for item in GlobalData.BuildOptionPcd:\r
+            if len(item) == 5 and (item[1],item[0]) in StruPcds:\r
+                StructurePcdInCom[(item[0],item[1],item[2] )] = (item[3],item[4])\r
         GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])\r
         for Pcd in StruPcds.values():\r
             if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:\r
                 continue\r
-            FieldValues = {item[2]:StructurePcdInCom[item] for item in StructurePcdInCom if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]}\r
-            for sku in Pcd.SkuOverrideValues:\r
-                for defaultstore in Pcd.SkuOverrideValues[sku]:\r
-                    for field in FieldValues:\r
-                        if field not in Pcd.SkuOverrideValues[sku][defaultstore]:\r
-                            Pcd.SkuOverrideValues[sku][defaultstore][field] = ["","",""]\r
-                        Pcd.SkuOverrideValues[sku][defaultstore][field][0] = FieldValues[field][0]\r
-                        Pcd.SkuOverrideValues[sku][defaultstore][field][1] = FieldValues[field][1][0]\r
-                        Pcd.SkuOverrideValues[sku][defaultstore][field][2] = FieldValues[field][1][1]\r
+            FieldValues = OrderedDict()\r
+            for item in StructurePcdInCom:\r
+                if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:\r
+                    FieldValues[item[2]] = StructurePcdInCom[item]\r
+            for field in FieldValues:\r
+                if field not in Pcd.PcdFieldValueFromComm:\r
+                    Pcd.PcdFieldValueFromComm[field] = ["","",""]\r
+                Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]\r
+                Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]\r
+                Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]\r
         return StruPcds\r
     def OverrideByFdfCommOverAll(self,AllPcds):\r
         def CheckStructureInComm(commpcds):\r
@@ -1234,15 +1239,31 @@ class DscBuildData(PlatformBuildClassObject):
         for Guid,Name in NoFiledValues:\r
             if (Name,Guid) in AllPcds:\r
                 Pcd = AllPcds.get((Name,Guid))\r
-                Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
-                for sku in Pcd.SkuInfoList:\r
-                    SkuInfo = Pcd.SkuInfoList[sku]\r
-                    if SkuInfo.DefaultValue:\r
-                        SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
-                    else:\r
-                        SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
-                        for defaultstore in SkuInfo.DefaultStoreDict:\r
-                            SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):\r
+                    self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                else:\r
+                    Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                    for sku in Pcd.SkuInfoList:\r
+                        SkuInfo = Pcd.SkuInfoList[sku]\r
+                        if SkuInfo.DefaultValue:\r
+                            SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                        else:\r
+                            SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                            for defaultstore in SkuInfo.DefaultStoreDict:\r
+                                SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
+                    if Pcd.DatumType == "VOID*":\r
+                        if Pcd.MaxDatumSize is None:\r
+                            Pcd.MaxDatumSize = '0'\r
+                        MaxSize = int(Pcd.MaxDatumSize,10)\r
+                        if Pcd.DefaultValue.startswith("{") and Pcd.DefaultValue.endswith("}"):\r
+                            MaxSize = max([len(Pcd.DefaultValue.split(",")),MaxSize])\r
+                        elif Pcd.DefaultValue.startswith("\"") or Pcd.DefaultValue.startswith("\'"):\r
+                            MaxSize = max([len(Pcd.DefaultValue)-2+1,MaxSize])\r
+                        elif Pcd.DefaultValue.startswith("L\""):\r
+                            MaxSize = max([2*(len(Pcd.DefaultValue)-3+1),MaxSize])\r
+                        else:\r
+                            MaxSize = max([len(Pcd.DefaultValue),MaxSize])\r
+                        Pcd.MaxDatumSize = str(MaxSize)\r
             else:\r
                 PcdInDec = self.DecPcds.get((Name,Guid))\r
                 if PcdInDec:\r
@@ -1543,10 +1564,8 @@ class DscBuildData(PlatformBuildClassObject):
         if Value[0] == '{' and Value[-1] == '}':\r
             return True\r
         if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
-            print 'foo = ', list(Value[2:-1])\r
             return True\r
         if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
-            print 'bar = ', list(Value[1:-1])\r
             return True\r
         return False\r
 \r
@@ -1567,6 +1586,27 @@ class DscBuildData(PlatformBuildClassObject):
         Result = Result + '"'\r
         return Result\r
 \r
+    def GetPcdMaxSize(self,Pcd):\r
+        MaxSize = int(Pcd.MaxDatumSize,10) if Pcd.MaxDatumSize else 0\r
+        if Pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:\r
+            if Pcd.PcdValueFromComm:\r
+                if Pcd.PcdValueFromComm.startswith("{") and Pcd.PcdValueFromComm.endswith("}"):\r
+                    MaxSize = max([len(Pcd.PcdValueFromComm.split(",")),MaxSize])\r
+                elif Pcd.PcdValueFromComm.startswith("\"") or Pcd.PcdValueFromComm.startswith("\'"):\r
+                    MaxSize = max([len(Pcd.PcdValueFromComm)-2+1,MaxSize])\r
+                elif Pcd.PcdValueFromComm.startswith("L\""):\r
+                    MaxSize = max([2*(len(Pcd.PcdValueFromComm)-3+1),MaxSize])\r
+                else:\r
+                    MaxSize = max([len(Pcd.PcdValueFromComm),MaxSize])\r
+        elif Pcd.DatumType not in ['BOOLEAN','UINT8']:\r
+            MaxSize = 1\r
+        elif Pcd.DatumType  == 'UINT16':\r
+            MaxSize = 2\r
+        elif Pcd.DatumType  == 'UINT32':\r
+            MaxSize = 4\r
+        elif Pcd.DatumType  == 'UINT64':\r
+            MaxSize = 8\r
+        return MaxSize\r
     def GenerateSizeFunction(self,Pcd):\r
         CApp = "// Default Value in Dec \n"\r
         CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
@@ -1625,6 +1665,31 @@ class DscBuildData(PlatformBuildClassObject):
                             while '[' in FieldName:\r
                                 FieldName = FieldName.rsplit('[', 1)[0]\r
                                 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])\r
+        if Pcd.PcdFieldValueFromComm:\r
+            CApp = CApp + "// From Command Line \n"\r
+        for FieldName in Pcd.PcdFieldValueFromComm:\r
+            FieldName = "." + FieldName\r
+            IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
+            if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r
+                try:\r
+                    Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
+                except BadExpression:\r
+                    EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                    (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
+                Value, ValueSize = ParseFieldValue(Value)\r
+                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]);\r
+            else:\r
+                NewFieldName = ''\r
+                FieldName_ori = FieldName.strip('.')\r
+                while '[' in  FieldName:\r
+                    NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
+                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
+                    FieldName = FieldName.split(']', 1)[1]\r
+                FieldName = NewFieldName + FieldName\r
+                while '[' in FieldName:\r
+                    FieldName = FieldName.rsplit('[', 1)[0]\r
+                    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])\r
+        CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd))\r
         CApp = CApp + "}\n"\r
         return CApp\r
     def GenerateSizeStatments(self,Pcd):\r
@@ -1764,6 +1829,68 @@ class DscBuildData(PlatformBuildClassObject):
     def GenerateInitValueStatement(self,Pcd,SkuName,DefaultStoreName):\r
         CApp = '  Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName)\r
         return CApp\r
+    def GenerateCommandLineValue(self,Pcd):\r
+        CApp = "// Value in CommandLine\n"\r
+        CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)\r
+        CApp = CApp + '  UINT32  FieldSize;\n'\r
+        CApp = CApp + '  CHAR8   *Value;\n'\r
+\r
+        pcddefaultvalue = Pcd.PcdValueFromComm\r
+        for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]:\r
+            if not FieldList:\r
+                continue\r
+            if pcddefaultvalue and FieldList == pcddefaultvalue:\r
+                IsArray = self.IsFieldValueAnArray(FieldList)\r
+                if IsArray:\r
+                    try:\r
+                        FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r
+                    except BadExpression:\r
+                        EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r
+                                        (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
+                Value, ValueSize = ParseFieldValue (FieldList)\r
+\r
+                if isinstance(Value, str):\r
+                    CApp = CApp + '  Pcd = %s; // From Command Line \n' % (Value)\r
+                elif IsArray:\r
+                #\r
+                # Use memcpy() to copy value into field\r
+                #\r
+                    CApp = CApp + '  Value     = %s; // From Command Line.\n' % (self.IntToCString(Value, ValueSize))\r
+                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
+                continue\r
+            for FieldName in FieldList:\r
+                IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
+                if IsArray:\r
+                    try:\r
+                        FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
+                    except BadExpression:\r
+                        EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
+                                        (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
+                    except:\r
+                        print "error"\r
+                try:\r
+                    Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
+                except Exception:\r
+                    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]))\r
+                if isinstance(Value, str):\r
+                    CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                elif IsArray:\r
+                #\r
+                # Use memcpy() to copy value into field\r
+                #\r
+                    CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
+                    CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
+                else:\r
+                    if ValueSize > 4:\r
+                        CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+                    else:\r
+                        CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
+        CApp = CApp + "}\n"\r
+        return CApp\r
+    def GenerateCommandLineValueStatement(self,Pcd):\r
+        CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
+        return CApp\r
     def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):\r
         OverrideValues = {DefaultStore:""}\r
         if Pcd.SkuOverrideValues:\r
@@ -1835,6 +1962,7 @@ class DscBuildData(PlatformBuildClassObject):
             else:\r
                 CApp = CApp + "// SkuName: DEFAULT,  DefaultStoreName: STANDARD \n"\r
                 CApp = CApp + self.GenerateInitValueStatement(Pcd,"DEFAULT","STANDARD")\r
+            CApp = CApp + self.GenerateCommandLineValueStatement(Pcd)\r
             #\r
             # Set new PCD value and size\r
             #\r
@@ -1870,6 +1998,7 @@ class DscBuildData(PlatformBuildClassObject):
             Pcd = StructuredPcds[PcdName]\r
             CApp = CApp + self.GenerateSizeFunction(Pcd)\r
             CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)\r
+            CApp = CApp + self.GenerateCommandLineValue(Pcd)\r
             if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
                 CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, 'STANDARD')\r
@@ -2374,7 +2503,7 @@ class DscBuildData(PlatformBuildClassObject):
                 MaxSize = int(pcd.MaxDatumSize, 0)\r
             else:\r
                 MaxSize = 0\r
-            if pcdDecObject.DatumType == 'VOID*':\r
+            if pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:\r
                 for (_, skuobj) in pcd.SkuInfoList.items():\r
                     datalen = 0\r
                     skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r