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