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