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