]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Convert string value of void* pcd in command line to array.
[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
0fd04efd
ZZ
1070 #In command line, the latter full assign value in commandLine should override the former field assign value.\r
1071 #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"\r
1072 delete_assign = []\r
1073 field_assign = {}\r
1074 if GlobalData.BuildOptionPcd:\r
1075 for pcdTuple in GlobalData.BuildOptionPcd:\r
1076 TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]\r
1077 if Field:\r
1078 if (TokenSpaceGuid, Token) not in field_assign:\r
1079 field_assign[TokenSpaceGuid, Token] = []\r
1080 field_assign[TokenSpaceGuid, Token].append(pcdTuple)\r
1081 else:\r
1082 if (TokenSpaceGuid, Token) in field_assign:\r
1083 delete_assign.extend(field_assign[TokenSpaceGuid, Token])\r
1084 field_assign[TokenSpaceGuid, Token] = []\r
1085 for item in delete_assign:\r
1086 GlobalData.BuildOptionPcd.remove(item)\r
8565b582 1087\r
9e508f3a
CJ
1088 @staticmethod\r
1089 def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):\r
8565b582
YZ
1090 if FieldName:\r
1091 IsArray = False\r
1092 TokenCName += '.' + FieldName\r
1093 if PcdValue.startswith('H'):\r
1094 if FieldName and IsFieldValueAnArray(PcdValue[1:]):\r
656d2539 1095 PcdDatumType = TAB_VOID\r
8565b582
YZ
1096 IsArray = True\r
1097 if FieldName and not IsArray:\r
1098 return PcdValue\r
1099 try:\r
1100 PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)\r
5b0671c1 1101 except BadExpression as Value:\r
8565b582
YZ
1102 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1103 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r
1104 elif PcdValue.startswith("L'") or PcdValue.startswith("'"):\r
1105 if FieldName and IsFieldValueAnArray(PcdValue):\r
656d2539 1106 PcdDatumType = TAB_VOID\r
8565b582
YZ
1107 IsArray = True\r
1108 if FieldName and not IsArray:\r
1109 return PcdValue\r
1110 try:\r
1111 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r
5b0671c1 1112 except BadExpression as Value:\r
8565b582
YZ
1113 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1114 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r
1115 elif PcdValue.startswith('L'):\r
1116 PcdValue = 'L"' + PcdValue[1:] + '"'\r
1117 if FieldName and IsFieldValueAnArray(PcdValue):\r
656d2539 1118 PcdDatumType = TAB_VOID\r
8565b582
YZ
1119 IsArray = True\r
1120 if FieldName and not IsArray:\r
1121 return PcdValue\r
1122 try:\r
1123 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r
5b0671c1 1124 except BadExpression as Value:\r
8565b582
YZ
1125 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1126 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r
1127 else:\r
1128 if PcdValue.upper() == 'FALSE':\r
1129 PcdValue = str(0)\r
1130 if PcdValue.upper() == 'TRUE':\r
1131 PcdValue = str(1)\r
1132 if not FieldName:\r
656d2539 1133 if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:\r
8565b582
YZ
1134 PcdValue = '"' + PcdValue + '"'\r
1135 else:\r
1136 IsArray = False\r
1137 Base = 10\r
1138 if PcdValue.upper().startswith('0X'):\r
1139 Base = 16\r
1140 try:\r
1141 Num = int(PcdValue, Base)\r
1142 except:\r
1143 PcdValue = '"' + PcdValue + '"'\r
1144 if IsFieldValueAnArray(PcdValue):\r
656d2539 1145 PcdDatumType = TAB_VOID\r
8565b582
YZ
1146 IsArray = True\r
1147 if not IsArray:\r
1148 return PcdValue\r
1149 try:\r
1150 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)\r
5b0671c1 1151 except BadExpression as Value:\r
8565b582
YZ
1152 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %\r
1153 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))\r
1154 return PcdValue\r
1155\r
ae7b6df8 1156 ## Retrieve all PCD settings in platform\r
71cac3f7
CJ
1157 @property\r
1158 def Pcds(self):\r
4231a819 1159 if self._Pcds is None:\r
a0767bae 1160 self._Pcds = OrderedDict()\r
6f49996c 1161 self.__ParsePcdFromCommandLine()\r
ae7b6df8
LG
1162 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1163 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1164 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1165 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
1166 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
1167 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
1168 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
1169 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
1170 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
1171\r
8518bf0b 1172 self._Pcds = self.CompletePcdValues(self._Pcds)\r
543f5ac3
B
1173 self._Pcds = self.OverrideByFdfOverAll(self._Pcds)\r
1174 self._Pcds = self.OverrideByCommOverAll(self._Pcds)\r
ae7b6df8 1175 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
2b8a6c44 1176 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
8518bf0b 1177 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
b854e2bf 1178\r
6f49996c 1179 self.RecoverCommandLinePcd()\r
ae7b6df8
LG
1180 return self._Pcds\r
1181\r
1182 ## Retrieve [BuildOptions]\r
71cac3f7
CJ
1183 @property\r
1184 def BuildOptions(self):\r
4231a819 1185 if self._BuildOptions is None:\r
a0767bae 1186 self._BuildOptions = OrderedDict()\r
ae7b6df8
LG
1187 #\r
1188 # Retrieve build option for EDKII and EDK style module\r
1189 #\r
1190 for CodeBase in (EDKII_NAME, EDK_NAME):\r
1191 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
ccaa7754 1192 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:\r
55c84777 1193 if Dummy3.upper() != TAB_COMMON:\r
c05c2c05 1194 continue\r
ae7b6df8
LG
1195 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
1196 #\r
1197 # Only flags can be appended\r
1198 #\r
1199 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1200 self._BuildOptions[CurKey] = Option\r
1201 else:\r
c05c2c05
LG
1202 if ' ' + Option not in self._BuildOptions[CurKey]:\r
1203 self._BuildOptions[CurKey] += ' ' + Option\r
ae7b6df8
LG
1204 return self._BuildOptions\r
1205\r
1206 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
4231a819 1207 if self._ModuleTypeOptions is None:\r
a0767bae 1208 self._ModuleTypeOptions = OrderedDict()\r
ae7b6df8 1209 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
a0767bae 1210 options = OrderedDict()\r
ae7b6df8
LG
1211 self._ModuleTypeOptions[Edk, ModuleType] = options\r
1212 DriverType = '%s.%s' % (Edk, ModuleType)\r
55c84777 1213 CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)\r
c05c2c05 1214 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]\r
ccaa7754 1215 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:\r
c05c2c05
LG
1216 Type = Dummy2 + '.' + Dummy3\r
1217 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():\r
ae7b6df8
LG
1218 Key = (ToolChainFamily, ToolChain, Edk)\r
1219 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1220 options[Key] = Option\r
1221 else:\r
c05c2c05
LG
1222 if ' ' + Option not in options[Key]:\r
1223 options[Key] += ' ' + Option\r
ae7b6df8
LG
1224 return self._ModuleTypeOptions[Edk, ModuleType]\r
1225\r
9759febd
CJ
1226 @staticmethod\r
1227 def GetStructurePcdInfo(PcdSet):\r
1228 structure_pcd_data = defaultdict(list)\r
ae7b6df8 1229 for item in PcdSet:\r
ccaa7754 1230 structure_pcd_data[(item[0], item[1])].append(item)\r
ae7b6df8
LG
1231\r
1232 return structure_pcd_data\r
9e508f3a
CJ
1233\r
1234 @staticmethod\r
543f5ac3
B
1235 def OverrideByFdf(StruPcds,workspace):\r
1236 if GlobalData.gFdfParser is None:\r
1237 return StruPcds\r
1238 StructurePcdInFdf = OrderedDict()\r
1239 fdfpcd = GlobalData.gFdfParser.Profile.PcdDict\r
1240 fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict\r
1241 for item in fdfpcd :\r
1242 if len(item[2]) and (item[0],item[1]) in StruPcds:\r
1243 StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]\r
1244 GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}\r
1245 for Pcd in StruPcds.values():\r
1246 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:\r
1247 continue\r
1248 FieldValues = OrderedDict()\r
1249 for item in StructurePcdInFdf:\r
1250 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:\r
1251 FieldValues[item[2]] = StructurePcdInFdf[item]\r
1252 for field in FieldValues:\r
1253 if field not in Pcd.PcdFieldValueFromFdf:\r
1254 Pcd.PcdFieldValueFromFdf[field] = ["","",""]\r
1255 Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]\r
1256 Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)\r
1257 Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]\r
1258\r
1259 return StruPcds\r
1260\r
1261 @staticmethod\r
1262 def OverrideByComm(StruPcds):\r
b854e2bf
B
1263 StructurePcdInCom = OrderedDict()\r
1264 for item in GlobalData.BuildOptionPcd:\r
ccaa7754
GL
1265 if len(item) == 5 and (item[1], item[0]) in StruPcds:\r
1266 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])\r
1267 GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}\r
6f49996c 1268 for Pcd in StruPcds.values():\r
ccaa7754 1269 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:\r
6f49996c 1270 continue\r
b854e2bf
B
1271 FieldValues = OrderedDict()\r
1272 for item in StructurePcdInCom:\r
ccaa7754 1273 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:\r
b854e2bf
B
1274 FieldValues[item[2]] = StructurePcdInCom[item]\r
1275 for field in FieldValues:\r
1276 if field not in Pcd.PcdFieldValueFromComm:\r
ccaa7754 1277 Pcd.PcdFieldValueFromComm[field] = ["", "", ""]\r
b854e2bf
B
1278 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]\r
1279 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]\r
1280 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]\r
6f49996c 1281 return StruPcds\r
9e508f3a 1282\r
543f5ac3 1283 def OverrideByCommOverAll(self,AllPcds):\r
6f49996c
FB
1284 def CheckStructureInComm(commpcds):\r
1285 if not commpcds:\r
1286 return False\r
1287 if len(commpcds[0]) == 5:\r
1288 return True\r
1289 return False\r
57ee97c0 1290 NoFiledValues = OrderedDict()\r
6f49996c 1291 if CheckStructureInComm(GlobalData.BuildOptionPcd):\r
57ee97c0
B
1292 StructurePcdInCom = OrderedDict()\r
1293 for item in GlobalData.BuildOptionPcd:\r
1294 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])\r
1295 for item in StructurePcdInCom:\r
1296 if not item[2]:\r
1297 NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]\r
6f49996c 1298 else:\r
57ee97c0
B
1299 for item in GlobalData.BuildOptionPcd:\r
1300 NoFiledValues[(item[0], item[1])] = [item[2]]\r
ccaa7754
GL
1301 for Guid, Name in NoFiledValues:\r
1302 if (Name, Guid) in AllPcds:\r
1303 Pcd = AllPcds.get((Name, Guid))\r
1304 if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):\r
1305 self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
b854e2bf 1306 else:\r
a96133d2
Z
1307 if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1308 Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
1309 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
1310 else:\r
1311 Pcd.PcdValueFromComm = StringToArray(NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0])\r
1312 Pcd.DefaultValue = StringToArray(NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0])\r
b854e2bf
B
1313 for sku in Pcd.SkuInfoList:\r
1314 SkuInfo = Pcd.SkuInfoList[sku]\r
1315 if SkuInfo.DefaultValue:\r
a96133d2
Z
1316 if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1317 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
1318 else:\r
1319 SkuInfo.DefaultValue = StringToArray(NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0])\r
b854e2bf 1320 else:\r
a96133d2
Z
1321 if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1322 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
1323 else:\r
1324 SkuInfo.HiiDefaultValue = StringToArray(NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0])\r
b854e2bf 1325 for defaultstore in SkuInfo.DefaultStoreDict:\r
a96133d2
Z
1326 if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1327 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]\r
1328 else:\r
1329 SkuInfo.DefaultStoreDict[defaultstore] = StringToArray(NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0])\r
c8ae65ac 1330 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:\r
656d2539 1331 if Pcd.DatumType == TAB_VOID:\r
c8ae65ac
YZ
1332 if not Pcd.MaxDatumSize:\r
1333 Pcd.MaxDatumSize = '0'\r
ccaa7754 1334 CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)\r
c8ae65ac
YZ
1335 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))\r
1336 MaxSize = max(CurrentSize, OptionSize)\r
1337 Pcd.MaxDatumSize = str(MaxSize)\r
6f49996c 1338 else:\r
ccaa7754 1339 PcdInDec = self.DecPcds.get((Name, Guid))\r
6f49996c 1340 if PcdInDec:\r
a96133d2
Z
1341 if PcdInDec.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1342 PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]\r
1343 else:\r
1344 PcdInDec.PcdValueFromComm = StringToArray(NoFiledValues[(Guid, Name)][0])\r
6f49996c 1345 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
b7bfcd1a 1346 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],\r
7c193787
FB
1347 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],\r
1348 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],\r
1349 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:\r
6f49996c 1350 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)\r
a96133d2
Z
1351 if PcdInDec.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1352 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]\r
1353 else:\r
1354 self.Pcds[Name, Guid].DefaultValue = StringToArray(NoFiledValues[( Guid, Name)][0])\r
7c193787
FB
1355 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],\r
1356 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:\r
a96133d2
Z
1357 if PcdInDec.DatumType in TAB_PCD_NUMERIC_TYPES:\r
1358 self.Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}\r
1359 else:\r
1360 self.Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', StringToArray(NoFiledValues[( Guid, Name)][0]))}\r
6f49996c 1361 return AllPcds\r
543f5ac3
B
1362\r
1363 def OverrideByFdfOverAll(self,AllPcds):\r
1364\r
1365 if GlobalData.gFdfParser is None:\r
1366 return AllPcds\r
1367 NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict\r
4c6d0de7 1368 for Name,Guid,Field in NoFiledValues:\r
543f5ac3
B
1369 if len(Field):\r
1370 continue\r
4c6d0de7 1371 Value = NoFiledValues[(Name,Guid,Field)]\r
543f5ac3
B
1372 if (Name,Guid) in AllPcds:\r
1373 Pcd = AllPcds.get((Name,Guid))\r
1374 if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):\r
1375 self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value\r
1376 else:\r
1377 Pcd.PcdValueFromComm = Value\r
1378 Pcd.DefaultValue = Value\r
1379 for sku in Pcd.SkuInfoList:\r
1380 SkuInfo = Pcd.SkuInfoList[sku]\r
1381 if SkuInfo.DefaultValue:\r
1382 SkuInfo.DefaultValue = Value\r
1383 else:\r
1384 SkuInfo.HiiDefaultValue = Value\r
1385 for defaultstore in SkuInfo.DefaultStoreDict:\r
1386 SkuInfo.DefaultStoreDict[defaultstore] = Value\r
1387 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:\r
1388 if Pcd.DatumType == TAB_VOID:\r
1389 if not Pcd.MaxDatumSize:\r
1390 Pcd.MaxDatumSize = '0'\r
1391 CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)\r
1392 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))\r
1393 MaxSize = max(CurrentSize, OptionSize)\r
1394 Pcd.MaxDatumSize = str(MaxSize)\r
1395 else:\r
1396 PcdInDec = self.DecPcds.get((Name,Guid))\r
1397 if PcdInDec:\r
4c6d0de7 1398 PcdInDec.PcdValueFromFdf = Value\r
543f5ac3
B
1399 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1400 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],\r
1401 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:\r
1402 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)\r
1403 self.Pcds[Name, Guid].DefaultValue = Value\r
1404 return AllPcds\r
1405\r
ae7b6df8 1406 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
65eff519
LG
1407\r
1408 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1409 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1410 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1411 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1412 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1413 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]\r
1414\r
ae7b6df8 1415 Pcds = AllPcds\r
8518bf0b 1416 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
84a52d4d 1417 SkuIds = self.SkuIds\r
b491aa95 1418 DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}\r
ae7b6df8
LG
1419\r
1420 S_PcdSet = []\r
1421 # Find out all possible PCD candidates for self._Arch\r
1422 RecordList = []\r
2b8a6c44 1423\r
ae7b6df8
LG
1424 for Type in TypeList:\r
1425 RecordList.extend(self._RawData[Type, self._Arch])\r
1426\r
ccaa7754 1427 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:\r
2b8a6c44
LG
1428 SkuName = SkuName.upper()\r
1429 default_store = default_store.upper()\r
55c84777 1430 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName\r
8518bf0b
LG
1431 if SkuName not in SkuIds:\r
1432 continue\r
2b8a6c44 1433\r
8518bf0b 1434 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
ccaa7754 1435 S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])\r
ae7b6df8
LG
1436\r
1437 # handle pcd value override\r
9759febd 1438 StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)\r
79820e32 1439 S_pcd_set = OrderedDict()\r
ae7b6df8 1440 for str_pcd in StrPcdSet:\r
8518bf0b
LG
1441 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
1442 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
5db9414c
B
1443 if not isinstance (str_pcd_dec, StructurePcd):\r
1444 EdkLogger.error('build', PARSER_ERROR,\r
1445 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
ccaa7754 1446 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8
LG
1447 if str_pcd_dec:\r
1448 str_pcd_obj_str = StructurePcd()\r
1449 str_pcd_obj_str.copy(str_pcd_dec)\r
1450 if str_pcd_obj:\r
1451 str_pcd_obj_str.copy(str_pcd_obj)\r
f832bb34
FB
1452 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1453 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
1454 else:\r
1455 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 1456 for str_pcd_data in StrPcdSet[str_pcd]:\r
8518bf0b 1457 if str_pcd_data[3] in SkuIds:\r
ccaa7754 1458 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 1459 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
2b8a6c44
LG
1460 else:\r
1461 EdkLogger.error('build', PARSER_ERROR,\r
1462 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
ccaa7754 1463 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8 1464 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
5644e5ce 1465 for Pcd in self.DecPcds:\r
0d1f5b2b 1466 if isinstance(self._DecPcds[Pcd], StructurePcd):\r
ae7b6df8
LG
1467 if Pcd not in S_pcd_set:\r
1468 str_pcd_obj_str = StructurePcd()\r
1469 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1470 str_pcd_obj = Pcds.get(Pcd, None)\r
1471 if str_pcd_obj:\r
1472 str_pcd_obj_str.copy(str_pcd_obj)\r
77204d60
FB
1473 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1474 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
1475 else:\r
1476 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}\r
ae7b6df8
LG
1477 S_pcd_set[Pcd] = str_pcd_obj_str\r
1478 if S_pcd_set:\r
1479 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
8518bf0b 1480 for stru_pcd in S_pcd_set.values():\r
67e63e9a
LG
1481 for skuid in SkuIds:\r
1482 if skuid in stru_pcd.SkuOverrideValues:\r
1483 continue\r
1484 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1485 NoDefault = False\r
f3b31433
FB
1486 if skuid not in stru_pcd.SkuOverrideValues:\r
1487 while nextskuid not in stru_pcd.SkuOverrideValues:\r
55c84777 1488 if nextskuid == TAB_DEFAULT:\r
f3b31433
FB
1489 NoDefault = True\r
1490 break\r
1491 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
71127ce8 1492 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 1493 if not NoDefault:\r
ccaa7754 1494 stru_pcd.ValueChain.add((skuid, ''))\r
8518bf0b
LG
1495 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1496 for skuid in SkuIds:\r
1497 nextskuid = skuid\r
2b8a6c44 1498 NoDefault = False\r
8518bf0b
LG
1499 if skuid not in stru_pcd.SkuOverrideValues:\r
1500 while nextskuid not in stru_pcd.SkuOverrideValues:\r
55c84777 1501 if nextskuid == TAB_DEFAULT:\r
2b8a6c44
LG
1502 NoDefault = True\r
1503 break\r
8518bf0b 1504 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1505 if NoDefault:\r
1506 continue\r
c5c7e68a 1507 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])\r
8518bf0b 1508 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
2b8a6c44 1509\r
8518bf0b
LG
1510 for defaultstoreid in DefaultStores:\r
1511 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
2b8a6c44 1512 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
ccaa7754 1513 stru_pcd.ValueChain.add((skuid, defaultstoreid))\r
543f5ac3
B
1514 S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)\r
1515 S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)\r
ae7b6df8
LG
1516 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1517 if Str_Pcd_Values:\r
ccaa7754 1518 for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:\r
8518bf0b 1519 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
ae7b6df8 1520 if str_pcd_obj is None:\r
72443dd2 1521 print(PcdName, PcdGuid)\r
ae7b6df8
LG
1522 raise\r
1523 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1524 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
8518bf0b
LG
1525 if skuname not in str_pcd_obj.SkuInfoList:\r
1526 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
ae7b6df8 1527 else:\r
8518bf0b
LG
1528 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1529 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
ae7b6df8
LG
1530 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1531 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
55c84777 1532 if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):\r
8518bf0b 1533 str_pcd_obj.DefaultValue = PcdValue\r
ae7b6df8 1534 else:\r
8518bf0b 1535 if skuname not in str_pcd_obj.SkuInfoList:\r
65eff519
LG
1536 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
1537 NoDefault = False\r
1538 while nextskuid not in str_pcd_obj.SkuInfoList:\r
55c84777 1539 if nextskuid == TAB_DEFAULT:\r
65eff519
LG
1540 NoDefault = True\r
1541 break\r
1542 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1543 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
1544 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]\r
1545 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname\r
ae7b6df8 1546 else:\r
8518bf0b
LG
1547 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1548 for str_pcd_obj in S_pcd_set.values():\r
1549 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1550 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1551 continue\r
c5c7e68a 1552 PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)\r
8518bf0b
LG
1553 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1554 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1555 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
ae7b6df8
LG
1556\r
1557 for str_pcd_obj in S_pcd_set.values():\r
2b8a6c44 1558\r
ae7b6df8
LG
1559 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1560 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
6a147d6d 1561 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True\r
ae7b6df8 1562\r
65eff519
LG
1563 for pcdkey in Pcds:\r
1564 pcd = Pcds[pcdkey]\r
55c84777
CJ
1565 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
1566 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]\r
1567 del pcd.SkuInfoList[TAB_COMMON]\r
1568 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
1569 del pcd.SkuInfoList[TAB_COMMON]\r
65eff519 1570\r
1ccc4d89 1571 map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])\r
ae7b6df8
LG
1572 return Pcds\r
1573\r
1574 ## Retrieve non-dynamic PCD settings\r
1575 #\r
1576 # @param Type PCD type\r
1577 #\r
1578 # @retval a dict object contains settings of given PCD type\r
1579 #\r
1580 def _GetPcd(self, Type):\r
a0767bae 1581 Pcds = OrderedDict()\r
ae7b6df8
LG
1582 #\r
1583 # tdict is a special dict kind of type, used for selecting correct\r
1584 # PCD settings for certain ARCH\r
1585 #\r
2b8a6c44 1586 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8
LG
1587\r
1588 PcdDict = tdict(True, 3)\r
1589 PcdSet = set()\r
1590 # Find out all possible PCD candidates for self._Arch\r
1591 RecordList = self._RawData[Type, self._Arch]\r
a0767bae 1592 PcdValueDict = OrderedDict()\r
ccaa7754 1593 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:\r
2b8a6c44 1594 SkuName = SkuName.upper()\r
55c84777 1595 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName\r
2b8a6c44
LG
1596 if SkuName not in AvailableSkuIdSet:\r
1597 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1598 File=self.MetaFile, Line=Dummy5)\r
55c84777 1599 if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):\r
8518bf0b 1600 if "." not in TokenSpaceGuid:\r
5db9414c 1601 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8 1602 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
ae7b6df8
LG
1603\r
1604 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1605 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
4231a819 1606 if Setting is None:\r
ae7b6df8
LG
1607 continue\r
1608 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
f843a328
YZ
1609 if MaxDatumSize:\r
1610 if int(MaxDatumSize, 0) > 0xFFFF:\r
1611 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
1612 File=self.MetaFile, Line=Dummy4)\r
1613 if int(MaxDatumSize, 0) < 0:\r
1614 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
1615 File=self.MetaFile, Line=Dummy4)\r
ae7b6df8
LG
1616 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1617 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1618 else:\r
1619 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1620\r
1ccc4d89 1621 for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.iteritems():\r
8518bf0b
LG
1622 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1623 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
a77e5bca
CJ
1624 elif TAB_DEFAULT in PcdSetting:\r
1625 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]\r
1626 elif TAB_COMMON in PcdSetting:\r
1627 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]\r
1628 else:\r
1629 PcdValue = None\r
1630 DatumType = None\r
1631 MaxDatumSize = None\r
ae7b6df8
LG
1632\r
1633 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1634 PcdCName,\r
1635 TokenSpaceGuid,\r
1636 self._PCD_TYPE_STRING_[Type],\r
1637 DatumType,\r
1638 PcdValue,\r
1639 '',\r
1640 MaxDatumSize,\r
1641 {},\r
1642 False,\r
1643 None,\r
1644 IsDsc=True)\r
1645\r
71127ce8
FB
1646 if self.SkuIdMgr.SystemSkuId not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:\r
1647 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId] = {}\r
1648 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId][TAB_DEFAULT_STORES_DEFAULT] = PcdValue\r
ae7b6df8
LG
1649 return Pcds\r
1650\r
1651 def GetStructurePcdMaxSize(self, str_pcd):\r
1652 pcd_default_value = str_pcd.DefaultValue\r
1653 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
1654 sku_values.append(pcd_default_value)\r
1655\r
1656 def get_length(value):\r
1657 Value = value.strip()\r
a0939593 1658 if len(value) > 1:\r
91fa33ee 1659 if Value.startswith(TAB_GUID) and Value.endswith(')'):\r
a0939593
LG
1660 return 16\r
1661 if Value.startswith('L"') and Value.endswith('"'):\r
1662 return len(Value[2:-1])\r
1663 if Value[0] == '"' and Value[-1] == '"':\r
1664 return len(Value) - 2\r
1665 if Value[0] == '{' and Value[-1] == '}':\r
1666 return len(Value.split(","))\r
1667 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1668 return len(list(Value[2:-1]))\r
1669 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1670 return len(Value) - 2\r
ae7b6df8
LG
1671 return len(Value)\r
1672\r
8252e6bf 1673 return str(max(get_length(item) for item in sku_values))\r
ae7b6df8 1674\r
9e508f3a
CJ
1675 @staticmethod\r
1676 def ExecuteCommand (Command):\r
ae7b6df8
LG
1677 try:\r
1678 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1679 except:\r
5db9414c 1680 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)\r
ae7b6df8 1681 Result = Process.communicate()\r
1ccc4d89 1682 return Process.returncode, Result[0], Result[1]\r
ae7b6df8 1683\r
9e508f3a
CJ
1684 @staticmethod\r
1685 def IntToCString(Value, ValueSize):\r
ae7b6df8
LG
1686 Result = '"'\r
1687 if not isinstance (Value, str):\r
1688 for Index in range(0, ValueSize):\r
1689 Result = Result + '\\x%02x' % (Value & 0xff)\r
1690 Value = Value >> 8\r
1691 Result = Result + '"'\r
1692 return Result\r
1693\r
ccaa7754 1694 def GenerateSizeFunction(self, Pcd):\r
79820e32
B
1695 CApp = "// Default Value in Dec \n"\r
1696 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1697 for FieldList in [Pcd.DefaultValues]:\r
1698 if not FieldList:\r
1699 continue\r
1700 for FieldName in FieldList:\r
1701 FieldName = "." + FieldName\r
8565b582 1702 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
79820e32
B
1703 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r
1704 try:\r
656d2539 1705 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)\r
79820e32
B
1706 except BadExpression:\r
1707 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1708 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
1709 Value, ValueSize = ParseFieldValue(Value)\r
1710 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
1711 else:\r
1712 NewFieldName = ''\r
1713 FieldName_ori = FieldName.strip('.')\r
1714 while '[' in FieldName:\r
1715 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1716 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1717 FieldName = FieldName.split(']', 1)[1]\r
1718 FieldName = NewFieldName + FieldName\r
1719 while '[' in FieldName:\r
1720 FieldName = FieldName.rsplit('[', 1)[0]\r
1721 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
1722 for skuname in Pcd.SkuOverrideValues:\r
55c84777 1723 if skuname == TAB_COMMON:\r
79820e32
B
1724 continue\r
1725 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:\r
1726 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
1727 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:\r
1728 if not FieldList:\r
1729 continue\r
1730 for FieldName in FieldList:\r
1731 FieldName = "." + FieldName\r
8565b582 1732 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
79820e32
B
1733 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):\r
1734 try:\r
656d2539 1735 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)\r
79820e32
B
1736 except BadExpression:\r
1737 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1738 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))\r
1739 Value, ValueSize = ParseFieldValue(Value)\r
1740 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
1741 else:\r
1742 NewFieldName = ''\r
1743 FieldName_ori = FieldName.strip('.')\r
1744 while '[' in FieldName:\r
1745 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1746 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1747 FieldName = FieldName.split(']', 1)[1]\r
1748 FieldName = NewFieldName + FieldName\r
1749 while '[' in FieldName:\r
1750 FieldName = FieldName.rsplit('[', 1)[0]\r
1751 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
1752 if Pcd.PcdFieldValueFromFdf:\r
1753 CApp = CApp + "// From fdf \n"\r
1754 for FieldName in Pcd.PcdFieldValueFromFdf:\r
1755 FieldName = "." + FieldName\r
1756 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])\r
1757 if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):\r
1758 try:\r
1759 Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)\r
1760 except BadExpression:\r
1761 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1762 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))\r
1763 Value, ValueSize = ParseFieldValue(Value)\r
1764 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
1765 else:\r
1766 NewFieldName = ''\r
1767 FieldName_ori = FieldName.strip('.')\r
1768 while '[' in FieldName:\r
1769 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1770 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1771 FieldName = FieldName.split(']', 1)[1]\r
1772 FieldName = NewFieldName + FieldName\r
1773 while '[' in FieldName:\r
1774 FieldName = FieldName.rsplit('[', 1)[0]\r
1775 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
1776 if Pcd.PcdFieldValueFromComm:\r
1777 CApp = CApp + "// From Command Line \n"\r
1778 for FieldName in Pcd.PcdFieldValueFromComm:\r
1779 FieldName = "." + FieldName\r
8565b582 1780 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])\r
1667eec6 1781 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):\r
b854e2bf 1782 try:\r
656d2539 1783 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)\r
b854e2bf
B
1784 except BadExpression:\r
1785 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1667eec6 1786 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))\r
b854e2bf 1787 Value, ValueSize = ParseFieldValue(Value)\r
1667eec6 1788 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
1789 else:\r
1790 NewFieldName = ''\r
1791 FieldName_ori = FieldName.strip('.')\r
1792 while '[' in FieldName:\r
1793 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1794 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1795 FieldName = FieldName.split(']', 1)[1]\r
1796 FieldName = NewFieldName + FieldName\r
1797 while '[' in FieldName:\r
1798 FieldName = FieldName.rsplit('[', 1)[0]\r
1667eec6 1799 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 1800 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())\r
79820e32
B
1801 CApp = CApp + "}\n"\r
1802 return CApp\r
9e508f3a
CJ
1803\r
1804 @staticmethod\r
1805 def GenerateSizeStatments(Pcd):\r
79820e32
B
1806 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
1807 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1808 return CApp\r
9e508f3a 1809\r
ccaa7754 1810 def GenerateDefaultValueAssignFunction(self, Pcd):\r
79820e32 1811 CApp = "// Default value in Dec \n"\r
ccaa7754 1812 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)\r
79820e32
B
1813 CApp = CApp + ' UINT32 FieldSize;\n'\r
1814 CApp = CApp + ' CHAR8 *Value;\n'\r
1815 DefaultValueFromDec = Pcd.DefaultValueFromDec\r
8565b582 1816 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)\r
79820e32
B
1817 if IsArray:\r
1818 try:\r
656d2539 1819 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)\r
79820e32
B
1820 except BadExpression:\r
1821 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %\r
1822 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))\r
0f228f19 1823 DefaultValueFromDec = StringToArray(DefaultValueFromDec)\r
79820e32
B
1824 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)\r
1825 if isinstance(Value, str):\r
1826 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)\r
1827 elif IsArray:\r
1828 #\r
1829 # Use memcpy() to copy value into field\r
1830 #\r
9e508f3a 1831 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)\r
79820e32
B
1832 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1833 for FieldList in [Pcd.DefaultValues]:\r
1834 if not FieldList:\r
1835 continue\r
1836 for FieldName in FieldList:\r
8565b582 1837 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r
79820e32
B
1838 if IsArray:\r
1839 try:\r
656d2539 1840 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)\r
79820e32
B
1841 except BadExpression:\r
1842 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
ccaa7754 1843 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
79820e32
B
1844\r
1845 try:\r
1846 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1847 except Exception:\r
ccaa7754 1848 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
1849 if isinstance(Value, str):\r
1850 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1851 elif IsArray:\r
1852 #\r
1853 # Use memcpy() to copy value into field\r
1854 #\r
1855 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
9e508f3a 1856 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 1857 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
1858 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
1859 else:\r
e451aaa6
Z
1860 if '[' in FieldName and ']' in FieldName:\r
1861 Index = int(FieldName.split('[')[1].split(']')[0])\r
1862 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
1863 if ValueSize > 4:\r
1864 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1865 else:\r
1866 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
1867 CApp = CApp + "}\n"\r
1868 return CApp\r
9e508f3a
CJ
1869\r
1870 @staticmethod\r
1871 def GenerateDefaultValueAssignStatement(Pcd):\r
f3b31433
FB
1872 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1873 return CApp\r
9e508f3a 1874\r
ccaa7754
GL
1875 def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):\r
1876 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)\r
1877 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)\r
f3b31433
FB
1878 CApp = CApp + ' UINT32 FieldSize;\n'\r
1879 CApp = CApp + ' CHAR8 *Value;\n'\r
1880\r
55c84777 1881 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)\r
f3b31433 1882 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
ccaa7754 1883 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):\r
71127ce8 1884 pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None\r
f3b31433 1885 else:\r
ccaa7754
GL
1886 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)\r
1887 for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:\r
79820e32
B
1888 if not FieldList:\r
1889 continue\r
1890 if pcddefaultvalue and FieldList == pcddefaultvalue:\r
8565b582 1891 IsArray = IsFieldValueAnArray(FieldList)\r
79820e32
B
1892 if IsArray:\r
1893 try:\r
656d2539 1894 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)\r
79820e32
B
1895 except BadExpression:\r
1896 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %\r
1897 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
1898 Value, ValueSize = ParseFieldValue (FieldList)\r
f3b31433 1899\r
ccaa7754 1900 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):\r
f3b31433 1901 if isinstance(Value, str):\r
ccaa7754 1902 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
1903 elif IsArray:\r
1904 #\r
1905 # Use memcpy() to copy value into field\r
1906 #\r
ccaa7754 1907 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
1908 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1909 else:\r
1910 if isinstance(Value, str):\r
ccaa7754 1911 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))\r
f3b31433
FB
1912 elif IsArray:\r
1913 #\r
1914 # Use memcpy() to copy value into field\r
1915 #\r
ccaa7754 1916 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))\r
f3b31433 1917 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
79820e32 1918 continue\r
ccaa7754 1919 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):\r
f3b31433 1920 for FieldName in FieldList:\r
8565b582 1921 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r
f3b31433
FB
1922 if IsArray:\r
1923 try:\r
0caf9039 1924 FieldValue = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)\r
f3b31433
FB
1925 except BadExpression:\r
1926 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1927 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
79820e32 1928 try:\r
0caf9039
Z
1929 if IsArray:\r
1930 Value, ValueSize = ParseFieldValue (FieldValue)\r
1931 else:\r
1932 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
f3b31433 1933 except Exception:\r
ccaa7754 1934 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
1935 if isinstance(Value, str):\r
1936 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1937 elif IsArray:\r
1938 #\r
1939 # Use memcpy() to copy value into field\r
1940 #\r
1941 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
9e508f3a 1942 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 1943 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 1944 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
79820e32 1945 else:\r
e451aaa6
Z
1946 if '[' in FieldName and ']' in FieldName:\r
1947 Index = int(FieldName.split('[')[1].split(']')[0])\r
1948 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
1949 if ValueSize > 4:\r
1950 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1951 else:\r
1952 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
1953 CApp = CApp + "}\n"\r
1954 return CApp\r
9e508f3a
CJ
1955\r
1956 @staticmethod\r
ccaa7754
GL
1957 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):\r
1958 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)\r
79820e32 1959 return CApp\r
9e508f3a 1960\r
ccaa7754 1961 def GenerateCommandLineValue(self, Pcd):\r
b854e2bf 1962 CApp = "// Value in CommandLine\n"\r
ccaa7754 1963 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)\r
b854e2bf
B
1964 CApp = CApp + ' UINT32 FieldSize;\n'\r
1965 CApp = CApp + ' CHAR8 *Value;\n'\r
1966\r
1967 pcddefaultvalue = Pcd.PcdValueFromComm\r
ccaa7754 1968 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:\r
b854e2bf
B
1969 if not FieldList:\r
1970 continue\r
1971 if pcddefaultvalue and FieldList == pcddefaultvalue:\r
8565b582 1972 IsArray = IsFieldValueAnArray(FieldList)\r
b854e2bf
B
1973 if IsArray:\r
1974 try:\r
656d2539 1975 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)\r
b854e2bf 1976 except BadExpression:\r
0f228f19 1977 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %\r
b854e2bf
B
1978 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
1979 Value, ValueSize = ParseFieldValue (FieldList)\r
1980\r
1981 if isinstance(Value, str):\r
1982 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)\r
1983 elif IsArray:\r
1984 #\r
1985 # Use memcpy() to copy value into field\r
1986 #\r
9e508f3a 1987 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))\r
b854e2bf
B
1988 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1989 continue\r
1990 for FieldName in FieldList:\r
8565b582 1991 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r
b854e2bf
B
1992 if IsArray:\r
1993 try:\r
656d2539 1994 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)\r
b854e2bf
B
1995 except BadExpression:\r
1996 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
1997 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
1998 except:\r
72443dd2 1999 print("error")\r
b854e2bf
B
2000 try:\r
2001 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
2002 except Exception:\r
ccaa7754 2003 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
2004 if isinstance(Value, str):\r
2005 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2006 elif IsArray:\r
2007 #\r
2008 # Use memcpy() to copy value into field\r
2009 #\r
2010 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
9e508f3a 2011 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
b854e2bf
B
2012 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
2013 else:\r
2014 if ValueSize > 4:\r
2015 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2016 else:\r
2017 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2018 CApp = CApp + "}\n"\r
2019 return CApp\r
9e508f3a
CJ
2020\r
2021 @staticmethod\r
2022 def GenerateCommandLineValueStatement(Pcd):\r
b854e2bf
B
2023 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
2024 return CApp\r
543f5ac3
B
2025 def GenerateFdfValue(self,Pcd):\r
2026 CApp = "// Value in Fdf\n"\r
2027 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)\r
2028 CApp = CApp + ' UINT32 FieldSize;\n'\r
2029 CApp = CApp + ' CHAR8 *Value;\n'\r
2030\r
2031 pcddefaultvalue = Pcd.PcdValueFromFdf\r
2032 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:\r
2033 if not FieldList:\r
2034 continue\r
2035 if pcddefaultvalue and FieldList == pcddefaultvalue:\r
2036 IsArray = IsFieldValueAnArray(FieldList)\r
2037 if IsArray:\r
2038 try:\r
2039 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)\r
2040 except BadExpression:\r
2041 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %\r
2042 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))\r
2043 Value, ValueSize = ParseFieldValue (FieldList)\r
2044\r
2045 if isinstance(Value, str):\r
2046 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)\r
2047 elif IsArray:\r
2048 #\r
2049 # Use memcpy() to copy value into field\r
2050 #\r
2051 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))\r
2052 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
2053 continue\r
2054 for FieldName in FieldList:\r
2055 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])\r
2056 if IsArray:\r
2057 try:\r
2058 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)\r
2059 except BadExpression:\r
2060 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %\r
2061 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))\r
2062 except:\r
2063 print("error")\r
2064 try:\r
2065 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
2066 except Exception:\r
2067 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
2068 if isinstance(Value, str):\r
2069 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2070 elif IsArray:\r
2071 #\r
2072 # Use memcpy() to copy value into field\r
2073 #\r
2074 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
2075 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
2076 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
2077 else:\r
2078 if ValueSize > 4:\r
2079 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2080 else:\r
2081 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
2082 CApp = CApp + "}\n"\r
2083 return CApp\r
2084\r
2085 @staticmethod\r
2086 def GenerateFdfValueStatement(Pcd):\r
2087 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
2088 return CApp\r
9e508f3a 2089\r
f3b31433
FB
2090 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):\r
2091 OverrideValues = {DefaultStore:""}\r
ae7b6df8
LG
2092 if Pcd.SkuOverrideValues:\r
2093 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
71127ce8
FB
2094 if not OverrideValues:\r
2095 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}\r
5a693b89 2096 for DefaultStoreName in OverrideValues:\r
8518bf0b
LG
2097 CApp = CApp + 'void\n'\r
2098 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
2099 CApp = CApp + ' void\n'\r
2100 CApp = CApp + ' )\n'\r
2101 CApp = CApp + '{\n'\r
2102 CApp = CApp + ' UINT32 Size;\n'\r
2103 CApp = CApp + ' UINT32 FieldSize;\n'\r
b2395724 2104 CApp = CApp + ' CHAR8 *Value;\n'\r
8518bf0b
LG
2105 CApp = CApp + ' UINT32 OriginalSize;\n'\r
2106 CApp = CApp + ' VOID *OriginalPcd;\n'\r
6a103440 2107 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)\r
8518bf0b 2108 CApp = CApp + '\n'\r
47854fd5 2109\r
8e011d83 2110 if SkuName in Pcd.SkuInfoList:\r
ccaa7754 2111 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)\r
8e011d83
FB
2112 else:\r
2113 DefaultValue = Pcd.DefaultValue\r
2114 PcdDefaultValue = StringToArray(DefaultValue.strip())\r
47854fd5 2115\r
8518bf0b 2116 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
ae7b6df8 2117\r
8518bf0b
LG
2118 #\r
2119 # Get current PCD value and size\r
2120 #\r
2121 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 2122\r
8518bf0b
LG
2123 #\r
2124 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
2125 # the correct value. For structures with a flexible array member, the flexible\r
2126 # array member is detected, and the size is based on the highest index used with\r
2127 # the flexible array member. The flexible array member must be the last field\r
2128 # in a structure. The size formula for this case is:\r
2129 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
2130 #\r
9e508f3a 2131 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)\r
ae7b6df8 2132\r
8518bf0b
LG
2133 #\r
2134 # Allocate and zero buffer for the PCD\r
2135 # Must handle cases where current value is smaller, larger, or same size\r
2136 # Always keep that larger one as the current size\r
2137 #\r
2138 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
2139 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
2140 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
ae7b6df8 2141\r
8518bf0b
LG
2142 #\r
2143 # Copy current PCD value into allocated buffer.\r
2144 #\r
2145 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
ae7b6df8 2146\r
8518bf0b
LG
2147 #\r
2148 # Assign field values in PCD\r
2149 #\r
9e508f3a 2150 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)\r
f3b31433
FB
2151 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
2152 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
2153 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
4d3b9389 2154 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]\r
f3b31433
FB
2155 for defaultstorenameitem in storeset:\r
2156 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)\r
ccaa7754 2157 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)\r
f3b31433
FB
2158 if skuname == SkuName:\r
2159 break\r
2160 else:\r
f832bb34 2161 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId\r
ccaa7754 2162 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)\r
543f5ac3 2163 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)\r
9e508f3a 2164 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)\r
8518bf0b
LG
2165 #\r
2166 # Set new PCD value and size\r
2167 #\r
2168 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 2169\r
8518bf0b
LG
2170 #\r
2171 # Free PCD\r
2172 #\r
2173 CApp = CApp + ' free (Pcd);\n'\r
2174 CApp = CApp + '}\n'\r
2175 CApp = CApp + '\n'\r
ae7b6df8 2176 return InitByteValue, CApp\r
71127ce8
FB
2177 def SkuOverrideValuesEmpty(self,OverrideValues):\r
2178 if not OverrideValues:\r
2179 return True\r
2180 for key in OverrideValues:\r
2181 if OverrideValues[key]:\r
2182 return False\r
2183 return True\r
ae7b6df8
LG
2184\r
2185 def GenerateByteArrayValue (self, StructuredPcds):\r
2186 #\r
2187 # Generate/Compile/Run C application to determine if there are any flexible array members\r
2188 #\r
2189 if not StructuredPcds:\r
2190 return\r
2191\r
2192 InitByteValue = ""\r
2193 CApp = PcdMainCHeader\r
2194\r
34d808ad 2195 IncludeFiles = set()\r
ae7b6df8
LG
2196 for PcdName in StructuredPcds:\r
2197 Pcd = StructuredPcds[PcdName]\r
81add864 2198 for IncludeFile in Pcd.StructuredPcdIncludeFile:\r
1d5fde83 2199 if IncludeFile not in IncludeFiles:\r
34d808ad 2200 IncludeFiles.add(IncludeFile)\r
81add864 2201 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
ae7b6df8 2202 CApp = CApp + '\n'\r
ae7b6df8
LG
2203 for PcdName in StructuredPcds:\r
2204 Pcd = StructuredPcds[PcdName]\r
79820e32
B
2205 CApp = CApp + self.GenerateSizeFunction(Pcd)\r
2206 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)\r
543f5ac3 2207 CApp = CApp + self.GenerateFdfValue(Pcd)\r
b854e2bf 2208 CApp = CApp + self.GenerateCommandLineValue(Pcd)\r
71127ce8 2209 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
f3b31433 2210 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
ccaa7754 2211 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)\r
f3b31433
FB
2212 else:\r
2213 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
2214 if SkuName not in Pcd.SkuOverrideValues:\r
2215 continue\r
2216 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ccaa7754 2217 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)\r
71127ce8 2218 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
0a57a978 2219 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
4d3b9389 2220 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)\r
ae7b6df8 2221 else:\r
c05c2c05
LG
2222 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
2223 if SkuName not in Pcd.SkuOverrideValues:\r
2224 continue\r
ae7b6df8
LG
2225 for DefaultStoreName in Pcd.DefaultStoreName:\r
2226 Pcd = StructuredPcds[PcdName]\r
2227 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
2228\r
2229 CApp = CApp + 'VOID\n'\r
2230 CApp = CApp + 'PcdEntryPoint(\n'\r
2231 CApp = CApp + ' VOID\n'\r
2232 CApp = CApp + ' )\n'\r
2233 CApp = CApp + '{\n'\r
2234 for Pcd in StructuredPcds.values():\r
71127ce8 2235 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 2236 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 2237 else:\r
c05c2c05 2238 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
84a52d4d 2239 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:\r
c05c2c05 2240 continue\r
8518bf0b 2241 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ae7b6df8
LG
2242 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
2243 CApp = CApp + '}\n'\r
2244\r
2245 CApp = CApp + PcdMainCEntry + '\n'\r
2246\r
2247 if not os.path.exists(self.OutputPath):\r
2248 os.makedirs(self.OutputPath)\r
2249 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
0a57a978 2250 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)\r
ae7b6df8
LG
2251\r
2252 MakeApp = PcdMakefileHeader\r
2253 if sys.platform == "win32":\r
0a57a978 2254 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
ae7b6df8
LG
2255 else:\r
2256 MakeApp = MakeApp + PcdGccMakefile\r
2257 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
68ba919f 2258 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='\r
ae7b6df8 2259\r
34d808ad 2260 IncSearchList = []\r
57ee97c0 2261 PlatformInc = OrderedDict()\r
ae7b6df8
LG
2262 for Cache in self._Bdb._CACHE_.values():\r
2263 if Cache.MetaFile.Ext.lower() != '.dec':\r
2264 continue\r
2265 if Cache.Includes:\r
2266 if str(Cache.MetaFile.Path) not in PlatformInc:\r
b005802a
LG
2267 PlatformInc[str(Cache.MetaFile.Path)] = []\r
2268 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))\r
2269 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)\r
ae7b6df8
LG
2270\r
2271 PcdDependDEC = []\r
2272 for Pcd in StructuredPcds.values():\r
2273 for PackageDec in Pcd.PackageDecs:\r
2274 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
2275 if not os.path.exists(Package):\r
2276 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
2277 if Package not in PcdDependDEC:\r
2278 PcdDependDEC.append(Package)\r
2279\r
2280 if PlatformInc and PcdDependDEC:\r
2281 for pkg in PcdDependDEC:\r
2282 if pkg in PlatformInc:\r
2283 for inc in PlatformInc[pkg]:\r
2284 MakeApp += '-I' + str(inc) + ' '\r
34d808ad 2285 IncSearchList.append(inc)\r
ae7b6df8 2286 MakeApp = MakeApp + '\n'\r
68ba919f
YZ
2287\r
2288 CC_FLAGS = LinuxCFLAGS\r
2289 if sys.platform == "win32":\r
2290 CC_FLAGS = WindowsCFLAGS\r
57ee97c0 2291 BuildOptions = OrderedDict()\r
68ba919f
YZ
2292 for Options in self.BuildOptions:\r
2293 if Options[2] != EDKII_NAME:\r
2294 continue\r
2295 Family = Options[0]\r
2296 if Family and Family != self.ToolChainFamily:\r
2297 continue\r
2298 Target, Tag, Arch, Tool, Attr = Options[1].split("_")\r
2299 if Tool != 'CC':\r
2300 continue\r
2301\r
2302 if Target == "*" or Target == self._Target:\r
2303 if Tag == "*" or Tag == self._Toolchain:\r
2304 if Arch == "*" or Arch == self.Arch:\r
2305 if Tool not in BuildOptions:\r
57ee97c0 2306 BuildOptions[Tool] = OrderedDict()\r
68ba919f
YZ
2307 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):\r
2308 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
2309 else:\r
2310 # append options for the same tool except PATH\r
2311 if Attr != 'PATH':\r
2312 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]\r
2313 else:\r
2314 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
2315 if BuildOptions:\r
2316 for Tool in BuildOptions:\r
2317 for Attr in BuildOptions[Tool]:\r
2318 if Attr == "FLAGS":\r
2319 Value = BuildOptions[Tool][Attr]\r
2320 ValueList = Value.split()\r
2321 if ValueList:\r
2322 for Id, Item in enumerate(ValueList):\r
5d9af6a5 2323 if Item in ['-D', '/D', '-U', '/U']:\r
68ba919f
YZ
2324 CC_FLAGS += ' ' + Item\r
2325 if Id + 1 < len(ValueList):\r
2326 CC_FLAGS += ' ' + ValueList[Id + 1]\r
5d9af6a5 2327 elif Item.startswith(('-D', '/D', '-U', '/U')):\r
68ba919f
YZ
2328 CC_FLAGS += ' ' + Item\r
2329 MakeApp += CC_FLAGS\r
2330\r
ae7b6df8
LG
2331 if sys.platform == "win32":\r
2332 MakeApp = MakeApp + PcdMakefileEnd\r
34d808ad
B
2333 MakeApp = MakeApp + '\n'\r
2334 IncludeFileFullPaths = []\r
2335 for includefile in IncludeFiles:\r
2336 for includepath in IncSearchList:\r
ccaa7754 2337 includefullpath = os.path.join(str(includepath), includefile)\r
34d808ad
B
2338 if os.path.exists(includefullpath):\r
2339 IncludeFileFullPaths.append(os.path.normpath(includefullpath))\r
2340 break\r
2341 SearchPathList = []\r
2342 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))\r
2343 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))\r
8252e6bf 2344 SearchPathList.extend(str(item) for item in IncSearchList)\r
ccaa7754 2345 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)\r
34d808ad
B
2346 for include_file in IncFileList:\r
2347 MakeApp += "$(OBJECTS) : %s\n" % include_file\r
ae7b6df8 2348 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
34d808ad 2349 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName\r
0a57a978 2350 SaveFileOnChange(MakeFileName, MakeApp, False)\r
ae7b6df8
LG
2351\r
2352 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
2353 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
0a57a978 2354 SaveFileOnChange(InputValueFile, InitByteValue, False)\r
ae7b6df8
LG
2355\r
2356 PcdValueInitExe = PcdValueInitName\r
2357 if not sys.platform == "win32":\r
2358 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
5db9414c 2359 else:\r
0a57a978 2360 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"\r
34d808ad
B
2361\r
2362 Messages = ''\r
2363 if sys.platform == "win32":\r
2364 MakeCommand = 'nmake -f %s' % (MakeFileName)\r
9e508f3a 2365 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)\r
34d808ad
B
2366 Messages = StdOut\r
2367 else:\r
2368 MakeCommand = 'make -f %s' % (MakeFileName)\r
9e508f3a 2369 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)\r
34d808ad
B
2370 Messages = StdErr\r
2371 Messages = Messages.split('\n')\r
2372 MessageGroup = []\r
9fb2cbda 2373 if returncode != 0:\r
34d808ad
B
2374 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
2375 File = open (CAppBaseFileName + '.c', 'r')\r
2376 FileData = File.readlines()\r
2377 File.close()\r
2378 for Message in Messages:\r
2379 if " error" in Message or "warning" in Message:\r
2380 FileInfo = Message.strip().split('(')\r
2381 if len (FileInfo) > 1:\r
2382 FileName = FileInfo [0]\r
2383 FileLine = FileInfo [1].split (')')[0]\r
2384 else:\r
2385 FileInfo = Message.strip().split(':')\r
2386 FileName = FileInfo [0]\r
2387 FileLine = FileInfo [1]\r
2388 if FileLine.isdigit():\r
2389 error_line = FileData[int (FileLine) - 1]\r
2390 if r"//" in error_line:\r
ccaa7754 2391 c_line, dsc_line = error_line.split(r"//")\r
0a57a978 2392 else:\r
34d808ad
B
2393 dsc_line = error_line\r
2394 message_itmes = Message.split(":")\r
2395 Index = 0\r
2396 if "PcdValueInit.c" not in Message:\r
2397 if not MessageGroup:\r
2398 MessageGroup.append(Message)\r
2399 break\r
0a57a978 2400 else:\r
34d808ad
B
2401 for item in message_itmes:\r
2402 if "PcdValueInit.c" in item:\r
2403 Index = message_itmes.index(item)\r
2404 message_itmes[Index] = dsc_line.strip()\r
2405 break\r
2406 MessageGroup.append(":".join(message_itmes[Index:]).strip())\r
2407 continue\r
2408 else:\r
2409 MessageGroup.append(Message)\r
2410 if MessageGroup:\r
2411 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )\r
2412 else:\r
2413 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)\r
2414\r
ccaa7754 2415 if DscBuildData.NeedUpdateOutput(OutputValueFile, PcdValueInitExe, InputValueFile):\r
0a57a978 2416 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)\r
9e508f3a 2417 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)\r
87d2afd0 2418 if returncode != 0:\r
0a57a978
FB
2419 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)\r
2420\r
2421 File = open (OutputValueFile, 'r')\r
2422 FileBuffer = File.readlines()\r
2423 File.close()\r
ae7b6df8
LG
2424\r
2425 StructurePcdSet = []\r
2426 for Pcd in FileBuffer:\r
2427 PcdValue = Pcd.split ('|')\r
2428 PcdInfo = PcdValue[0].split ('.')\r
ccaa7754 2429 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
ae7b6df8
LG
2430 return StructurePcdSet\r
2431\r
9e508f3a
CJ
2432 @staticmethod\r
2433 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):\r
0a57a978
FB
2434 if not os.path.exists(OutputFile):\r
2435 return True\r
2436 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:\r
2437 return True\r
0a57a978
FB
2438 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:\r
2439 return True\r
2440 return False\r
2441\r
ae7b6df8
LG
2442 ## Retrieve dynamic PCD settings\r
2443 #\r
2444 # @param Type PCD type\r
2445 #\r
2446 # @retval a dict object contains settings of given PCD type\r
2447 #\r
2448 def _GetDynamicPcd(self, Type):\r
2449\r
ae7b6df8 2450\r
a0767bae 2451 Pcds = OrderedDict()\r
ae7b6df8
LG
2452 #\r
2453 # tdict is a special dict kind of type, used for selecting correct\r
2454 # PCD settings for certain ARCH and SKU\r
2455 #\r
2456 PcdDict = tdict(True, 4)\r
2457 PcdList = []\r
2458 # Find out all possible PCD candidates for self._Arch\r
2459 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 2460 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 2461\r
ae7b6df8 2462\r
ccaa7754 2463 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:\r
2b8a6c44 2464 SkuName = SkuName.upper()\r
55c84777 2465 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName\r
ae7b6df8 2466 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2467 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2468 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2469 if "." not in TokenSpaceGuid:\r
5db9414c 2470 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8
LG
2471 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
2472\r
2473 # Remove redundant PCD candidates, per the ARCH and SKU\r
2474 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
2475\r
2476 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
4231a819 2477 if Setting is None:\r
ae7b6df8
LG
2478 continue\r
2479\r
2480 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
f843a328
YZ
2481 if MaxDatumSize:\r
2482 if int(MaxDatumSize, 0) > 0xFFFF:\r
2483 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
2484 File=self.MetaFile, Line=Dummy4)\r
2485 if int(MaxDatumSize, 0) < 0:\r
2486 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
2487 File=self.MetaFile, Line=Dummy4)\r
8518bf0b 2488 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
5a693b89 2489 if (PcdCName, TokenSpaceGuid) in Pcds:\r
ae7b6df8
LG
2490 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2491 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2492 if MaxDatumSize.strip():\r
2493 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2494 else:\r
2495 CurrentMaxSize = 0\r
2496 if pcdObject.MaxDatumSize:\r
2497 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2498 else:\r
2499 PcdMaxSize = 0\r
2500 if CurrentMaxSize > PcdMaxSize:\r
2501 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2502 else:\r
2503 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2504 PcdCName,\r
2505 TokenSpaceGuid,\r
2506 self._PCD_TYPE_STRING_[Type],\r
2507 DatumType,\r
2508 PcdValue,\r
2509 '',\r
2510 MaxDatumSize,\r
57ee97c0 2511 OrderedDict({SkuName : SkuInfo}),\r
ae7b6df8
LG
2512 False,\r
2513 None,\r
2514 IsDsc=True)\r
2515\r
71127ce8
FB
2516 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:\r
2517 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}\r
2518 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue\r
2519\r
ae7b6df8
LG
2520 for pcd in Pcds.values():\r
2521 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
2522 # Only fix the value while no value provided in DSC file.\r
2523 for sku in pcd.SkuInfoList.values():\r
128d435f 2524 if not sku.DefaultValue:\r
e651d06c 2525 sku.DefaultValue = pcdDecObject.DefaultValue\r
55c84777 2526 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:\r
ae7b6df8 2527 valuefromDec = pcdDecObject.DefaultValue\r
55c84777
CJ
2528 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)\r
2529 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo\r
2530 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2531 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]\r
2532 del pcd.SkuInfoList[TAB_COMMON]\r
2533 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2534 del pcd.SkuInfoList[TAB_COMMON]\r
65eff519 2535\r
1ccc4d89 2536 map(self.FilterSkuSettings, Pcds.values())\r
ae7b6df8
LG
2537\r
2538 return Pcds\r
2539\r
65eff519
LG
2540 def FilterSkuSettings(self, PcdObj):\r
2541\r
2542 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
55c84777
CJ
2543 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:\r
2544 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]\r
2545 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}\r
2546 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT\r
2547 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'\r
65eff519
LG
2548\r
2549 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:\r
55c84777 2550 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}\r
65eff519
LG
2551\r
2552 return PcdObj\r
2553\r
9e508f3a
CJ
2554 @staticmethod\r
2555 def CompareVarAttr(Attr1, Attr2):\r
ae7b6df8
LG
2556 if not Attr1 or not Attr2: # for empty string\r
2557 return True\r
2558 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
2559 Attr1Set = set(Attr1s)\r
2560 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
2561 Attr2Set = set(Attr2s)\r
2562 if Attr2Set == Attr1Set:\r
2563 return True\r
2564 else:\r
2565 return False\r
9e508f3a 2566\r
ccaa7754 2567 def CompletePcdValues(self, PcdSet):\r
57ee97c0 2568 Pcds = OrderedDict()\r
8518bf0b 2569 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
ccaa7754 2570 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}\r
c5c7e68a 2571 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)\r
8518bf0b
LG
2572 for PcdCName, TokenSpaceGuid in PcdSet:\r
2573 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
71127ce8 2574\r
8518bf0b
LG
2575 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
2576 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
2577 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
2578 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
2579 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
2580 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
2581 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
2582 continue\r
2583 PcdType = PcdObj.Type\r
2584 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
2585 for skuid in PcdObj.SkuInfoList:\r
2586 skuobj = PcdObj.SkuInfoList[skuid]\r
8252e6bf 2587 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))\r
8518bf0b
LG
2588 for defaultstorename in DefaultStores:\r
2589 if defaultstorename not in skuobj.DefaultStoreDict:\r
2b8a6c44 2590 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
8518bf0b 2591 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
ccaa7754 2592 for skuname, skuid in SkuIds.items():\r
2b8a6c44
LG
2593 if skuname not in PcdObj.SkuInfoList:\r
2594 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
8518bf0b
LG
2595 while nextskuid not in PcdObj.SkuInfoList:\r
2596 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
2597 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r
2598 PcdObj.SkuInfoList[skuname].SkuId = skuid\r
2599 PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r
8518bf0b 2600 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1ccc4d89 2601 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue\r
8518bf0b
LG
2602 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
2603 return Pcds\r
ae7b6df8
LG
2604 ## Retrieve dynamic HII PCD settings\r
2605 #\r
2606 # @param Type PCD type\r
2607 #\r
2608 # @retval a dict object contains settings of given PCD type\r
2609 #\r
2610 def _GetDynamicHiiPcd(self, Type):\r
2611\r
ae7b6df8
LG
2612 VariableAttrs = {}\r
2613\r
a0767bae 2614 Pcds = OrderedDict()\r
ced86858 2615 UserDefinedDefaultStores = []\r
ae7b6df8
LG
2616 #\r
2617 # tdict is a special dict kind of type, used for selecting correct\r
2618 # PCD settings for certain ARCH and SKU\r
2619 #\r
8518bf0b 2620 PcdDict = tdict(True, 5)\r
ae7b6df8
LG
2621 PcdSet = set()\r
2622 RecordList = self._RawData[Type, self._Arch]\r
2623 # Find out all possible PCD candidates for self._Arch\r
8518bf0b 2624 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
2b8a6c44 2625 DefaultStoresDefine = self._GetDefaultStores()\r
ae7b6df8 2626\r
ccaa7754 2627 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:\r
2b8a6c44 2628 SkuName = SkuName.upper()\r
55c84777 2629 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName\r
2b8a6c44 2630 DefaultStore = DefaultStore.upper()\r
55c84777 2631 if DefaultStore == TAB_COMMON:\r
4d3b9389 2632 DefaultStore = TAB_DEFAULT_STORES_DEFAULT\r
ced86858
ZZ
2633 else:\r
2634 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC\r
2635 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))\r
ae7b6df8 2636 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2637 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2638 File=self.MetaFile, Line=Dummy5)\r
2639 if DefaultStore not in DefaultStoresDefine:\r
2640 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r
2641 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2642 if "." not in TokenSpaceGuid:\r
ccaa7754
GL
2643 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))\r
2644 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting\r
ae7b6df8
LG
2645\r
2646\r
2647 # Remove redundant PCD candidates, per the ARCH and SKU\r
ccaa7754 2648 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:\r
ae7b6df8 2649\r
ccaa7754 2650 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]\r
4231a819 2651 if Setting is None:\r
ae7b6df8
LG
2652 continue\r
2653 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
2654\r
2655 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
2656 if not rt:\r
2657 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
2658 ExtraData="[%s]" % VarAttribute)\r
2659 ExceedMax = False\r
2660 FormatCorrect = True\r
2661 if VariableOffset.isdigit():\r
2662 if int(VariableOffset, 10) > 0xFFFF:\r
2663 ExceedMax = True\r
3e4faa26 2664 elif variablePattern.match(VariableOffset):\r
ae7b6df8
LG
2665 if int(VariableOffset, 16) > 0xFFFF:\r
2666 ExceedMax = True\r
2667 # For Offset written in "A.B"\r
2668 elif VariableOffset.find('.') > -1:\r
2669 VariableOffsetList = VariableOffset.split(".")\r
2670 if not (len(VariableOffsetList) == 2\r
2671 and IsValidWord(VariableOffsetList[0])\r
2672 and IsValidWord(VariableOffsetList[1])):\r
2673 FormatCorrect = False\r
2674 else:\r
2675 FormatCorrect = False\r
2676 if not FormatCorrect:\r
2677 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
2678\r
2679 if ExceedMax:\r
2680 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
2681 if (VariableName, VariableGuid) not in VariableAttrs:\r
2682 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
2683 else:\r
9e508f3a 2684 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
ae7b6df8
LG
2685 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
2686\r
ae7b6df8 2687 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
5a693b89 2688 if (PcdCName, TokenSpaceGuid) in Pcds:\r
ae7b6df8 2689 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
8518bf0b
LG
2690 if SkuName in pcdObject.SkuInfoList:\r
2691 Skuitem = pcdObject.SkuInfoList[SkuName]\r
2692 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
2693 else:\r
ccaa7754 2694 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})\r
8518bf0b 2695 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
ae7b6df8 2696 else:\r
ccaa7754 2697 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})\r
ced86858 2698 PcdClassObj = PcdClassObject(\r
ae7b6df8
LG
2699 PcdCName,\r
2700 TokenSpaceGuid,\r
2701 self._PCD_TYPE_STRING_[Type],\r
2702 '',\r
2703 DefaultValue,\r
2704 '',\r
2705 '',\r
57ee97c0 2706 OrderedDict({SkuName : SkuInfo}),\r
ae7b6df8
LG
2707 False,\r
2708 None,\r
2709 pcdDecObject.validateranges,\r
2710 pcdDecObject.validlists,\r
2711 pcdDecObject.expressions,\r
2712 IsDsc=True)\r
ced86858
ZZ
2713 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:\r
2714 PcdClassObj.UserDefinedDefaultStoresFlag = True\r
2715 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj\r
ae7b6df8 2716\r
6a147d6d 2717 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)\r
71127ce8
FB
2718 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:\r
2719 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}\r
2720 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue\r
ae7b6df8 2721 for pcd in Pcds.values():\r
1ccc4d89 2722 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
ae7b6df8 2723 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e1511113 2724 pcd.DatumType = pcdDecObject.DatumType\r
ae7b6df8
LG
2725 # Only fix the value while no value provided in DSC file.\r
2726 for sku in pcd.SkuInfoList.values():\r
4231a819 2727 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):\r
ae7b6df8 2728 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
e1511113
B
2729 for default_store in sku.DefaultStoreDict:\r
2730 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue\r
2731 pcd.DefaultValue = pcdDecObject.DefaultValue\r
55c84777 2732 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:\r
ae7b6df8 2733 valuefromDec = pcdDecObject.DefaultValue\r
ccaa7754 2734 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})\r
55c84777
CJ
2735 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo\r
2736 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2737 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]\r
2738 del pcd.SkuInfoList[TAB_COMMON]\r
2739 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2740 del pcd.SkuInfoList[TAB_COMMON]\r
ae7b6df8 2741\r
ae7b6df8
LG
2742 if pcd.MaxDatumSize.strip():\r
2743 MaxSize = int(pcd.MaxDatumSize, 0)\r
2744 else:\r
2745 MaxSize = 0\r
656d2539 2746 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:\r
2b8a6c44 2747 for (_, skuobj) in pcd.SkuInfoList.items():\r
ae7b6df8 2748 datalen = 0\r
47854fd5
LG
2749 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r
2750 datalen = len(skuobj.HiiDefaultValue.split(","))\r
ae7b6df8
LG
2751 if datalen > MaxSize:\r
2752 MaxSize = datalen\r
47854fd5
LG
2753 for defaultst in skuobj.DefaultStoreDict:\r
2754 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r
2755 pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r
ae7b6df8 2756 pcd.MaxDatumSize = str(MaxSize)\r
9e508f3a 2757 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)\r
2b8a6c44
LG
2758 if not rt:\r
2759 invalidpcd = ",".join(invalidhii)\r
2760 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 2761\r
1ccc4d89 2762 map(self.FilterSkuSettings, Pcds.values())\r
65eff519 2763\r
ae7b6df8
LG
2764 return Pcds\r
2765\r
9e508f3a
CJ
2766 @staticmethod\r
2767 def CheckVariableNameAssignment(Pcds):\r
2b8a6c44
LG
2768 invalidhii = []\r
2769 for pcdname in Pcds:\r
2770 pcd = Pcds[pcdname]\r
ccaa7754 2771 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())\r
2b8a6c44 2772 if len(varnameset) > 1:\r
ccaa7754 2773 invalidhii.append(".".join((pcdname[1], pcdname[0])))\r
2b8a6c44 2774 if len(invalidhii):\r
ccaa7754 2775 return False, invalidhii\r
2b8a6c44
LG
2776 else:\r
2777 return True, []\r
ae7b6df8
LG
2778 ## Retrieve dynamic VPD PCD settings\r
2779 #\r
2780 # @param Type PCD type\r
2781 #\r
2782 # @retval a dict object contains settings of given PCD type\r
2783 #\r
2784 def _GetDynamicVpdPcd(self, Type):\r
2785\r
ae7b6df8 2786\r
a0767bae 2787 Pcds = OrderedDict()\r
ae7b6df8
LG
2788 #\r
2789 # tdict is a special dict kind of type, used for selecting correct\r
2790 # PCD settings for certain ARCH and SKU\r
2791 #\r
2792 PcdDict = tdict(True, 4)\r
2793 PcdList = []\r
2794\r
2795 # Find out all possible PCD candidates for self._Arch\r
2796 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 2797 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 2798\r
ccaa7754 2799 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:\r
2b8a6c44 2800 SkuName = SkuName.upper()\r
55c84777 2801 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName\r
ae7b6df8 2802 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
2803 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
2804 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 2805 if "." not in TokenSpaceGuid:\r
5db9414c 2806 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))\r
ae7b6df8
LG
2807 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
2808\r
2809 # Remove redundant PCD candidates, per the ARCH and SKU\r
2810 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
2811 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
4231a819 2812 if Setting is None:\r
ae7b6df8
LG
2813 continue\r
2814 #\r
2815 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
2816 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
2817 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
2818 # until the DEC parser has been called.\r
2819 #\r
2820 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
f843a328
YZ
2821 if MaxDatumSize:\r
2822 if int(MaxDatumSize, 0) > 0xFFFF:\r
2823 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
2824 File=self.MetaFile, Line=Dummy4)\r
2825 if int(MaxDatumSize, 0) < 0:\r
2826 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),\r
2827 File=self.MetaFile, Line=Dummy4)\r
8518bf0b 2828 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
5a693b89 2829 if (PcdCName, TokenSpaceGuid) in Pcds:\r
ae7b6df8
LG
2830 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2831 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2832 if MaxDatumSize.strip():\r
2833 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2834 else:\r
2835 CurrentMaxSize = 0\r
2836 if pcdObject.MaxDatumSize:\r
2837 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2838 else:\r
2839 PcdMaxSize = 0\r
2840 if CurrentMaxSize > PcdMaxSize:\r
2841 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2842 else:\r
2843 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2844 PcdCName,\r
2845 TokenSpaceGuid,\r
2846 self._PCD_TYPE_STRING_[Type],\r
2847 '',\r
2848 InitialValue,\r
2849 '',\r
2850 MaxDatumSize,\r
57ee97c0 2851 OrderedDict({SkuName : SkuInfo}),\r
ae7b6df8
LG
2852 False,\r
2853 None,\r
2854 IsDsc=True)\r
71127ce8
FB
2855\r
2856 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:\r
2857 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}\r
2858 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue\r
ae7b6df8 2859 for pcd in Pcds.values():\r
1ccc4d89 2860 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
ae7b6df8 2861 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
8aa4db4b 2862 pcd.DatumType = pcdDecObject.DatumType\r
e651d06c
LG
2863 # Only fix the value while no value provided in DSC file.\r
2864 for sku in pcd.SkuInfoList.values():\r
128d435f 2865 if not sku.DefaultValue:\r
e651d06c 2866 sku.DefaultValue = pcdDecObject.DefaultValue\r
55c84777 2867 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:\r
ae7b6df8 2868 valuefromDec = pcdDecObject.DefaultValue\r
55c84777
CJ
2869 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
2870 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo\r
2871 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2872 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]\r
2873 del pcd.SkuInfoList[TAB_COMMON]\r
2874 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:\r
2875 del pcd.SkuInfoList[TAB_COMMON]\r
ae7b6df8 2876\r
65eff519 2877\r
1ccc4d89 2878 map(self.FilterSkuSettings, Pcds.values())\r
ae7b6df8
LG
2879 return Pcds\r
2880\r
2881 ## Add external modules\r
2882 #\r
2883 # The external modules are mostly those listed in FDF file, which don't\r
2884 # need "build".\r
2885 #\r
2886 # @param FilePath The path of module description file\r
2887 #\r
2888 def AddModule(self, FilePath):\r
2889 FilePath = NormPath(FilePath)\r
2890 if FilePath not in self.Modules:\r
2891 Module = ModuleBuildClassObject()\r
2892 Module.MetaFile = FilePath\r
2893 self.Modules.append(Module)\r
2894\r
71cac3f7
CJ
2895 @property\r
2896 def ToolChainFamily(self):\r
94c04559 2897 self._ToolChainFamily = TAB_COMPILER_MSFT\r
68ba919f
YZ
2898 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))\r
2899 if os.path.isfile(BuildConfigurationFile) == True:\r
2900 TargetTxt = TargetTxtClassObject()\r
2901 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
2902 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
2903 if ToolDefinitionFile == '':\r
2904 ToolDefinitionFile = "tools_def.txt"\r
2905 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))\r
2906 if os.path.isfile(ToolDefinitionFile) == True:\r
2907 ToolDef = ToolDefClassObject()\r
2908 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
2909 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
2910 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
2911 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
2912 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:\r
94c04559 2913 self._ToolChainFamily = TAB_COMPILER_MSFT\r
68ba919f
YZ
2914 else:\r
2915 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]\r
2916 return self._ToolChainFamily\r
2917\r
ae7b6df8
LG
2918 ## Add external PCDs\r
2919 #\r
2920 # The external PCDs are mostly those listed in FDF file to specify address\r
2921 # or offset information.\r
2922 #\r
2923 # @param Name Name of the PCD\r
2924 # @param Guid Token space guid of the PCD\r
2925 # @param Value Value of the PCD\r
2926 #\r
2927 def AddPcd(self, Name, Guid, Value):\r
2928 if (Name, Guid) not in self.Pcds:\r
2929 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
2930 self.Pcds[Name, Guid].DefaultValue = Value\r
71cac3f7 2931\r
5644e5ce
FB
2932 @property\r
2933 def DecPcds(self):\r
4231a819 2934 if self._DecPcds is None:\r
5644e5ce
FB
2935 FdfInfList = []\r
2936 if GlobalData.gFdfParser:\r
2937 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
2938 PkgSet = set()\r
2939 for Inf in FdfInfList:\r
2940 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
2941 if ModuleFile in self._Modules:\r
2942 continue\r
2943 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
2944 PkgSet.update(ModuleData.Packages)\r
ccaa7754 2945 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)\r
5644e5ce 2946 return self._DecPcds\r