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