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