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