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