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