]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Fix flexible PCD single quote and double quote bugs
[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 self._GuidDict.update(GlobalData.gPlatformPcds)
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 # Replace \' to ', \\\' to \'
995 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
996 for key in self.DecPcds:
997 PcdItem = self.DecPcds[key]
998 if HasTokenSpace:
999 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
1000 PcdDatumType = PcdItem.DatumType
1001 if pcdvalue.startswith('H'):
1002 try:
1003 pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
1004 except BadExpression, Value:
1005 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1006 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1007 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
1008 pcdvalue = 'H' + pcdvalue
1009 elif pcdvalue.startswith("L'"):
1010 try:
1011 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1012 except BadExpression, Value:
1013 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1014 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1015 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
1016 pcdvalue = 'H' + pcdvalue
1017 elif pcdvalue.startswith("'"):
1018 try:
1019 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1020 except BadExpression, Value:
1021 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1022 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1023 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
1024 pcdvalue = 'H' + pcdvalue
1025 elif pcdvalue.startswith('L'):
1026 pcdvalue = 'L"' + pcdvalue[1:] + '"'
1027 try:
1028 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1029 except BadExpression, Value:
1030 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1031 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1032 else:
1033 try:
1034 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1035 except BadExpression, Value:
1036 try:
1037 pcdvalue = '"' + pcdvalue + '"'
1038 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1039 except BadExpression, Value:
1040 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1041 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1042 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
1043 FoundFlag = True
1044 else:
1045 if PcdItem.TokenCName == TokenCName:
1046 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
1047 if len (TokenSpaceGuidCNameList) < 1:
1048 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
1049 PcdDatumType = PcdItem.DatumType
1050 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
1051 if pcdvalue.startswith('H'):
1052 try:
1053 pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
1054 except BadExpression, Value:
1055 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1056 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1057 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:
1058 pcdvalue = 'H' + pcdvalue
1059 elif pcdvalue.startswith("L'"):
1060 try:
1061 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
1062 True)
1063 except BadExpression, Value:
1064 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1065 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1066 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
1067 pcdvalue = 'H' + pcdvalue
1068 elif pcdvalue.startswith("'"):
1069 try:
1070 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
1071 True)
1072 except BadExpression, Value:
1073 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1074 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1075 if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']:
1076 pcdvalue = 'H' + pcdvalue
1077 elif pcdvalue.startswith('L'):
1078 pcdvalue = 'L"' + pcdvalue[1:] + '"'
1079 try:
1080 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(
1081 True)
1082 except BadExpression, Value:
1083 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1084 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1085 else:
1086 try:
1087 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1088 except BadExpression, Value:
1089 try:
1090 pcdvalue = '"' + pcdvalue + '"'
1091 pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True)
1092 except BadExpression, Value:
1093 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1094 (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
1095 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
1096 FoundFlag = True
1097 else:
1098 EdkLogger.error(
1099 'build',
1100 AUTOGEN_ERROR,
1101 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
1102 )
1103 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))
1104 if not FoundFlag:
1105 if HasTokenSpace:
1106 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
1107 else:
1108 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))
1109 for BuildData in self._Bdb._CACHE_.values():
1110 if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
1111 continue
1112 for key in BuildData.Pcds:
1113 PcdItem = BuildData.Pcds[key]
1114 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
1115 PcdItem.DefaultValue = NewValue
1116 ## Retrieve all PCD settings in platform
1117 def _GetPcds(self):
1118 if self._Pcds == None:
1119 self._Pcds = sdict()
1120 self.__ParsePcdFromCommandLine()
1121 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
1122 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
1123 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
1124 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
1125 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
1126 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
1127 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
1128 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
1129 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
1130
1131 self._Pcds = self.CompletePcdValues(self._Pcds)
1132 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
1133 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
1134 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
1135 self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)
1136 self.RecoverCommandLinePcd()
1137 return self._Pcds
1138
1139 def _dumpPcdInfo(self,Pcds):
1140 for pcd in Pcds:
1141 pcdobj = Pcds[pcd]
1142 if not pcdobj.TokenCName.startswith("Test"):
1143 continue
1144 for skuid in pcdobj.SkuInfoList:
1145 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):
1146 for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:
1147 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))
1148 else:
1149 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))
1150 ## Retrieve [BuildOptions]
1151 def _GetBuildOptions(self):
1152 if self._BuildOptions == None:
1153 self._BuildOptions = sdict()
1154 #
1155 # Retrieve build option for EDKII and EDK style module
1156 #
1157 for CodeBase in (EDKII_NAME, EDK_NAME):
1158 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
1159 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
1160 if Dummy3.upper() != 'COMMON':
1161 continue
1162 CurKey = (ToolChainFamily, ToolChain, CodeBase)
1163 #
1164 # Only flags can be appended
1165 #
1166 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1167 self._BuildOptions[CurKey] = Option
1168 else:
1169 if ' ' + Option not in self._BuildOptions[CurKey]:
1170 self._BuildOptions[CurKey] += ' ' + Option
1171 return self._BuildOptions
1172
1173 def GetBuildOptionsByModuleType(self, Edk, ModuleType):
1174 if self._ModuleTypeOptions == None:
1175 self._ModuleTypeOptions = sdict()
1176 if (Edk, ModuleType) not in self._ModuleTypeOptions:
1177 options = sdict()
1178 self._ModuleTypeOptions[Edk, ModuleType] = options
1179 DriverType = '%s.%s' % (Edk, ModuleType)
1180 CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
1181 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
1182 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
1183 Type = Dummy2 + '.' + Dummy3
1184 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
1185 Key = (ToolChainFamily, ToolChain, Edk)
1186 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1187 options[Key] = Option
1188 else:
1189 if ' ' + Option not in options[Key]:
1190 options[Key] += ' ' + Option
1191 return self._ModuleTypeOptions[Edk, ModuleType]
1192
1193 def GetStructurePcdInfo(self, PcdSet):
1194 structure_pcd_data = {}
1195 for item in PcdSet:
1196 if (item[0],item[1]) not in structure_pcd_data:
1197 structure_pcd_data[(item[0],item[1])] = []
1198 structure_pcd_data[(item[0],item[1])].append(item)
1199
1200 return structure_pcd_data
1201 def OverrideByFdfComm(self,StruPcds):
1202 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 {}
1203 GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])
1204 for Pcd in StruPcds.values():
1205 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
1206 continue
1207 FieldValues = {item[2]:StructurePcdInCom[item] for item in StructurePcdInCom if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]}
1208 for sku in Pcd.SkuOverrideValues:
1209 for defaultstore in Pcd.SkuOverrideValues[sku]:
1210 for field in FieldValues:
1211 if field not in Pcd.SkuOverrideValues[sku][defaultstore]:
1212 Pcd.SkuOverrideValues[sku][defaultstore][field] = ["","",""]
1213 Pcd.SkuOverrideValues[sku][defaultstore][field][0] = FieldValues[field][0]
1214 Pcd.SkuOverrideValues[sku][defaultstore][field][1] = FieldValues[field][1][0]
1215 Pcd.SkuOverrideValues[sku][defaultstore][field][2] = FieldValues[field][1][1]
1216 return StruPcds
1217 def OverrideByFdfCommOverAll(self,AllPcds):
1218 def CheckStructureInComm(commpcds):
1219 if not commpcds:
1220 return False
1221 if len(commpcds[0]) == 5:
1222 return True
1223 return False
1224
1225 if CheckStructureInComm(GlobalData.BuildOptionPcd):
1226 StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}
1227 NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}
1228 else:
1229 NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}
1230 for Guid,Name in NoFiledValues:
1231 if (Name,Guid) in AllPcds:
1232 Pcd = AllPcds.get((Name,Guid))
1233 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
1234 for sku in Pcd.SkuInfoList:
1235 SkuInfo = Pcd.SkuInfoList[sku]
1236 if SkuInfo.DefaultValue:
1237 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
1238 else:
1239 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
1240 for defaultstore in SkuInfo.DefaultStoreDict:
1241 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
1242 else:
1243 PcdInDec = self.DecPcds.get((Name,Guid))
1244 if PcdInDec:
1245 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1246 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1247 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1248 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]
1249 return AllPcds
1250 def UpdateStructuredPcds(self, TypeList, AllPcds):
1251
1252 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1253 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1254 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1255 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1256 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1257 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
1258
1259 Pcds = AllPcds
1260 DefaultStoreMgr = DefaultStore(self.DefaultStores)
1261 SkuIds = self.SkuIdMgr.AvailableSkuIdSet
1262 SkuIds.update({'DEFAULT':0})
1263 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
1264
1265 S_PcdSet = []
1266 # Find out all possible PCD candidates for self._Arch
1267 RecordList = []
1268
1269 for Type in TypeList:
1270 RecordList.extend(self._RawData[Type, self._Arch])
1271
1272 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:
1273 SkuName = SkuName.upper()
1274 default_store = default_store.upper()
1275 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1276 if SkuName not in SkuIds:
1277 continue
1278
1279 if SkuName in SkuIds and "." in TokenSpaceGuid:
1280 S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]])
1281
1282 # handle pcd value override
1283 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)
1284 S_pcd_set = {}
1285 for str_pcd in StrPcdSet:
1286 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1287 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1288 if not isinstance (str_pcd_dec, StructurePcd):
1289 EdkLogger.error('build', PARSER_ERROR,
1290 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1291 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
1292 if str_pcd_dec:
1293 str_pcd_obj_str = StructurePcd()
1294 str_pcd_obj_str.copy(str_pcd_dec)
1295 if str_pcd_obj:
1296 str_pcd_obj_str.copy(str_pcd_obj)
1297 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1298 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1299 else:
1300 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1301 for str_pcd_data in StrPcdSet[str_pcd]:
1302 if str_pcd_data[3] in SkuIds:
1303 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])
1304 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1305 else:
1306 EdkLogger.error('build', PARSER_ERROR,
1307 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1308 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
1309 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1310 for Pcd in self.DecPcds:
1311 if type (self._DecPcds[Pcd]) is StructurePcd:
1312 if Pcd not in S_pcd_set:
1313 str_pcd_obj_str = StructurePcd()
1314 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1315 str_pcd_obj = Pcds.get(Pcd, None)
1316 if str_pcd_obj:
1317 str_pcd_obj_str.copy(str_pcd_obj)
1318 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1319 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1320 else:
1321 str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
1322 S_pcd_set[Pcd] = str_pcd_obj_str
1323 if S_pcd_set:
1324 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1325 for stru_pcd in S_pcd_set.values():
1326 for skuid in SkuIds:
1327 if skuid in stru_pcd.SkuOverrideValues:
1328 continue
1329 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1330 NoDefault = False
1331 while nextskuid not in stru_pcd.SkuOverrideValues:
1332 if nextskuid == "DEFAULT":
1333 NoDefault = True
1334 break
1335 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1336 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})
1337 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1338 for skuid in SkuIds:
1339 nextskuid = skuid
1340 NoDefault = False
1341 if skuid not in stru_pcd.SkuOverrideValues:
1342 while nextskuid not in stru_pcd.SkuOverrideValues:
1343 if nextskuid == "DEFAULT":
1344 NoDefault = True
1345 break
1346 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1347 if NoDefault:
1348 continue
1349 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])
1350 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1351
1352 for defaultstoreid in DefaultStores:
1353 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1354 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1355 S_pcd_set = self.OverrideByFdfComm(S_pcd_set)
1356 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1357 if Str_Pcd_Values:
1358 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:
1359 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1360 if str_pcd_obj is None:
1361 print PcdName, PcdGuid
1362 raise
1363 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1364 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1365 if skuname not in str_pcd_obj.SkuInfoList:
1366 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1367 else:
1368 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1369 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1370 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1371 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1372 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1373 str_pcd_obj.DefaultValue = PcdValue
1374 else:
1375 if skuname not in str_pcd_obj.SkuInfoList:
1376 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1377 NoDefault = False
1378 while nextskuid not in str_pcd_obj.SkuInfoList:
1379 if nextskuid == "DEFAULT":
1380 NoDefault = True
1381 break
1382 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1383 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)
1384 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1385 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1386 else:
1387 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1388 for str_pcd_obj in S_pcd_set.values():
1389 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1390 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1391 continue
1392 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])
1393 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1394 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1395 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1396
1397 for str_pcd_obj in S_pcd_set.values():
1398
1399 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1400 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1401
1402 for pcdkey in Pcds:
1403 pcd = Pcds[pcdkey]
1404 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1405 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
1406 del(pcd.SkuInfoList['COMMON'])
1407 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1408 del(pcd.SkuInfoList['COMMON'])
1409
1410 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1411 return Pcds
1412
1413 ## Retrieve non-dynamic PCD settings
1414 #
1415 # @param Type PCD type
1416 #
1417 # @retval a dict object contains settings of given PCD type
1418 #
1419 def _GetPcd(self, Type):
1420 Pcds = sdict()
1421 #
1422 # tdict is a special dict kind of type, used for selecting correct
1423 # PCD settings for certain ARCH
1424 #
1425 AvailableSkuIdSet = copy.copy(self.SkuIds)
1426
1427 PcdDict = tdict(True, 3)
1428 PcdSet = set()
1429 # Find out all possible PCD candidates for self._Arch
1430 RecordList = self._RawData[Type, self._Arch]
1431 PcdValueDict = sdict()
1432 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
1433 SkuName = SkuName.upper()
1434 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1435 if SkuName not in AvailableSkuIdSet:
1436 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1437 File=self.MetaFile, Line=Dummy5)
1438 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1439 if "." not in TokenSpaceGuid:
1440 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1441 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1442
1443 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1444 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1445 if Setting == None:
1446 continue
1447 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1448 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1449 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1450 else:
1451 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1452
1453 PcdsKeys = PcdValueDict.keys()
1454 for PcdCName, TokenSpaceGuid in PcdsKeys:
1455
1456 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
1457 PcdValue = None
1458 DatumType = None
1459 MaxDatumSize = None
1460 if 'COMMON' in PcdSetting:
1461 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']
1462 if 'DEFAULT' in PcdSetting:
1463 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']
1464 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1465 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1466
1467 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1468 PcdCName,
1469 TokenSpaceGuid,
1470 self._PCD_TYPE_STRING_[Type],
1471 DatumType,
1472 PcdValue,
1473 '',
1474 MaxDatumSize,
1475 {},
1476 False,
1477 None,
1478 IsDsc=True)
1479
1480
1481 return Pcds
1482
1483 def __UNICODE2OCTList(self,Value):
1484 Value = Value.strip()
1485 Value = Value[2:-1]
1486 List = []
1487 for Item in Value:
1488 Temp = '%04X' % ord(Item)
1489 List.append('0x' + Temp[2:4])
1490 List.append('0x' + Temp[0:2])
1491 List.append('0x00')
1492 List.append('0x00')
1493 return List
1494 def __STRING2OCTList(self,Value):
1495 OCTList = []
1496 Value = Value.strip('"')
1497 for char in Value:
1498 Temp = '%02X' % ord(char)
1499 OCTList.append('0x' + Temp)
1500 OCTList.append('0x00')
1501 return OCTList
1502
1503 def GetStructurePcdMaxSize(self, str_pcd):
1504 pcd_default_value = str_pcd.DefaultValue
1505 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()]
1506 sku_values.append(pcd_default_value)
1507
1508 def get_length(value):
1509 Value = value.strip()
1510 if len(value) > 1:
1511 if Value.startswith('GUID') and Value.endswith(')'):
1512 return 16
1513 if Value.startswith('L"') and Value.endswith('"'):
1514 return len(Value[2:-1])
1515 if Value[0] == '"' and Value[-1] == '"':
1516 return len(Value) - 2
1517 if Value[0] == '{' and Value[-1] == '}':
1518 return len(Value.split(","))
1519 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1520 return len(list(Value[2:-1]))
1521 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1522 return len(Value) - 2
1523 return len(Value)
1524
1525 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
1526
1527 def IsFieldValueAnArray (self, Value):
1528 Value = Value.strip()
1529 if Value.startswith('GUID') and Value.endswith(')'):
1530 return True
1531 if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
1532 return True
1533 if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
1534 return True
1535 if Value[0] == '{' and Value[-1] == '}':
1536 return True
1537 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1538 print 'foo = ', list(Value[2:-1])
1539 return True
1540 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1541 print 'bar = ', list(Value[1:-1])
1542 return True
1543 return False
1544
1545 def ExecuteCommand (self, Command):
1546 try:
1547 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1548 except:
1549 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1550 Result = Process.communicate()
1551 return Process.returncode, Result[0], Result[1]
1552
1553 def IntToCString(self, Value, ValueSize):
1554 Result = '"'
1555 if not isinstance (Value, str):
1556 for Index in range(0, ValueSize):
1557 Result = Result + '\\x%02x' % (Value & 0xff)
1558 Value = Value >> 8
1559 Result = Result + '"'
1560 return Result
1561
1562 def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):
1563 OverrideValues = {DefaultStoreName:""}
1564 if Pcd.SkuOverrideValues:
1565 OverrideValues = Pcd.SkuOverrideValues[SkuName]
1566 for DefaultStoreName in OverrideValues.keys():
1567 CApp = CApp + 'void\n'
1568 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1569 CApp = CApp + ' void\n'
1570 CApp = CApp + ' )\n'
1571 CApp = CApp + '{\n'
1572 CApp = CApp + ' UINT32 Size;\n'
1573 CApp = CApp + ' UINT32 FieldSize;\n'
1574 CApp = CApp + ' CHAR8 *Value;\n'
1575 CApp = CApp + ' UINT32 OriginalSize;\n'
1576 CApp = CApp + ' VOID *OriginalPcd;\n'
1577 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
1578 CApp = CApp + '\n'
1579
1580 if SkuName in Pcd.SkuInfoList:
1581 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue) if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue
1582 else:
1583 DefaultValue = Pcd.DefaultValue
1584 PcdDefaultValue = StringToArray(DefaultValue.strip())
1585
1586 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
1587
1588 #
1589 # Get current PCD value and size
1590 #
1591 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1592
1593 #
1594 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1595 # the correct value. For structures with a flexible array member, the flexible
1596 # array member is detected, and the size is based on the highest index used with
1597 # the flexible array member. The flexible array member must be the last field
1598 # in a structure. The size formula for this case is:
1599 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1600 #
1601 CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1602 CApp = CApp + "// Default Value in Dec \n"
1603 for FieldList in [Pcd.DefaultValues]:
1604 if not FieldList:
1605 continue
1606 for FieldName in FieldList:
1607 FieldName = "." + FieldName
1608 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1609 if IsArray:
1610 try:
1611 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
1612 except BadExpression:
1613 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1614 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1615 Value, ValueSize = ParseFieldValue(Value)
1616 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]);
1617 else:
1618 NewFieldName = ''
1619 FieldName_ori = FieldName.strip('.')
1620 while '[' in FieldName:
1621 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1622 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1623 FieldName = FieldName.split(']', 1)[1]
1624 FieldName = NewFieldName + FieldName
1625 while '[' in FieldName:
1626 FieldName = FieldName.rsplit('[', 1)[0]
1627 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])
1628 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
1629 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
1630 storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
1631 for defaultstorenameitem in storeset:
1632 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1633 for FieldList in [inherit_OverrideValues.get(defaultstorenameitem)]:
1634 if not FieldList:
1635 continue
1636 for FieldName in FieldList:
1637 FieldName = "." + FieldName
1638 IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1639 if IsArray:
1640 try:
1641 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
1642 except BadExpression:
1643 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1644 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1645 Value, ValueSize = ParseFieldValue(Value)
1646 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]);
1647 else:
1648 NewFieldName = ''
1649 FieldName_ori = FieldName.strip('.')
1650 while '[' in FieldName:
1651 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1652 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1653 FieldName = FieldName.split(']', 1)[1]
1654 FieldName = NewFieldName + FieldName
1655 while '[' in FieldName:
1656 FieldName = FieldName.rsplit('[', 1)[0]
1657 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])
1658 if skuname == SkuName:
1659 break
1660
1661 #
1662 # Allocate and zero buffer for the PCD
1663 # Must handle cases where current value is smaller, larger, or same size
1664 # Always keep that larger one as the current size
1665 #
1666 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1667 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
1668 CApp = CApp + ' memset (Pcd, 0, Size);\n'
1669
1670 #
1671 # Copy current PCD value into allocated buffer.
1672 #
1673 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1674
1675 #
1676 # Assign field values in PCD
1677 #
1678 CApp = CApp + "// Default value in Dec \n"
1679 for FieldList in [Pcd.DefaultValues]:
1680 if not FieldList:
1681 continue
1682 for FieldName in FieldList:
1683 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
1684 if IsArray:
1685 try:
1686 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
1687 except BadExpression:
1688 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1689 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))
1690
1691 try:
1692 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1693 except Exception:
1694 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]))
1695 if isinstance(Value, str):
1696 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1697 elif IsArray:
1698 #
1699 # Use memcpy() to copy value into field
1700 #
1701 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1702 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1703 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1704 else:
1705 if ValueSize > 4:
1706 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1707 else:
1708 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1709 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
1710 inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
1711 storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
1712 for defaultstorenameitem in storeset:
1713 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1714 pcddefaultvalue = Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue
1715 for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(defaultstorenameitem)]:
1716 if not FieldList:
1717 continue
1718 if pcddefaultvalue and FieldList == pcddefaultvalue:
1719 IsArray = self.IsFieldValueAnArray(FieldList)
1720 if IsArray:
1721 try:
1722 FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
1723 except BadExpression:
1724 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1725 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1726 Value, ValueSize = ParseFieldValue (FieldList)
1727 if isinstance(Value, str):
1728 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
1729 elif IsArray:
1730 #
1731 # Use memcpy() to copy value into field
1732 #
1733 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(skuname,{}).get(defaultstorenameitem, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
1734 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1735 continue
1736 for FieldName in FieldList:
1737 IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
1738 if IsArray:
1739 try:
1740 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
1741 except BadExpression:
1742 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1743 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1744 try:
1745 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1746 except Exception:
1747 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]))
1748 if isinstance(Value, str):
1749 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1750 elif IsArray:
1751 #
1752 # Use memcpy() to copy value into field
1753 #
1754 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1755 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1756 CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1757 else:
1758 if ValueSize > 4:
1759 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1760 else:
1761 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1762 if skuname == SkuName:
1763 break
1764 #
1765 # Set new PCD value and size
1766 #
1767 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1768
1769 #
1770 # Free PCD
1771 #
1772 CApp = CApp + ' free (Pcd);\n'
1773 CApp = CApp + '}\n'
1774 CApp = CApp + '\n'
1775 return InitByteValue, CApp
1776
1777 def GenerateByteArrayValue (self, StructuredPcds):
1778 #
1779 # Generate/Compile/Run C application to determine if there are any flexible array members
1780 #
1781 if not StructuredPcds:
1782 return
1783
1784 InitByteValue = ""
1785 CApp = PcdMainCHeader
1786
1787 Includes = {}
1788 for PcdName in StructuredPcds:
1789 Pcd = StructuredPcds[PcdName]
1790 for IncludeFile in Pcd.StructuredPcdIncludeFile:
1791 if IncludeFile not in Includes:
1792 Includes[IncludeFile] = True
1793 CApp = CApp + '#include <%s>\n' % (IncludeFile)
1794 CApp = CApp + '\n'
1795
1796 for PcdName in StructuredPcds:
1797 Pcd = StructuredPcds[PcdName]
1798 if not Pcd.SkuOverrideValues:
1799 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)
1800 else:
1801 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
1802 if SkuName not in Pcd.SkuOverrideValues:
1803 continue
1804 for DefaultStoreName in Pcd.DefaultStoreName:
1805 Pcd = StructuredPcds[PcdName]
1806 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
1807
1808 CApp = CApp + 'VOID\n'
1809 CApp = CApp + 'PcdEntryPoint(\n'
1810 CApp = CApp + ' VOID\n'
1811 CApp = CApp + ' )\n'
1812 CApp = CApp + '{\n'
1813 for Pcd in StructuredPcds.values():
1814 if not Pcd.SkuOverrideValues:
1815 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1816 else:
1817 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
1818 if SkuName not in Pcd.SkuOverrideValues:
1819 continue
1820 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
1821 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1822 CApp = CApp + '}\n'
1823
1824 CApp = CApp + PcdMainCEntry + '\n'
1825
1826 if not os.path.exists(self.OutputPath):
1827 os.makedirs(self.OutputPath)
1828 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
1829 File = open (CAppBaseFileName + '.c', 'w')
1830 File.write(CApp)
1831 File.close()
1832
1833 MakeApp = PcdMakefileHeader
1834 if sys.platform == "win32":
1835 MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
1836 else:
1837 MakeApp = MakeApp + PcdGccMakefile
1838 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
1839 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1840
1841 PlatformInc = {}
1842 for Cache in self._Bdb._CACHE_.values():
1843 if Cache.MetaFile.Ext.lower() != '.dec':
1844 continue
1845 if Cache.Includes:
1846 if str(Cache.MetaFile.Path) not in PlatformInc:
1847 PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes
1848
1849 PcdDependDEC = []
1850 for Pcd in StructuredPcds.values():
1851 for PackageDec in Pcd.PackageDecs:
1852 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
1853 if not os.path.exists(Package):
1854 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
1855 if Package not in PcdDependDEC:
1856 PcdDependDEC.append(Package)
1857
1858 if PlatformInc and PcdDependDEC:
1859 for pkg in PcdDependDEC:
1860 if pkg in PlatformInc:
1861 for inc in PlatformInc[pkg]:
1862 MakeApp += '-I' + str(inc) + ' '
1863 MakeApp = MakeApp + '\n'
1864
1865 CC_FLAGS = LinuxCFLAGS
1866 if sys.platform == "win32":
1867 CC_FLAGS = WindowsCFLAGS
1868 BuildOptions = {}
1869 for Options in self.BuildOptions:
1870 if Options[2] != EDKII_NAME:
1871 continue
1872 Family = Options[0]
1873 if Family and Family != self.ToolChainFamily:
1874 continue
1875 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
1876 if Tool != 'CC':
1877 continue
1878
1879 if Target == "*" or Target == self._Target:
1880 if Tag == "*" or Tag == self._Toolchain:
1881 if Arch == "*" or Arch == self.Arch:
1882 if Tool not in BuildOptions:
1883 BuildOptions[Tool] = {}
1884 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
1885 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
1886 else:
1887 # append options for the same tool except PATH
1888 if Attr != 'PATH':
1889 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
1890 else:
1891 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
1892 if BuildOptions:
1893 for Tool in BuildOptions:
1894 for Attr in BuildOptions[Tool]:
1895 if Attr == "FLAGS":
1896 Value = BuildOptions[Tool][Attr]
1897 ValueList = Value.split()
1898 if ValueList:
1899 for Id, Item in enumerate(ValueList):
1900 if Item == '-D' or Item == '/D':
1901 CC_FLAGS += ' ' + Item
1902 if Id + 1 < len(ValueList):
1903 CC_FLAGS += ' ' + ValueList[Id + 1]
1904 elif Item.startswith('/D') or Item.startswith('-D'):
1905 CC_FLAGS += ' ' + Item
1906 MakeApp += CC_FLAGS
1907
1908 if sys.platform == "win32":
1909 MakeApp = MakeApp + PcdMakefileEnd
1910 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
1911 File = open (MakeFileName, 'w')
1912 File.write(MakeApp)
1913 File.close()
1914
1915 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
1916 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
1917 File = open (InputValueFile, 'w')
1918 File.write(InitByteValue)
1919 File.close()
1920
1921 Messages = ''
1922 if sys.platform == "win32":
1923 MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName)
1924 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
1925 Messages = StdOut
1926 else:
1927 MakeCommand = 'make clean & make -f %s' % (MakeFileName)
1928 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
1929 Messages = StdErr
1930 Messages = Messages.split('\n')
1931 MessageGroup = []
1932 if returncode <>0:
1933 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
1934 File = open (CAppBaseFileName + '.c', 'r')
1935 FileData = File.readlines()
1936 File.close()
1937 for Message in Messages:
1938 if " error" in Message or "warning" in Message:
1939 FileInfo = Message.strip().split('(')
1940 if len (FileInfo) > 1:
1941 FileName = FileInfo [0]
1942 FileLine = FileInfo [1].split (')')[0]
1943 else:
1944 FileInfo = Message.strip().split(':')
1945 FileName = FileInfo [0]
1946 FileLine = FileInfo [1]
1947 if FileLine.isdigit():
1948 error_line = FileData[int (FileLine) - 1]
1949 if r"//" in error_line:
1950 c_line,dsc_line = error_line.split(r"//")
1951 else:
1952 dsc_line = error_line
1953 message_itmes = Message.split(":")
1954 Index = 0
1955 if "PcdValueInit.c" not in Message:
1956 if not MessageGroup:
1957 MessageGroup.append(Message)
1958 break
1959 else:
1960 for item in message_itmes:
1961 if "PcdValueInit.c" in item:
1962 Index = message_itmes.index(item)
1963 message_itmes[Index] = dsc_line.strip()
1964 break
1965 MessageGroup.append(":".join(message_itmes[Index:]).strip())
1966 continue
1967 else:
1968 MessageGroup.append(Message)
1969 if MessageGroup:
1970 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
1971 else:
1972 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
1973
1974 PcdValueInitExe = PcdValueInitName
1975 if not sys.platform == "win32":
1976 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
1977
1978 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
1979 returncode, StdOut, StdErr = self.ExecuteCommand (Command)
1980 if returncode <> 0:
1981 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
1982 FileBuffer = []
1983 else:
1984 File = open (OutputValueFile, 'r')
1985 FileBuffer = File.readlines()
1986 File.close()
1987
1988 StructurePcdSet = []
1989 for Pcd in FileBuffer:
1990 PcdValue = Pcd.split ('|')
1991 PcdInfo = PcdValue[0].split ('.')
1992 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
1993 return StructurePcdSet
1994
1995 ## Retrieve dynamic PCD settings
1996 #
1997 # @param Type PCD type
1998 #
1999 # @retval a dict object contains settings of given PCD type
2000 #
2001 def _GetDynamicPcd(self, Type):
2002
2003
2004 Pcds = sdict()
2005 #
2006 # tdict is a special dict kind of type, used for selecting correct
2007 # PCD settings for certain ARCH and SKU
2008 #
2009 PcdDict = tdict(True, 4)
2010 PcdList = []
2011 # Find out all possible PCD candidates for self._Arch
2012 RecordList = self._RawData[Type, self._Arch]
2013 AvailableSkuIdSet = copy.copy(self.SkuIds)
2014
2015
2016 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
2017 SkuName = SkuName.upper()
2018 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2019 if SkuName not in AvailableSkuIdSet:
2020 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2021 File=self.MetaFile, Line=Dummy5)
2022 if "." not in TokenSpaceGuid:
2023 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2024 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2025
2026 # Remove redundant PCD candidates, per the ARCH and SKU
2027 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2028
2029 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2030 if Setting == None:
2031 continue
2032
2033 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2034 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2035 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2036 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2037 pcdObject.SkuInfoList[SkuName] = SkuInfo
2038 if MaxDatumSize.strip():
2039 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2040 else:
2041 CurrentMaxSize = 0
2042 if pcdObject.MaxDatumSize:
2043 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2044 else:
2045 PcdMaxSize = 0
2046 if CurrentMaxSize > PcdMaxSize:
2047 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2048 else:
2049 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2050 PcdCName,
2051 TokenSpaceGuid,
2052 self._PCD_TYPE_STRING_[Type],
2053 DatumType,
2054 PcdValue,
2055 '',
2056 MaxDatumSize,
2057 {SkuName : SkuInfo},
2058 False,
2059 None,
2060 IsDsc=True)
2061
2062 for pcd in Pcds.values():
2063 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2064 # Only fix the value while no value provided in DSC file.
2065 for sku in pcd.SkuInfoList.values():
2066 if (sku.DefaultValue == "" or sku.DefaultValue==None):
2067 sku.DefaultValue = pcdDecObject.DefaultValue
2068 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2069 valuefromDec = pcdDecObject.DefaultValue
2070 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
2071 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2072 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2073 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2074 del(pcd.SkuInfoList['COMMON'])
2075 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2076 del(pcd.SkuInfoList['COMMON'])
2077
2078 map(self.FilterSkuSettings,Pcds.values())
2079
2080 return Pcds
2081
2082 def FilterSkuSettings(self, PcdObj):
2083
2084 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2085 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():
2086 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']
2087 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2088 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'
2089 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'
2090
2091 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2092 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}
2093
2094 return PcdObj
2095
2096
2097 def CompareVarAttr(self, Attr1, Attr2):
2098 if not Attr1 or not Attr2: # for empty string
2099 return True
2100 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2101 Attr1Set = set(Attr1s)
2102 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2103 Attr2Set = set(Attr2s)
2104 if Attr2Set == Attr1Set:
2105 return True
2106 else:
2107 return False
2108 def CompletePcdValues(self,PcdSet):
2109 Pcds = {}
2110 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2111 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}
2112 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
2113 for PcdCName, TokenSpaceGuid in PcdSet:
2114 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2115 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2116 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2117 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2118 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2119 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2120 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2121 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2122 continue
2123 PcdType = PcdObj.Type
2124 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2125 for skuid in PcdObj.SkuInfoList:
2126 skuobj = PcdObj.SkuInfoList[skuid]
2127 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))
2128 for defaultstorename in DefaultStores:
2129 if defaultstorename not in skuobj.DefaultStoreDict:
2130 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2131 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2132 for skuname,skuid in SkuIds.items():
2133 if skuname not in PcdObj.SkuInfoList:
2134 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2135 while nextskuid not in PcdObj.SkuInfoList:
2136 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2137 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2138 PcdObj.SkuInfoList[skuname].SkuId = skuid
2139 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2140 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2141 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue
2142 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2143 return Pcds
2144 ## Retrieve dynamic HII PCD settings
2145 #
2146 # @param Type PCD type
2147 #
2148 # @retval a dict object contains settings of given PCD type
2149 #
2150 def _GetDynamicHiiPcd(self, Type):
2151
2152 VariableAttrs = {}
2153
2154 Pcds = sdict()
2155 #
2156 # tdict is a special dict kind of type, used for selecting correct
2157 # PCD settings for certain ARCH and SKU
2158 #
2159 PcdDict = tdict(True, 5)
2160 PcdSet = set()
2161 RecordList = self._RawData[Type, self._Arch]
2162 # Find out all possible PCD candidates for self._Arch
2163 AvailableSkuIdSet = copy.copy(self.SkuIds)
2164 DefaultStoresDefine = self._GetDefaultStores()
2165
2166 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:
2167 SkuName = SkuName.upper()
2168 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2169 DefaultStore = DefaultStore.upper()
2170 if DefaultStore == "COMMON":
2171 DefaultStore = "STANDARD"
2172 if SkuName not in AvailableSkuIdSet:
2173 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2174 File=self.MetaFile, Line=Dummy5)
2175 if DefaultStore not in DefaultStoresDefine:
2176 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2177 File=self.MetaFile, Line=Dummy5)
2178 if "." not in TokenSpaceGuid:
2179 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5))
2180 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting
2181
2182
2183 # Remove redundant PCD candidates, per the ARCH and SKU
2184 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:
2185
2186 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]
2187 if Setting == None:
2188 continue
2189 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2190
2191 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2192 if not rt:
2193 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2194 ExtraData="[%s]" % VarAttribute)
2195 ExceedMax = False
2196 FormatCorrect = True
2197 if VariableOffset.isdigit():
2198 if int(VariableOffset, 10) > 0xFFFF:
2199 ExceedMax = True
2200 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):
2201 if int(VariableOffset, 16) > 0xFFFF:
2202 ExceedMax = True
2203 # For Offset written in "A.B"
2204 elif VariableOffset.find('.') > -1:
2205 VariableOffsetList = VariableOffset.split(".")
2206 if not (len(VariableOffsetList) == 2
2207 and IsValidWord(VariableOffsetList[0])
2208 and IsValidWord(VariableOffsetList[1])):
2209 FormatCorrect = False
2210 else:
2211 FormatCorrect = False
2212 if not FormatCorrect:
2213 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2214
2215 if ExceedMax:
2216 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2217 if (VariableName, VariableGuid) not in VariableAttrs:
2218 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2219 else:
2220 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2221 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)]))
2222
2223 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2224 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2225 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2226 if SkuName in pcdObject.SkuInfoList:
2227 Skuitem = pcdObject.SkuInfoList[SkuName]
2228 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2229 else:
2230 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
2231 pcdObject.SkuInfoList[SkuName] = SkuInfo
2232 else:
2233 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
2234 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2235 PcdCName,
2236 TokenSpaceGuid,
2237 self._PCD_TYPE_STRING_[Type],
2238 '',
2239 DefaultValue,
2240 '',
2241 '',
2242 {SkuName : SkuInfo},
2243 False,
2244 None,
2245 pcdDecObject.validateranges,
2246 pcdDecObject.validlists,
2247 pcdDecObject.expressions,
2248 IsDsc=True)
2249
2250
2251 for pcd in Pcds.values():
2252 SkuInfoObj = pcd.SkuInfoList.values()[0]
2253 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2254 pcd.DatumType = pcdDecObject.DatumType
2255 # Only fix the value while no value provided in DSC file.
2256 for sku in pcd.SkuInfoList.values():
2257 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):
2258 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2259 for default_store in sku.DefaultStoreDict:
2260 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2261 pcd.DefaultValue = pcdDecObject.DefaultValue
2262 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2263 valuefromDec = pcdDecObject.DefaultValue
2264 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})
2265 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2266 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2267 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2268 del(pcd.SkuInfoList['COMMON'])
2269 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2270 del(pcd.SkuInfoList['COMMON'])
2271
2272 if pcd.MaxDatumSize.strip():
2273 MaxSize = int(pcd.MaxDatumSize, 0)
2274 else:
2275 MaxSize = 0
2276 if pcdDecObject.DatumType == 'VOID*':
2277 for (_, skuobj) in pcd.SkuInfoList.items():
2278 datalen = 0
2279 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2280 datalen = len(skuobj.HiiDefaultValue.split(","))
2281 if datalen > MaxSize:
2282 MaxSize = datalen
2283 for defaultst in skuobj.DefaultStoreDict:
2284 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2285 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2286 pcd.MaxDatumSize = str(MaxSize)
2287 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)
2288 if not rt:
2289 invalidpcd = ",".join(invalidhii)
2290 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)
2291
2292 map(self.FilterSkuSettings,Pcds.values())
2293
2294 return Pcds
2295
2296 def CheckVariableNameAssignment(self,Pcds):
2297 invalidhii = []
2298 for pcdname in Pcds:
2299 pcd = Pcds[pcdname]
2300 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])
2301 if len(varnameset) > 1:
2302 invalidhii.append(".".join((pcdname[1],pcdname[0])))
2303 if len(invalidhii):
2304 return False,invalidhii
2305 else:
2306 return True, []
2307 ## Retrieve dynamic VPD PCD settings
2308 #
2309 # @param Type PCD type
2310 #
2311 # @retval a dict object contains settings of given PCD type
2312 #
2313 def _GetDynamicVpdPcd(self, Type):
2314
2315
2316 Pcds = sdict()
2317 #
2318 # tdict is a special dict kind of type, used for selecting correct
2319 # PCD settings for certain ARCH and SKU
2320 #
2321 PcdDict = tdict(True, 4)
2322 PcdList = []
2323
2324 # Find out all possible PCD candidates for self._Arch
2325 RecordList = self._RawData[Type, self._Arch]
2326 AvailableSkuIdSet = copy.copy(self.SkuIds)
2327
2328 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
2329 SkuName = SkuName.upper()
2330 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2331 if SkuName not in AvailableSkuIdSet:
2332 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2333 File=self.MetaFile, Line=Dummy5)
2334 if "." not in TokenSpaceGuid:
2335 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2336 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2337
2338 # Remove redundant PCD candidates, per the ARCH and SKU
2339 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2340 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2341 if Setting == None:
2342 continue
2343 #
2344 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2345 # For the Integer & Boolean type, the optional data can only be InitialValue.
2346 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2347 # until the DEC parser has been called.
2348 #
2349 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2350 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2351 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2352 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2353 pcdObject.SkuInfoList[SkuName] = SkuInfo
2354 if MaxDatumSize.strip():
2355 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2356 else:
2357 CurrentMaxSize = 0
2358 if pcdObject.MaxDatumSize:
2359 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2360 else:
2361 PcdMaxSize = 0
2362 if CurrentMaxSize > PcdMaxSize:
2363 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2364 else:
2365 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2366 PcdCName,
2367 TokenSpaceGuid,
2368 self._PCD_TYPE_STRING_[Type],
2369 '',
2370 InitialValue,
2371 '',
2372 MaxDatumSize,
2373 {SkuName : SkuInfo},
2374 False,
2375 None,
2376 IsDsc=True)
2377 for pcd in Pcds.values():
2378 SkuInfoObj = pcd.SkuInfoList.values()[0]
2379 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2380 pcd.DatumType = pcdDecObject.DatumType
2381 # Only fix the value while no value provided in DSC file.
2382 for sku in pcd.SkuInfoList.values():
2383 if (sku.DefaultValue == "" or sku.DefaultValue==None):
2384 sku.DefaultValue = pcdDecObject.DefaultValue
2385 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2386 valuefromDec = pcdDecObject.DefaultValue
2387 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2388 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2389 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2390 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2391 del(pcd.SkuInfoList['COMMON'])
2392 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2393 del(pcd.SkuInfoList['COMMON'])
2394
2395
2396 map(self.FilterSkuSettings,Pcds.values())
2397 return Pcds
2398
2399 ## Add external modules
2400 #
2401 # The external modules are mostly those listed in FDF file, which don't
2402 # need "build".
2403 #
2404 # @param FilePath The path of module description file
2405 #
2406 def AddModule(self, FilePath):
2407 FilePath = NormPath(FilePath)
2408 if FilePath not in self.Modules:
2409 Module = ModuleBuildClassObject()
2410 Module.MetaFile = FilePath
2411 self.Modules.append(Module)
2412
2413 def _GetToolChainFamily(self):
2414 self._ToolChainFamily = "MSFT"
2415 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2416 if os.path.isfile(BuildConfigurationFile) == True:
2417 TargetTxt = TargetTxtClassObject()
2418 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2419 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2420 if ToolDefinitionFile == '':
2421 ToolDefinitionFile = "tools_def.txt"
2422 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2423 if os.path.isfile(ToolDefinitionFile) == True:
2424 ToolDef = ToolDefClassObject()
2425 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2426 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2427 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2428 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2429 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2430 self._ToolChainFamily = "MSFT"
2431 else:
2432 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2433 return self._ToolChainFamily
2434
2435 ## Add external PCDs
2436 #
2437 # The external PCDs are mostly those listed in FDF file to specify address
2438 # or offset information.
2439 #
2440 # @param Name Name of the PCD
2441 # @param Guid Token space guid of the PCD
2442 # @param Value Value of the PCD
2443 #
2444 def AddPcd(self, Name, Guid, Value):
2445 if (Name, Guid) not in self.Pcds:
2446 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2447 self.Pcds[Name, Guid].DefaultValue = Value
2448 @property
2449 def DecPcds(self):
2450 if self._DecPcds == None:
2451 FdfInfList = []
2452 if GlobalData.gFdfParser:
2453 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2454 PkgSet = set()
2455 for Inf in FdfInfList:
2456 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2457 if ModuleFile in self._Modules:
2458 continue
2459 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2460 PkgSet.update(ModuleData.Packages)
2461 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
2462 return self._DecPcds
2463 _Macros = property(_GetMacros)
2464 Arch = property(_GetArch, _SetArch)
2465 Platform = property(_GetPlatformName)
2466 PlatformName = property(_GetPlatformName)
2467 Guid = property(_GetFileGuid)
2468 Version = property(_GetVersion)
2469 DscSpecification = property(_GetDscSpec)
2470 OutputDirectory = property(_GetOutpuDir)
2471 SupArchList = property(_GetSupArch)
2472 BuildTargets = property(_GetBuildTarget)
2473 SkuName = property(_GetSkuName, _SetSkuName)
2474 PcdInfoFlag = property(_GetPcdInfoFlag)
2475 VarCheckFlag = property(_GetVarCheckFlag)
2476 FlashDefinition = property(_GetFdfFile)
2477 Prebuild = property(_GetPrebuild)
2478 Postbuild = property(_GetPostbuild)
2479 BuildNumber = property(_GetBuildNumber)
2480 MakefileName = property(_GetMakefileName)
2481 BsBaseAddress = property(_GetBsBaseAddress)
2482 RtBaseAddress = property(_GetRtBaseAddress)
2483 LoadFixAddress = property(_GetLoadFixAddress)
2484 RFCLanguages = property(_GetRFCLanguages)
2485 ISOLanguages = property(_GetISOLanguages)
2486 VpdToolGuid = property(_GetVpdToolGuid)
2487 SkuIds = property(_GetSkuIds)
2488 Modules = property(_GetModules)
2489 LibraryInstances = property(_GetLibraryInstances)
2490 LibraryClasses = property(_GetLibraryClasses)
2491 Pcds = property(_GetPcds)
2492 BuildOptions = property(_GetBuildOptions)
2493 ToolChainFamily = property(_GetToolChainFamily)