]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/DscBuildData.py
MdeModulePkg/SdMmcPciHcDxe: allow HC capabilities to be overridden
[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
24\r
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
40from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject\r
41\r
42#\r
43# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs\r
44#\r
45PcdValueInitName = 'PcdValueInit'\r
46PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']\r
47PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}\r
48PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']\r
49\r
50PcdMainCHeader = '''\r
51/**\r
52 DO NOT EDIT\r
53 FILE auto-generated\r
54**/\r
55\r
56#include <stdio.h>\r
57#include <stdlib.h>\r
58#include <string.h>\r
59#include <PcdValueCommon.h>\r
60'''\r
61\r
62PcdMainCEntry = '''\r
63int\r
64main (\r
65 int argc,\r
66 char *argv[]\r
67 )\r
68{\r
69 return PcdValueMain (argc, argv);\r
70}\r
71'''\r
72\r
73PcdMakefileHeader = '''\r
74#\r
75# DO NOT EDIT\r
76# This file is auto-generated by build utility\r
77#\r
78\r
79'''\r
80\r
68ba919f
YZ
81WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '\r
82LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '\r
ae7b6df8
LG
83PcdMakefileEnd = '''\r
84!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common\r
85\r
ae7b6df8
LG
86LIBS = $(LIB_PATH)\Common.lib\r
87\r
88!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app\r
89'''\r
90\r
91PcdGccMakefile = '''\r
92ARCH ?= IA32\r
93MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C\r
94LIBS = -lCommon\r
95'''\r
96\r
97class DscBuildData(PlatformBuildClassObject):\r
98 # dict used to convert PCD type in database to string used by build tool\r
99 _PCD_TYPE_STRING_ = {\r
100 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
101 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
102 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
103 MODEL_PCD_DYNAMIC : "Dynamic",\r
104 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
105 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
106 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
107 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
108 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
109 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
110 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
111 }\r
112\r
113 # dict used to convert part of [Defines] to members of DscBuildData directly\r
114 _PROPERTY_ = {\r
115 #\r
116 # Required Fields\r
117 #\r
118 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",\r
119 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",\r
120 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",\r
121 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",\r
122 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",\r
123 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",\r
124 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",\r
125 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",\r
126 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",\r
127 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",\r
128 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
129 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",\r
130 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",\r
131 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",\r
132 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",\r
133 }\r
134\r
135 # used to compose dummy library class name for those forced library instances\r
136 _NullLibraryNumber = 0\r
137\r
138 ## Constructor of DscBuildData\r
139 #\r
140 # Initialize object of DscBuildData\r
141 #\r
142 # @param FilePath The path of platform description file\r
143 # @param RawData The raw data of DSC file\r
144 # @param BuildDataBase Database used to retrieve module/package information\r
145 # @param Arch The target architecture\r
146 # @param Platform (not used for DscBuildData)\r
147 # @param Macros Macros used for replacement in DSC file\r
148 #\r
149 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
150 self.MetaFile = FilePath\r
151 self._RawData = RawData\r
152 self._Bdb = BuildDataBase\r
153 self._Arch = Arch\r
154 self._Target = Target\r
155 self._Toolchain = Toolchain\r
68ba919f 156 self._ToolChainFamily = None\r
ae7b6df8
LG
157 self._Clear()\r
158 self._HandleOverridePath()\r
159 if os.getenv("WORKSPACE"):\r
160 self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)\r
161 else:\r
162 self.OutputPath = os.path.dirname(self.DscFile)\r
8518bf0b 163 self.DefaultStores = None\r
e651d06c 164 self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)\r
8518bf0b 165 arraystr = self.SkuIdMgr.DumpSkuIdArrary()\r
ae7b6df8
LG
166\r
167 ## XXX[key] = value\r
168 def __setitem__(self, key, value):\r
169 self.__dict__[self._PROPERTY_[key]] = value\r
170\r
171 ## value = XXX[key]\r
172 def __getitem__(self, key):\r
173 return self.__dict__[self._PROPERTY_[key]]\r
174\r
175 ## "in" test support\r
176 def __contains__(self, key):\r
177 return key in self._PROPERTY_\r
178\r
179 ## Set all internal used members of DscBuildData to None\r
180 def _Clear(self):\r
181 self._Header = None\r
182 self._PlatformName = None\r
183 self._Guid = None\r
184 self._Version = None\r
185 self._DscSpecification = None\r
186 self._OutputDirectory = None\r
187 self._SupArchList = None\r
188 self._BuildTargets = None\r
189 self._SkuName = None\r
ae7b6df8
LG
190 self._PcdInfoFlag = None\r
191 self._VarCheckFlag = None\r
192 self._FlashDefinition = None\r
193 self._Prebuild = None\r
194 self._Postbuild = None\r
195 self._BuildNumber = None\r
196 self._MakefileName = None\r
197 self._BsBaseAddress = None\r
198 self._RtBaseAddress = None\r
199 self._SkuIds = None\r
200 self._Modules = None\r
201 self._LibraryInstances = None\r
202 self._LibraryClasses = None\r
203 self._Pcds = None\r
204 self._DecPcds = None\r
205 self._BuildOptions = None\r
206 self._ModuleTypeOptions = None\r
207 self._LoadFixAddress = None\r
208 self._RFCLanguages = None\r
209 self._ISOLanguages = None\r
210 self._VpdToolGuid = None\r
211 self.__Macros = None\r
8518bf0b 212 self.DefaultStores = None\r
ae7b6df8
LG
213\r
214\r
215 ## handle Override Path of Module\r
216 def _HandleOverridePath(self):\r
217 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
218 Macros = self._Macros\r
219 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
220 for Record in RecordList:\r
8518bf0b
LG
221 ModuleId = Record[6]\r
222 LineNo = Record[7]\r
ae7b6df8
LG
223 ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
224 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
225 if RecordList != []:\r
226 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
227\r
228 # Check if the source override path exists\r
229 if not os.path.isdir(SourceOverridePath):\r
230 EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r
231\r
232 # Add to GlobalData Variables\r
233 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r
234\r
235 ## Get current effective macros\r
236 def _GetMacros(self):\r
237 if self.__Macros == None:\r
238 self.__Macros = {}\r
239 self.__Macros.update(GlobalData.gPlatformDefines)\r
240 self.__Macros.update(GlobalData.gGlobalDefines)\r
241 self.__Macros.update(GlobalData.gCommandLineDefines)\r
242 return self.__Macros\r
243\r
244 ## Get architecture\r
245 def _GetArch(self):\r
246 return self._Arch\r
247\r
248 ## Set architecture\r
249 #\r
250 # Changing the default ARCH to another may affect all other information\r
251 # because all information in a platform may be ARCH-related. That's\r
252 # why we need to clear all internal used members, in order to cause all\r
253 # information to be re-retrieved.\r
254 #\r
255 # @param Value The value of ARCH\r
256 #\r
257 def _SetArch(self, Value):\r
258 if self._Arch == Value:\r
259 return\r
260 self._Arch = Value\r
261 self._Clear()\r
262\r
263 ## Retrieve all information in [Defines] section\r
264 #\r
265 # (Retriving all [Defines] information in one-shot is just to save time.)\r
266 #\r
267 def _GetHeaderInfo(self):\r
268 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
269 for Record in RecordList:\r
270 Name = Record[1]\r
271 # items defined _PROPERTY_ don't need additional processing\r
272\r
273 # some special items in [Defines] section need special treatment\r
274 if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
275 self._OutputDirectory = NormPath(Record[2], self._Macros)\r
276 if ' ' in self._OutputDirectory:\r
277 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
278 File=self.MetaFile, Line=Record[-1],\r
279 ExtraData=self._OutputDirectory)\r
280 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
281 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
282 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
283 if ErrorCode != 0:\r
284 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
285 ExtraData=ErrorInfo)\r
286 elif Name == TAB_DSC_PREBUILD:\r
287 PrebuildValue = Record[2]\r
288 if Record[2][0] == '"':\r
289 if Record[2][-1] != '"':\r
290 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,\r
291 File=self.MetaFile, Line=Record[-1])\r
292 PrebuildValue = Record[2][1:-1]\r
293 self._Prebuild = PrebuildValue\r
294 elif Name == TAB_DSC_POSTBUILD:\r
295 PostbuildValue = Record[2]\r
296 if Record[2][0] == '"':\r
297 if Record[2][-1] != '"':\r
298 EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,\r
299 File=self.MetaFile, Line=Record[-1])\r
300 PostbuildValue = Record[2][1:-1]\r
301 self._Postbuild = PostbuildValue\r
302 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
303 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
304 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
305 self._BuildTargets = GetSplitValueList(Record[2])\r
306 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
307 if self._SkuName == None:\r
308 self._SkuName = Record[2]\r
e651d06c
LG
309 if GlobalData.gSKUID_CMD:\r
310 self._SkuName = GlobalData.gSKUID_CMD\r
ae7b6df8
LG
311 elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
312 self._PcdInfoFlag = Record[2]\r
313 elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
314 self._VarCheckFlag = Record[2]\r
315 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
316 try:\r
317 self._LoadFixAddress = int (Record[2], 0)\r
318 except:\r
319 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
320 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
321 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
322 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
323 File=self.MetaFile, Line=Record[-1])\r
324 LanguageCodes = Record[2][1:-1]\r
325 if not LanguageCodes:\r
326 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
327 File=self.MetaFile, Line=Record[-1])\r
328 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
329 # check whether there is empty entries in the list\r
330 if None in LanguageList:\r
331 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
332 File=self.MetaFile, Line=Record[-1])\r
333 self._RFCLanguages = LanguageList\r
334 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
335 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
336 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
337 File=self.MetaFile, Line=Record[-1])\r
338 LanguageCodes = Record[2][1:-1]\r
339 if not LanguageCodes:\r
340 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
341 File=self.MetaFile, Line=Record[-1])\r
342 if len(LanguageCodes) % 3:\r
343 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
344 File=self.MetaFile, Line=Record[-1])\r
345 LanguageList = []\r
346 for i in range(0, len(LanguageCodes), 3):\r
347 LanguageList.append(LanguageCodes[i:i + 3])\r
348 self._ISOLanguages = LanguageList\r
349 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
350 #\r
351 # try to convert GUID to a real UUID value to see whether the GUID is format\r
352 # for VPD_TOOL_GUID is correct.\r
353 #\r
354 try:\r
355 uuid.UUID(Record[2])\r
356 except:\r
357 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
358 self._VpdToolGuid = Record[2]\r
359 elif Name in self:\r
360 self[Name] = Record[2]\r
361 # set _Header to non-None in order to avoid database re-querying\r
362 self._Header = 'DUMMY'\r
363\r
364 ## Retrieve platform name\r
365 def _GetPlatformName(self):\r
366 if self._PlatformName == None:\r
367 if self._Header == None:\r
368 self._GetHeaderInfo()\r
369 if self._PlatformName == None:\r
370 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)\r
371 return self._PlatformName\r
372\r
373 ## Retrieve file guid\r
374 def _GetFileGuid(self):\r
375 if self._Guid == None:\r
376 if self._Header == None:\r
377 self._GetHeaderInfo()\r
378 if self._Guid == None:\r
379 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)\r
380 return self._Guid\r
381\r
382 ## Retrieve platform version\r
383 def _GetVersion(self):\r
384 if self._Version == None:\r
385 if self._Header == None:\r
386 self._GetHeaderInfo()\r
387 if self._Version == None:\r
388 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\r
389 return self._Version\r
390\r
391 ## Retrieve platform description file version\r
392 def _GetDscSpec(self):\r
393 if self._DscSpecification == None:\r
394 if self._Header == None:\r
395 self._GetHeaderInfo()\r
396 if self._DscSpecification == None:\r
397 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)\r
398 return self._DscSpecification\r
399\r
400 ## Retrieve OUTPUT_DIRECTORY\r
401 def _GetOutpuDir(self):\r
402 if self._OutputDirectory == None:\r
403 if self._Header == None:\r
404 self._GetHeaderInfo()\r
405 if self._OutputDirectory == None:\r
406 self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
407 return self._OutputDirectory\r
408\r
409 ## Retrieve SUPPORTED_ARCHITECTURES\r
410 def _GetSupArch(self):\r
411 if self._SupArchList == None:\r
412 if self._Header == None:\r
413 self._GetHeaderInfo()\r
414 if self._SupArchList == None:\r
415 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\r
416 return self._SupArchList\r
417\r
418 ## Retrieve BUILD_TARGETS\r
419 def _GetBuildTarget(self):\r
420 if self._BuildTargets == None:\r
421 if self._Header == None:\r
422 self._GetHeaderInfo()\r
423 if self._BuildTargets == None:\r
424 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
425 return self._BuildTargets\r
426\r
427 def _GetPcdInfoFlag(self):\r
428 if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
429 return False\r
430 elif self._PcdInfoFlag.upper() == 'TRUE':\r
431 return True\r
432 else:\r
433 return False\r
434 def _GetVarCheckFlag(self):\r
435 if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
436 return False\r
437 elif self._VarCheckFlag.upper() == 'TRUE':\r
438 return True\r
439 else:\r
440 return False\r
e651d06c
LG
441\r
442 # # Retrieve SKUID_IDENTIFIER\r
ae7b6df8
LG
443 def _GetSkuName(self):\r
444 if self._SkuName == None:\r
445 if self._Header == None:\r
446 self._GetHeaderInfo()\r
e651d06c 447 if self._SkuName == None:\r
ae7b6df8
LG
448 self._SkuName = 'DEFAULT'\r
449 return self._SkuName\r
450\r
451 ## Override SKUID_IDENTIFIER\r
452 def _SetSkuName(self, Value):\r
453 self._SkuName = Value\r
454 self._Pcds = None\r
455\r
456 def _GetFdfFile(self):\r
457 if self._FlashDefinition == None:\r
458 if self._Header == None:\r
459 self._GetHeaderInfo()\r
460 if self._FlashDefinition == None:\r
461 self._FlashDefinition = ''\r
462 return self._FlashDefinition\r
463\r
464 def _GetPrebuild(self):\r
465 if self._Prebuild == None:\r
466 if self._Header == None:\r
467 self._GetHeaderInfo()\r
468 if self._Prebuild == None:\r
469 self._Prebuild = ''\r
470 return self._Prebuild\r
471\r
472 def _GetPostbuild(self):\r
473 if self._Postbuild == None:\r
474 if self._Header == None:\r
475 self._GetHeaderInfo()\r
476 if self._Postbuild == None:\r
477 self._Postbuild = ''\r
478 return self._Postbuild\r
479\r
480 ## Retrieve FLASH_DEFINITION\r
481 def _GetBuildNumber(self):\r
482 if self._BuildNumber == None:\r
483 if self._Header == None:\r
484 self._GetHeaderInfo()\r
485 if self._BuildNumber == None:\r
486 self._BuildNumber = ''\r
487 return self._BuildNumber\r
488\r
489 ## Retrieve MAKEFILE_NAME\r
490 def _GetMakefileName(self):\r
491 if self._MakefileName == None:\r
492 if self._Header == None:\r
493 self._GetHeaderInfo()\r
494 if self._MakefileName == None:\r
495 self._MakefileName = ''\r
496 return self._MakefileName\r
497\r
498 ## Retrieve BsBaseAddress\r
499 def _GetBsBaseAddress(self):\r
500 if self._BsBaseAddress == None:\r
501 if self._Header == None:\r
502 self._GetHeaderInfo()\r
503 if self._BsBaseAddress == None:\r
504 self._BsBaseAddress = ''\r
505 return self._BsBaseAddress\r
506\r
507 ## Retrieve RtBaseAddress\r
508 def _GetRtBaseAddress(self):\r
509 if self._RtBaseAddress == None:\r
510 if self._Header == None:\r
511 self._GetHeaderInfo()\r
512 if self._RtBaseAddress == None:\r
513 self._RtBaseAddress = ''\r
514 return self._RtBaseAddress\r
515\r
516 ## Retrieve the top address for the load fix address\r
517 def _GetLoadFixAddress(self):\r
518 if self._LoadFixAddress == None:\r
519 if self._Header == None:\r
520 self._GetHeaderInfo()\r
521\r
522 if self._LoadFixAddress == None:\r
523 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
524\r
525 try:\r
526 self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
527 except:\r
528 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
529\r
530 #\r
531 # If command line defined, should override the value in DSC file.\r
532 #\r
533 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
534 try:\r
535 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
536 except:\r
537 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
538\r
539 if self._LoadFixAddress < 0:\r
540 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
541 if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
542 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
543\r
544 return self._LoadFixAddress\r
545\r
546 ## Retrieve RFCLanguage filter\r
547 def _GetRFCLanguages(self):\r
548 if self._RFCLanguages == None:\r
549 if self._Header == None:\r
550 self._GetHeaderInfo()\r
551 if self._RFCLanguages == None:\r
552 self._RFCLanguages = []\r
553 return self._RFCLanguages\r
554\r
555 ## Retrieve ISOLanguage filter\r
556 def _GetISOLanguages(self):\r
557 if self._ISOLanguages == None:\r
558 if self._Header == None:\r
559 self._GetHeaderInfo()\r
560 if self._ISOLanguages == None:\r
561 self._ISOLanguages = []\r
562 return self._ISOLanguages\r
563 ## Retrieve the GUID string for VPD tool\r
564 def _GetVpdToolGuid(self):\r
565 if self._VpdToolGuid == None:\r
566 if self._Header == None:\r
567 self._GetHeaderInfo()\r
568 if self._VpdToolGuid == None:\r
569 self._VpdToolGuid = ''\r
570 return self._VpdToolGuid\r
571\r
572 ## Retrieve [SkuIds] section information\r
573 def _GetSkuIds(self):\r
574 if self._SkuIds == None:\r
575 self._SkuIds = sdict()\r
576 RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
577 for Record in RecordList:\r
578 if Record[0] in [None, '']:\r
579 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
580 File=self.MetaFile, Line=Record[-1])\r
581 if Record[1] in [None, '']:\r
582 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
583 File=self.MetaFile, Line=Record[-1])\r
8518bf0b 584 Pattern = re.compile('^[1-9]\d*|0$')\r
e6b10112
YZ
585 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')\r
586 if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None:\r
587 EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",\r
8518bf0b
LG
588 File=self.MetaFile, Line=Record[-1])\r
589 if not IsValidWord(Record[1]):\r
590 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
591 File=self.MetaFile, Line=Record[-1])\r
e6b10112 592 self._SkuIds[Record[1].upper()] = (str(self.ToInt(Record[0])), Record[1].upper(), Record[2].upper())\r
ae7b6df8 593 if 'DEFAULT' not in self._SkuIds:\r
8518bf0b 594 self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")\r
ae7b6df8 595 if 'COMMON' not in self._SkuIds:\r
8518bf0b 596 self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")\r
ae7b6df8 597 return self._SkuIds\r
8518bf0b
LG
598 def ToInt(self,intstr):\r
599 return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr)\r
600 def _GetDefaultStores(self):\r
601 if self.DefaultStores == None:\r
602 self.DefaultStores = sdict()\r
603 RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]\r
604 for Record in RecordList:\r
605 if Record[0] in [None, '']:\r
606 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',\r
607 File=self.MetaFile, Line=Record[-1])\r
608 if Record[1] in [None, '']:\r
609 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',\r
610 File=self.MetaFile, Line=Record[-1])\r
767ddbe8
YZ
611 Pattern = re.compile('^[1-9]\d*|0$')\r
612 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')\r
613 if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None:\r
614 EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",\r
615 File=self.MetaFile, Line=Record[-1])\r
616 if not IsValidWord(Record[1]):\r
617 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
618 File=self.MetaFile, Line=Record[-1])\r
2b8a6c44 619 self.DefaultStores[Record[1].upper()] = (self.ToInt(Record[0]),Record[1].upper())\r
8518bf0b
LG
620 if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:\r
621 self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT)\r
e651d06c
LG
622 GlobalData.gDefaultStores = self.DefaultStores.keys()\r
623 if GlobalData.gDefaultStores:\r
624 GlobalData.gDefaultStores.sort()\r
8518bf0b 625 return self.DefaultStores\r
ae7b6df8
LG
626\r
627 ## Retrieve [Components] section information\r
628 def _GetModules(self):\r
629 if self._Modules != None:\r
630 return self._Modules\r
631\r
632 self._Modules = sdict()\r
633 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
634 Macros = self._Macros\r
635 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
636 for Record in RecordList:\r
637 DuplicatedFile = False\r
638\r
639 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
8518bf0b
LG
640 ModuleId = Record[6]\r
641 LineNo = Record[7]\r
ae7b6df8
LG
642\r
643 # check the file validation\r
644 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
645 if ErrorCode != 0:\r
646 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
647 ExtraData=ErrorInfo)\r
648 # Check duplication\r
649 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
650 if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
651 DuplicatedFile = True\r
652\r
653 Module = ModuleBuildClassObject()\r
654 Module.MetaFile = ModuleFile\r
655\r
656 # get module private library instance\r
657 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
658 for Record in RecordList:\r
659 LibraryClass = Record[0]\r
660 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
661 LineNo = Record[-1]\r
662\r
663 # check the file validation\r
664 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
665 if ErrorCode != 0:\r
666 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
667 ExtraData=ErrorInfo)\r
668\r
669 if LibraryClass == '' or LibraryClass == 'NULL':\r
670 self._NullLibraryNumber += 1\r
671 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
672 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
673 Module.LibraryClasses[LibraryClass] = LibraryPath\r
674 if LibraryPath not in self.LibraryInstances:\r
675 self.LibraryInstances.append(LibraryPath)\r
676\r
677 # get module private PCD setting\r
678 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
679 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
680 RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
8518bf0b 681 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
682 TokenList = GetSplitValueList(Setting)\r
683 DefaultValue = TokenList[0]\r
684 if len(TokenList) > 1:\r
685 MaxDatumSize = TokenList[1]\r
686 else:\r
687 MaxDatumSize = ''\r
688 TypeString = self._PCD_TYPE_STRING_[Type]\r
689 Pcd = PcdClassObject(\r
690 PcdCName,\r
691 TokenSpaceGuid,\r
692 TypeString,\r
693 '',\r
694 DefaultValue,\r
695 '',\r
696 MaxDatumSize,\r
697 {},\r
698 False,\r
699 None\r
700 )\r
701 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
702\r
703 # get module private build options\r
704 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
8518bf0b 705 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
ae7b6df8
LG
706 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
707 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
708 else:\r
709 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
710 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
711\r
712 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
713 if DuplicatedFile and not RecordList:\r
714 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
715 if RecordList:\r
716 if len(RecordList) != 1:\r
717 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
718 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
719 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
720 ModuleFile.Arch = self._Arch\r
721\r
722 self._Modules[ModuleFile] = Module\r
723 return self._Modules\r
724\r
725 ## Retrieve all possible library instances used in this platform\r
726 def _GetLibraryInstances(self):\r
727 if self._LibraryInstances == None:\r
728 self._GetLibraryClasses()\r
729 return self._LibraryInstances\r
730\r
731 ## Retrieve [LibraryClasses] information\r
732 def _GetLibraryClasses(self):\r
733 if self._LibraryClasses == None:\r
734 self._LibraryInstances = []\r
735 #\r
736 # tdict is a special dict kind of type, used for selecting correct\r
737 # library instance for given library class and module type\r
738 #\r
739 LibraryClassDict = tdict(True, 3)\r
740 # track all library class names\r
741 LibraryClassSet = set()\r
742 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r
743 Macros = self._Macros\r
744 for Record in RecordList:\r
8518bf0b 745 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record\r
ae7b6df8
LG
746 if LibraryClass == '' or LibraryClass == 'NULL':\r
747 self._NullLibraryNumber += 1\r
748 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
749 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
750 LibraryClassSet.add(LibraryClass)\r
751 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
752 # check the file validation\r
753 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
754 if ErrorCode != 0:\r
755 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
756 ExtraData=ErrorInfo)\r
757\r
758 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
759 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
760 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r
761 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
762 if LibraryInstance not in self._LibraryInstances:\r
763 self._LibraryInstances.append(LibraryInstance)\r
764\r
765 # resolve the specific library instance for each class and each module type\r
766 self._LibraryClasses = tdict(True)\r
767 for LibraryClass in LibraryClassSet:\r
768 # try all possible module types\r
769 for ModuleType in SUP_MODULE_LIST:\r
770 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
771 if LibraryInstance == None:\r
772 continue\r
773 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
774\r
775 # for Edk style library instances, which are listed in different section\r
776 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
777 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
778 for Record in RecordList:\r
779 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
780 LineNo = Record[-1]\r
781 # check the file validation\r
782 ErrorCode, ErrorInfo = File.Validate('.inf')\r
783 if ErrorCode != 0:\r
784 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
785 ExtraData=ErrorInfo)\r
786 if File not in self._LibraryInstances:\r
787 self._LibraryInstances.append(File)\r
788 #\r
789 # we need the module name as the library class name, so we have\r
790 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
791 # hasn't been parsed)\r
792 #\r
793 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
794 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
795 return self._LibraryClasses\r
796\r
797 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
798 if self._DecPcds == None:\r
2b8a6c44 799\r
ae7b6df8
LG
800 FdfInfList = []\r
801 if GlobalData.gFdfParser:\r
802 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
803\r
804 PkgSet = set()\r
805 for Inf in FdfInfList:\r
806 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
807 if ModuleFile in self._Modules:\r
808 continue\r
809 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
810 PkgSet.update(ModuleData.Packages)\r
ae7b6df8 811\r
726c501c 812 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
2b8a6c44
LG
813\r
814\r
815 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
ae7b6df8
LG
816 EdkLogger.error('build', PARSER_ERROR,\r
817 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
818 File=self.MetaFile, Line=LineNo)\r
819 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
520365de
B
820 if not IsValid:\r
821 if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
822 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
823 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
824 else:\r
825 if ValueList[2] == '-1':\r
826 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
827 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
ae7b6df8
LG
828 if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
829 try:\r
830 ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
831 except WrnExpression, Value:\r
832 ValueList[Index] = Value.result\r
726c501c
YZ
833 except BadExpression, Value:\r
834 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=self._LineIndex + 1)\r
ae7b6df8
LG
835 except EvaluationException, Excpt:\r
836 if hasattr(Excpt, 'Pcd'):\r
837 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
838 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
839 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
840 " of the DSC file" % Excpt.Pcd,\r
841 File=self.MetaFile, Line=LineNo)\r
842 else:\r
843 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
844 File=self.MetaFile, Line=LineNo)\r
845 else:\r
846 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
847 File=self.MetaFile, Line=LineNo)\r
ae7b6df8 848 if ValueList[Index]:\r
726c501c
YZ
849 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType\r
850 try:\r
851 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)\r
852 except BadExpression, Value:\r
853 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,\r
854 ExtraData="PCD [%s.%s] Value \"%s\" " % (TokenSpaceGuid, PcdCName, ValueList[Index]))\r
ae7b6df8
LG
855 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
856 if not Valid:\r
857 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
858 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
520365de
B
859 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
860 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():\r
861 EdkLogger.error('build', FORMAT_INVALID, ErrStr , File=self.MetaFile, Line=LineNo,\r
862 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
ae7b6df8
LG
863 return ValueList\r
864\r
8518bf0b
LG
865 def _FilterPcdBySkuUsage(self,Pcds):\r
866 available_sku = self.SkuIdMgr.AvailableSkuIdSet\r
867 sku_usage = self.SkuIdMgr.SkuUsageType\r
868 if sku_usage == SkuClass.SINGLE:\r
869 for pcdname in Pcds:\r
870 pcd = Pcds[pcdname]\r
871 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
872 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
873 Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b
LG
874 else:\r
875 for pcdname in Pcds:\r
876 pcd = Pcds[pcdname]\r
877 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
878 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
879 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b 880 return Pcds\r
2b8a6c44
LG
881 def CompleteHiiPcdsDefaultStores(self,Pcds):\r
882 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
883 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
884 for pcd in HiiPcd:\r
885 for skuid in pcd.SkuInfoList:\r
886 skuobj = pcd.SkuInfoList.get(skuid)\r
887 if "STANDARD" not in skuobj.DefaultStoreDict:\r
888 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])\r
889 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
890 skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
891 return Pcds\r
892\r
ae7b6df8
LG
893 ## Retrieve all PCD settings in platform\r
894 def _GetPcds(self):\r
895 if self._Pcds == None:\r
896 self._Pcds = sdict()\r
897 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
898 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
899 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
900 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
901 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
902 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
903 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
904 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
905 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
906\r
8518bf0b 907 self._Pcds = self.CompletePcdValues(self._Pcds)\r
ae7b6df8 908 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
2b8a6c44 909 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
8518bf0b 910 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
ae7b6df8
LG
911 return self._Pcds\r
912\r
8518bf0b
LG
913 def _dumpPcdInfo(self,Pcds):\r
914 for pcd in Pcds:\r
915 pcdobj = Pcds[pcd]\r
916 if not pcdobj.TokenCName.startswith("Test"):\r
917 continue\r
918 for skuid in pcdobj.SkuInfoList:\r
919 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r
920 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r
921 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r
922 else:\r
923 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r
ae7b6df8
LG
924 ## Retrieve [BuildOptions]\r
925 def _GetBuildOptions(self):\r
926 if self._BuildOptions == None:\r
927 self._BuildOptions = sdict()\r
928 #\r
929 # Retrieve build option for EDKII and EDK style module\r
930 #\r
931 for CodeBase in (EDKII_NAME, EDK_NAME):\r
932 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
8518bf0b 933 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
c05c2c05
LG
934 if Dummy3.upper() != 'COMMON':\r
935 continue\r
ae7b6df8
LG
936 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
937 #\r
938 # Only flags can be appended\r
939 #\r
940 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
941 self._BuildOptions[CurKey] = Option\r
942 else:\r
c05c2c05
LG
943 if ' ' + Option not in self._BuildOptions[CurKey]:\r
944 self._BuildOptions[CurKey] += ' ' + Option\r
ae7b6df8
LG
945 return self._BuildOptions\r
946\r
947 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
948 if self._ModuleTypeOptions == None:\r
949 self._ModuleTypeOptions = sdict()\r
950 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
951 options = sdict()\r
952 self._ModuleTypeOptions[Edk, ModuleType] = options\r
953 DriverType = '%s.%s' % (Edk, ModuleType)\r
954 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
c05c2c05
LG
955 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]\r
956 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
957 Type = Dummy2 + '.' + Dummy3\r
958 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():\r
ae7b6df8
LG
959 Key = (ToolChainFamily, ToolChain, Edk)\r
960 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
961 options[Key] = Option\r
962 else:\r
c05c2c05
LG
963 if ' ' + Option not in options[Key]:\r
964 options[Key] += ' ' + Option\r
ae7b6df8
LG
965 return self._ModuleTypeOptions[Edk, ModuleType]\r
966\r
967 def GetStructurePcdInfo(self, PcdSet):\r
968 structure_pcd_data = {}\r
969 for item in PcdSet:\r
8518bf0b
LG
970 if (item[0],item[1]) not in structure_pcd_data:\r
971 structure_pcd_data[(item[0],item[1])] = []\r
972 structure_pcd_data[(item[0],item[1])].append(item)\r
ae7b6df8
LG
973\r
974 return structure_pcd_data\r
975\r
976 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
65eff519
LG
977\r
978 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
979 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
980 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
981 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
982 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
983 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]\r
984\r
ae7b6df8 985 Pcds = AllPcds\r
8518bf0b 986 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
65eff519
LG
987 SkuIds = self.SkuIdMgr.AvailableSkuIdSet\r
988 SkuIds.update({'DEFAULT':0})\r
8518bf0b 989 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
ae7b6df8
LG
990\r
991 S_PcdSet = []\r
992 # Find out all possible PCD candidates for self._Arch\r
993 RecordList = []\r
2b8a6c44 994\r
ae7b6df8
LG
995 for Type in TypeList:\r
996 RecordList.extend(self._RawData[Type, self._Arch])\r
997\r
8518bf0b 998 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
999 SkuName = SkuName.upper()\r
1000 default_store = default_store.upper()\r
1001 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
8518bf0b
LG
1002 if SkuName not in SkuIds:\r
1003 continue\r
2b8a6c44 1004\r
8518bf0b
LG
1005 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
1006 S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]))\r
ae7b6df8
LG
1007\r
1008 # handle pcd value override\r
1009 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
1010 S_pcd_set = {}\r
1011 for str_pcd in StrPcdSet:\r
8518bf0b
LG
1012 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
1013 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
ae7b6df8
LG
1014 if str_pcd_dec:\r
1015 str_pcd_obj_str = StructurePcd()\r
1016 str_pcd_obj_str.copy(str_pcd_dec)\r
1017 if str_pcd_obj:\r
1018 str_pcd_obj_str.copy(str_pcd_obj)\r
1019 if str_pcd_obj.DefaultValue:\r
1020 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1021 for str_pcd_data in StrPcdSet[str_pcd]:\r
8518bf0b
LG
1022 if str_pcd_data[3] in SkuIds:\r
1023 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,LineNo=str_pcd_data[5])\r
1024 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
2b8a6c44
LG
1025 else:\r
1026 EdkLogger.error('build', PARSER_ERROR,\r
1027 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
1028 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8 1029 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
5644e5ce 1030 for Pcd in self.DecPcds:\r
ae7b6df8
LG
1031 if type (self._DecPcds[Pcd]) is StructurePcd:\r
1032 if Pcd not in S_pcd_set:\r
1033 str_pcd_obj_str = StructurePcd()\r
1034 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1035 str_pcd_obj = Pcds.get(Pcd, None)\r
1036 if str_pcd_obj:\r
1037 str_pcd_obj_str.copy(str_pcd_obj)\r
1038 if str_pcd_obj.DefaultValue:\r
1039 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1040 S_pcd_set[Pcd] = str_pcd_obj_str\r
1041 if S_pcd_set:\r
1042 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
8518bf0b 1043 for stru_pcd in S_pcd_set.values():\r
67e63e9a
LG
1044 for skuid in SkuIds:\r
1045 if skuid in stru_pcd.SkuOverrideValues:\r
1046 continue\r
1047 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1048 NoDefault = False\r
1049 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1050 if nextskuid == "DEFAULT":\r
1051 NoDefault = True\r
1052 break\r
1053 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1054 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
8518bf0b
LG
1055 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1056 for skuid in SkuIds:\r
1057 nextskuid = skuid\r
2b8a6c44 1058 NoDefault = False\r
8518bf0b
LG
1059 if skuid not in stru_pcd.SkuOverrideValues:\r
1060 while nextskuid not in stru_pcd.SkuOverrideValues:\r
2b8a6c44
LG
1061 if nextskuid == "DEFAULT":\r
1062 NoDefault = True\r
1063 break\r
8518bf0b 1064 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1065 if NoDefault:\r
1066 continue\r
1067 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])\r
8518bf0b 1068 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
2b8a6c44 1069\r
8518bf0b
LG
1070 for defaultstoreid in DefaultStores:\r
1071 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
2b8a6c44 1072 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
65eff519 1073\r
ae7b6df8
LG
1074 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1075 if Str_Pcd_Values:\r
8518bf0b
LG
1076 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r
1077 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
ae7b6df8 1078 if str_pcd_obj is None:\r
67e63e9a 1079 print PcdName, PcdGuid\r
ae7b6df8
LG
1080 raise\r
1081 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1082 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
8518bf0b
LG
1083 if skuname not in str_pcd_obj.SkuInfoList:\r
1084 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
ae7b6df8 1085 else:\r
8518bf0b
LG
1086 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1087 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
ae7b6df8
LG
1088 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1089 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
8518bf0b
LG
1090 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1091 str_pcd_obj.DefaultValue = PcdValue\r
ae7b6df8 1092 else:\r
8518bf0b 1093 if skuname not in str_pcd_obj.SkuInfoList:\r
65eff519
LG
1094 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
1095 NoDefault = False\r
1096 while nextskuid not in str_pcd_obj.SkuInfoList:\r
1097 if nextskuid == "DEFAULT":\r
1098 NoDefault = True\r
1099 break\r
1100 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1101 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
1102 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]\r
1103 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname\r
ae7b6df8 1104 else:\r
8518bf0b
LG
1105 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1106 for str_pcd_obj in S_pcd_set.values():\r
1107 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1108 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1109 continue\r
1110 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r
1111 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1112 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1113 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
ae7b6df8
LG
1114\r
1115 for str_pcd_obj in S_pcd_set.values():\r
2b8a6c44 1116\r
ae7b6df8
LG
1117 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1118 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
1119\r
65eff519
LG
1120 for pcdkey in Pcds:\r
1121 pcd = Pcds[pcdkey]\r
1122 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1123 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1124 del(pcd.SkuInfoList['COMMON'])\r
1125 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1126 del(pcd.SkuInfoList['COMMON'])\r
1127\r
1128 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])\r
ae7b6df8
LG
1129 return Pcds\r
1130\r
1131 ## Retrieve non-dynamic PCD settings\r
1132 #\r
1133 # @param Type PCD type\r
1134 #\r
1135 # @retval a dict object contains settings of given PCD type\r
1136 #\r
1137 def _GetPcd(self, Type):\r
1138 Pcds = sdict()\r
1139 #\r
1140 # tdict is a special dict kind of type, used for selecting correct\r
1141 # PCD settings for certain ARCH\r
1142 #\r
2b8a6c44 1143 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8
LG
1144\r
1145 PcdDict = tdict(True, 3)\r
1146 PcdSet = set()\r
1147 # Find out all possible PCD candidates for self._Arch\r
1148 RecordList = self._RawData[Type, self._Arch]\r
ae7b6df8 1149 PcdValueDict = sdict()\r
8518bf0b 1150 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1151 SkuName = SkuName.upper()\r
1152 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1153 if SkuName not in AvailableSkuIdSet:\r
1154 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1155 File=self.MetaFile, Line=Dummy5)\r
8518bf0b
LG
1156 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1157 if "." not in TokenSpaceGuid:\r
1158 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
ae7b6df8 1159 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
ae7b6df8
LG
1160\r
1161 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1162 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
1163 if Setting == None:\r
1164 continue\r
1165 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1166 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1167 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1168 else:\r
1169 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1170\r
1171 PcdsKeys = PcdValueDict.keys()\r
1172 for PcdCName, TokenSpaceGuid in PcdsKeys:\r
1173\r
1174 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
1175 PcdValue = None\r
1176 DatumType = None\r
1177 MaxDatumSize = None\r
1178 if 'COMMON' in PcdSetting:\r
1179 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
1180 if 'DEFAULT' in PcdSetting:\r
1181 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
8518bf0b
LG
1182 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1183 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
ae7b6df8
LG
1184\r
1185 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1186 PcdCName,\r
1187 TokenSpaceGuid,\r
1188 self._PCD_TYPE_STRING_[Type],\r
1189 DatumType,\r
1190 PcdValue,\r
1191 '',\r
1192 MaxDatumSize,\r
1193 {},\r
1194 False,\r
1195 None,\r
1196 IsDsc=True)\r
1197\r
1198\r
1199 return Pcds\r
1200\r
8518bf0b
LG
1201 def __UNICODE2OCTList(self,Value):\r
1202 Value = Value.strip()\r
1203 Value = Value[2:-1]\r
1204 List = []\r
1205 for Item in Value:\r
1206 Temp = '%04X' % ord(Item)\r
1207 List.append('0x' + Temp[2:4])\r
1208 List.append('0x' + Temp[0:2])\r
1209 List.append('0x00')\r
1210 List.append('0x00')\r
1211 return List\r
1212 def __STRING2OCTList(self,Value):\r
1213 OCTList = []\r
1214 Value = Value.strip('"')\r
1215 for char in Value:\r
1216 Temp = '%02X' % ord(char)\r
1217 OCTList.append('0x' + Temp)\r
1218 OCTList.append('0x00')\r
1219 return OCTList\r
1220\r
ae7b6df8
LG
1221 def GetStructurePcdMaxSize(self, str_pcd):\r
1222 pcd_default_value = str_pcd.DefaultValue\r
1223 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
1224 sku_values.append(pcd_default_value)\r
1225\r
1226 def get_length(value):\r
1227 Value = value.strip()\r
a0939593
LG
1228 if len(value) > 1:\r
1229 if Value.startswith('GUID') and Value.endswith(')'):\r
1230 return 16\r
1231 if Value.startswith('L"') and Value.endswith('"'):\r
1232 return len(Value[2:-1])\r
1233 if Value[0] == '"' and Value[-1] == '"':\r
1234 return len(Value) - 2\r
1235 if Value[0] == '{' and Value[-1] == '}':\r
1236 return len(Value.split(","))\r
1237 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1238 return len(list(Value[2:-1]))\r
1239 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1240 return len(Value) - 2\r
ae7b6df8
LG
1241 return len(Value)\r
1242\r
1243 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
1244\r
1245 def IsFieldValueAnArray (self, Value):\r
1246 Value = Value.strip()\r
1247 if Value.startswith('GUID') and Value.endswith(')'):\r
1248 return True\r
1249 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:\r
1250 return True\r
1251 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
1252 return True\r
1253 if Value[0] == '{' and Value[-1] == '}':\r
1254 return True\r
1255 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1256 print 'foo = ', list(Value[2:-1])\r
1257 return True\r
1258 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1259 print 'bar = ', list(Value[1:-1])\r
1260 return True\r
1261 return False\r
1262\r
1263 def ExecuteCommand (self, Command):\r
1264 try:\r
1265 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1266 except:\r
1267 print 'ERROR: Can not execute command:', Command\r
1268 sys.exit(1)\r
1269 Result = Process.communicate()\r
1270 if Process.returncode <> 0:\r
1271 print 'ERROR: Can not collect output from command:', Command\r
1272 return Result[0], Result[1]\r
1273\r
1274 def IntToCString(self, Value, ValueSize):\r
1275 Result = '"'\r
1276 if not isinstance (Value, str):\r
1277 for Index in range(0, ValueSize):\r
1278 Result = Result + '\\x%02x' % (Value & 0xff)\r
1279 Value = Value >> 8\r
1280 Result = Result + '"'\r
1281 return Result\r
1282\r
1283 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
8518bf0b 1284 OverrideValues = {DefaultStoreName:""}\r
ae7b6df8
LG
1285 if Pcd.SkuOverrideValues:\r
1286 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
8518bf0b
LG
1287 for DefaultStoreName in OverrideValues.keys():\r
1288 CApp = CApp + 'void\n'\r
1289 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1290 CApp = CApp + ' void\n'\r
1291 CApp = CApp + ' )\n'\r
1292 CApp = CApp + '{\n'\r
1293 CApp = CApp + ' UINT32 Size;\n'\r
1294 CApp = CApp + ' UINT32 FieldSize;\n'\r
b2395724 1295 CApp = CApp + ' CHAR8 *Value;\n'\r
8518bf0b
LG
1296 CApp = CApp + ' UINT32 OriginalSize;\n'\r
1297 CApp = CApp + ' VOID *OriginalPcd;\n'\r
6a103440 1298 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)\r
8518bf0b 1299 CApp = CApp + '\n'\r
47854fd5 1300\r
8e011d83
FB
1301 if SkuName in Pcd.SkuInfoList:\r
1302 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue\r
1303 else:\r
1304 DefaultValue = Pcd.DefaultValue\r
1305 PcdDefaultValue = StringToArray(DefaultValue.strip())\r
47854fd5 1306\r
8518bf0b 1307 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
ae7b6df8 1308\r
8518bf0b
LG
1309 #\r
1310 # Get current PCD value and size\r
1311 #\r
1312 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1313\r
8518bf0b
LG
1314 #\r
1315 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
1316 # the correct value. For structures with a flexible array member, the flexible\r
1317 # array member is detected, and the size is based on the highest index used with\r
1318 # the flexible array member. The flexible array member must be the last field\r
1319 # in a structure. The size formula for this case is:\r
1320 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
1321 #\r
1322 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
4cc82428
FB
1323 for FieldList in [Pcd.DefaultValues]:\r
1324 if not FieldList:\r
1325 continue\r
1326 for FieldName in FieldList:\r
1327 FieldName = "." + FieldName\r
1328 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1329 if IsArray:\r
1330 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1331 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."));\r
1332 else:\r
1333 NewFieldName = ''\r
1334 while '[' in FieldName:\r
1335 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1336 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1337 FieldName = FieldName.split(']', 1)[1]\r
1338 FieldName = NewFieldName + FieldName\r
1339 while '[' in FieldName:\r
1340 FieldName = FieldName.rsplit('[', 1)[0]\r
1341 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
09c80b07 1342 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1343 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
4cc82428 1344 for FieldList in [inherit_OverrideValues.get(DefaultStoreName)]:\r
c05c2c05
LG
1345 if not FieldList:\r
1346 continue\r
1347 for FieldName in FieldList:\r
1348 FieldName = "." + FieldName\r
1349 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1350 if IsArray:\r
1351 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1352 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."));\r
1353 else:\r
1354 NewFieldName = ''\r
1355 while '[' in FieldName:\r
1356 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1357 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1358 FieldName = FieldName.split(']', 1)[1]\r
1359 FieldName = NewFieldName + FieldName\r
1360 while '[' in FieldName:\r
1361 FieldName = FieldName.rsplit('[', 1)[0]\r
1362 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
1363 if skuname == SkuName:\r
1364 break\r
ae7b6df8 1365\r
8518bf0b
LG
1366 #\r
1367 # Allocate and zero buffer for the PCD\r
1368 # Must handle cases where current value is smaller, larger, or same size\r
1369 # Always keep that larger one as the current size\r
1370 #\r
1371 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
1372 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
1373 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
ae7b6df8 1374\r
8518bf0b
LG
1375 #\r
1376 # Copy current PCD value into allocated buffer.\r
1377 #\r
1378 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
ae7b6df8 1379\r
8518bf0b
LG
1380 #\r
1381 # Assign field values in PCD\r
1382 #\r
4cc82428
FB
1383 for FieldList in [Pcd.DefaultValues]:\r
1384 if not FieldList:\r
1385 continue\r
1386 for FieldName in FieldList:\r
1387 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1388 try:\r
1389 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1390 except Exception:\r
1391 print FieldList[FieldName][0]\r
1392 if isinstance(Value, str):\r
1393 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1394 elif IsArray:\r
1395 #\r
1396 # Use memcpy() to copy value into field\r
1397 #\r
1398 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1399 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
1400 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
1401 else:\r
1402 if ValueSize > 4:\r
1403 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1404 else:\r
1405 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
09c80b07 1406 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1407 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
4cc82428 1408 for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(DefaultStoreName)]:\r
c05c2c05
LG
1409 if not FieldList:\r
1410 continue\r
1411 if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:\r
1412 IsArray = self.IsFieldValueAnArray(FieldList)\r
1413 Value, ValueSize = ParseFieldValue (FieldList)\r
1414 if isinstance(Value, str):\r
1415 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)\r
1416 elif IsArray:\r
8518bf0b
LG
1417 #\r
1418 # Use memcpy() to copy value into field\r
1419 #\r
c05c2c05
LG
1420 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)\r
1421 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1422 continue\r
ae7b6df8 1423\r
c05c2c05
LG
1424 for FieldName in FieldList:\r
1425 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1426 try:\r
1427 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1428 except Exception:\r
1429 print FieldList[FieldName][0]\r
1430 if isinstance(Value, str):\r
1431 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1432 elif IsArray:\r
8518bf0b
LG
1433 #\r
1434 # Use memcpy() to copy value into field\r
1435 #\r
c05c2c05
LG
1436 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1437 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
1438 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
8518bf0b 1439 else:\r
c05c2c05
LG
1440 if ValueSize > 4:\r
1441 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1442 else:\r
1443 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1444 if skuname == SkuName:\r
1445 break\r
8518bf0b
LG
1446 #\r
1447 # Set new PCD value and size\r
1448 #\r
1449 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1450\r
8518bf0b
LG
1451 #\r
1452 # Free PCD\r
1453 #\r
1454 CApp = CApp + ' free (Pcd);\n'\r
1455 CApp = CApp + '}\n'\r
1456 CApp = CApp + '\n'\r
ae7b6df8
LG
1457 return InitByteValue, CApp\r
1458\r
1459 def GenerateByteArrayValue (self, StructuredPcds):\r
1460 #\r
1461 # Generate/Compile/Run C application to determine if there are any flexible array members\r
1462 #\r
1463 if not StructuredPcds:\r
1464 return\r
1465\r
1466 InitByteValue = ""\r
1467 CApp = PcdMainCHeader\r
1468\r
1469 Includes = {}\r
1470 for PcdName in StructuredPcds:\r
1471 Pcd = StructuredPcds[PcdName]\r
1472 IncludeFile = Pcd.StructuredPcdIncludeFile\r
1473 if IncludeFile not in Includes:\r
1474 Includes[IncludeFile] = True\r
1475 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
1476 CApp = CApp + '\n'\r
1477\r
1478 for PcdName in StructuredPcds:\r
1479 Pcd = StructuredPcds[PcdName]\r
1480 if not Pcd.SkuOverrideValues:\r
8518bf0b 1481 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
ae7b6df8 1482 else:\r
c05c2c05
LG
1483 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1484 if SkuName not in Pcd.SkuOverrideValues:\r
1485 continue\r
ae7b6df8
LG
1486 for DefaultStoreName in Pcd.DefaultStoreName:\r
1487 Pcd = StructuredPcds[PcdName]\r
1488 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
1489\r
1490 CApp = CApp + 'VOID\n'\r
1491 CApp = CApp + 'PcdEntryPoint(\n'\r
1492 CApp = CApp + ' VOID\n'\r
1493 CApp = CApp + ' )\n'\r
1494 CApp = CApp + '{\n'\r
1495 for Pcd in StructuredPcds.values():\r
1496 if not Pcd.SkuOverrideValues:\r
8518bf0b 1497 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1498 else:\r
c05c2c05
LG
1499 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1500 if SkuName not in Pcd.SkuOverrideValues:\r
1501 continue\r
8518bf0b 1502 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ae7b6df8
LG
1503 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1504 CApp = CApp + '}\n'\r
1505\r
1506 CApp = CApp + PcdMainCEntry + '\n'\r
1507\r
1508 if not os.path.exists(self.OutputPath):\r
1509 os.makedirs(self.OutputPath)\r
1510 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1511 File = open (CAppBaseFileName + '.c', 'w')\r
1512 File.write(CApp)\r
1513 File.close()\r
1514\r
1515 MakeApp = PcdMakefileHeader\r
1516 if sys.platform == "win32":\r
1517 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
1518 else:\r
1519 MakeApp = MakeApp + PcdGccMakefile\r
1520 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
68ba919f 1521 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='\r
ae7b6df8
LG
1522\r
1523 PlatformInc = {}\r
1524 for Cache in self._Bdb._CACHE_.values():\r
1525 if Cache.MetaFile.Ext.lower() != '.dec':\r
1526 continue\r
1527 if Cache.Includes:\r
1528 if str(Cache.MetaFile.Path) not in PlatformInc:\r
1529 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
1530\r
1531 PcdDependDEC = []\r
1532 for Pcd in StructuredPcds.values():\r
1533 for PackageDec in Pcd.PackageDecs:\r
1534 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
1535 if not os.path.exists(Package):\r
1536 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1537 if Package not in PcdDependDEC:\r
1538 PcdDependDEC.append(Package)\r
1539\r
1540 if PlatformInc and PcdDependDEC:\r
1541 for pkg in PcdDependDEC:\r
1542 if pkg in PlatformInc:\r
1543 for inc in PlatformInc[pkg]:\r
1544 MakeApp += '-I' + str(inc) + ' '\r
1545 MakeApp = MakeApp + '\n'\r
68ba919f
YZ
1546\r
1547 CC_FLAGS = LinuxCFLAGS\r
1548 if sys.platform == "win32":\r
1549 CC_FLAGS = WindowsCFLAGS\r
1550 BuildOptions = {}\r
1551 for Options in self.BuildOptions:\r
1552 if Options[2] != EDKII_NAME:\r
1553 continue\r
1554 Family = Options[0]\r
1555 if Family and Family != self.ToolChainFamily:\r
1556 continue\r
1557 Target, Tag, Arch, Tool, Attr = Options[1].split("_")\r
1558 if Tool != 'CC':\r
1559 continue\r
1560\r
1561 if Target == "*" or Target == self._Target:\r
1562 if Tag == "*" or Tag == self._Toolchain:\r
1563 if Arch == "*" or Arch == self.Arch:\r
1564 if Tool not in BuildOptions:\r
1565 BuildOptions[Tool] = {}\r
1566 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):\r
1567 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1568 else:\r
1569 # append options for the same tool except PATH\r
1570 if Attr != 'PATH':\r
1571 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]\r
1572 else:\r
1573 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1574 if BuildOptions:\r
1575 for Tool in BuildOptions:\r
1576 for Attr in BuildOptions[Tool]:\r
1577 if Attr == "FLAGS":\r
1578 Value = BuildOptions[Tool][Attr]\r
1579 ValueList = Value.split()\r
1580 if ValueList:\r
1581 for Id, Item in enumerate(ValueList):\r
1582 if Item == '-D' or Item == '/D':\r
1583 CC_FLAGS += ' ' + Item\r
1584 if Id + 1 < len(ValueList):\r
1585 CC_FLAGS += ' ' + ValueList[Id + 1]\r
1586 elif Item.startswith('/D') or Item.startswith('-D'):\r
1587 CC_FLAGS += ' ' + Item\r
1588 MakeApp += CC_FLAGS\r
1589\r
ae7b6df8
LG
1590 if sys.platform == "win32":\r
1591 MakeApp = MakeApp + PcdMakefileEnd\r
1592 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
1593 File = open (MakeFileName, 'w')\r
1594 File.write(MakeApp)\r
1595 File.close()\r
1596\r
1597 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
1598 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
1599 File = open (InputValueFile, 'w')\r
1600 File.write(InitByteValue)\r
1601 File.close()\r
1602\r
b2395724 1603 Messages = ''\r
ae7b6df8
LG
1604 if sys.platform == "win32":\r
1605 StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))\r
b2395724 1606 Messages = StdOut\r
ae7b6df8
LG
1607 else:\r
1608 StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
b2395724
LG
1609 Messages = StdErr\r
1610 Messages = Messages.split('\n')\r
1611 for Message in Messages:\r
1612 if " error" in Message:\r
1613 FileInfo = Message.strip().split('(')\r
1614 if len (FileInfo) > 1:\r
1615 FileName = FileInfo [0]\r
1616 FileLine = FileInfo [1].split (')')[0]\r
1617 else:\r
1618 FileInfo = Message.strip().split(':')\r
1619 FileName = FileInfo [0]\r
1620 FileLine = FileInfo [1]\r
1621\r
1622 File = open (FileName, 'r')\r
1623 FileData = File.readlines()\r
1624 File.close()\r
1625 error_line = FileData[int (FileLine) - 1]\r
1626 if r"//" in error_line:\r
1627 c_line,dsc_line = error_line.split(r"//")\r
1628 else:\r
1629 dsc_line = error_line\r
1630\r
1631 message_itmes = Message.split(":")\r
1632 Index = 0\r
1633 for item in message_itmes:\r
1634 if "PcdValueInit.c" in item:\r
1635 Index = message_itmes.index(item)\r
1636 message_itmes[Index] = dsc_line.strip()\r
1637 break\r
1638\r
1639 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[Index:]))\r
ae7b6df8
LG
1640\r
1641 PcdValueInitExe = PcdValueInitName\r
1642 if not sys.platform == "win32":\r
1643 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
1644\r
1645 StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))\r
1646 File = open (OutputValueFile, 'r')\r
1647 FileBuffer = File.readlines()\r
1648 File.close()\r
1649\r
1650 StructurePcdSet = []\r
1651 for Pcd in FileBuffer:\r
1652 PcdValue = Pcd.split ('|')\r
1653 PcdInfo = PcdValue[0].split ('.')\r
8518bf0b 1654 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
ae7b6df8
LG
1655 return StructurePcdSet\r
1656\r
1657 ## Retrieve dynamic PCD settings\r
1658 #\r
1659 # @param Type PCD type\r
1660 #\r
1661 # @retval a dict object contains settings of given PCD type\r
1662 #\r
1663 def _GetDynamicPcd(self, Type):\r
1664\r
ae7b6df8
LG
1665\r
1666 Pcds = sdict()\r
1667 #\r
1668 # tdict is a special dict kind of type, used for selecting correct\r
1669 # PCD settings for certain ARCH and SKU\r
1670 #\r
1671 PcdDict = tdict(True, 4)\r
1672 PcdList = []\r
1673 # Find out all possible PCD candidates for self._Arch\r
1674 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1675 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1676\r
ae7b6df8 1677\r
8518bf0b 1678 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1679 SkuName = SkuName.upper()\r
1680 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 1681 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1682 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1683 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8
LG
1684 if "." not in TokenSpaceGuid:\r
1685 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1686 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1687\r
1688 # Remove redundant PCD candidates, per the ARCH and SKU\r
1689 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1690\r
1691 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1692 if Setting == None:\r
1693 continue\r
1694\r
1695 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 1696 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
ae7b6df8
LG
1697 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1698 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1699 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1700 if MaxDatumSize.strip():\r
1701 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1702 else:\r
1703 CurrentMaxSize = 0\r
1704 if pcdObject.MaxDatumSize:\r
1705 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1706 else:\r
1707 PcdMaxSize = 0\r
1708 if CurrentMaxSize > PcdMaxSize:\r
1709 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1710 else:\r
1711 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1712 PcdCName,\r
1713 TokenSpaceGuid,\r
1714 self._PCD_TYPE_STRING_[Type],\r
1715 DatumType,\r
1716 PcdValue,\r
1717 '',\r
1718 MaxDatumSize,\r
1719 {SkuName : SkuInfo},\r
1720 False,\r
1721 None,\r
1722 IsDsc=True)\r
1723\r
1724 for pcd in Pcds.values():\r
1725 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
1726 # Only fix the value while no value provided in DSC file.\r
1727 for sku in pcd.SkuInfoList.values():\r
1728 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
1729 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
1730 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1731 valuefromDec = pcdDecObject.DefaultValue\r
1732 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
1733 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1734 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1735 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1736 del(pcd.SkuInfoList['COMMON'])\r
1737 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1738 del(pcd.SkuInfoList['COMMON'])\r
65eff519
LG
1739\r
1740 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
1741\r
1742 return Pcds\r
1743\r
65eff519
LG
1744 def FilterSkuSettings(self, PcdObj):\r
1745\r
1746 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1747 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():\r
1748 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']\r
1749 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}\r
1750 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'\r
1751 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'\r
1752\r
1753 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:\r
1754 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}\r
1755\r
1756 return PcdObj\r
1757\r
1758\r
ae7b6df8
LG
1759 def CompareVarAttr(self, Attr1, Attr2):\r
1760 if not Attr1 or not Attr2: # for empty string\r
1761 return True\r
1762 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
1763 Attr1Set = set(Attr1s)\r
1764 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
1765 Attr2Set = set(Attr2s)\r
1766 if Attr2Set == Attr1Set:\r
1767 return True\r
1768 else:\r
1769 return False\r
8518bf0b
LG
1770 def CompletePcdValues(self,PcdSet):\r
1771 Pcds = {}\r
1772 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
98eb1364 1773 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}\r
8518bf0b
LG
1774 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
1775 for PcdCName, TokenSpaceGuid in PcdSet:\r
1776 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
1777 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1778 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1779 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1780 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1781 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1782 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1783 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1784 continue\r
1785 PcdType = PcdObj.Type\r
1786 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1787 for skuid in PcdObj.SkuInfoList:\r
1788 skuobj = PcdObj.SkuInfoList[skuid]\r
1789 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r
1790 for defaultstorename in DefaultStores:\r
1791 if defaultstorename not in skuobj.DefaultStoreDict:\r
2b8a6c44 1792 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
8518bf0b 1793 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
8ac16789 1794 for skuname,skuid in SkuIds.items():\r
2b8a6c44
LG
1795 if skuname not in PcdObj.SkuInfoList:\r
1796 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
8518bf0b
LG
1797 while nextskuid not in PcdObj.SkuInfoList:\r
1798 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1799 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r
1800 PcdObj.SkuInfoList[skuname].SkuId = skuid\r
1801 PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r
8518bf0b
LG
1802 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1803 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r
1804 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1805 return Pcds\r
ae7b6df8
LG
1806 ## Retrieve dynamic HII PCD settings\r
1807 #\r
1808 # @param Type PCD type\r
1809 #\r
1810 # @retval a dict object contains settings of given PCD type\r
1811 #\r
1812 def _GetDynamicHiiPcd(self, Type):\r
1813\r
ae7b6df8
LG
1814 VariableAttrs = {}\r
1815\r
1816 Pcds = sdict()\r
1817 #\r
1818 # tdict is a special dict kind of type, used for selecting correct\r
1819 # PCD settings for certain ARCH and SKU\r
1820 #\r
8518bf0b 1821 PcdDict = tdict(True, 5)\r
ae7b6df8
LG
1822 PcdSet = set()\r
1823 RecordList = self._RawData[Type, self._Arch]\r
1824 # Find out all possible PCD candidates for self._Arch\r
8518bf0b 1825 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
2b8a6c44 1826 DefaultStoresDefine = self._GetDefaultStores()\r
ae7b6df8 1827\r
8518bf0b 1828 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1829 SkuName = SkuName.upper()\r
1830 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1831 DefaultStore = DefaultStore.upper()\r
8518bf0b
LG
1832 if DefaultStore == "COMMON":\r
1833 DefaultStore = "STANDARD"\r
ae7b6df8 1834 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1835 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1836 File=self.MetaFile, Line=Dummy5)\r
1837 if DefaultStore not in DefaultStoresDefine:\r
1838 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r
1839 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 1840 if "." not in TokenSpaceGuid:\r
8518bf0b
LG
1841 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4))\r
1842 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r
ae7b6df8
LG
1843\r
1844\r
1845 # Remove redundant PCD candidates, per the ARCH and SKU\r
8518bf0b 1846 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r
ae7b6df8 1847\r
8518bf0b 1848 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r
ae7b6df8
LG
1849 if Setting == None:\r
1850 continue\r
1851 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1852\r
1853 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
1854 if not rt:\r
1855 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
1856 ExtraData="[%s]" % VarAttribute)\r
1857 ExceedMax = False\r
1858 FormatCorrect = True\r
1859 if VariableOffset.isdigit():\r
1860 if int(VariableOffset, 10) > 0xFFFF:\r
1861 ExceedMax = True\r
1862 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
1863 if int(VariableOffset, 16) > 0xFFFF:\r
1864 ExceedMax = True\r
1865 # For Offset written in "A.B"\r
1866 elif VariableOffset.find('.') > -1:\r
1867 VariableOffsetList = VariableOffset.split(".")\r
1868 if not (len(VariableOffsetList) == 2\r
1869 and IsValidWord(VariableOffsetList[0])\r
1870 and IsValidWord(VariableOffsetList[1])):\r
1871 FormatCorrect = False\r
1872 else:\r
1873 FormatCorrect = False\r
1874 if not FormatCorrect:\r
1875 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
1876\r
1877 if ExceedMax:\r
1878 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
1879 if (VariableName, VariableGuid) not in VariableAttrs:\r
1880 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1881 else:\r
1882 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1883 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
1884\r
ae7b6df8
LG
1885 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
1886 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1887 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
8518bf0b
LG
1888 if SkuName in pcdObject.SkuInfoList:\r
1889 Skuitem = pcdObject.SkuInfoList[SkuName]\r
1890 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
1891 else:\r
1892 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
1893 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
ae7b6df8 1894 else:\r
8518bf0b 1895 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
ae7b6df8
LG
1896 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1897 PcdCName,\r
1898 TokenSpaceGuid,\r
1899 self._PCD_TYPE_STRING_[Type],\r
1900 '',\r
1901 DefaultValue,\r
1902 '',\r
1903 '',\r
1904 {SkuName : SkuInfo},\r
1905 False,\r
1906 None,\r
1907 pcdDecObject.validateranges,\r
1908 pcdDecObject.validlists,\r
1909 pcdDecObject.expressions,\r
1910 IsDsc=True)\r
1911\r
1912\r
1913 for pcd in Pcds.values():\r
1914 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1915 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1916 # Only fix the value while no value provided in DSC file.\r
1917 for sku in pcd.SkuInfoList.values():\r
1918 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
1919 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1920 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1921 valuefromDec = pcdDecObject.DefaultValue\r
2b8a6c44 1922 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})\r
ae7b6df8
LG
1923 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1924 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1925 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1926 del(pcd.SkuInfoList['COMMON'])\r
1927 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1928 del(pcd.SkuInfoList['COMMON'])\r
1929\r
ae7b6df8
LG
1930 if pcd.MaxDatumSize.strip():\r
1931 MaxSize = int(pcd.MaxDatumSize, 0)\r
1932 else:\r
1933 MaxSize = 0\r
1934 if pcdDecObject.DatumType == 'VOID*':\r
2b8a6c44 1935 for (_, skuobj) in pcd.SkuInfoList.items():\r
ae7b6df8 1936 datalen = 0\r
47854fd5
LG
1937 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r
1938 datalen = len(skuobj.HiiDefaultValue.split(","))\r
ae7b6df8
LG
1939 if datalen > MaxSize:\r
1940 MaxSize = datalen\r
47854fd5
LG
1941 for defaultst in skuobj.DefaultStoreDict:\r
1942 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r
1943 pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r
ae7b6df8 1944 pcd.MaxDatumSize = str(MaxSize)\r
2b8a6c44
LG
1945 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r
1946 if not rt:\r
1947 invalidpcd = ",".join(invalidhii)\r
1948 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
1949\r
1950 map(self.FilterSkuSettings,Pcds.values())\r
1951\r
ae7b6df8
LG
1952 return Pcds\r
1953\r
2b8a6c44
LG
1954 def CheckVariableNameAssignment(self,Pcds):\r
1955 invalidhii = []\r
1956 for pcdname in Pcds:\r
1957 pcd = Pcds[pcdname]\r
1958 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])\r
1959 if len(varnameset) > 1:\r
1960 invalidhii.append(".".join((pcdname[1],pcdname[0])))\r
1961 if len(invalidhii):\r
1962 return False,invalidhii\r
1963 else:\r
1964 return True, []\r
ae7b6df8
LG
1965 ## Retrieve dynamic VPD PCD settings\r
1966 #\r
1967 # @param Type PCD type\r
1968 #\r
1969 # @retval a dict object contains settings of given PCD type\r
1970 #\r
1971 def _GetDynamicVpdPcd(self, Type):\r
1972\r
ae7b6df8
LG
1973\r
1974 Pcds = sdict()\r
1975 #\r
1976 # tdict is a special dict kind of type, used for selecting correct\r
1977 # PCD settings for certain ARCH and SKU\r
1978 #\r
1979 PcdDict = tdict(True, 4)\r
1980 PcdList = []\r
1981\r
1982 # Find out all possible PCD candidates for self._Arch\r
1983 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1984 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1985\r
8518bf0b 1986 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1987 SkuName = SkuName.upper()\r
1988 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 1989 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1990 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1991 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8
LG
1992 if "." not in TokenSpaceGuid:\r
1993 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1994 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1995\r
1996 # Remove redundant PCD candidates, per the ARCH and SKU\r
1997 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1998 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1999 if Setting == None:\r
2000 continue\r
2001 #\r
2002 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
2003 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
2004 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
2005 # until the DEC parser has been called.\r
2006 #\r
2007 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 2008 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
ae7b6df8
LG
2009 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
2010 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2011 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2012 if MaxDatumSize.strip():\r
2013 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2014 else:\r
2015 CurrentMaxSize = 0\r
2016 if pcdObject.MaxDatumSize:\r
2017 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2018 else:\r
2019 PcdMaxSize = 0\r
2020 if CurrentMaxSize > PcdMaxSize:\r
2021 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2022 else:\r
2023 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2024 PcdCName,\r
2025 TokenSpaceGuid,\r
2026 self._PCD_TYPE_STRING_[Type],\r
2027 '',\r
2028 InitialValue,\r
2029 '',\r
2030 MaxDatumSize,\r
2031 {SkuName : SkuInfo},\r
2032 False,\r
2033 None,\r
2034 IsDsc=True)\r
2035 for pcd in Pcds.values():\r
2036 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2037 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
2038 # Only fix the value while no value provided in DSC file.\r
2039 for sku in pcd.SkuInfoList.values():\r
2040 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
2041 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
2042 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
2043 valuefromDec = pcdDecObject.DefaultValue\r
2044 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
2045 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
2046 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2047 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
2048 del(pcd.SkuInfoList['COMMON'])\r
2049 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2050 del(pcd.SkuInfoList['COMMON'])\r
ae7b6df8 2051\r
65eff519
LG
2052\r
2053 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
2054 return Pcds\r
2055\r
2056 ## Add external modules\r
2057 #\r
2058 # The external modules are mostly those listed in FDF file, which don't\r
2059 # need "build".\r
2060 #\r
2061 # @param FilePath The path of module description file\r
2062 #\r
2063 def AddModule(self, FilePath):\r
2064 FilePath = NormPath(FilePath)\r
2065 if FilePath not in self.Modules:\r
2066 Module = ModuleBuildClassObject()\r
2067 Module.MetaFile = FilePath\r
2068 self.Modules.append(Module)\r
2069\r
68ba919f
YZ
2070 def _GetToolChainFamily(self):\r
2071 self._ToolChainFamily = "MSFT"\r
2072 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))\r
2073 if os.path.isfile(BuildConfigurationFile) == True:\r
2074 TargetTxt = TargetTxtClassObject()\r
2075 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
2076 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
2077 if ToolDefinitionFile == '':\r
2078 ToolDefinitionFile = "tools_def.txt"\r
2079 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))\r
2080 if os.path.isfile(ToolDefinitionFile) == True:\r
2081 ToolDef = ToolDefClassObject()\r
2082 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
2083 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
2084 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
2085 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
2086 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:\r
2087 self._ToolChainFamily = "MSFT"\r
2088 else:\r
2089 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]\r
2090 return self._ToolChainFamily\r
2091\r
ae7b6df8
LG
2092 ## Add external PCDs\r
2093 #\r
2094 # The external PCDs are mostly those listed in FDF file to specify address\r
2095 # or offset information.\r
2096 #\r
2097 # @param Name Name of the PCD\r
2098 # @param Guid Token space guid of the PCD\r
2099 # @param Value Value of the PCD\r
2100 #\r
2101 def AddPcd(self, Name, Guid, Value):\r
2102 if (Name, Guid) not in self.Pcds:\r
2103 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
2104 self.Pcds[Name, Guid].DefaultValue = Value\r
5644e5ce
FB
2105 @property\r
2106 def DecPcds(self):\r
2107 if self._DecPcds == None:\r
2108 FdfInfList = []\r
2109 if GlobalData.gFdfParser:\r
2110 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
2111 PkgSet = set()\r
2112 for Inf in FdfInfList:\r
2113 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
2114 if ModuleFile in self._Modules:\r
2115 continue\r
2116 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
2117 PkgSet.update(ModuleData.Packages)\r
726c501c 2118 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
5644e5ce 2119 return self._DecPcds\r
ae7b6df8
LG
2120 _Macros = property(_GetMacros)\r
2121 Arch = property(_GetArch, _SetArch)\r
2122 Platform = property(_GetPlatformName)\r
2123 PlatformName = property(_GetPlatformName)\r
2124 Guid = property(_GetFileGuid)\r
2125 Version = property(_GetVersion)\r
2126 DscSpecification = property(_GetDscSpec)\r
2127 OutputDirectory = property(_GetOutpuDir)\r
2128 SupArchList = property(_GetSupArch)\r
2129 BuildTargets = property(_GetBuildTarget)\r
2130 SkuName = property(_GetSkuName, _SetSkuName)\r
ae7b6df8
LG
2131 PcdInfoFlag = property(_GetPcdInfoFlag)\r
2132 VarCheckFlag = property(_GetVarCheckFlag)\r
2133 FlashDefinition = property(_GetFdfFile)\r
2134 Prebuild = property(_GetPrebuild)\r
2135 Postbuild = property(_GetPostbuild)\r
2136 BuildNumber = property(_GetBuildNumber)\r
2137 MakefileName = property(_GetMakefileName)\r
2138 BsBaseAddress = property(_GetBsBaseAddress)\r
2139 RtBaseAddress = property(_GetRtBaseAddress)\r
2140 LoadFixAddress = property(_GetLoadFixAddress)\r
2141 RFCLanguages = property(_GetRFCLanguages)\r
2142 ISOLanguages = property(_GetISOLanguages)\r
2143 VpdToolGuid = property(_GetVpdToolGuid)\r
2144 SkuIds = property(_GetSkuIds)\r
2145 Modules = property(_GetModules)\r
2146 LibraryInstances = property(_GetLibraryInstances)\r
2147 LibraryClasses = property(_GetLibraryClasses)\r
2148 Pcds = property(_GetPcds)\r
2149 BuildOptions = property(_GetBuildOptions)\r
68ba919f 2150 ToolChainFamily = property(_GetToolChainFamily)\r