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