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