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