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