]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: PcdDataBase Optimization for multiple SkuIds
[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) 2017, 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
26\r
27from MetaDataTable import *\r
28from MetaFileTable import *\r
29from MetaFileParser import *\r
30\r
31from WorkspaceCommon import GetDeclaredPcd\r
32from Common.Misc import AnalyzeDscPcd\r
33from Common.Misc import ProcessDuplicatedInf\r
34import re\r
35from Common.Parsing import IsValidWord\r
36from Common.VariableAttributes import VariableAttributes\r
37import Common.GlobalData as GlobalData\r
38import subprocess\r
39from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject\r
40\r
41#\r
42# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs\r
43#\r
44PcdValueInitName = 'PcdValueInit'\r
45PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']\r
46PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}\r
47PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']\r
48\r
49PcdMainCHeader = '''\r
50/**\r
51 DO NOT EDIT\r
52 FILE auto-generated\r
53**/\r
54\r
55#include <stdio.h>\r
56#include <stdlib.h>\r
57#include <string.h>\r
58#include <PcdValueCommon.h>\r
59'''\r
60\r
61PcdMainCEntry = '''\r
62int\r
63main (\r
64 int argc,\r
65 char *argv[]\r
66 )\r
67{\r
68 return PcdValueMain (argc, argv);\r
69}\r
70'''\r
71\r
72PcdMakefileHeader = '''\r
73#\r
74# DO NOT EDIT\r
75# This file is auto-generated by build utility\r
76#\r
77\r
78'''\r
79\r
80PcdMakefileEnd = '''\r
81!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common\r
82\r
83CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101\r
84\r
85LIBS = $(LIB_PATH)\Common.lib\r
86\r
87!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app\r
88'''\r
89\r
90PcdGccMakefile = '''\r
91ARCH ?= IA32\r
92MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r
93LIBS = -lCommon\r
94'''\r
95\r
96class DscBuildData(PlatformBuildClassObject):\r
97 # dict used to convert PCD type in database to string used by build tool\r
98 _PCD_TYPE_STRING_ = {\r
99 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
100 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
101 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
102 MODEL_PCD_DYNAMIC : "Dynamic",\r
103 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
104 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
105 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
106 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
107 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
108 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
109 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
110 }\r
111\r
112 # dict used to convert part of [Defines] to members of DscBuildData directly\r
113 _PROPERTY_ = {\r
114 #\r
115 # Required Fields\r
116 #\r
117 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",\r
118 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",\r
119 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",\r
120 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",\r
121 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",\r
122 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",\r
123 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",\r
124 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",\r
125 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",\r
126 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",\r
127 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
128 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",\r
129 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",\r
130 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",\r
131 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",\r
132 }\r
133\r
134 # used to compose dummy library class name for those forced library instances\r
135 _NullLibraryNumber = 0\r
136\r
137 ## Constructor of DscBuildData\r
138 #\r
139 # Initialize object of DscBuildData\r
140 #\r
141 # @param FilePath The path of platform description file\r
142 # @param RawData The raw data of DSC file\r
143 # @param BuildDataBase Database used to retrieve module/package information\r
144 # @param Arch The target architecture\r
145 # @param Platform (not used for DscBuildData)\r
146 # @param Macros Macros used for replacement in DSC file\r
147 #\r
148 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
149 self.MetaFile = FilePath\r
150 self._RawData = RawData\r
151 self._Bdb = BuildDataBase\r
152 self._Arch = Arch\r
153 self._Target = Target\r
154 self._Toolchain = Toolchain\r
155 self._Clear()\r
156 self._HandleOverridePath()\r
157 if os.getenv("WORKSPACE"):\r
158 self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)\r
159 else:\r
160 self.OutputPath = os.path.dirname(self.DscFile)\r
161 self.DefaultStores = None\r
162 self.SkuIdMgr = SkuClass(self.SkuIdentifier, self.SkuIds)\r
163 arraystr = self.SkuIdMgr.DumpSkuIdArrary()\r
164\r
165 ## XXX[key] = value\r
166 def __setitem__(self, key, value):\r
167 self.__dict__[self._PROPERTY_[key]] = value\r
168\r
169 ## value = XXX[key]\r
170 def __getitem__(self, key):\r
171 return self.__dict__[self._PROPERTY_[key]]\r
172\r
173 ## "in" test support\r
174 def __contains__(self, key):\r
175 return key in self._PROPERTY_\r
176\r
177 ## Set all internal used members of DscBuildData to None\r
178 def _Clear(self):\r
179 self._Header = None\r
180 self._PlatformName = None\r
181 self._Guid = None\r
182 self._Version = None\r
183 self._DscSpecification = None\r
184 self._OutputDirectory = None\r
185 self._SupArchList = None\r
186 self._BuildTargets = None\r
187 self._SkuName = None\r
188 self._SkuIdentifier = None\r
189 self._AvilableSkuIds = None\r
190 self._PcdInfoFlag = None\r
191 self._VarCheckFlag = None\r
192 self._FlashDefinition = None\r
193 self._Prebuild = None\r
194 self._Postbuild = None\r
195 self._BuildNumber = None\r
196 self._MakefileName = None\r
197 self._BsBaseAddress = None\r
198 self._RtBaseAddress = None\r
199 self._SkuIds = None\r
200 self._Modules = None\r
201 self._LibraryInstances = None\r
202 self._LibraryClasses = None\r
203 self._Pcds = None\r
204 self._DecPcds = None\r
205 self._BuildOptions = None\r
206 self._ModuleTypeOptions = None\r
207 self._LoadFixAddress = None\r
208 self._RFCLanguages = None\r
209 self._ISOLanguages = None\r
210 self._VpdToolGuid = None\r
211 self.__Macros = None\r
212 self.DefaultStores = None\r
213\r
214\r
215 ## handle Override Path of Module\r
216 def _HandleOverridePath(self):\r
217 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
218 Macros = self._Macros\r
219 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
220 for Record in RecordList:\r
221 ModuleId = Record[6]\r
222 LineNo = Record[7]\r
223 ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
224 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
225 if RecordList != []:\r
226 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
227\r
228 # Check if the source override path exists\r
229 if not os.path.isdir(SourceOverridePath):\r
230 EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r
231\r
232 # Add to GlobalData Variables\r
233 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r
234\r
235 ## Get current effective macros\r
236 def _GetMacros(self):\r
237 if self.__Macros == None:\r
238 self.__Macros = {}\r
239 self.__Macros.update(GlobalData.gPlatformDefines)\r
240 self.__Macros.update(GlobalData.gGlobalDefines)\r
241 self.__Macros.update(GlobalData.gCommandLineDefines)\r
242 return self.__Macros\r
243\r
244 ## Get architecture\r
245 def _GetArch(self):\r
246 return self._Arch\r
247\r
248 ## Set architecture\r
249 #\r
250 # Changing the default ARCH to another may affect all other information\r
251 # because all information in a platform may be ARCH-related. That's\r
252 # why we need to clear all internal used members, in order to cause all\r
253 # information to be re-retrieved.\r
254 #\r
255 # @param Value The value of ARCH\r
256 #\r
257 def _SetArch(self, Value):\r
258 if self._Arch == Value:\r
259 return\r
260 self._Arch = Value\r
261 self._Clear()\r
262\r
263 ## Retrieve all information in [Defines] section\r
264 #\r
265 # (Retriving all [Defines] information in one-shot is just to save time.)\r
266 #\r
267 def _GetHeaderInfo(self):\r
268 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
269 for Record in RecordList:\r
270 Name = Record[1]\r
271 # items defined _PROPERTY_ don't need additional processing\r
272\r
273 # some special items in [Defines] section need special treatment\r
274 if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
275 self._OutputDirectory = NormPath(Record[2], self._Macros)\r
276 if ' ' in self._OutputDirectory:\r
277 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
278 File=self.MetaFile, Line=Record[-1],\r
279 ExtraData=self._OutputDirectory)\r
280 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
281 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
282 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
283 if ErrorCode != 0:\r
284 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
285 ExtraData=ErrorInfo)\r
286 elif Name == TAB_DSC_PREBUILD:\r
287 PrebuildValue = Record[2]\r
288 if Record[2][0] == '"':\r
289 if Record[2][-1] != '"':\r
290 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,\r
291 File=self.MetaFile, Line=Record[-1])\r
292 PrebuildValue = Record[2][1:-1]\r
293 self._Prebuild = PrebuildValue\r
294 elif Name == TAB_DSC_POSTBUILD:\r
295 PostbuildValue = Record[2]\r
296 if Record[2][0] == '"':\r
297 if Record[2][-1] != '"':\r
298 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,\r
299 File=self.MetaFile, Line=Record[-1])\r
300 PostbuildValue = Record[2][1:-1]\r
301 self._Postbuild = PostbuildValue\r
302 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
303 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
304 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
305 self._BuildTargets = GetSplitValueList(Record[2])\r
306 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
307 if self._SkuName == None:\r
308 self._SkuName = Record[2]\r
309 self._SkuIdentifier = Record[2]\r
310 self._AvilableSkuIds = Record[2]\r
311 elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
312 self._PcdInfoFlag = Record[2]\r
313 elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
314 self._VarCheckFlag = Record[2]\r
315 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
316 try:\r
317 self._LoadFixAddress = int (Record[2], 0)\r
318 except:\r
319 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
320 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
321 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
322 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
323 File=self.MetaFile, Line=Record[-1])\r
324 LanguageCodes = Record[2][1:-1]\r
325 if not LanguageCodes:\r
326 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
327 File=self.MetaFile, Line=Record[-1])\r
328 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
329 # check whether there is empty entries in the list\r
330 if None in LanguageList:\r
331 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
332 File=self.MetaFile, Line=Record[-1])\r
333 self._RFCLanguages = LanguageList\r
334 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
335 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
336 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
337 File=self.MetaFile, Line=Record[-1])\r
338 LanguageCodes = Record[2][1:-1]\r
339 if not LanguageCodes:\r
340 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
341 File=self.MetaFile, Line=Record[-1])\r
342 if len(LanguageCodes) % 3:\r
343 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
344 File=self.MetaFile, Line=Record[-1])\r
345 LanguageList = []\r
346 for i in range(0, len(LanguageCodes), 3):\r
347 LanguageList.append(LanguageCodes[i:i + 3])\r
348 self._ISOLanguages = LanguageList\r
349 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
350 #\r
351 # try to convert GUID to a real UUID value to see whether the GUID is format\r
352 # for VPD_TOOL_GUID is correct.\r
353 #\r
354 try:\r
355 uuid.UUID(Record[2])\r
356 except:\r
357 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
358 self._VpdToolGuid = Record[2]\r
359 elif Name in self:\r
360 self[Name] = Record[2]\r
361 # set _Header to non-None in order to avoid database re-querying\r
362 self._Header = 'DUMMY'\r
363\r
364 ## Retrieve platform name\r
365 def _GetPlatformName(self):\r
366 if self._PlatformName == None:\r
367 if self._Header == None:\r
368 self._GetHeaderInfo()\r
369 if self._PlatformName == None:\r
370 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)\r
371 return self._PlatformName\r
372\r
373 ## Retrieve file guid\r
374 def _GetFileGuid(self):\r
375 if self._Guid == None:\r
376 if self._Header == None:\r
377 self._GetHeaderInfo()\r
378 if self._Guid == None:\r
379 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)\r
380 return self._Guid\r
381\r
382 ## Retrieve platform version\r
383 def _GetVersion(self):\r
384 if self._Version == None:\r
385 if self._Header == None:\r
386 self._GetHeaderInfo()\r
387 if self._Version == None:\r
388 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\r
389 return self._Version\r
390\r
391 ## Retrieve platform description file version\r
392 def _GetDscSpec(self):\r
393 if self._DscSpecification == None:\r
394 if self._Header == None:\r
395 self._GetHeaderInfo()\r
396 if self._DscSpecification == None:\r
397 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)\r
398 return self._DscSpecification\r
399\r
400 ## Retrieve OUTPUT_DIRECTORY\r
401 def _GetOutpuDir(self):\r
402 if self._OutputDirectory == None:\r
403 if self._Header == None:\r
404 self._GetHeaderInfo()\r
405 if self._OutputDirectory == None:\r
406 self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
407 return self._OutputDirectory\r
408\r
409 ## Retrieve SUPPORTED_ARCHITECTURES\r
410 def _GetSupArch(self):\r
411 if self._SupArchList == None:\r
412 if self._Header == None:\r
413 self._GetHeaderInfo()\r
414 if self._SupArchList == None:\r
415 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\r
416 return self._SupArchList\r
417\r
418 ## Retrieve BUILD_TARGETS\r
419 def _GetBuildTarget(self):\r
420 if self._BuildTargets == None:\r
421 if self._Header == None:\r
422 self._GetHeaderInfo()\r
423 if self._BuildTargets == None:\r
424 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
425 return self._BuildTargets\r
426\r
427 def _GetPcdInfoFlag(self):\r
428 if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
429 return False\r
430 elif self._PcdInfoFlag.upper() == 'TRUE':\r
431 return True\r
432 else:\r
433 return False\r
434 def _GetVarCheckFlag(self):\r
435 if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
436 return False\r
437 elif self._VarCheckFlag.upper() == 'TRUE':\r
438 return True\r
439 else:\r
440 return False\r
441 def _GetAviableSkuIds(self):\r
442 if self._AvilableSkuIds:\r
443 return self._AvilableSkuIds\r
444 return self.SkuIdentifier\r
445 def _GetSkuIdentifier(self):\r
446 if self._SkuName:\r
447 return self._SkuName\r
448 if self._SkuIdentifier == None:\r
449 if self._Header == None:\r
450 self._GetHeaderInfo()\r
451 return self._SkuIdentifier\r
452 ## Retrieve SKUID_IDENTIFIER\r
453 def _GetSkuName(self):\r
454 if self._SkuName == None:\r
455 if self._Header == None:\r
456 self._GetHeaderInfo()\r
457 if (self._SkuName == None or self._SkuName not in self.SkuIds):\r
458 self._SkuName = 'DEFAULT'\r
459 return self._SkuName\r
460\r
461 ## Override SKUID_IDENTIFIER\r
462 def _SetSkuName(self, Value):\r
463 self._SkuName = Value\r
464 self._Pcds = None\r
465\r
466 def _GetFdfFile(self):\r
467 if self._FlashDefinition == None:\r
468 if self._Header == None:\r
469 self._GetHeaderInfo()\r
470 if self._FlashDefinition == None:\r
471 self._FlashDefinition = ''\r
472 return self._FlashDefinition\r
473\r
474 def _GetPrebuild(self):\r
475 if self._Prebuild == None:\r
476 if self._Header == None:\r
477 self._GetHeaderInfo()\r
478 if self._Prebuild == None:\r
479 self._Prebuild = ''\r
480 return self._Prebuild\r
481\r
482 def _GetPostbuild(self):\r
483 if self._Postbuild == None:\r
484 if self._Header == None:\r
485 self._GetHeaderInfo()\r
486 if self._Postbuild == None:\r
487 self._Postbuild = ''\r
488 return self._Postbuild\r
489\r
490 ## Retrieve FLASH_DEFINITION\r
491 def _GetBuildNumber(self):\r
492 if self._BuildNumber == None:\r
493 if self._Header == None:\r
494 self._GetHeaderInfo()\r
495 if self._BuildNumber == None:\r
496 self._BuildNumber = ''\r
497 return self._BuildNumber\r
498\r
499 ## Retrieve MAKEFILE_NAME\r
500 def _GetMakefileName(self):\r
501 if self._MakefileName == None:\r
502 if self._Header == None:\r
503 self._GetHeaderInfo()\r
504 if self._MakefileName == None:\r
505 self._MakefileName = ''\r
506 return self._MakefileName\r
507\r
508 ## Retrieve BsBaseAddress\r
509 def _GetBsBaseAddress(self):\r
510 if self._BsBaseAddress == None:\r
511 if self._Header == None:\r
512 self._GetHeaderInfo()\r
513 if self._BsBaseAddress == None:\r
514 self._BsBaseAddress = ''\r
515 return self._BsBaseAddress\r
516\r
517 ## Retrieve RtBaseAddress\r
518 def _GetRtBaseAddress(self):\r
519 if self._RtBaseAddress == None:\r
520 if self._Header == None:\r
521 self._GetHeaderInfo()\r
522 if self._RtBaseAddress == None:\r
523 self._RtBaseAddress = ''\r
524 return self._RtBaseAddress\r
525\r
526 ## Retrieve the top address for the load fix address\r
527 def _GetLoadFixAddress(self):\r
528 if self._LoadFixAddress == None:\r
529 if self._Header == None:\r
530 self._GetHeaderInfo()\r
531\r
532 if self._LoadFixAddress == None:\r
533 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
534\r
535 try:\r
536 self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
537 except:\r
538 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
539\r
540 #\r
541 # If command line defined, should override the value in DSC file.\r
542 #\r
543 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
544 try:\r
545 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
546 except:\r
547 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
548\r
549 if self._LoadFixAddress < 0:\r
550 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
551 if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
552 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
553\r
554 return self._LoadFixAddress\r
555\r
556 ## Retrieve RFCLanguage filter\r
557 def _GetRFCLanguages(self):\r
558 if self._RFCLanguages == None:\r
559 if self._Header == None:\r
560 self._GetHeaderInfo()\r
561 if self._RFCLanguages == None:\r
562 self._RFCLanguages = []\r
563 return self._RFCLanguages\r
564\r
565 ## Retrieve ISOLanguage filter\r
566 def _GetISOLanguages(self):\r
567 if self._ISOLanguages == None:\r
568 if self._Header == None:\r
569 self._GetHeaderInfo()\r
570 if self._ISOLanguages == None:\r
571 self._ISOLanguages = []\r
572 return self._ISOLanguages\r
573 ## Retrieve the GUID string for VPD tool\r
574 def _GetVpdToolGuid(self):\r
575 if self._VpdToolGuid == None:\r
576 if self._Header == None:\r
577 self._GetHeaderInfo()\r
578 if self._VpdToolGuid == None:\r
579 self._VpdToolGuid = ''\r
580 return self._VpdToolGuid\r
581\r
582 ## Retrieve [SkuIds] section information\r
583 def _GetSkuIds(self):\r
584 if self._SkuIds == None:\r
585 self._SkuIds = sdict()\r
586 RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
587 for Record in RecordList:\r
588 if Record[0] in [None, '']:\r
589 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
590 File=self.MetaFile, Line=Record[-1])\r
591 if Record[1] in [None, '']:\r
592 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
593 File=self.MetaFile, Line=Record[-1])\r
594 Pattern = re.compile('^[1-9]\d*|0$')\r
595 if Pattern.match(Record[0]) == None:\r
596 EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. The correct format is '{(0-9)} {(1-9)(0-9)+}'",\r
597 File=self.MetaFile, Line=Record[-1])\r
598 if not IsValidWord(Record[1]):\r
599 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
600 File=self.MetaFile, Line=Record[-1])\r
601 self._SkuIds[Record[1].upper()] = (Record[0], Record[1].upper(), Record[2].upper())\r
602 if 'DEFAULT' not in self._SkuIds:\r
603 self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")\r
604 if 'COMMON' not in self._SkuIds:\r
605 self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")\r
606 return self._SkuIds\r
607 def ToInt(self,intstr):\r
608 return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr)\r
609 def _GetDefaultStores(self):\r
610 if self.DefaultStores == None:\r
611 self.DefaultStores = sdict()\r
612 RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]\r
613 for Record in RecordList:\r
614 if Record[0] in [None, '']:\r
615 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',\r
616 File=self.MetaFile, Line=Record[-1])\r
617 if Record[1] in [None, '']:\r
618 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',\r
619 File=self.MetaFile, Line=Record[-1])\r
620 self.DefaultStores[Record[1].upper()] = (self.ToInt(Record[0]),Record[1].upper())\r
621 if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:\r
622 self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT)\r
623 return self.DefaultStores\r
624\r
625 ## Retrieve [Components] section information\r
626 def _GetModules(self):\r
627 if self._Modules != None:\r
628 return self._Modules\r
629\r
630 self._Modules = sdict()\r
631 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
632 Macros = self._Macros\r
633 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
634 for Record in RecordList:\r
635 DuplicatedFile = False\r
636\r
637 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
638 ModuleId = Record[6]\r
639 LineNo = Record[7]\r
640\r
641 # check the file validation\r
642 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
643 if ErrorCode != 0:\r
644 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
645 ExtraData=ErrorInfo)\r
646 # Check duplication\r
647 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
648 if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
649 DuplicatedFile = True\r
650\r
651 Module = ModuleBuildClassObject()\r
652 Module.MetaFile = ModuleFile\r
653\r
654 # get module private library instance\r
655 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
656 for Record in RecordList:\r
657 LibraryClass = Record[0]\r
658 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
659 LineNo = Record[-1]\r
660\r
661 # check the file validation\r
662 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
663 if ErrorCode != 0:\r
664 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
665 ExtraData=ErrorInfo)\r
666\r
667 if LibraryClass == '' or LibraryClass == 'NULL':\r
668 self._NullLibraryNumber += 1\r
669 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
670 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
671 Module.LibraryClasses[LibraryClass] = LibraryPath\r
672 if LibraryPath not in self.LibraryInstances:\r
673 self.LibraryInstances.append(LibraryPath)\r
674\r
675 # get module private PCD setting\r
676 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
677 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
678 RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
679 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
680 TokenList = GetSplitValueList(Setting)\r
681 DefaultValue = TokenList[0]\r
682 if len(TokenList) > 1:\r
683 MaxDatumSize = TokenList[1]\r
684 else:\r
685 MaxDatumSize = ''\r
686 TypeString = self._PCD_TYPE_STRING_[Type]\r
687 Pcd = PcdClassObject(\r
688 PcdCName,\r
689 TokenSpaceGuid,\r
690 TypeString,\r
691 '',\r
692 DefaultValue,\r
693 '',\r
694 MaxDatumSize,\r
695 {},\r
696 False,\r
697 None\r
698 )\r
699 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
700\r
701 # get module private build options\r
702 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
703 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
704 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
705 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
706 else:\r
707 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
708 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
709\r
710 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
711 if DuplicatedFile and not RecordList:\r
712 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
713 if RecordList:\r
714 if len(RecordList) != 1:\r
715 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
716 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
717 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
718 ModuleFile.Arch = self._Arch\r
719\r
720 self._Modules[ModuleFile] = Module\r
721 return self._Modules\r
722\r
723 ## Retrieve all possible library instances used in this platform\r
724 def _GetLibraryInstances(self):\r
725 if self._LibraryInstances == None:\r
726 self._GetLibraryClasses()\r
727 return self._LibraryInstances\r
728\r
729 ## Retrieve [LibraryClasses] information\r
730 def _GetLibraryClasses(self):\r
731 if self._LibraryClasses == None:\r
732 self._LibraryInstances = []\r
733 #\r
734 # tdict is a special dict kind of type, used for selecting correct\r
735 # library instance for given library class and module type\r
736 #\r
737 LibraryClassDict = tdict(True, 3)\r
738 # track all library class names\r
739 LibraryClassSet = set()\r
740 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r
741 Macros = self._Macros\r
742 for Record in RecordList:\r
743 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record\r
744 if LibraryClass == '' or LibraryClass == 'NULL':\r
745 self._NullLibraryNumber += 1\r
746 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
747 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
748 LibraryClassSet.add(LibraryClass)\r
749 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
750 # check the file validation\r
751 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
752 if ErrorCode != 0:\r
753 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
754 ExtraData=ErrorInfo)\r
755\r
756 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
757 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
758 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r
759 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
760 if LibraryInstance not in self._LibraryInstances:\r
761 self._LibraryInstances.append(LibraryInstance)\r
762\r
763 # resolve the specific library instance for each class and each module type\r
764 self._LibraryClasses = tdict(True)\r
765 for LibraryClass in LibraryClassSet:\r
766 # try all possible module types\r
767 for ModuleType in SUP_MODULE_LIST:\r
768 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
769 if LibraryInstance == None:\r
770 continue\r
771 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
772\r
773 # for Edk style library instances, which are listed in different section\r
774 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
775 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
776 for Record in RecordList:\r
777 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
778 LineNo = Record[-1]\r
779 # check the file validation\r
780 ErrorCode, ErrorInfo = File.Validate('.inf')\r
781 if ErrorCode != 0:\r
782 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
783 ExtraData=ErrorInfo)\r
784 if File not in self._LibraryInstances:\r
785 self._LibraryInstances.append(File)\r
786 #\r
787 # we need the module name as the library class name, so we have\r
788 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
789 # hasn't been parsed)\r
790 #\r
791 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
792 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
793 return self._LibraryClasses\r
794\r
795 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
796 if self._DecPcds == None:\r
797\r
798 FdfInfList = []\r
799 if GlobalData.gFdfParser:\r
800 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
801\r
802 PkgSet = set()\r
803 for Inf in FdfInfList:\r
804 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
805 if ModuleFile in self._Modules:\r
806 continue\r
807 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
808 PkgSet.update(ModuleData.Packages)\r
809\r
810 self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
811\r
812\r
813 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
814 EdkLogger.error('build', PARSER_ERROR,\r
815 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
816 File=self.MetaFile, Line=LineNo)\r
817 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
818 if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
819 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
820 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
821 if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
822 try:\r
823 ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
824 except WrnExpression, Value:\r
825 ValueList[Index] = Value.result\r
826 except EvaluationException, Excpt:\r
827 if hasattr(Excpt, 'Pcd'):\r
828 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
829 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
830 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
831 " of the DSC file" % Excpt.Pcd,\r
832 File=self.MetaFile, Line=LineNo)\r
833 else:\r
834 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
835 File=self.MetaFile, Line=LineNo)\r
836 else:\r
837 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
838 File=self.MetaFile, Line=LineNo)\r
839 if ValueList[Index] == 'True':\r
840 ValueList[Index] = '1'\r
841 elif ValueList[Index] == 'False':\r
842 ValueList[Index] = '0'\r
843 if ValueList[Index]:\r
844 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
845 if not Valid:\r
846 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
847 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
848 return ValueList\r
849\r
850 def _FilterPcdBySkuUsage(self,Pcds):\r
851 available_sku = self.SkuIdMgr.AvailableSkuIdSet\r
852 sku_usage = self.SkuIdMgr.SkuUsageType\r
853 if sku_usage == SkuClass.SINGLE:\r
854 for pcdname in Pcds:\r
855 pcd = Pcds[pcdname]\r
856 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
857 else:\r
858 for pcdname in Pcds:\r
859 pcd = Pcds[pcdname]\r
860 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
861 return Pcds\r
862 def CompleteHiiPcdsDefaultStores(self,Pcds):\r
863 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
864 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
865 for pcd in HiiPcd:\r
866 for skuid in pcd.SkuInfoList:\r
867 skuobj = pcd.SkuInfoList.get(skuid)\r
868 if "STANDARD" not in skuobj.DefaultStoreDict:\r
869 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])\r
870 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
871 skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
872 return Pcds\r
873\r
874 ## Retrieve all PCD settings in platform\r
875 def _GetPcds(self):\r
876 if self._Pcds == None:\r
877 self._Pcds = sdict()\r
878 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
879 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
880 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
881 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
882 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
883 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
884 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
885 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
886 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
887\r
888 self._Pcds = self.CompletePcdValues(self._Pcds)\r
889 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
890 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
891 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
892 return self._Pcds\r
893\r
894 def _dumpPcdInfo(self,Pcds):\r
895 for pcd in Pcds:\r
896 pcdobj = Pcds[pcd]\r
897 if not pcdobj.TokenCName.startswith("Test"):\r
898 continue\r
899 for skuid in pcdobj.SkuInfoList:\r
900 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r
901 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r
902 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r
903 else:\r
904 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r
905 ## Retrieve [BuildOptions]\r
906 def _GetBuildOptions(self):\r
907 if self._BuildOptions == None:\r
908 self._BuildOptions = sdict()\r
909 #\r
910 # Retrieve build option for EDKII and EDK style module\r
911 #\r
912 for CodeBase in (EDKII_NAME, EDK_NAME):\r
913 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
914 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
915 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
916 #\r
917 # Only flags can be appended\r
918 #\r
919 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
920 self._BuildOptions[CurKey] = Option\r
921 else:\r
922 self._BuildOptions[CurKey] += ' ' + Option\r
923 return self._BuildOptions\r
924\r
925 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
926 if self._ModuleTypeOptions == None:\r
927 self._ModuleTypeOptions = sdict()\r
928 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
929 options = sdict()\r
930 self._ModuleTypeOptions[Edk, ModuleType] = options\r
931 DriverType = '%s.%s' % (Edk, ModuleType)\r
932 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
933 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
934 for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4,Dummy5 in RecordList:\r
935 if Type == DriverType or Type == CommonDriverType:\r
936 Key = (ToolChainFamily, ToolChain, Edk)\r
937 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
938 options[Key] = Option\r
939 else:\r
940 options[Key] += ' ' + Option\r
941 return self._ModuleTypeOptions[Edk, ModuleType]\r
942\r
943 def GetStructurePcdInfo(self, PcdSet):\r
944 structure_pcd_data = {}\r
945 for item in PcdSet:\r
946 if (item[0],item[1]) not in structure_pcd_data:\r
947 structure_pcd_data[(item[0],item[1])] = []\r
948 structure_pcd_data[(item[0],item[1])].append(item)\r
949\r
950 return structure_pcd_data\r
951\r
952 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
953 Pcds = AllPcds\r
954 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
955 SkuIds = set([skuid for pcdobj in AllPcds.values() for skuid in pcdobj.SkuInfoList.keys()])\r
956 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
957\r
958 S_PcdSet = []\r
959 # Find out all possible PCD candidates for self._Arch\r
960 RecordList = []\r
961\r
962 for Type in TypeList:\r
963 RecordList.extend(self._RawData[Type, self._Arch])\r
964\r
965 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r
966 SkuName = SkuName.upper()\r
967 default_store = default_store.upper()\r
968 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
969 if SkuName not in SkuIds:\r
970 continue\r
971\r
972 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
973 S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]))\r
974\r
975 # handle pcd value override\r
976 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
977 S_pcd_set = {}\r
978 for str_pcd in StrPcdSet:\r
979 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
980 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
981 if str_pcd_dec:\r
982 str_pcd_obj_str = StructurePcd()\r
983 str_pcd_obj_str.copy(str_pcd_dec)\r
984 if str_pcd_obj:\r
985 str_pcd_obj_str.copy(str_pcd_obj)\r
986 if str_pcd_obj.DefaultValue:\r
987 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
988 for str_pcd_data in StrPcdSet[str_pcd]:\r
989 if str_pcd_data[3] in SkuIds:\r
990 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,LineNo=str_pcd_data[5])\r
991 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
992 else:\r
993 EdkLogger.error('build', PARSER_ERROR,\r
994 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
995 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r
996 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
997 for Pcd in self._DecPcds:\r
998 if type (self._DecPcds[Pcd]) is StructurePcd:\r
999 if Pcd not in S_pcd_set:\r
1000 str_pcd_obj_str = StructurePcd()\r
1001 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1002 str_pcd_obj = Pcds.get(Pcd, None)\r
1003 if str_pcd_obj:\r
1004 str_pcd_obj_str.copy(str_pcd_obj)\r
1005 if str_pcd_obj.DefaultValue:\r
1006 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1007 S_pcd_set[Pcd] = str_pcd_obj_str\r
1008 if S_pcd_set:\r
1009 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
1010 for stru_pcd in S_pcd_set.values():\r
1011 if stru_pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1012 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1013 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1014 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1015 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1016 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1017 continue\r
1018 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1019 for skuid in SkuIds:\r
1020 nextskuid = skuid\r
1021 NoDefault = False\r
1022 if skuid not in stru_pcd.SkuOverrideValues:\r
1023 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1024 if nextskuid == "DEFAULT":\r
1025 NoDefault = True\r
1026 break\r
1027 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1028 stru_pcd.SkuOverrideValues[skuid] = {}\r
1029 if NoDefault:\r
1030 continue\r
1031 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])\r
1032 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
1033\r
1034 for defaultstoreid in DefaultStores:\r
1035 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
1036 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
1037 for skuid in SkuIds:\r
1038 if skuid in stru_pcd.SkuOverrideValues:\r
1039 continue\r
1040 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1041 NoDefault = False\r
1042 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1043 if nextskuid == "DEFAULT":\r
1044 NoDefault = True\r
1045 break\r
1046 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1047 stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores})\r
1048 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1049 if Str_Pcd_Values:\r
1050 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r
1051 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
1052 if str_pcd_obj is None:\r
1053 raise\r
1054 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1055 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1056 if skuname not in str_pcd_obj.SkuInfoList:\r
1057 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
1058 else:\r
1059 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1060 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
1061 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1062 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
1063 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1064 str_pcd_obj.DefaultValue = PcdValue\r
1065 else:\r
1066 if skuname not in str_pcd_obj.SkuInfoList:\r
1067 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)\r
1068 else:\r
1069 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1070 for str_pcd_obj in S_pcd_set.values():\r
1071 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1072 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1073 continue\r
1074 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r
1075 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1076 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1077 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
1078\r
1079 for str_pcd_obj in S_pcd_set.values():\r
1080\r
1081 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1082 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
1083\r
1084 return Pcds\r
1085\r
1086 ## Retrieve non-dynamic PCD settings\r
1087 #\r
1088 # @param Type PCD type\r
1089 #\r
1090 # @retval a dict object contains settings of given PCD type\r
1091 #\r
1092 def _GetPcd(self, Type):\r
1093 Pcds = sdict()\r
1094 #\r
1095 # tdict is a special dict kind of type, used for selecting correct\r
1096 # PCD settings for certain ARCH\r
1097 #\r
1098 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
1099\r
1100 PcdDict = tdict(True, 3)\r
1101 PcdSet = set()\r
1102 # Find out all possible PCD candidates for self._Arch\r
1103 RecordList = self._RawData[Type, self._Arch]\r
1104 PcdValueDict = sdict()\r
1105 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
1106 SkuName = SkuName.upper()\r
1107 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1108 if SkuName not in AvailableSkuIdSet:\r
1109 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1110 File=self.MetaFile, Line=Dummy5)\r
1111 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1112 if "." not in TokenSpaceGuid:\r
1113 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1114 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
1115\r
1116 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1117 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
1118 if Setting == None:\r
1119 continue\r
1120 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1121 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1122 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1123 else:\r
1124 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1125\r
1126 PcdsKeys = PcdValueDict.keys()\r
1127 for PcdCName, TokenSpaceGuid in PcdsKeys:\r
1128\r
1129 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
1130 PcdValue = None\r
1131 DatumType = None\r
1132 MaxDatumSize = None\r
1133 if 'COMMON' in PcdSetting:\r
1134 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
1135 if 'DEFAULT' in PcdSetting:\r
1136 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
1137 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1138 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
1139\r
1140 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1141 PcdCName,\r
1142 TokenSpaceGuid,\r
1143 self._PCD_TYPE_STRING_[Type],\r
1144 DatumType,\r
1145 PcdValue,\r
1146 '',\r
1147 MaxDatumSize,\r
1148 {},\r
1149 False,\r
1150 None,\r
1151 IsDsc=True)\r
1152\r
1153\r
1154 return Pcds\r
1155\r
1156 def __UNICODE2OCTList(self,Value):\r
1157 Value = Value.strip()\r
1158 Value = Value[2:-1]\r
1159 List = []\r
1160 for Item in Value:\r
1161 Temp = '%04X' % ord(Item)\r
1162 List.append('0x' + Temp[2:4])\r
1163 List.append('0x' + Temp[0:2])\r
1164 List.append('0x00')\r
1165 List.append('0x00')\r
1166 return List\r
1167 def __STRING2OCTList(self,Value):\r
1168 OCTList = []\r
1169 Value = Value.strip('"')\r
1170 for char in Value:\r
1171 Temp = '%02X' % ord(char)\r
1172 OCTList.append('0x' + Temp)\r
1173 OCTList.append('0x00')\r
1174 return OCTList\r
1175\r
1176 def GetStructurePcdMaxSize(self, str_pcd):\r
1177 pcd_default_value = str_pcd.DefaultValue\r
1178 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
1179 sku_values.append(pcd_default_value)\r
1180\r
1181 def get_length(value):\r
1182 Value = value.strip()\r
1183 if Value.startswith('GUID') and Value.endswith(')'):\r
1184 return 16\r
1185 if Value.startswith('L"') and Value.endswith('"'):\r
1186 return len(Value[2:-1])\r
1187 if Value[0] == '"' and Value[-1] == '"':\r
1188 return len(Value) - 2\r
1189 if Value[0] == '{' and Value[-1] == '}':\r
1190 return len(Value.split(","))\r
1191 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1192 return len(list(Value[2:-1]))\r
1193 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1194 return len(Value) - 2\r
1195 return len(Value)\r
1196\r
1197 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
1198\r
1199 def IsFieldValueAnArray (self, Value):\r
1200 Value = Value.strip()\r
1201 if Value.startswith('GUID') and Value.endswith(')'):\r
1202 return True\r
1203 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:\r
1204 return True\r
1205 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
1206 return True\r
1207 if Value[0] == '{' and Value[-1] == '}':\r
1208 return True\r
1209 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1210 print 'foo = ', list(Value[2:-1])\r
1211 return True\r
1212 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1213 print 'bar = ', list(Value[1:-1])\r
1214 return True\r
1215 return False\r
1216\r
1217 def ExecuteCommand (self, Command):\r
1218 try:\r
1219 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1220 except:\r
1221 print 'ERROR: Can not execute command:', Command\r
1222 sys.exit(1)\r
1223 Result = Process.communicate()\r
1224 if Process.returncode <> 0:\r
1225 print 'ERROR: Can not collect output from command:', Command\r
1226 return Result[0], Result[1]\r
1227\r
1228 def IntToCString(self, Value, ValueSize):\r
1229 Result = '"'\r
1230 if not isinstance (Value, str):\r
1231 for Index in range(0, ValueSize):\r
1232 Result = Result + '\\x%02x' % (Value & 0xff)\r
1233 Value = Value >> 8\r
1234 Result = Result + '"'\r
1235 return Result\r
1236\r
1237 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
1238 OverrideValues = {DefaultStoreName:""}\r
1239 if Pcd.SkuOverrideValues:\r
1240 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
1241 for DefaultStoreName in OverrideValues.keys():\r
1242 CApp = CApp + 'void\n'\r
1243 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1244 CApp = CApp + ' void\n'\r
1245 CApp = CApp + ' )\n'\r
1246 CApp = CApp + '{\n'\r
1247 CApp = CApp + ' UINT32 Size;\n'\r
1248 CApp = CApp + ' UINT32 FieldSize;\n'\r
1249 CApp = CApp + ' UINT8 *Value;\n'\r
1250 CApp = CApp + ' UINT32 OriginalSize;\n'\r
1251 CApp = CApp + ' VOID *OriginalPcd;\n'\r
1252 CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType)\r
1253 CApp = CApp + '\n'\r
1254 Pcd.DefaultValue = Pcd.DefaultValue.strip()\r
1255 if Pcd.DefaultValue.startswith('L"') and Pcd.DefaultValue.endswith('"'):\r
1256 PcdDefaultValue = "{" + ",".join(self.__UNICODE2OCTList(Pcd.DefaultValue)) + "}"\r
1257 elif Pcd.DefaultValue.startswith('"') and Pcd.DefaultValue.endswith('"'):\r
1258 PcdDefaultValue = "{" + ",".join(self.__STRING2OCTList(Pcd.DefaultValue)) + "}"\r
1259 else:\r
1260 PcdDefaultValue = Pcd.DefaultValue\r
1261 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
1262\r
1263 #\r
1264 # Get current PCD value and size\r
1265 #\r
1266 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1267\r
1268 #\r
1269 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
1270 # the correct value. For structures with a flexible array member, the flexible\r
1271 # array member is detected, and the size is based on the highest index used with\r
1272 # the flexible array member. The flexible array member must be the last field\r
1273 # in a structure. The size formula for this case is:\r
1274 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
1275 #\r
1276 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
1277 for FieldList in [Pcd.DefaultValues, OverrideValues.get(DefaultStoreName)]:\r
1278 if not FieldList:\r
1279 continue\r
1280 for FieldName in FieldList:\r
1281 FieldName = "." + FieldName\r
1282 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1283 if IsArray:\r
1284 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1285 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."));\r
1286 else:\r
1287 NewFieldName = ''\r
1288 while '[' in FieldName:\r
1289 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1290 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1291 FieldName = FieldName.split(']', 1)[1]\r
1292 FieldName = NewFieldName + FieldName\r
1293 while '[' in FieldName:\r
1294 FieldName = FieldName.rsplit('[', 1)[0]\r
1295 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
1296\r
1297 #\r
1298 # Allocate and zero buffer for the PCD\r
1299 # Must handle cases where current value is smaller, larger, or same size\r
1300 # Always keep that larger one as the current size\r
1301 #\r
1302 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
1303 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
1304 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
1305\r
1306 #\r
1307 # Copy current PCD value into allocated buffer.\r
1308 #\r
1309 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
1310\r
1311 #\r
1312 # Assign field values in PCD\r
1313 #\r
1314 for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC,OverrideValues.get(DefaultStoreName)]:\r
1315 if not FieldList:\r
1316 continue\r
1317 if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:\r
1318 IsArray = self.IsFieldValueAnArray(FieldList)\r
1319 Value, ValueSize = ParseFieldValue (FieldList)\r
1320 if isinstance(Value, str):\r
1321 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)\r
1322 elif IsArray:\r
1323 #\r
1324 # Use memcpy() to copy value into field\r
1325 #\r
1326 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)\r
1327 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1328 continue\r
1329\r
1330 for FieldName in FieldList:\r
1331 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1332 try:\r
1333 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1334 except Exception:\r
1335 print FieldList[FieldName][0]\r
1336 if isinstance(Value, str):\r
1337 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1338 elif IsArray:\r
1339 #\r
1340 # Use memcpy() to copy value into field\r
1341 #\r
1342 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1343 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
1344 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
1345 else:\r
1346 if ValueSize > 4:\r
1347 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1348 else:\r
1349 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1350\r
1351 #\r
1352 # Set new PCD value and size\r
1353 #\r
1354 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1355\r
1356 #\r
1357 # Free PCD\r
1358 #\r
1359 CApp = CApp + ' free (Pcd);\n'\r
1360 CApp = CApp + '}\n'\r
1361 CApp = CApp + '\n'\r
1362 return InitByteValue, CApp\r
1363\r
1364 def GenerateByteArrayValue (self, StructuredPcds):\r
1365 #\r
1366 # Generate/Compile/Run C application to determine if there are any flexible array members\r
1367 #\r
1368 if not StructuredPcds:\r
1369 return\r
1370\r
1371 InitByteValue = ""\r
1372 CApp = PcdMainCHeader\r
1373\r
1374 Includes = {}\r
1375 for PcdName in StructuredPcds:\r
1376 Pcd = StructuredPcds[PcdName]\r
1377 IncludeFile = Pcd.StructuredPcdIncludeFile\r
1378 if IncludeFile not in Includes:\r
1379 Includes[IncludeFile] = True\r
1380 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
1381 CApp = CApp + '\n'\r
1382\r
1383 for PcdName in StructuredPcds:\r
1384 Pcd = StructuredPcds[PcdName]\r
1385 if not Pcd.SkuOverrideValues:\r
1386 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
1387 else:\r
1388 for SkuName in Pcd.SkuOverrideValues:\r
1389 for DefaultStoreName in Pcd.DefaultStoreName:\r
1390 Pcd = StructuredPcds[PcdName]\r
1391 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
1392\r
1393 CApp = CApp + 'VOID\n'\r
1394 CApp = CApp + 'PcdEntryPoint(\n'\r
1395 CApp = CApp + ' VOID\n'\r
1396 CApp = CApp + ' )\n'\r
1397 CApp = CApp + '{\n'\r
1398 for Pcd in StructuredPcds.values():\r
1399 if not Pcd.SkuOverrideValues:\r
1400 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1401 else:\r
1402 for SkuName in Pcd.SkuOverrideValues:\r
1403 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
1404 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1405 CApp = CApp + '}\n'\r
1406\r
1407 CApp = CApp + PcdMainCEntry + '\n'\r
1408\r
1409 if not os.path.exists(self.OutputPath):\r
1410 os.makedirs(self.OutputPath)\r
1411 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1412 File = open (CAppBaseFileName + '.c', 'w')\r
1413 File.write(CApp)\r
1414 File.close()\r
1415\r
1416 MakeApp = PcdMakefileHeader\r
1417 if sys.platform == "win32":\r
1418 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
1419 else:\r
1420 MakeApp = MakeApp + PcdGccMakefile\r
1421 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
1422 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='\r
1423\r
1424 PlatformInc = {}\r
1425 for Cache in self._Bdb._CACHE_.values():\r
1426 if Cache.MetaFile.Ext.lower() != '.dec':\r
1427 continue\r
1428 if Cache.Includes:\r
1429 if str(Cache.MetaFile.Path) not in PlatformInc:\r
1430 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
1431\r
1432 PcdDependDEC = []\r
1433 for Pcd in StructuredPcds.values():\r
1434 for PackageDec in Pcd.PackageDecs:\r
1435 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
1436 if not os.path.exists(Package):\r
1437 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1438 if Package not in PcdDependDEC:\r
1439 PcdDependDEC.append(Package)\r
1440\r
1441 if PlatformInc and PcdDependDEC:\r
1442 for pkg in PcdDependDEC:\r
1443 if pkg in PlatformInc:\r
1444 for inc in PlatformInc[pkg]:\r
1445 MakeApp += '-I' + str(inc) + ' '\r
1446 MakeApp = MakeApp + '\n'\r
1447 if sys.platform == "win32":\r
1448 MakeApp = MakeApp + PcdMakefileEnd\r
1449 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
1450 File = open (MakeFileName, 'w')\r
1451 File.write(MakeApp)\r
1452 File.close()\r
1453\r
1454 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
1455 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
1456 File = open (InputValueFile, 'w')\r
1457 File.write(InitByteValue)\r
1458 File.close()\r
1459\r
1460 if sys.platform == "win32":\r
1461 StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))\r
1462 else:\r
1463 StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
1464 Messages = StdOut.split('\r')\r
1465 for Message in Messages:\r
1466 if " error " in Message:\r
1467 FileInfo = Message.strip().split('(')\r
1468 if len (FileInfo) > 0:\r
1469 FileName = FileInfo [0]\r
1470 FileLine = FileInfo [1].split (')')[0]\r
1471 else:\r
1472 FileInfo = Message.strip().split(':')\r
1473 FileName = FileInfo [0]\r
1474 FileLine = FileInfo [1]\r
1475\r
1476 File = open (FileName, 'r')\r
1477 FileData = File.readlines()\r
1478 File.close()\r
1479 error_line = FileData[int (FileLine) - 1]\r
1480 if r"//" in error_line:\r
1481 c_line,dsc_line = error_line.split(r"//")\r
1482 else:\r
1483 dsc_line = error_line\r
1484\r
1485 message_itmes = Message.split(":")\r
1486 for item in message_itmes:\r
1487 if "PcdValueInit.c" in item:\r
1488 message_itmes[message_itmes.index(item)] = dsc_line.strip()\r
1489\r
1490 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:]))\r
1491\r
1492 PcdValueInitExe = PcdValueInitName\r
1493 if not sys.platform == "win32":\r
1494 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
1495\r
1496 StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))\r
1497 File = open (OutputValueFile, 'r')\r
1498 FileBuffer = File.readlines()\r
1499 File.close()\r
1500\r
1501 StructurePcdSet = []\r
1502 for Pcd in FileBuffer:\r
1503 PcdValue = Pcd.split ('|')\r
1504 PcdInfo = PcdValue[0].split ('.')\r
1505 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
1506 return StructurePcdSet\r
1507\r
1508 ## Retrieve dynamic PCD settings\r
1509 #\r
1510 # @param Type PCD type\r
1511 #\r
1512 # @retval a dict object contains settings of given PCD type\r
1513 #\r
1514 def _GetDynamicPcd(self, Type):\r
1515\r
1516\r
1517 Pcds = sdict()\r
1518 #\r
1519 # tdict is a special dict kind of type, used for selecting correct\r
1520 # PCD settings for certain ARCH and SKU\r
1521 #\r
1522 PcdDict = tdict(True, 4)\r
1523 PcdList = []\r
1524 # Find out all possible PCD candidates for self._Arch\r
1525 RecordList = self._RawData[Type, self._Arch]\r
1526 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
1527\r
1528\r
1529 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
1530 SkuName = SkuName.upper()\r
1531 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1532 if SkuName not in AvailableSkuIdSet:\r
1533 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1534 File=self.MetaFile, Line=Dummy5)\r
1535 if "." not in TokenSpaceGuid:\r
1536 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1537 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1538\r
1539 # Remove redundant PCD candidates, per the ARCH and SKU\r
1540 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1541\r
1542 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1543 if Setting == None:\r
1544 continue\r
1545\r
1546 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1547 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
1548 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1549 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1550 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1551 if MaxDatumSize.strip():\r
1552 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1553 else:\r
1554 CurrentMaxSize = 0\r
1555 if pcdObject.MaxDatumSize:\r
1556 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1557 else:\r
1558 PcdMaxSize = 0\r
1559 if CurrentMaxSize > PcdMaxSize:\r
1560 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1561 else:\r
1562 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1563 PcdCName,\r
1564 TokenSpaceGuid,\r
1565 self._PCD_TYPE_STRING_[Type],\r
1566 DatumType,\r
1567 PcdValue,\r
1568 '',\r
1569 MaxDatumSize,\r
1570 {SkuName : SkuInfo},\r
1571 False,\r
1572 None,\r
1573 IsDsc=True)\r
1574\r
1575 for pcd in Pcds.values():\r
1576 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1577 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1578 valuefromDec = pcdDecObject.DefaultValue\r
1579 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
1580 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1581 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1582 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1583 del(pcd.SkuInfoList['COMMON'])\r
1584 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1585 del(pcd.SkuInfoList['COMMON'])\r
1586 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1587 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1588 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1589 del(pcd.SkuInfoList['DEFAULT'])\r
1590\r
1591 return Pcds\r
1592\r
1593 def CompareVarAttr(self, Attr1, Attr2):\r
1594 if not Attr1 or not Attr2: # for empty string\r
1595 return True\r
1596 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
1597 Attr1Set = set(Attr1s)\r
1598 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
1599 Attr2Set = set(Attr2s)\r
1600 if Attr2Set == Attr1Set:\r
1601 return True\r
1602 else:\r
1603 return False\r
1604 def CompletePcdValues(self,PcdSet):\r
1605 Pcds = {}\r
1606 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1607 SkuIds = set([(skuid,skuobj.SkuId) for pcdobj in PcdSet.values() for skuid,skuobj in pcdobj.SkuInfoList.items()])\r
1608 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
1609 for PcdCName, TokenSpaceGuid in PcdSet:\r
1610 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
1611 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1612 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1613 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1614 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1615 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1616 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1617 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1618 continue\r
1619 PcdType = PcdObj.Type\r
1620 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1621 for skuid in PcdObj.SkuInfoList:\r
1622 skuobj = PcdObj.SkuInfoList[skuid]\r
1623 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r
1624 for defaultstorename in DefaultStores:\r
1625 if defaultstorename not in skuobj.DefaultStoreDict:\r
1626 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
1627 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
1628 for skuname,skuid in SkuIds:\r
1629 if skuname not in PcdObj.SkuInfoList:\r
1630 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
1631 while nextskuid not in PcdObj.SkuInfoList:\r
1632 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1633 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r
1634 PcdObj.SkuInfoList[skuname].SkuId = skuid\r
1635 PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r
1636 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1637 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r
1638 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1639 return Pcds\r
1640 ## Retrieve dynamic HII PCD settings\r
1641 #\r
1642 # @param Type PCD type\r
1643 #\r
1644 # @retval a dict object contains settings of given PCD type\r
1645 #\r
1646 def _GetDynamicHiiPcd(self, Type):\r
1647\r
1648 VariableAttrs = {}\r
1649\r
1650 Pcds = sdict()\r
1651 #\r
1652 # tdict is a special dict kind of type, used for selecting correct\r
1653 # PCD settings for certain ARCH and SKU\r
1654 #\r
1655 PcdDict = tdict(True, 5)\r
1656 PcdSet = set()\r
1657 RecordList = self._RawData[Type, self._Arch]\r
1658 # Find out all possible PCD candidates for self._Arch\r
1659 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
1660 DefaultStoresDefine = self._GetDefaultStores()\r
1661\r
1662 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r
1663 SkuName = SkuName.upper()\r
1664 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1665 DefaultStore = DefaultStore.upper()\r
1666 if DefaultStore == "COMMON":\r
1667 DefaultStore = "STANDARD"\r
1668 if SkuName not in AvailableSkuIdSet:\r
1669 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1670 File=self.MetaFile, Line=Dummy5)\r
1671 if DefaultStore not in DefaultStoresDefine:\r
1672 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r
1673 File=self.MetaFile, Line=Dummy5)\r
1674 if "." not in TokenSpaceGuid:\r
1675 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4))\r
1676 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r
1677\r
1678\r
1679 # Remove redundant PCD candidates, per the ARCH and SKU\r
1680 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r
1681\r
1682 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r
1683 if Setting == None:\r
1684 continue\r
1685 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1686\r
1687 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
1688 if not rt:\r
1689 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
1690 ExtraData="[%s]" % VarAttribute)\r
1691 ExceedMax = False\r
1692 FormatCorrect = True\r
1693 if VariableOffset.isdigit():\r
1694 if int(VariableOffset, 10) > 0xFFFF:\r
1695 ExceedMax = True\r
1696 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
1697 if int(VariableOffset, 16) > 0xFFFF:\r
1698 ExceedMax = True\r
1699 # For Offset written in "A.B"\r
1700 elif VariableOffset.find('.') > -1:\r
1701 VariableOffsetList = VariableOffset.split(".")\r
1702 if not (len(VariableOffsetList) == 2\r
1703 and IsValidWord(VariableOffsetList[0])\r
1704 and IsValidWord(VariableOffsetList[1])):\r
1705 FormatCorrect = False\r
1706 else:\r
1707 FormatCorrect = False\r
1708 if not FormatCorrect:\r
1709 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
1710\r
1711 if ExceedMax:\r
1712 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
1713 if (VariableName, VariableGuid) not in VariableAttrs:\r
1714 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1715 else:\r
1716 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1717 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
1718\r
1719 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
1720 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1721 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1722 if SkuName in pcdObject.SkuInfoList:\r
1723 Skuitem = pcdObject.SkuInfoList[SkuName]\r
1724 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
1725 else:\r
1726 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
1727 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1728 else:\r
1729 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
1730 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1731 PcdCName,\r
1732 TokenSpaceGuid,\r
1733 self._PCD_TYPE_STRING_[Type],\r
1734 '',\r
1735 DefaultValue,\r
1736 '',\r
1737 '',\r
1738 {SkuName : SkuInfo},\r
1739 False,\r
1740 None,\r
1741 pcdDecObject.validateranges,\r
1742 pcdDecObject.validlists,\r
1743 pcdDecObject.expressions,\r
1744 IsDsc=True)\r
1745\r
1746\r
1747 for pcd in Pcds.values():\r
1748 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1749 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1750 # Only fix the value while no value provided in DSC file.\r
1751 for sku in pcd.SkuInfoList.values():\r
1752 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
1753 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1754 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1755 valuefromDec = pcdDecObject.DefaultValue\r
1756 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})\r
1757 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1758 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1759 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1760 del(pcd.SkuInfoList['COMMON'])\r
1761 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1762 del(pcd.SkuInfoList['COMMON'])\r
1763\r
1764 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1765 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1766 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1767 del(pcd.SkuInfoList['DEFAULT'])\r
1768\r
1769 if pcd.MaxDatumSize.strip():\r
1770 MaxSize = int(pcd.MaxDatumSize, 0)\r
1771 else:\r
1772 MaxSize = 0\r
1773 if pcdDecObject.DatumType == 'VOID*':\r
1774 for (_, skuobj) in pcd.SkuInfoList.items():\r
1775 datalen = 0\r
1776 if skuobj.HiiDefaultValue.startswith("L"):\r
1777 datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2\r
1778 elif skuobj.HiiDefaultValue.startswith("{"):\r
1779 datalen = len(skuobj.HiiDefaultValue.split(","))\r
1780 else:\r
1781 datalen = len(skuobj.HiiDefaultValue) - 2 + 1\r
1782 if datalen > MaxSize:\r
1783 MaxSize = datalen\r
1784 pcd.MaxDatumSize = str(MaxSize)\r
1785 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r
1786 if not rt:\r
1787 invalidpcd = ",".join(invalidhii)\r
1788 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
1789 return Pcds\r
1790\r
1791 def CheckVariableNameAssignment(self,Pcds):\r
1792 invalidhii = []\r
1793 for pcdname in Pcds:\r
1794 pcd = Pcds[pcdname]\r
1795 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])\r
1796 if len(varnameset) > 1:\r
1797 invalidhii.append(".".join((pcdname[1],pcdname[0])))\r
1798 if len(invalidhii):\r
1799 return False,invalidhii\r
1800 else:\r
1801 return True, []\r
1802 ## Retrieve dynamic VPD PCD settings\r
1803 #\r
1804 # @param Type PCD type\r
1805 #\r
1806 # @retval a dict object contains settings of given PCD type\r
1807 #\r
1808 def _GetDynamicVpdPcd(self, Type):\r
1809\r
1810\r
1811 Pcds = sdict()\r
1812 #\r
1813 # tdict is a special dict kind of type, used for selecting correct\r
1814 # PCD settings for certain ARCH and SKU\r
1815 #\r
1816 PcdDict = tdict(True, 4)\r
1817 PcdList = []\r
1818\r
1819 # Find out all possible PCD candidates for self._Arch\r
1820 RecordList = self._RawData[Type, self._Arch]\r
1821 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
1822\r
1823 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
1824 SkuName = SkuName.upper()\r
1825 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1826 if SkuName not in AvailableSkuIdSet:\r
1827 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1828 File=self.MetaFile, Line=Dummy5)\r
1829 if "." not in TokenSpaceGuid:\r
1830 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1831 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1832\r
1833 # Remove redundant PCD candidates, per the ARCH and SKU\r
1834 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1835 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1836 if Setting == None:\r
1837 continue\r
1838 #\r
1839 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
1840 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
1841 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
1842 # until the DEC parser has been called.\r
1843 #\r
1844 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1845 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
1846 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1847 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1848 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1849 if MaxDatumSize.strip():\r
1850 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1851 else:\r
1852 CurrentMaxSize = 0\r
1853 if pcdObject.MaxDatumSize:\r
1854 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1855 else:\r
1856 PcdMaxSize = 0\r
1857 if CurrentMaxSize > PcdMaxSize:\r
1858 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1859 else:\r
1860 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1861 PcdCName,\r
1862 TokenSpaceGuid,\r
1863 self._PCD_TYPE_STRING_[Type],\r
1864 '',\r
1865 InitialValue,\r
1866 '',\r
1867 MaxDatumSize,\r
1868 {SkuName : SkuInfo},\r
1869 False,\r
1870 None,\r
1871 IsDsc=True)\r
1872 for pcd in Pcds.values():\r
1873 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1874 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1875 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1876 valuefromDec = pcdDecObject.DefaultValue\r
1877 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
1878 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1879 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1880 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1881 del(pcd.SkuInfoList['COMMON'])\r
1882 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1883 del(pcd.SkuInfoList['COMMON'])\r
1884 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1885 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1886 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1887 del(pcd.SkuInfoList['DEFAULT'])\r
1888\r
1889 return Pcds\r
1890\r
1891 ## Add external modules\r
1892 #\r
1893 # The external modules are mostly those listed in FDF file, which don't\r
1894 # need "build".\r
1895 #\r
1896 # @param FilePath The path of module description file\r
1897 #\r
1898 def AddModule(self, FilePath):\r
1899 FilePath = NormPath(FilePath)\r
1900 if FilePath not in self.Modules:\r
1901 Module = ModuleBuildClassObject()\r
1902 Module.MetaFile = FilePath\r
1903 self.Modules.append(Module)\r
1904\r
1905 ## Add external PCDs\r
1906 #\r
1907 # The external PCDs are mostly those listed in FDF file to specify address\r
1908 # or offset information.\r
1909 #\r
1910 # @param Name Name of the PCD\r
1911 # @param Guid Token space guid of the PCD\r
1912 # @param Value Value of the PCD\r
1913 #\r
1914 def AddPcd(self, Name, Guid, Value):\r
1915 if (Name, Guid) not in self.Pcds:\r
1916 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
1917 self.Pcds[Name, Guid].DefaultValue = Value\r
1918\r
1919 _Macros = property(_GetMacros)\r
1920 Arch = property(_GetArch, _SetArch)\r
1921 Platform = property(_GetPlatformName)\r
1922 PlatformName = property(_GetPlatformName)\r
1923 Guid = property(_GetFileGuid)\r
1924 Version = property(_GetVersion)\r
1925 DscSpecification = property(_GetDscSpec)\r
1926 OutputDirectory = property(_GetOutpuDir)\r
1927 SupArchList = property(_GetSupArch)\r
1928 BuildTargets = property(_GetBuildTarget)\r
1929 SkuName = property(_GetSkuName, _SetSkuName)\r
1930 SkuIdentifier = property(_GetSkuIdentifier)\r
1931 AvilableSkuIds = property(_GetAviableSkuIds)\r
1932 PcdInfoFlag = property(_GetPcdInfoFlag)\r
1933 VarCheckFlag = property(_GetVarCheckFlag)\r
1934 FlashDefinition = property(_GetFdfFile)\r
1935 Prebuild = property(_GetPrebuild)\r
1936 Postbuild = property(_GetPostbuild)\r
1937 BuildNumber = property(_GetBuildNumber)\r
1938 MakefileName = property(_GetMakefileName)\r
1939 BsBaseAddress = property(_GetBsBaseAddress)\r
1940 RtBaseAddress = property(_GetRtBaseAddress)\r
1941 LoadFixAddress = property(_GetLoadFixAddress)\r
1942 RFCLanguages = property(_GetRFCLanguages)\r
1943 ISOLanguages = property(_GetISOLanguages)\r
1944 VpdToolGuid = property(_GetVpdToolGuid)\r
1945 SkuIds = property(_GetSkuIds)\r
1946 Modules = property(_GetModules)\r
1947 LibraryInstances = property(_GetLibraryInstances)\r
1948 LibraryClasses = property(_GetLibraryClasses)\r
1949 Pcds = property(_GetPcds)\r
1950 BuildOptions = property(_GetBuildOptions)\r