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