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