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