BaseTools: Fixed the pcd value override issue.
[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
cdbf45ad
YZ
682 # the format is PcdName| Value | VOID* | MaxDatumSize\r
683 if len(TokenList) > 2:\r
684 MaxDatumSize = TokenList[2]\r
ae7b6df8
LG
685 else:\r
686 MaxDatumSize = ''\r
687 TypeString = self._PCD_TYPE_STRING_[Type]\r
688 Pcd = PcdClassObject(\r
689 PcdCName,\r
690 TokenSpaceGuid,\r
691 TypeString,\r
692 '',\r
693 DefaultValue,\r
694 '',\r
695 MaxDatumSize,\r
696 {},\r
697 False,\r
698 None\r
699 )\r
700 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
701\r
702 # get module private build options\r
703 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
8518bf0b 704 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
705 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
706 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
707 else:\r
708 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
709 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
710\r
711 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
712 if DuplicatedFile and not RecordList:\r
713 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
714 if RecordList:\r
715 if len(RecordList) != 1:\r
716 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
717 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
718 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
719 ModuleFile.Arch = self._Arch\r
720\r
721 self._Modules[ModuleFile] = Module\r
722 return self._Modules\r
723\r
724 ## Retrieve all possible library instances used in this platform\r
725 def _GetLibraryInstances(self):\r
726 if self._LibraryInstances == None:\r
727 self._GetLibraryClasses()\r
728 return self._LibraryInstances\r
729\r
730 ## Retrieve [LibraryClasses] information\r
731 def _GetLibraryClasses(self):\r
732 if self._LibraryClasses == None:\r
733 self._LibraryInstances = []\r
734 #\r
735 # tdict is a special dict kind of type, used for selecting correct\r
736 # library instance for given library class and module type\r
737 #\r
738 LibraryClassDict = tdict(True, 3)\r
739 # track all library class names\r
740 LibraryClassSet = set()\r
741 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r
742 Macros = self._Macros\r
743 for Record in RecordList:\r
8518bf0b 744 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record\r
ae7b6df8
LG
745 if LibraryClass == '' or LibraryClass == 'NULL':\r
746 self._NullLibraryNumber += 1\r
747 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
748 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
749 LibraryClassSet.add(LibraryClass)\r
750 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
751 # check the file validation\r
752 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
753 if ErrorCode != 0:\r
754 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
755 ExtraData=ErrorInfo)\r
756\r
757 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
758 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
759 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r
760 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
761 if LibraryInstance not in self._LibraryInstances:\r
762 self._LibraryInstances.append(LibraryInstance)\r
763\r
764 # resolve the specific library instance for each class and each module type\r
765 self._LibraryClasses = tdict(True)\r
766 for LibraryClass in LibraryClassSet:\r
767 # try all possible module types\r
768 for ModuleType in SUP_MODULE_LIST:\r
769 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
770 if LibraryInstance == None:\r
771 continue\r
772 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
773\r
774 # for Edk style library instances, which are listed in different section\r
775 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
776 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
777 for Record in RecordList:\r
778 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
779 LineNo = Record[-1]\r
780 # check the file validation\r
781 ErrorCode, ErrorInfo = File.Validate('.inf')\r
782 if ErrorCode != 0:\r
783 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
784 ExtraData=ErrorInfo)\r
785 if File not in self._LibraryInstances:\r
786 self._LibraryInstances.append(File)\r
787 #\r
788 # we need the module name as the library class name, so we have\r
789 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
790 # hasn't been parsed)\r
791 #\r
792 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
793 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
794 return self._LibraryClasses\r
795\r
796 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
797 if self._DecPcds == None:\r
2b8a6c44 798\r
ae7b6df8
LG
799 FdfInfList = []\r
800 if GlobalData.gFdfParser:\r
801 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
802\r
803 PkgSet = set()\r
804 for Inf in FdfInfList:\r
805 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
806 if ModuleFile in self._Modules:\r
807 continue\r
808 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
809 PkgSet.update(ModuleData.Packages)\r
ae7b6df8 810\r
726c501c 811 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
9efe8d60 812 self._GuidDict.update(GlobalData.gPlatformPcds)\r
2b8a6c44
LG
813\r
814 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
ae7b6df8
LG
815 EdkLogger.error('build', PARSER_ERROR,\r
816 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
817 File=self.MetaFile, Line=LineNo)\r
818 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
520365de
B
819 if not IsValid:\r
820 if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
821 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
822 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
823 else:\r
824 if ValueList[2] == '-1':\r
825 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
826 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
35f613d9
YF
827 if ValueList[Index]:\r
828 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType\r
ae7b6df8 829 try:\r
35f613d9 830 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)\r
726c501c 831 except BadExpression, Value:\r
35f613d9
YF
832 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,\r
833 ExtraData="PCD [%s.%s] Value \"%s\" " % (\r
834 TokenSpaceGuid, PcdCName, ValueList[Index]))\r
ae7b6df8
LG
835 except EvaluationException, Excpt:\r
836 if hasattr(Excpt, 'Pcd'):\r
837 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
838 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
839 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
840 " of the DSC file" % Excpt.Pcd,\r
841 File=self.MetaFile, Line=LineNo)\r
842 else:\r
843 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
844 File=self.MetaFile, Line=LineNo)\r
845 else:\r
846 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
847 File=self.MetaFile, Line=LineNo)\r
35f613d9 848\r
ae7b6df8
LG
849 if ValueList[Index]:\r
850 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
851 if not Valid:\r
852 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
853 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
520365de
B
854 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
855 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():\r
5db9414c 856 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 857 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
35f613d9
YF
858 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:\r
859 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:\r
860 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]\r
ae7b6df8
LG
861 return ValueList\r
862\r
8518bf0b
LG
863 def _FilterPcdBySkuUsage(self,Pcds):\r
864 available_sku = self.SkuIdMgr.AvailableSkuIdSet\r
865 sku_usage = self.SkuIdMgr.SkuUsageType\r
866 if sku_usage == SkuClass.SINGLE:\r
867 for pcdname in Pcds:\r
868 pcd = Pcds[pcdname]\r
869 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
870 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
871 Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b
LG
872 else:\r
873 for pcdname in Pcds:\r
874 pcd = Pcds[pcdname]\r
875 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
876 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
877 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b 878 return Pcds\r
2b8a6c44
LG
879 def CompleteHiiPcdsDefaultStores(self,Pcds):\r
880 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
881 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
882 for pcd in HiiPcd:\r
883 for skuid in pcd.SkuInfoList:\r
884 skuobj = pcd.SkuInfoList.get(skuid)\r
885 if "STANDARD" not in skuobj.DefaultStoreDict:\r
886 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])\r
887 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
888 skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
889 return Pcds\r
890\r
6f49996c
FB
891 def RecoverCommandLinePcd(self):\r
892 pcdset = []\r
893 if GlobalData.BuildOptionPcd:\r
894 for pcd in GlobalData.BuildOptionPcd:\r
895 if pcd[2] == "":\r
896 pcdset.append((pcd[0],pcd[1],pcd[3]))\r
897 else:\r
06140766 898 if (pcd[1],pcd[0]) not in self._Pcds:\r
e1511113
B
899 pcdvalue = pcd[3] if len(pcd) == 4 else pcd[2]\r
900 pcdset.append((pcd[0],pcd[1],pcdvalue))\r
06140766
FB
901 #else:\r
902 # remove the settings from command line since it has been handled.\r
6f49996c
FB
903 GlobalData.BuildOptionPcd = pcdset\r
904 def GetFieldValueFromComm(self,ValueStr,TokenSpaceGuidCName, TokenCName, FieldName):\r
905 PredictedFieldType = "VOID*"\r
906 if ValueStr.startswith('L'):\r
907 if not ValueStr[1]:\r
908 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
909 ValueStr = ValueStr[0] + '"' + ValueStr[1:] + '"'\r
910 PredictedFieldType = "VOID*"\r
911 elif ValueStr.startswith('H') or ValueStr.startswith('{'):\r
912 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
913 ValueStr = ValueStr[1:]\r
914 PredictedFieldType = "VOID*"\r
915 elif ValueStr.upper() in ['TRUE', '0X1', '0X01', '1', 'FALSE', '0X0', '0X00', '0']:\r
916 PredictedFieldType = "BOOLEAN"\r
917 elif ValueStr.isdigit() or ValueStr.upper().startswith('0X'):\r
918 PredictedFieldType = TAB_UINT16\r
919 else:\r
920 if not ValueStr[0]:\r
921 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
922 ValueStr = '"' + ValueStr + '"'\r
923 PredictedFieldType = "VOID*"\r
924 IsValid, Cause = CheckPcdDatum(PredictedFieldType, ValueStr)\r
925 if not IsValid:\r
926 EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName, TokenCName, FieldName))\r
927 if PredictedFieldType == 'BOOLEAN':\r
928 ValueStr = ValueStr.upper()\r
929 if ValueStr == 'TRUE' or ValueStr == '1':\r
930 ValueStr = '1'\r
931 elif ValueStr == 'FALSE' or ValueStr == '0':\r
932 ValueStr = '0'\r
933 return ValueStr\r
934 def __ParsePcdFromCommandLine(self):\r
935 if GlobalData.BuildOptionPcd:\r
936 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
937 if type(pcd) is tuple:\r
938 continue\r
939 (pcdname, pcdvalue) = pcd.split('=')\r
940 if not pcdvalue:\r
941 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))\r
942 if '.' in pcdname:\r
943 (Name1, Name2) = pcdname.split('.',1)\r
944 if "." in Name2:\r
945 (Name3, FieldName) = Name2.split(".",1)\r
946 if ((Name3,Name1)) in self.DecPcds:\r
947 HasTokenSpace = True\r
948 TokenCName = Name3\r
949 TokenSpaceGuidCName = Name1\r
950 else:\r
951 FieldName = Name2\r
952 TokenCName = Name1\r
953 TokenSpaceGuidCName = ''\r
954 HasTokenSpace = False\r
955 else:\r
956 if ((Name2,Name1)) in self.DecPcds:\r
957 HasTokenSpace = True\r
958 TokenCName = Name2\r
959 TokenSpaceGuidCName = Name1\r
960 FieldName =""\r
961 else:\r
962 FieldName = Name2\r
963 TokenCName = Name1\r
964 TokenSpaceGuidCName = ''\r
965 HasTokenSpace = False\r
966 else:\r
967 FieldName = ""\r
968 TokenCName = pcdname\r
969 TokenSpaceGuidCName = ''\r
970 HasTokenSpace = False\r
971 TokenSpaceGuidCNameList = []\r
972 FoundFlag = False\r
973 PcdDatumType = ''\r
974 NewValue = ''\r
975 if not HasTokenSpace:\r
976 for key in self.DecPcds:\r
977 if TokenCName == key[0]:\r
978 if TokenSpaceGuidCName:\r
979 EdkLogger.error(\r
980 'build',\r
981 AUTOGEN_ERROR,\r
982 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, TokenSpaceGuidCName, key[1])\r
983 )\r
984 else:\r
985 TokenSpaceGuidCName = key[1]\r
986 FoundFlag = True\r
987 else:\r
988 if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:\r
989 FoundFlag = True\r
990 if FieldName:\r
991 NewValue = self.GetFieldValueFromComm(pcdvalue, TokenSpaceGuidCName, TokenCName, FieldName)\r
992 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))\r
993 else:\r
ea927d2f
FY
994 # Replace \' to ', \\\' to \'\r
995 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")\r
6f49996c
FB
996 for key in self.DecPcds:\r
997 PcdItem = self.DecPcds[key]\r
998 if HasTokenSpace:\r
999 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
1000 PcdDatumType = PcdItem.DatumType\r
1001 if pcdvalue.startswith('H'):\r
1002 try:\r
1003 pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)\r
1004 except BadExpression, Value:\r
f9bba774
FY
1005 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1006 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1007 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
f9bba774
FY
1008 pcdvalue = 'H' + pcdvalue\r
1009 elif pcdvalue.startswith("L'"):\r
1010 try:\r
1011 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1012 except BadExpression, Value:\r
1013 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1014 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1015 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
f9bba774
FY
1016 pcdvalue = 'H' + pcdvalue\r
1017 elif pcdvalue.startswith("'"):\r
1018 try:\r
1019 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1020 except BadExpression, Value:\r
1021 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1022 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1023 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
f9bba774
FY
1024 pcdvalue = 'H' + pcdvalue\r
1025 elif pcdvalue.startswith('L'):\r
1026 pcdvalue = 'L"' + pcdvalue[1:] + '"'\r
1027 try:\r
1028 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1029 except BadExpression, Value:\r
1030 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1031 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
1032 else:\r
1033 try:\r
1034 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1035 except BadExpression, Value:\r
ea927d2f
FY
1036 try:\r
1037 pcdvalue = '"' + pcdvalue + '"'\r
1038 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1039 except BadExpression, Value:\r
1040 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1041 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
6f49996c
FB
1042 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
1043 FoundFlag = True\r
1044 else:\r
1045 if PcdItem.TokenCName == TokenCName:\r
1046 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
1047 if len (TokenSpaceGuidCNameList) < 1:\r
1048 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
1049 PcdDatumType = PcdItem.DatumType\r
1050 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
1051 if pcdvalue.startswith('H'):\r
1052 try:\r
1053 pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)\r
1054 except BadExpression, Value:\r
1055 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1056 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1057 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:\r
f9bba774
FY
1058 pcdvalue = 'H' + pcdvalue\r
1059 elif pcdvalue.startswith("L'"):\r
1060 try:\r
1061 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(\r
1062 True)\r
1063 except BadExpression, Value:\r
1064 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1065 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1066 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
f9bba774
FY
1067 pcdvalue = 'H' + pcdvalue\r
1068 elif pcdvalue.startswith("'"):\r
1069 try:\r
1070 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(\r
1071 True)\r
1072 except BadExpression, Value:\r
1073 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1074 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
ea927d2f 1075 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:\r
f9bba774
FY
1076 pcdvalue = 'H' + pcdvalue\r
1077 elif pcdvalue.startswith('L'):\r
1078 pcdvalue = 'L"' + pcdvalue[1:] + '"'\r
1079 try:\r
1080 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(\r
1081 True)\r
1082 except BadExpression, Value:\r
1083 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1084 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
1085 else:\r
1086 try:\r
1087 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1088 except BadExpression, Value:\r
ea927d2f
FY
1089 try:\r
1090 pcdvalue = '"' + pcdvalue + '"'\r
1091 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)\r
1092 except BadExpression, Value:\r
1093 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1094 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))\r
6f49996c
FB
1095 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
1096 FoundFlag = True\r
1097 else:\r
1098 EdkLogger.error(\r
1099 'build',\r
1100 AUTOGEN_ERROR,\r
1101 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
1102 )\r
1103 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))\r
1104 if not FoundFlag:\r
1105 if HasTokenSpace:\r
1106 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))\r
1107 else:\r
1108 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))\r
1109 for BuildData in self._Bdb._CACHE_.values():\r
1110 if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':\r
1111 continue\r
1112 for key in BuildData.Pcds:\r
1113 PcdItem = BuildData.Pcds[key]\r
1114 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":\r
1115 PcdItem.DefaultValue = NewValue\r
ae7b6df8
LG
1116 ## Retrieve all PCD settings in platform\r
1117 def _GetPcds(self):\r
1118 if self._Pcds == None:\r
1119 self._Pcds = sdict()\r
6f49996c 1120 self.__ParsePcdFromCommandLine()\r
ae7b6df8
LG
1121 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1122 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1123 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1124 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
1125 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
1126 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
1127 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
1128 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
1129 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
1130\r
8518bf0b 1131 self._Pcds = self.CompletePcdValues(self._Pcds)\r
ae7b6df8 1132 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
2b8a6c44 1133 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
8518bf0b 1134 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
6f49996c
FB
1135 self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)\r
1136 self.RecoverCommandLinePcd()\r
ae7b6df8
LG
1137 return self._Pcds\r
1138\r
8518bf0b
LG
1139 def _dumpPcdInfo(self,Pcds):\r
1140 for pcd in Pcds:\r
1141 pcdobj = Pcds[pcd]\r
1142 if not pcdobj.TokenCName.startswith("Test"):\r
1143 continue\r
1144 for skuid in pcdobj.SkuInfoList:\r
1145 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r
1146 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r
1147 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r
1148 else:\r
1149 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r
ae7b6df8
LG
1150 ## Retrieve [BuildOptions]\r
1151 def _GetBuildOptions(self):\r
1152 if self._BuildOptions == None:\r
1153 self._BuildOptions = sdict()\r
1154 #\r
1155 # Retrieve build option for EDKII and EDK style module\r
1156 #\r
1157 for CodeBase in (EDKII_NAME, EDK_NAME):\r
1158 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
8518bf0b 1159 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
c05c2c05
LG
1160 if Dummy3.upper() != 'COMMON':\r
1161 continue\r
ae7b6df8
LG
1162 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
1163 #\r
1164 # Only flags can be appended\r
1165 #\r
1166 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1167 self._BuildOptions[CurKey] = Option\r
1168 else:\r
c05c2c05
LG
1169 if ' ' + Option not in self._BuildOptions[CurKey]:\r
1170 self._BuildOptions[CurKey] += ' ' + Option\r
ae7b6df8
LG
1171 return self._BuildOptions\r
1172\r
1173 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
1174 if self._ModuleTypeOptions == None:\r
1175 self._ModuleTypeOptions = sdict()\r
1176 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
1177 options = sdict()\r
1178 self._ModuleTypeOptions[Edk, ModuleType] = options\r
1179 DriverType = '%s.%s' % (Edk, ModuleType)\r
1180 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
c05c2c05
LG
1181 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]\r
1182 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
1183 Type = Dummy2 + '.' + Dummy3\r
1184 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():\r
ae7b6df8
LG
1185 Key = (ToolChainFamily, ToolChain, Edk)\r
1186 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1187 options[Key] = Option\r
1188 else:\r
c05c2c05
LG
1189 if ' ' + Option not in options[Key]:\r
1190 options[Key] += ' ' + Option\r
ae7b6df8
LG
1191 return self._ModuleTypeOptions[Edk, ModuleType]\r
1192\r
1193 def GetStructurePcdInfo(self, PcdSet):\r
1194 structure_pcd_data = {}\r
1195 for item in PcdSet:\r
8518bf0b
LG
1196 if (item[0],item[1]) not in structure_pcd_data:\r
1197 structure_pcd_data[(item[0],item[1])] = []\r
1198 structure_pcd_data[(item[0],item[1])].append(item)\r
ae7b6df8
LG
1199\r
1200 return structure_pcd_data\r
6f49996c
FB
1201 def OverrideByFdfComm(self,StruPcds):\r
1202 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
1203 GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])\r
1204 for Pcd in StruPcds.values():\r
1205 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:\r
1206 continue\r
1207 FieldValues = {item[2]:StructurePcdInCom[item] for item in StructurePcdInCom if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]}\r
1208 for sku in Pcd.SkuOverrideValues:\r
1209 for defaultstore in Pcd.SkuOverrideValues[sku]:\r
1210 for field in FieldValues:\r
1211 if field not in Pcd.SkuOverrideValues[sku][defaultstore]:\r
1212 Pcd.SkuOverrideValues[sku][defaultstore][field] = ["","",""]\r
1213 Pcd.SkuOverrideValues[sku][defaultstore][field][0] = FieldValues[field][0]\r
1214 Pcd.SkuOverrideValues[sku][defaultstore][field][1] = FieldValues[field][1][0]\r
1215 Pcd.SkuOverrideValues[sku][defaultstore][field][2] = FieldValues[field][1][1]\r
1216 return StruPcds\r
1217 def OverrideByFdfCommOverAll(self,AllPcds):\r
1218 def CheckStructureInComm(commpcds):\r
1219 if not commpcds:\r
1220 return False\r
1221 if len(commpcds[0]) == 5:\r
1222 return True\r
1223 return False\r
ae7b6df8 1224\r
6f49996c
FB
1225 if CheckStructureInComm(GlobalData.BuildOptionPcd):\r
1226 StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}\r
1227 NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}\r
1228 else:\r
1229 NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}\r
1230 for Guid,Name in NoFiledValues:\r
1231 if (Name,Guid) in AllPcds:\r
1232 Pcd = AllPcds.get((Name,Guid))\r
1233 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
1234 for sku in Pcd.SkuInfoList:\r
1235 SkuInfo = Pcd.SkuInfoList[sku]\r
1236 if SkuInfo.DefaultValue:\r
1237 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
1238 else:\r
1239 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
1240 for defaultstore in SkuInfo.DefaultStoreDict:\r
1241 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]\r
1242 else:\r
1243 PcdInDec = self.DecPcds.get((Name,Guid))\r
1244 if PcdInDec:\r
1245 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1246 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
1247 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)\r
1248 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]\r
1249 return AllPcds\r
ae7b6df8 1250 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
65eff519
LG
1251\r
1252 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1253 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1254 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1255 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1256 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1257 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]\r
1258\r
ae7b6df8 1259 Pcds = AllPcds\r
8518bf0b 1260 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
65eff519
LG
1261 SkuIds = self.SkuIdMgr.AvailableSkuIdSet\r
1262 SkuIds.update({'DEFAULT':0})\r
8518bf0b 1263 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
ae7b6df8
LG
1264\r
1265 S_PcdSet = []\r
1266 # Find out all possible PCD candidates for self._Arch\r
1267 RecordList = []\r
2b8a6c44 1268\r
ae7b6df8
LG
1269 for Type in TypeList:\r
1270 RecordList.extend(self._RawData[Type, self._Arch])\r
1271\r
8518bf0b 1272 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1273 SkuName = SkuName.upper()\r
1274 default_store = default_store.upper()\r
1275 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
8518bf0b
LG
1276 if SkuName not in SkuIds:\r
1277 continue\r
2b8a6c44 1278\r
8518bf0b 1279 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
6f49996c 1280 S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]])\r
ae7b6df8
LG
1281\r
1282 # handle pcd value override\r
1283 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
1284 S_pcd_set = {}\r
1285 for str_pcd in StrPcdSet:\r
8518bf0b
LG
1286 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
1287 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
5db9414c
B
1288 if not isinstance (str_pcd_dec, StructurePcd):\r
1289 EdkLogger.error('build', PARSER_ERROR,\r
1290 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
1291 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8
LG
1292 if str_pcd_dec:\r
1293 str_pcd_obj_str = StructurePcd()\r
1294 str_pcd_obj_str.copy(str_pcd_dec)\r
1295 if str_pcd_obj:\r
1296 str_pcd_obj_str.copy(str_pcd_obj)\r
77204d60
FB
1297 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1298 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
1299 else:\r
1300 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
ae7b6df8 1301 for str_pcd_data in StrPcdSet[str_pcd]:\r
8518bf0b
LG
1302 if str_pcd_data[3] in SkuIds:\r
1303 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
1304 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
2b8a6c44
LG
1305 else:\r
1306 EdkLogger.error('build', PARSER_ERROR,\r
1307 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
1308 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8 1309 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
5644e5ce 1310 for Pcd in self.DecPcds:\r
ae7b6df8
LG
1311 if type (self._DecPcds[Pcd]) is StructurePcd:\r
1312 if Pcd not in S_pcd_set:\r
1313 str_pcd_obj_str = StructurePcd()\r
1314 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1315 str_pcd_obj = Pcds.get(Pcd, None)\r
1316 if str_pcd_obj:\r
1317 str_pcd_obj_str.copy(str_pcd_obj)\r
77204d60
FB
1318 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1319 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
1320 else:\r
1321 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
ae7b6df8
LG
1322 S_pcd_set[Pcd] = str_pcd_obj_str\r
1323 if S_pcd_set:\r
1324 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
8518bf0b 1325 for stru_pcd in S_pcd_set.values():\r
67e63e9a
LG
1326 for skuid in SkuIds:\r
1327 if skuid in stru_pcd.SkuOverrideValues:\r
1328 continue\r
1329 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1330 NoDefault = False\r
1331 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1332 if nextskuid == "DEFAULT":\r
1333 NoDefault = True\r
1334 break\r
1335 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1336 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
1337 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1338 for skuid in SkuIds:\r
1339 nextskuid = skuid\r
2b8a6c44 1340 NoDefault = False\r
8518bf0b
LG
1341 if skuid not in stru_pcd.SkuOverrideValues:\r
1342 while nextskuid not in stru_pcd.SkuOverrideValues:\r
2b8a6c44
LG
1343 if nextskuid == "DEFAULT":\r
1344 NoDefault = True\r
1345 break\r
8518bf0b 1346 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1347 if NoDefault:\r
1348 continue\r
1349 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])\r
8518bf0b 1350 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
2b8a6c44 1351\r
8518bf0b
LG
1352 for defaultstoreid in DefaultStores:\r
1353 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
2b8a6c44 1354 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
6f49996c 1355 S_pcd_set = self.OverrideByFdfComm(S_pcd_set)\r
ae7b6df8
LG
1356 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1357 if Str_Pcd_Values:\r
8518bf0b
LG
1358 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r
1359 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
ae7b6df8 1360 if str_pcd_obj is None:\r
67e63e9a 1361 print PcdName, PcdGuid\r
ae7b6df8
LG
1362 raise\r
1363 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1364 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
8518bf0b
LG
1365 if skuname not in str_pcd_obj.SkuInfoList:\r
1366 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
ae7b6df8 1367 else:\r
8518bf0b
LG
1368 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1369 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
ae7b6df8
LG
1370 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1371 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
8518bf0b
LG
1372 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1373 str_pcd_obj.DefaultValue = PcdValue\r
ae7b6df8 1374 else:\r
8518bf0b 1375 if skuname not in str_pcd_obj.SkuInfoList:\r
65eff519
LG
1376 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
1377 NoDefault = False\r
1378 while nextskuid not in str_pcd_obj.SkuInfoList:\r
1379 if nextskuid == "DEFAULT":\r
1380 NoDefault = True\r
1381 break\r
1382 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1383 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
1384 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]\r
1385 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname\r
ae7b6df8 1386 else:\r
8518bf0b
LG
1387 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1388 for str_pcd_obj in S_pcd_set.values():\r
1389 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1390 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1391 continue\r
1392 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r
1393 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1394 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1395 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
ae7b6df8
LG
1396\r
1397 for str_pcd_obj in S_pcd_set.values():\r
2b8a6c44 1398\r
ae7b6df8
LG
1399 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1400 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
1401\r
65eff519
LG
1402 for pcdkey in Pcds:\r
1403 pcd = Pcds[pcdkey]\r
1404 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1405 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1406 del(pcd.SkuInfoList['COMMON'])\r
1407 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1408 del(pcd.SkuInfoList['COMMON'])\r
1409\r
1410 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])\r
ae7b6df8
LG
1411 return Pcds\r
1412\r
1413 ## Retrieve non-dynamic PCD settings\r
1414 #\r
1415 # @param Type PCD type\r
1416 #\r
1417 # @retval a dict object contains settings of given PCD type\r
1418 #\r
1419 def _GetPcd(self, Type):\r
1420 Pcds = sdict()\r
1421 #\r
1422 # tdict is a special dict kind of type, used for selecting correct\r
1423 # PCD settings for certain ARCH\r
1424 #\r
2b8a6c44 1425 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8
LG
1426\r
1427 PcdDict = tdict(True, 3)\r
1428 PcdSet = set()\r
1429 # Find out all possible PCD candidates for self._Arch\r
1430 RecordList = self._RawData[Type, self._Arch]\r
ae7b6df8 1431 PcdValueDict = sdict()\r
8518bf0b 1432 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1433 SkuName = SkuName.upper()\r
1434 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1435 if SkuName not in AvailableSkuIdSet:\r
1436 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1437 File=self.MetaFile, Line=Dummy5)\r
8518bf0b
LG
1438 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1439 if "." not in TokenSpaceGuid:\r
5db9414c 1440 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8 1441 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
ae7b6df8
LG
1442\r
1443 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1444 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
1445 if Setting == None:\r
1446 continue\r
1447 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1448 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1449 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1450 else:\r
1451 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1452\r
1453 PcdsKeys = PcdValueDict.keys()\r
1454 for PcdCName, TokenSpaceGuid in PcdsKeys:\r
1455\r
1456 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
1457 PcdValue = None\r
1458 DatumType = None\r
1459 MaxDatumSize = None\r
1460 if 'COMMON' in PcdSetting:\r
1461 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
1462 if 'DEFAULT' in PcdSetting:\r
1463 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
8518bf0b
LG
1464 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1465 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
ae7b6df8
LG
1466\r
1467 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1468 PcdCName,\r
1469 TokenSpaceGuid,\r
1470 self._PCD_TYPE_STRING_[Type],\r
1471 DatumType,\r
1472 PcdValue,\r
1473 '',\r
1474 MaxDatumSize,\r
1475 {},\r
1476 False,\r
1477 None,\r
1478 IsDsc=True)\r
1479\r
1480\r
1481 return Pcds\r
1482\r
8518bf0b
LG
1483 def __UNICODE2OCTList(self,Value):\r
1484 Value = Value.strip()\r
1485 Value = Value[2:-1]\r
1486 List = []\r
1487 for Item in Value:\r
1488 Temp = '%04X' % ord(Item)\r
1489 List.append('0x' + Temp[2:4])\r
1490 List.append('0x' + Temp[0:2])\r
1491 List.append('0x00')\r
1492 List.append('0x00')\r
1493 return List\r
1494 def __STRING2OCTList(self,Value):\r
1495 OCTList = []\r
1496 Value = Value.strip('"')\r
1497 for char in Value:\r
1498 Temp = '%02X' % ord(char)\r
1499 OCTList.append('0x' + Temp)\r
1500 OCTList.append('0x00')\r
1501 return OCTList\r
1502\r
ae7b6df8
LG
1503 def GetStructurePcdMaxSize(self, str_pcd):\r
1504 pcd_default_value = str_pcd.DefaultValue\r
1505 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
1506 sku_values.append(pcd_default_value)\r
1507\r
1508 def get_length(value):\r
1509 Value = value.strip()\r
a0939593
LG
1510 if len(value) > 1:\r
1511 if Value.startswith('GUID') and Value.endswith(')'):\r
1512 return 16\r
1513 if Value.startswith('L"') and Value.endswith('"'):\r
1514 return len(Value[2:-1])\r
1515 if Value[0] == '"' and Value[-1] == '"':\r
1516 return len(Value) - 2\r
1517 if Value[0] == '{' and Value[-1] == '}':\r
1518 return len(Value.split(","))\r
1519 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1520 return len(list(Value[2:-1]))\r
1521 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1522 return len(Value) - 2\r
ae7b6df8
LG
1523 return len(Value)\r
1524\r
1525 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
1526\r
1527 def IsFieldValueAnArray (self, Value):\r
1528 Value = Value.strip()\r
1529 if Value.startswith('GUID') and Value.endswith(')'):\r
1530 return True\r
1531 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:\r
1532 return True\r
1533 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
1534 return True\r
1535 if Value[0] == '{' and Value[-1] == '}':\r
1536 return True\r
1537 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1538 print 'foo = ', list(Value[2:-1])\r
1539 return True\r
1540 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1541 print 'bar = ', list(Value[1:-1])\r
1542 return True\r
1543 return False\r
1544\r
1545 def ExecuteCommand (self, Command):\r
1546 try:\r
1547 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1548 except:\r
5db9414c 1549 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)\r
ae7b6df8 1550 Result = Process.communicate()\r
5db9414c 1551 return Process.returncode, Result[0], Result[1]\r
ae7b6df8
LG
1552\r
1553 def IntToCString(self, Value, ValueSize):\r
1554 Result = '"'\r
1555 if not isinstance (Value, str):\r
1556 for Index in range(0, ValueSize):\r
1557 Result = Result + '\\x%02x' % (Value & 0xff)\r
1558 Value = Value >> 8\r
1559 Result = Result + '"'\r
1560 return Result\r
1561\r
1562 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
8518bf0b 1563 OverrideValues = {DefaultStoreName:""}\r
ae7b6df8
LG
1564 if Pcd.SkuOverrideValues:\r
1565 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
8518bf0b
LG
1566 for DefaultStoreName in OverrideValues.keys():\r
1567 CApp = CApp + 'void\n'\r
1568 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1569 CApp = CApp + ' void\n'\r
1570 CApp = CApp + ' )\n'\r
1571 CApp = CApp + '{\n'\r
1572 CApp = CApp + ' UINT32 Size;\n'\r
1573 CApp = CApp + ' UINT32 FieldSize;\n'\r
b2395724 1574 CApp = CApp + ' CHAR8 *Value;\n'\r
8518bf0b
LG
1575 CApp = CApp + ' UINT32 OriginalSize;\n'\r
1576 CApp = CApp + ' VOID *OriginalPcd;\n'\r
6a103440 1577 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)\r
8518bf0b 1578 CApp = CApp + '\n'\r
47854fd5 1579\r
8e011d83
FB
1580 if SkuName in Pcd.SkuInfoList:\r
1581 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue\r
1582 else:\r
1583 DefaultValue = Pcd.DefaultValue\r
1584 PcdDefaultValue = StringToArray(DefaultValue.strip())\r
47854fd5 1585\r
8518bf0b 1586 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
ae7b6df8 1587\r
8518bf0b
LG
1588 #\r
1589 # Get current PCD value and size\r
1590 #\r
1591 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1592\r
8518bf0b
LG
1593 #\r
1594 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
1595 # the correct value. For structures with a flexible array member, the flexible\r
1596 # array member is detected, and the size is based on the highest index used with\r
1597 # the flexible array member. The flexible array member must be the last field\r
1598 # in a structure. The size formula for this case is:\r
1599 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
1600 #\r
1601 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
8aa4db4b 1602 CApp = CApp + "// Default Value in Dec \n"\r
4cc82428
FB
1603 for FieldList in [Pcd.DefaultValues]:\r
1604 if not FieldList:\r
1605 continue\r
1606 for FieldName in FieldList:\r
1607 FieldName = "." + FieldName\r
1608 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1609 if IsArray:\r
bee0f2f1
FY
1610 try:\r
1611 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
1612 except BadExpression:\r
1613 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1614 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
1615 Value, ValueSize = ParseFieldValue(Value)\r
75771aeb 1616 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
1617 else:\r
1618 NewFieldName = ''\r
75771aeb 1619 FieldName_ori = FieldName.strip('.')\r
4cc82428
FB
1620 while '[' in FieldName:\r
1621 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1622 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1623 FieldName = FieldName.split(']', 1)[1]\r
1624 FieldName = NewFieldName + FieldName\r
1625 while '[' in FieldName:\r
1626 FieldName = FieldName.rsplit('[', 1)[0]\r
75771aeb 1627 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 1628 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1629 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
8aa4db4b
FB
1630 storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]\r
1631 for defaultstorenameitem in storeset:\r
1632 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
1633 for FieldList in [inherit_OverrideValues.get(defaultstorenameitem)]:\r
1634 if not FieldList:\r
1635 continue\r
1636 for FieldName in FieldList:\r
1637 FieldName = "." + FieldName\r
1638 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1639 if IsArray:\r
1640 try:\r
1641 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)\r
1642 except BadExpression:\r
1643 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1644 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
1645 Value, ValueSize = ParseFieldValue(Value)\r
1646 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
1647 else:\r
1648 NewFieldName = ''\r
1649 FieldName_ori = FieldName.strip('.')\r
1650 while '[' in FieldName:\r
1651 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1652 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1653 FieldName = FieldName.split(']', 1)[1]\r
1654 FieldName = NewFieldName + FieldName\r
1655 while '[' in FieldName:\r
1656 FieldName = FieldName.rsplit('[', 1)[0]\r
1657 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
1658 if skuname == SkuName:\r
1659 break\r
ae7b6df8 1660\r
8518bf0b
LG
1661 #\r
1662 # Allocate and zero buffer for the PCD\r
1663 # Must handle cases where current value is smaller, larger, or same size\r
1664 # Always keep that larger one as the current size\r
1665 #\r
1666 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
1667 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
1668 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
ae7b6df8 1669\r
8518bf0b
LG
1670 #\r
1671 # Copy current PCD value into allocated buffer.\r
1672 #\r
1673 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
ae7b6df8 1674\r
8518bf0b
LG
1675 #\r
1676 # Assign field values in PCD\r
1677 #\r
8aa4db4b 1678 CApp = CApp + "// Default value in Dec \n"\r
06140766
FB
1679 DefaultValueFromDec = Pcd.DefaultValueFromDec\r
1680 IsArray = self.IsFieldValueAnArray(Pcd.DefaultValueFromDec)\r
1681 if IsArray:\r
1682 try:\r
1683 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)\r
1684 except BadExpression:\r
1685 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %\r
1686 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))\r
1687 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)\r
1688 if isinstance(Value, str):\r
1689 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)\r
1690 elif IsArray:\r
1691 #\r
1692 # Use memcpy() to copy value into field\r
1693 #\r
1694 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)\r
1695 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
4cc82428
FB
1696 for FieldList in [Pcd.DefaultValues]:\r
1697 if not FieldList:\r
1698 continue\r
1699 for FieldName in FieldList:\r
1700 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
bee0f2f1
FY
1701 if IsArray:\r
1702 try:\r
1703 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
1704 except BadExpression:\r
1705 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1706 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))\r
1707\r
4cc82428
FB
1708 try:\r
1709 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1710 except Exception:\r
5db9414c 1711 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
1712 if isinstance(Value, str):\r
1713 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1714 elif IsArray:\r
1715 #\r
1716 # Use memcpy() to copy value into field\r
1717 #\r
1718 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1719 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
1720 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
1721 else:\r
1722 if ValueSize > 4:\r
1723 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1724 else:\r
1725 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 1726 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1727 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
8aa4db4b
FB
1728 storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]\r
1729 for defaultstorenameitem in storeset:\r
1730 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
77204d60
FB
1731 pcddefaultvalue = Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue\r
1732 for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(defaultstorenameitem)]:\r
8aa4db4b
FB
1733 if not FieldList:\r
1734 continue\r
77204d60 1735 if pcddefaultvalue and FieldList == pcddefaultvalue:\r
8aa4db4b
FB
1736 IsArray = self.IsFieldValueAnArray(FieldList)\r
1737 if IsArray:\r
1738 try:\r
1739 FieldList = ValueExpressionEx(FieldList, "VOID*")(True)\r
1740 except BadExpression:\r
1741 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r
1742 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
1743 Value, ValueSize = ParseFieldValue (FieldList)\r
1744 if isinstance(Value, str):\r
77204d60 1745 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
8aa4db4b
FB
1746 elif IsArray:\r
1747 #\r
1748 # Use memcpy() to copy value into field\r
1749 #\r
77204d60 1750 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)\r
8aa4db4b
FB
1751 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1752 continue\r
1753 for FieldName in FieldList:\r
1754 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1755 if IsArray:\r
1756 try:\r
1757 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)\r
1758 except BadExpression:\r
1759 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1760 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
bee0f2f1 1761 try:\r
8aa4db4b
FB
1762 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1763 except Exception:\r
1764 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
1765 if isinstance(Value, str):\r
1766 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1767 elif IsArray:\r
1768 #\r
1769 # Use memcpy() to copy value into field\r
1770 #\r
1771 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1772 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
1773 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
c05c2c05 1774 else:\r
8aa4db4b
FB
1775 if ValueSize > 4:\r
1776 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1777 else:\r
1778 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
1779 if skuname == SkuName:\r
1780 break\r
8518bf0b
LG
1781 #\r
1782 # Set new PCD value and size\r
1783 #\r
1784 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1785\r
8518bf0b
LG
1786 #\r
1787 # Free PCD\r
1788 #\r
1789 CApp = CApp + ' free (Pcd);\n'\r
1790 CApp = CApp + '}\n'\r
1791 CApp = CApp + '\n'\r
ae7b6df8
LG
1792 return InitByteValue, CApp\r
1793\r
1794 def GenerateByteArrayValue (self, StructuredPcds):\r
1795 #\r
1796 # Generate/Compile/Run C application to determine if there are any flexible array members\r
1797 #\r
1798 if not StructuredPcds:\r
1799 return\r
1800\r
1801 InitByteValue = ""\r
1802 CApp = PcdMainCHeader\r
1803\r
1804 Includes = {}\r
1805 for PcdName in StructuredPcds:\r
1806 Pcd = StructuredPcds[PcdName]\r
81add864
FB
1807 for IncludeFile in Pcd.StructuredPcdIncludeFile:\r
1808 if IncludeFile not in Includes:\r
1809 Includes[IncludeFile] = True\r
1810 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
ae7b6df8
LG
1811 CApp = CApp + '\n'\r
1812\r
1813 for PcdName in StructuredPcds:\r
1814 Pcd = StructuredPcds[PcdName]\r
1815 if not Pcd.SkuOverrideValues:\r
8518bf0b 1816 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
ae7b6df8 1817 else:\r
c05c2c05
LG
1818 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1819 if SkuName not in Pcd.SkuOverrideValues:\r
1820 continue\r
ae7b6df8
LG
1821 for DefaultStoreName in Pcd.DefaultStoreName:\r
1822 Pcd = StructuredPcds[PcdName]\r
1823 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
1824\r
1825 CApp = CApp + 'VOID\n'\r
1826 CApp = CApp + 'PcdEntryPoint(\n'\r
1827 CApp = CApp + ' VOID\n'\r
1828 CApp = CApp + ' )\n'\r
1829 CApp = CApp + '{\n'\r
1830 for Pcd in StructuredPcds.values():\r
1831 if not Pcd.SkuOverrideValues:\r
8518bf0b 1832 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1833 else:\r
c05c2c05
LG
1834 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1835 if SkuName not in Pcd.SkuOverrideValues:\r
1836 continue\r
8518bf0b 1837 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ae7b6df8
LG
1838 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1839 CApp = CApp + '}\n'\r
1840\r
1841 CApp = CApp + PcdMainCEntry + '\n'\r
1842\r
1843 if not os.path.exists(self.OutputPath):\r
1844 os.makedirs(self.OutputPath)\r
1845 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1846 File = open (CAppBaseFileName + '.c', 'w')\r
1847 File.write(CApp)\r
1848 File.close()\r
1849\r
1850 MakeApp = PcdMakefileHeader\r
1851 if sys.platform == "win32":\r
1852 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
1853 else:\r
1854 MakeApp = MakeApp + PcdGccMakefile\r
1855 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
68ba919f 1856 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='\r
ae7b6df8
LG
1857\r
1858 PlatformInc = {}\r
1859 for Cache in self._Bdb._CACHE_.values():\r
1860 if Cache.MetaFile.Ext.lower() != '.dec':\r
1861 continue\r
1862 if Cache.Includes:\r
1863 if str(Cache.MetaFile.Path) not in PlatformInc:\r
1864 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
1865\r
1866 PcdDependDEC = []\r
1867 for Pcd in StructuredPcds.values():\r
1868 for PackageDec in Pcd.PackageDecs:\r
1869 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
1870 if not os.path.exists(Package):\r
1871 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1872 if Package not in PcdDependDEC:\r
1873 PcdDependDEC.append(Package)\r
1874\r
1875 if PlatformInc and PcdDependDEC:\r
1876 for pkg in PcdDependDEC:\r
1877 if pkg in PlatformInc:\r
1878 for inc in PlatformInc[pkg]:\r
1879 MakeApp += '-I' + str(inc) + ' '\r
1880 MakeApp = MakeApp + '\n'\r
68ba919f
YZ
1881\r
1882 CC_FLAGS = LinuxCFLAGS\r
1883 if sys.platform == "win32":\r
1884 CC_FLAGS = WindowsCFLAGS\r
1885 BuildOptions = {}\r
1886 for Options in self.BuildOptions:\r
1887 if Options[2] != EDKII_NAME:\r
1888 continue\r
1889 Family = Options[0]\r
1890 if Family and Family != self.ToolChainFamily:\r
1891 continue\r
1892 Target, Tag, Arch, Tool, Attr = Options[1].split("_")\r
1893 if Tool != 'CC':\r
1894 continue\r
1895\r
1896 if Target == "*" or Target == self._Target:\r
1897 if Tag == "*" or Tag == self._Toolchain:\r
1898 if Arch == "*" or Arch == self.Arch:\r
1899 if Tool not in BuildOptions:\r
1900 BuildOptions[Tool] = {}\r
1901 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):\r
1902 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1903 else:\r
1904 # append options for the same tool except PATH\r
1905 if Attr != 'PATH':\r
1906 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]\r
1907 else:\r
1908 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1909 if BuildOptions:\r
1910 for Tool in BuildOptions:\r
1911 for Attr in BuildOptions[Tool]:\r
1912 if Attr == "FLAGS":\r
1913 Value = BuildOptions[Tool][Attr]\r
1914 ValueList = Value.split()\r
1915 if ValueList:\r
1916 for Id, Item in enumerate(ValueList):\r
1917 if Item == '-D' or Item == '/D':\r
1918 CC_FLAGS += ' ' + Item\r
1919 if Id + 1 < len(ValueList):\r
1920 CC_FLAGS += ' ' + ValueList[Id + 1]\r
1921 elif Item.startswith('/D') or Item.startswith('-D'):\r
1922 CC_FLAGS += ' ' + Item\r
1923 MakeApp += CC_FLAGS\r
1924\r
ae7b6df8
LG
1925 if sys.platform == "win32":\r
1926 MakeApp = MakeApp + PcdMakefileEnd\r
1927 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
1928 File = open (MakeFileName, 'w')\r
1929 File.write(MakeApp)\r
1930 File.close()\r
1931\r
1932 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
1933 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
1934 File = open (InputValueFile, 'w')\r
1935 File.write(InitByteValue)\r
1936 File.close()\r
1937\r
b2395724 1938 Messages = ''\r
ae7b6df8 1939 if sys.platform == "win32":\r
5db9414c
B
1940 MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)\r
1941 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
b2395724 1942 Messages = StdOut\r
ae7b6df8 1943 else:\r
5db9414c
B
1944 MakeCommand = 'make clean & make -f %s' % (MakeFileName)\r
1945 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)\r
b2395724
LG
1946 Messages = StdErr\r
1947 Messages = Messages.split('\n')\r
5db9414c
B
1948 MessageGroup = []\r
1949 if returncode <>0:\r
1950 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1951 File = open (CAppBaseFileName + '.c', 'r')\r
1952 FileData = File.readlines()\r
1953 File.close()\r
1954 for Message in Messages:\r
1955 if " error" in Message or "warning" in Message:\r
1956 FileInfo = Message.strip().split('(')\r
1957 if len (FileInfo) > 1:\r
1958 FileName = FileInfo [0]\r
1959 FileLine = FileInfo [1].split (')')[0]\r
1960 else:\r
1961 FileInfo = Message.strip().split(':')\r
1962 FileName = FileInfo [0]\r
1963 FileLine = FileInfo [1]\r
1964 if FileLine.isdigit():\r
1965 error_line = FileData[int (FileLine) - 1]\r
1966 if r"//" in error_line:\r
1967 c_line,dsc_line = error_line.split(r"//")\r
1968 else:\r
1969 dsc_line = error_line\r
1970 message_itmes = Message.split(":")\r
1971 Index = 0\r
1972 if "PcdValueInit.c" not in Message:\r
0939fda9
LG
1973 if not MessageGroup:\r
1974 MessageGroup.append(Message)\r
5db9414c
B
1975 break\r
1976 else:\r
1977 for item in message_itmes:\r
1978 if "PcdValueInit.c" in item:\r
1979 Index = message_itmes.index(item)\r
1980 message_itmes[Index] = dsc_line.strip()\r
1981 break\r
1982 MessageGroup.append(":".join(message_itmes[Index:]).strip())\r
1983 continue\r
1984 else:\r
1985 MessageGroup.append(Message)\r
1986 if MessageGroup:\r
1987 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )\r
1988 else:\r
1989 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)\r
ae7b6df8
LG
1990\r
1991 PcdValueInitExe = PcdValueInitName\r
1992 if not sys.platform == "win32":\r
1993 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
1994\r
5db9414c
B
1995 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)\r
1996 returncode, StdOut, StdErr = self.ExecuteCommand (Command)\r
1997 if returncode <> 0:\r
1998 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)\r
1999 FileBuffer = []\r
2000 else:\r
2001 File = open (OutputValueFile, 'r')\r
2002 FileBuffer = File.readlines()\r
2003 File.close()\r
ae7b6df8
LG
2004\r
2005 StructurePcdSet = []\r
2006 for Pcd in FileBuffer:\r
2007 PcdValue = Pcd.split ('|')\r
2008 PcdInfo = PcdValue[0].split ('.')\r
8518bf0b 2009 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
ae7b6df8
LG
2010 return StructurePcdSet\r
2011\r
2012 ## Retrieve dynamic PCD settings\r
2013 #\r
2014 # @param Type PCD type\r
2015 #\r
2016 # @retval a dict object contains settings of given PCD type\r
2017 #\r
2018 def _GetDynamicPcd(self, Type):\r
2019\r
ae7b6df8
LG
2020\r
2021 Pcds = sdict()\r
2022 #\r
2023 # tdict is a special dict kind of type, used for selecting correct\r
2024 # PCD settings for certain ARCH and SKU\r
2025 #\r
2026 PcdDict = tdict(True, 4)\r
2027 PcdList = []\r
2028 # Find out all possible PCD candidates for self._Arch\r
2029 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 2030 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 2031\r
ae7b6df8 2032\r
8518bf0b 2033 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
2034 SkuName = SkuName.upper()\r
2035 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 2036 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2037 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2038 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2039 if "." not in TokenSpaceGuid:\r
5db9414c 2040 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8
LG
2041 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
2042\r
2043 # Remove redundant PCD candidates, per the ARCH and SKU\r
2044 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
2045\r
2046 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
2047 if Setting == None:\r
2048 continue\r
2049\r
2050 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 2051 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
ae7b6df8
LG
2052 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
2053 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2054 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2055 if MaxDatumSize.strip():\r
2056 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2057 else:\r
2058 CurrentMaxSize = 0\r
2059 if pcdObject.MaxDatumSize:\r
2060 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2061 else:\r
2062 PcdMaxSize = 0\r
2063 if CurrentMaxSize > PcdMaxSize:\r
2064 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2065 else:\r
2066 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2067 PcdCName,\r
2068 TokenSpaceGuid,\r
2069 self._PCD_TYPE_STRING_[Type],\r
2070 DatumType,\r
2071 PcdValue,\r
2072 '',\r
2073 MaxDatumSize,\r
2074 {SkuName : SkuInfo},\r
2075 False,\r
2076 None,\r
2077 IsDsc=True)\r
2078\r
2079 for pcd in Pcds.values():\r
2080 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
2081 # Only fix the value while no value provided in DSC file.\r
2082 for sku in pcd.SkuInfoList.values():\r
2083 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
2084 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
2085 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
2086 valuefromDec = pcdDecObject.DefaultValue\r
2087 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
2088 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
2089 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2090 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
2091 del(pcd.SkuInfoList['COMMON'])\r
2092 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2093 del(pcd.SkuInfoList['COMMON'])\r
65eff519
LG
2094\r
2095 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
2096\r
2097 return Pcds\r
2098\r
65eff519
LG
2099 def FilterSkuSettings(self, PcdObj):\r
2100\r
2101 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
2102 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():\r
2103 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']\r
2104 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}\r
2105 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'\r
2106 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'\r
2107\r
2108 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:\r
2109 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}\r
2110\r
2111 return PcdObj\r
2112\r
2113\r
ae7b6df8
LG
2114 def CompareVarAttr(self, Attr1, Attr2):\r
2115 if not Attr1 or not Attr2: # for empty string\r
2116 return True\r
2117 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
2118 Attr1Set = set(Attr1s)\r
2119 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
2120 Attr2Set = set(Attr2s)\r
2121 if Attr2Set == Attr1Set:\r
2122 return True\r
2123 else:\r
2124 return False\r
8518bf0b
LG
2125 def CompletePcdValues(self,PcdSet):\r
2126 Pcds = {}\r
2127 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
98eb1364 2128 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}\r
8518bf0b
LG
2129 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
2130 for PcdCName, TokenSpaceGuid in PcdSet:\r
2131 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
2132 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
2133 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
2134 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
2135 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
2136 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
2137 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
2138 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
2139 continue\r
2140 PcdType = PcdObj.Type\r
2141 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
2142 for skuid in PcdObj.SkuInfoList:\r
2143 skuobj = PcdObj.SkuInfoList[skuid]\r
2144 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r
2145 for defaultstorename in DefaultStores:\r
2146 if defaultstorename not in skuobj.DefaultStoreDict:\r
2b8a6c44 2147 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
8518bf0b 2148 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
8ac16789 2149 for skuname,skuid in SkuIds.items():\r
2b8a6c44
LG
2150 if skuname not in PcdObj.SkuInfoList:\r
2151 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
8518bf0b
LG
2152 while nextskuid not in PcdObj.SkuInfoList:\r
2153 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
2154 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r
2155 PcdObj.SkuInfoList[skuname].SkuId = skuid\r
2156 PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r
8518bf0b
LG
2157 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
2158 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r
2159 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
2160 return Pcds\r
ae7b6df8
LG
2161 ## Retrieve dynamic HII PCD settings\r
2162 #\r
2163 # @param Type PCD type\r
2164 #\r
2165 # @retval a dict object contains settings of given PCD type\r
2166 #\r
2167 def _GetDynamicHiiPcd(self, Type):\r
2168\r
ae7b6df8
LG
2169 VariableAttrs = {}\r
2170\r
2171 Pcds = sdict()\r
2172 #\r
2173 # tdict is a special dict kind of type, used for selecting correct\r
2174 # PCD settings for certain ARCH and SKU\r
2175 #\r
8518bf0b 2176 PcdDict = tdict(True, 5)\r
ae7b6df8
LG
2177 PcdSet = set()\r
2178 RecordList = self._RawData[Type, self._Arch]\r
2179 # Find out all possible PCD candidates for self._Arch\r
8518bf0b 2180 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
2b8a6c44 2181 DefaultStoresDefine = self._GetDefaultStores()\r
ae7b6df8 2182\r
8518bf0b 2183 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
2184 SkuName = SkuName.upper()\r
2185 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
2186 DefaultStore = DefaultStore.upper()\r
8518bf0b
LG
2187 if DefaultStore == "COMMON":\r
2188 DefaultStore = "STANDARD"\r
ae7b6df8 2189 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2190 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2191 File=self.MetaFile, Line=Dummy5)\r
2192 if DefaultStore not in DefaultStoresDefine:\r
2193 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r
2194 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2195 if "." not in TokenSpaceGuid:\r
5db9414c 2196 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5))\r
8518bf0b 2197 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r
ae7b6df8
LG
2198\r
2199\r
2200 # Remove redundant PCD candidates, per the ARCH and SKU\r
8518bf0b 2201 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r
ae7b6df8 2202\r
8518bf0b 2203 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r
ae7b6df8
LG
2204 if Setting == None:\r
2205 continue\r
2206 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
2207\r
2208 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
2209 if not rt:\r
2210 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
2211 ExtraData="[%s]" % VarAttribute)\r
2212 ExceedMax = False\r
2213 FormatCorrect = True\r
2214 if VariableOffset.isdigit():\r
2215 if int(VariableOffset, 10) > 0xFFFF:\r
2216 ExceedMax = True\r
2217 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
2218 if int(VariableOffset, 16) > 0xFFFF:\r
2219 ExceedMax = True\r
2220 # For Offset written in "A.B"\r
2221 elif VariableOffset.find('.') > -1:\r
2222 VariableOffsetList = VariableOffset.split(".")\r
2223 if not (len(VariableOffsetList) == 2\r
2224 and IsValidWord(VariableOffsetList[0])\r
2225 and IsValidWord(VariableOffsetList[1])):\r
2226 FormatCorrect = False\r
2227 else:\r
2228 FormatCorrect = False\r
2229 if not FormatCorrect:\r
2230 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
2231\r
2232 if ExceedMax:\r
2233 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
2234 if (VariableName, VariableGuid) not in VariableAttrs:\r
2235 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
2236 else:\r
2237 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
2238 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
2239\r
ae7b6df8
LG
2240 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
2241 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
2242 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
8518bf0b
LG
2243 if SkuName in pcdObject.SkuInfoList:\r
2244 Skuitem = pcdObject.SkuInfoList[SkuName]\r
2245 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
2246 else:\r
2247 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
2248 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
ae7b6df8 2249 else:\r
8518bf0b 2250 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
ae7b6df8
LG
2251 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2252 PcdCName,\r
2253 TokenSpaceGuid,\r
2254 self._PCD_TYPE_STRING_[Type],\r
2255 '',\r
2256 DefaultValue,\r
2257 '',\r
2258 '',\r
2259 {SkuName : SkuInfo},\r
2260 False,\r
2261 None,\r
2262 pcdDecObject.validateranges,\r
2263 pcdDecObject.validlists,\r
2264 pcdDecObject.expressions,\r
2265 IsDsc=True)\r
2266\r
2267\r
2268 for pcd in Pcds.values():\r
2269 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2270 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e1511113 2271 pcd.DatumType = pcdDecObject.DatumType\r
ae7b6df8
LG
2272 # Only fix the value while no value provided in DSC file.\r
2273 for sku in pcd.SkuInfoList.values():\r
2274 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
2275 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
e1511113
B
2276 for default_store in sku.DefaultStoreDict:\r
2277 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue\r
2278 pcd.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
2279 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
2280 valuefromDec = pcdDecObject.DefaultValue\r
2b8a6c44 2281 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})\r
ae7b6df8
LG
2282 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
2283 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2284 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
2285 del(pcd.SkuInfoList['COMMON'])\r
2286 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2287 del(pcd.SkuInfoList['COMMON'])\r
2288\r
ae7b6df8
LG
2289 if pcd.MaxDatumSize.strip():\r
2290 MaxSize = int(pcd.MaxDatumSize, 0)\r
2291 else:\r
2292 MaxSize = 0\r
2293 if pcdDecObject.DatumType == 'VOID*':\r
2b8a6c44 2294 for (_, skuobj) in pcd.SkuInfoList.items():\r
ae7b6df8 2295 datalen = 0\r
47854fd5
LG
2296 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r
2297 datalen = len(skuobj.HiiDefaultValue.split(","))\r
ae7b6df8
LG
2298 if datalen > MaxSize:\r
2299 MaxSize = datalen\r
47854fd5
LG
2300 for defaultst in skuobj.DefaultStoreDict:\r
2301 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r
2302 pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r
ae7b6df8 2303 pcd.MaxDatumSize = str(MaxSize)\r
2b8a6c44
LG
2304 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r
2305 if not rt:\r
2306 invalidpcd = ",".join(invalidhii)\r
2307 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
2308\r
2309 map(self.FilterSkuSettings,Pcds.values())\r
2310\r
ae7b6df8
LG
2311 return Pcds\r
2312\r
2b8a6c44
LG
2313 def CheckVariableNameAssignment(self,Pcds):\r
2314 invalidhii = []\r
2315 for pcdname in Pcds:\r
2316 pcd = Pcds[pcdname]\r
2317 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])\r
2318 if len(varnameset) > 1:\r
2319 invalidhii.append(".".join((pcdname[1],pcdname[0])))\r
2320 if len(invalidhii):\r
2321 return False,invalidhii\r
2322 else:\r
2323 return True, []\r
ae7b6df8
LG
2324 ## Retrieve dynamic VPD PCD settings\r
2325 #\r
2326 # @param Type PCD type\r
2327 #\r
2328 # @retval a dict object contains settings of given PCD type\r
2329 #\r
2330 def _GetDynamicVpdPcd(self, Type):\r
2331\r
ae7b6df8
LG
2332\r
2333 Pcds = sdict()\r
2334 #\r
2335 # tdict is a special dict kind of type, used for selecting correct\r
2336 # PCD settings for certain ARCH and SKU\r
2337 #\r
2338 PcdDict = tdict(True, 4)\r
2339 PcdList = []\r
2340\r
2341 # Find out all possible PCD candidates for self._Arch\r
2342 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 2343 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 2344\r
8518bf0b 2345 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
2346 SkuName = SkuName.upper()\r
2347 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 2348 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2349 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2350 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2351 if "." not in TokenSpaceGuid:\r
5db9414c 2352 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8
LG
2353 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
2354\r
2355 # Remove redundant PCD candidates, per the ARCH and SKU\r
2356 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
2357 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
2358 if Setting == None:\r
2359 continue\r
2360 #\r
2361 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
2362 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
2363 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
2364 # until the DEC parser has been called.\r
2365 #\r
2366 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 2367 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
ae7b6df8
LG
2368 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
2369 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2370 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2371 if MaxDatumSize.strip():\r
2372 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2373 else:\r
2374 CurrentMaxSize = 0\r
2375 if pcdObject.MaxDatumSize:\r
2376 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2377 else:\r
2378 PcdMaxSize = 0\r
2379 if CurrentMaxSize > PcdMaxSize:\r
2380 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2381 else:\r
2382 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2383 PcdCName,\r
2384 TokenSpaceGuid,\r
2385 self._PCD_TYPE_STRING_[Type],\r
2386 '',\r
2387 InitialValue,\r
2388 '',\r
2389 MaxDatumSize,\r
2390 {SkuName : SkuInfo},\r
2391 False,\r
2392 None,\r
2393 IsDsc=True)\r
2394 for pcd in Pcds.values():\r
2395 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2396 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
8aa4db4b 2397 pcd.DatumType = pcdDecObject.DatumType\r
e651d06c
LG
2398 # Only fix the value while no value provided in DSC file.\r
2399 for sku in pcd.SkuInfoList.values():\r
2400 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
2401 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
2402 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
2403 valuefromDec = pcdDecObject.DefaultValue\r
2404 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
2405 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
2406 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2407 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
2408 del(pcd.SkuInfoList['COMMON'])\r
2409 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2410 del(pcd.SkuInfoList['COMMON'])\r
ae7b6df8 2411\r
65eff519
LG
2412\r
2413 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
2414 return Pcds\r
2415\r
2416 ## Add external modules\r
2417 #\r
2418 # The external modules are mostly those listed in FDF file, which don't\r
2419 # need "build".\r
2420 #\r
2421 # @param FilePath The path of module description file\r
2422 #\r
2423 def AddModule(self, FilePath):\r
2424 FilePath = NormPath(FilePath)\r
2425 if FilePath not in self.Modules:\r
2426 Module = ModuleBuildClassObject()\r
2427 Module.MetaFile = FilePath\r
2428 self.Modules.append(Module)\r
2429\r
68ba919f
YZ
2430 def _GetToolChainFamily(self):\r
2431 self._ToolChainFamily = "MSFT"\r
2432 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))\r
2433 if os.path.isfile(BuildConfigurationFile) == True:\r
2434 TargetTxt = TargetTxtClassObject()\r
2435 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
2436 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
2437 if ToolDefinitionFile == '':\r
2438 ToolDefinitionFile = "tools_def.txt"\r
2439 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))\r
2440 if os.path.isfile(ToolDefinitionFile) == True:\r
2441 ToolDef = ToolDefClassObject()\r
2442 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
2443 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
2444 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
2445 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
2446 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:\r
2447 self._ToolChainFamily = "MSFT"\r
2448 else:\r
2449 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]\r
2450 return self._ToolChainFamily\r
2451\r
ae7b6df8
LG
2452 ## Add external PCDs\r
2453 #\r
2454 # The external PCDs are mostly those listed in FDF file to specify address\r
2455 # or offset information.\r
2456 #\r
2457 # @param Name Name of the PCD\r
2458 # @param Guid Token space guid of the PCD\r
2459 # @param Value Value of the PCD\r
2460 #\r
2461 def AddPcd(self, Name, Guid, Value):\r
2462 if (Name, Guid) not in self.Pcds:\r
2463 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
2464 self.Pcds[Name, Guid].DefaultValue = Value\r
5644e5ce
FB
2465 @property\r
2466 def DecPcds(self):\r
2467 if self._DecPcds == None:\r
2468 FdfInfList = []\r
2469 if GlobalData.gFdfParser:\r
2470 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
2471 PkgSet = set()\r
2472 for Inf in FdfInfList:\r
2473 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
2474 if ModuleFile in self._Modules:\r
2475 continue\r
2476 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
2477 PkgSet.update(ModuleData.Packages)\r
726c501c 2478 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
5644e5ce 2479 return self._DecPcds\r
ae7b6df8
LG
2480 _Macros = property(_GetMacros)\r
2481 Arch = property(_GetArch, _SetArch)\r
2482 Platform = property(_GetPlatformName)\r
2483 PlatformName = property(_GetPlatformName)\r
2484 Guid = property(_GetFileGuid)\r
2485 Version = property(_GetVersion)\r
2486 DscSpecification = property(_GetDscSpec)\r
2487 OutputDirectory = property(_GetOutpuDir)\r
2488 SupArchList = property(_GetSupArch)\r
2489 BuildTargets = property(_GetBuildTarget)\r
2490 SkuName = property(_GetSkuName, _SetSkuName)\r
ae7b6df8
LG
2491 PcdInfoFlag = property(_GetPcdInfoFlag)\r
2492 VarCheckFlag = property(_GetVarCheckFlag)\r
2493 FlashDefinition = property(_GetFdfFile)\r
2494 Prebuild = property(_GetPrebuild)\r
2495 Postbuild = property(_GetPostbuild)\r
2496 BuildNumber = property(_GetBuildNumber)\r
2497 MakefileName = property(_GetMakefileName)\r
2498 BsBaseAddress = property(_GetBsBaseAddress)\r
2499 RtBaseAddress = property(_GetRtBaseAddress)\r
2500 LoadFixAddress = property(_GetLoadFixAddress)\r
2501 RFCLanguages = property(_GetRFCLanguages)\r
2502 ISOLanguages = property(_GetISOLanguages)\r
2503 VpdToolGuid = property(_GetVpdToolGuid)\r
2504 SkuIds = property(_GetSkuIds)\r
2505 Modules = property(_GetModules)\r
2506 LibraryInstances = property(_GetLibraryInstances)\r
2507 LibraryClasses = property(_GetLibraryClasses)\r
2508 Pcds = property(_GetPcds)\r
2509 BuildOptions = property(_GetBuildOptions)\r
68ba919f 2510 ToolChainFamily = property(_GetToolChainFamily)\r