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