BaseTools: Support Structure PCD value inherit between the different SKUs
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
CommitLineData
ae7b6df8
LG
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
8518bf0b
LG
161 self.DefaultStores = None\r
162 self.SkuIdMgr = SkuClass(self.SkuIdentifier, self.SkuIds)\r
163 arraystr = self.SkuIdMgr.DumpSkuIdArrary()\r
ae7b6df8
LG
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
8518bf0b 212 self.DefaultStores = None\r
ae7b6df8
LG
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
8518bf0b
LG
221 ModuleId = Record[6]\r
222 LineNo = Record[7]\r
ae7b6df8
LG
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
8518bf0b
LG
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]] = (Record[0],Record[1],Record[2])\r
ae7b6df8 602 if 'DEFAULT' not in self._SkuIds:\r
8518bf0b 603 self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")\r
ae7b6df8 604 if 'COMMON' not in self._SkuIds:\r
8518bf0b 605 self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")\r
ae7b6df8 606 return self._SkuIds\r
8518bf0b
LG
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]] = (self.ToInt(Record[0]),Record[1])\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
ae7b6df8
LG
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
8518bf0b
LG
638 ModuleId = Record[6]\r
639 LineNo = Record[7]\r
ae7b6df8
LG
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
8518bf0b 679 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
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
8518bf0b 703 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
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
8518bf0b 743 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record\r
ae7b6df8
LG
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 self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)\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 DecPcds = {}\r
810 for Pkg in PkgSet:\r
811 for Pcd in Pkg.Pcds:\r
812 DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
813 self._DecPcds.update(DecPcds)\r
814\r
815 if (PcdCName, TokenSpaceGuid) not in self._DecPcds and "." in TokenSpaceGuid and (TokenSpaceGuid.split(".")[1], TokenSpaceGuid.split(".")[0]) not in self._DecPcds:\r
816 EdkLogger.error('build', PARSER_ERROR,\r
817 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
818 File=self.MetaFile, Line=LineNo)\r
819 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
820 if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
821 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
822 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
823 if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
824 try:\r
825 ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
826 except WrnExpression, Value:\r
827 ValueList[Index] = Value.result\r
828 except EvaluationException, Excpt:\r
829 if hasattr(Excpt, 'Pcd'):\r
830 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
831 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
832 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
833 " of the DSC file" % Excpt.Pcd,\r
834 File=self.MetaFile, Line=LineNo)\r
835 else:\r
836 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
837 File=self.MetaFile, Line=LineNo)\r
838 else:\r
839 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
840 File=self.MetaFile, Line=LineNo)\r
841 if ValueList[Index] == 'True':\r
842 ValueList[Index] = '1'\r
843 elif ValueList[Index] == 'False':\r
844 ValueList[Index] = '0'\r
845 if ValueList[Index]:\r
846 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
847 if not Valid:\r
848 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
849 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
850 return ValueList\r
851\r
8518bf0b
LG
852 def _FilterPcdBySkuUsage(self,Pcds):\r
853 available_sku = self.SkuIdMgr.AvailableSkuIdSet\r
854 sku_usage = self.SkuIdMgr.SkuUsageType\r
855 if sku_usage == SkuClass.SINGLE:\r
856 for pcdname in Pcds:\r
857 pcd = Pcds[pcdname]\r
858 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
859 else:\r
860 for pcdname in Pcds:\r
861 pcd = Pcds[pcdname]\r
862 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
863 return Pcds\r
ae7b6df8
LG
864 ## Retrieve all PCD settings in platform\r
865 def _GetPcds(self):\r
866 if self._Pcds == None:\r
867 self._Pcds = sdict()\r
868 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
869 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
870 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
871 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
872 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
873 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
874 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
875 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
876 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
877\r
8518bf0b 878 self._Pcds = self.CompletePcdValues(self._Pcds)\r
ae7b6df8 879 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
8518bf0b 880 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
ae7b6df8
LG
881 return self._Pcds\r
882\r
8518bf0b
LG
883 def _dumpPcdInfo(self,Pcds):\r
884 for pcd in Pcds:\r
885 pcdobj = Pcds[pcd]\r
886 if not pcdobj.TokenCName.startswith("Test"):\r
887 continue\r
888 for skuid in pcdobj.SkuInfoList:\r
889 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r
890 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r
891 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r
892 else:\r
893 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r
ae7b6df8
LG
894 ## Retrieve [BuildOptions]\r
895 def _GetBuildOptions(self):\r
896 if self._BuildOptions == None:\r
897 self._BuildOptions = sdict()\r
898 #\r
899 # Retrieve build option for EDKII and EDK style module\r
900 #\r
901 for CodeBase in (EDKII_NAME, EDK_NAME):\r
902 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
8518bf0b 903 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
904 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
905 #\r
906 # Only flags can be appended\r
907 #\r
908 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
909 self._BuildOptions[CurKey] = Option\r
910 else:\r
911 self._BuildOptions[CurKey] += ' ' + Option\r
912 return self._BuildOptions\r
913\r
914 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
915 if self._ModuleTypeOptions == None:\r
916 self._ModuleTypeOptions = sdict()\r
917 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
918 options = sdict()\r
919 self._ModuleTypeOptions[Edk, ModuleType] = options\r
920 DriverType = '%s.%s' % (Edk, ModuleType)\r
921 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
922 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
8518bf0b 923 for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
924 if Type == DriverType or Type == CommonDriverType:\r
925 Key = (ToolChainFamily, ToolChain, Edk)\r
926 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
927 options[Key] = Option\r
928 else:\r
929 options[Key] += ' ' + Option\r
930 return self._ModuleTypeOptions[Edk, ModuleType]\r
931\r
932 def GetStructurePcdInfo(self, PcdSet):\r
933 structure_pcd_data = {}\r
934 for item in PcdSet:\r
8518bf0b
LG
935 if (item[0],item[1]) not in structure_pcd_data:\r
936 structure_pcd_data[(item[0],item[1])] = []\r
937 structure_pcd_data[(item[0],item[1])].append(item)\r
ae7b6df8
LG
938\r
939 return structure_pcd_data\r
940\r
8518bf0b
LG
941 def CompleteStructurePcdValue(self,pcdset):\r
942 skuset = set([item[3] for item in pcdset])\r
943 pcddatamap = {(item[0],item[1],item[2],item[3]):item for item in pcdset}\r
944 FieldSet = {}\r
945 for item in pcdset:\r
946 if (item[0],item[1]) not in FieldSet:\r
947 FieldSet[(item[0],item[1])] = set()\r
948 FieldSet[(item[0],item[1])].add(item[2])\r
949 completeset = []\r
950 for tockenspacename,pcdname, in FieldSet:\r
951 for field in FieldSet[(tockenspacename,pcdname)]:\r
952 for skuid in skuset:\r
953 nextskuid = skuid\r
954 while (tockenspacename,pcdname,field,nextskuid) not in pcddatamap:\r
955 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
956 if nextskuid == "DEFAULT":\r
957 break\r
958 if (tockenspacename,pcdname,field,nextskuid) not in pcddatamap:\r
959 continue\r
960 item = pcddatamap[tockenspacename,pcdname,field,nextskuid]\r
961 completeset.append((tockenspacename,pcdname,field,skuid, item[4],item[5], item[6]))\r
962 return completeset\r
ae7b6df8
LG
963 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
964 Pcds = AllPcds\r
8518bf0b
LG
965 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
966 SkuIds = set([skuid for pcdobj in AllPcds.values() for skuid in pcdobj.SkuInfoList.keys()])\r
967 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
ae7b6df8
LG
968\r
969 S_PcdSet = []\r
970 # Find out all possible PCD candidates for self._Arch\r
971 RecordList = []\r
972 for Type in TypeList:\r
973 RecordList.extend(self._RawData[Type, self._Arch])\r
974\r
8518bf0b
LG
975 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r
976 if SkuName not in SkuIds:\r
977 continue\r
ae7b6df8 978 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
8518bf0b
LG
979 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
980 S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]))\r
981 S_PcdSet = self.CompleteStructurePcdValue(S_PcdSet)\r
ae7b6df8
LG
982\r
983 # handle pcd value override\r
984 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
985 S_pcd_set = {}\r
986 for str_pcd in StrPcdSet:\r
8518bf0b
LG
987 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
988 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
ae7b6df8
LG
989 if str_pcd_dec:\r
990 str_pcd_obj_str = StructurePcd()\r
991 str_pcd_obj_str.copy(str_pcd_dec)\r
992 if str_pcd_obj:\r
993 str_pcd_obj_str.copy(str_pcd_obj)\r
994 if str_pcd_obj.DefaultValue:\r
995 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
996 for str_pcd_data in StrPcdSet[str_pcd]:\r
8518bf0b
LG
997 if str_pcd_data[3] in SkuIds:\r
998 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
999 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
ae7b6df8
LG
1000 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
1001 for Pcd in self._DecPcds:\r
1002 if type (self._DecPcds[Pcd]) is StructurePcd:\r
1003 if Pcd not in S_pcd_set:\r
1004 str_pcd_obj_str = StructurePcd()\r
1005 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1006 str_pcd_obj = Pcds.get(Pcd, None)\r
1007 if str_pcd_obj:\r
1008 str_pcd_obj_str.copy(str_pcd_obj)\r
1009 if str_pcd_obj.DefaultValue:\r
1010 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1011 S_pcd_set[Pcd] = str_pcd_obj_str\r
1012 if S_pcd_set:\r
1013 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
8518bf0b
LG
1014 for stru_pcd in S_pcd_set.values():\r
1015 if stru_pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1016 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1017 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1018 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1019 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1020 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1021 continue\r
1022 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1023 for skuid in SkuIds:\r
1024 nextskuid = skuid\r
1025 if skuid not in stru_pcd.SkuOverrideValues:\r
1026 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1027 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1028 stru_pcd.SkuOverrideValues[skuid] = {}\r
1029 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[skuid]])\r
1030 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
1031 for defaultstoreid in DefaultStores:\r
1032 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
1033 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename]\r
1034 for skuid in SkuIds:\r
1035 if skuid in stru_pcd.SkuOverrideValues:\r
1036 continue\r
1037 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1038 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1039 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1040 stru_pcd.SkuOverrideValues[skuid] = stru_pcd.SkuOverrideValues[nextskuid]\r
ae7b6df8
LG
1041 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1042 if Str_Pcd_Values:\r
8518bf0b
LG
1043 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r
1044 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
ae7b6df8
LG
1045 if str_pcd_obj is None:\r
1046 raise\r
1047 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1048 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
8518bf0b
LG
1049 if skuname not in str_pcd_obj.SkuInfoList:\r
1050 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
ae7b6df8 1051 else:\r
8518bf0b
LG
1052 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1053 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
ae7b6df8
LG
1054 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1055 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
8518bf0b
LG
1056 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1057 str_pcd_obj.DefaultValue = PcdValue\r
ae7b6df8 1058 else:\r
8518bf0b
LG
1059 if skuname not in str_pcd_obj.SkuInfoList:\r
1060 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)\r
ae7b6df8 1061 else:\r
8518bf0b
LG
1062 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1063 for str_pcd_obj in S_pcd_set.values():\r
1064 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1065 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1066 continue\r
1067 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r
1068 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1069 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1070 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
ae7b6df8
LG
1071\r
1072 for str_pcd_obj in S_pcd_set.values():\r
8518bf0b
LG
1073 if not str_pcd_obj.OverrideValues:\r
1074 continue\r
ae7b6df8
LG
1075 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1076 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
1077\r
1078 return Pcds\r
1079\r
1080 ## Retrieve non-dynamic PCD settings\r
1081 #\r
1082 # @param Type PCD type\r
1083 #\r
1084 # @retval a dict object contains settings of given PCD type\r
1085 #\r
1086 def _GetPcd(self, Type):\r
1087 Pcds = sdict()\r
1088 #\r
1089 # tdict is a special dict kind of type, used for selecting correct\r
1090 # PCD settings for certain ARCH\r
1091 #\r
1092\r
ae7b6df8
LG
1093\r
1094 PcdDict = tdict(True, 3)\r
1095 PcdSet = set()\r
1096 # Find out all possible PCD candidates for self._Arch\r
1097 RecordList = self._RawData[Type, self._Arch]\r
ae7b6df8 1098 PcdValueDict = sdict()\r
8518bf0b
LG
1099 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
1100 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1101 if "." not in TokenSpaceGuid:\r
1102 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
ae7b6df8 1103 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
ae7b6df8
LG
1104\r
1105 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1106 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
1107 if Setting == None:\r
1108 continue\r
1109 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1110 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1111 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1112 else:\r
1113 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1114\r
1115 PcdsKeys = PcdValueDict.keys()\r
1116 for PcdCName, TokenSpaceGuid in PcdsKeys:\r
1117\r
1118 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
1119 PcdValue = None\r
1120 DatumType = None\r
1121 MaxDatumSize = None\r
1122 if 'COMMON' in PcdSetting:\r
1123 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
1124 if 'DEFAULT' in PcdSetting:\r
1125 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
8518bf0b
LG
1126 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1127 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
ae7b6df8
LG
1128\r
1129 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1130 PcdCName,\r
1131 TokenSpaceGuid,\r
1132 self._PCD_TYPE_STRING_[Type],\r
1133 DatumType,\r
1134 PcdValue,\r
1135 '',\r
1136 MaxDatumSize,\r
1137 {},\r
1138 False,\r
1139 None,\r
1140 IsDsc=True)\r
1141\r
1142\r
1143 return Pcds\r
1144\r
8518bf0b
LG
1145 def __UNICODE2OCTList(self,Value):\r
1146 Value = Value.strip()\r
1147 Value = Value[2:-1]\r
1148 List = []\r
1149 for Item in Value:\r
1150 Temp = '%04X' % ord(Item)\r
1151 List.append('0x' + Temp[2:4])\r
1152 List.append('0x' + Temp[0:2])\r
1153 List.append('0x00')\r
1154 List.append('0x00')\r
1155 return List\r
1156 def __STRING2OCTList(self,Value):\r
1157 OCTList = []\r
1158 Value = Value.strip('"')\r
1159 for char in Value:\r
1160 Temp = '%02X' % ord(char)\r
1161 OCTList.append('0x' + Temp)\r
1162 OCTList.append('0x00')\r
1163 return OCTList\r
1164\r
ae7b6df8
LG
1165 def GetStructurePcdMaxSize(self, str_pcd):\r
1166 pcd_default_value = str_pcd.DefaultValue\r
1167 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
1168 sku_values.append(pcd_default_value)\r
1169\r
1170 def get_length(value):\r
1171 Value = value.strip()\r
1172 if Value.startswith('GUID') and Value.endswith(')'):\r
1173 return 16\r
1174 if Value.startswith('L"') and Value.endswith('"'):\r
1175 return len(Value[2:-1])\r
1176 if Value[0] == '"' and Value[-1] == '"':\r
1177 return len(Value) - 2\r
1178 if Value[0] == '{' and Value[-1] == '}':\r
1179 return len(Value.split(","))\r
1180 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1181 return len(list(Value[2:-1]))\r
1182 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1183 return len(Value) - 2\r
1184 return len(Value)\r
1185\r
1186 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
1187\r
1188 def IsFieldValueAnArray (self, Value):\r
1189 Value = Value.strip()\r
1190 if Value.startswith('GUID') and Value.endswith(')'):\r
1191 return True\r
1192 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:\r
1193 return True\r
1194 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
1195 return True\r
1196 if Value[0] == '{' and Value[-1] == '}':\r
1197 return True\r
1198 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1199 print 'foo = ', list(Value[2:-1])\r
1200 return True\r
1201 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1202 print 'bar = ', list(Value[1:-1])\r
1203 return True\r
1204 return False\r
1205\r
1206 def ExecuteCommand (self, Command):\r
1207 try:\r
1208 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1209 except:\r
1210 print 'ERROR: Can not execute command:', Command\r
1211 sys.exit(1)\r
1212 Result = Process.communicate()\r
1213 if Process.returncode <> 0:\r
1214 print 'ERROR: Can not collect output from command:', Command\r
1215 return Result[0], Result[1]\r
1216\r
1217 def IntToCString(self, Value, ValueSize):\r
1218 Result = '"'\r
1219 if not isinstance (Value, str):\r
1220 for Index in range(0, ValueSize):\r
1221 Result = Result + '\\x%02x' % (Value & 0xff)\r
1222 Value = Value >> 8\r
1223 Result = Result + '"'\r
1224 return Result\r
1225\r
1226 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
8518bf0b 1227 OverrideValues = {DefaultStoreName:""}\r
ae7b6df8
LG
1228 if Pcd.SkuOverrideValues:\r
1229 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
8518bf0b
LG
1230 for DefaultStoreName in OverrideValues.keys():\r
1231 CApp = CApp + 'void\n'\r
1232 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1233 CApp = CApp + ' void\n'\r
1234 CApp = CApp + ' )\n'\r
1235 CApp = CApp + '{\n'\r
1236 CApp = CApp + ' UINT32 Size;\n'\r
1237 CApp = CApp + ' UINT32 FieldSize;\n'\r
1238 CApp = CApp + ' UINT8 *Value;\n'\r
1239 CApp = CApp + ' UINT32 OriginalSize;\n'\r
1240 CApp = CApp + ' VOID *OriginalPcd;\n'\r
1241 CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType)\r
1242 CApp = CApp + '\n'\r
1243 Pcd.DefaultValue = Pcd.DefaultValue.strip()\r
1244 if Pcd.DefaultValue.startswith('L"') and Pcd.DefaultValue.endswith('"'):\r
1245 PcdDefaultValue = "{" + ",".join(self.__UNICODE2OCTList(Pcd.DefaultValue)) + "}"\r
1246 elif Pcd.DefaultValue.startswith('"') and Pcd.DefaultValue.endswith('"'):\r
1247 PcdDefaultValue = "{" + ",".join(self.__STRING2OCTList(Pcd.DefaultValue)) + "}"\r
1248 else:\r
1249 PcdDefaultValue = Pcd.DefaultValue\r
1250 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
ae7b6df8 1251\r
8518bf0b
LG
1252 #\r
1253 # Get current PCD value and size\r
1254 #\r
1255 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1256\r
8518bf0b
LG
1257 #\r
1258 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
1259 # the correct value. For structures with a flexible array member, the flexible\r
1260 # array member is detected, and the size is based on the highest index used with\r
1261 # the flexible array member. The flexible array member must be the last field\r
1262 # in a structure. The size formula for this case is:\r
1263 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
1264 #\r
1265 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
1266 for FieldList in [Pcd.DefaultValues, OverrideValues.get(DefaultStoreName)]:\r
1267 if not FieldList:\r
1268 continue\r
1269 for FieldName in FieldList:\r
1270 FieldName = "." + FieldName\r
1271 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1272 if IsArray:\r
1273 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1274 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."));\r
1275 else:\r
1276 NewFieldName = ''\r
1277 while '[' in FieldName:\r
1278 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1279 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1280 FieldName = FieldName.split(']', 1)[1]\r
1281 FieldName = NewFieldName + FieldName\r
1282 while '[' in FieldName:\r
1283 FieldName = FieldName.rsplit('[', 1)[0]\r
1284 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
ae7b6df8 1285\r
8518bf0b
LG
1286 #\r
1287 # Allocate and zero buffer for the PCD\r
1288 # Must handle cases where current value is smaller, larger, or same size\r
1289 # Always keep that larger one as the current size\r
1290 #\r
1291 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
1292 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
1293 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
ae7b6df8 1294\r
8518bf0b
LG
1295 #\r
1296 # Copy current PCD value into allocated buffer.\r
1297 #\r
1298 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
ae7b6df8 1299\r
8518bf0b
LG
1300 #\r
1301 # Assign field values in PCD\r
1302 #\r
1303 for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC,OverrideValues.get(DefaultStoreName)]:\r
1304 if not FieldList:\r
1305 continue\r
1306 if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:\r
1307 IsArray = self.IsFieldValueAnArray(FieldList)\r
1308 Value, ValueSize = ParseFieldValue (FieldList)\r
1309 if isinstance(Value, str):\r
1310 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)\r
1311 elif IsArray:\r
1312 #\r
1313 # Use memcpy() to copy value into field\r
1314 #\r
1315 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)\r
1316 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1317 continue\r
ae7b6df8 1318\r
8518bf0b
LG
1319 for FieldName in FieldList:\r
1320 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1321 try:\r
1322 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1323 except Exception:\r
1324 print FieldList[FieldName][0]\r
1325 if isinstance(Value, str):\r
1326 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1327 elif IsArray:\r
1328 #\r
1329 # Use memcpy() to copy value into field\r
1330 #\r
1331 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1332 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
1333 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
ae7b6df8 1334 else:\r
8518bf0b
LG
1335 if ValueSize > 4:\r
1336 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1337 else:\r
1338 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
ae7b6df8 1339\r
8518bf0b
LG
1340 #\r
1341 # Set new PCD value and size\r
1342 #\r
1343 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1344\r
8518bf0b
LG
1345 #\r
1346 # Free PCD\r
1347 #\r
1348 CApp = CApp + ' free (Pcd);\n'\r
1349 CApp = CApp + '}\n'\r
1350 CApp = CApp + '\n'\r
ae7b6df8
LG
1351 return InitByteValue, CApp\r
1352\r
1353 def GenerateByteArrayValue (self, StructuredPcds):\r
1354 #\r
1355 # Generate/Compile/Run C application to determine if there are any flexible array members\r
1356 #\r
1357 if not StructuredPcds:\r
1358 return\r
1359\r
1360 InitByteValue = ""\r
1361 CApp = PcdMainCHeader\r
1362\r
1363 Includes = {}\r
1364 for PcdName in StructuredPcds:\r
1365 Pcd = StructuredPcds[PcdName]\r
1366 IncludeFile = Pcd.StructuredPcdIncludeFile\r
1367 if IncludeFile not in Includes:\r
1368 Includes[IncludeFile] = True\r
1369 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
1370 CApp = CApp + '\n'\r
1371\r
1372 for PcdName in StructuredPcds:\r
1373 Pcd = StructuredPcds[PcdName]\r
1374 if not Pcd.SkuOverrideValues:\r
8518bf0b 1375 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
ae7b6df8
LG
1376 else:\r
1377 for SkuName in Pcd.SkuOverrideValues:\r
1378 for DefaultStoreName in Pcd.DefaultStoreName:\r
1379 Pcd = StructuredPcds[PcdName]\r
1380 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
1381\r
1382 CApp = CApp + 'VOID\n'\r
1383 CApp = CApp + 'PcdEntryPoint(\n'\r
1384 CApp = CApp + ' VOID\n'\r
1385 CApp = CApp + ' )\n'\r
1386 CApp = CApp + '{\n'\r
1387 for Pcd in StructuredPcds.values():\r
1388 if not Pcd.SkuOverrideValues:\r
8518bf0b 1389 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8
LG
1390 else:\r
1391 for SkuName in Pcd.SkuOverrideValues:\r
8518bf0b 1392 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ae7b6df8
LG
1393 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1394 CApp = CApp + '}\n'\r
1395\r
1396 CApp = CApp + PcdMainCEntry + '\n'\r
1397\r
1398 if not os.path.exists(self.OutputPath):\r
1399 os.makedirs(self.OutputPath)\r
1400 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1401 File = open (CAppBaseFileName + '.c', 'w')\r
1402 File.write(CApp)\r
1403 File.close()\r
1404\r
1405 MakeApp = PcdMakefileHeader\r
1406 if sys.platform == "win32":\r
1407 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
1408 else:\r
1409 MakeApp = MakeApp + PcdGccMakefile\r
1410 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
1411 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='\r
1412\r
1413 PlatformInc = {}\r
1414 for Cache in self._Bdb._CACHE_.values():\r
1415 if Cache.MetaFile.Ext.lower() != '.dec':\r
1416 continue\r
1417 if Cache.Includes:\r
1418 if str(Cache.MetaFile.Path) not in PlatformInc:\r
1419 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
1420\r
1421 PcdDependDEC = []\r
1422 for Pcd in StructuredPcds.values():\r
1423 for PackageDec in Pcd.PackageDecs:\r
1424 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
1425 if not os.path.exists(Package):\r
1426 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1427 if Package not in PcdDependDEC:\r
1428 PcdDependDEC.append(Package)\r
1429\r
1430 if PlatformInc and PcdDependDEC:\r
1431 for pkg in PcdDependDEC:\r
1432 if pkg in PlatformInc:\r
1433 for inc in PlatformInc[pkg]:\r
1434 MakeApp += '-I' + str(inc) + ' '\r
1435 MakeApp = MakeApp + '\n'\r
1436 if sys.platform == "win32":\r
1437 MakeApp = MakeApp + PcdMakefileEnd\r
1438 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
1439 File = open (MakeFileName, 'w')\r
1440 File.write(MakeApp)\r
1441 File.close()\r
1442\r
1443 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
1444 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
1445 File = open (InputValueFile, 'w')\r
1446 File.write(InitByteValue)\r
1447 File.close()\r
1448\r
1449 if sys.platform == "win32":\r
1450 StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))\r
1451 else:\r
1452 StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
1453 Messages = StdOut.split('\r')\r
1454 for Message in Messages:\r
1455 if " error " in Message:\r
1456 FileInfo = Message.strip().split('(')\r
1457 if len (FileInfo) > 0:\r
1458 FileName = FileInfo [0]\r
1459 FileLine = FileInfo [1].split (')')[0]\r
1460 else:\r
1461 FileInfo = Message.strip().split(':')\r
1462 FileName = FileInfo [0]\r
1463 FileLine = FileInfo [1]\r
1464\r
1465 File = open (FileName, 'r')\r
1466 FileData = File.readlines()\r
1467 File.close()\r
1468 error_line = FileData[int (FileLine) - 1]\r
1469 if r"//" in error_line:\r
1470 c_line,dsc_line = error_line.split(r"//")\r
1471 else:\r
1472 dsc_line = error_line\r
1473\r
1474 message_itmes = Message.split(":")\r
1475 for item in message_itmes:\r
1476 if "PcdValueInit.c" in item:\r
1477 message_itmes[message_itmes.index(item)] = dsc_line.strip()\r
1478\r
1479 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:]))\r
1480\r
1481 PcdValueInitExe = PcdValueInitName\r
1482 if not sys.platform == "win32":\r
1483 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
1484\r
1485 StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))\r
1486 File = open (OutputValueFile, 'r')\r
1487 FileBuffer = File.readlines()\r
1488 File.close()\r
1489\r
1490 StructurePcdSet = []\r
1491 for Pcd in FileBuffer:\r
1492 PcdValue = Pcd.split ('|')\r
1493 PcdInfo = PcdValue[0].split ('.')\r
8518bf0b 1494 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
ae7b6df8
LG
1495 return StructurePcdSet\r
1496\r
1497 ## Retrieve dynamic PCD settings\r
1498 #\r
1499 # @param Type PCD type\r
1500 #\r
1501 # @retval a dict object contains settings of given PCD type\r
1502 #\r
1503 def _GetDynamicPcd(self, Type):\r
1504\r
ae7b6df8
LG
1505\r
1506 Pcds = sdict()\r
1507 #\r
1508 # tdict is a special dict kind of type, used for selecting correct\r
1509 # PCD settings for certain ARCH and SKU\r
1510 #\r
1511 PcdDict = tdict(True, 4)\r
1512 PcdList = []\r
1513 # Find out all possible PCD candidates for self._Arch\r
1514 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1515 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1516\r
ae7b6df8 1517\r
8518bf0b 1518 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8 1519 if SkuName not in AvailableSkuIdSet:\r
8518bf0b 1520 continue\r
ae7b6df8
LG
1521 if "." not in TokenSpaceGuid:\r
1522 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1523 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1524\r
1525 # Remove redundant PCD candidates, per the ARCH and SKU\r
1526 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1527\r
1528 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1529 if Setting == None:\r
1530 continue\r
1531\r
1532 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 1533 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
ae7b6df8
LG
1534 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1535 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1536 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1537 if MaxDatumSize.strip():\r
1538 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1539 else:\r
1540 CurrentMaxSize = 0\r
1541 if pcdObject.MaxDatumSize:\r
1542 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1543 else:\r
1544 PcdMaxSize = 0\r
1545 if CurrentMaxSize > PcdMaxSize:\r
1546 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1547 else:\r
1548 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1549 PcdCName,\r
1550 TokenSpaceGuid,\r
1551 self._PCD_TYPE_STRING_[Type],\r
1552 DatumType,\r
1553 PcdValue,\r
1554 '',\r
1555 MaxDatumSize,\r
1556 {SkuName : SkuInfo},\r
1557 False,\r
1558 None,\r
1559 IsDsc=True)\r
1560\r
1561 for pcd in Pcds.values():\r
1562 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1563 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1564 valuefromDec = pcdDecObject.DefaultValue\r
1565 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
1566 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1567 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1568 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1569 del(pcd.SkuInfoList['COMMON'])\r
1570 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1571 del(pcd.SkuInfoList['COMMON'])\r
8518bf0b
LG
1572 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1573 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1574 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
ae7b6df8
LG
1575 del(pcd.SkuInfoList['DEFAULT'])\r
1576\r
1577 return Pcds\r
1578\r
1579 def CompareVarAttr(self, Attr1, Attr2):\r
1580 if not Attr1 or not Attr2: # for empty string\r
1581 return True\r
1582 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
1583 Attr1Set = set(Attr1s)\r
1584 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
1585 Attr2Set = set(Attr2s)\r
1586 if Attr2Set == Attr1Set:\r
1587 return True\r
1588 else:\r
1589 return False\r
8518bf0b
LG
1590 def CompletePcdValues(self,PcdSet):\r
1591 Pcds = {}\r
1592 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1593 SkuIds = set([skuid for pcdobj in PcdSet.values() for skuid in pcdobj.SkuInfoList.keys()])\r
1594 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
1595 for PcdCName, TokenSpaceGuid in PcdSet:\r
1596 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
1597 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1598 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1599 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1600 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1601 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1602 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1603 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1604 continue\r
1605 PcdType = PcdObj.Type\r
1606 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1607 for skuid in PcdObj.SkuInfoList:\r
1608 skuobj = PcdObj.SkuInfoList[skuid]\r
1609 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r
1610 for defaultstorename in DefaultStores:\r
1611 if defaultstorename not in skuobj.DefaultStoreDict:\r
1612 skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename]\r
1613 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
1614 for skuid in SkuIds:\r
1615 if skuid not in PcdObj.SkuInfoList:\r
1616 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1617 while nextskuid not in PcdObj.SkuInfoList:\r
1618 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1619 PcdObj.SkuInfoList[skuid] = PcdObj.SkuInfoList[nextskuid]\r
1620 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1621 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r
1622 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1623 return Pcds\r
ae7b6df8
LG
1624 ## Retrieve dynamic HII PCD settings\r
1625 #\r
1626 # @param Type PCD type\r
1627 #\r
1628 # @retval a dict object contains settings of given PCD type\r
1629 #\r
1630 def _GetDynamicHiiPcd(self, Type):\r
1631\r
ae7b6df8
LG
1632 VariableAttrs = {}\r
1633\r
1634 Pcds = sdict()\r
1635 #\r
1636 # tdict is a special dict kind of type, used for selecting correct\r
1637 # PCD settings for certain ARCH and SKU\r
1638 #\r
8518bf0b 1639 PcdDict = tdict(True, 5)\r
ae7b6df8
LG
1640 PcdSet = set()\r
1641 RecordList = self._RawData[Type, self._Arch]\r
1642 # Find out all possible PCD candidates for self._Arch\r
8518bf0b 1643 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1644\r
8518bf0b
LG
1645 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r
1646 if DefaultStore == "COMMON":\r
1647 DefaultStore = "STANDARD"\r
ae7b6df8 1648 if SkuName not in AvailableSkuIdSet:\r
8518bf0b 1649 continue\r
ae7b6df8 1650 if "." not in TokenSpaceGuid:\r
8518bf0b
LG
1651 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4))\r
1652 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r
ae7b6df8
LG
1653\r
1654\r
1655 # Remove redundant PCD candidates, per the ARCH and SKU\r
8518bf0b 1656 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r
ae7b6df8 1657\r
8518bf0b 1658 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r
ae7b6df8
LG
1659 if Setting == None:\r
1660 continue\r
1661 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1662\r
1663 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
1664 if not rt:\r
1665 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
1666 ExtraData="[%s]" % VarAttribute)\r
1667 ExceedMax = False\r
1668 FormatCorrect = True\r
1669 if VariableOffset.isdigit():\r
1670 if int(VariableOffset, 10) > 0xFFFF:\r
1671 ExceedMax = True\r
1672 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
1673 if int(VariableOffset, 16) > 0xFFFF:\r
1674 ExceedMax = True\r
1675 # For Offset written in "A.B"\r
1676 elif VariableOffset.find('.') > -1:\r
1677 VariableOffsetList = VariableOffset.split(".")\r
1678 if not (len(VariableOffsetList) == 2\r
1679 and IsValidWord(VariableOffsetList[0])\r
1680 and IsValidWord(VariableOffsetList[1])):\r
1681 FormatCorrect = False\r
1682 else:\r
1683 FormatCorrect = False\r
1684 if not FormatCorrect:\r
1685 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
1686\r
1687 if ExceedMax:\r
1688 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
1689 if (VariableName, VariableGuid) not in VariableAttrs:\r
1690 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1691 else:\r
1692 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1693 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
1694\r
ae7b6df8
LG
1695 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
1696 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1697 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
8518bf0b
LG
1698 if SkuName in pcdObject.SkuInfoList:\r
1699 Skuitem = pcdObject.SkuInfoList[SkuName]\r
1700 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
1701 else:\r
1702 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
1703 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
ae7b6df8 1704 else:\r
8518bf0b 1705 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
ae7b6df8
LG
1706 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1707 PcdCName,\r
1708 TokenSpaceGuid,\r
1709 self._PCD_TYPE_STRING_[Type],\r
1710 '',\r
1711 DefaultValue,\r
1712 '',\r
1713 '',\r
1714 {SkuName : SkuInfo},\r
1715 False,\r
1716 None,\r
1717 pcdDecObject.validateranges,\r
1718 pcdDecObject.validlists,\r
1719 pcdDecObject.expressions,\r
1720 IsDsc=True)\r
1721\r
1722\r
1723 for pcd in Pcds.values():\r
1724 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1725 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1726 # Only fix the value while no value provided in DSC file.\r
1727 for sku in pcd.SkuInfoList.values():\r
1728 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
1729 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1730 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1731 valuefromDec = pcdDecObject.DefaultValue\r
1732 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
1733 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1734 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1735 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1736 del(pcd.SkuInfoList['COMMON'])\r
1737 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1738 del(pcd.SkuInfoList['COMMON'])\r
1739\r
8518bf0b
LG
1740 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1741 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1742 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
ae7b6df8
LG
1743 del(pcd.SkuInfoList['DEFAULT'])\r
1744\r
1745 if pcd.MaxDatumSize.strip():\r
1746 MaxSize = int(pcd.MaxDatumSize, 0)\r
1747 else:\r
1748 MaxSize = 0\r
1749 if pcdDecObject.DatumType == 'VOID*':\r
1750 for (skuname, skuobj) in pcd.SkuInfoList.items():\r
1751 datalen = 0\r
1752 if skuobj.HiiDefaultValue.startswith("L"):\r
1753 datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2\r
1754 elif skuobj.HiiDefaultValue.startswith("{"):\r
1755 datalen = len(skuobj.HiiDefaultValue.split(","))\r
1756 else:\r
1757 datalen = len(skuobj.HiiDefaultValue) - 2 + 1\r
1758 if datalen > MaxSize:\r
1759 MaxSize = datalen\r
1760 pcd.MaxDatumSize = str(MaxSize)\r
1761 return Pcds\r
1762\r
1763\r
1764 ## Retrieve dynamic VPD PCD settings\r
1765 #\r
1766 # @param Type PCD type\r
1767 #\r
1768 # @retval a dict object contains settings of given PCD type\r
1769 #\r
1770 def _GetDynamicVpdPcd(self, Type):\r
1771\r
ae7b6df8
LG
1772\r
1773 Pcds = sdict()\r
1774 #\r
1775 # tdict is a special dict kind of type, used for selecting correct\r
1776 # PCD settings for certain ARCH and SKU\r
1777 #\r
1778 PcdDict = tdict(True, 4)\r
1779 PcdList = []\r
1780\r
1781 # Find out all possible PCD candidates for self._Arch\r
1782 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1783 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1784\r
8518bf0b 1785 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8 1786 if SkuName not in AvailableSkuIdSet:\r
8518bf0b 1787 continue\r
ae7b6df8
LG
1788 if "." not in TokenSpaceGuid:\r
1789 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1790 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1791\r
1792 # Remove redundant PCD candidates, per the ARCH and SKU\r
1793 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1794 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1795 if Setting == None:\r
1796 continue\r
1797 #\r
1798 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
1799 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
1800 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
1801 # until the DEC parser has been called.\r
1802 #\r
1803 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 1804 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
ae7b6df8
LG
1805 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1806 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1807 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1808 if MaxDatumSize.strip():\r
1809 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1810 else:\r
1811 CurrentMaxSize = 0\r
1812 if pcdObject.MaxDatumSize:\r
1813 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1814 else:\r
1815 PcdMaxSize = 0\r
1816 if CurrentMaxSize > PcdMaxSize:\r
1817 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1818 else:\r
1819 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1820 PcdCName,\r
1821 TokenSpaceGuid,\r
1822 self._PCD_TYPE_STRING_[Type],\r
1823 '',\r
1824 InitialValue,\r
1825 '',\r
1826 MaxDatumSize,\r
1827 {SkuName : SkuInfo},\r
1828 False,\r
1829 None,\r
1830 IsDsc=True)\r
1831 for pcd in Pcds.values():\r
1832 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1833 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1834 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1835 valuefromDec = pcdDecObject.DefaultValue\r
1836 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
1837 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1838 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1839 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1840 del(pcd.SkuInfoList['COMMON'])\r
1841 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1842 del(pcd.SkuInfoList['COMMON'])\r
8518bf0b
LG
1843 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1844 if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys():\r
1845 pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
ae7b6df8
LG
1846 del(pcd.SkuInfoList['DEFAULT'])\r
1847\r
1848 return Pcds\r
1849\r
1850 ## Add external modules\r
1851 #\r
1852 # The external modules are mostly those listed in FDF file, which don't\r
1853 # need "build".\r
1854 #\r
1855 # @param FilePath The path of module description file\r
1856 #\r
1857 def AddModule(self, FilePath):\r
1858 FilePath = NormPath(FilePath)\r
1859 if FilePath not in self.Modules:\r
1860 Module = ModuleBuildClassObject()\r
1861 Module.MetaFile = FilePath\r
1862 self.Modules.append(Module)\r
1863\r
1864 ## Add external PCDs\r
1865 #\r
1866 # The external PCDs are mostly those listed in FDF file to specify address\r
1867 # or offset information.\r
1868 #\r
1869 # @param Name Name of the PCD\r
1870 # @param Guid Token space guid of the PCD\r
1871 # @param Value Value of the PCD\r
1872 #\r
1873 def AddPcd(self, Name, Guid, Value):\r
1874 if (Name, Guid) not in self.Pcds:\r
1875 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
1876 self.Pcds[Name, Guid].DefaultValue = Value\r
1877\r
1878 _Macros = property(_GetMacros)\r
1879 Arch = property(_GetArch, _SetArch)\r
1880 Platform = property(_GetPlatformName)\r
1881 PlatformName = property(_GetPlatformName)\r
1882 Guid = property(_GetFileGuid)\r
1883 Version = property(_GetVersion)\r
1884 DscSpecification = property(_GetDscSpec)\r
1885 OutputDirectory = property(_GetOutpuDir)\r
1886 SupArchList = property(_GetSupArch)\r
1887 BuildTargets = property(_GetBuildTarget)\r
1888 SkuName = property(_GetSkuName, _SetSkuName)\r
1889 SkuIdentifier = property(_GetSkuIdentifier)\r
1890 AvilableSkuIds = property(_GetAviableSkuIds)\r
1891 PcdInfoFlag = property(_GetPcdInfoFlag)\r
1892 VarCheckFlag = property(_GetVarCheckFlag)\r
1893 FlashDefinition = property(_GetFdfFile)\r
1894 Prebuild = property(_GetPrebuild)\r
1895 Postbuild = property(_GetPostbuild)\r
1896 BuildNumber = property(_GetBuildNumber)\r
1897 MakefileName = property(_GetMakefileName)\r
1898 BsBaseAddress = property(_GetBsBaseAddress)\r
1899 RtBaseAddress = property(_GetRtBaseAddress)\r
1900 LoadFixAddress = property(_GetLoadFixAddress)\r
1901 RFCLanguages = property(_GetRFCLanguages)\r
1902 ISOLanguages = property(_GetISOLanguages)\r
1903 VpdToolGuid = property(_GetVpdToolGuid)\r
1904 SkuIds = property(_GetSkuIds)\r
1905 Modules = property(_GetModules)\r
1906 LibraryInstances = property(_GetLibraryInstances)\r
1907 LibraryClasses = property(_GetLibraryClasses)\r
1908 Pcds = property(_GetPcds)\r
1909 BuildOptions = property(_GetBuildOptions)\r