| 1 | ## @file\r |
| 2 | # This file is used to create a database used by build tool\r |
| 3 | #\r |
| 4 | # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r |
| 5 | # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r |
| 6 | # This program and the accompanying materials\r |
| 7 | # are licensed and made available under the terms and conditions of the BSD License\r |
| 8 | # which accompanies this distribution. The full text of the license may be found at\r |
| 9 | # http://opensource.org/licenses/bsd-license.php\r |
| 10 | #\r |
| 11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
| 12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
| 13 | #\r |
| 14 | \r |
| 15 | ## Platform build information from DSC file\r |
| 16 | #\r |
| 17 | # This class is used to retrieve information stored in database and convert them\r |
| 18 | # into PlatformBuildClassObject form for easier use for AutoGen.\r |
| 19 | #\r |
| 20 | from Common.String import *\r |
| 21 | from Common.DataType import *\r |
| 22 | from Common.Misc import *\r |
| 23 | from types import *\r |
| 24 | from Common.Expression import *\r |
| 25 | from CommonDataClass.CommonClass import SkuInfoClass\r |
| 26 | from Common.TargetTxtClassObject import *\r |
| 27 | from Common.ToolDefClassObject import *\r |
| 28 | from MetaDataTable import *\r |
| 29 | from MetaFileTable import *\r |
| 30 | from MetaFileParser import *\r |
| 31 | \r |
| 32 | from WorkspaceCommon import GetDeclaredPcd\r |
| 33 | from Common.Misc import AnalyzeDscPcd\r |
| 34 | from Common.Misc import ProcessDuplicatedInf\r |
| 35 | import re\r |
| 36 | from Common.Parsing import IsValidWord\r |
| 37 | from Common.VariableAttributes import VariableAttributes\r |
| 38 | import Common.GlobalData as GlobalData\r |
| 39 | import subprocess\r |
| 40 | from Common.Misc import SaveFileOnChange\r |
| 41 | from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject\r |
| 42 | from collections import OrderedDict\r |
| 43 | \r |
| 44 | #\r |
| 45 | # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs\r |
| 46 | #\r |
| 47 | PcdValueInitName = 'PcdValueInit'\r |
| 48 | PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']\r |
| 49 | PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}\r |
| 50 | PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']\r |
| 51 | \r |
| 52 | PcdMainCHeader = '''\r |
| 53 | /**\r |
| 54 | DO NOT EDIT\r |
| 55 | FILE auto-generated\r |
| 56 | **/\r |
| 57 | \r |
| 58 | #include <stdio.h>\r |
| 59 | #include <stdlib.h>\r |
| 60 | #include <string.h>\r |
| 61 | #include <PcdValueCommon.h>\r |
| 62 | '''\r |
| 63 | \r |
| 64 | PcdMainCEntry = '''\r |
| 65 | int\r |
| 66 | main (\r |
| 67 | int argc,\r |
| 68 | char *argv[]\r |
| 69 | )\r |
| 70 | {\r |
| 71 | return PcdValueMain (argc, argv);\r |
| 72 | }\r |
| 73 | '''\r |
| 74 | \r |
| 75 | PcdMakefileHeader = '''\r |
| 76 | #\r |
| 77 | # DO NOT EDIT\r |
| 78 | # This file is auto-generated by build utility\r |
| 79 | #\r |
| 80 | \r |
| 81 | '''\r |
| 82 | \r |
| 83 | WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '\r |
| 84 | LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '\r |
| 85 | PcdMakefileEnd = '''\r |
| 86 | !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common\r |
| 87 | \r |
| 88 | LIBS = $(LIB_PATH)\Common.lib\r |
| 89 | \r |
| 90 | !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app\r |
| 91 | '''\r |
| 92 | \r |
| 93 | PcdGccMakefile = '''\r |
| 94 | MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r |
| 95 | LIBS = -lCommon\r |
| 96 | '''\r |
| 97 | \r |
| 98 | ## Regular expression for finding header file inclusions\r |
| 99 | from AutoGen.GenMake import gIncludePattern\r |
| 100 | \r |
| 101 | ## Find dependencies for one source file\r |
| 102 | #\r |
| 103 | # By searching recursively "#include" directive in file, find out all the\r |
| 104 | # files needed by given source file. The dependecies will be only searched\r |
| 105 | # in given search path list.\r |
| 106 | #\r |
| 107 | # @param SearchPathList The list of search path\r |
| 108 | #\r |
| 109 | # @retval list The list of files the given source file depends on\r |
| 110 | #\r |
| 111 | def GetDependencyList(FileStack,SearchPathList):\r |
| 112 | DepDb = dict()\r |
| 113 | DependencySet = set(FileStack)\r |
| 114 | while len(FileStack) > 0:\r |
| 115 | F = FileStack.pop()\r |
| 116 | FullPathDependList = []\r |
| 117 | CurrentFileDependencyList = []\r |
| 118 | if F in DepDb:\r |
| 119 | CurrentFileDependencyList = DepDb[F]\r |
| 120 | else:\r |
| 121 | try:\r |
| 122 | Fd = open(F, 'r')\r |
| 123 | FileContent = Fd.read()\r |
| 124 | except BaseException, X:\r |
| 125 | EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))\r |
| 126 | finally:\r |
| 127 | if "Fd" in dir(locals()):\r |
| 128 | Fd.close()\r |
| 129 | \r |
| 130 | if len(FileContent) == 0:\r |
| 131 | continue\r |
| 132 | \r |
| 133 | if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r |
| 134 | FileContent = unicode(FileContent, "utf-16")\r |
| 135 | IncludedFileList = gIncludePattern.findall(FileContent)\r |
| 136 | \r |
| 137 | for Inc in IncludedFileList:\r |
| 138 | Inc = Inc.strip()\r |
| 139 | Inc = os.path.normpath(Inc)\r |
| 140 | CurrentFileDependencyList.append(Inc)\r |
| 141 | DepDb[F] = CurrentFileDependencyList\r |
| 142 | \r |
| 143 | CurrentFilePath = os.path.dirname(F)\r |
| 144 | PathList = [CurrentFilePath] + SearchPathList\r |
| 145 | for Inc in CurrentFileDependencyList:\r |
| 146 | for SearchPath in PathList:\r |
| 147 | FilePath = os.path.join(SearchPath, Inc)\r |
| 148 | if not os.path.exists(FilePath):\r |
| 149 | continue\r |
| 150 | if FilePath not in DependencySet:\r |
| 151 | FileStack.append(FilePath)\r |
| 152 | FullPathDependList.append(FilePath)\r |
| 153 | break\r |
| 154 | DependencySet.update(FullPathDependList)\r |
| 155 | DependencyList = list(DependencySet) # remove duplicate ones\r |
| 156 | \r |
| 157 | return DependencyList\r |
| 158 | \r |
| 159 | class DscBuildData(PlatformBuildClassObject):\r |
| 160 | # dict used to convert PCD type in database to string used by build tool\r |
| 161 | _PCD_TYPE_STRING_ = {\r |
| 162 | MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r |
| 163 | MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r |
| 164 | MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r |
| 165 | MODEL_PCD_DYNAMIC : "Dynamic",\r |
| 166 | MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r |
| 167 | MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r |
| 168 | MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r |
| 169 | MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r |
| 170 | MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r |
| 171 | MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r |
| 172 | MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r |
| 173 | }\r |
| 174 | \r |
| 175 | # dict used to convert part of [Defines] to members of DscBuildData directly\r |
| 176 | _PROPERTY_ = {\r |
| 177 | #\r |
| 178 | # Required Fields\r |
| 179 | #\r |
| 180 | TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",\r |
| 181 | TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",\r |
| 182 | TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",\r |
| 183 | TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",\r |
| 184 | # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",\r |
| 185 | # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",\r |
| 186 | # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",\r |
| 187 | TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",\r |
| 188 | # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",\r |
| 189 | TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",\r |
| 190 | TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",\r |
| 191 | TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",\r |
| 192 | TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",\r |
| 193 | # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",\r |
| 194 | # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",\r |
| 195 | }\r |
| 196 | \r |
| 197 | # used to compose dummy library class name for those forced library instances\r |
| 198 | _NullLibraryNumber = 0\r |
| 199 | \r |
| 200 | ## Constructor of DscBuildData\r |
| 201 | #\r |
| 202 | # Initialize object of DscBuildData\r |
| 203 | #\r |
| 204 | # @param FilePath The path of platform description file\r |
| 205 | # @param RawData The raw data of DSC file\r |
| 206 | # @param BuildDataBase Database used to retrieve module/package information\r |
| 207 | # @param Arch The target architecture\r |
| 208 | # @param Platform (not used for DscBuildData)\r |
| 209 | # @param Macros Macros used for replacement in DSC file\r |
| 210 | #\r |
| 211 | def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r |
| 212 | self.MetaFile = FilePath\r |
| 213 | self._RawData = RawData\r |
| 214 | self._Bdb = BuildDataBase\r |
| 215 | self._Arch = Arch\r |
| 216 | self._Target = Target\r |
| 217 | self._Toolchain = Toolchain\r |
| 218 | self._ToolChainFamily = None\r |
| 219 | self._Clear()\r |
| 220 | self._HandleOverridePath()\r |
| 221 | self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""\r |
| 222 | self.DefaultStores = None\r |
| 223 | self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)\r |
| 224 | @property\r |
| 225 | def OutputPath(self):\r |
| 226 | if os.getenv("WORKSPACE"):\r |
| 227 | return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain,PcdValueInitName)\r |
| 228 | else:\r |
| 229 | return os.path.dirname(self.DscFile)\r |
| 230 | \r |
| 231 | ## XXX[key] = value\r |
| 232 | def __setitem__(self, key, value):\r |
| 233 | self.__dict__[self._PROPERTY_[key]] = value\r |
| 234 | \r |
| 235 | ## value = XXX[key]\r |
| 236 | def __getitem__(self, key):\r |
| 237 | return self.__dict__[self._PROPERTY_[key]]\r |
| 238 | \r |
| 239 | ## "in" test support\r |
| 240 | def __contains__(self, key):\r |
| 241 | return key in self._PROPERTY_\r |
| 242 | \r |
| 243 | ## Set all internal used members of DscBuildData to None\r |
| 244 | def _Clear(self):\r |
| 245 | self._Header = None\r |
| 246 | self._PlatformName = None\r |
| 247 | self._Guid = None\r |
| 248 | self._Version = None\r |
| 249 | self._DscSpecification = None\r |
| 250 | self._OutputDirectory = None\r |
| 251 | self._SupArchList = None\r |
| 252 | self._BuildTargets = None\r |
| 253 | self._SkuName = None\r |
| 254 | self._PcdInfoFlag = None\r |
| 255 | self._VarCheckFlag = None\r |
| 256 | self._FlashDefinition = None\r |
| 257 | self._Prebuild = None\r |
| 258 | self._Postbuild = None\r |
| 259 | self._BuildNumber = None\r |
| 260 | self._MakefileName = None\r |
| 261 | self._BsBaseAddress = None\r |
| 262 | self._RtBaseAddress = None\r |
| 263 | self._SkuIds = None\r |
| 264 | self._Modules = None\r |
| 265 | self._LibraryInstances = None\r |
| 266 | self._LibraryClasses = None\r |
| 267 | self._Pcds = None\r |
| 268 | self._DecPcds = None\r |
| 269 | self._BuildOptions = None\r |
| 270 | self._ModuleTypeOptions = None\r |
| 271 | self._LoadFixAddress = None\r |
| 272 | self._RFCLanguages = None\r |
| 273 | self._ISOLanguages = None\r |
| 274 | self._VpdToolGuid = None\r |
| 275 | self.__Macros = None\r |
| 276 | self.DefaultStores = None\r |
| 277 | \r |
| 278 | \r |
| 279 | ## handle Override Path of Module\r |
| 280 | def _HandleOverridePath(self):\r |
| 281 | RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r |
| 282 | for Record in RecordList:\r |
| 283 | ModuleId = Record[6]\r |
| 284 | LineNo = Record[7]\r |
| 285 | ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 286 | RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r |
| 287 | if RecordList != []:\r |
| 288 | SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r |
| 289 | \r |
| 290 | # Check if the source override path exists\r |
| 291 | if not os.path.isdir(SourceOverridePath):\r |
| 292 | EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r |
| 293 | \r |
| 294 | # Add to GlobalData Variables\r |
| 295 | GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r |
| 296 | \r |
| 297 | ## Get current effective macros\r |
| 298 | def _GetMacros(self):\r |
| 299 | if self.__Macros is None:\r |
| 300 | self.__Macros = {}\r |
| 301 | self.__Macros.update(GlobalData.gPlatformDefines)\r |
| 302 | self.__Macros.update(GlobalData.gGlobalDefines)\r |
| 303 | self.__Macros.update(GlobalData.gCommandLineDefines)\r |
| 304 | return self.__Macros\r |
| 305 | \r |
| 306 | ## Get architecture\r |
| 307 | def _GetArch(self):\r |
| 308 | return self._Arch\r |
| 309 | \r |
| 310 | ## Set architecture\r |
| 311 | #\r |
| 312 | # Changing the default ARCH to another may affect all other information\r |
| 313 | # because all information in a platform may be ARCH-related. That's\r |
| 314 | # why we need to clear all internal used members, in order to cause all\r |
| 315 | # information to be re-retrieved.\r |
| 316 | #\r |
| 317 | # @param Value The value of ARCH\r |
| 318 | #\r |
| 319 | def _SetArch(self, Value):\r |
| 320 | if self._Arch == Value:\r |
| 321 | return\r |
| 322 | self._Arch = Value\r |
| 323 | self._Clear()\r |
| 324 | \r |
| 325 | ## Retrieve all information in [Defines] section\r |
| 326 | #\r |
| 327 | # (Retriving all [Defines] information in one-shot is just to save time.)\r |
| 328 | #\r |
| 329 | def _GetHeaderInfo(self):\r |
| 330 | RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r |
| 331 | for Record in RecordList:\r |
| 332 | Name = Record[1]\r |
| 333 | # items defined _PROPERTY_ don't need additional processing\r |
| 334 | \r |
| 335 | # some special items in [Defines] section need special treatment\r |
| 336 | if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r |
| 337 | self._OutputDirectory = NormPath(Record[2], self._Macros)\r |
| 338 | if ' ' in self._OutputDirectory:\r |
| 339 | EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r |
| 340 | File=self.MetaFile, Line=Record[-1],\r |
| 341 | ExtraData=self._OutputDirectory)\r |
| 342 | elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r |
| 343 | self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r |
| 344 | ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r |
| 345 | if ErrorCode != 0:\r |
| 346 | EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r |
| 347 | ExtraData=ErrorInfo)\r |
| 348 | elif Name == TAB_DSC_PREBUILD:\r |
| 349 | PrebuildValue = Record[2]\r |
| 350 | if Record[2][0] == '"':\r |
| 351 | if Record[2][-1] != '"':\r |
| 352 | EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,\r |
| 353 | File=self.MetaFile, Line=Record[-1])\r |
| 354 | PrebuildValue = Record[2][1:-1]\r |
| 355 | self._Prebuild = PrebuildValue\r |
| 356 | elif Name == TAB_DSC_POSTBUILD:\r |
| 357 | PostbuildValue = Record[2]\r |
| 358 | if Record[2][0] == '"':\r |
| 359 | if Record[2][-1] != '"':\r |
| 360 | EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,\r |
| 361 | File=self.MetaFile, Line=Record[-1])\r |
| 362 | PostbuildValue = Record[2][1:-1]\r |
| 363 | self._Postbuild = PostbuildValue\r |
| 364 | elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r |
| 365 | self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r |
| 366 | elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r |
| 367 | self._BuildTargets = GetSplitValueList(Record[2])\r |
| 368 | elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r |
| 369 | if self._SkuName is None:\r |
| 370 | self._SkuName = Record[2]\r |
| 371 | if GlobalData.gSKUID_CMD:\r |
| 372 | self._SkuName = GlobalData.gSKUID_CMD\r |
| 373 | elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r |
| 374 | self._PcdInfoFlag = Record[2]\r |
| 375 | elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r |
| 376 | self._VarCheckFlag = Record[2]\r |
| 377 | elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r |
| 378 | try:\r |
| 379 | self._LoadFixAddress = int (Record[2], 0)\r |
| 380 | except:\r |
| 381 | EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r |
| 382 | elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r |
| 383 | if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r |
| 384 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',\r |
| 385 | File=self.MetaFile, Line=Record[-1])\r |
| 386 | LanguageCodes = Record[2][1:-1]\r |
| 387 | if not LanguageCodes:\r |
| 388 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r |
| 389 | File=self.MetaFile, Line=Record[-1])\r |
| 390 | LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r |
| 391 | # check whether there is empty entries in the list\r |
| 392 | if None in LanguageList:\r |
| 393 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r |
| 394 | File=self.MetaFile, Line=Record[-1])\r |
| 395 | self._RFCLanguages = LanguageList\r |
| 396 | elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r |
| 397 | if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r |
| 398 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r |
| 399 | File=self.MetaFile, Line=Record[-1])\r |
| 400 | LanguageCodes = Record[2][1:-1]\r |
| 401 | if not LanguageCodes:\r |
| 402 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r |
| 403 | File=self.MetaFile, Line=Record[-1])\r |
| 404 | if len(LanguageCodes) % 3:\r |
| 405 | EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r |
| 406 | File=self.MetaFile, Line=Record[-1])\r |
| 407 | LanguageList = []\r |
| 408 | for i in range(0, len(LanguageCodes), 3):\r |
| 409 | LanguageList.append(LanguageCodes[i:i + 3])\r |
| 410 | self._ISOLanguages = LanguageList\r |
| 411 | elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r |
| 412 | #\r |
| 413 | # try to convert GUID to a real UUID value to see whether the GUID is format\r |
| 414 | # for VPD_TOOL_GUID is correct.\r |
| 415 | #\r |
| 416 | try:\r |
| 417 | uuid.UUID(Record[2])\r |
| 418 | except:\r |
| 419 | EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r |
| 420 | self._VpdToolGuid = Record[2]\r |
| 421 | elif Name in self:\r |
| 422 | self[Name] = Record[2]\r |
| 423 | # set _Header to non-None in order to avoid database re-querying\r |
| 424 | self._Header = 'DUMMY'\r |
| 425 | \r |
| 426 | ## Retrieve platform name\r |
| 427 | def _GetPlatformName(self):\r |
| 428 | if self._PlatformName is None:\r |
| 429 | if self._Header is None:\r |
| 430 | self._GetHeaderInfo()\r |
| 431 | if self._PlatformName is None:\r |
| 432 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)\r |
| 433 | return self._PlatformName\r |
| 434 | \r |
| 435 | ## Retrieve file guid\r |
| 436 | def _GetFileGuid(self):\r |
| 437 | if self._Guid is None:\r |
| 438 | if self._Header is None:\r |
| 439 | self._GetHeaderInfo()\r |
| 440 | if self._Guid is None:\r |
| 441 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)\r |
| 442 | return self._Guid\r |
| 443 | \r |
| 444 | ## Retrieve platform version\r |
| 445 | def _GetVersion(self):\r |
| 446 | if self._Version is None:\r |
| 447 | if self._Header is None:\r |
| 448 | self._GetHeaderInfo()\r |
| 449 | if self._Version is None:\r |
| 450 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\r |
| 451 | return self._Version\r |
| 452 | \r |
| 453 | ## Retrieve platform description file version\r |
| 454 | def _GetDscSpec(self):\r |
| 455 | if self._DscSpecification is None:\r |
| 456 | if self._Header is None:\r |
| 457 | self._GetHeaderInfo()\r |
| 458 | if self._DscSpecification is None:\r |
| 459 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)\r |
| 460 | return self._DscSpecification\r |
| 461 | \r |
| 462 | ## Retrieve OUTPUT_DIRECTORY\r |
| 463 | def _GetOutpuDir(self):\r |
| 464 | if self._OutputDirectory is None:\r |
| 465 | if self._Header is None:\r |
| 466 | self._GetHeaderInfo()\r |
| 467 | if self._OutputDirectory is None:\r |
| 468 | self._OutputDirectory = os.path.join("Build", self._PlatformName)\r |
| 469 | return self._OutputDirectory\r |
| 470 | \r |
| 471 | ## Retrieve SUPPORTED_ARCHITECTURES\r |
| 472 | def _GetSupArch(self):\r |
| 473 | if self._SupArchList is None:\r |
| 474 | if self._Header is None:\r |
| 475 | self._GetHeaderInfo()\r |
| 476 | if self._SupArchList is None:\r |
| 477 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\r |
| 478 | return self._SupArchList\r |
| 479 | \r |
| 480 | ## Retrieve BUILD_TARGETS\r |
| 481 | def _GetBuildTarget(self):\r |
| 482 | if self._BuildTargets is None:\r |
| 483 | if self._Header is None:\r |
| 484 | self._GetHeaderInfo()\r |
| 485 | if self._BuildTargets is None:\r |
| 486 | EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r |
| 487 | return self._BuildTargets\r |
| 488 | \r |
| 489 | def _GetPcdInfoFlag(self):\r |
| 490 | if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':\r |
| 491 | return False\r |
| 492 | elif self._PcdInfoFlag.upper() == 'TRUE':\r |
| 493 | return True\r |
| 494 | else:\r |
| 495 | return False\r |
| 496 | def _GetVarCheckFlag(self):\r |
| 497 | if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':\r |
| 498 | return False\r |
| 499 | elif self._VarCheckFlag.upper() == 'TRUE':\r |
| 500 | return True\r |
| 501 | else:\r |
| 502 | return False\r |
| 503 | \r |
| 504 | # # Retrieve SKUID_IDENTIFIER\r |
| 505 | def _GetSkuName(self):\r |
| 506 | if self._SkuName is None:\r |
| 507 | if self._Header is None:\r |
| 508 | self._GetHeaderInfo()\r |
| 509 | if self._SkuName is None:\r |
| 510 | self._SkuName = 'DEFAULT'\r |
| 511 | return self._SkuName\r |
| 512 | \r |
| 513 | ## Override SKUID_IDENTIFIER\r |
| 514 | def _SetSkuName(self, Value):\r |
| 515 | self._SkuName = Value\r |
| 516 | \r |
| 517 | def _GetFdfFile(self):\r |
| 518 | if self._FlashDefinition is None:\r |
| 519 | if self._Header is None:\r |
| 520 | self._GetHeaderInfo()\r |
| 521 | if self._FlashDefinition is None:\r |
| 522 | self._FlashDefinition = ''\r |
| 523 | return self._FlashDefinition\r |
| 524 | \r |
| 525 | def _GetPrebuild(self):\r |
| 526 | if self._Prebuild is None:\r |
| 527 | if self._Header is None:\r |
| 528 | self._GetHeaderInfo()\r |
| 529 | if self._Prebuild is None:\r |
| 530 | self._Prebuild = ''\r |
| 531 | return self._Prebuild\r |
| 532 | \r |
| 533 | def _GetPostbuild(self):\r |
| 534 | if self._Postbuild is None:\r |
| 535 | if self._Header is None:\r |
| 536 | self._GetHeaderInfo()\r |
| 537 | if self._Postbuild is None:\r |
| 538 | self._Postbuild = ''\r |
| 539 | return self._Postbuild\r |
| 540 | \r |
| 541 | ## Retrieve FLASH_DEFINITION\r |
| 542 | def _GetBuildNumber(self):\r |
| 543 | if self._BuildNumber is None:\r |
| 544 | if self._Header is None:\r |
| 545 | self._GetHeaderInfo()\r |
| 546 | if self._BuildNumber is None:\r |
| 547 | self._BuildNumber = ''\r |
| 548 | return self._BuildNumber\r |
| 549 | \r |
| 550 | ## Retrieve MAKEFILE_NAME\r |
| 551 | def _GetMakefileName(self):\r |
| 552 | if self._MakefileName is None:\r |
| 553 | if self._Header is None:\r |
| 554 | self._GetHeaderInfo()\r |
| 555 | if self._MakefileName is None:\r |
| 556 | self._MakefileName = ''\r |
| 557 | return self._MakefileName\r |
| 558 | \r |
| 559 | ## Retrieve BsBaseAddress\r |
| 560 | def _GetBsBaseAddress(self):\r |
| 561 | if self._BsBaseAddress is None:\r |
| 562 | if self._Header is None:\r |
| 563 | self._GetHeaderInfo()\r |
| 564 | if self._BsBaseAddress is None:\r |
| 565 | self._BsBaseAddress = ''\r |
| 566 | return self._BsBaseAddress\r |
| 567 | \r |
| 568 | ## Retrieve RtBaseAddress\r |
| 569 | def _GetRtBaseAddress(self):\r |
| 570 | if self._RtBaseAddress is None:\r |
| 571 | if self._Header is None:\r |
| 572 | self._GetHeaderInfo()\r |
| 573 | if self._RtBaseAddress is None:\r |
| 574 | self._RtBaseAddress = ''\r |
| 575 | return self._RtBaseAddress\r |
| 576 | \r |
| 577 | ## Retrieve the top address for the load fix address\r |
| 578 | def _GetLoadFixAddress(self):\r |
| 579 | if self._LoadFixAddress is None:\r |
| 580 | if self._Header is None:\r |
| 581 | self._GetHeaderInfo()\r |
| 582 | \r |
| 583 | if self._LoadFixAddress is None:\r |
| 584 | self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r |
| 585 | \r |
| 586 | try:\r |
| 587 | self._LoadFixAddress = int (self._LoadFixAddress, 0)\r |
| 588 | except:\r |
| 589 | EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r |
| 590 | \r |
| 591 | #\r |
| 592 | # If command line defined, should override the value in DSC file.\r |
| 593 | #\r |
| 594 | if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r |
| 595 | try:\r |
| 596 | self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r |
| 597 | except:\r |
| 598 | EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))\r |
| 599 | \r |
| 600 | if self._LoadFixAddress < 0:\r |
| 601 | EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r |
| 602 | if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r |
| 603 | EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r |
| 604 | \r |
| 605 | return self._LoadFixAddress\r |
| 606 | \r |
| 607 | ## Retrieve RFCLanguage filter\r |
| 608 | def _GetRFCLanguages(self):\r |
| 609 | if self._RFCLanguages is None:\r |
| 610 | if self._Header is None:\r |
| 611 | self._GetHeaderInfo()\r |
| 612 | if self._RFCLanguages is None:\r |
| 613 | self._RFCLanguages = []\r |
| 614 | return self._RFCLanguages\r |
| 615 | \r |
| 616 | ## Retrieve ISOLanguage filter\r |
| 617 | def _GetISOLanguages(self):\r |
| 618 | if self._ISOLanguages is None:\r |
| 619 | if self._Header is None:\r |
| 620 | self._GetHeaderInfo()\r |
| 621 | if self._ISOLanguages is None:\r |
| 622 | self._ISOLanguages = []\r |
| 623 | return self._ISOLanguages\r |
| 624 | ## Retrieve the GUID string for VPD tool\r |
| 625 | def _GetVpdToolGuid(self):\r |
| 626 | if self._VpdToolGuid is None:\r |
| 627 | if self._Header is None:\r |
| 628 | self._GetHeaderInfo()\r |
| 629 | if self._VpdToolGuid is None:\r |
| 630 | self._VpdToolGuid = ''\r |
| 631 | return self._VpdToolGuid\r |
| 632 | \r |
| 633 | ## Retrieve [SkuIds] section information\r |
| 634 | def _GetSkuIds(self):\r |
| 635 | if self._SkuIds is None:\r |
| 636 | self._SkuIds = OrderedDict()\r |
| 637 | RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r |
| 638 | for Record in RecordList:\r |
| 639 | if Record[0] in [None, '']:\r |
| 640 | EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r |
| 641 | File=self.MetaFile, Line=Record[-1])\r |
| 642 | if Record[1] in [None, '']:\r |
| 643 | EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r |
| 644 | File=self.MetaFile, Line=Record[-1])\r |
| 645 | Pattern = re.compile('^[1-9]\d*|0$')\r |
| 646 | HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')\r |
| 647 | if Pattern.match(Record[0]) is None and HexPattern.match(Record[0]) is None:\r |
| 648 | EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",\r |
| 649 | File=self.MetaFile, Line=Record[-1])\r |
| 650 | if not IsValidWord(Record[1]):\r |
| 651 | EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",\r |
| 652 | File=self.MetaFile, Line=Record[-1])\r |
| 653 | self._SkuIds[Record[1].upper()] = (str(self.ToInt(Record[0])), Record[1].upper(), Record[2].upper())\r |
| 654 | if 'DEFAULT' not in self._SkuIds:\r |
| 655 | self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")\r |
| 656 | if 'COMMON' not in self._SkuIds:\r |
| 657 | self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")\r |
| 658 | return self._SkuIds\r |
| 659 | def ToInt(self,intstr):\r |
| 660 | return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr)\r |
| 661 | def _GetDefaultStores(self):\r |
| 662 | if self.DefaultStores is None:\r |
| 663 | self.DefaultStores = OrderedDict()\r |
| 664 | RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]\r |
| 665 | for Record in RecordList:\r |
| 666 | if Record[0] in [None, '']:\r |
| 667 | EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',\r |
| 668 | File=self.MetaFile, Line=Record[-1])\r |
| 669 | if Record[1] in [None, '']:\r |
| 670 | EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',\r |
| 671 | File=self.MetaFile, Line=Record[-1])\r |
| 672 | Pattern = re.compile('^[1-9]\d*|0$')\r |
| 673 | HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')\r |
| 674 | if Pattern.match(Record[0]) is None and HexPattern.match(Record[0]) is None:\r |
| 675 | EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",\r |
| 676 | File=self.MetaFile, Line=Record[-1])\r |
| 677 | if not IsValidWord(Record[1]):\r |
| 678 | EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",\r |
| 679 | File=self.MetaFile, Line=Record[-1])\r |
| 680 | self.DefaultStores[Record[1].upper()] = (self.ToInt(Record[0]),Record[1].upper())\r |
| 681 | if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:\r |
| 682 | self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT)\r |
| 683 | GlobalData.gDefaultStores = self.DefaultStores.keys()\r |
| 684 | if GlobalData.gDefaultStores:\r |
| 685 | GlobalData.gDefaultStores.sort()\r |
| 686 | return self.DefaultStores\r |
| 687 | \r |
| 688 | ## Retrieve [Components] section information\r |
| 689 | def _GetModules(self):\r |
| 690 | if self._Modules is not None:\r |
| 691 | return self._Modules\r |
| 692 | \r |
| 693 | self._Modules = OrderedDict()\r |
| 694 | RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r |
| 695 | Macros = self._Macros\r |
| 696 | Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r |
| 697 | for Record in RecordList:\r |
| 698 | DuplicatedFile = False\r |
| 699 | \r |
| 700 | ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 701 | ModuleId = Record[6]\r |
| 702 | LineNo = Record[7]\r |
| 703 | \r |
| 704 | # check the file validation\r |
| 705 | ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r |
| 706 | if ErrorCode != 0:\r |
| 707 | EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r |
| 708 | ExtraData=ErrorInfo)\r |
| 709 | # Check duplication\r |
| 710 | # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r |
| 711 | if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r |
| 712 | DuplicatedFile = True\r |
| 713 | \r |
| 714 | Module = ModuleBuildClassObject()\r |
| 715 | Module.MetaFile = ModuleFile\r |
| 716 | \r |
| 717 | # get module private library instance\r |
| 718 | RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r |
| 719 | for Record in RecordList:\r |
| 720 | LibraryClass = Record[0]\r |
| 721 | LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 722 | LineNo = Record[-1]\r |
| 723 | \r |
| 724 | # check the file validation\r |
| 725 | ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r |
| 726 | if ErrorCode != 0:\r |
| 727 | EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r |
| 728 | ExtraData=ErrorInfo)\r |
| 729 | \r |
| 730 | if LibraryClass == '' or LibraryClass == 'NULL':\r |
| 731 | self._NullLibraryNumber += 1\r |
| 732 | LibraryClass = 'NULL%d' % self._NullLibraryNumber\r |
| 733 | EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r |
| 734 | Module.LibraryClasses[LibraryClass] = LibraryPath\r |
| 735 | if LibraryPath not in self.LibraryInstances:\r |
| 736 | self.LibraryInstances.append(LibraryPath)\r |
| 737 | \r |
| 738 | # get module private PCD setting\r |
| 739 | for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r |
| 740 | MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r |
| 741 | RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r |
| 742 | for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 743 | TokenList = GetSplitValueList(Setting)\r |
| 744 | DefaultValue = TokenList[0]\r |
| 745 | # the format is PcdName| Value | VOID* | MaxDatumSize\r |
| 746 | if len(TokenList) > 2:\r |
| 747 | MaxDatumSize = TokenList[2]\r |
| 748 | else:\r |
| 749 | MaxDatumSize = ''\r |
| 750 | TypeString = self._PCD_TYPE_STRING_[Type]\r |
| 751 | Pcd = PcdClassObject(\r |
| 752 | PcdCName,\r |
| 753 | TokenSpaceGuid,\r |
| 754 | TypeString,\r |
| 755 | '',\r |
| 756 | DefaultValue,\r |
| 757 | '',\r |
| 758 | MaxDatumSize,\r |
| 759 | {},\r |
| 760 | False,\r |
| 761 | None\r |
| 762 | )\r |
| 763 | Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r |
| 764 | \r |
| 765 | # get module private build options\r |
| 766 | RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r |
| 767 | for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 768 | if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r |
| 769 | Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r |
| 770 | else:\r |
| 771 | OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r |
| 772 | Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r |
| 773 | \r |
| 774 | RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r |
| 775 | if DuplicatedFile and not RecordList:\r |
| 776 | EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r |
| 777 | if RecordList:\r |
| 778 | if len(RecordList) != 1:\r |
| 779 | EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r |
| 780 | File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r |
| 781 | ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r |
| 782 | ModuleFile.Arch = self._Arch\r |
| 783 | \r |
| 784 | self._Modules[ModuleFile] = Module\r |
| 785 | return self._Modules\r |
| 786 | \r |
| 787 | ## Retrieve all possible library instances used in this platform\r |
| 788 | def _GetLibraryInstances(self):\r |
| 789 | if self._LibraryInstances is None:\r |
| 790 | self._GetLibraryClasses()\r |
| 791 | return self._LibraryInstances\r |
| 792 | \r |
| 793 | ## Retrieve [LibraryClasses] information\r |
| 794 | def _GetLibraryClasses(self):\r |
| 795 | if self._LibraryClasses is None:\r |
| 796 | self._LibraryInstances = []\r |
| 797 | #\r |
| 798 | # tdict is a special dict kind of type, used for selecting correct\r |
| 799 | # library instance for given library class and module type\r |
| 800 | #\r |
| 801 | LibraryClassDict = tdict(True, 3)\r |
| 802 | # track all library class names\r |
| 803 | LibraryClassSet = set()\r |
| 804 | RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r |
| 805 | Macros = self._Macros\r |
| 806 | for Record in RecordList:\r |
| 807 | LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record\r |
| 808 | if LibraryClass == '' or LibraryClass == 'NULL':\r |
| 809 | self._NullLibraryNumber += 1\r |
| 810 | LibraryClass = 'NULL%d' % self._NullLibraryNumber\r |
| 811 | EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r |
| 812 | LibraryClassSet.add(LibraryClass)\r |
| 813 | LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 814 | # check the file validation\r |
| 815 | ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r |
| 816 | if ErrorCode != 0:\r |
| 817 | EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r |
| 818 | ExtraData=ErrorInfo)\r |
| 819 | \r |
| 820 | if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r |
| 821 | EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r |
| 822 | File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r |
| 823 | LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r |
| 824 | if LibraryInstance not in self._LibraryInstances:\r |
| 825 | self._LibraryInstances.append(LibraryInstance)\r |
| 826 | \r |
| 827 | # resolve the specific library instance for each class and each module type\r |
| 828 | self._LibraryClasses = tdict(True)\r |
| 829 | for LibraryClass in LibraryClassSet:\r |
| 830 | # try all possible module types\r |
| 831 | for ModuleType in SUP_MODULE_LIST:\r |
| 832 | LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r |
| 833 | if LibraryInstance is None:\r |
| 834 | continue\r |
| 835 | self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r |
| 836 | \r |
| 837 | # for Edk style library instances, which are listed in different section\r |
| 838 | Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r |
| 839 | RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r |
| 840 | for Record in RecordList:\r |
| 841 | File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 842 | LineNo = Record[-1]\r |
| 843 | # check the file validation\r |
| 844 | ErrorCode, ErrorInfo = File.Validate('.inf')\r |
| 845 | if ErrorCode != 0:\r |
| 846 | EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r |
| 847 | ExtraData=ErrorInfo)\r |
| 848 | if File not in self._LibraryInstances:\r |
| 849 | self._LibraryInstances.append(File)\r |
| 850 | #\r |
| 851 | # we need the module name as the library class name, so we have\r |
| 852 | # to parse it here. (self._Bdb[] will trigger a file parse if it\r |
| 853 | # hasn't been parsed)\r |
| 854 | #\r |
| 855 | Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r |
| 856 | self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r |
| 857 | return self._LibraryClasses\r |
| 858 | \r |
| 859 | def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r |
| 860 | if self._DecPcds is None:\r |
| 861 | \r |
| 862 | FdfInfList = []\r |
| 863 | if GlobalData.gFdfParser:\r |
| 864 | FdfInfList = GlobalData.gFdfParser.Profile.InfList\r |
| 865 | \r |
| 866 | PkgSet = set()\r |
| 867 | for Inf in FdfInfList:\r |
| 868 | ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 869 | if ModuleFile in self._Modules:\r |
| 870 | continue\r |
| 871 | ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r |
| 872 | PkgSet.update(ModuleData.Packages)\r |
| 873 | \r |
| 874 | self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r |
| 875 | self._GuidDict.update(GlobalData.gPlatformPcds)\r |
| 876 | \r |
| 877 | if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r |
| 878 | EdkLogger.error('build', PARSER_ERROR,\r |
| 879 | "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r |
| 880 | File=self.MetaFile, Line=LineNo)\r |
| 881 | ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r |
| 882 | if not IsValid:\r |
| 883 | if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r |
| 884 | EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r |
| 885 | ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r |
| 886 | else:\r |
| 887 | if ValueList[2] == '-1':\r |
| 888 | EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r |
| 889 | ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r |
| 890 | if ValueList[Index]:\r |
| 891 | DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType\r |
| 892 | try:\r |
| 893 | ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)\r |
| 894 | except BadExpression, Value:\r |
| 895 | EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,\r |
| 896 | ExtraData="PCD [%s.%s] Value \"%s\" " % (\r |
| 897 | TokenSpaceGuid, PcdCName, ValueList[Index]))\r |
| 898 | except EvaluationException, Excpt:\r |
| 899 | if hasattr(Excpt, 'Pcd'):\r |
| 900 | if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r |
| 901 | EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r |
| 902 | " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r |
| 903 | " of the DSC file" % Excpt.Pcd,\r |
| 904 | File=self.MetaFile, Line=LineNo)\r |
| 905 | else:\r |
| 906 | EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r |
| 907 | File=self.MetaFile, Line=LineNo)\r |
| 908 | else:\r |
| 909 | EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r |
| 910 | File=self.MetaFile, Line=LineNo)\r |
| 911 | \r |
| 912 | if ValueList[Index]:\r |
| 913 | Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r |
| 914 | if not Valid:\r |
| 915 | EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r |
| 916 | ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r |
| 917 | if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r |
| 918 | if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():\r |
| 919 | EdkLogger.error('build', FORMAT_INVALID, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file." , File=self.MetaFile, Line=LineNo,\r |
| 920 | ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r |
| 921 | if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:\r |
| 922 | if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:\r |
| 923 | GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]\r |
| 924 | return ValueList\r |
| 925 | \r |
| 926 | def _FilterPcdBySkuUsage(self,Pcds):\r |
| 927 | available_sku = self.SkuIdMgr.AvailableSkuIdSet\r |
| 928 | sku_usage = self.SkuIdMgr.SkuUsageType\r |
| 929 | if sku_usage == SkuClass.SINGLE:\r |
| 930 | for pcdname in Pcds:\r |
| 931 | pcd = Pcds[pcdname]\r |
| 932 | Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r |
| 933 | if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r |
| 934 | Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r |
| 935 | else:\r |
| 936 | for pcdname in Pcds:\r |
| 937 | pcd = Pcds[pcdname]\r |
| 938 | Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r |
| 939 | if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r |
| 940 | Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r |
| 941 | return Pcds\r |
| 942 | def CompleteHiiPcdsDefaultStores(self,Pcds):\r |
| 943 | HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]\r |
| 944 | DefaultStoreMgr = DefaultStore(self.DefaultStores)\r |
| 945 | for pcd in HiiPcd:\r |
| 946 | for skuid in pcd.SkuInfoList:\r |
| 947 | skuobj = pcd.SkuInfoList.get(skuid)\r |
| 948 | if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:\r |
| 949 | PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])\r |
| 950 | mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r |
| 951 | skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r |
| 952 | return Pcds\r |
| 953 | \r |
| 954 | def RecoverCommandLinePcd(self):\r |
| 955 | def UpdateCommandLineValue(pcd):\r |
| 956 | if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 957 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 958 | pcd.PcdValueFromComm = pcd.DefaultValue\r |
| 959 | elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 960 | pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").HiiDefaultValue\r |
| 961 | else:\r |
| 962 | pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").DefaultValue\r |
| 963 | for pcd in self._Pcds:\r |
| 964 | if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):\r |
| 965 | UpdateCommandLineValue(self._Pcds[pcd])\r |
| 966 | \r |
| 967 | def __ParsePcdFromCommandLine(self):\r |
| 968 | if GlobalData.BuildOptionPcd:\r |
| 969 | for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r |
| 970 | if type(pcd) is tuple:\r |
| 971 | continue\r |
| 972 | (pcdname, pcdvalue) = pcd.split('=')\r |
| 973 | if not pcdvalue:\r |
| 974 | EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))\r |
| 975 | if '.' in pcdname:\r |
| 976 | (Name1, Name2) = pcdname.split('.',1)\r |
| 977 | if "." in Name2:\r |
| 978 | (Name3, FieldName) = Name2.split(".",1)\r |
| 979 | if ((Name3,Name1)) in self.DecPcds:\r |
| 980 | HasTokenSpace = True\r |
| 981 | TokenCName = Name3\r |
| 982 | TokenSpaceGuidCName = Name1\r |
| 983 | else:\r |
| 984 | FieldName = Name2\r |
| 985 | TokenCName = Name1\r |
| 986 | TokenSpaceGuidCName = ''\r |
| 987 | HasTokenSpace = False\r |
| 988 | else:\r |
| 989 | if ((Name2,Name1)) in self.DecPcds:\r |
| 990 | HasTokenSpace = True\r |
| 991 | TokenCName = Name2\r |
| 992 | TokenSpaceGuidCName = Name1\r |
| 993 | FieldName =""\r |
| 994 | else:\r |
| 995 | FieldName = Name2\r |
| 996 | TokenCName = Name1\r |
| 997 | TokenSpaceGuidCName = ''\r |
| 998 | HasTokenSpace = False\r |
| 999 | else:\r |
| 1000 | FieldName = ""\r |
| 1001 | TokenCName = pcdname\r |
| 1002 | TokenSpaceGuidCName = ''\r |
| 1003 | HasTokenSpace = False\r |
| 1004 | TokenSpaceGuidCNameList = []\r |
| 1005 | FoundFlag = False\r |
| 1006 | PcdDatumType = ''\r |
| 1007 | DisplayName = TokenCName\r |
| 1008 | if FieldName:\r |
| 1009 | DisplayName = TokenCName + '.' + FieldName\r |
| 1010 | if not HasTokenSpace:\r |
| 1011 | for key in self.DecPcds:\r |
| 1012 | PcdItem = self.DecPcds[key]\r |
| 1013 | if TokenCName == PcdItem.TokenCName:\r |
| 1014 | if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r |
| 1015 | if len (TokenSpaceGuidCNameList) < 1:\r |
| 1016 | TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r |
| 1017 | TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r |
| 1018 | PcdDatumType = PcdItem.DatumType\r |
| 1019 | FoundFlag = True\r |
| 1020 | else:\r |
| 1021 | EdkLogger.error(\r |
| 1022 | 'build',\r |
| 1023 | AUTOGEN_ERROR,\r |
| 1024 | "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r |
| 1025 | )\r |
| 1026 | else:\r |
| 1027 | if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:\r |
| 1028 | PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType\r |
| 1029 | FoundFlag = True\r |
| 1030 | if not FoundFlag:\r |
| 1031 | if HasTokenSpace:\r |
| 1032 | EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))\r |
| 1033 | else:\r |
| 1034 | EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))\r |
| 1035 | pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")\r |
| 1036 | if FieldName:\r |
| 1037 | pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)\r |
| 1038 | else:\r |
| 1039 | pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)\r |
| 1040 | IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)\r |
| 1041 | if not IsValid:\r |
| 1042 | EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r |
| 1043 | GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue,("build command options",1))\r |
| 1044 | \r |
| 1045 | for BuildData in self._Bdb._CACHE_.values():\r |
| 1046 | if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':\r |
| 1047 | continue\r |
| 1048 | for key in BuildData.Pcds:\r |
| 1049 | PcdItem = BuildData.Pcds[key]\r |
| 1050 | if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":\r |
| 1051 | PcdItem.DefaultValue = pcdvalue\r |
| 1052 | \r |
| 1053 | def HandleFlexiblePcd(self, TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):\r |
| 1054 | if FieldName:\r |
| 1055 | IsArray = False\r |
| 1056 | TokenCName += '.' + FieldName\r |
| 1057 | if PcdValue.startswith('H'):\r |
| 1058 | if FieldName and IsFieldValueAnArray(PcdValue[1:]):\r |
| 1059 | PcdDatumType = 'VOID*'\r |
| 1060 | IsArray = True\r |
| 1061 | if FieldName and not IsArray:\r |
| 1062 | return PcdValue\r |
| 1063 | try:\r |
| 1064 | PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)\r |
| 1065 | except BadExpression, Value: \r |
| 1066 | EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r |
| 1067 | (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r |
| 1068 | elif PcdValue.startswith("L'") or PcdValue.startswith("'"):\r |
| 1069 | if FieldName and IsFieldValueAnArray(PcdValue):\r |
| 1070 | PcdDatumType = 'VOID*'\r |
| 1071 | IsArray = True\r |
| 1072 | if FieldName and not IsArray:\r |
| 1073 | return PcdValue\r |
| 1074 | try:\r |
| 1075 | PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r |
| 1076 | except BadExpression, Value:\r |
| 1077 | EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r |
| 1078 | (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r |
| 1079 | elif PcdValue.startswith('L'):\r |
| 1080 | PcdValue = 'L"' + PcdValue[1:] + '"'\r |
| 1081 | if FieldName and IsFieldValueAnArray(PcdValue):\r |
| 1082 | PcdDatumType = 'VOID*'\r |
| 1083 | IsArray = True\r |
| 1084 | if FieldName and not IsArray:\r |
| 1085 | return PcdValue\r |
| 1086 | try:\r |
| 1087 | PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r |
| 1088 | except BadExpression, Value:\r |
| 1089 | EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r |
| 1090 | (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r |
| 1091 | else:\r |
| 1092 | if PcdValue.upper() == 'FALSE':\r |
| 1093 | PcdValue = str(0)\r |
| 1094 | if PcdValue.upper() == 'TRUE':\r |
| 1095 | PcdValue = str(1)\r |
| 1096 | if not FieldName:\r |
| 1097 | if PcdDatumType not in ['UINT8','UINT16','UINT32','UINT64','BOOLEAN']:\r |
| 1098 | PcdValue = '"' + PcdValue + '"'\r |
| 1099 | else:\r |
| 1100 | IsArray = False\r |
| 1101 | Base = 10\r |
| 1102 | if PcdValue.upper().startswith('0X'):\r |
| 1103 | Base = 16\r |
| 1104 | try:\r |
| 1105 | Num = int(PcdValue, Base)\r |
| 1106 | except:\r |
| 1107 | PcdValue = '"' + PcdValue + '"'\r |
| 1108 | if IsFieldValueAnArray(PcdValue):\r |
| 1109 | PcdDatumType = 'VOID*'\r |
| 1110 | IsArray = True\r |
| 1111 | if not IsArray:\r |
| 1112 | return PcdValue\r |
| 1113 | try:\r |
| 1114 | PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r |
| 1115 | except BadExpression, Value:\r |
| 1116 | EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r |
| 1117 | (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r |
| 1118 | return PcdValue\r |
| 1119 | \r |
| 1120 | ## Retrieve all PCD settings in platform\r |
| 1121 | def _GetPcds(self):\r |
| 1122 | if self._Pcds is None:\r |
| 1123 | self._Pcds = OrderedDict()\r |
| 1124 | self.__ParsePcdFromCommandLine()\r |
| 1125 | self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r |
| 1126 | self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r |
| 1127 | self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r |
| 1128 | self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r |
| 1129 | self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r |
| 1130 | self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r |
| 1131 | self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r |
| 1132 | self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r |
| 1133 | self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r |
| 1134 | \r |
| 1135 | self._Pcds = self.CompletePcdValues(self._Pcds)\r |
| 1136 | self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)\r |
| 1137 | self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r |
| 1138 | self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r |
| 1139 | self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r |
| 1140 | \r |
| 1141 | self.RecoverCommandLinePcd()\r |
| 1142 | return self._Pcds\r |
| 1143 | \r |
| 1144 | def _dumpPcdInfo(self,Pcds):\r |
| 1145 | for pcd in Pcds:\r |
| 1146 | pcdobj = Pcds[pcd]\r |
| 1147 | if not pcdobj.TokenCName.startswith("Test"):\r |
| 1148 | continue\r |
| 1149 | for skuid in pcdobj.SkuInfoList:\r |
| 1150 | if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r |
| 1151 | for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r |
| 1152 | print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r |
| 1153 | else:\r |
| 1154 | print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r |
| 1155 | ## Retrieve [BuildOptions]\r |
| 1156 | def _GetBuildOptions(self):\r |
| 1157 | if self._BuildOptions is None:\r |
| 1158 | self._BuildOptions = OrderedDict()\r |
| 1159 | #\r |
| 1160 | # Retrieve build option for EDKII and EDK style module\r |
| 1161 | #\r |
| 1162 | for CodeBase in (EDKII_NAME, EDK_NAME):\r |
| 1163 | RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r |
| 1164 | for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 1165 | if Dummy3.upper() != 'COMMON':\r |
| 1166 | continue\r |
| 1167 | CurKey = (ToolChainFamily, ToolChain, CodeBase)\r |
| 1168 | #\r |
| 1169 | # Only flags can be appended\r |
| 1170 | #\r |
| 1171 | if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r |
| 1172 | self._BuildOptions[CurKey] = Option\r |
| 1173 | else:\r |
| 1174 | if ' ' + Option not in self._BuildOptions[CurKey]:\r |
| 1175 | self._BuildOptions[CurKey] += ' ' + Option\r |
| 1176 | return self._BuildOptions\r |
| 1177 | \r |
| 1178 | def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r |
| 1179 | if self._ModuleTypeOptions is None:\r |
| 1180 | self._ModuleTypeOptions = OrderedDict()\r |
| 1181 | if (Edk, ModuleType) not in self._ModuleTypeOptions:\r |
| 1182 | options = OrderedDict()\r |
| 1183 | self._ModuleTypeOptions[Edk, ModuleType] = options\r |
| 1184 | DriverType = '%s.%s' % (Edk, ModuleType)\r |
| 1185 | CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r |
| 1186 | RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]\r |
| 1187 | for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 1188 | Type = Dummy2 + '.' + Dummy3\r |
| 1189 | if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():\r |
| 1190 | Key = (ToolChainFamily, ToolChain, Edk)\r |
| 1191 | if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r |
| 1192 | options[Key] = Option\r |
| 1193 | else:\r |
| 1194 | if ' ' + Option not in options[Key]:\r |
| 1195 | options[Key] += ' ' + Option\r |
| 1196 | return self._ModuleTypeOptions[Edk, ModuleType]\r |
| 1197 | \r |
| 1198 | def GetStructurePcdInfo(self, PcdSet):\r |
| 1199 | structure_pcd_data = {}\r |
| 1200 | for item in PcdSet:\r |
| 1201 | if (item[0],item[1]) not in structure_pcd_data:\r |
| 1202 | structure_pcd_data[(item[0],item[1])] = []\r |
| 1203 | structure_pcd_data[(item[0],item[1])].append(item)\r |
| 1204 | \r |
| 1205 | return structure_pcd_data\r |
| 1206 | def OverrideByFdfComm(self,StruPcds):\r |
| 1207 | StructurePcdInCom = OrderedDict()\r |
| 1208 | for item in GlobalData.BuildOptionPcd:\r |
| 1209 | if len(item) == 5 and (item[1],item[0]) in StruPcds:\r |
| 1210 | StructurePcdInCom[(item[0],item[1],item[2] )] = (item[3],item[4])\r |
| 1211 | GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])\r |
| 1212 | for Pcd in StruPcds.values():\r |
| 1213 | if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:\r |
| 1214 | continue\r |
| 1215 | FieldValues = OrderedDict()\r |
| 1216 | for item in StructurePcdInCom:\r |
| 1217 | if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:\r |
| 1218 | FieldValues[item[2]] = StructurePcdInCom[item]\r |
| 1219 | for field in FieldValues:\r |
| 1220 | if field not in Pcd.PcdFieldValueFromComm:\r |
| 1221 | Pcd.PcdFieldValueFromComm[field] = ["","",""]\r |
| 1222 | Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]\r |
| 1223 | Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]\r |
| 1224 | Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]\r |
| 1225 | return StruPcds\r |
| 1226 | def OverrideByFdfCommOverAll(self,AllPcds):\r |
| 1227 | def CheckStructureInComm(commpcds):\r |
| 1228 | if not commpcds:\r |
| 1229 | return False\r |
| 1230 | if len(commpcds[0]) == 5:\r |
| 1231 | return True\r |
| 1232 | return False\r |
| 1233 | \r |
| 1234 | if CheckStructureInComm(GlobalData.BuildOptionPcd):\r |
| 1235 | StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}\r |
| 1236 | NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}\r |
| 1237 | else:\r |
| 1238 | NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}\r |
| 1239 | for Guid,Name in NoFiledValues:\r |
| 1240 | if (Name,Guid) in AllPcds:\r |
| 1241 | Pcd = AllPcds.get((Name,Guid))\r |
| 1242 | if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):\r |
| 1243 | self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1244 | else:\r |
| 1245 | Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1246 | Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1247 | for sku in Pcd.SkuInfoList:\r |
| 1248 | SkuInfo = Pcd.SkuInfoList[sku]\r |
| 1249 | if SkuInfo.DefaultValue:\r |
| 1250 | SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1251 | else:\r |
| 1252 | SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1253 | for defaultstore in SkuInfo.DefaultStoreDict:\r |
| 1254 | SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r |
| 1255 | if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:\r |
| 1256 | if Pcd.DatumType == "VOID*":\r |
| 1257 | if not Pcd.MaxDatumSize:\r |
| 1258 | Pcd.MaxDatumSize = '0'\r |
| 1259 | CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)\r |
| 1260 | OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))\r |
| 1261 | MaxSize = max(CurrentSize, OptionSize)\r |
| 1262 | Pcd.MaxDatumSize = str(MaxSize)\r |
| 1263 | else:\r |
| 1264 | PcdInDec = self.DecPcds.get((Name,Guid))\r |
| 1265 | if PcdInDec:\r |
| 1266 | PcdInDec.PcdValueFromComm = NoFiledValues[(Guid,Name)][0]\r |
| 1267 | if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 1268 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],\r |
| 1269 | self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:\r |
| 1270 | self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)\r |
| 1271 | self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]\r |
| 1272 | return AllPcds\r |
| 1273 | def UpdateStructuredPcds(self, TypeList, AllPcds):\r |
| 1274 | \r |
| 1275 | DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r |
| 1276 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r |
| 1277 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r |
| 1278 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r |
| 1279 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r |
| 1280 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]\r |
| 1281 | \r |
| 1282 | Pcds = AllPcds\r |
| 1283 | DefaultStoreMgr = DefaultStore(self.DefaultStores)\r |
| 1284 | SkuIds = self.SkuIdMgr.AvailableSkuIdSet\r |
| 1285 | SkuIds.update({'DEFAULT':0})\r |
| 1286 | DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r |
| 1287 | \r |
| 1288 | S_PcdSet = []\r |
| 1289 | # Find out all possible PCD candidates for self._Arch\r |
| 1290 | RecordList = []\r |
| 1291 | \r |
| 1292 | for Type in TypeList:\r |
| 1293 | RecordList.extend(self._RawData[Type, self._Arch])\r |
| 1294 | \r |
| 1295 | for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r |
| 1296 | SkuName = SkuName.upper()\r |
| 1297 | default_store = default_store.upper()\r |
| 1298 | SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r |
| 1299 | if SkuName not in SkuIds:\r |
| 1300 | continue\r |
| 1301 | \r |
| 1302 | if SkuName in SkuIds and "." in TokenSpaceGuid:\r |
| 1303 | S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]])\r |
| 1304 | \r |
| 1305 | # handle pcd value override\r |
| 1306 | StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r |
| 1307 | S_pcd_set = OrderedDict()\r |
| 1308 | for str_pcd in StrPcdSet:\r |
| 1309 | str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r |
| 1310 | str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r |
| 1311 | if not isinstance (str_pcd_dec, StructurePcd):\r |
| 1312 | EdkLogger.error('build', PARSER_ERROR,\r |
| 1313 | "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r |
| 1314 | File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r |
| 1315 | if str_pcd_dec:\r |
| 1316 | str_pcd_obj_str = StructurePcd()\r |
| 1317 | str_pcd_obj_str.copy(str_pcd_dec)\r |
| 1318 | if str_pcd_obj:\r |
| 1319 | str_pcd_obj_str.copy(str_pcd_obj)\r |
| 1320 | if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 1321 | str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r |
| 1322 | else:\r |
| 1323 | 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}\r |
| 1324 | for str_pcd_data in StrPcdSet[str_pcd]:\r |
| 1325 | if str_pcd_data[3] in SkuIds:\r |
| 1326 | str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], 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[5])\r |
| 1327 | S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r |
| 1328 | else:\r |
| 1329 | EdkLogger.error('build', PARSER_ERROR,\r |
| 1330 | "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r |
| 1331 | File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r |
| 1332 | # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r |
| 1333 | for Pcd in self.DecPcds:\r |
| 1334 | if type (self._DecPcds[Pcd]) is StructurePcd:\r |
| 1335 | if Pcd not in S_pcd_set:\r |
| 1336 | str_pcd_obj_str = StructurePcd()\r |
| 1337 | str_pcd_obj_str.copy(self._DecPcds[Pcd])\r |
| 1338 | str_pcd_obj = Pcds.get(Pcd, None)\r |
| 1339 | if str_pcd_obj:\r |
| 1340 | str_pcd_obj_str.copy(str_pcd_obj)\r |
| 1341 | if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 1342 | str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r |
| 1343 | else:\r |
| 1344 | 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}\r |
| 1345 | S_pcd_set[Pcd] = str_pcd_obj_str\r |
| 1346 | if S_pcd_set:\r |
| 1347 | GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r |
| 1348 | for stru_pcd in S_pcd_set.values():\r |
| 1349 | for skuid in SkuIds:\r |
| 1350 | if skuid in stru_pcd.SkuOverrideValues:\r |
| 1351 | continue\r |
| 1352 | nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r |
| 1353 | NoDefault = False\r |
| 1354 | if skuid not in stru_pcd.SkuOverrideValues:\r |
| 1355 | while nextskuid not in stru_pcd.SkuOverrideValues:\r |
| 1356 | if nextskuid == "DEFAULT":\r |
| 1357 | NoDefault = True\r |
| 1358 | break\r |
| 1359 | nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r |
| 1360 | stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})\r |
| 1361 | if not NoDefault:\r |
| 1362 | stru_pcd.ValueChain[(skuid,'')]= (nextskuid,'')\r |
| 1363 | if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 1364 | for skuid in SkuIds:\r |
| 1365 | nextskuid = skuid\r |
| 1366 | NoDefault = False\r |
| 1367 | if skuid not in stru_pcd.SkuOverrideValues:\r |
| 1368 | while nextskuid not in stru_pcd.SkuOverrideValues:\r |
| 1369 | if nextskuid == "DEFAULT":\r |
| 1370 | NoDefault = True\r |
| 1371 | break\r |
| 1372 | nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r |
| 1373 | if NoDefault:\r |
| 1374 | continue\r |
| 1375 | PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])\r |
| 1376 | mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r |
| 1377 | \r |
| 1378 | for defaultstoreid in DefaultStores:\r |
| 1379 | if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r |
| 1380 | stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r |
| 1381 | stru_pcd.ValueChain[(skuid,defaultstoreid)]= (nextskuid,mindefaultstorename)\r |
| 1382 | S_pcd_set = self.OverrideByFdfComm(S_pcd_set)\r |
| 1383 | Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r |
| 1384 | if Str_Pcd_Values:\r |
| 1385 | for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r |
| 1386 | str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r |
| 1387 | if str_pcd_obj is None:\r |
| 1388 | print PcdName, PcdGuid\r |
| 1389 | raise\r |
| 1390 | if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r |
| 1391 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 1392 | if skuname not in str_pcd_obj.SkuInfoList:\r |
| 1393 | str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r |
| 1394 | else:\r |
| 1395 | str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r |
| 1396 | str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r |
| 1397 | elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 1398 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 1399 | if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r |
| 1400 | str_pcd_obj.DefaultValue = PcdValue\r |
| 1401 | else:\r |
| 1402 | if skuname not in str_pcd_obj.SkuInfoList:\r |
| 1403 | nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r |
| 1404 | NoDefault = False\r |
| 1405 | while nextskuid not in str_pcd_obj.SkuInfoList:\r |
| 1406 | if nextskuid == "DEFAULT":\r |
| 1407 | NoDefault = True\r |
| 1408 | break\r |
| 1409 | nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r |
| 1410 | str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)\r |
| 1411 | str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]\r |
| 1412 | str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname\r |
| 1413 | else:\r |
| 1414 | str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r |
| 1415 | for str_pcd_obj in S_pcd_set.values():\r |
| 1416 | if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r |
| 1417 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 1418 | continue\r |
| 1419 | PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r |
| 1420 | DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r |
| 1421 | mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r |
| 1422 | str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r |
| 1423 | \r |
| 1424 | for str_pcd_obj in S_pcd_set.values():\r |
| 1425 | \r |
| 1426 | str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r |
| 1427 | Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r |
| 1428 | \r |
| 1429 | for pcdkey in Pcds:\r |
| 1430 | pcd = Pcds[pcdkey]\r |
| 1431 | if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 1432 | pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r |
| 1433 | del(pcd.SkuInfoList['COMMON'])\r |
| 1434 | elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 1435 | del(pcd.SkuInfoList['COMMON'])\r |
| 1436 | \r |
| 1437 | map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])\r |
| 1438 | return Pcds\r |
| 1439 | \r |
| 1440 | ## Retrieve non-dynamic PCD settings\r |
| 1441 | #\r |
| 1442 | # @param Type PCD type\r |
| 1443 | #\r |
| 1444 | # @retval a dict object contains settings of given PCD type\r |
| 1445 | #\r |
| 1446 | def _GetPcd(self, Type):\r |
| 1447 | Pcds = OrderedDict()\r |
| 1448 | #\r |
| 1449 | # tdict is a special dict kind of type, used for selecting correct\r |
| 1450 | # PCD settings for certain ARCH\r |
| 1451 | #\r |
| 1452 | AvailableSkuIdSet = copy.copy(self.SkuIds)\r |
| 1453 | \r |
| 1454 | PcdDict = tdict(True, 3)\r |
| 1455 | PcdSet = set()\r |
| 1456 | # Find out all possible PCD candidates for self._Arch\r |
| 1457 | RecordList = self._RawData[Type, self._Arch]\r |
| 1458 | PcdValueDict = OrderedDict()\r |
| 1459 | for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 1460 | SkuName = SkuName.upper()\r |
| 1461 | SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r |
| 1462 | if SkuName not in AvailableSkuIdSet:\r |
| 1463 | EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r |
| 1464 | File=self.MetaFile, Line=Dummy5)\r |
| 1465 | if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r |
| 1466 | if "." not in TokenSpaceGuid:\r |
| 1467 | PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r |
| 1468 | PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r |
| 1469 | \r |
| 1470 | for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r |
| 1471 | Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r |
| 1472 | if Setting is None:\r |
| 1473 | continue\r |
| 1474 | PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r |
| 1475 | if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r |
| 1476 | PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r |
| 1477 | else:\r |
| 1478 | PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r |
| 1479 | \r |
| 1480 | PcdsKeys = PcdValueDict.keys()\r |
| 1481 | for PcdCName, TokenSpaceGuid in PcdsKeys:\r |
| 1482 | \r |
| 1483 | PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r |
| 1484 | PcdValue = None\r |
| 1485 | DatumType = None\r |
| 1486 | MaxDatumSize = None\r |
| 1487 | if 'COMMON' in PcdSetting:\r |
| 1488 | PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r |
| 1489 | if 'DEFAULT' in PcdSetting:\r |
| 1490 | PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r |
| 1491 | if self.SkuIdMgr.SystemSkuId in PcdSetting:\r |
| 1492 | PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r |
| 1493 | \r |
| 1494 | Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r |
| 1495 | PcdCName,\r |
| 1496 | TokenSpaceGuid,\r |
| 1497 | self._PCD_TYPE_STRING_[Type],\r |
| 1498 | DatumType,\r |
| 1499 | PcdValue,\r |
| 1500 | '',\r |
| 1501 | MaxDatumSize,\r |
| 1502 | {},\r |
| 1503 | False,\r |
| 1504 | None,\r |
| 1505 | IsDsc=True)\r |
| 1506 | \r |
| 1507 | \r |
| 1508 | return Pcds\r |
| 1509 | \r |
| 1510 | def __UNICODE2OCTList(self,Value):\r |
| 1511 | Value = Value.strip()\r |
| 1512 | Value = Value[2:-1]\r |
| 1513 | List = []\r |
| 1514 | for Item in Value:\r |
| 1515 | Temp = '%04X' % ord(Item)\r |
| 1516 | List.append('0x' + Temp[2:4])\r |
| 1517 | List.append('0x' + Temp[0:2])\r |
| 1518 | List.append('0x00')\r |
| 1519 | List.append('0x00')\r |
| 1520 | return List\r |
| 1521 | def __STRING2OCTList(self,Value):\r |
| 1522 | OCTList = []\r |
| 1523 | Value = Value.strip('"')\r |
| 1524 | for char in Value:\r |
| 1525 | Temp = '%02X' % ord(char)\r |
| 1526 | OCTList.append('0x' + Temp)\r |
| 1527 | OCTList.append('0x00')\r |
| 1528 | return OCTList\r |
| 1529 | \r |
| 1530 | def GetStructurePcdMaxSize(self, str_pcd):\r |
| 1531 | pcd_default_value = str_pcd.DefaultValue\r |
| 1532 | sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]\r |
| 1533 | sku_values.append(pcd_default_value)\r |
| 1534 | \r |
| 1535 | def get_length(value):\r |
| 1536 | Value = value.strip()\r |
| 1537 | if len(value) > 1:\r |
| 1538 | if Value.startswith('GUID') and Value.endswith(')'):\r |
| 1539 | return 16\r |
| 1540 | if Value.startswith('L"') and Value.endswith('"'):\r |
| 1541 | return len(Value[2:-1])\r |
| 1542 | if Value[0] == '"' and Value[-1] == '"':\r |
| 1543 | return len(Value) - 2\r |
| 1544 | if Value[0] == '{' and Value[-1] == '}':\r |
| 1545 | return len(Value.split(","))\r |
| 1546 | if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r |
| 1547 | return len(list(Value[2:-1]))\r |
| 1548 | if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r |
| 1549 | return len(Value) - 2\r |
| 1550 | return len(Value)\r |
| 1551 | \r |
| 1552 | return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r |
| 1553 | \r |
| 1554 | def ExecuteCommand (self, Command):\r |
| 1555 | try:\r |
| 1556 | Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r |
| 1557 | except:\r |
| 1558 | EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)\r |
| 1559 | Result = Process.communicate()\r |
| 1560 | return Process.returncode, Result[0], Result[1]\r |
| 1561 | \r |
| 1562 | def IntToCString(self, Value, ValueSize):\r |
| 1563 | Result = '"'\r |
| 1564 | if not isinstance (Value, str):\r |
| 1565 | for Index in range(0, ValueSize):\r |
| 1566 | Result = Result + '\\x%02x' % (Value & 0xff)\r |
| 1567 | Value = Value >> 8\r |
| 1568 | Result = Result + '"'\r |
| 1569 | return Result\r |
| 1570 | \r |
| 1571 | def GetPcdMaxSize(self,Pcd):\r |
| 1572 | MaxSize = int(Pcd.MaxDatumSize,10) if Pcd.MaxDatumSize else 0\r |
| 1573 | if Pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:\r |
| 1574 | if Pcd.PcdValueFromComm:\r |
| 1575 | if Pcd.PcdValueFromComm.startswith("{") and Pcd.PcdValueFromComm.endswith("}"):\r |
| 1576 | MaxSize = max([len(Pcd.PcdValueFromComm.split(",")),MaxSize])\r |
| 1577 | elif Pcd.PcdValueFromComm.startswith("\"") or Pcd.PcdValueFromComm.startswith("\'"):\r |
| 1578 | MaxSize = max([len(Pcd.PcdValueFromComm)-2+1,MaxSize])\r |
| 1579 | elif Pcd.PcdValueFromComm.startswith("L\""):\r |
| 1580 | MaxSize = max([2*(len(Pcd.PcdValueFromComm)-3+1),MaxSize])\r |
| 1581 | else:\r |
| 1582 | MaxSize = max([len(Pcd.PcdValueFromComm),MaxSize])\r |
| 1583 | elif Pcd.DatumType not in ['BOOLEAN','UINT8']:\r |
| 1584 | MaxSize = 1\r |
| 1585 | elif Pcd.DatumType == 'UINT16':\r |
| 1586 | MaxSize = 2\r |
| 1587 | elif Pcd.DatumType == 'UINT32':\r |
| 1588 | MaxSize = 4\r |
| 1589 | elif Pcd.DatumType == 'UINT64':\r |
| 1590 | MaxSize = 8\r |
| 1591 | return MaxSize\r |
| 1592 | def GenerateSizeFunction(self,Pcd):\r |
| 1593 | CApp = "// Default Value in Dec \n"\r |
| 1594 | CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1595 | for FieldList in [Pcd.DefaultValues]:\r |
| 1596 | if not FieldList:\r |
| 1597 | continue\r |
| 1598 | for FieldName in FieldList:\r |
| 1599 | FieldName = "." + FieldName\r |
| 1600 | IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r |
| 1601 | if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r |
| 1602 | try:\r |
| 1603 | Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r |
| 1604 | except BadExpression:\r |
| 1605 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1606 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r |
| 1607 | Value, ValueSize = ParseFieldValue(Value)\r |
| 1608 | 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 |
| 1609 | else:\r |
| 1610 | NewFieldName = ''\r |
| 1611 | FieldName_ori = FieldName.strip('.')\r |
| 1612 | while '[' in FieldName:\r |
| 1613 | NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r |
| 1614 | ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r |
| 1615 | FieldName = FieldName.split(']', 1)[1]\r |
| 1616 | FieldName = NewFieldName + FieldName\r |
| 1617 | while '[' in FieldName:\r |
| 1618 | FieldName = FieldName.rsplit('[', 1)[0]\r |
| 1619 | 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 |
| 1620 | for skuname in Pcd.SkuOverrideValues:\r |
| 1621 | if skuname == "COMMON":\r |
| 1622 | continue\r |
| 1623 | for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:\r |
| 1624 | CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r |
| 1625 | for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:\r |
| 1626 | if not FieldList:\r |
| 1627 | continue\r |
| 1628 | for FieldName in FieldList:\r |
| 1629 | FieldName = "." + FieldName\r |
| 1630 | IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r |
| 1631 | if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r |
| 1632 | try:\r |
| 1633 | Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r |
| 1634 | except BadExpression:\r |
| 1635 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1636 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r |
| 1637 | Value, ValueSize = ParseFieldValue(Value)\r |
| 1638 | 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 |
| 1639 | else:\r |
| 1640 | NewFieldName = ''\r |
| 1641 | FieldName_ori = FieldName.strip('.')\r |
| 1642 | while '[' in FieldName:\r |
| 1643 | NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r |
| 1644 | ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r |
| 1645 | FieldName = FieldName.split(']', 1)[1]\r |
| 1646 | FieldName = NewFieldName + FieldName\r |
| 1647 | while '[' in FieldName:\r |
| 1648 | FieldName = FieldName.rsplit('[', 1)[0]\r |
| 1649 | 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 |
| 1650 | if Pcd.PcdFieldValueFromComm:\r |
| 1651 | CApp = CApp + "// From Command Line \n"\r |
| 1652 | for FieldName in Pcd.PcdFieldValueFromComm:\r |
| 1653 | FieldName = "." + FieldName\r |
| 1654 | IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])\r |
| 1655 | if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):\r |
| 1656 | try:\r |
| 1657 | Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r |
| 1658 | except BadExpression:\r |
| 1659 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1660 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))\r |
| 1661 | Value, ValueSize = ParseFieldValue(Value)\r |
| 1662 | 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("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);\r |
| 1663 | else:\r |
| 1664 | NewFieldName = ''\r |
| 1665 | FieldName_ori = FieldName.strip('.')\r |
| 1666 | while '[' in FieldName:\r |
| 1667 | NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r |
| 1668 | ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r |
| 1669 | FieldName = FieldName.split(']', 1)[1]\r |
| 1670 | FieldName = NewFieldName + FieldName\r |
| 1671 | while '[' in FieldName:\r |
| 1672 | FieldName = FieldName.rsplit('[', 1)[0]\r |
| 1673 | CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])\r |
| 1674 | CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd))\r |
| 1675 | CApp = CApp + "}\n"\r |
| 1676 | return CApp\r |
| 1677 | def GenerateSizeStatments(self,Pcd):\r |
| 1678 | CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r |
| 1679 | CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1680 | return CApp\r |
| 1681 | def GenerateDefaultValueAssignFunction(self,Pcd):\r |
| 1682 | CApp = "// Default value in Dec \n"\r |
| 1683 | CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)\r |
| 1684 | CApp = CApp + ' UINT32 FieldSize;\n'\r |
| 1685 | CApp = CApp + ' CHAR8 *Value;\n'\r |
| 1686 | DefaultValueFromDec = Pcd.DefaultValueFromDec\r |
| 1687 | IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)\r |
| 1688 | if IsArray:\r |
| 1689 | try:\r |
| 1690 | DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)\r |
| 1691 | except BadExpression:\r |
| 1692 | EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %\r |
| 1693 | (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))\r |
| 1694 | DefaultValueFromDec = StringToArray(DefaultValueFromDec)\r |
| 1695 | Value, ValueSize = ParseFieldValue (DefaultValueFromDec)\r |
| 1696 | if isinstance(Value, str):\r |
| 1697 | CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)\r |
| 1698 | elif IsArray:\r |
| 1699 | #\r |
| 1700 | # Use memcpy() to copy value into field\r |
| 1701 | #\r |
| 1702 | CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)\r |
| 1703 | CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r |
| 1704 | for FieldList in [Pcd.DefaultValues]:\r |
| 1705 | if not FieldList:\r |
| 1706 | continue\r |
| 1707 | for FieldName in FieldList:\r |
| 1708 | IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r |
| 1709 | if IsArray:\r |
| 1710 | try:\r |
| 1711 | FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r |
| 1712 | except BadExpression:\r |
| 1713 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1714 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))\r |
| 1715 | \r |
| 1716 | try:\r |
| 1717 | Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r |
| 1718 | except Exception:\r |
| 1719 | 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 |
| 1720 | if isinstance(Value, str):\r |
| 1721 | CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1722 | elif IsArray:\r |
| 1723 | #\r |
| 1724 | # Use memcpy() to copy value into field\r |
| 1725 | #\r |
| 1726 | CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r |
| 1727 | 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 |
| 1728 | CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r |
| 1729 | else:\r |
| 1730 | if ValueSize > 4:\r |
| 1731 | CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1732 | else:\r |
| 1733 | CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1734 | CApp = CApp + "}\n"\r |
| 1735 | return CApp\r |
| 1736 | def GenerateDefaultValueAssignStatement(self,Pcd):\r |
| 1737 | CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1738 | return CApp\r |
| 1739 | def GenerateInitValueFunction(self,Pcd,SkuName,DefaultStoreName):\r |
| 1740 | CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,DefaultStoreName)\r |
| 1741 | CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName,Pcd.DatumType)\r |
| 1742 | CApp = CApp + ' UINT32 FieldSize;\n'\r |
| 1743 | CApp = CApp + ' CHAR8 *Value;\n'\r |
| 1744 | \r |
| 1745 | CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % ('DEFAULT', TAB_DEFAULT_STORES_DEFAULT)\r |
| 1746 | inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]\r |
| 1747 | if (SkuName,DefaultStoreName) == ('DEFAULT',TAB_DEFAULT_STORES_DEFAULT):\r |
| 1748 | pcddefaultvalue = Pcd.DefaultFromDSC.get('DEFAULT',{}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue\r |
| 1749 | else:\r |
| 1750 | if not Pcd.DscRawValue:\r |
| 1751 | # handle the case that structure pcd is not appear in DSC\r |
| 1752 | self.CopyDscRawValue(Pcd)\r |
| 1753 | pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)\r |
| 1754 | for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]:\r |
| 1755 | if not FieldList:\r |
| 1756 | continue\r |
| 1757 | if pcddefaultvalue and FieldList == pcddefaultvalue:\r |
| 1758 | IsArray = IsFieldValueAnArray(FieldList)\r |
| 1759 | if IsArray:\r |
| 1760 | try:\r |
| 1761 | FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r |
| 1762 | except BadExpression:\r |
| 1763 | EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r |
| 1764 | (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r |
| 1765 | Value, ValueSize = ParseFieldValue (FieldList)\r |
| 1766 | \r |
| 1767 | if (SkuName,DefaultStoreName) == ('DEFAULT',TAB_DEFAULT_STORES_DEFAULT):\r |
| 1768 | if isinstance(Value, str):\r |
| 1769 | CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get('DEFAULT',{}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r |
| 1770 | elif IsArray:\r |
| 1771 | #\r |
| 1772 | # Use memcpy() to copy value into field\r |
| 1773 | #\r |
| 1774 | CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get('DEFAULT',{}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r |
| 1775 | CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r |
| 1776 | else:\r |
| 1777 | if isinstance(Value, str):\r |
| 1778 | CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))\r |
| 1779 | elif IsArray:\r |
| 1780 | #\r |
| 1781 | # Use memcpy() to copy value into field\r |
| 1782 | #\r |
| 1783 | CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))\r |
| 1784 | CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r |
| 1785 | continue\r |
| 1786 | if (SkuName,DefaultStoreName) == ('DEFAULT',TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )):\r |
| 1787 | for FieldName in FieldList:\r |
| 1788 | IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r |
| 1789 | if IsArray:\r |
| 1790 | try:\r |
| 1791 | FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r |
| 1792 | except BadExpression:\r |
| 1793 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1794 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r |
| 1795 | try:\r |
| 1796 | Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r |
| 1797 | except Exception:\r |
| 1798 | 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 |
| 1799 | if isinstance(Value, str):\r |
| 1800 | CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1801 | elif IsArray:\r |
| 1802 | #\r |
| 1803 | # Use memcpy() to copy value into field\r |
| 1804 | #\r |
| 1805 | CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r |
| 1806 | 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 |
| 1807 | CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r |
| 1808 | else:\r |
| 1809 | if ValueSize > 4:\r |
| 1810 | CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1811 | else:\r |
| 1812 | CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1813 | CApp = CApp + "}\n"\r |
| 1814 | return CApp\r |
| 1815 | def GenerateInitValueStatement(self,Pcd,SkuName,DefaultStoreName):\r |
| 1816 | CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName)\r |
| 1817 | return CApp\r |
| 1818 | def GenerateCommandLineValue(self,Pcd):\r |
| 1819 | CApp = "// Value in CommandLine\n"\r |
| 1820 | CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)\r |
| 1821 | CApp = CApp + ' UINT32 FieldSize;\n'\r |
| 1822 | CApp = CApp + ' CHAR8 *Value;\n'\r |
| 1823 | \r |
| 1824 | pcddefaultvalue = Pcd.PcdValueFromComm\r |
| 1825 | for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]:\r |
| 1826 | if not FieldList:\r |
| 1827 | continue\r |
| 1828 | if pcddefaultvalue and FieldList == pcddefaultvalue:\r |
| 1829 | IsArray = IsFieldValueAnArray(FieldList)\r |
| 1830 | if IsArray:\r |
| 1831 | try:\r |
| 1832 | FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r |
| 1833 | except BadExpression:\r |
| 1834 | EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %\r |
| 1835 | (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r |
| 1836 | Value, ValueSize = ParseFieldValue (FieldList)\r |
| 1837 | \r |
| 1838 | if isinstance(Value, str):\r |
| 1839 | CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)\r |
| 1840 | elif IsArray:\r |
| 1841 | #\r |
| 1842 | # Use memcpy() to copy value into field\r |
| 1843 | #\r |
| 1844 | CApp = CApp + ' Value = %s; // From Command Line.\n' % (self.IntToCString(Value, ValueSize))\r |
| 1845 | CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r |
| 1846 | continue\r |
| 1847 | for FieldName in FieldList:\r |
| 1848 | IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r |
| 1849 | if IsArray:\r |
| 1850 | try:\r |
| 1851 | FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r |
| 1852 | except BadExpression:\r |
| 1853 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r |
| 1854 | (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r |
| 1855 | except:\r |
| 1856 | print "error"\r |
| 1857 | try:\r |
| 1858 | Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r |
| 1859 | except Exception:\r |
| 1860 | 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 |
| 1861 | if isinstance(Value, str):\r |
| 1862 | CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1863 | elif IsArray:\r |
| 1864 | #\r |
| 1865 | # Use memcpy() to copy value into field\r |
| 1866 | #\r |
| 1867 | CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r |
| 1868 | 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 |
| 1869 | CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r |
| 1870 | else:\r |
| 1871 | if ValueSize > 4:\r |
| 1872 | CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1873 | else:\r |
| 1874 | CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r |
| 1875 | CApp = CApp + "}\n"\r |
| 1876 | return CApp\r |
| 1877 | def GenerateCommandLineValueStatement(self,Pcd):\r |
| 1878 | CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1879 | return CApp\r |
| 1880 | def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):\r |
| 1881 | OverrideValues = {DefaultStore:""}\r |
| 1882 | if Pcd.SkuOverrideValues:\r |
| 1883 | OverrideValues = Pcd.SkuOverrideValues[SkuName]\r |
| 1884 | for DefaultStoreName in OverrideValues.keys():\r |
| 1885 | CApp = CApp + 'void\n'\r |
| 1886 | CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1887 | CApp = CApp + ' void\n'\r |
| 1888 | CApp = CApp + ' )\n'\r |
| 1889 | CApp = CApp + '{\n'\r |
| 1890 | CApp = CApp + ' UINT32 Size;\n'\r |
| 1891 | CApp = CApp + ' UINT32 FieldSize;\n'\r |
| 1892 | CApp = CApp + ' CHAR8 *Value;\n'\r |
| 1893 | CApp = CApp + ' UINT32 OriginalSize;\n'\r |
| 1894 | CApp = CApp + ' VOID *OriginalPcd;\n'\r |
| 1895 | CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)\r |
| 1896 | CApp = CApp + '\n'\r |
| 1897 | \r |
| 1898 | if SkuName in Pcd.SkuInfoList:\r |
| 1899 | DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)\r |
| 1900 | else:\r |
| 1901 | DefaultValue = Pcd.DefaultValue\r |
| 1902 | PcdDefaultValue = StringToArray(DefaultValue.strip())\r |
| 1903 | \r |
| 1904 | InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r |
| 1905 | \r |
| 1906 | #\r |
| 1907 | # Get current PCD value and size\r |
| 1908 | #\r |
| 1909 | CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1910 | \r |
| 1911 | #\r |
| 1912 | # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r |
| 1913 | # the correct value. For structures with a flexible array member, the flexible\r |
| 1914 | # array member is detected, and the size is based on the highest index used with\r |
| 1915 | # the flexible array member. The flexible array member must be the last field\r |
| 1916 | # in a structure. The size formula for this case is:\r |
| 1917 | # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r |
| 1918 | #\r |
| 1919 | CApp = CApp + self.GenerateSizeStatments(Pcd)\r |
| 1920 | \r |
| 1921 | #\r |
| 1922 | # Allocate and zero buffer for the PCD\r |
| 1923 | # Must handle cases where current value is smaller, larger, or same size\r |
| 1924 | # Always keep that larger one as the current size\r |
| 1925 | #\r |
| 1926 | CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r |
| 1927 | CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r |
| 1928 | CApp = CApp + ' memset (Pcd, 0, Size);\n'\r |
| 1929 | \r |
| 1930 | #\r |
| 1931 | # Copy current PCD value into allocated buffer.\r |
| 1932 | #\r |
| 1933 | CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r |
| 1934 | \r |
| 1935 | #\r |
| 1936 | # Assign field values in PCD\r |
| 1937 | #\r |
| 1938 | CApp = CApp + self.GenerateDefaultValueAssignStatement(Pcd)\r |
| 1939 | if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 1940 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 1941 | for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r |
| 1942 | storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]\r |
| 1943 | for defaultstorenameitem in storeset:\r |
| 1944 | CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r |
| 1945 | CApp = CApp + self.GenerateInitValueStatement(Pcd,skuname,defaultstorenameitem)\r |
| 1946 | if skuname == SkuName:\r |
| 1947 | break\r |
| 1948 | else:\r |
| 1949 | CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId\r |
| 1950 | CApp = CApp + self.GenerateInitValueStatement(Pcd,self.SkuIdMgr.SystemSkuId,TAB_DEFAULT_STORES_DEFAULT)\r |
| 1951 | CApp = CApp + self.GenerateCommandLineValueStatement(Pcd)\r |
| 1952 | #\r |
| 1953 | # Set new PCD value and size\r |
| 1954 | #\r |
| 1955 | CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 1956 | \r |
| 1957 | #\r |
| 1958 | # Free PCD\r |
| 1959 | #\r |
| 1960 | CApp = CApp + ' free (Pcd);\n'\r |
| 1961 | CApp = CApp + '}\n'\r |
| 1962 | CApp = CApp + '\n'\r |
| 1963 | return InitByteValue, CApp\r |
| 1964 | \r |
| 1965 | def GenerateByteArrayValue (self, StructuredPcds):\r |
| 1966 | #\r |
| 1967 | # Generate/Compile/Run C application to determine if there are any flexible array members\r |
| 1968 | #\r |
| 1969 | if not StructuredPcds:\r |
| 1970 | return\r |
| 1971 | \r |
| 1972 | InitByteValue = ""\r |
| 1973 | CApp = PcdMainCHeader\r |
| 1974 | \r |
| 1975 | Includes = {}\r |
| 1976 | IncludeFiles = set()\r |
| 1977 | for PcdName in StructuredPcds:\r |
| 1978 | Pcd = StructuredPcds[PcdName]\r |
| 1979 | for IncludeFile in Pcd.StructuredPcdIncludeFile:\r |
| 1980 | if IncludeFile not in Includes:\r |
| 1981 | Includes[IncludeFile] = True\r |
| 1982 | IncludeFiles.add(IncludeFile)\r |
| 1983 | CApp = CApp + '#include <%s>\n' % (IncludeFile)\r |
| 1984 | CApp = CApp + '\n'\r |
| 1985 | for PcdName in StructuredPcds:\r |
| 1986 | Pcd = StructuredPcds[PcdName]\r |
| 1987 | CApp = CApp + self.GenerateSizeFunction(Pcd)\r |
| 1988 | CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)\r |
| 1989 | CApp = CApp + self.GenerateCommandLineValue(Pcd)\r |
| 1990 | if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 1991 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 1992 | CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)\r |
| 1993 | else:\r |
| 1994 | for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r |
| 1995 | if SkuName not in Pcd.SkuOverrideValues:\r |
| 1996 | continue\r |
| 1997 | for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r |
| 1998 | CApp = CApp + self.GenerateInitValueFunction(Pcd,SkuName,DefaultStoreName)\r |
| 1999 | if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r |
| 2000 | self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 2001 | InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)\r |
| 2002 | else:\r |
| 2003 | for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r |
| 2004 | if SkuName not in Pcd.SkuOverrideValues:\r |
| 2005 | continue\r |
| 2006 | for DefaultStoreName in Pcd.DefaultStoreName:\r |
| 2007 | Pcd = StructuredPcds[PcdName]\r |
| 2008 | InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r |
| 2009 | \r |
| 2010 | CApp = CApp + 'VOID\n'\r |
| 2011 | CApp = CApp + 'PcdEntryPoint(\n'\r |
| 2012 | CApp = CApp + ' VOID\n'\r |
| 2013 | CApp = CApp + ' )\n'\r |
| 2014 | CApp = CApp + '{\n'\r |
| 2015 | for Pcd in StructuredPcds.values():\r |
| 2016 | if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 2017 | CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 2018 | else:\r |
| 2019 | for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r |
| 2020 | if SkuName not in Pcd.SkuOverrideValues:\r |
| 2021 | continue\r |
| 2022 | for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r |
| 2023 | CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r |
| 2024 | CApp = CApp + '}\n'\r |
| 2025 | \r |
| 2026 | CApp = CApp + PcdMainCEntry + '\n'\r |
| 2027 | \r |
| 2028 | if not os.path.exists(self.OutputPath):\r |
| 2029 | os.makedirs(self.OutputPath)\r |
| 2030 | CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r |
| 2031 | SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)\r |
| 2032 | \r |
| 2033 | MakeApp = PcdMakefileHeader\r |
| 2034 | if sys.platform == "win32":\r |
| 2035 | MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r |
| 2036 | else:\r |
| 2037 | MakeApp = MakeApp + PcdGccMakefile\r |
| 2038 | MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r |
| 2039 | 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='\r |
| 2040 | \r |
| 2041 | IncSearchList = []\r |
| 2042 | PlatformInc = {}\r |
| 2043 | for Cache in self._Bdb._CACHE_.values():\r |
| 2044 | if Cache.MetaFile.Ext.lower() != '.dec':\r |
| 2045 | continue\r |
| 2046 | if Cache.Includes:\r |
| 2047 | if str(Cache.MetaFile.Path) not in PlatformInc:\r |
| 2048 | PlatformInc[str(Cache.MetaFile.Path)] = []\r |
| 2049 | PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))\r |
| 2050 | PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)\r |
| 2051 | \r |
| 2052 | PcdDependDEC = []\r |
| 2053 | for Pcd in StructuredPcds.values():\r |
| 2054 | for PackageDec in Pcd.PackageDecs:\r |
| 2055 | Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r |
| 2056 | if not os.path.exists(Package):\r |
| 2057 | EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r |
| 2058 | if Package not in PcdDependDEC:\r |
| 2059 | PcdDependDEC.append(Package)\r |
| 2060 | \r |
| 2061 | if PlatformInc and PcdDependDEC:\r |
| 2062 | for pkg in PcdDependDEC:\r |
| 2063 | if pkg in PlatformInc:\r |
| 2064 | for inc in PlatformInc[pkg]:\r |
| 2065 | MakeApp += '-I' + str(inc) + ' '\r |
| 2066 | IncSearchList.append(inc)\r |
| 2067 | MakeApp = MakeApp + '\n'\r |
| 2068 | \r |
| 2069 | CC_FLAGS = LinuxCFLAGS\r |
| 2070 | if sys.platform == "win32":\r |
| 2071 | CC_FLAGS = WindowsCFLAGS\r |
| 2072 | BuildOptions = {}\r |
| 2073 | for Options in self.BuildOptions:\r |
| 2074 | if Options[2] != EDKII_NAME:\r |
| 2075 | continue\r |
| 2076 | Family = Options[0]\r |
| 2077 | if Family and Family != self.ToolChainFamily:\r |
| 2078 | continue\r |
| 2079 | Target, Tag, Arch, Tool, Attr = Options[1].split("_")\r |
| 2080 | if Tool != 'CC':\r |
| 2081 | continue\r |
| 2082 | \r |
| 2083 | if Target == "*" or Target == self._Target:\r |
| 2084 | if Tag == "*" or Tag == self._Toolchain:\r |
| 2085 | if Arch == "*" or Arch == self.Arch:\r |
| 2086 | if Tool not in BuildOptions:\r |
| 2087 | BuildOptions[Tool] = {}\r |
| 2088 | if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):\r |
| 2089 | BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r |
| 2090 | else:\r |
| 2091 | # append options for the same tool except PATH\r |
| 2092 | if Attr != 'PATH':\r |
| 2093 | BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]\r |
| 2094 | else:\r |
| 2095 | BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r |
| 2096 | if BuildOptions:\r |
| 2097 | for Tool in BuildOptions:\r |
| 2098 | for Attr in BuildOptions[Tool]:\r |
| 2099 | if Attr == "FLAGS":\r |
| 2100 | Value = BuildOptions[Tool][Attr]\r |
| 2101 | ValueList = Value.split()\r |
| 2102 | if ValueList:\r |
| 2103 | for Id, Item in enumerate(ValueList):\r |
| 2104 | if Item == '-D' or Item == '/D':\r |
| 2105 | CC_FLAGS += ' ' + Item\r |
| 2106 | if Id + 1 < len(ValueList):\r |
| 2107 | CC_FLAGS += ' ' + ValueList[Id + 1]\r |
| 2108 | elif Item.startswith('/D') or Item.startswith('-D'):\r |
| 2109 | CC_FLAGS += ' ' + Item\r |
| 2110 | MakeApp += CC_FLAGS\r |
| 2111 | \r |
| 2112 | if sys.platform == "win32":\r |
| 2113 | MakeApp = MakeApp + PcdMakefileEnd\r |
| 2114 | MakeApp = MakeApp + '\n'\r |
| 2115 | IncludeFileFullPaths = []\r |
| 2116 | for includefile in IncludeFiles:\r |
| 2117 | for includepath in IncSearchList:\r |
| 2118 | includefullpath = os.path.join(str(includepath),includefile)\r |
| 2119 | if os.path.exists(includefullpath):\r |
| 2120 | IncludeFileFullPaths.append(os.path.normpath(includefullpath))\r |
| 2121 | break\r |
| 2122 | SearchPathList = []\r |
| 2123 | SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))\r |
| 2124 | SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))\r |
| 2125 | SearchPathList.extend([str(item) for item in IncSearchList])\r |
| 2126 | IncFileList = GetDependencyList(IncludeFileFullPaths,SearchPathList)\r |
| 2127 | for include_file in IncFileList:\r |
| 2128 | MakeApp += "$(OBJECTS) : %s\n" % include_file\r |
| 2129 | MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r |
| 2130 | MakeApp += "$(OBJECTS) : %s\n" % MakeFileName\r |
| 2131 | SaveFileOnChange(MakeFileName, MakeApp, False)\r |
| 2132 | \r |
| 2133 | InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r |
| 2134 | OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r |
| 2135 | SaveFileOnChange(InputValueFile, InitByteValue, False)\r |
| 2136 | \r |
| 2137 | PcdValueInitExe = PcdValueInitName\r |
| 2138 | if not sys.platform == "win32":\r |
| 2139 | PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r |
| 2140 | else:\r |
| 2141 | PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"\r |
| 2142 | \r |
| 2143 | Messages = ''\r |
| 2144 | if sys.platform == "win32":\r |
| 2145 | MakeCommand = 'nmake -f %s' % (MakeFileName)\r |
| 2146 | returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r |
| 2147 | Messages = StdOut\r |
| 2148 | else:\r |
| 2149 | MakeCommand = 'make -f %s' % (MakeFileName)\r |
| 2150 | returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r |
| 2151 | Messages = StdErr\r |
| 2152 | Messages = Messages.split('\n')\r |
| 2153 | MessageGroup = []\r |
| 2154 | if returncode <>0:\r |
| 2155 | CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r |
| 2156 | File = open (CAppBaseFileName + '.c', 'r')\r |
| 2157 | FileData = File.readlines()\r |
| 2158 | File.close()\r |
| 2159 | for Message in Messages:\r |
| 2160 | if " error" in Message or "warning" in Message:\r |
| 2161 | FileInfo = Message.strip().split('(')\r |
| 2162 | if len (FileInfo) > 1:\r |
| 2163 | FileName = FileInfo [0]\r |
| 2164 | FileLine = FileInfo [1].split (')')[0]\r |
| 2165 | else:\r |
| 2166 | FileInfo = Message.strip().split(':')\r |
| 2167 | FileName = FileInfo [0]\r |
| 2168 | FileLine = FileInfo [1]\r |
| 2169 | if FileLine.isdigit():\r |
| 2170 | error_line = FileData[int (FileLine) - 1]\r |
| 2171 | if r"//" in error_line:\r |
| 2172 | c_line,dsc_line = error_line.split(r"//")\r |
| 2173 | else:\r |
| 2174 | dsc_line = error_line\r |
| 2175 | message_itmes = Message.split(":")\r |
| 2176 | Index = 0\r |
| 2177 | if "PcdValueInit.c" not in Message:\r |
| 2178 | if not MessageGroup:\r |
| 2179 | MessageGroup.append(Message)\r |
| 2180 | break\r |
| 2181 | else:\r |
| 2182 | for item in message_itmes:\r |
| 2183 | if "PcdValueInit.c" in item:\r |
| 2184 | Index = message_itmes.index(item)\r |
| 2185 | message_itmes[Index] = dsc_line.strip()\r |
| 2186 | break\r |
| 2187 | MessageGroup.append(":".join(message_itmes[Index:]).strip())\r |
| 2188 | continue\r |
| 2189 | else:\r |
| 2190 | MessageGroup.append(Message)\r |
| 2191 | if MessageGroup:\r |
| 2192 | EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )\r |
| 2193 | else:\r |
| 2194 | EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)\r |
| 2195 | \r |
| 2196 | if self.NeedUpdateOutput(OutputValueFile, PcdValueInitExe ,InputValueFile):\r |
| 2197 | Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)\r |
| 2198 | returncode, StdOut, StdErr = self.ExecuteCommand (Command)\r |
| 2199 | if returncode <> 0:\r |
| 2200 | EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)\r |
| 2201 | \r |
| 2202 | File = open (OutputValueFile, 'r')\r |
| 2203 | FileBuffer = File.readlines()\r |
| 2204 | File.close()\r |
| 2205 | \r |
| 2206 | StructurePcdSet = []\r |
| 2207 | for Pcd in FileBuffer:\r |
| 2208 | PcdValue = Pcd.split ('|')\r |
| 2209 | PcdInfo = PcdValue[0].split ('.')\r |
| 2210 | StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r |
| 2211 | return StructurePcdSet\r |
| 2212 | \r |
| 2213 | def NeedUpdateOutput(self,OutputFile, ValueCFile, StructureInput):\r |
| 2214 | if not os.path.exists(OutputFile):\r |
| 2215 | return True\r |
| 2216 | if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:\r |
| 2217 | return True\r |
| 2218 | if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:\r |
| 2219 | return True\r |
| 2220 | return False\r |
| 2221 | \r |
| 2222 | ## Retrieve dynamic PCD settings\r |
| 2223 | #\r |
| 2224 | # @param Type PCD type\r |
| 2225 | #\r |
| 2226 | # @retval a dict object contains settings of given PCD type\r |
| 2227 | #\r |
| 2228 | def _GetDynamicPcd(self, Type):\r |
| 2229 | \r |
| 2230 | \r |
| 2231 | Pcds = OrderedDict()\r |
| 2232 | #\r |
| 2233 | # tdict is a special dict kind of type, used for selecting correct\r |
| 2234 | # PCD settings for certain ARCH and SKU\r |
| 2235 | #\r |
| 2236 | PcdDict = tdict(True, 4)\r |
| 2237 | PcdList = []\r |
| 2238 | # Find out all possible PCD candidates for self._Arch\r |
| 2239 | RecordList = self._RawData[Type, self._Arch]\r |
| 2240 | AvailableSkuIdSet = copy.copy(self.SkuIds)\r |
| 2241 | \r |
| 2242 | \r |
| 2243 | for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 2244 | SkuName = SkuName.upper()\r |
| 2245 | SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r |
| 2246 | if SkuName not in AvailableSkuIdSet:\r |
| 2247 | EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r |
| 2248 | File=self.MetaFile, Line=Dummy5)\r |
| 2249 | if "." not in TokenSpaceGuid:\r |
| 2250 | PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r |
| 2251 | PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r |
| 2252 | \r |
| 2253 | # Remove redundant PCD candidates, per the ARCH and SKU\r |
| 2254 | for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r |
| 2255 | \r |
| 2256 | Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r |
| 2257 | if Setting is None:\r |
| 2258 | continue\r |
| 2259 | \r |
| 2260 | PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r |
| 2261 | SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r |
| 2262 | if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r |
| 2263 | pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r |
| 2264 | pcdObject.SkuInfoList[SkuName] = SkuInfo\r |
| 2265 | if MaxDatumSize.strip():\r |
| 2266 | CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r |
| 2267 | else:\r |
| 2268 | CurrentMaxSize = 0\r |
| 2269 | if pcdObject.MaxDatumSize:\r |
| 2270 | PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r |
| 2271 | else:\r |
| 2272 | PcdMaxSize = 0\r |
| 2273 | if CurrentMaxSize > PcdMaxSize:\r |
| 2274 | pcdObject.MaxDatumSize = str(CurrentMaxSize)\r |
| 2275 | else:\r |
| 2276 | Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r |
| 2277 | PcdCName,\r |
| 2278 | TokenSpaceGuid,\r |
| 2279 | self._PCD_TYPE_STRING_[Type],\r |
| 2280 | DatumType,\r |
| 2281 | PcdValue,\r |
| 2282 | '',\r |
| 2283 | MaxDatumSize,\r |
| 2284 | {SkuName : SkuInfo},\r |
| 2285 | False,\r |
| 2286 | None,\r |
| 2287 | IsDsc=True)\r |
| 2288 | \r |
| 2289 | for pcd in Pcds.values():\r |
| 2290 | pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r |
| 2291 | # Only fix the value while no value provided in DSC file.\r |
| 2292 | for sku in pcd.SkuInfoList.values():\r |
| 2293 | if not sku.DefaultValue:\r |
| 2294 | sku.DefaultValue = pcdDecObject.DefaultValue\r |
| 2295 | if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r |
| 2296 | valuefromDec = pcdDecObject.DefaultValue\r |
| 2297 | SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r |
| 2298 | pcd.SkuInfoList['DEFAULT'] = SkuInfo\r |
| 2299 | elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2300 | pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r |
| 2301 | del(pcd.SkuInfoList['COMMON'])\r |
| 2302 | elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2303 | del(pcd.SkuInfoList['COMMON'])\r |
| 2304 | \r |
| 2305 | map(self.FilterSkuSettings,Pcds.values())\r |
| 2306 | \r |
| 2307 | return Pcds\r |
| 2308 | \r |
| 2309 | def FilterSkuSettings(self, PcdObj):\r |
| 2310 | \r |
| 2311 | if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r |
| 2312 | if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():\r |
| 2313 | PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']\r |
| 2314 | PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}\r |
| 2315 | PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'\r |
| 2316 | PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'\r |
| 2317 | \r |
| 2318 | elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:\r |
| 2319 | PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}\r |
| 2320 | \r |
| 2321 | return PcdObj\r |
| 2322 | \r |
| 2323 | \r |
| 2324 | def CompareVarAttr(self, Attr1, Attr2):\r |
| 2325 | if not Attr1 or not Attr2: # for empty string\r |
| 2326 | return True\r |
| 2327 | Attr1s = [attr.strip() for attr in Attr1.split(",")]\r |
| 2328 | Attr1Set = set(Attr1s)\r |
| 2329 | Attr2s = [attr.strip() for attr in Attr2.split(",")]\r |
| 2330 | Attr2Set = set(Attr2s)\r |
| 2331 | if Attr2Set == Attr1Set:\r |
| 2332 | return True\r |
| 2333 | else:\r |
| 2334 | return False\r |
| 2335 | def CopyDscRawValue(self,Pcd):\r |
| 2336 | if Pcd.DscRawValue is None:\r |
| 2337 | Pcd.DscRawValue = dict()\r |
| 2338 | if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r |
| 2339 | if self.SkuIdMgr.SystemSkuId not in Pcd.DscRawValue:\r |
| 2340 | Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId] = {}\r |
| 2341 | Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId][TAB_DEFAULT_STORES_DEFAULT] = Pcd.DefaultValue\r |
| 2342 | for skuname in Pcd.SkuInfoList:\r |
| 2343 | Pcd.DscRawValue[skuname] = {}\r |
| 2344 | if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 2345 | for defaultstore in Pcd.SkuInfoList[skuname].DefaultStoreDict:\r |
| 2346 | Pcd.DscRawValue[skuname][defaultstore] = Pcd.SkuInfoList[skuname].DefaultStoreDict[defaultstore]\r |
| 2347 | else:\r |
| 2348 | Pcd.DscRawValue[skuname][TAB_DEFAULT_STORES_DEFAULT] = Pcd.SkuInfoList[skuname].DefaultValue\r |
| 2349 | def CompletePcdValues(self,PcdSet):\r |
| 2350 | Pcds = {}\r |
| 2351 | DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r |
| 2352 | SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}\r |
| 2353 | DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r |
| 2354 | for PcdCName, TokenSpaceGuid in PcdSet:\r |
| 2355 | PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r |
| 2356 | self.CopyDscRawValue(PcdObj)\r |
| 2357 | if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r |
| 2358 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r |
| 2359 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r |
| 2360 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r |
| 2361 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r |
| 2362 | self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r |
| 2363 | Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r |
| 2364 | continue\r |
| 2365 | PcdType = PcdObj.Type\r |
| 2366 | if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 2367 | for skuid in PcdObj.SkuInfoList:\r |
| 2368 | skuobj = PcdObj.SkuInfoList[skuid]\r |
| 2369 | mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r |
| 2370 | for defaultstorename in DefaultStores:\r |
| 2371 | if defaultstorename not in skuobj.DefaultStoreDict:\r |
| 2372 | skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r |
| 2373 | skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r |
| 2374 | for skuname,skuid in SkuIds.items():\r |
| 2375 | if skuname not in PcdObj.SkuInfoList:\r |
| 2376 | nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r |
| 2377 | while nextskuid not in PcdObj.SkuInfoList:\r |
| 2378 | nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r |
| 2379 | PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r |
| 2380 | PcdObj.SkuInfoList[skuname].SkuId = skuid\r |
| 2381 | PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r |
| 2382 | if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r |
| 2383 | PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r |
| 2384 | Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r |
| 2385 | return Pcds\r |
| 2386 | ## Retrieve dynamic HII PCD settings\r |
| 2387 | #\r |
| 2388 | # @param Type PCD type\r |
| 2389 | #\r |
| 2390 | # @retval a dict object contains settings of given PCD type\r |
| 2391 | #\r |
| 2392 | def _GetDynamicHiiPcd(self, Type):\r |
| 2393 | \r |
| 2394 | VariableAttrs = {}\r |
| 2395 | \r |
| 2396 | Pcds = OrderedDict()\r |
| 2397 | #\r |
| 2398 | # tdict is a special dict kind of type, used for selecting correct\r |
| 2399 | # PCD settings for certain ARCH and SKU\r |
| 2400 | #\r |
| 2401 | PcdDict = tdict(True, 5)\r |
| 2402 | PcdSet = set()\r |
| 2403 | RecordList = self._RawData[Type, self._Arch]\r |
| 2404 | # Find out all possible PCD candidates for self._Arch\r |
| 2405 | AvailableSkuIdSet = copy.copy(self.SkuIds)\r |
| 2406 | DefaultStoresDefine = self._GetDefaultStores()\r |
| 2407 | \r |
| 2408 | for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r |
| 2409 | SkuName = SkuName.upper()\r |
| 2410 | SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r |
| 2411 | DefaultStore = DefaultStore.upper()\r |
| 2412 | if DefaultStore == "COMMON":\r |
| 2413 | DefaultStore = TAB_DEFAULT_STORES_DEFAULT\r |
| 2414 | if SkuName not in AvailableSkuIdSet:\r |
| 2415 | EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r |
| 2416 | File=self.MetaFile, Line=Dummy5)\r |
| 2417 | if DefaultStore not in DefaultStoresDefine:\r |
| 2418 | EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r |
| 2419 | File=self.MetaFile, Line=Dummy5)\r |
| 2420 | if "." not in TokenSpaceGuid:\r |
| 2421 | PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5))\r |
| 2422 | PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r |
| 2423 | \r |
| 2424 | \r |
| 2425 | # Remove redundant PCD candidates, per the ARCH and SKU\r |
| 2426 | for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r |
| 2427 | \r |
| 2428 | Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r |
| 2429 | if Setting is None:\r |
| 2430 | continue\r |
| 2431 | VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r |
| 2432 | \r |
| 2433 | rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r |
| 2434 | if not rt:\r |
| 2435 | EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r |
| 2436 | ExtraData="[%s]" % VarAttribute)\r |
| 2437 | ExceedMax = False\r |
| 2438 | FormatCorrect = True\r |
| 2439 | if VariableOffset.isdigit():\r |
| 2440 | if int(VariableOffset, 10) > 0xFFFF:\r |
| 2441 | ExceedMax = True\r |
| 2442 | elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r |
| 2443 | if int(VariableOffset, 16) > 0xFFFF:\r |
| 2444 | ExceedMax = True\r |
| 2445 | # For Offset written in "A.B"\r |
| 2446 | elif VariableOffset.find('.') > -1:\r |
| 2447 | VariableOffsetList = VariableOffset.split(".")\r |
| 2448 | if not (len(VariableOffsetList) == 2\r |
| 2449 | and IsValidWord(VariableOffsetList[0])\r |
| 2450 | and IsValidWord(VariableOffsetList[1])):\r |
| 2451 | FormatCorrect = False\r |
| 2452 | else:\r |
| 2453 | FormatCorrect = False\r |
| 2454 | if not FormatCorrect:\r |
| 2455 | EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r |
| 2456 | \r |
| 2457 | if ExceedMax:\r |
| 2458 | EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r |
| 2459 | if (VariableName, VariableGuid) not in VariableAttrs:\r |
| 2460 | VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r |
| 2461 | else:\r |
| 2462 | if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r |
| 2463 | EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))\r |
| 2464 | \r |
| 2465 | pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r |
| 2466 | if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r |
| 2467 | pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r |
| 2468 | if SkuName in pcdObject.SkuInfoList:\r |
| 2469 | Skuitem = pcdObject.SkuInfoList[SkuName]\r |
| 2470 | Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r |
| 2471 | else:\r |
| 2472 | SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r |
| 2473 | pcdObject.SkuInfoList[SkuName] = SkuInfo\r |
| 2474 | else:\r |
| 2475 | SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r |
| 2476 | Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r |
| 2477 | PcdCName,\r |
| 2478 | TokenSpaceGuid,\r |
| 2479 | self._PCD_TYPE_STRING_[Type],\r |
| 2480 | '',\r |
| 2481 | DefaultValue,\r |
| 2482 | '',\r |
| 2483 | '',\r |
| 2484 | {SkuName : SkuInfo},\r |
| 2485 | False,\r |
| 2486 | None,\r |
| 2487 | pcdDecObject.validateranges,\r |
| 2488 | pcdDecObject.validlists,\r |
| 2489 | pcdDecObject.expressions,\r |
| 2490 | IsDsc=True)\r |
| 2491 | \r |
| 2492 | \r |
| 2493 | for pcd in Pcds.values():\r |
| 2494 | SkuInfoObj = pcd.SkuInfoList.values()[0]\r |
| 2495 | pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r |
| 2496 | pcd.DatumType = pcdDecObject.DatumType\r |
| 2497 | # Only fix the value while no value provided in DSC file.\r |
| 2498 | for sku in pcd.SkuInfoList.values():\r |
| 2499 | if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):\r |
| 2500 | sku.HiiDefaultValue = pcdDecObject.DefaultValue\r |
| 2501 | for default_store in sku.DefaultStoreDict:\r |
| 2502 | sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue\r |
| 2503 | pcd.DefaultValue = pcdDecObject.DefaultValue\r |
| 2504 | if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r |
| 2505 | valuefromDec = pcdDecObject.DefaultValue\r |
| 2506 | SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})\r |
| 2507 | pcd.SkuInfoList['DEFAULT'] = SkuInfo\r |
| 2508 | elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2509 | pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r |
| 2510 | del(pcd.SkuInfoList['COMMON'])\r |
| 2511 | elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2512 | del(pcd.SkuInfoList['COMMON'])\r |
| 2513 | \r |
| 2514 | if pcd.MaxDatumSize.strip():\r |
| 2515 | MaxSize = int(pcd.MaxDatumSize, 0)\r |
| 2516 | else:\r |
| 2517 | MaxSize = 0\r |
| 2518 | if pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:\r |
| 2519 | for (_, skuobj) in pcd.SkuInfoList.items():\r |
| 2520 | datalen = 0\r |
| 2521 | skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r |
| 2522 | datalen = len(skuobj.HiiDefaultValue.split(","))\r |
| 2523 | if datalen > MaxSize:\r |
| 2524 | MaxSize = datalen\r |
| 2525 | for defaultst in skuobj.DefaultStoreDict:\r |
| 2526 | skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r |
| 2527 | pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r |
| 2528 | pcd.MaxDatumSize = str(MaxSize)\r |
| 2529 | rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r |
| 2530 | if not rt:\r |
| 2531 | invalidpcd = ",".join(invalidhii)\r |
| 2532 | EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)\r |
| 2533 | \r |
| 2534 | map(self.FilterSkuSettings,Pcds.values())\r |
| 2535 | \r |
| 2536 | return Pcds\r |
| 2537 | \r |
| 2538 | def CheckVariableNameAssignment(self,Pcds):\r |
| 2539 | invalidhii = []\r |
| 2540 | for pcdname in Pcds:\r |
| 2541 | pcd = Pcds[pcdname]\r |
| 2542 | varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])\r |
| 2543 | if len(varnameset) > 1:\r |
| 2544 | invalidhii.append(".".join((pcdname[1],pcdname[0])))\r |
| 2545 | if len(invalidhii):\r |
| 2546 | return False,invalidhii\r |
| 2547 | else:\r |
| 2548 | return True, []\r |
| 2549 | ## Retrieve dynamic VPD PCD settings\r |
| 2550 | #\r |
| 2551 | # @param Type PCD type\r |
| 2552 | #\r |
| 2553 | # @retval a dict object contains settings of given PCD type\r |
| 2554 | #\r |
| 2555 | def _GetDynamicVpdPcd(self, Type):\r |
| 2556 | \r |
| 2557 | \r |
| 2558 | Pcds = OrderedDict()\r |
| 2559 | #\r |
| 2560 | # tdict is a special dict kind of type, used for selecting correct\r |
| 2561 | # PCD settings for certain ARCH and SKU\r |
| 2562 | #\r |
| 2563 | PcdDict = tdict(True, 4)\r |
| 2564 | PcdList = []\r |
| 2565 | \r |
| 2566 | # Find out all possible PCD candidates for self._Arch\r |
| 2567 | RecordList = self._RawData[Type, self._Arch]\r |
| 2568 | AvailableSkuIdSet = copy.copy(self.SkuIds)\r |
| 2569 | \r |
| 2570 | for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r |
| 2571 | SkuName = SkuName.upper()\r |
| 2572 | SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r |
| 2573 | if SkuName not in AvailableSkuIdSet:\r |
| 2574 | EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r |
| 2575 | File=self.MetaFile, Line=Dummy5)\r |
| 2576 | if "." not in TokenSpaceGuid:\r |
| 2577 | PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r |
| 2578 | PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r |
| 2579 | \r |
| 2580 | # Remove redundant PCD candidates, per the ARCH and SKU\r |
| 2581 | for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r |
| 2582 | Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r |
| 2583 | if Setting is None:\r |
| 2584 | continue\r |
| 2585 | #\r |
| 2586 | # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r |
| 2587 | # For the Integer & Boolean type, the optional data can only be InitialValue.\r |
| 2588 | # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r |
| 2589 | # until the DEC parser has been called.\r |
| 2590 | #\r |
| 2591 | VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r |
| 2592 | SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r |
| 2593 | if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r |
| 2594 | pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r |
| 2595 | pcdObject.SkuInfoList[SkuName] = SkuInfo\r |
| 2596 | if MaxDatumSize.strip():\r |
| 2597 | CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r |
| 2598 | else:\r |
| 2599 | CurrentMaxSize = 0\r |
| 2600 | if pcdObject.MaxDatumSize:\r |
| 2601 | PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r |
| 2602 | else:\r |
| 2603 | PcdMaxSize = 0\r |
| 2604 | if CurrentMaxSize > PcdMaxSize:\r |
| 2605 | pcdObject.MaxDatumSize = str(CurrentMaxSize)\r |
| 2606 | else:\r |
| 2607 | Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r |
| 2608 | PcdCName,\r |
| 2609 | TokenSpaceGuid,\r |
| 2610 | self._PCD_TYPE_STRING_[Type],\r |
| 2611 | '',\r |
| 2612 | InitialValue,\r |
| 2613 | '',\r |
| 2614 | MaxDatumSize,\r |
| 2615 | {SkuName : SkuInfo},\r |
| 2616 | False,\r |
| 2617 | None,\r |
| 2618 | IsDsc=True)\r |
| 2619 | for pcd in Pcds.values():\r |
| 2620 | SkuInfoObj = pcd.SkuInfoList.values()[0]\r |
| 2621 | pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r |
| 2622 | pcd.DatumType = pcdDecObject.DatumType\r |
| 2623 | # Only fix the value while no value provided in DSC file.\r |
| 2624 | for sku in pcd.SkuInfoList.values():\r |
| 2625 | if not sku.DefaultValue:\r |
| 2626 | sku.DefaultValue = pcdDecObject.DefaultValue\r |
| 2627 | if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r |
| 2628 | valuefromDec = pcdDecObject.DefaultValue\r |
| 2629 | SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r |
| 2630 | pcd.SkuInfoList['DEFAULT'] = SkuInfo\r |
| 2631 | elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2632 | pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r |
| 2633 | del(pcd.SkuInfoList['COMMON'])\r |
| 2634 | elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r |
| 2635 | del(pcd.SkuInfoList['COMMON'])\r |
| 2636 | \r |
| 2637 | \r |
| 2638 | map(self.FilterSkuSettings,Pcds.values())\r |
| 2639 | return Pcds\r |
| 2640 | \r |
| 2641 | ## Add external modules\r |
| 2642 | #\r |
| 2643 | # The external modules are mostly those listed in FDF file, which don't\r |
| 2644 | # need "build".\r |
| 2645 | #\r |
| 2646 | # @param FilePath The path of module description file\r |
| 2647 | #\r |
| 2648 | def AddModule(self, FilePath):\r |
| 2649 | FilePath = NormPath(FilePath)\r |
| 2650 | if FilePath not in self.Modules:\r |
| 2651 | Module = ModuleBuildClassObject()\r |
| 2652 | Module.MetaFile = FilePath\r |
| 2653 | self.Modules.append(Module)\r |
| 2654 | \r |
| 2655 | def _GetToolChainFamily(self):\r |
| 2656 | self._ToolChainFamily = "MSFT"\r |
| 2657 | BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))\r |
| 2658 | if os.path.isfile(BuildConfigurationFile) == True:\r |
| 2659 | TargetTxt = TargetTxtClassObject()\r |
| 2660 | TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r |
| 2661 | ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r |
| 2662 | if ToolDefinitionFile == '':\r |
| 2663 | ToolDefinitionFile = "tools_def.txt"\r |
| 2664 | ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))\r |
| 2665 | if os.path.isfile(ToolDefinitionFile) == True:\r |
| 2666 | ToolDef = ToolDefClassObject()\r |
| 2667 | ToolDef.LoadToolDefFile(ToolDefinitionFile)\r |
| 2668 | ToolDefinition = ToolDef.ToolsDefTxtDatabase\r |
| 2669 | if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r |
| 2670 | or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r |
| 2671 | or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:\r |
| 2672 | self._ToolChainFamily = "MSFT"\r |
| 2673 | else:\r |
| 2674 | self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]\r |
| 2675 | return self._ToolChainFamily\r |
| 2676 | \r |
| 2677 | ## Add external PCDs\r |
| 2678 | #\r |
| 2679 | # The external PCDs are mostly those listed in FDF file to specify address\r |
| 2680 | # or offset information.\r |
| 2681 | #\r |
| 2682 | # @param Name Name of the PCD\r |
| 2683 | # @param Guid Token space guid of the PCD\r |
| 2684 | # @param Value Value of the PCD\r |
| 2685 | #\r |
| 2686 | def AddPcd(self, Name, Guid, Value):\r |
| 2687 | if (Name, Guid) not in self.Pcds:\r |
| 2688 | self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r |
| 2689 | self.Pcds[Name, Guid].DefaultValue = Value\r |
| 2690 | @property\r |
| 2691 | def DecPcds(self):\r |
| 2692 | if self._DecPcds is None:\r |
| 2693 | FdfInfList = []\r |
| 2694 | if GlobalData.gFdfParser:\r |
| 2695 | FdfInfList = GlobalData.gFdfParser.Profile.InfList\r |
| 2696 | PkgSet = set()\r |
| 2697 | for Inf in FdfInfList:\r |
| 2698 | ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r |
| 2699 | if ModuleFile in self._Modules:\r |
| 2700 | continue\r |
| 2701 | ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r |
| 2702 | PkgSet.update(ModuleData.Packages)\r |
| 2703 | self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r |
| 2704 | return self._DecPcds\r |
| 2705 | _Macros = property(_GetMacros)\r |
| 2706 | Arch = property(_GetArch, _SetArch)\r |
| 2707 | Platform = property(_GetPlatformName)\r |
| 2708 | PlatformName = property(_GetPlatformName)\r |
| 2709 | Guid = property(_GetFileGuid)\r |
| 2710 | Version = property(_GetVersion)\r |
| 2711 | DscSpecification = property(_GetDscSpec)\r |
| 2712 | OutputDirectory = property(_GetOutpuDir)\r |
| 2713 | SupArchList = property(_GetSupArch)\r |
| 2714 | BuildTargets = property(_GetBuildTarget)\r |
| 2715 | SkuName = property(_GetSkuName, _SetSkuName)\r |
| 2716 | PcdInfoFlag = property(_GetPcdInfoFlag)\r |
| 2717 | VarCheckFlag = property(_GetVarCheckFlag)\r |
| 2718 | FlashDefinition = property(_GetFdfFile)\r |
| 2719 | Prebuild = property(_GetPrebuild)\r |
| 2720 | Postbuild = property(_GetPostbuild)\r |
| 2721 | BuildNumber = property(_GetBuildNumber)\r |
| 2722 | MakefileName = property(_GetMakefileName)\r |
| 2723 | BsBaseAddress = property(_GetBsBaseAddress)\r |
| 2724 | RtBaseAddress = property(_GetRtBaseAddress)\r |
| 2725 | LoadFixAddress = property(_GetLoadFixAddress)\r |
| 2726 | RFCLanguages = property(_GetRFCLanguages)\r |
| 2727 | ISOLanguages = property(_GetISOLanguages)\r |
| 2728 | VpdToolGuid = property(_GetVpdToolGuid)\r |
| 2729 | SkuIds = property(_GetSkuIds)\r |
| 2730 | Modules = property(_GetModules)\r |
| 2731 | LibraryInstances = property(_GetLibraryInstances)\r |
| 2732 | LibraryClasses = property(_GetLibraryClasses)\r |
| 2733 | Pcds = property(_GetPcds)\r |
| 2734 | BuildOptions = property(_GetBuildOptions)\r |
| 2735 | ToolChainFamily = property(_GetToolChainFamily)\r |