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