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