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