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