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