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