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