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