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