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