]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTool: Add comments in PcdValueInit.c.
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
1 ## @file
2 # This file is used to create a database used by build tool
3 #
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ## Platform build information from DSC file
16 #
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
19 #
20 from Common.String import *
21 from Common.DataType import *
22 from Common.Misc import *
23 from types import *
24
25 from CommonDataClass.CommonClass import SkuInfoClass
26 from Common.TargetTxtClassObject import *
27 from Common.ToolDefClassObject import *
28 from MetaDataTable import *
29 from MetaFileTable import *
30 from MetaFileParser import *
31
32 from WorkspaceCommon import GetDeclaredPcd
33 from Common.Misc import AnalyzeDscPcd
34 from Common.Misc import ProcessDuplicatedInf
35 import re
36 from Common.Parsing import IsValidWord
37 from Common.VariableAttributes import VariableAttributes
38 import Common.GlobalData as GlobalData
39 import subprocess
40 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
41
42 #
43 # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
44 #
45 PcdValueInitName = 'PcdValueInit'
46 PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
47 PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
48 PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
49
50 PcdMainCHeader = '''
51 /**
52 DO NOT EDIT
53 FILE auto-generated
54 **/
55
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <PcdValueCommon.h>
60 '''
61
62 PcdMainCEntry = '''
63 int
64 main (
65 int argc,
66 char *argv[]
67 )
68 {
69 return PcdValueMain (argc, argv);
70 }
71 '''
72
73 PcdMakefileHeader = '''
74 #
75 # DO NOT EDIT
76 # This file is auto-generated by build utility
77 #
78
79 '''
80
81 WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
82 LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
83 PcdMakefileEnd = '''
84 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
85
86 LIBS = $(LIB_PATH)\Common.lib
87
88 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
89 '''
90
91 PcdGccMakefile = '''
92 ARCH ?= IA32
93 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
94 LIBS = -lCommon
95 '''
96
97 class DscBuildData(PlatformBuildClassObject):
98 # dict used to convert PCD type in database to string used by build tool
99 _PCD_TYPE_STRING_ = {
100 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
101 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
102 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
103 MODEL_PCD_DYNAMIC : "Dynamic",
104 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
105 MODEL_PCD_DYNAMIC_HII : "DynamicHii",
106 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
107 MODEL_PCD_DYNAMIC_EX : "DynamicEx",
108 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
109 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
110 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
111 }
112
113 # dict used to convert part of [Defines] to members of DscBuildData directly
114 _PROPERTY_ = {
115 #
116 # Required Fields
117 #
118 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
119 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
120 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
121 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
122 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
123 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
124 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
125 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
126 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
127 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
128 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
129 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
130 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
131 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
132 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
133 }
134
135 # used to compose dummy library class name for those forced library instances
136 _NullLibraryNumber = 0
137
138 ## Constructor of DscBuildData
139 #
140 # Initialize object of DscBuildData
141 #
142 # @param FilePath The path of platform description file
143 # @param RawData The raw data of DSC file
144 # @param BuildDataBase Database used to retrieve module/package information
145 # @param Arch The target architecture
146 # @param Platform (not used for DscBuildData)
147 # @param Macros Macros used for replacement in DSC file
148 #
149 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
150 self.MetaFile = FilePath
151 self._RawData = RawData
152 self._Bdb = BuildDataBase
153 self._Arch = Arch
154 self._Target = Target
155 self._Toolchain = Toolchain
156 self._ToolChainFamily = None
157 self._Clear()
158 self._HandleOverridePath()
159 if os.getenv("WORKSPACE"):
160 self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)
161 else:
162 self.OutputPath = os.path.dirname(self.DscFile)
163 self.DefaultStores = None
164 self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
165 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 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
586 if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None:
587 EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
588 File=self.MetaFile, Line=Record[-1])
589 if not IsValidWord(Record[1]):
590 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_-.)*'",
591 File=self.MetaFile, Line=Record[-1])
592 self._SkuIds[Record[1].upper()] = (str(self.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
593 if 'DEFAULT' not in self._SkuIds:
594 self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")
595 if 'COMMON' not in self._SkuIds:
596 self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")
597 return self._SkuIds
598 def ToInt(self,intstr):
599 return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr)
600 def _GetDefaultStores(self):
601 if self.DefaultStores == None:
602 self.DefaultStores = sdict()
603 RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
604 for Record in RecordList:
605 if Record[0] in [None, '']:
606 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
607 File=self.MetaFile, Line=Record[-1])
608 if Record[1] in [None, '']:
609 EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
610 File=self.MetaFile, Line=Record[-1])
611 Pattern = re.compile('^[1-9]\d*|0$')
612 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
613 if Pattern.match(Record[0]) == None and HexPattern.match(Record[0]) == None:
614 EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
615 File=self.MetaFile, Line=Record[-1])
616 if not IsValidWord(Record[1]):
617 EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
618 File=self.MetaFile, Line=Record[-1])
619 self.DefaultStores[Record[1].upper()] = (self.ToInt(Record[0]),Record[1].upper())
620 if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
621 self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT)
622 GlobalData.gDefaultStores = self.DefaultStores.keys()
623 if GlobalData.gDefaultStores:
624 GlobalData.gDefaultStores.sort()
625 return self.DefaultStores
626
627 ## Retrieve [Components] section information
628 def _GetModules(self):
629 if self._Modules != None:
630 return self._Modules
631
632 self._Modules = sdict()
633 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
634 Macros = self._Macros
635 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
636 for Record in RecordList:
637 DuplicatedFile = False
638
639 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
640 ModuleId = Record[6]
641 LineNo = Record[7]
642
643 # check the file validation
644 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
645 if ErrorCode != 0:
646 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
647 ExtraData=ErrorInfo)
648 # Check duplication
649 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
650 if self._Arch != 'COMMON' and ModuleFile in self._Modules:
651 DuplicatedFile = True
652
653 Module = ModuleBuildClassObject()
654 Module.MetaFile = ModuleFile
655
656 # get module private library instance
657 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
658 for Record in RecordList:
659 LibraryClass = Record[0]
660 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
661 LineNo = Record[-1]
662
663 # check the file validation
664 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
665 if ErrorCode != 0:
666 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
667 ExtraData=ErrorInfo)
668
669 if LibraryClass == '' or LibraryClass == 'NULL':
670 self._NullLibraryNumber += 1
671 LibraryClass = 'NULL%d' % self._NullLibraryNumber
672 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
673 Module.LibraryClasses[LibraryClass] = LibraryPath
674 if LibraryPath not in self.LibraryInstances:
675 self.LibraryInstances.append(LibraryPath)
676
677 # get module private PCD setting
678 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
679 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
680 RecordList = self._RawData[Type, self._Arch, None, ModuleId]
681 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
682 TokenList = GetSplitValueList(Setting)
683 DefaultValue = TokenList[0]
684 if len(TokenList) > 1:
685 MaxDatumSize = TokenList[1]
686 else:
687 MaxDatumSize = ''
688 TypeString = self._PCD_TYPE_STRING_[Type]
689 Pcd = PcdClassObject(
690 PcdCName,
691 TokenSpaceGuid,
692 TypeString,
693 '',
694 DefaultValue,
695 '',
696 MaxDatumSize,
697 {},
698 False,
699 None
700 )
701 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
702
703 # get module private build options
704 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
705 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
706 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
707 Module.BuildOptions[ToolChainFamily, ToolChain] = Option
708 else:
709 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
710 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
711
712 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
713 if DuplicatedFile and not RecordList:
714 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
715 if RecordList:
716 if len(RecordList) != 1:
717 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
718 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
719 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
720 ModuleFile.Arch = self._Arch
721
722 self._Modules[ModuleFile] = Module
723 return self._Modules
724
725 ## Retrieve all possible library instances used in this platform
726 def _GetLibraryInstances(self):
727 if self._LibraryInstances == None:
728 self._GetLibraryClasses()
729 return self._LibraryInstances
730
731 ## Retrieve [LibraryClasses] information
732 def _GetLibraryClasses(self):
733 if self._LibraryClasses == None:
734 self._LibraryInstances = []
735 #
736 # tdict is a special dict kind of type, used for selecting correct
737 # library instance for given library class and module type
738 #
739 LibraryClassDict = tdict(True, 3)
740 # track all library class names
741 LibraryClassSet = set()
742 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
743 Macros = self._Macros
744 for Record in RecordList:
745 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record
746 if LibraryClass == '' or LibraryClass == 'NULL':
747 self._NullLibraryNumber += 1
748 LibraryClass = 'NULL%d' % self._NullLibraryNumber
749 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
750 LibraryClassSet.add(LibraryClass)
751 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
752 # check the file validation
753 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
754 if ErrorCode != 0:
755 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
756 ExtraData=ErrorInfo)
757
758 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:
759 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
760 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
761 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
762 if LibraryInstance not in self._LibraryInstances:
763 self._LibraryInstances.append(LibraryInstance)
764
765 # resolve the specific library instance for each class and each module type
766 self._LibraryClasses = tdict(True)
767 for LibraryClass in LibraryClassSet:
768 # try all possible module types
769 for ModuleType in SUP_MODULE_LIST:
770 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
771 if LibraryInstance == None:
772 continue
773 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
774
775 # for Edk style library instances, which are listed in different section
776 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
777 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
778 for Record in RecordList:
779 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
780 LineNo = Record[-1]
781 # check the file validation
782 ErrorCode, ErrorInfo = File.Validate('.inf')
783 if ErrorCode != 0:
784 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
785 ExtraData=ErrorInfo)
786 if File not in self._LibraryInstances:
787 self._LibraryInstances.append(File)
788 #
789 # we need the module name as the library class name, so we have
790 # to parse it here. (self._Bdb[] will trigger a file parse if it
791 # hasn't been parsed)
792 #
793 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
794 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
795 return self._LibraryClasses
796
797 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
798 if self._DecPcds == None:
799
800 FdfInfList = []
801 if GlobalData.gFdfParser:
802 FdfInfList = GlobalData.gFdfParser.Profile.InfList
803
804 PkgSet = set()
805 for Inf in FdfInfList:
806 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
807 if ModuleFile in self._Modules:
808 continue
809 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
810 PkgSet.update(ModuleData.Packages)
811
812 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
813
814
815 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
816 EdkLogger.error('build', PARSER_ERROR,
817 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
818 File=self.MetaFile, Line=LineNo)
819 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
820 if not IsValid:
821 if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
822 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
823 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
824 else:
825 if ValueList[2] == '-1':
826 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
827 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
828 if ValueList[Index]:
829 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
830 try:
831 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
832 except BadExpression, Value:
833 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
834 ExtraData="PCD [%s.%s] Value \"%s\" " % (
835 TokenSpaceGuid, PcdCName, ValueList[Index]))
836 except EvaluationException, Excpt:
837 if hasattr(Excpt, 'Pcd'):
838 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
839 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
840 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
841 " of the DSC file" % Excpt.Pcd,
842 File=self.MetaFile, Line=LineNo)
843 else:
844 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
845 File=self.MetaFile, Line=LineNo)
846 else:
847 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
848 File=self.MetaFile, Line=LineNo)
849
850 if ValueList[Index]:
851 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
852 if not Valid:
853 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
854 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
855 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
856 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
857 EdkLogger.error('build', FORMAT_INVALID, ErrStr , File=self.MetaFile, Line=LineNo,
858 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
859 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
860 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
861 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
862 return ValueList
863
864 def _FilterPcdBySkuUsage(self,Pcds):
865 available_sku = self.SkuIdMgr.AvailableSkuIdSet
866 sku_usage = self.SkuIdMgr.SkuUsageType
867 if sku_usage == SkuClass.SINGLE:
868 for pcdname in Pcds:
869 pcd = Pcds[pcdname]
870 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
871 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:
872 Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
873 else:
874 for pcdname in Pcds:
875 pcd = Pcds[pcdname]
876 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
877 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:
878 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
879 return Pcds
880 def CompleteHiiPcdsDefaultStores(self,Pcds):
881 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]]]
882 DefaultStoreMgr = DefaultStore(self.DefaultStores)
883 for pcd in HiiPcd:
884 for skuid in pcd.SkuInfoList:
885 skuobj = pcd.SkuInfoList.get(skuid)
886 if "STANDARD" not in skuobj.DefaultStoreDict:
887 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])
888 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
889 skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
890 return Pcds
891
892 ## Retrieve all PCD settings in platform
893 def _GetPcds(self):
894 if self._Pcds == None:
895 self._Pcds = sdict()
896 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
897 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
898 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
899 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
900 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
901 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
902 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
903 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
904 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
905
906 self._Pcds = self.CompletePcdValues(self._Pcds)
907 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
908 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
909 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
910 return self._Pcds
911
912 def _dumpPcdInfo(self,Pcds):
913 for pcd in Pcds:
914 pcdobj = Pcds[pcd]
915 if not pcdobj.TokenCName.startswith("Test"):
916 continue
917 for skuid in pcdobj.SkuInfoList:
918 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):
919 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:
920 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))
921 else:
922 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))
923 ## Retrieve [BuildOptions]
924 def _GetBuildOptions(self):
925 if self._BuildOptions == None:
926 self._BuildOptions = sdict()
927 #
928 # Retrieve build option for EDKII and EDK style module
929 #
930 for CodeBase in (EDKII_NAME, EDK_NAME):
931 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
932 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
933 if Dummy3.upper() != 'COMMON':
934 continue
935 CurKey = (ToolChainFamily, ToolChain, CodeBase)
936 #
937 # Only flags can be appended
938 #
939 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
940 self._BuildOptions[CurKey] = Option
941 else:
942 if ' ' + Option not in self._BuildOptions[CurKey]:
943 self._BuildOptions[CurKey] += ' ' + Option
944 return self._BuildOptions
945
946 def GetBuildOptionsByModuleType(self, Edk, ModuleType):
947 if self._ModuleTypeOptions == None:
948 self._ModuleTypeOptions = sdict()
949 if (Edk, ModuleType) not in self._ModuleTypeOptions:
950 options = sdict()
951 self._ModuleTypeOptions[Edk, ModuleType] = options
952 DriverType = '%s.%s' % (Edk, ModuleType)
953 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
954 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
955 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
956 Type = Dummy2 + '.' + Dummy3
957 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
958 Key = (ToolChainFamily, ToolChain, Edk)
959 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
960 options[Key] = Option
961 else:
962 if ' ' + Option not in options[Key]:
963 options[Key] += ' ' + Option
964 return self._ModuleTypeOptions[Edk, ModuleType]
965
966 def GetStructurePcdInfo(self, PcdSet):
967 structure_pcd_data = {}
968 for item in PcdSet:
969 if (item[0],item[1]) not in structure_pcd_data:
970 structure_pcd_data[(item[0],item[1])] = []
971 structure_pcd_data[(item[0],item[1])].append(item)
972
973 return structure_pcd_data
974
975 def UpdateStructuredPcds(self, TypeList, AllPcds):
976
977 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
978 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
979 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
980 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
981 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
982 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
983
984 Pcds = AllPcds
985 DefaultStoreMgr = DefaultStore(self.DefaultStores)
986 SkuIds = self.SkuIdMgr.AvailableSkuIdSet
987 SkuIds.update({'DEFAULT':0})
988 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
989
990 S_PcdSet = []
991 # Find out all possible PCD candidates for self._Arch
992 RecordList = []
993
994 for Type in TypeList:
995 RecordList.extend(self._RawData[Type, self._Arch])
996
997 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:
998 SkuName = SkuName.upper()
999 default_store = default_store.upper()
1000 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1001 if SkuName not in SkuIds:
1002 continue
1003
1004 if SkuName in SkuIds and "." in TokenSpaceGuid:
1005 S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]))
1006
1007 # handle pcd value override
1008 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)
1009 S_pcd_set = {}
1010 for str_pcd in StrPcdSet:
1011 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1012 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1013 if str_pcd_dec:
1014 str_pcd_obj_str = StructurePcd()
1015 str_pcd_obj_str.copy(str_pcd_dec)
1016 if str_pcd_obj:
1017 str_pcd_obj_str.copy(str_pcd_obj)
1018 if str_pcd_obj.DefaultValue:
1019 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue
1020 for str_pcd_data in StrPcdSet[str_pcd]:
1021 if str_pcd_data[3] in SkuIds:
1022 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])
1023 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1024 else:
1025 EdkLogger.error('build', PARSER_ERROR,
1026 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1027 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
1028 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1029 for Pcd in self.DecPcds:
1030 if type (self._DecPcds[Pcd]) is StructurePcd:
1031 if Pcd not in S_pcd_set:
1032 str_pcd_obj_str = StructurePcd()
1033 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1034 str_pcd_obj = Pcds.get(Pcd, None)
1035 if str_pcd_obj:
1036 str_pcd_obj_str.copy(str_pcd_obj)
1037 if str_pcd_obj.DefaultValue:
1038 str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue
1039 S_pcd_set[Pcd] = str_pcd_obj_str
1040 if S_pcd_set:
1041 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1042 for stru_pcd in S_pcd_set.values():
1043 for skuid in SkuIds:
1044 if skuid in stru_pcd.SkuOverrideValues:
1045 continue
1046 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1047 NoDefault = False
1048 while nextskuid not in stru_pcd.SkuOverrideValues:
1049 if nextskuid == "DEFAULT":
1050 NoDefault = True
1051 break
1052 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1053 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})
1054 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1055 for skuid in SkuIds:
1056 nextskuid = skuid
1057 NoDefault = False
1058 if skuid not in stru_pcd.SkuOverrideValues:
1059 while nextskuid not in stru_pcd.SkuOverrideValues:
1060 if nextskuid == "DEFAULT":
1061 NoDefault = True
1062 break
1063 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1064 if NoDefault:
1065 continue
1066 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])
1067 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1068
1069 for defaultstoreid in DefaultStores:
1070 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1071 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1072
1073 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1074 if Str_Pcd_Values:
1075 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:
1076 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1077 if str_pcd_obj is None:
1078 print PcdName, PcdGuid
1079 raise
1080 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1081 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1082 if skuname not in str_pcd_obj.SkuInfoList:
1083 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1084 else:
1085 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1086 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1087 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1088 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1089 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1090 str_pcd_obj.DefaultValue = PcdValue
1091 else:
1092 if skuname not in str_pcd_obj.SkuInfoList:
1093 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1094 NoDefault = False
1095 while nextskuid not in str_pcd_obj.SkuInfoList:
1096 if nextskuid == "DEFAULT":
1097 NoDefault = True
1098 break
1099 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1100 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)
1101 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1102 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1103 else:
1104 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1105 for str_pcd_obj in S_pcd_set.values():
1106 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1107 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1108 continue
1109 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])
1110 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1111 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1112 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1113
1114 for str_pcd_obj in S_pcd_set.values():
1115
1116 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1117 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1118
1119 for pcdkey in Pcds:
1120 pcd = Pcds[pcdkey]
1121 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1122 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
1123 del(pcd.SkuInfoList['COMMON'])
1124 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1125 del(pcd.SkuInfoList['COMMON'])
1126
1127 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1128 return Pcds
1129
1130 ## Retrieve non-dynamic PCD settings
1131 #
1132 # @param Type PCD type
1133 #
1134 # @retval a dict object contains settings of given PCD type
1135 #
1136 def _GetPcd(self, Type):
1137 Pcds = sdict()
1138 #
1139 # tdict is a special dict kind of type, used for selecting correct
1140 # PCD settings for certain ARCH
1141 #
1142 AvailableSkuIdSet = copy.copy(self.SkuIds)
1143
1144 PcdDict = tdict(True, 3)
1145 PcdSet = set()
1146 # Find out all possible PCD candidates for self._Arch
1147 RecordList = self._RawData[Type, self._Arch]
1148 PcdValueDict = sdict()
1149 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
1150 SkuName = SkuName.upper()
1151 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1152 if SkuName not in AvailableSkuIdSet:
1153 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1154 File=self.MetaFile, Line=Dummy5)
1155 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1156 if "." not in TokenSpaceGuid:
1157 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
1158 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1159
1160 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1161 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1162 if Setting == None:
1163 continue
1164 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1165 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1166 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1167 else:
1168 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1169
1170 PcdsKeys = PcdValueDict.keys()
1171 for PcdCName, TokenSpaceGuid in PcdsKeys:
1172
1173 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
1174 PcdValue = None
1175 DatumType = None
1176 MaxDatumSize = None
1177 if 'COMMON' in PcdSetting:
1178 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']
1179 if 'DEFAULT' in PcdSetting:
1180 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']
1181 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1182 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1183
1184 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1185 PcdCName,
1186 TokenSpaceGuid,
1187 self._PCD_TYPE_STRING_[Type],
1188 DatumType,
1189 PcdValue,
1190 '',
1191 MaxDatumSize,
1192 {},
1193 False,
1194 None,
1195 IsDsc=True)
1196
1197
1198 return Pcds
1199
1200 def __UNICODE2OCTList(self,Value):
1201 Value = Value.strip()
1202 Value = Value[2:-1]
1203 List = []
1204 for Item in Value:
1205 Temp = '%04X' % ord(Item)
1206 List.append('0x' + Temp[2:4])
1207 List.append('0x' + Temp[0:2])
1208 List.append('0x00')
1209 List.append('0x00')
1210 return List
1211 def __STRING2OCTList(self,Value):
1212 OCTList = []
1213 Value = Value.strip('"')
1214 for char in Value:
1215 Temp = '%02X' % ord(char)
1216 OCTList.append('0x' + Temp)
1217 OCTList.append('0x00')
1218 return OCTList
1219
1220 def GetStructurePcdMaxSize(self, str_pcd):
1221 pcd_default_value = str_pcd.DefaultValue
1222 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()]
1223 sku_values.append(pcd_default_value)
1224
1225 def get_length(value):
1226 Value = value.strip()
1227 if len(value) > 1:
1228 if Value.startswith('GUID') and Value.endswith(')'):
1229 return 16
1230 if Value.startswith('L"') and Value.endswith('"'):
1231 return len(Value[2:-1])
1232 if Value[0] == '"' and Value[-1] == '"':
1233 return len(Value) - 2
1234 if Value[0] == '{' and Value[-1] == '}':
1235 return len(Value.split(","))
1236 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1237 return len(list(Value[2:-1]))
1238 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1239 return len(Value) - 2
1240 return len(Value)
1241
1242 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
1243
1244 def IsFieldValueAnArray (self, Value):
1245 Value = Value.strip()
1246 if Value.startswith('GUID') and Value.endswith(')'):
1247 return True
1248 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
1249 return True
1250 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
1251 return True
1252 if Value[0] == '{' and Value[-1] == '}':
1253 return True
1254 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1255 print 'foo = ', list(Value[2:-1])
1256 return True
1257 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1258 print 'bar = ', list(Value[1:-1])
1259 return True
1260 return False
1261
1262 def ExecuteCommand (self, Command):
1263 try:
1264 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1265 except:
1266 print 'ERROR: Can not execute command:', Command
1267 sys.exit(1)
1268 Result = Process.communicate()
1269 if Process.returncode <> 0:
1270 print 'ERROR: Can not collect output from command:', Command
1271 return Result[0], Result[1]
1272
1273 def IntToCString(self, Value, ValueSize):
1274 Result = '"'
1275 if not isinstance (Value, str):
1276 for Index in range(0, ValueSize):
1277 Result = Result + '\\x%02x' % (Value & 0xff)
1278 Value = Value >> 8
1279 Result = Result + '"'
1280 return Result
1281
1282 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):
1283 OverrideValues = {DefaultStoreName:""}
1284 if Pcd.SkuOverrideValues:
1285 OverrideValues = Pcd.SkuOverrideValues[SkuName]
1286 for DefaultStoreName in OverrideValues.keys():
1287 CApp = CApp + 'void\n'
1288 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1289 CApp = CApp + ' void\n'
1290 CApp = CApp + ' )\n'
1291 CApp = CApp + '{\n'
1292 CApp = CApp + ' UINT32 Size;\n'
1293 CApp = CApp + ' UINT32 FieldSize;\n'
1294 CApp = CApp + ' CHAR8 *Value;\n'
1295 CApp = CApp + ' UINT32 OriginalSize;\n'
1296 CApp = CApp + ' VOID *OriginalPcd;\n'
1297 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
1298 CApp = CApp + '\n'
1299
1300 if SkuName in Pcd.SkuInfoList:
1301 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue
1302 else:
1303 DefaultValue = Pcd.DefaultValue
1304 PcdDefaultValue = StringToArray(DefaultValue.strip())
1305
1306 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
1307
1308 #
1309 # Get current PCD value and size
1310 #
1311 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1312
1313 #
1314 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1315 # the correct value. For structures with a flexible array member, the flexible
1316 # array member is detected, and the size is based on the highest index used with
1317 # the flexible array member. The flexible array member must be the last field
1318 # in a structure. The size formula for this case is:
1319 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1320 #
1321 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1322 for FieldList in [Pcd.DefaultValues]:
1323 if not FieldList:
1324 continue
1325 for FieldName in FieldList:
1326 FieldName = "." + FieldName
1327 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1328 if IsArray:
1329 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])
1330 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
1331 else:
1332 NewFieldName = ''
1333 FieldName_ori = FieldName.strip('.')
1334 while '[' in FieldName:
1335 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1336 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1337 FieldName = FieldName.split(']', 1)[1]
1338 FieldName = NewFieldName + FieldName
1339 while '[' in FieldName:
1340 FieldName = FieldName.rsplit('[', 1)[0]
1341 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1342 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
1343 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
1344 for FieldList in [inherit_OverrideValues.get(DefaultStoreName)]:
1345 if not FieldList:
1346 continue
1347 for FieldName in FieldList:
1348 FieldName = "." + FieldName
1349 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1350 if IsArray:
1351 Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])
1352 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
1353 else:
1354 NewFieldName = ''
1355 FieldName_ori = FieldName.strip('.')
1356 while '[' in FieldName:
1357 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1358 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1359 FieldName = FieldName.split(']', 1)[1]
1360 FieldName = NewFieldName + FieldName
1361 while '[' in FieldName:
1362 FieldName = FieldName.rsplit('[', 1)[0]
1363 CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1364 if skuname == SkuName:
1365 break
1366
1367 #
1368 # Allocate and zero buffer for the PCD
1369 # Must handle cases where current value is smaller, larger, or same size
1370 # Always keep that larger one as the current size
1371 #
1372 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1373 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
1374 CApp = CApp + ' memset (Pcd, 0, Size);\n'
1375
1376 #
1377 # Copy current PCD value into allocated buffer.
1378 #
1379 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1380
1381 #
1382 # Assign field values in PCD
1383 #
1384 for FieldList in [Pcd.DefaultValues]:
1385 if not FieldList:
1386 continue
1387 for FieldName in FieldList:
1388 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
1389 try:
1390 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1391 except Exception:
1392 print FieldList[FieldName][0]
1393 if isinstance(Value, str):
1394 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1395 elif IsArray:
1396 #
1397 # Use memcpy() to copy value into field
1398 #
1399 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1400 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1401 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1402 else:
1403 if ValueSize > 4:
1404 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1405 else:
1406 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1407 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
1408 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
1409 for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(DefaultStoreName)]:
1410 if not FieldList:
1411 continue
1412 if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:
1413 IsArray = self.IsFieldValueAnArray(FieldList)
1414 Value, ValueSize = ParseFieldValue (FieldList)
1415 if isinstance(Value, str):
1416 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)
1417 elif IsArray:
1418 #
1419 # Use memcpy() to copy value into field
1420 #
1421 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)
1422 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1423 continue
1424
1425 for FieldName in FieldList:
1426 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
1427 try:
1428 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1429 except Exception:
1430 print FieldList[FieldName][0]
1431 if isinstance(Value, str):
1432 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1433 elif IsArray:
1434 #
1435 # Use memcpy() to copy value into field
1436 #
1437 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1438 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1439 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1440 else:
1441 if ValueSize > 4:
1442 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1443 else:
1444 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1445 if skuname == SkuName:
1446 break
1447 #
1448 # Set new PCD value and size
1449 #
1450 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1451
1452 #
1453 # Free PCD
1454 #
1455 CApp = CApp + ' free (Pcd);\n'
1456 CApp = CApp + '}\n'
1457 CApp = CApp + '\n'
1458 return InitByteValue, CApp
1459
1460 def GenerateByteArrayValue (self, StructuredPcds):
1461 #
1462 # Generate/Compile/Run C application to determine if there are any flexible array members
1463 #
1464 if not StructuredPcds:
1465 return
1466
1467 InitByteValue = ""
1468 CApp = PcdMainCHeader
1469
1470 Includes = {}
1471 for PcdName in StructuredPcds:
1472 Pcd = StructuredPcds[PcdName]
1473 IncludeFile = Pcd.StructuredPcdIncludeFile
1474 if IncludeFile not in Includes:
1475 Includes[IncludeFile] = True
1476 CApp = CApp + '#include <%s>\n' % (IncludeFile)
1477 CApp = CApp + '\n'
1478
1479 for PcdName in StructuredPcds:
1480 Pcd = StructuredPcds[PcdName]
1481 if not Pcd.SkuOverrideValues:
1482 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)
1483 else:
1484 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
1485 if SkuName not in Pcd.SkuOverrideValues:
1486 continue
1487 for DefaultStoreName in Pcd.DefaultStoreName:
1488 Pcd = StructuredPcds[PcdName]
1489 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
1490
1491 CApp = CApp + 'VOID\n'
1492 CApp = CApp + 'PcdEntryPoint(\n'
1493 CApp = CApp + ' VOID\n'
1494 CApp = CApp + ' )\n'
1495 CApp = CApp + '{\n'
1496 for Pcd in StructuredPcds.values():
1497 if not Pcd.SkuOverrideValues:
1498 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1499 else:
1500 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
1501 if SkuName not in Pcd.SkuOverrideValues:
1502 continue
1503 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
1504 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1505 CApp = CApp + '}\n'
1506
1507 CApp = CApp + PcdMainCEntry + '\n'
1508
1509 if not os.path.exists(self.OutputPath):
1510 os.makedirs(self.OutputPath)
1511 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
1512 File = open (CAppBaseFileName + '.c', 'w')
1513 File.write(CApp)
1514 File.close()
1515
1516 MakeApp = PcdMakefileHeader
1517 if sys.platform == "win32":
1518 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
1519 else:
1520 MakeApp = MakeApp + PcdGccMakefile
1521 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
1522 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1523
1524 PlatformInc = {}
1525 for Cache in self._Bdb._CACHE_.values():
1526 if Cache.MetaFile.Ext.lower() != '.dec':
1527 continue
1528 if Cache.Includes:
1529 if str(Cache.MetaFile.Path) not in PlatformInc:
1530 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes
1531
1532 PcdDependDEC = []
1533 for Pcd in StructuredPcds.values():
1534 for PackageDec in Pcd.PackageDecs:
1535 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
1536 if not os.path.exists(Package):
1537 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
1538 if Package not in PcdDependDEC:
1539 PcdDependDEC.append(Package)
1540
1541 if PlatformInc and PcdDependDEC:
1542 for pkg in PcdDependDEC:
1543 if pkg in PlatformInc:
1544 for inc in PlatformInc[pkg]:
1545 MakeApp += '-I' + str(inc) + ' '
1546 MakeApp = MakeApp + '\n'
1547
1548 CC_FLAGS = LinuxCFLAGS
1549 if sys.platform == "win32":
1550 CC_FLAGS = WindowsCFLAGS
1551 BuildOptions = {}
1552 for Options in self.BuildOptions:
1553 if Options[2] != EDKII_NAME:
1554 continue
1555 Family = Options[0]
1556 if Family and Family != self.ToolChainFamily:
1557 continue
1558 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
1559 if Tool != 'CC':
1560 continue
1561
1562 if Target == "*" or Target == self._Target:
1563 if Tag == "*" or Tag == self._Toolchain:
1564 if Arch == "*" or Arch == self.Arch:
1565 if Tool not in BuildOptions:
1566 BuildOptions[Tool] = {}
1567 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
1568 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
1569 else:
1570 # append options for the same tool except PATH
1571 if Attr != 'PATH':
1572 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
1573 else:
1574 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
1575 if BuildOptions:
1576 for Tool in BuildOptions:
1577 for Attr in BuildOptions[Tool]:
1578 if Attr == "FLAGS":
1579 Value = BuildOptions[Tool][Attr]
1580 ValueList = Value.split()
1581 if ValueList:
1582 for Id, Item in enumerate(ValueList):
1583 if Item == '-D' or Item == '/D':
1584 CC_FLAGS += ' ' + Item
1585 if Id + 1 < len(ValueList):
1586 CC_FLAGS += ' ' + ValueList[Id + 1]
1587 elif Item.startswith('/D') or Item.startswith('-D'):
1588 CC_FLAGS += ' ' + Item
1589 MakeApp += CC_FLAGS
1590
1591 if sys.platform == "win32":
1592 MakeApp = MakeApp + PcdMakefileEnd
1593 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
1594 File = open (MakeFileName, 'w')
1595 File.write(MakeApp)
1596 File.close()
1597
1598 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
1599 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
1600 File = open (InputValueFile, 'w')
1601 File.write(InitByteValue)
1602 File.close()
1603
1604 Messages = ''
1605 if sys.platform == "win32":
1606 StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))
1607 Messages = StdOut
1608 else:
1609 StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))
1610 Messages = StdErr
1611 Messages = Messages.split('\n')
1612 for Message in Messages:
1613 if " error" in Message:
1614 FileInfo = Message.strip().split('(')
1615 if len (FileInfo) > 1:
1616 FileName = FileInfo [0]
1617 FileLine = FileInfo [1].split (')')[0]
1618 else:
1619 FileInfo = Message.strip().split(':')
1620 FileName = FileInfo [0]
1621 FileLine = FileInfo [1]
1622
1623 File = open (FileName, 'r')
1624 FileData = File.readlines()
1625 File.close()
1626 error_line = FileData[int (FileLine) - 1]
1627 if r"//" in error_line:
1628 c_line,dsc_line = error_line.split(r"//")
1629 else:
1630 dsc_line = error_line
1631
1632 message_itmes = Message.split(":")
1633 Index = 0
1634 for item in message_itmes:
1635 if "PcdValueInit.c" in item:
1636 Index = message_itmes.index(item)
1637 message_itmes[Index] = dsc_line.strip()
1638 break
1639
1640 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[Index:]))
1641
1642 PcdValueInitExe = PcdValueInitName
1643 if not sys.platform == "win32":
1644 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
1645
1646 StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))
1647 File = open (OutputValueFile, 'r')
1648 FileBuffer = File.readlines()
1649 File.close()
1650
1651 StructurePcdSet = []
1652 for Pcd in FileBuffer:
1653 PcdValue = Pcd.split ('|')
1654 PcdInfo = PcdValue[0].split ('.')
1655 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
1656 return StructurePcdSet
1657
1658 ## Retrieve dynamic PCD settings
1659 #
1660 # @param Type PCD type
1661 #
1662 # @retval a dict object contains settings of given PCD type
1663 #
1664 def _GetDynamicPcd(self, Type):
1665
1666
1667 Pcds = sdict()
1668 #
1669 # tdict is a special dict kind of type, used for selecting correct
1670 # PCD settings for certain ARCH and SKU
1671 #
1672 PcdDict = tdict(True, 4)
1673 PcdList = []
1674 # Find out all possible PCD candidates for self._Arch
1675 RecordList = self._RawData[Type, self._Arch]
1676 AvailableSkuIdSet = copy.copy(self.SkuIds)
1677
1678
1679 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
1680 SkuName = SkuName.upper()
1681 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1682 if SkuName not in AvailableSkuIdSet:
1683 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1684 File=self.MetaFile, Line=Dummy5)
1685 if "." not in TokenSpaceGuid:
1686 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
1687 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
1688
1689 # Remove redundant PCD candidates, per the ARCH and SKU
1690 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
1691
1692 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
1693 if Setting == None:
1694 continue
1695
1696 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1697 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
1698 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
1699 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
1700 pcdObject.SkuInfoList[SkuName] = SkuInfo
1701 if MaxDatumSize.strip():
1702 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
1703 else:
1704 CurrentMaxSize = 0
1705 if pcdObject.MaxDatumSize:
1706 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
1707 else:
1708 PcdMaxSize = 0
1709 if CurrentMaxSize > PcdMaxSize:
1710 pcdObject.MaxDatumSize = str(CurrentMaxSize)
1711 else:
1712 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1713 PcdCName,
1714 TokenSpaceGuid,
1715 self._PCD_TYPE_STRING_[Type],
1716 DatumType,
1717 PcdValue,
1718 '',
1719 MaxDatumSize,
1720 {SkuName : SkuInfo},
1721 False,
1722 None,
1723 IsDsc=True)
1724
1725 for pcd in Pcds.values():
1726 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
1727 # Only fix the value while no value provided in DSC file.
1728 for sku in pcd.SkuInfoList.values():
1729 if (sku.DefaultValue == "" or sku.DefaultValue==None):
1730 sku.DefaultValue = pcdDecObject.DefaultValue
1731 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
1732 valuefromDec = pcdDecObject.DefaultValue
1733 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
1734 pcd.SkuInfoList['DEFAULT'] = SkuInfo
1735 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1736 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
1737 del(pcd.SkuInfoList['COMMON'])
1738 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1739 del(pcd.SkuInfoList['COMMON'])
1740
1741 map(self.FilterSkuSettings,Pcds.values())
1742
1743 return Pcds
1744
1745 def FilterSkuSettings(self, PcdObj):
1746
1747 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
1748 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():
1749 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']
1750 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
1751 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'
1752 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'
1753
1754 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
1755 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}
1756
1757 return PcdObj
1758
1759
1760 def CompareVarAttr(self, Attr1, Attr2):
1761 if not Attr1 or not Attr2: # for empty string
1762 return True
1763 Attr1s = [attr.strip() for attr in Attr1.split(",")]
1764 Attr1Set = set(Attr1s)
1765 Attr2s = [attr.strip() for attr in Attr2.split(",")]
1766 Attr2Set = set(Attr2s)
1767 if Attr2Set == Attr1Set:
1768 return True
1769 else:
1770 return False
1771 def CompletePcdValues(self,PcdSet):
1772 Pcds = {}
1773 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1774 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}
1775 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
1776 for PcdCName, TokenSpaceGuid in PcdSet:
1777 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
1778 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1779 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1780 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1781 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1782 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1783 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
1784 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
1785 continue
1786 PcdType = PcdObj.Type
1787 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1788 for skuid in PcdObj.SkuInfoList:
1789 skuobj = PcdObj.SkuInfoList[skuid]
1790 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))
1791 for defaultstorename in DefaultStores:
1792 if defaultstorename not in skuobj.DefaultStoreDict:
1793 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
1794 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
1795 for skuname,skuid in SkuIds.items():
1796 if skuname not in PcdObj.SkuInfoList:
1797 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1798 while nextskuid not in PcdObj.SkuInfoList:
1799 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1800 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
1801 PcdObj.SkuInfoList[skuname].SkuId = skuid
1802 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
1803 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1804 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue
1805 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
1806 return Pcds
1807 ## Retrieve dynamic HII PCD settings
1808 #
1809 # @param Type PCD type
1810 #
1811 # @retval a dict object contains settings of given PCD type
1812 #
1813 def _GetDynamicHiiPcd(self, Type):
1814
1815 VariableAttrs = {}
1816
1817 Pcds = sdict()
1818 #
1819 # tdict is a special dict kind of type, used for selecting correct
1820 # PCD settings for certain ARCH and SKU
1821 #
1822 PcdDict = tdict(True, 5)
1823 PcdSet = set()
1824 RecordList = self._RawData[Type, self._Arch]
1825 # Find out all possible PCD candidates for self._Arch
1826 AvailableSkuIdSet = copy.copy(self.SkuIds)
1827 DefaultStoresDefine = self._GetDefaultStores()
1828
1829 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:
1830 SkuName = SkuName.upper()
1831 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1832 DefaultStore = DefaultStore.upper()
1833 if DefaultStore == "COMMON":
1834 DefaultStore = "STANDARD"
1835 if SkuName not in AvailableSkuIdSet:
1836 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1837 File=self.MetaFile, Line=Dummy5)
1838 if DefaultStore not in DefaultStoresDefine:
1839 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
1840 File=self.MetaFile, Line=Dummy5)
1841 if "." not in TokenSpaceGuid:
1842 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4))
1843 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting
1844
1845
1846 # Remove redundant PCD candidates, per the ARCH and SKU
1847 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:
1848
1849 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]
1850 if Setting == None:
1851 continue
1852 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1853
1854 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
1855 if not rt:
1856 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
1857 ExtraData="[%s]" % VarAttribute)
1858 ExceedMax = False
1859 FormatCorrect = True
1860 if VariableOffset.isdigit():
1861 if int(VariableOffset, 10) > 0xFFFF:
1862 ExceedMax = True
1863 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):
1864 if int(VariableOffset, 16) > 0xFFFF:
1865 ExceedMax = True
1866 # For Offset written in "A.B"
1867 elif VariableOffset.find('.') > -1:
1868 VariableOffsetList = VariableOffset.split(".")
1869 if not (len(VariableOffsetList) == 2
1870 and IsValidWord(VariableOffsetList[0])
1871 and IsValidWord(VariableOffsetList[1])):
1872 FormatCorrect = False
1873 else:
1874 FormatCorrect = False
1875 if not FormatCorrect:
1876 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
1877
1878 if ExceedMax:
1879 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
1880 if (VariableName, VariableGuid) not in VariableAttrs:
1881 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
1882 else:
1883 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
1884 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)]))
1885
1886 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
1887 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
1888 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
1889 if SkuName in pcdObject.SkuInfoList:
1890 Skuitem = pcdObject.SkuInfoList[SkuName]
1891 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
1892 else:
1893 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
1894 pcdObject.SkuInfoList[SkuName] = SkuInfo
1895 else:
1896 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
1897 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1898 PcdCName,
1899 TokenSpaceGuid,
1900 self._PCD_TYPE_STRING_[Type],
1901 '',
1902 DefaultValue,
1903 '',
1904 '',
1905 {SkuName : SkuInfo},
1906 False,
1907 None,
1908 pcdDecObject.validateranges,
1909 pcdDecObject.validlists,
1910 pcdDecObject.expressions,
1911 IsDsc=True)
1912
1913
1914 for pcd in Pcds.values():
1915 SkuInfoObj = pcd.SkuInfoList.values()[0]
1916 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
1917 # Only fix the value while no value provided in DSC file.
1918 for sku in pcd.SkuInfoList.values():
1919 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):
1920 sku.HiiDefaultValue = pcdDecObject.DefaultValue
1921 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
1922 valuefromDec = pcdDecObject.DefaultValue
1923 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})
1924 pcd.SkuInfoList['DEFAULT'] = SkuInfo
1925 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1926 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
1927 del(pcd.SkuInfoList['COMMON'])
1928 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1929 del(pcd.SkuInfoList['COMMON'])
1930
1931 if pcd.MaxDatumSize.strip():
1932 MaxSize = int(pcd.MaxDatumSize, 0)
1933 else:
1934 MaxSize = 0
1935 if pcdDecObject.DatumType == 'VOID*':
1936 for (_, skuobj) in pcd.SkuInfoList.items():
1937 datalen = 0
1938 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
1939 datalen = len(skuobj.HiiDefaultValue.split(","))
1940 if datalen > MaxSize:
1941 MaxSize = datalen
1942 for defaultst in skuobj.DefaultStoreDict:
1943 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
1944 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
1945 pcd.MaxDatumSize = str(MaxSize)
1946 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)
1947 if not rt:
1948 invalidpcd = ",".join(invalidhii)
1949 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)
1950
1951 map(self.FilterSkuSettings,Pcds.values())
1952
1953 return Pcds
1954
1955 def CheckVariableNameAssignment(self,Pcds):
1956 invalidhii = []
1957 for pcdname in Pcds:
1958 pcd = Pcds[pcdname]
1959 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])
1960 if len(varnameset) > 1:
1961 invalidhii.append(".".join((pcdname[1],pcdname[0])))
1962 if len(invalidhii):
1963 return False,invalidhii
1964 else:
1965 return True, []
1966 ## Retrieve dynamic VPD PCD settings
1967 #
1968 # @param Type PCD type
1969 #
1970 # @retval a dict object contains settings of given PCD type
1971 #
1972 def _GetDynamicVpdPcd(self, Type):
1973
1974
1975 Pcds = sdict()
1976 #
1977 # tdict is a special dict kind of type, used for selecting correct
1978 # PCD settings for certain ARCH and SKU
1979 #
1980 PcdDict = tdict(True, 4)
1981 PcdList = []
1982
1983 # Find out all possible PCD candidates for self._Arch
1984 RecordList = self._RawData[Type, self._Arch]
1985 AvailableSkuIdSet = copy.copy(self.SkuIds)
1986
1987 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
1988 SkuName = SkuName.upper()
1989 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1990 if SkuName not in AvailableSkuIdSet:
1991 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1992 File=self.MetaFile, Line=Dummy5)
1993 if "." not in TokenSpaceGuid:
1994 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
1995 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
1996
1997 # Remove redundant PCD candidates, per the ARCH and SKU
1998 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
1999 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2000 if Setting == None:
2001 continue
2002 #
2003 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2004 # For the Integer & Boolean type, the optional data can only be InitialValue.
2005 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2006 # until the DEC parser has been called.
2007 #
2008 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2009 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2010 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2011 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2012 pcdObject.SkuInfoList[SkuName] = SkuInfo
2013 if MaxDatumSize.strip():
2014 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2015 else:
2016 CurrentMaxSize = 0
2017 if pcdObject.MaxDatumSize:
2018 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2019 else:
2020 PcdMaxSize = 0
2021 if CurrentMaxSize > PcdMaxSize:
2022 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2023 else:
2024 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2025 PcdCName,
2026 TokenSpaceGuid,
2027 self._PCD_TYPE_STRING_[Type],
2028 '',
2029 InitialValue,
2030 '',
2031 MaxDatumSize,
2032 {SkuName : SkuInfo},
2033 False,
2034 None,
2035 IsDsc=True)
2036 for pcd in Pcds.values():
2037 SkuInfoObj = pcd.SkuInfoList.values()[0]
2038 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2039 # Only fix the value while no value provided in DSC file.
2040 for sku in pcd.SkuInfoList.values():
2041 if (sku.DefaultValue == "" or sku.DefaultValue==None):
2042 sku.DefaultValue = pcdDecObject.DefaultValue
2043 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2044 valuefromDec = pcdDecObject.DefaultValue
2045 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2046 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2047 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2048 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2049 del(pcd.SkuInfoList['COMMON'])
2050 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2051 del(pcd.SkuInfoList['COMMON'])
2052
2053
2054 map(self.FilterSkuSettings,Pcds.values())
2055 return Pcds
2056
2057 ## Add external modules
2058 #
2059 # The external modules are mostly those listed in FDF file, which don't
2060 # need "build".
2061 #
2062 # @param FilePath The path of module description file
2063 #
2064 def AddModule(self, FilePath):
2065 FilePath = NormPath(FilePath)
2066 if FilePath not in self.Modules:
2067 Module = ModuleBuildClassObject()
2068 Module.MetaFile = FilePath
2069 self.Modules.append(Module)
2070
2071 def _GetToolChainFamily(self):
2072 self._ToolChainFamily = "MSFT"
2073 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2074 if os.path.isfile(BuildConfigurationFile) == True:
2075 TargetTxt = TargetTxtClassObject()
2076 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2077 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2078 if ToolDefinitionFile == '':
2079 ToolDefinitionFile = "tools_def.txt"
2080 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2081 if os.path.isfile(ToolDefinitionFile) == True:
2082 ToolDef = ToolDefClassObject()
2083 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2084 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2085 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2086 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2087 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2088 self._ToolChainFamily = "MSFT"
2089 else:
2090 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2091 return self._ToolChainFamily
2092
2093 ## Add external PCDs
2094 #
2095 # The external PCDs are mostly those listed in FDF file to specify address
2096 # or offset information.
2097 #
2098 # @param Name Name of the PCD
2099 # @param Guid Token space guid of the PCD
2100 # @param Value Value of the PCD
2101 #
2102 def AddPcd(self, Name, Guid, Value):
2103 if (Name, Guid) not in self.Pcds:
2104 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2105 self.Pcds[Name, Guid].DefaultValue = Value
2106 @property
2107 def DecPcds(self):
2108 if self._DecPcds == None:
2109 FdfInfList = []
2110 if GlobalData.gFdfParser:
2111 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2112 PkgSet = set()
2113 for Inf in FdfInfList:
2114 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2115 if ModuleFile in self._Modules:
2116 continue
2117 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2118 PkgSet.update(ModuleData.Packages)
2119 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
2120 return self._DecPcds
2121 _Macros = property(_GetMacros)
2122 Arch = property(_GetArch, _SetArch)
2123 Platform = property(_GetPlatformName)
2124 PlatformName = property(_GetPlatformName)
2125 Guid = property(_GetFileGuid)
2126 Version = property(_GetVersion)
2127 DscSpecification = property(_GetDscSpec)
2128 OutputDirectory = property(_GetOutpuDir)
2129 SupArchList = property(_GetSupArch)
2130 BuildTargets = property(_GetBuildTarget)
2131 SkuName = property(_GetSkuName, _SetSkuName)
2132 PcdInfoFlag = property(_GetPcdInfoFlag)
2133 VarCheckFlag = property(_GetVarCheckFlag)
2134 FlashDefinition = property(_GetFdfFile)
2135 Prebuild = property(_GetPrebuild)
2136 Postbuild = property(_GetPostbuild)
2137 BuildNumber = property(_GetBuildNumber)
2138 MakefileName = property(_GetMakefileName)
2139 BsBaseAddress = property(_GetBsBaseAddress)
2140 RtBaseAddress = property(_GetRtBaseAddress)
2141 LoadFixAddress = property(_GetLoadFixAddress)
2142 RFCLanguages = property(_GetRFCLanguages)
2143 ISOLanguages = property(_GetISOLanguages)
2144 VpdToolGuid = property(_GetVpdToolGuid)
2145 SkuIds = property(_GetSkuIds)
2146 Modules = property(_GetModules)
2147 LibraryInstances = property(_GetLibraryInstances)
2148 LibraryClasses = property(_GetLibraryClasses)
2149 Pcds = property(_GetPcds)
2150 BuildOptions = property(_GetBuildOptions)
2151 ToolChainFamily = property(_GetToolChainFamily)