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