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