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