]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/DscBuildData.py
UefiCpuPkg/PiSmmCpuDxeSmm: eliminate conditional jump in IA32 SmmStartup()
[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
35f613d9
YF
828 if ValueList[Index]:\r
829 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType\r
ae7b6df8 830 try:\r
35f613d9 831 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)\r
726c501c 832 except BadExpression, Value:\r
35f613d9
YF
833 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,\r
834 ExtraData="PCD [%s.%s] Value \"%s\" " % (\r
835 TokenSpaceGuid, PcdCName, ValueList[Index]))\r
ae7b6df8
LG
836 except EvaluationException, Excpt:\r
837 if hasattr(Excpt, 'Pcd'):\r
838 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
839 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
840 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
841 " of the DSC file" % Excpt.Pcd,\r
842 File=self.MetaFile, Line=LineNo)\r
843 else:\r
844 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
845 File=self.MetaFile, Line=LineNo)\r
846 else:\r
847 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
848 File=self.MetaFile, Line=LineNo)\r
35f613d9 849\r
ae7b6df8
LG
850 if ValueList[Index]:\r
851 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
852 if not Valid:\r
853 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
854 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
520365de
B
855 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):\r
856 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():\r
857 EdkLogger.error('build', FORMAT_INVALID, ErrStr , File=self.MetaFile, Line=LineNo,\r
858 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
35f613d9
YF
859 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:\r
860 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:\r
861 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]\r
ae7b6df8
LG
862 return ValueList\r
863\r
8518bf0b
LG
864 def _FilterPcdBySkuUsage(self,Pcds):\r
865 available_sku = self.SkuIdMgr.AvailableSkuIdSet\r
866 sku_usage = self.SkuIdMgr.SkuUsageType\r
867 if sku_usage == SkuClass.SINGLE:\r
868 for pcdname in Pcds:\r
869 pcd = Pcds[pcdname]\r
870 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
871 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
872 Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b
LG
873 else:\r
874 for pcdname in Pcds:\r
875 pcd = Pcds[pcdname]\r
876 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}\r
65eff519
LG
877 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:\r
878 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}\r
8518bf0b 879 return Pcds\r
2b8a6c44
LG
880 def CompleteHiiPcdsDefaultStores(self,Pcds):\r
881 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
882 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
883 for pcd in HiiPcd:\r
884 for skuid in pcd.SkuInfoList:\r
885 skuobj = pcd.SkuInfoList.get(skuid)\r
886 if "STANDARD" not in skuobj.DefaultStoreDict:\r
887 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])\r
888 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
889 skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
890 return Pcds\r
891\r
ae7b6df8
LG
892 ## Retrieve all PCD settings in platform\r
893 def _GetPcds(self):\r
894 if self._Pcds == None:\r
895 self._Pcds = sdict()\r
896 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
897 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
898 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
899 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
900 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
901 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
902 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
903 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
904 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
905\r
8518bf0b 906 self._Pcds = self.CompletePcdValues(self._Pcds)\r
ae7b6df8 907 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)\r
2b8a6c44 908 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)\r
8518bf0b 909 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)\r
ae7b6df8
LG
910 return self._Pcds\r
911\r
8518bf0b
LG
912 def _dumpPcdInfo(self,Pcds):\r
913 for pcd in Pcds:\r
914 pcdobj = Pcds[pcd]\r
915 if not pcdobj.TokenCName.startswith("Test"):\r
916 continue\r
917 for skuid in pcdobj.SkuInfoList:\r
918 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):\r
919 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:\r
920 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))\r
921 else:\r
922 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))\r
ae7b6df8
LG
923 ## Retrieve [BuildOptions]\r
924 def _GetBuildOptions(self):\r
925 if self._BuildOptions == None:\r
926 self._BuildOptions = sdict()\r
927 #\r
928 # Retrieve build option for EDKII and EDK style module\r
929 #\r
930 for CodeBase in (EDKII_NAME, EDK_NAME):\r
931 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
8518bf0b 932 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
c05c2c05
LG
933 if Dummy3.upper() != 'COMMON':\r
934 continue\r
ae7b6df8
LG
935 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
936 #\r
937 # Only flags can be appended\r
938 #\r
939 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
940 self._BuildOptions[CurKey] = Option\r
941 else:\r
c05c2c05
LG
942 if ' ' + Option not in self._BuildOptions[CurKey]:\r
943 self._BuildOptions[CurKey] += ' ' + Option\r
ae7b6df8
LG
944 return self._BuildOptions\r
945\r
946 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
947 if self._ModuleTypeOptions == None:\r
948 self._ModuleTypeOptions = sdict()\r
949 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
950 options = sdict()\r
951 self._ModuleTypeOptions[Edk, ModuleType] = options\r
952 DriverType = '%s.%s' % (Edk, ModuleType)\r
953 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)\r
c05c2c05
LG
954 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]\r
955 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:\r
956 Type = Dummy2 + '.' + Dummy3\r
957 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():\r
ae7b6df8
LG
958 Key = (ToolChainFamily, ToolChain, Edk)\r
959 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
960 options[Key] = Option\r
961 else:\r
c05c2c05
LG
962 if ' ' + Option not in options[Key]:\r
963 options[Key] += ' ' + Option\r
ae7b6df8
LG
964 return self._ModuleTypeOptions[Edk, ModuleType]\r
965\r
966 def GetStructurePcdInfo(self, PcdSet):\r
967 structure_pcd_data = {}\r
968 for item in PcdSet:\r
8518bf0b
LG
969 if (item[0],item[1]) not in structure_pcd_data:\r
970 structure_pcd_data[(item[0],item[1])] = []\r
971 structure_pcd_data[(item[0],item[1])].append(item)\r
ae7b6df8
LG
972\r
973 return structure_pcd_data\r
974\r
975 def UpdateStructuredPcds(self, TypeList, AllPcds):\r
65eff519
LG
976\r
977 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
978 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
979 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
980 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
981 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
982 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]\r
983\r
ae7b6df8 984 Pcds = AllPcds\r
8518bf0b 985 DefaultStoreMgr = DefaultStore(self.DefaultStores)\r
65eff519
LG
986 SkuIds = self.SkuIdMgr.AvailableSkuIdSet\r
987 SkuIds.update({'DEFAULT':0})\r
8518bf0b 988 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
ae7b6df8
LG
989\r
990 S_PcdSet = []\r
991 # Find out all possible PCD candidates for self._Arch\r
992 RecordList = []\r
2b8a6c44 993\r
ae7b6df8
LG
994 for Type in TypeList:\r
995 RecordList.extend(self._RawData[Type, self._Arch])\r
996\r
8518bf0b 997 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
998 SkuName = SkuName.upper()\r
999 default_store = default_store.upper()\r
1000 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
8518bf0b
LG
1001 if SkuName not in SkuIds:\r
1002 continue\r
2b8a6c44 1003\r
8518bf0b
LG
1004 if SkuName in SkuIds and "." in TokenSpaceGuid:\r
1005 S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]))\r
ae7b6df8
LG
1006\r
1007 # handle pcd value override\r
1008 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)\r
1009 S_pcd_set = {}\r
1010 for str_pcd in StrPcdSet:\r
8518bf0b
LG
1011 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)\r
1012 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)\r
ae7b6df8
LG
1013 if str_pcd_dec:\r
1014 str_pcd_obj_str = StructurePcd()\r
1015 str_pcd_obj_str.copy(str_pcd_dec)\r
1016 if str_pcd_obj:\r
1017 str_pcd_obj_str.copy(str_pcd_obj)\r
1018 if str_pcd_obj.DefaultValue:\r
1019 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1020 for str_pcd_data in StrPcdSet[str_pcd]:\r
8518bf0b
LG
1021 if str_pcd_data[3] in SkuIds:\r
1022 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
1023 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str\r
2b8a6c44
LG
1024 else:\r
1025 EdkLogger.error('build', PARSER_ERROR,\r
1026 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),\r
1027 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])\r
ae7b6df8 1028 # Add the Structure PCD that only defined in DEC, don't have override in DSC file\r
5644e5ce 1029 for Pcd in self.DecPcds:\r
ae7b6df8
LG
1030 if type (self._DecPcds[Pcd]) is StructurePcd:\r
1031 if Pcd not in S_pcd_set:\r
1032 str_pcd_obj_str = StructurePcd()\r
1033 str_pcd_obj_str.copy(self._DecPcds[Pcd])\r
1034 str_pcd_obj = Pcds.get(Pcd, None)\r
1035 if str_pcd_obj:\r
1036 str_pcd_obj_str.copy(str_pcd_obj)\r
1037 if str_pcd_obj.DefaultValue:\r
1038 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue\r
1039 S_pcd_set[Pcd] = str_pcd_obj_str\r
1040 if S_pcd_set:\r
1041 GlobalData.gStructurePcd[self.Arch] = S_pcd_set\r
8518bf0b 1042 for stru_pcd in S_pcd_set.values():\r
67e63e9a
LG
1043 for skuid in SkuIds:\r
1044 if skuid in stru_pcd.SkuOverrideValues:\r
1045 continue\r
1046 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)\r
1047 NoDefault = False\r
1048 while nextskuid not in stru_pcd.SkuOverrideValues:\r
1049 if nextskuid == "DEFAULT":\r
1050 NoDefault = True\r
1051 break\r
1052 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1053 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
1054 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1055 for skuid in SkuIds:\r
1056 nextskuid = skuid\r
2b8a6c44 1057 NoDefault = False\r
8518bf0b
LG
1058 if skuid not in stru_pcd.SkuOverrideValues:\r
1059 while nextskuid not in stru_pcd.SkuOverrideValues:\r
2b8a6c44
LG
1060 if nextskuid == "DEFAULT":\r
1061 NoDefault = True\r
1062 break\r
8518bf0b 1063 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1064 if NoDefault:\r
1065 continue\r
1066 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])\r
8518bf0b 1067 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)\r
2b8a6c44 1068\r
8518bf0b
LG
1069 for defaultstoreid in DefaultStores:\r
1070 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:\r
2b8a6c44 1071 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])\r
65eff519 1072\r
ae7b6df8
LG
1073 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)\r
1074 if Str_Pcd_Values:\r
8518bf0b
LG
1075 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:\r
1076 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))\r
ae7b6df8 1077 if str_pcd_obj is None:\r
67e63e9a 1078 print PcdName, PcdGuid\r
ae7b6df8
LG
1079 raise\r
1080 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1081 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
8518bf0b
LG
1082 if skuname not in str_pcd_obj.SkuInfoList:\r
1083 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})\r
ae7b6df8 1084 else:\r
8518bf0b
LG
1085 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue\r
1086 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})\r
ae7b6df8
LG
1087 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],\r
1088 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:\r
8518bf0b
LG
1089 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1090 str_pcd_obj.DefaultValue = PcdValue\r
ae7b6df8 1091 else:\r
8518bf0b 1092 if skuname not in str_pcd_obj.SkuInfoList:\r
65eff519
LG
1093 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
1094 NoDefault = False\r
1095 while nextskuid not in str_pcd_obj.SkuInfoList:\r
1096 if nextskuid == "DEFAULT":\r
1097 NoDefault = True\r
1098 break\r
1099 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
1100 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
1101 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]\r
1102 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname\r
ae7b6df8 1103 else:\r
8518bf0b
LG
1104 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue\r
1105 for str_pcd_obj in S_pcd_set.values():\r
1106 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1107 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1108 continue\r
1109 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])\r
1110 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
1111 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)\r
1112 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]\r
ae7b6df8
LG
1113\r
1114 for str_pcd_obj in S_pcd_set.values():\r
2b8a6c44 1115\r
ae7b6df8
LG
1116 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)\r
1117 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj\r
1118\r
65eff519
LG
1119 for pcdkey in Pcds:\r
1120 pcd = Pcds[pcdkey]\r
1121 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1122 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1123 del(pcd.SkuInfoList['COMMON'])\r
1124 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1125 del(pcd.SkuInfoList['COMMON'])\r
1126\r
1127 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])\r
ae7b6df8
LG
1128 return Pcds\r
1129\r
1130 ## Retrieve non-dynamic PCD settings\r
1131 #\r
1132 # @param Type PCD type\r
1133 #\r
1134 # @retval a dict object contains settings of given PCD type\r
1135 #\r
1136 def _GetPcd(self, Type):\r
1137 Pcds = sdict()\r
1138 #\r
1139 # tdict is a special dict kind of type, used for selecting correct\r
1140 # PCD settings for certain ARCH\r
1141 #\r
2b8a6c44 1142 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8
LG
1143\r
1144 PcdDict = tdict(True, 3)\r
1145 PcdSet = set()\r
1146 # Find out all possible PCD candidates for self._Arch\r
1147 RecordList = self._RawData[Type, self._Arch]\r
ae7b6df8 1148 PcdValueDict = sdict()\r
8518bf0b 1149 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1150 SkuName = SkuName.upper()\r
1151 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1152 if SkuName not in AvailableSkuIdSet:\r
1153 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1154 File=self.MetaFile, Line=Dummy5)\r
8518bf0b
LG
1155 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):\r
1156 if "." not in TokenSpaceGuid:\r
1157 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
ae7b6df8 1158 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting\r
ae7b6df8
LG
1159\r
1160 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:\r
1161 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]\r
1162 if Setting == None:\r
1163 continue\r
1164 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1165 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
1166 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)\r
1167 else:\r
1168 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}\r
1169\r
1170 PcdsKeys = PcdValueDict.keys()\r
1171 for PcdCName, TokenSpaceGuid in PcdsKeys:\r
1172\r
1173 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
1174 PcdValue = None\r
1175 DatumType = None\r
1176 MaxDatumSize = None\r
1177 if 'COMMON' in PcdSetting:\r
1178 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']\r
1179 if 'DEFAULT' in PcdSetting:\r
1180 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']\r
8518bf0b
LG
1181 if self.SkuIdMgr.SystemSkuId in PcdSetting:\r
1182 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]\r
ae7b6df8
LG
1183\r
1184 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1185 PcdCName,\r
1186 TokenSpaceGuid,\r
1187 self._PCD_TYPE_STRING_[Type],\r
1188 DatumType,\r
1189 PcdValue,\r
1190 '',\r
1191 MaxDatumSize,\r
1192 {},\r
1193 False,\r
1194 None,\r
1195 IsDsc=True)\r
1196\r
1197\r
1198 return Pcds\r
1199\r
8518bf0b
LG
1200 def __UNICODE2OCTList(self,Value):\r
1201 Value = Value.strip()\r
1202 Value = Value[2:-1]\r
1203 List = []\r
1204 for Item in Value:\r
1205 Temp = '%04X' % ord(Item)\r
1206 List.append('0x' + Temp[2:4])\r
1207 List.append('0x' + Temp[0:2])\r
1208 List.append('0x00')\r
1209 List.append('0x00')\r
1210 return List\r
1211 def __STRING2OCTList(self,Value):\r
1212 OCTList = []\r
1213 Value = Value.strip('"')\r
1214 for char in Value:\r
1215 Temp = '%02X' % ord(char)\r
1216 OCTList.append('0x' + Temp)\r
1217 OCTList.append('0x00')\r
1218 return OCTList\r
1219\r
ae7b6df8
LG
1220 def GetStructurePcdMaxSize(self, str_pcd):\r
1221 pcd_default_value = str_pcd.DefaultValue\r
1222 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
1223 sku_values.append(pcd_default_value)\r
1224\r
1225 def get_length(value):\r
1226 Value = value.strip()\r
a0939593
LG
1227 if len(value) > 1:\r
1228 if Value.startswith('GUID') and Value.endswith(')'):\r
1229 return 16\r
1230 if Value.startswith('L"') and Value.endswith('"'):\r
1231 return len(Value[2:-1])\r
1232 if Value[0] == '"' and Value[-1] == '"':\r
1233 return len(Value) - 2\r
1234 if Value[0] == '{' and Value[-1] == '}':\r
1235 return len(Value.split(","))\r
1236 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1237 return len(list(Value[2:-1]))\r
1238 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1239 return len(Value) - 2\r
ae7b6df8
LG
1240 return len(Value)\r
1241\r
1242 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))\r
1243\r
1244 def IsFieldValueAnArray (self, Value):\r
1245 Value = Value.strip()\r
1246 if Value.startswith('GUID') and Value.endswith(')'):\r
1247 return True\r
1248 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:\r
1249 return True\r
1250 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:\r
1251 return True\r
1252 if Value[0] == '{' and Value[-1] == '}':\r
1253 return True\r
1254 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:\r
1255 print 'foo = ', list(Value[2:-1])\r
1256 return True\r
1257 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:\r
1258 print 'bar = ', list(Value[1:-1])\r
1259 return True\r
1260 return False\r
1261\r
1262 def ExecuteCommand (self, Command):\r
1263 try:\r
1264 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
1265 except:\r
1266 print 'ERROR: Can not execute command:', Command\r
1267 sys.exit(1)\r
1268 Result = Process.communicate()\r
1269 if Process.returncode <> 0:\r
1270 print 'ERROR: Can not collect output from command:', Command\r
1271 return Result[0], Result[1]\r
1272\r
1273 def IntToCString(self, Value, ValueSize):\r
1274 Result = '"'\r
1275 if not isinstance (Value, str):\r
1276 for Index in range(0, ValueSize):\r
1277 Result = Result + '\\x%02x' % (Value & 0xff)\r
1278 Value = Value >> 8\r
1279 Result = Result + '"'\r
1280 return Result\r
1281\r
1282 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):\r
8518bf0b 1283 OverrideValues = {DefaultStoreName:""}\r
ae7b6df8
LG
1284 if Pcd.SkuOverrideValues:\r
1285 OverrideValues = Pcd.SkuOverrideValues[SkuName]\r
8518bf0b
LG
1286 for DefaultStoreName in OverrideValues.keys():\r
1287 CApp = CApp + 'void\n'\r
1288 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1289 CApp = CApp + ' void\n'\r
1290 CApp = CApp + ' )\n'\r
1291 CApp = CApp + '{\n'\r
1292 CApp = CApp + ' UINT32 Size;\n'\r
1293 CApp = CApp + ' UINT32 FieldSize;\n'\r
b2395724 1294 CApp = CApp + ' CHAR8 *Value;\n'\r
8518bf0b
LG
1295 CApp = CApp + ' UINT32 OriginalSize;\n'\r
1296 CApp = CApp + ' VOID *OriginalPcd;\n'\r
6a103440 1297 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)\r
8518bf0b 1298 CApp = CApp + '\n'\r
47854fd5 1299\r
8e011d83
FB
1300 if SkuName in Pcd.SkuInfoList:\r
1301 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue\r
1302 else:\r
1303 DefaultValue = Pcd.DefaultValue\r
1304 PcdDefaultValue = StringToArray(DefaultValue.strip())\r
47854fd5 1305\r
8518bf0b 1306 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)\r
ae7b6df8 1307\r
8518bf0b
LG
1308 #\r
1309 # Get current PCD value and size\r
1310 #\r
1311 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1312\r
8518bf0b
LG
1313 #\r
1314 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides\r
1315 # the correct value. For structures with a flexible array member, the flexible\r
1316 # array member is detected, and the size is based on the highest index used with\r
1317 # the flexible array member. The flexible array member must be the last field\r
1318 # in a structure. The size formula for this case is:\r
1319 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)\r
1320 #\r
1321 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)\r
4cc82428
FB
1322 for FieldList in [Pcd.DefaultValues]:\r
1323 if not FieldList:\r
1324 continue\r
1325 for FieldName in FieldList:\r
1326 FieldName = "." + FieldName\r
1327 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1328 if IsArray:\r
1329 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1330 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
1331 else:\r
1332 NewFieldName = ''\r
1333 while '[' in FieldName:\r
1334 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1335 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1336 FieldName = FieldName.split(']', 1)[1]\r
1337 FieldName = NewFieldName + FieldName\r
1338 while '[' in FieldName:\r
1339 FieldName = FieldName.rsplit('[', 1)[0]\r
1340 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
09c80b07 1341 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1342 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
4cc82428 1343 for FieldList in [inherit_OverrideValues.get(DefaultStoreName)]:\r
c05c2c05
LG
1344 if not FieldList:\r
1345 continue\r
1346 for FieldName in FieldList:\r
1347 FieldName = "." + FieldName\r
1348 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])\r
1349 if IsArray:\r
1350 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])\r
1351 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
1352 else:\r
1353 NewFieldName = ''\r
1354 while '[' in FieldName:\r
1355 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'\r
1356 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])\r
1357 FieldName = FieldName.split(']', 1)[1]\r
1358 FieldName = NewFieldName + FieldName\r
1359 while '[' in FieldName:\r
1360 FieldName = FieldName.rsplit('[', 1)[0]\r
1361 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)\r
1362 if skuname == SkuName:\r
1363 break\r
ae7b6df8 1364\r
8518bf0b
LG
1365 #\r
1366 # Allocate and zero buffer for the PCD\r
1367 # Must handle cases where current value is smaller, larger, or same size\r
1368 # Always keep that larger one as the current size\r
1369 #\r
1370 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'\r
1371 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)\r
1372 CApp = CApp + ' memset (Pcd, 0, Size);\n'\r
ae7b6df8 1373\r
8518bf0b
LG
1374 #\r
1375 # Copy current PCD value into allocated buffer.\r
1376 #\r
1377 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'\r
ae7b6df8 1378\r
8518bf0b
LG
1379 #\r
1380 # Assign field values in PCD\r
1381 #\r
4cc82428
FB
1382 for FieldList in [Pcd.DefaultValues]:\r
1383 if not FieldList:\r
1384 continue\r
1385 for FieldName in FieldList:\r
1386 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1387 try:\r
1388 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1389 except Exception:\r
1390 print FieldList[FieldName][0]\r
1391 if isinstance(Value, str):\r
1392 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1393 elif IsArray:\r
1394 #\r
1395 # Use memcpy() to copy value into field\r
1396 #\r
1397 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1398 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
1399 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
1400 else:\r
1401 if ValueSize > 4:\r
1402 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1403 else:\r
1404 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 1405 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):\r
c05c2c05 1406 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]\r
4cc82428 1407 for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(DefaultStoreName)]:\r
c05c2c05
LG
1408 if not FieldList:\r
1409 continue\r
1410 if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:\r
1411 IsArray = self.IsFieldValueAnArray(FieldList)\r
1412 Value, ValueSize = ParseFieldValue (FieldList)\r
1413 if isinstance(Value, str):\r
1414 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)\r
1415 elif IsArray:\r
8518bf0b
LG
1416 #\r
1417 # Use memcpy() to copy value into field\r
1418 #\r
c05c2c05
LG
1419 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)\r
1420 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)\r
1421 continue\r
ae7b6df8 1422\r
c05c2c05
LG
1423 for FieldName in FieldList:\r
1424 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])\r
1425 try:\r
1426 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])\r
1427 except Exception:\r
1428 print FieldList[FieldName][0]\r
1429 if isinstance(Value, str):\r
1430 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1431 elif IsArray:\r
8518bf0b
LG
1432 #\r
1433 # Use memcpy() to copy value into field\r
1434 #\r
c05c2c05
LG
1435 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)\r
1436 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
1437 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)\r
8518bf0b 1438 else:\r
c05c2c05
LG
1439 if ValueSize > 4:\r
1440 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1441 else:\r
1442 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])\r
1443 if skuname == SkuName:\r
1444 break\r
8518bf0b
LG
1445 #\r
1446 # Set new PCD value and size\r
1447 #\r
1448 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1449\r
8518bf0b
LG
1450 #\r
1451 # Free PCD\r
1452 #\r
1453 CApp = CApp + ' free (Pcd);\n'\r
1454 CApp = CApp + '}\n'\r
1455 CApp = CApp + '\n'\r
ae7b6df8
LG
1456 return InitByteValue, CApp\r
1457\r
1458 def GenerateByteArrayValue (self, StructuredPcds):\r
1459 #\r
1460 # Generate/Compile/Run C application to determine if there are any flexible array members\r
1461 #\r
1462 if not StructuredPcds:\r
1463 return\r
1464\r
1465 InitByteValue = ""\r
1466 CApp = PcdMainCHeader\r
1467\r
1468 Includes = {}\r
1469 for PcdName in StructuredPcds:\r
1470 Pcd = StructuredPcds[PcdName]\r
1471 IncludeFile = Pcd.StructuredPcdIncludeFile\r
1472 if IncludeFile not in Includes:\r
1473 Includes[IncludeFile] = True\r
1474 CApp = CApp + '#include <%s>\n' % (IncludeFile)\r
1475 CApp = CApp + '\n'\r
1476\r
1477 for PcdName in StructuredPcds:\r
1478 Pcd = StructuredPcds[PcdName]\r
1479 if not Pcd.SkuOverrideValues:\r
8518bf0b 1480 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)\r
ae7b6df8 1481 else:\r
c05c2c05
LG
1482 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1483 if SkuName not in Pcd.SkuOverrideValues:\r
1484 continue\r
ae7b6df8
LG
1485 for DefaultStoreName in Pcd.DefaultStoreName:\r
1486 Pcd = StructuredPcds[PcdName]\r
1487 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)\r
1488\r
1489 CApp = CApp + 'VOID\n'\r
1490 CApp = CApp + 'PcdEntryPoint(\n'\r
1491 CApp = CApp + ' VOID\n'\r
1492 CApp = CApp + ' )\n'\r
1493 CApp = CApp + '{\n'\r
1494 for Pcd in StructuredPcds.values():\r
1495 if not Pcd.SkuOverrideValues:\r
8518bf0b 1496 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
ae7b6df8 1497 else:\r
c05c2c05
LG
1498 for SkuName in self.SkuIdMgr.SkuOverrideOrder():\r
1499 if SkuName not in Pcd.SkuOverrideValues:\r
1500 continue\r
8518bf0b 1501 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:\r
ae7b6df8
LG
1502 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)\r
1503 CApp = CApp + '}\n'\r
1504\r
1505 CApp = CApp + PcdMainCEntry + '\n'\r
1506\r
1507 if not os.path.exists(self.OutputPath):\r
1508 os.makedirs(self.OutputPath)\r
1509 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)\r
1510 File = open (CAppBaseFileName + '.c', 'w')\r
1511 File.write(CApp)\r
1512 File.close()\r
1513\r
1514 MakeApp = PcdMakefileHeader\r
1515 if sys.platform == "win32":\r
1516 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '\r
1517 else:\r
1518 MakeApp = MakeApp + PcdGccMakefile\r
1519 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \\r
68ba919f 1520 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='\r
ae7b6df8
LG
1521\r
1522 PlatformInc = {}\r
1523 for Cache in self._Bdb._CACHE_.values():\r
1524 if Cache.MetaFile.Ext.lower() != '.dec':\r
1525 continue\r
1526 if Cache.Includes:\r
1527 if str(Cache.MetaFile.Path) not in PlatformInc:\r
1528 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes\r
1529\r
1530 PcdDependDEC = []\r
1531 for Pcd in StructuredPcds.values():\r
1532 for PackageDec in Pcd.PackageDecs:\r
1533 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))\r
1534 if not os.path.exists(Package):\r
1535 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
1536 if Package not in PcdDependDEC:\r
1537 PcdDependDEC.append(Package)\r
1538\r
1539 if PlatformInc and PcdDependDEC:\r
1540 for pkg in PcdDependDEC:\r
1541 if pkg in PlatformInc:\r
1542 for inc in PlatformInc[pkg]:\r
1543 MakeApp += '-I' + str(inc) + ' '\r
1544 MakeApp = MakeApp + '\n'\r
68ba919f
YZ
1545\r
1546 CC_FLAGS = LinuxCFLAGS\r
1547 if sys.platform == "win32":\r
1548 CC_FLAGS = WindowsCFLAGS\r
1549 BuildOptions = {}\r
1550 for Options in self.BuildOptions:\r
1551 if Options[2] != EDKII_NAME:\r
1552 continue\r
1553 Family = Options[0]\r
1554 if Family and Family != self.ToolChainFamily:\r
1555 continue\r
1556 Target, Tag, Arch, Tool, Attr = Options[1].split("_")\r
1557 if Tool != 'CC':\r
1558 continue\r
1559\r
1560 if Target == "*" or Target == self._Target:\r
1561 if Tag == "*" or Tag == self._Toolchain:\r
1562 if Arch == "*" or Arch == self.Arch:\r
1563 if Tool not in BuildOptions:\r
1564 BuildOptions[Tool] = {}\r
1565 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):\r
1566 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1567 else:\r
1568 # append options for the same tool except PATH\r
1569 if Attr != 'PATH':\r
1570 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]\r
1571 else:\r
1572 BuildOptions[Tool][Attr] = self.BuildOptions[Options]\r
1573 if BuildOptions:\r
1574 for Tool in BuildOptions:\r
1575 for Attr in BuildOptions[Tool]:\r
1576 if Attr == "FLAGS":\r
1577 Value = BuildOptions[Tool][Attr]\r
1578 ValueList = Value.split()\r
1579 if ValueList:\r
1580 for Id, Item in enumerate(ValueList):\r
1581 if Item == '-D' or Item == '/D':\r
1582 CC_FLAGS += ' ' + Item\r
1583 if Id + 1 < len(ValueList):\r
1584 CC_FLAGS += ' ' + ValueList[Id + 1]\r
1585 elif Item.startswith('/D') or Item.startswith('-D'):\r
1586 CC_FLAGS += ' ' + Item\r
1587 MakeApp += CC_FLAGS\r
1588\r
ae7b6df8
LG
1589 if sys.platform == "win32":\r
1590 MakeApp = MakeApp + PcdMakefileEnd\r
1591 MakeFileName = os.path.join(self.OutputPath, 'Makefile')\r
1592 File = open (MakeFileName, 'w')\r
1593 File.write(MakeApp)\r
1594 File.close()\r
1595\r
1596 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')\r
1597 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')\r
1598 File = open (InputValueFile, 'w')\r
1599 File.write(InitByteValue)\r
1600 File.close()\r
1601\r
b2395724 1602 Messages = ''\r
ae7b6df8
LG
1603 if sys.platform == "win32":\r
1604 StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))\r
b2395724 1605 Messages = StdOut\r
ae7b6df8
LG
1606 else:\r
1607 StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))\r
b2395724
LG
1608 Messages = StdErr\r
1609 Messages = Messages.split('\n')\r
1610 for Message in Messages:\r
1611 if " error" in Message:\r
1612 FileInfo = Message.strip().split('(')\r
1613 if len (FileInfo) > 1:\r
1614 FileName = FileInfo [0]\r
1615 FileLine = FileInfo [1].split (')')[0]\r
1616 else:\r
1617 FileInfo = Message.strip().split(':')\r
1618 FileName = FileInfo [0]\r
1619 FileLine = FileInfo [1]\r
1620\r
1621 File = open (FileName, 'r')\r
1622 FileData = File.readlines()\r
1623 File.close()\r
1624 error_line = FileData[int (FileLine) - 1]\r
1625 if r"//" in error_line:\r
1626 c_line,dsc_line = error_line.split(r"//")\r
1627 else:\r
1628 dsc_line = error_line\r
1629\r
1630 message_itmes = Message.split(":")\r
1631 Index = 0\r
1632 for item in message_itmes:\r
1633 if "PcdValueInit.c" in item:\r
1634 Index = message_itmes.index(item)\r
1635 message_itmes[Index] = dsc_line.strip()\r
1636 break\r
1637\r
1638 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[Index:]))\r
ae7b6df8
LG
1639\r
1640 PcdValueInitExe = PcdValueInitName\r
1641 if not sys.platform == "win32":\r
1642 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)\r
1643\r
1644 StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))\r
1645 File = open (OutputValueFile, 'r')\r
1646 FileBuffer = File.readlines()\r
1647 File.close()\r
1648\r
1649 StructurePcdSet = []\r
1650 for Pcd in FileBuffer:\r
1651 PcdValue = Pcd.split ('|')\r
1652 PcdInfo = PcdValue[0].split ('.')\r
8518bf0b 1653 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))\r
ae7b6df8
LG
1654 return StructurePcdSet\r
1655\r
1656 ## Retrieve dynamic PCD settings\r
1657 #\r
1658 # @param Type PCD type\r
1659 #\r
1660 # @retval a dict object contains settings of given PCD type\r
1661 #\r
1662 def _GetDynamicPcd(self, Type):\r
1663\r
ae7b6df8
LG
1664\r
1665 Pcds = sdict()\r
1666 #\r
1667 # tdict is a special dict kind of type, used for selecting correct\r
1668 # PCD settings for certain ARCH and SKU\r
1669 #\r
1670 PcdDict = tdict(True, 4)\r
1671 PcdList = []\r
1672 # Find out all possible PCD candidates for self._Arch\r
1673 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1674 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1675\r
ae7b6df8 1676\r
8518bf0b 1677 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1678 SkuName = SkuName.upper()\r
1679 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 1680 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1681 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1682 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8
LG
1683 if "." not in TokenSpaceGuid:\r
1684 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1685 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1686\r
1687 # Remove redundant PCD candidates, per the ARCH and SKU\r
1688 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1689\r
1690 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1691 if Setting == None:\r
1692 continue\r
1693\r
1694 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 1695 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)\r
ae7b6df8
LG
1696 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1697 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
1698 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1699 if MaxDatumSize.strip():\r
1700 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
1701 else:\r
1702 CurrentMaxSize = 0\r
1703 if pcdObject.MaxDatumSize:\r
1704 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
1705 else:\r
1706 PcdMaxSize = 0\r
1707 if CurrentMaxSize > PcdMaxSize:\r
1708 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
1709 else:\r
1710 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1711 PcdCName,\r
1712 TokenSpaceGuid,\r
1713 self._PCD_TYPE_STRING_[Type],\r
1714 DatumType,\r
1715 PcdValue,\r
1716 '',\r
1717 MaxDatumSize,\r
1718 {SkuName : SkuInfo},\r
1719 False,\r
1720 None,\r
1721 IsDsc=True)\r
1722\r
1723 for pcd in Pcds.values():\r
1724 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
1725 # Only fix the value while no value provided in DSC file.\r
1726 for sku in pcd.SkuInfoList.values():\r
1727 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
1728 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
1729 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1730 valuefromDec = pcdDecObject.DefaultValue\r
1731 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
1732 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1733 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1734 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1735 del(pcd.SkuInfoList['COMMON'])\r
1736 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1737 del(pcd.SkuInfoList['COMMON'])\r
65eff519
LG
1738\r
1739 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
1740\r
1741 return Pcds\r
1742\r
65eff519
LG
1743 def FilterSkuSettings(self, PcdObj):\r
1744\r
1745 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:\r
1746 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():\r
1747 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']\r
1748 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}\r
1749 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'\r
1750 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'\r
1751\r
1752 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:\r
1753 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}\r
1754\r
1755 return PcdObj\r
1756\r
1757\r
ae7b6df8
LG
1758 def CompareVarAttr(self, Attr1, Attr2):\r
1759 if not Attr1 or not Attr2: # for empty string\r
1760 return True\r
1761 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
1762 Attr1Set = set(Attr1s)\r
1763 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
1764 Attr2Set = set(Attr2s)\r
1765 if Attr2Set == Attr1Set:\r
1766 return True\r
1767 else:\r
1768 return False\r
8518bf0b
LG
1769 def CompletePcdValues(self,PcdSet):\r
1770 Pcds = {}\r
1771 DefaultStoreObj = DefaultStore(self._GetDefaultStores())\r
98eb1364 1772 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}\r
8518bf0b
LG
1773 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])\r
1774 for PcdCName, TokenSpaceGuid in PcdSet:\r
1775 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]\r
1776 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],\r
1777 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],\r
1778 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],\r
1779 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],\r
1780 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],\r
1781 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:\r
1782 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1783 continue\r
1784 PcdType = PcdObj.Type\r
1785 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1786 for skuid in PcdObj.SkuInfoList:\r
1787 skuobj = PcdObj.SkuInfoList[skuid]\r
1788 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))\r
1789 for defaultstorename in DefaultStores:\r
1790 if defaultstorename not in skuobj.DefaultStoreDict:\r
2b8a6c44 1791 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])\r
8518bf0b 1792 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]\r
8ac16789 1793 for skuname,skuid in SkuIds.items():\r
2b8a6c44
LG
1794 if skuname not in PcdObj.SkuInfoList:\r
1795 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)\r
8518bf0b
LG
1796 while nextskuid not in PcdObj.SkuInfoList:\r
1797 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)\r
2b8a6c44
LG
1798 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])\r
1799 PcdObj.SkuInfoList[skuname].SkuId = skuid\r
1800 PcdObj.SkuInfoList[skuname].SkuIdName = skuname\r
8518bf0b
LG
1801 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:\r
1802 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue\r
1803 Pcds[PcdCName, TokenSpaceGuid]= PcdObj\r
1804 return Pcds\r
ae7b6df8
LG
1805 ## Retrieve dynamic HII PCD settings\r
1806 #\r
1807 # @param Type PCD type\r
1808 #\r
1809 # @retval a dict object contains settings of given PCD type\r
1810 #\r
1811 def _GetDynamicHiiPcd(self, Type):\r
1812\r
ae7b6df8
LG
1813 VariableAttrs = {}\r
1814\r
1815 Pcds = sdict()\r
1816 #\r
1817 # tdict is a special dict kind of type, used for selecting correct\r
1818 # PCD settings for certain ARCH and SKU\r
1819 #\r
8518bf0b 1820 PcdDict = tdict(True, 5)\r
ae7b6df8
LG
1821 PcdSet = set()\r
1822 RecordList = self._RawData[Type, self._Arch]\r
1823 # Find out all possible PCD candidates for self._Arch\r
8518bf0b 1824 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
2b8a6c44 1825 DefaultStoresDefine = self._GetDefaultStores()\r
ae7b6df8 1826\r
8518bf0b 1827 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1828 SkuName = SkuName.upper()\r
1829 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
1830 DefaultStore = DefaultStore.upper()\r
8518bf0b
LG
1831 if DefaultStore == "COMMON":\r
1832 DefaultStore = "STANDARD"\r
ae7b6df8 1833 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1834 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1835 File=self.MetaFile, Line=Dummy5)\r
1836 if DefaultStore not in DefaultStoresDefine:\r
1837 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,\r
1838 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8 1839 if "." not in TokenSpaceGuid:\r
8518bf0b
LG
1840 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4))\r
1841 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting\r
ae7b6df8
LG
1842\r
1843\r
1844 # Remove redundant PCD candidates, per the ARCH and SKU\r
8518bf0b 1845 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:\r
ae7b6df8 1846\r
8518bf0b 1847 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]\r
ae7b6df8
LG
1848 if Setting == None:\r
1849 continue\r
1850 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
1851\r
1852 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
1853 if not rt:\r
1854 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
1855 ExtraData="[%s]" % VarAttribute)\r
1856 ExceedMax = False\r
1857 FormatCorrect = True\r
1858 if VariableOffset.isdigit():\r
1859 if int(VariableOffset, 10) > 0xFFFF:\r
1860 ExceedMax = True\r
1861 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):\r
1862 if int(VariableOffset, 16) > 0xFFFF:\r
1863 ExceedMax = True\r
1864 # For Offset written in "A.B"\r
1865 elif VariableOffset.find('.') > -1:\r
1866 VariableOffsetList = VariableOffset.split(".")\r
1867 if not (len(VariableOffsetList) == 2\r
1868 and IsValidWord(VariableOffsetList[0])\r
1869 and IsValidWord(VariableOffsetList[1])):\r
1870 FormatCorrect = False\r
1871 else:\r
1872 FormatCorrect = False\r
1873 if not FormatCorrect:\r
1874 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))\r
1875\r
1876 if ExceedMax:\r
1877 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
1878 if (VariableName, VariableGuid) not in VariableAttrs:\r
1879 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1880 else:\r
1881 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1882 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
1883\r
ae7b6df8
LG
1884 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
1885 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
1886 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
8518bf0b
LG
1887 if SkuName in pcdObject.SkuInfoList:\r
1888 Skuitem = pcdObject.SkuInfoList[SkuName]\r
1889 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})\r
1890 else:\r
1891 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
1892 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
ae7b6df8 1893 else:\r
8518bf0b 1894 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})\r
ae7b6df8
LG
1895 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
1896 PcdCName,\r
1897 TokenSpaceGuid,\r
1898 self._PCD_TYPE_STRING_[Type],\r
1899 '',\r
1900 DefaultValue,\r
1901 '',\r
1902 '',\r
1903 {SkuName : SkuInfo},\r
1904 False,\r
1905 None,\r
1906 pcdDecObject.validateranges,\r
1907 pcdDecObject.validlists,\r
1908 pcdDecObject.expressions,\r
1909 IsDsc=True)\r
1910\r
1911\r
1912 for pcd in Pcds.values():\r
1913 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
1914 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
1915 # Only fix the value while no value provided in DSC file.\r
1916 for sku in pcd.SkuInfoList.values():\r
1917 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):\r
1918 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1919 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
1920 valuefromDec = pcdDecObject.DefaultValue\r
2b8a6c44 1921 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})\r
ae7b6df8
LG
1922 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1923 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1924 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1925 del(pcd.SkuInfoList['COMMON'])\r
1926 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1927 del(pcd.SkuInfoList['COMMON'])\r
1928\r
ae7b6df8
LG
1929 if pcd.MaxDatumSize.strip():\r
1930 MaxSize = int(pcd.MaxDatumSize, 0)\r
1931 else:\r
1932 MaxSize = 0\r
1933 if pcdDecObject.DatumType == 'VOID*':\r
2b8a6c44 1934 for (_, skuobj) in pcd.SkuInfoList.items():\r
ae7b6df8 1935 datalen = 0\r
47854fd5
LG
1936 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)\r
1937 datalen = len(skuobj.HiiDefaultValue.split(","))\r
ae7b6df8
LG
1938 if datalen > MaxSize:\r
1939 MaxSize = datalen\r
47854fd5
LG
1940 for defaultst in skuobj.DefaultStoreDict:\r
1941 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])\r
1942 pcd.DefaultValue = StringToArray(pcd.DefaultValue)\r
ae7b6df8 1943 pcd.MaxDatumSize = str(MaxSize)\r
2b8a6c44
LG
1944 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)\r
1945 if not rt:\r
1946 invalidpcd = ",".join(invalidhii)\r
1947 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
1948\r
1949 map(self.FilterSkuSettings,Pcds.values())\r
1950\r
ae7b6df8
LG
1951 return Pcds\r
1952\r
2b8a6c44
LG
1953 def CheckVariableNameAssignment(self,Pcds):\r
1954 invalidhii = []\r
1955 for pcdname in Pcds:\r
1956 pcd = Pcds[pcdname]\r
1957 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])\r
1958 if len(varnameset) > 1:\r
1959 invalidhii.append(".".join((pcdname[1],pcdname[0])))\r
1960 if len(invalidhii):\r
1961 return False,invalidhii\r
1962 else:\r
1963 return True, []\r
ae7b6df8
LG
1964 ## Retrieve dynamic VPD PCD settings\r
1965 #\r
1966 # @param Type PCD type\r
1967 #\r
1968 # @retval a dict object contains settings of given PCD type\r
1969 #\r
1970 def _GetDynamicVpdPcd(self, Type):\r
1971\r
ae7b6df8
LG
1972\r
1973 Pcds = sdict()\r
1974 #\r
1975 # tdict is a special dict kind of type, used for selecting correct\r
1976 # PCD settings for certain ARCH and SKU\r
1977 #\r
1978 PcdDict = tdict(True, 4)\r
1979 PcdList = []\r
1980\r
1981 # Find out all possible PCD candidates for self._Arch\r
1982 RecordList = self._RawData[Type, self._Arch]\r
8518bf0b 1983 AvailableSkuIdSet = copy.copy(self.SkuIds)\r
ae7b6df8 1984\r
8518bf0b 1985 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:\r
2b8a6c44
LG
1986 SkuName = SkuName.upper()\r
1987 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName\r
ae7b6df8 1988 if SkuName not in AvailableSkuIdSet:\r
2b8a6c44
LG
1989 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,\r
1990 File=self.MetaFile, Line=Dummy5)\r
ae7b6df8
LG
1991 if "." not in TokenSpaceGuid:\r
1992 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))\r
1993 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1994\r
1995 # Remove redundant PCD candidates, per the ARCH and SKU\r
1996 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
1997 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
1998 if Setting == None:\r
1999 continue\r
2000 #\r
2001 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
2002 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
2003 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
2004 # until the DEC parser has been called.\r
2005 #\r
2006 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
8518bf0b 2007 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)\r
ae7b6df8
LG
2008 if (PcdCName, TokenSpaceGuid) in Pcds.keys():\r
2009 pcdObject = Pcds[PcdCName, TokenSpaceGuid]\r
2010 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2011 if MaxDatumSize.strip():\r
2012 CurrentMaxSize = int(MaxDatumSize.strip(), 0)\r
2013 else:\r
2014 CurrentMaxSize = 0\r
2015 if pcdObject.MaxDatumSize:\r
2016 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)\r
2017 else:\r
2018 PcdMaxSize = 0\r
2019 if CurrentMaxSize > PcdMaxSize:\r
2020 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
2021 else:\r
2022 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
2023 PcdCName,\r
2024 TokenSpaceGuid,\r
2025 self._PCD_TYPE_STRING_[Type],\r
2026 '',\r
2027 InitialValue,\r
2028 '',\r
2029 MaxDatumSize,\r
2030 {SkuName : SkuInfo},\r
2031 False,\r
2032 None,\r
2033 IsDsc=True)\r
2034 for pcd in Pcds.values():\r
2035 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2036 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]\r
e651d06c
LG
2037 # Only fix the value while no value provided in DSC file.\r
2038 for sku in pcd.SkuInfoList.values():\r
2039 if (sku.DefaultValue == "" or sku.DefaultValue==None):\r
2040 sku.DefaultValue = pcdDecObject.DefaultValue\r
ae7b6df8
LG
2041 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
2042 valuefromDec = pcdDecObject.DefaultValue\r
2043 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)\r
2044 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
2045 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2046 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
2047 del(pcd.SkuInfoList['COMMON'])\r
2048 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
2049 del(pcd.SkuInfoList['COMMON'])\r
ae7b6df8 2050\r
65eff519
LG
2051\r
2052 map(self.FilterSkuSettings,Pcds.values())\r
ae7b6df8
LG
2053 return Pcds\r
2054\r
2055 ## Add external modules\r
2056 #\r
2057 # The external modules are mostly those listed in FDF file, which don't\r
2058 # need "build".\r
2059 #\r
2060 # @param FilePath The path of module description file\r
2061 #\r
2062 def AddModule(self, FilePath):\r
2063 FilePath = NormPath(FilePath)\r
2064 if FilePath not in self.Modules:\r
2065 Module = ModuleBuildClassObject()\r
2066 Module.MetaFile = FilePath\r
2067 self.Modules.append(Module)\r
2068\r
68ba919f
YZ
2069 def _GetToolChainFamily(self):\r
2070 self._ToolChainFamily = "MSFT"\r
2071 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))\r
2072 if os.path.isfile(BuildConfigurationFile) == True:\r
2073 TargetTxt = TargetTxtClassObject()\r
2074 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
2075 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]\r
2076 if ToolDefinitionFile == '':\r
2077 ToolDefinitionFile = "tools_def.txt"\r
2078 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))\r
2079 if os.path.isfile(ToolDefinitionFile) == True:\r
2080 ToolDef = ToolDefClassObject()\r
2081 ToolDef.LoadToolDefFile(ToolDefinitionFile)\r
2082 ToolDefinition = ToolDef.ToolsDefTxtDatabase\r
2083 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
2084 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
2085 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:\r
2086 self._ToolChainFamily = "MSFT"\r
2087 else:\r
2088 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]\r
2089 return self._ToolChainFamily\r
2090\r
ae7b6df8
LG
2091 ## Add external PCDs\r
2092 #\r
2093 # The external PCDs are mostly those listed in FDF file to specify address\r
2094 # or offset information.\r
2095 #\r
2096 # @param Name Name of the PCD\r
2097 # @param Guid Token space guid of the PCD\r
2098 # @param Value Value of the PCD\r
2099 #\r
2100 def AddPcd(self, Name, Guid, Value):\r
2101 if (Name, Guid) not in self.Pcds:\r
2102 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
2103 self.Pcds[Name, Guid].DefaultValue = Value\r
5644e5ce
FB
2104 @property\r
2105 def DecPcds(self):\r
2106 if self._DecPcds == None:\r
2107 FdfInfList = []\r
2108 if GlobalData.gFdfParser:\r
2109 FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
2110 PkgSet = set()\r
2111 for Inf in FdfInfList:\r
2112 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
2113 if ModuleFile in self._Modules:\r
2114 continue\r
2115 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
2116 PkgSet.update(ModuleData.Packages)\r
726c501c 2117 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)\r
5644e5ce 2118 return self._DecPcds\r
ae7b6df8
LG
2119 _Macros = property(_GetMacros)\r
2120 Arch = property(_GetArch, _SetArch)\r
2121 Platform = property(_GetPlatformName)\r
2122 PlatformName = property(_GetPlatformName)\r
2123 Guid = property(_GetFileGuid)\r
2124 Version = property(_GetVersion)\r
2125 DscSpecification = property(_GetDscSpec)\r
2126 OutputDirectory = property(_GetOutpuDir)\r
2127 SupArchList = property(_GetSupArch)\r
2128 BuildTargets = property(_GetBuildTarget)\r
2129 SkuName = property(_GetSkuName, _SetSkuName)\r
ae7b6df8
LG
2130 PcdInfoFlag = property(_GetPcdInfoFlag)\r
2131 VarCheckFlag = property(_GetVarCheckFlag)\r
2132 FlashDefinition = property(_GetFdfFile)\r
2133 Prebuild = property(_GetPrebuild)\r
2134 Postbuild = property(_GetPostbuild)\r
2135 BuildNumber = property(_GetBuildNumber)\r
2136 MakefileName = property(_GetMakefileName)\r
2137 BsBaseAddress = property(_GetBsBaseAddress)\r
2138 RtBaseAddress = property(_GetRtBaseAddress)\r
2139 LoadFixAddress = property(_GetLoadFixAddress)\r
2140 RFCLanguages = property(_GetRFCLanguages)\r
2141 ISOLanguages = property(_GetISOLanguages)\r
2142 VpdToolGuid = property(_GetVpdToolGuid)\r
2143 SkuIds = property(_GetSkuIds)\r
2144 Modules = property(_GetModules)\r
2145 LibraryInstances = property(_GetLibraryInstances)\r
2146 LibraryClasses = property(_GetLibraryClasses)\r
2147 Pcds = property(_GetPcds)\r
2148 BuildOptions = property(_GetBuildOptions)\r
68ba919f 2149 ToolChainFamily = property(_GetToolChainFamily)\r