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