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