]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
5ed879c8d7a919dc48f5c721df57b0d768c58e32
[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 IncludedFileList = []
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() in TAB_PCD_NUMERIC_TYPES_VOID \
941 and self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
942 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,
943 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
944 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
945 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
946 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
947 return ValueList
948
949 def _FilterPcdBySkuUsage(self, Pcds):
950 available_sku = self.SkuIdMgr.AvailableSkuIdSet
951 sku_usage = self.SkuIdMgr.SkuUsageType
952 if sku_usage == SkuClass.SINGLE:
953 for pcdname in Pcds:
954 pcd = Pcds[pcdname]
955 Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
956 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
957 Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
958 else:
959 for pcdname in Pcds:
960 pcd = Pcds[pcdname]
961 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
962 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
963 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
964 return Pcds
965
966 def CompleteHiiPcdsDefaultStores(self, Pcds):
967 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]]]
968 DefaultStoreMgr = DefaultStore(self.DefaultStores)
969 for pcd in HiiPcd:
970 for skuid in pcd.SkuInfoList:
971 skuobj = pcd.SkuInfoList.get(skuid)
972 if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
973 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
974 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
975 skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
976 return Pcds
977
978 def RecoverCommandLinePcd(self):
979 def UpdateCommandLineValue(pcd):
980 if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
981 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
982 pcd.PcdValueFromComm = pcd.DefaultValue
983 elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
984 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
985 else:
986 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
987 for pcd in self._Pcds:
988 if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
989 UpdateCommandLineValue(self._Pcds[pcd])
990
991 def __ParsePcdFromCommandLine(self):
992 if GlobalData.BuildOptionPcd:
993 for i, pcd in enumerate(GlobalData.BuildOptionPcd):
994 if isinstance(pcd, tuple):
995 continue
996 (pcdname, pcdvalue) = pcd.split('=')
997 if not pcdvalue:
998 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
999 if '.' in pcdname:
1000 (Name1, Name2) = pcdname.split('.', 1)
1001 if "." in Name2:
1002 (Name3, FieldName) = Name2.split(".", 1)
1003 if ((Name3, Name1)) in self.DecPcds:
1004 HasTokenSpace = True
1005 TokenCName = Name3
1006 TokenSpaceGuidCName = Name1
1007 else:
1008 FieldName = Name2
1009 TokenCName = Name1
1010 TokenSpaceGuidCName = ''
1011 HasTokenSpace = False
1012 else:
1013 if ((Name2, Name1)) in self.DecPcds:
1014 HasTokenSpace = True
1015 TokenCName = Name2
1016 TokenSpaceGuidCName = Name1
1017 FieldName =""
1018 else:
1019 FieldName = Name2
1020 TokenCName = Name1
1021 TokenSpaceGuidCName = ''
1022 HasTokenSpace = False
1023 else:
1024 FieldName = ""
1025 TokenCName = pcdname
1026 TokenSpaceGuidCName = ''
1027 HasTokenSpace = False
1028 TokenSpaceGuidCNameList = []
1029 FoundFlag = False
1030 PcdDatumType = ''
1031 DisplayName = TokenCName
1032 if FieldName:
1033 DisplayName = TokenCName + '.' + FieldName
1034 if not HasTokenSpace:
1035 for key in self.DecPcds:
1036 PcdItem = self.DecPcds[key]
1037 if TokenCName == PcdItem.TokenCName:
1038 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
1039 if len (TokenSpaceGuidCNameList) < 1:
1040 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
1041 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
1042 PcdDatumType = PcdItem.DatumType
1043 FoundFlag = True
1044 else:
1045 EdkLogger.error(
1046 'build',
1047 AUTOGEN_ERROR,
1048 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
1049 )
1050 else:
1051 if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
1052 PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
1053 FoundFlag = True
1054 if not FoundFlag:
1055 if HasTokenSpace:
1056 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
1057 else:
1058 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
1059 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
1060 if FieldName:
1061 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
1062 else:
1063 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
1064 IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
1065 if not IsValid:
1066 EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
1067 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
1068
1069 for BuildData in self._Bdb._CACHE_.values():
1070 if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
1071 continue
1072 for key in BuildData.Pcds:
1073 PcdItem = BuildData.Pcds[key]
1074 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
1075 PcdItem.DefaultValue = pcdvalue
1076 #In command line, the latter full assign value in commandLine should override the former field assign value.
1077 #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
1078 delete_assign = []
1079 field_assign = {}
1080 if GlobalData.BuildOptionPcd:
1081 for pcdTuple in GlobalData.BuildOptionPcd:
1082 TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]
1083 if Field:
1084 if (TokenSpaceGuid, Token) not in field_assign:
1085 field_assign[TokenSpaceGuid, Token] = []
1086 field_assign[TokenSpaceGuid, Token].append(pcdTuple)
1087 else:
1088 if (TokenSpaceGuid, Token) in field_assign:
1089 delete_assign.extend(field_assign[TokenSpaceGuid, Token])
1090 field_assign[TokenSpaceGuid, Token] = []
1091 for item in delete_assign:
1092 GlobalData.BuildOptionPcd.remove(item)
1093
1094 @staticmethod
1095 def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
1096 if FieldName:
1097 IsArray = False
1098 TokenCName += '.' + FieldName
1099 if PcdValue.startswith('H'):
1100 if FieldName and IsFieldValueAnArray(PcdValue[1:]):
1101 PcdDatumType = TAB_VOID
1102 IsArray = True
1103 if FieldName and not IsArray:
1104 return PcdValue
1105 try:
1106 PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
1107 except BadExpression as Value:
1108 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1109 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1110 elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
1111 if FieldName and IsFieldValueAnArray(PcdValue):
1112 PcdDatumType = TAB_VOID
1113 IsArray = True
1114 if FieldName and not IsArray:
1115 return PcdValue
1116 try:
1117 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1118 except BadExpression as Value:
1119 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1120 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1121 elif PcdValue.startswith('L'):
1122 PcdValue = 'L"' + PcdValue[1:] + '"'
1123 if FieldName and IsFieldValueAnArray(PcdValue):
1124 PcdDatumType = TAB_VOID
1125 IsArray = True
1126 if FieldName and not IsArray:
1127 return PcdValue
1128 try:
1129 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1130 except BadExpression as Value:
1131 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1132 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1133 else:
1134 if PcdValue.upper() == 'FALSE':
1135 PcdValue = str(0)
1136 if PcdValue.upper() == 'TRUE':
1137 PcdValue = str(1)
1138 if not FieldName:
1139 if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
1140 PcdValue = '"' + PcdValue + '"'
1141 else:
1142 IsArray = False
1143 Base = 10
1144 if PcdValue.upper().startswith('0X'):
1145 Base = 16
1146 try:
1147 Num = int(PcdValue, Base)
1148 except:
1149 PcdValue = '"' + PcdValue + '"'
1150 if IsFieldValueAnArray(PcdValue):
1151 PcdDatumType = TAB_VOID
1152 IsArray = True
1153 if not IsArray:
1154 return PcdValue
1155 try:
1156 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1157 except BadExpression as Value:
1158 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1159 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1160 return PcdValue
1161
1162 ## Retrieve all PCD settings in platform
1163 @property
1164 def Pcds(self):
1165 if self._Pcds is None:
1166 self._Pcds = OrderedDict()
1167 self.__ParsePcdFromCommandLine()
1168 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
1169 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
1170 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
1171 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
1172 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
1173 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
1174 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
1175 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
1176 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
1177
1178 self._Pcds = self.CompletePcdValues(self._Pcds)
1179 self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
1180 self._Pcds = self.OverrideByCommOverAll(self._Pcds)
1181 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
1182 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
1183 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
1184
1185 self.RecoverCommandLinePcd()
1186 return self._Pcds
1187
1188 ## Retrieve [BuildOptions]
1189 @property
1190 def BuildOptions(self):
1191 if self._BuildOptions is None:
1192 self._BuildOptions = OrderedDict()
1193 #
1194 # Retrieve build option for EDKII and EDK style module
1195 #
1196 for CodeBase in (EDKII_NAME, EDK_NAME):
1197 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
1198 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1199 if Dummy3.upper() != TAB_COMMON:
1200 continue
1201 CurKey = (ToolChainFamily, ToolChain, CodeBase)
1202 #
1203 # Only flags can be appended
1204 #
1205 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1206 self._BuildOptions[CurKey] = Option
1207 else:
1208 if ' ' + Option not in self._BuildOptions[CurKey]:
1209 self._BuildOptions[CurKey] += ' ' + Option
1210 return self._BuildOptions
1211
1212 def GetBuildOptionsByModuleType(self, Edk, ModuleType):
1213 if self._ModuleTypeOptions is None:
1214 self._ModuleTypeOptions = OrderedDict()
1215 if (Edk, ModuleType) not in self._ModuleTypeOptions:
1216 options = OrderedDict()
1217 self._ModuleTypeOptions[Edk, ModuleType] = options
1218 DriverType = '%s.%s' % (Edk, ModuleType)
1219 CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
1220 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
1221 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1222 Type = Dummy2 + '.' + Dummy3
1223 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
1224 Key = (ToolChainFamily, ToolChain, Edk)
1225 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1226 options[Key] = Option
1227 else:
1228 if ' ' + Option not in options[Key]:
1229 options[Key] += ' ' + Option
1230 return self._ModuleTypeOptions[Edk, ModuleType]
1231
1232 @staticmethod
1233 def GetStructurePcdInfo(PcdSet):
1234 structure_pcd_data = defaultdict(list)
1235 for item in PcdSet:
1236 structure_pcd_data[(item[0], item[1])].append(item)
1237
1238 return structure_pcd_data
1239
1240 @staticmethod
1241 def OverrideByFdf(StruPcds,workspace):
1242 if GlobalData.gFdfParser is None:
1243 return StruPcds
1244 StructurePcdInFdf = OrderedDict()
1245 fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
1246 fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
1247 for item in fdfpcd :
1248 if len(item[2]) and (item[0],item[1]) in StruPcds:
1249 StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
1250 GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
1251 for Pcd in StruPcds.values():
1252 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
1253 continue
1254 FieldValues = OrderedDict()
1255 for item in StructurePcdInFdf:
1256 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
1257 FieldValues[item[2]] = StructurePcdInFdf[item]
1258 for field in FieldValues:
1259 if field not in Pcd.PcdFieldValueFromFdf:
1260 Pcd.PcdFieldValueFromFdf[field] = ["","",""]
1261 Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
1262 Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
1263 Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
1264
1265 return StruPcds
1266
1267 @staticmethod
1268 def OverrideByComm(StruPcds):
1269 StructurePcdInCom = OrderedDict()
1270 for item in GlobalData.BuildOptionPcd:
1271 if len(item) == 5 and (item[1], item[0]) in StruPcds:
1272 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
1273 GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
1274 for Pcd in StruPcds.values():
1275 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
1276 continue
1277 FieldValues = OrderedDict()
1278 for item in StructurePcdInCom:
1279 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
1280 FieldValues[item[2]] = StructurePcdInCom[item]
1281 for field in FieldValues:
1282 if field not in Pcd.PcdFieldValueFromComm:
1283 Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
1284 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
1285 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
1286 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
1287 return StruPcds
1288
1289 def OverrideByCommOverAll(self,AllPcds):
1290 def CheckStructureInComm(commpcds):
1291 if not commpcds:
1292 return False
1293 if len(commpcds[0]) == 5:
1294 return True
1295 return False
1296 NoFiledValues = OrderedDict()
1297 if CheckStructureInComm(GlobalData.BuildOptionPcd):
1298 StructurePcdInCom = OrderedDict()
1299 for item in GlobalData.BuildOptionPcd:
1300 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
1301 for item in StructurePcdInCom:
1302 if not item[2]:
1303 NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]
1304 else:
1305 for item in GlobalData.BuildOptionPcd:
1306 NoFiledValues[(item[0], item[1])] = [item[2]]
1307 for Guid, Name in NoFiledValues:
1308 if (Name, Guid) in AllPcds:
1309 Pcd = AllPcds.get((Name, Guid))
1310 if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
1311 self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1312 else:
1313 Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1314 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1315 for sku in Pcd.SkuInfoList:
1316 SkuInfo = Pcd.SkuInfoList[sku]
1317 if SkuInfo.DefaultValue:
1318 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1319 else:
1320 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1321 for defaultstore in SkuInfo.DefaultStoreDict:
1322 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1323 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1324 if Pcd.DatumType == TAB_VOID:
1325 if not Pcd.MaxDatumSize:
1326 Pcd.MaxDatumSize = '0'
1327 CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1328 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1329 MaxSize = max(CurrentSize, OptionSize)
1330 Pcd.MaxDatumSize = str(MaxSize)
1331 else:
1332 PcdInDec = self.DecPcds.get((Name, Guid))
1333 if PcdInDec:
1334 PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
1335 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1336 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1337 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
1338 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1339 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1340 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1341 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
1342 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1343 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1344 self.Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
1345 return AllPcds
1346
1347 def OverrideByFdfOverAll(self,AllPcds):
1348
1349 if GlobalData.gFdfParser is None:
1350 return AllPcds
1351 NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
1352 for Name,Guid,Field in NoFiledValues:
1353 if len(Field):
1354 continue
1355 Value = NoFiledValues[(Name,Guid,Field)]
1356 if (Name,Guid) in AllPcds:
1357 Pcd = AllPcds.get((Name,Guid))
1358 if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
1359 self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
1360 else:
1361 Pcd.PcdValueFromComm = Value
1362 Pcd.DefaultValue = Value
1363 for sku in Pcd.SkuInfoList:
1364 SkuInfo = Pcd.SkuInfoList[sku]
1365 if SkuInfo.DefaultValue:
1366 SkuInfo.DefaultValue = Value
1367 else:
1368 SkuInfo.HiiDefaultValue = Value
1369 for defaultstore in SkuInfo.DefaultStoreDict:
1370 SkuInfo.DefaultStoreDict[defaultstore] = Value
1371 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1372 if Pcd.DatumType == TAB_VOID:
1373 if not Pcd.MaxDatumSize:
1374 Pcd.MaxDatumSize = '0'
1375 CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1376 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1377 MaxSize = max(CurrentSize, OptionSize)
1378 Pcd.MaxDatumSize = str(MaxSize)
1379 else:
1380 PcdInDec = self.DecPcds.get((Name,Guid))
1381 if PcdInDec:
1382 PcdInDec.PcdValueFromFdf = Value
1383 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1384 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1385 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
1386 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1387 self.Pcds[Name, Guid].DefaultValue = Value
1388 return AllPcds
1389
1390 def UpdateStructuredPcds(self, TypeList, AllPcds):
1391
1392 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1393 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1394 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1395 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1396 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1397 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
1398
1399 Pcds = AllPcds
1400 DefaultStoreMgr = DefaultStore(self.DefaultStores)
1401 SkuIds = self.SkuIds
1402 DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
1403
1404 S_PcdSet = []
1405 # Find out all possible PCD candidates for self._Arch
1406 RecordList = []
1407
1408 for Type in TypeList:
1409 RecordList.extend(self._RawData[Type, self._Arch])
1410
1411 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
1412 SkuName = SkuName.upper()
1413 default_store = default_store.upper()
1414 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1415 if SkuName not in SkuIds:
1416 continue
1417
1418 if SkuName in SkuIds and "." in TokenSpaceGuid:
1419 S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
1420
1421 # handle pcd value override
1422 StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
1423 S_pcd_set = OrderedDict()
1424 for str_pcd in StrPcdSet:
1425 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1426 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1427 if not isinstance (str_pcd_dec, StructurePcd):
1428 EdkLogger.error('build', PARSER_ERROR,
1429 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1430 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1431 if str_pcd_dec:
1432 str_pcd_obj_str = StructurePcd()
1433 str_pcd_obj_str.copy(str_pcd_dec)
1434 if str_pcd_obj:
1435 str_pcd_obj_str.copy(str_pcd_obj)
1436 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1437 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}
1438 else:
1439 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}
1440 for str_pcd_data in StrPcdSet[str_pcd]:
1441 if str_pcd_data[3] in SkuIds:
1442 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])
1443 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1444 else:
1445 EdkLogger.error('build', PARSER_ERROR,
1446 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1447 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1448 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1449 for Pcd in self.DecPcds:
1450 if isinstance(self._DecPcds[Pcd], StructurePcd):
1451 if Pcd not in S_pcd_set:
1452 str_pcd_obj_str = StructurePcd()
1453 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1454 str_pcd_obj = Pcds.get(Pcd, None)
1455 if str_pcd_obj:
1456 str_pcd_obj_str.copy(str_pcd_obj)
1457 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1458 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}
1459 else:
1460 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}
1461 S_pcd_set[Pcd] = str_pcd_obj_str
1462 if S_pcd_set:
1463 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1464 for stru_pcd in S_pcd_set.values():
1465 for skuid in SkuIds:
1466 if skuid in stru_pcd.SkuOverrideValues:
1467 continue
1468 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1469 NoDefault = False
1470 if skuid not in stru_pcd.SkuOverrideValues:
1471 while nextskuid not in stru_pcd.SkuOverrideValues:
1472 if nextskuid == TAB_DEFAULT:
1473 NoDefault = True
1474 break
1475 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1476 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})
1477 if not NoDefault:
1478 stru_pcd.ValueChain.add((skuid, ''))
1479 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1480 for skuid in SkuIds:
1481 nextskuid = skuid
1482 NoDefault = False
1483 if skuid not in stru_pcd.SkuOverrideValues:
1484 while nextskuid not in stru_pcd.SkuOverrideValues:
1485 if nextskuid == TAB_DEFAULT:
1486 NoDefault = True
1487 break
1488 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1489 if NoDefault:
1490 continue
1491 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
1492 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1493
1494 for defaultstoreid in DefaultStores:
1495 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1496 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1497 stru_pcd.ValueChain.add((skuid, defaultstoreid))
1498 S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
1499 S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
1500 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1501 if Str_Pcd_Values:
1502 for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
1503 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1504 if str_pcd_obj is None:
1505 print(PcdName, PcdGuid)
1506 raise
1507 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1508 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1509 if skuname not in str_pcd_obj.SkuInfoList:
1510 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1511 else:
1512 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1513 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1514 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1515 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1516 if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1517 str_pcd_obj.DefaultValue = PcdValue
1518 else:
1519 if skuname not in str_pcd_obj.SkuInfoList:
1520 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1521 NoDefault = False
1522 while nextskuid not in str_pcd_obj.SkuInfoList:
1523 if nextskuid == TAB_DEFAULT:
1524 NoDefault = True
1525 break
1526 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1527 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)
1528 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1529 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1530 else:
1531 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1532 for str_pcd_obj in S_pcd_set.values():
1533 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1534 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1535 continue
1536 PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
1537 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1538 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1539 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1540
1541 for str_pcd_obj in S_pcd_set.values():
1542
1543 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1544 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1545 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
1546
1547 for pcdkey in Pcds:
1548 pcd = Pcds[pcdkey]
1549 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1550 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
1551 del pcd.SkuInfoList[TAB_COMMON]
1552 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1553 del pcd.SkuInfoList[TAB_COMMON]
1554
1555 list(map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType]))
1556 return Pcds
1557
1558 ## Retrieve non-dynamic PCD settings
1559 #
1560 # @param Type PCD type
1561 #
1562 # @retval a dict object contains settings of given PCD type
1563 #
1564 def _GetPcd(self, Type):
1565 Pcds = OrderedDict()
1566 #
1567 # tdict is a special dict kind of type, used for selecting correct
1568 # PCD settings for certain ARCH
1569 #
1570 AvailableSkuIdSet = copy.copy(self.SkuIds)
1571
1572 PcdDict = tdict(True, 3)
1573 PcdSet = set()
1574 # Find out all possible PCD candidates for self._Arch
1575 RecordList = self._RawData[Type, self._Arch]
1576 PcdValueDict = OrderedDict()
1577 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
1578 SkuName = SkuName.upper()
1579 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1580 if SkuName not in AvailableSkuIdSet:
1581 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1582 File=self.MetaFile, Line=Dummy5)
1583 if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1584 if "." not in TokenSpaceGuid:
1585 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1586 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1587
1588 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1589 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1590 if Setting is None:
1591 continue
1592 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1593 if MaxDatumSize:
1594 if int(MaxDatumSize, 0) > 0xFFFF:
1595 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1596 File=self.MetaFile, Line=Dummy4)
1597 if int(MaxDatumSize, 0) < 0:
1598 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1599 File=self.MetaFile, Line=Dummy4)
1600 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1601 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1602 else:
1603 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1604
1605 for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
1606 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1607 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1608 elif TAB_DEFAULT in PcdSetting:
1609 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
1610 elif TAB_COMMON in PcdSetting:
1611 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
1612 else:
1613 PcdValue = None
1614 DatumType = None
1615 MaxDatumSize = None
1616
1617 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1618 PcdCName,
1619 TokenSpaceGuid,
1620 self._PCD_TYPE_STRING_[Type],
1621 DatumType,
1622 PcdValue,
1623 '',
1624 MaxDatumSize,
1625 {},
1626 False,
1627 None,
1628 IsDsc=True)
1629
1630 if self.SkuIdMgr.SystemSkuId not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
1631 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId] = {}
1632 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
1633 return Pcds
1634
1635 def GetStructurePcdMaxSize(self, str_pcd):
1636 pcd_default_value = str_pcd.DefaultValue
1637 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()]
1638 sku_values.append(pcd_default_value)
1639
1640 def get_length(value):
1641 Value = value.strip()
1642 if len(value) > 1:
1643 if Value.startswith(TAB_GUID) and Value.endswith(')'):
1644 return 16
1645 if Value.startswith('L"') and Value.endswith('"'):
1646 return len(Value[2:-1])
1647 if Value[0] == '"' and Value[-1] == '"':
1648 return len(Value) - 2
1649 if Value[0] == '{' and Value[-1] == '}':
1650 return len(Value.split(","))
1651 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1652 return len(list(Value[2:-1]))
1653 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1654 return len(Value) - 2
1655 return len(Value)
1656
1657 return str(max(get_length(item) for item in sku_values))
1658
1659 @staticmethod
1660 def ExecuteCommand (Command):
1661 try:
1662 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1663 except:
1664 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1665 Result = Process.communicate()
1666 return Process.returncode, Result[0].decode(encoding='utf-8', errors='ignore'), Result[1].decode(encoding='utf-8', errors='ignore')
1667
1668 @staticmethod
1669 def IntToCString(Value, ValueSize):
1670 Result = '"'
1671 if not isinstance (Value, str):
1672 for Index in range(0, ValueSize):
1673 Result = Result + '\\x%02x' % (Value & 0xff)
1674 Value = Value >> 8
1675 Result = Result + '"'
1676 return Result
1677
1678 def GenerateSizeFunction(self, Pcd):
1679 CApp = "// Default Value in Dec \n"
1680 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1681 for FieldList in [Pcd.DefaultValues]:
1682 if not FieldList:
1683 continue
1684 for FieldName in FieldList:
1685 FieldName = "." + FieldName
1686 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1687 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1688 try:
1689 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1690 except BadExpression:
1691 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1692 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1693 Value, ValueSize = ParseFieldValue(Value)
1694 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]);
1695 else:
1696 NewFieldName = ''
1697 FieldName_ori = FieldName.strip('.')
1698 while '[' in FieldName:
1699 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1700 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1701 FieldName = FieldName.split(']', 1)[1]
1702 FieldName = NewFieldName + FieldName
1703 while '[' in FieldName:
1704 FieldName = FieldName.rsplit('[', 1)[0]
1705 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])
1706 for skuname in Pcd.SkuOverrideValues:
1707 if skuname == TAB_COMMON:
1708 continue
1709 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
1710 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1711 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
1712 if not FieldList:
1713 continue
1714 for FieldName in FieldList:
1715 FieldName = "." + FieldName
1716 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1717 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1718 try:
1719 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1720 except BadExpression:
1721 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1722 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1723 Value, ValueSize = ParseFieldValue(Value)
1724 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]);
1725 else:
1726 NewFieldName = ''
1727 FieldName_ori = FieldName.strip('.')
1728 while '[' in FieldName:
1729 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1730 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1731 FieldName = FieldName.split(']', 1)[1]
1732 FieldName = NewFieldName + FieldName
1733 while '[' in FieldName:
1734 FieldName = FieldName.rsplit('[', 1)[0]
1735 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])
1736 if Pcd.PcdFieldValueFromFdf:
1737 CApp = CApp + "// From fdf \n"
1738 for FieldName in Pcd.PcdFieldValueFromFdf:
1739 FieldName = "." + FieldName
1740 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
1741 if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
1742 try:
1743 Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1744 except BadExpression:
1745 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1746 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
1747 Value, ValueSize = ParseFieldValue(Value)
1748 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]);
1749 else:
1750 NewFieldName = ''
1751 FieldName_ori = FieldName.strip('.')
1752 while '[' in FieldName:
1753 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1754 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1755 FieldName = FieldName.split(']', 1)[1]
1756 FieldName = NewFieldName + FieldName
1757 while '[' in FieldName:
1758 FieldName = FieldName.rsplit('[', 1)[0]
1759 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])
1760 if Pcd.PcdFieldValueFromComm:
1761 CApp = CApp + "// From Command Line \n"
1762 for FieldName in Pcd.PcdFieldValueFromComm:
1763 FieldName = "." + FieldName
1764 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
1765 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
1766 try:
1767 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1768 except BadExpression:
1769 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1770 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
1771 Value, ValueSize = ParseFieldValue(Value)
1772 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]);
1773 else:
1774 NewFieldName = ''
1775 FieldName_ori = FieldName.strip('.')
1776 while '[' in FieldName:
1777 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1778 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1779 FieldName = FieldName.split(']', 1)[1]
1780 FieldName = NewFieldName + FieldName
1781 while '[' in FieldName:
1782 FieldName = FieldName.rsplit('[', 1)[0]
1783 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])
1784 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
1785 CApp = CApp + "}\n"
1786 return CApp
1787
1788 @staticmethod
1789 def GenerateSizeStatments(Pcd):
1790 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1791 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1792 return CApp
1793
1794 def GenerateDefaultValueAssignFunction(self, Pcd):
1795 CApp = "// Default value in Dec \n"
1796 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1797 CApp = CApp + ' UINT32 FieldSize;\n'
1798 CApp = CApp + ' CHAR8 *Value;\n'
1799 DefaultValueFromDec = Pcd.DefaultValueFromDec
1800 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
1801 if IsArray:
1802 try:
1803 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
1804 except BadExpression:
1805 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
1806 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
1807 DefaultValueFromDec = StringToArray(DefaultValueFromDec)
1808 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
1809 if isinstance(Value, str):
1810 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
1811 elif IsArray:
1812 #
1813 # Use memcpy() to copy value into field
1814 #
1815 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
1816 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1817 for FieldList in [Pcd.DefaultValues]:
1818 if not FieldList:
1819 continue
1820 for FieldName in FieldList:
1821 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1822 if IsArray:
1823 try:
1824 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1825 except BadExpression:
1826 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1827 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1828
1829 try:
1830 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1831 except Exception:
1832 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]))
1833 if isinstance(Value, str):
1834 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1835 elif IsArray:
1836 #
1837 # Use memcpy() to copy value into field
1838 #
1839 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1840 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1841 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1842 else:
1843 if ValueSize > 4:
1844 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1845 else:
1846 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1847 CApp = CApp + "}\n"
1848 return CApp
1849
1850 @staticmethod
1851 def GenerateDefaultValueAssignStatement(Pcd):
1852 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1853 return CApp
1854
1855 def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
1856 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
1857 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)
1858 CApp = CApp + ' UINT32 FieldSize;\n'
1859 CApp = CApp + ' CHAR8 *Value;\n'
1860
1861 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
1862 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
1863 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1864 pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
1865 else:
1866 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
1867 for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:
1868 if not FieldList:
1869 continue
1870 if pcddefaultvalue and FieldList == pcddefaultvalue:
1871 IsArray = IsFieldValueAnArray(FieldList)
1872 if IsArray:
1873 try:
1874 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1875 except BadExpression:
1876 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1877 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1878 Value, ValueSize = ParseFieldValue (FieldList)
1879
1880 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1881 if isinstance(Value, str):
1882 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)
1883 elif IsArray:
1884 #
1885 # Use memcpy() to copy value into field
1886 #
1887 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)
1888 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1889 else:
1890 if isinstance(Value, str):
1891 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1892 elif IsArray:
1893 #
1894 # Use memcpy() to copy value into field
1895 #
1896 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1897 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1898 continue
1899 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
1900 for FieldName in FieldList:
1901 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1902 if IsArray:
1903 try:
1904 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1905 except BadExpression:
1906 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1907 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1908 try:
1909 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1910 except Exception:
1911 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]))
1912 if isinstance(Value, str):
1913 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1914 elif IsArray:
1915 #
1916 # Use memcpy() to copy value into field
1917 #
1918 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1919 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1920 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1921 else:
1922 if ValueSize > 4:
1923 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1924 else:
1925 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1926 CApp = CApp + "}\n"
1927 return CApp
1928
1929 @staticmethod
1930 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
1931 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
1932 return CApp
1933
1934 def GenerateCommandLineValue(self, Pcd):
1935 CApp = "// Value in CommandLine\n"
1936 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1937 CApp = CApp + ' UINT32 FieldSize;\n'
1938 CApp = CApp + ' CHAR8 *Value;\n'
1939
1940 pcddefaultvalue = Pcd.PcdValueFromComm
1941 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
1942 if not FieldList:
1943 continue
1944 if pcddefaultvalue and FieldList == pcddefaultvalue:
1945 IsArray = IsFieldValueAnArray(FieldList)
1946 if IsArray:
1947 try:
1948 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1949 except BadExpression:
1950 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1951 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1952 Value, ValueSize = ParseFieldValue (FieldList)
1953
1954 if isinstance(Value, str):
1955 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1956 elif IsArray:
1957 #
1958 # Use memcpy() to copy value into field
1959 #
1960 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
1961 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1962 continue
1963 for FieldName in FieldList:
1964 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1965 if IsArray:
1966 try:
1967 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1968 except BadExpression:
1969 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1970 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1971 except:
1972 print("error")
1973 try:
1974 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1975 except Exception:
1976 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]))
1977 if isinstance(Value, str):
1978 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1979 elif IsArray:
1980 #
1981 # Use memcpy() to copy value into field
1982 #
1983 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1984 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1985 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1986 else:
1987 if ValueSize > 4:
1988 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1989 else:
1990 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1991 CApp = CApp + "}\n"
1992 return CApp
1993
1994 @staticmethod
1995 def GenerateCommandLineValueStatement(Pcd):
1996 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1997 return CApp
1998 def GenerateFdfValue(self,Pcd):
1999 CApp = "// Value in Fdf\n"
2000 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
2001 CApp = CApp + ' UINT32 FieldSize;\n'
2002 CApp = CApp + ' CHAR8 *Value;\n'
2003
2004 pcddefaultvalue = Pcd.PcdValueFromFdf
2005 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
2006 if not FieldList:
2007 continue
2008 if pcddefaultvalue and FieldList == pcddefaultvalue:
2009 IsArray = IsFieldValueAnArray(FieldList)
2010 if IsArray:
2011 try:
2012 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
2013 except BadExpression:
2014 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
2015 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
2016 Value, ValueSize = ParseFieldValue (FieldList)
2017
2018 if isinstance(Value, str):
2019 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
2020 elif IsArray:
2021 #
2022 # Use memcpy() to copy value into field
2023 #
2024 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
2025 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
2026 continue
2027 for FieldName in FieldList:
2028 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2029 if IsArray:
2030 try:
2031 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2032 except BadExpression:
2033 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2034 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2035 except:
2036 print("error")
2037 try:
2038 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2039 except Exception:
2040 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]))
2041 if isinstance(Value, str):
2042 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2043 elif IsArray:
2044 #
2045 # Use memcpy() to copy value into field
2046 #
2047 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2048 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2049 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2050 else:
2051 if ValueSize > 4:
2052 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2053 else:
2054 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2055 CApp = CApp + "}\n"
2056 return CApp
2057
2058 @staticmethod
2059 def GenerateFdfValueStatement(Pcd):
2060 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2061 return CApp
2062
2063 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
2064 OverrideValues = {DefaultStore:""}
2065 if Pcd.SkuOverrideValues:
2066 OverrideValues = Pcd.SkuOverrideValues[SkuName]
2067 if not OverrideValues:
2068 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
2069 for DefaultStoreName in OverrideValues:
2070 CApp = CApp + 'void\n'
2071 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2072 CApp = CApp + ' void\n'
2073 CApp = CApp + ' )\n'
2074 CApp = CApp + '{\n'
2075 CApp = CApp + ' UINT32 Size;\n'
2076 CApp = CApp + ' UINT32 FieldSize;\n'
2077 CApp = CApp + ' CHAR8 *Value;\n'
2078 CApp = CApp + ' UINT32 OriginalSize;\n'
2079 CApp = CApp + ' VOID *OriginalPcd;\n'
2080 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
2081 CApp = CApp + '\n'
2082
2083 if SkuName in Pcd.SkuInfoList:
2084 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
2085 else:
2086 DefaultValue = Pcd.DefaultValue
2087 PcdDefaultValue = StringToArray(DefaultValue.strip())
2088
2089 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
2090
2091 #
2092 # Get current PCD value and size
2093 #
2094 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2095
2096 #
2097 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
2098 # the correct value. For structures with a flexible array member, the flexible
2099 # array member is detected, and the size is based on the highest index used with
2100 # the flexible array member. The flexible array member must be the last field
2101 # in a structure. The size formula for this case is:
2102 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
2103 #
2104 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)
2105
2106 #
2107 # Allocate and zero buffer for the PCD
2108 # Must handle cases where current value is smaller, larger, or same size
2109 # Always keep that larger one as the current size
2110 #
2111 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
2112 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
2113 CApp = CApp + ' memset (Pcd, 0, Size);\n'
2114
2115 #
2116 # Copy current PCD value into allocated buffer.
2117 #
2118 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
2119
2120 #
2121 # Assign field values in PCD
2122 #
2123 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
2124 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2125 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2126 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
2127 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
2128 for defaultstorenameitem in storeset:
2129 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
2130 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
2131 if skuname == SkuName:
2132 break
2133 else:
2134 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
2135 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2136 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
2137 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
2138 #
2139 # Set new PCD value and size
2140 #
2141 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2142
2143 #
2144 # Free PCD
2145 #
2146 CApp = CApp + ' free (Pcd);\n'
2147 CApp = CApp + '}\n'
2148 CApp = CApp + '\n'
2149 return InitByteValue, CApp
2150 def SkuOverrideValuesEmpty(self,OverrideValues):
2151 if not OverrideValues:
2152 return True
2153 for key in OverrideValues:
2154 if OverrideValues[key]:
2155 return False
2156 return True
2157
2158 def GenerateByteArrayValue (self, StructuredPcds):
2159 #
2160 # Generate/Compile/Run C application to determine if there are any flexible array members
2161 #
2162 if not StructuredPcds:
2163 return
2164
2165 InitByteValue = ""
2166 CApp = PcdMainCHeader
2167
2168 IncludeFiles = set()
2169 for PcdName in StructuredPcds:
2170 Pcd = StructuredPcds[PcdName]
2171 for IncludeFile in Pcd.StructuredPcdIncludeFile:
2172 if IncludeFile not in IncludeFiles:
2173 IncludeFiles.add(IncludeFile)
2174 CApp = CApp + '#include <%s>\n' % (IncludeFile)
2175 CApp = CApp + '\n'
2176 for PcdName in StructuredPcds:
2177 Pcd = StructuredPcds[PcdName]
2178 CApp = CApp + self.GenerateSizeFunction(Pcd)
2179 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
2180 CApp = CApp + self.GenerateFdfValue(Pcd)
2181 CApp = CApp + self.GenerateCommandLineValue(Pcd)
2182 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2183 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2184 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2185 else:
2186 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2187 if SkuName not in Pcd.SkuOverrideValues:
2188 continue
2189 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2190 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
2191 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2192 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2193 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
2194 else:
2195 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2196 if SkuName not in Pcd.SkuOverrideValues:
2197 continue
2198 for DefaultStoreName in Pcd.DefaultStoreName:
2199 Pcd = StructuredPcds[PcdName]
2200 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2201
2202 CApp = CApp + 'VOID\n'
2203 CApp = CApp + 'PcdEntryPoint(\n'
2204 CApp = CApp + ' VOID\n'
2205 CApp = CApp + ' )\n'
2206 CApp = CApp + '{\n'
2207 for Pcd in StructuredPcds.values():
2208 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]]:
2209 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2210 else:
2211 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2212 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
2213 continue
2214 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2215 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2216 CApp = CApp + '}\n'
2217
2218 CApp = CApp + PcdMainCEntry + '\n'
2219
2220 if not os.path.exists(self.OutputPath):
2221 os.makedirs(self.OutputPath)
2222 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2223 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2224
2225 MakeApp = PcdMakefileHeader
2226 if sys.platform == "win32":
2227 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2228 else:
2229 MakeApp = MakeApp + PcdGccMakefile
2230 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2231 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2232
2233 IncSearchList = []
2234 PlatformInc = OrderedDict()
2235 for Cache in self._Bdb._CACHE_.values():
2236 if Cache.MetaFile.Ext.lower() != '.dec':
2237 continue
2238 if Cache.Includes:
2239 if str(Cache.MetaFile.Path) not in PlatformInc:
2240 PlatformInc[str(Cache.MetaFile.Path)] = []
2241 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
2242 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
2243
2244 PcdDependDEC = []
2245 for Pcd in StructuredPcds.values():
2246 for PackageDec in Pcd.PackageDecs:
2247 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2248 if not os.path.exists(Package):
2249 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2250 if Package not in PcdDependDEC:
2251 PcdDependDEC.append(Package)
2252
2253 if PlatformInc and PcdDependDEC:
2254 for pkg in PcdDependDEC:
2255 if pkg in PlatformInc:
2256 for inc in PlatformInc[pkg]:
2257 MakeApp += '-I' + str(inc) + ' '
2258 IncSearchList.append(inc)
2259 MakeApp = MakeApp + '\n'
2260
2261 CC_FLAGS = LinuxCFLAGS
2262 if sys.platform == "win32":
2263 CC_FLAGS = WindowsCFLAGS
2264 BuildOptions = OrderedDict()
2265 for Options in self.BuildOptions:
2266 if Options[2] != EDKII_NAME:
2267 continue
2268 Family = Options[0]
2269 if Family and Family != self.ToolChainFamily:
2270 continue
2271 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2272 if Tool != 'CC':
2273 continue
2274
2275 if Target == "*" or Target == self._Target:
2276 if Tag == "*" or Tag == self._Toolchain:
2277 if Arch == "*" or Arch == self.Arch:
2278 if Tool not in BuildOptions:
2279 BuildOptions[Tool] = OrderedDict()
2280 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2281 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2282 else:
2283 # append options for the same tool except PATH
2284 if Attr != 'PATH':
2285 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2286 else:
2287 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2288 if BuildOptions:
2289 for Tool in BuildOptions:
2290 for Attr in BuildOptions[Tool]:
2291 if Attr == "FLAGS":
2292 Value = BuildOptions[Tool][Attr]
2293 ValueList = Value.split()
2294 if ValueList:
2295 for Id, Item in enumerate(ValueList):
2296 if Item in ['-D', '/D', '-U', '/U']:
2297 CC_FLAGS += ' ' + Item
2298 if Id + 1 < len(ValueList):
2299 CC_FLAGS += ' ' + ValueList[Id + 1]
2300 elif Item.startswith(('-D', '/D', '-U', '/U')):
2301 CC_FLAGS += ' ' + Item
2302 MakeApp += CC_FLAGS
2303
2304 if sys.platform == "win32":
2305 MakeApp = MakeApp + PcdMakefileEnd
2306 MakeApp = MakeApp + '\n'
2307 IncludeFileFullPaths = []
2308 for includefile in IncludeFiles:
2309 for includepath in IncSearchList:
2310 includefullpath = os.path.join(str(includepath), includefile)
2311 if os.path.exists(includefullpath):
2312 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2313 break
2314 SearchPathList = []
2315 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2316 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2317 SearchPathList.extend(str(item) for item in IncSearchList)
2318 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
2319 for include_file in IncFileList:
2320 MakeApp += "$(OBJECTS) : %s\n" % include_file
2321 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2322 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2323 SaveFileOnChange(MakeFileName, MakeApp, False)
2324
2325 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2326 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2327 SaveFileOnChange(InputValueFile, InitByteValue, False)
2328
2329 PcdValueInitExe = PcdValueInitName
2330 if not sys.platform == "win32":
2331 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
2332 else:
2333 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
2334
2335 Messages = ''
2336 if sys.platform == "win32":
2337 MakeCommand = 'nmake -f %s' % (MakeFileName)
2338 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2339 Messages = StdOut
2340 else:
2341 MakeCommand = 'make -f %s' % (MakeFileName)
2342 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2343 Messages = StdErr
2344 Messages = Messages.split('\n')
2345 MessageGroup = []
2346 if returncode != 0:
2347 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2348 File = open (CAppBaseFileName + '.c', 'r')
2349 FileData = File.readlines()
2350 File.close()
2351 for Message in Messages:
2352 if " error" in Message or "warning" in Message:
2353 FileInfo = Message.strip().split('(')
2354 if len (FileInfo) > 1:
2355 FileName = FileInfo [0]
2356 FileLine = FileInfo [1].split (')')[0]
2357 else:
2358 FileInfo = Message.strip().split(':')
2359 FileName = FileInfo [0]
2360 FileLine = FileInfo [1]
2361 if FileLine.isdigit():
2362 error_line = FileData[int (FileLine) - 1]
2363 if r"//" in error_line:
2364 c_line, dsc_line = error_line.split(r"//")
2365 else:
2366 dsc_line = error_line
2367 message_itmes = Message.split(":")
2368 Index = 0
2369 if "PcdValueInit.c" not in Message:
2370 if not MessageGroup:
2371 MessageGroup.append(Message)
2372 break
2373 else:
2374 for item in message_itmes:
2375 if "PcdValueInit.c" in item:
2376 Index = message_itmes.index(item)
2377 message_itmes[Index] = dsc_line.strip()
2378 break
2379 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2380 continue
2381 else:
2382 MessageGroup.append(Message)
2383 if MessageGroup:
2384 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2385 else:
2386 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2387
2388 if DscBuildData.NeedUpdateOutput(OutputValueFile, PcdValueInitExe, InputValueFile):
2389 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2390 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
2391 if returncode != 0:
2392 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2393
2394 File = open (OutputValueFile, 'r')
2395 FileBuffer = File.readlines()
2396 File.close()
2397
2398 StructurePcdSet = []
2399 for Pcd in FileBuffer:
2400 PcdValue = Pcd.split ('|')
2401 PcdInfo = PcdValue[0].split ('.')
2402 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2403 return StructurePcdSet
2404
2405 @staticmethod
2406 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
2407 if not os.path.exists(OutputFile):
2408 return True
2409 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2410 return True
2411 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2412 return True
2413 return False
2414
2415 ## Retrieve dynamic PCD settings
2416 #
2417 # @param Type PCD type
2418 #
2419 # @retval a dict object contains settings of given PCD type
2420 #
2421 def _GetDynamicPcd(self, Type):
2422
2423
2424 Pcds = OrderedDict()
2425 #
2426 # tdict is a special dict kind of type, used for selecting correct
2427 # PCD settings for certain ARCH and SKU
2428 #
2429 PcdDict = tdict(True, 4)
2430 PcdList = []
2431 # Find out all possible PCD candidates for self._Arch
2432 RecordList = self._RawData[Type, self._Arch]
2433 AvailableSkuIdSet = copy.copy(self.SkuIds)
2434
2435
2436 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2437 SkuName = SkuName.upper()
2438 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2439 if SkuName not in AvailableSkuIdSet:
2440 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2441 File=self.MetaFile, Line=Dummy5)
2442 if "." not in TokenSpaceGuid:
2443 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2444 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2445
2446 # Remove redundant PCD candidates, per the ARCH and SKU
2447 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2448
2449 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2450 if Setting is None:
2451 continue
2452
2453 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2454 if MaxDatumSize:
2455 if int(MaxDatumSize, 0) > 0xFFFF:
2456 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2457 File=self.MetaFile, Line=Dummy4)
2458 if int(MaxDatumSize, 0) < 0:
2459 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2460 File=self.MetaFile, Line=Dummy4)
2461 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2462 if (PcdCName, TokenSpaceGuid) in Pcds:
2463 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2464 pcdObject.SkuInfoList[SkuName] = SkuInfo
2465 if MaxDatumSize.strip():
2466 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2467 else:
2468 CurrentMaxSize = 0
2469 if pcdObject.MaxDatumSize:
2470 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2471 else:
2472 PcdMaxSize = 0
2473 if CurrentMaxSize > PcdMaxSize:
2474 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2475 else:
2476 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2477 PcdCName,
2478 TokenSpaceGuid,
2479 self._PCD_TYPE_STRING_[Type],
2480 DatumType,
2481 PcdValue,
2482 '',
2483 MaxDatumSize,
2484 OrderedDict({SkuName : SkuInfo}),
2485 False,
2486 None,
2487 IsDsc=True)
2488
2489 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2490 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2491 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
2492
2493 for pcd in Pcds.values():
2494 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2495 # Only fix the value while no value provided in DSC file.
2496 for sku in pcd.SkuInfoList.values():
2497 if not sku.DefaultValue:
2498 sku.DefaultValue = pcdDecObject.DefaultValue
2499 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2500 valuefromDec = pcdDecObject.DefaultValue
2501 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
2502 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2503 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2504 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2505 del pcd.SkuInfoList[TAB_COMMON]
2506 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2507 del pcd.SkuInfoList[TAB_COMMON]
2508
2509 list(map(self.FilterSkuSettings, Pcds.values()))
2510
2511 return Pcds
2512
2513 def FilterSkuSettings(self, PcdObj):
2514
2515 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2516 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
2517 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
2518 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2519 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
2520 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
2521
2522 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2523 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
2524
2525 return PcdObj
2526
2527 @staticmethod
2528 def CompareVarAttr(Attr1, Attr2):
2529 if not Attr1 or not Attr2: # for empty string
2530 return True
2531 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2532 Attr1Set = set(Attr1s)
2533 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2534 Attr2Set = set(Attr2s)
2535 if Attr2Set == Attr1Set:
2536 return True
2537 else:
2538 return False
2539
2540 def CompletePcdValues(self, PcdSet):
2541 Pcds = OrderedDict()
2542 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2543 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
2544 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
2545 for PcdCName, TokenSpaceGuid in PcdSet:
2546 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2547
2548 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2549 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2550 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2551 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2552 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2553 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2554 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2555 continue
2556 PcdType = PcdObj.Type
2557 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2558 for skuid in PcdObj.SkuInfoList:
2559 skuobj = PcdObj.SkuInfoList[skuid]
2560 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
2561 for defaultstorename in DefaultStores:
2562 if defaultstorename not in skuobj.DefaultStoreDict:
2563 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2564 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2565 for skuname, skuid in SkuIds.items():
2566 if skuname not in PcdObj.SkuInfoList:
2567 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2568 while nextskuid not in PcdObj.SkuInfoList:
2569 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2570 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2571 PcdObj.SkuInfoList[skuname].SkuId = skuid
2572 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2573 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2574 PcdObj.DefaultValue = list(PcdObj.SkuInfoList.values())[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
2575 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2576 return Pcds
2577 ## Retrieve dynamic HII PCD settings
2578 #
2579 # @param Type PCD type
2580 #
2581 # @retval a dict object contains settings of given PCD type
2582 #
2583 def _GetDynamicHiiPcd(self, Type):
2584
2585 VariableAttrs = {}
2586
2587 Pcds = OrderedDict()
2588 UserDefinedDefaultStores = []
2589 #
2590 # tdict is a special dict kind of type, used for selecting correct
2591 # PCD settings for certain ARCH and SKU
2592 #
2593 PcdDict = tdict(True, 5)
2594 PcdSet = set()
2595 RecordList = self._RawData[Type, self._Arch]
2596 # Find out all possible PCD candidates for self._Arch
2597 AvailableSkuIdSet = copy.copy(self.SkuIds)
2598 DefaultStoresDefine = self._GetDefaultStores()
2599
2600 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
2601 SkuName = SkuName.upper()
2602 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2603 DefaultStore = DefaultStore.upper()
2604 if DefaultStore == TAB_COMMON:
2605 DefaultStore = TAB_DEFAULT_STORES_DEFAULT
2606 else:
2607 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
2608 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
2609 if SkuName not in AvailableSkuIdSet:
2610 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2611 File=self.MetaFile, Line=Dummy5)
2612 if DefaultStore not in DefaultStoresDefine:
2613 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2614 File=self.MetaFile, Line=Dummy5)
2615 if "." not in TokenSpaceGuid:
2616 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
2617 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
2618
2619
2620 # Remove redundant PCD candidates, per the ARCH and SKU
2621 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:
2622
2623 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
2624 if Setting is None:
2625 continue
2626 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2627
2628 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2629 if not rt:
2630 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2631 ExtraData="[%s]" % VarAttribute)
2632 ExceedMax = False
2633 FormatCorrect = True
2634 if VariableOffset.isdigit():
2635 if int(VariableOffset, 10) > 0xFFFF:
2636 ExceedMax = True
2637 elif variablePattern.match(VariableOffset):
2638 if int(VariableOffset, 16) > 0xFFFF:
2639 ExceedMax = True
2640 # For Offset written in "A.B"
2641 elif VariableOffset.find('.') > -1:
2642 VariableOffsetList = VariableOffset.split(".")
2643 if not (len(VariableOffsetList) == 2
2644 and IsValidWord(VariableOffsetList[0])
2645 and IsValidWord(VariableOffsetList[1])):
2646 FormatCorrect = False
2647 else:
2648 FormatCorrect = False
2649 if not FormatCorrect:
2650 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2651
2652 if ExceedMax:
2653 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2654 if (VariableName, VariableGuid) not in VariableAttrs:
2655 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2656 else:
2657 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2658 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)]))
2659
2660 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2661 if (PcdCName, TokenSpaceGuid) in Pcds:
2662 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2663 if SkuName in pcdObject.SkuInfoList:
2664 Skuitem = pcdObject.SkuInfoList[SkuName]
2665 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2666 else:
2667 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2668 pcdObject.SkuInfoList[SkuName] = SkuInfo
2669 else:
2670 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2671 PcdClassObj = PcdClassObject(
2672 PcdCName,
2673 TokenSpaceGuid,
2674 self._PCD_TYPE_STRING_[Type],
2675 '',
2676 DefaultValue,
2677 '',
2678 '',
2679 OrderedDict({SkuName : SkuInfo}),
2680 False,
2681 None,
2682 pcdDecObject.validateranges,
2683 pcdDecObject.validlists,
2684 pcdDecObject.expressions,
2685 IsDsc=True)
2686 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
2687 PcdClassObj.UserDefinedDefaultStoresFlag = True
2688 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
2689
2690 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
2691 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2692 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2693 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
2694 for pcd in Pcds.values():
2695 SkuInfoObj = list(pcd.SkuInfoList.values())[0]
2696 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2697 pcd.DatumType = pcdDecObject.DatumType
2698 # Only fix the value while no value provided in DSC file.
2699 for sku in pcd.SkuInfoList.values():
2700 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
2701 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2702 for default_store in sku.DefaultStoreDict:
2703 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2704 pcd.DefaultValue = pcdDecObject.DefaultValue
2705 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2706 valuefromDec = pcdDecObject.DefaultValue
2707 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
2708 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2709 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2710 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2711 del pcd.SkuInfoList[TAB_COMMON]
2712 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2713 del pcd.SkuInfoList[TAB_COMMON]
2714
2715 if pcd.MaxDatumSize.strip():
2716 MaxSize = int(pcd.MaxDatumSize, 0)
2717 else:
2718 MaxSize = 0
2719 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
2720 for (_, skuobj) in pcd.SkuInfoList.items():
2721 datalen = 0
2722 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2723 datalen = len(skuobj.HiiDefaultValue.split(","))
2724 if datalen > MaxSize:
2725 MaxSize = datalen
2726 for defaultst in skuobj.DefaultStoreDict:
2727 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2728 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2729 pcd.MaxDatumSize = str(MaxSize)
2730 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
2731 if not rt:
2732 invalidpcd = ",".join(invalidhii)
2733 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)
2734
2735 list(map(self.FilterSkuSettings, Pcds.values()))
2736
2737 return Pcds
2738
2739 @staticmethod
2740 def CheckVariableNameAssignment(Pcds):
2741 invalidhii = []
2742 for pcdname in Pcds:
2743 pcd = Pcds[pcdname]
2744 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
2745 if len(varnameset) > 1:
2746 invalidhii.append(".".join((pcdname[1], pcdname[0])))
2747 if len(invalidhii):
2748 return False, invalidhii
2749 else:
2750 return True, []
2751 ## Retrieve dynamic VPD PCD settings
2752 #
2753 # @param Type PCD type
2754 #
2755 # @retval a dict object contains settings of given PCD type
2756 #
2757 def _GetDynamicVpdPcd(self, Type):
2758
2759
2760 Pcds = OrderedDict()
2761 #
2762 # tdict is a special dict kind of type, used for selecting correct
2763 # PCD settings for certain ARCH and SKU
2764 #
2765 PcdDict = tdict(True, 4)
2766 PcdList = []
2767
2768 # Find out all possible PCD candidates for self._Arch
2769 RecordList = self._RawData[Type, self._Arch]
2770 AvailableSkuIdSet = copy.copy(self.SkuIds)
2771
2772 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2773 SkuName = SkuName.upper()
2774 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2775 if SkuName not in AvailableSkuIdSet:
2776 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2777 File=self.MetaFile, Line=Dummy5)
2778 if "." not in TokenSpaceGuid:
2779 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2780 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2781
2782 # Remove redundant PCD candidates, per the ARCH and SKU
2783 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2784 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2785 if Setting is None:
2786 continue
2787 #
2788 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2789 # For the Integer & Boolean type, the optional data can only be InitialValue.
2790 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2791 # until the DEC parser has been called.
2792 #
2793 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2794 if MaxDatumSize:
2795 if int(MaxDatumSize, 0) > 0xFFFF:
2796 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2797 File=self.MetaFile, Line=Dummy4)
2798 if int(MaxDatumSize, 0) < 0:
2799 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2800 File=self.MetaFile, Line=Dummy4)
2801 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2802 if (PcdCName, TokenSpaceGuid) in Pcds:
2803 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2804 pcdObject.SkuInfoList[SkuName] = SkuInfo
2805 if MaxDatumSize.strip():
2806 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2807 else:
2808 CurrentMaxSize = 0
2809 if pcdObject.MaxDatumSize:
2810 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2811 else:
2812 PcdMaxSize = 0
2813 if CurrentMaxSize > PcdMaxSize:
2814 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2815 else:
2816 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2817 PcdCName,
2818 TokenSpaceGuid,
2819 self._PCD_TYPE_STRING_[Type],
2820 '',
2821 InitialValue,
2822 '',
2823 MaxDatumSize,
2824 OrderedDict({SkuName : SkuInfo}),
2825 False,
2826 None,
2827 IsDsc=True)
2828
2829 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2830 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2831 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
2832 for pcd in Pcds.values():
2833 SkuInfoObj = list(pcd.SkuInfoList.values())[0]
2834 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2835 pcd.DatumType = pcdDecObject.DatumType
2836 # Only fix the value while no value provided in DSC file.
2837 for sku in pcd.SkuInfoList.values():
2838 if not sku.DefaultValue:
2839 sku.DefaultValue = pcdDecObject.DefaultValue
2840 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2841 valuefromDec = pcdDecObject.DefaultValue
2842 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2843 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2844 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2845 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2846 del pcd.SkuInfoList[TAB_COMMON]
2847 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2848 del pcd.SkuInfoList[TAB_COMMON]
2849
2850
2851 list(map(self.FilterSkuSettings, Pcds.values()))
2852 return Pcds
2853
2854 ## Add external modules
2855 #
2856 # The external modules are mostly those listed in FDF file, which don't
2857 # need "build".
2858 #
2859 # @param FilePath The path of module description file
2860 #
2861 def AddModule(self, FilePath):
2862 FilePath = NormPath(FilePath)
2863 if FilePath not in self.Modules:
2864 Module = ModuleBuildClassObject()
2865 Module.MetaFile = FilePath
2866 self.Modules.append(Module)
2867
2868 @property
2869 def ToolChainFamily(self):
2870 self._ToolChainFamily = TAB_COMPILER_MSFT
2871 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2872 if os.path.isfile(BuildConfigurationFile) == True:
2873 TargetTxt = TargetTxtClassObject()
2874 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2875 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2876 if ToolDefinitionFile == '':
2877 ToolDefinitionFile = "tools_def.txt"
2878 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2879 if os.path.isfile(ToolDefinitionFile) == True:
2880 ToolDef = ToolDefClassObject()
2881 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2882 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2883 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2884 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2885 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2886 self._ToolChainFamily = TAB_COMPILER_MSFT
2887 else:
2888 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2889 return self._ToolChainFamily
2890
2891 ## Add external PCDs
2892 #
2893 # The external PCDs are mostly those listed in FDF file to specify address
2894 # or offset information.
2895 #
2896 # @param Name Name of the PCD
2897 # @param Guid Token space guid of the PCD
2898 # @param Value Value of the PCD
2899 #
2900 def AddPcd(self, Name, Guid, Value):
2901 if (Name, Guid) not in self.Pcds:
2902 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2903 self.Pcds[Name, Guid].DefaultValue = Value
2904
2905 @property
2906 def DecPcds(self):
2907 if self._DecPcds is None:
2908 FdfInfList = []
2909 if GlobalData.gFdfParser:
2910 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2911 PkgSet = set()
2912 for Inf in FdfInfList:
2913 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2914 if ModuleFile in self._Modules:
2915 continue
2916 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2917 PkgSet.update(ModuleData.Packages)
2918 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
2919 return self._DecPcds