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