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