+\r
+ self.PatchPcds = []\r
+ InfPcds = Inf.Pcds\r
+ Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+ FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
+ PlatformPcds = Platform.Pcds\r
+\r
+ # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
+ # But INF file path in FDF and DSC file may have real case characters.\r
+ # Try to convert the path to lower case to see if PCDs value are override by DSC.\r
+ DscModules = {}\r
+ for DscModule in Platform.Modules:\r
+ DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]\r
+ for PcdKey in InfPcds:\r
+ Pcd = InfPcds[PcdKey]\r
+ if not hasattr(Pcd, 'Offset'):\r
+ continue\r
+ if Pcd.Type != 'PatchableInModule':\r
+ continue\r
+ # Override Patchable PCD value by the value from DSC\r
+ PatchPcd = None\r
+ if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
+ PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
+ elif PcdKey in Platform.Pcds:\r
+ PatchPcd = Platform.Pcds[PcdKey]\r
+ DscOverride = False\r
+ if PatchPcd and Pcd.Type == PatchPcd.Type:\r
+ DefaultValue = PatchPcd.DefaultValue\r
+ DscOverride = True\r
+\r
+ # Override Patchable PCD value by the value from FDF\r
+ FdfOverride = False\r
+ if PcdKey in FdfPcdDict:\r
+ DefaultValue = FdfPcdDict[PcdKey]\r
+ FdfOverride = True\r
+\r
+ # Override Patchable PCD value by the value from Build Option\r
+ BuildOptionOverride = False\r
+ if GlobalData.BuildOptionPcd:\r
+ for pcd in GlobalData.BuildOptionPcd:\r
+ if PcdKey == (pcd[1], pcd[0]):\r
+ if pcd[2]:\r
+ continue\r
+ DefaultValue = pcd[3]\r
+ BuildOptionOverride = True\r
+ break\r
+\r
+ if not DscOverride and not FdfOverride and not BuildOptionOverride:\r
+ continue\r
+\r
+ # Support Flexible PCD format\r
+ if DefaultValue:\r
+ try:\r
+ DefaultValue = ValueExpressionEx(DefaultValue, Pcd.DatumType, Platform._GuidDict)(True)\r
+ except BadExpression:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName)\r
+\r
+ if Pcd.InfDefaultValue:\r
+ try:\r
+ Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True)\r
+ except BadExpression:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue),File=self.InfFileName)\r
+\r
+ # Check value, if value are equal, no need to patch\r
+ if Pcd.DatumType == "VOID*":\r
+ if Pcd.InfDefaultValue == DefaultValue or DefaultValue in [None, '']:\r
+ continue\r
+ # Get the string size from FDF or DSC\r
+ if DefaultValue[0] == 'L':\r
+ # Remove L"", but the '\0' must be appended\r
+ MaxDatumSize = str((len(DefaultValue) - 2) * 2)\r
+ elif DefaultValue[0] == '{':\r
+ MaxDatumSize = str(len(DefaultValue.split(',')))\r
+ else:\r
+ MaxDatumSize = str(len(DefaultValue) - 1)\r
+ if DscOverride:\r
+ Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
+ # If no defined the maximum size in DSC, try to get current size from INF\r
+ if Pcd.MaxDatumSize in ['', None]:\r
+ Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(',')))\r
+ else:\r
+ Base1 = Base2 = 10\r
+ if Pcd.InfDefaultValue.upper().startswith('0X'):\r
+ Base1 = 16\r
+ if DefaultValue.upper().startswith('0X'):\r
+ Base2 = 16\r
+ try:\r
+ PcdValueInImg = int(Pcd.InfDefaultValue, Base1)\r
+ PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
+ if PcdValueInImg == PcdValueInDscOrFdf:\r
+ continue\r
+ except:\r
+ continue\r
+ # Check the Pcd size and data type\r
+ if Pcd.DatumType == "VOID*":\r
+ if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
+ else:\r
+ if PcdValueInDscOrFdf > MAX_VAL_TYPE[Pcd.DatumType] \\r
+ or PcdValueInImg > MAX_VAL_TYPE[Pcd.DatumType]:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
+ % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
+ self.PatchPcds.append((Pcd, DefaultValue))\r
+\r