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