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