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