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