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