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