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