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