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