]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools:Not miss the full assign value of FixedAtBuild structure PCD
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / DscBuildData.py
1 ## @file
2 # This file is used to create a database used by build tool
3 #
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ## Platform build information from DSC file
16 #
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
19 #
20 from __future__ import print_function
21 from __future__ import absolute_import
22 from Common.StringUtils import *
23 from Common.DataType import *
24 from Common.Misc import *
25 from types import *
26 from Common.Expression import *
27 from CommonDataClass.CommonClass import SkuInfoClass
28 from Common.TargetTxtClassObject import *
29 from Common.ToolDefClassObject import *
30 from .MetaDataTable import *
31 from .MetaFileTable import *
32 from .MetaFileParser import *
33
34 from .WorkspaceCommon import GetDeclaredPcd
35 from Common.Misc import AnalyzeDscPcd
36 from Common.Misc import ProcessDuplicatedInf
37 import re
38 from Common.Parsing import IsValidWord
39 from Common.VariableAttributes import VariableAttributes
40 import Common.GlobalData as GlobalData
41 import subprocess
42 from Common.Misc import SaveFileOnChange
43 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
44 from collections import OrderedDict, defaultdict
45
46 PcdValueInitName = 'PcdValueInit'
47
48 PcdMainCHeader = '''
49 /**
50 DO NOT EDIT
51 FILE auto-generated
52 **/
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <PcdValueCommon.h>
58 '''
59
60 PcdMainCEntry = '''
61 int
62 main (
63 int argc,
64 char *argv[]
65 )
66 {
67 return PcdValueMain (argc, argv);
68 }
69 '''
70
71 PcdMakefileHeader = '''
72 #
73 # DO NOT EDIT
74 # This file is auto-generated by build utility
75 #
76
77 '''
78
79 WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
80 LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
81 PcdMakefileEnd = '''
82 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
83
84 LIBS = $(LIB_PATH)\Common.lib
85
86 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
87 '''
88
89 AppTarget = '''
90 all: $(APPFILE)
91 $(APPFILE): $(OBJECTS)
92 %s
93 '''
94
95 PcdGccMakefile = '''
96 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
97 LIBS = -lCommon
98 '''
99
100 variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$')
101 SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
102 ## regular expressions for finding decimal and hex numbers
103 Pattern = re.compile('^[1-9]\d*|0$')
104 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
105 ## Regular expression for finding header file inclusions
106 from AutoGen.GenMake import gIncludePattern
107
108 ## Find dependencies for one source file
109 #
110 # By searching recursively "#include" directive in file, find out all the
111 # files needed by given source file. The dependecies will be only searched
112 # in given search path list.
113 #
114 # @param SearchPathList The list of search path
115 #
116 # @retval list The list of files the given source file depends on
117 #
118 def GetDependencyList(FileStack, SearchPathList):
119 DepDb = dict()
120 DependencySet = set(FileStack)
121 while len(FileStack) > 0:
122 F = FileStack.pop()
123 FullPathDependList = []
124 CurrentFileDependencyList = []
125 if F in DepDb:
126 CurrentFileDependencyList = DepDb[F]
127 else:
128 try:
129 Fd = open(F, 'r')
130 FileContent = Fd.read()
131 except BaseException as X:
132 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
133 finally:
134 if "Fd" in dir(locals()):
135 Fd.close()
136
137 if len(FileContent) == 0:
138 continue
139
140 if FileContent[0] == 0xff or FileContent[0] == 0xfe:
141 FileContent = unicode(FileContent, "utf-16")
142 IncludedFileList = gIncludePattern.findall(FileContent)
143
144 for Inc in IncludedFileList:
145 Inc = Inc.strip()
146 Inc = os.path.normpath(Inc)
147 CurrentFileDependencyList.append(Inc)
148 DepDb[F] = CurrentFileDependencyList
149
150 CurrentFilePath = os.path.dirname(F)
151 PathList = [CurrentFilePath] + SearchPathList
152 for Inc in CurrentFileDependencyList:
153 for SearchPath in PathList:
154 FilePath = os.path.join(SearchPath, Inc)
155 if not os.path.exists(FilePath):
156 continue
157 if FilePath not in DependencySet:
158 FileStack.append(FilePath)
159 FullPathDependList.append(FilePath)
160 break
161 DependencySet.update(FullPathDependList)
162 DependencyList = list(DependencySet) # remove duplicate ones
163
164 return DependencyList
165
166 class DscBuildData(PlatformBuildClassObject):
167 # dict used to convert PCD type in database to string used by build tool
168 _PCD_TYPE_STRING_ = {
169 MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,
170 MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,
171 MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,
172 MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,
173 MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,
174 MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,
175 MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,
176 MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,
177 MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,
178 MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,
179 MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,
180 }
181
182 # dict used to convert part of [Defines] to members of DscBuildData directly
183 _PROPERTY_ = {
184 #
185 # Required Fields
186 #
187 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
188 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
189 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
190 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
191 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
192 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
193 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
194 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
195 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
196 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
197 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
198 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
199 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
200 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
201 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
202 }
203
204 # used to compose dummy library class name for those forced library instances
205 _NullLibraryNumber = 0
206
207 ## Constructor of DscBuildData
208 #
209 # Initialize object of DscBuildData
210 #
211 # @param FilePath The path of platform description file
212 # @param RawData The raw data of DSC file
213 # @param BuildDataBase Database used to retrieve module/package information
214 # @param Arch The target architecture
215 # @param Platform (not used for DscBuildData)
216 # @param Macros Macros used for replacement in DSC file
217 #
218 def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
219 self.MetaFile = FilePath
220 self._RawData = RawData
221 self._Bdb = BuildDataBase
222 self._Arch = Arch
223 self._Target = Target
224 self._Toolchain = Toolchain
225 self._ToolChainFamily = None
226 self._Clear()
227 self._HandleOverridePath()
228 self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
229 self.DefaultStores = None
230 self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
231
232 @property
233 def OutputPath(self):
234 if os.getenv("WORKSPACE"):
235 return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName)
236 else:
237 return os.path.dirname(self.DscFile)
238
239 ## XXX[key] = value
240 def __setitem__(self, key, value):
241 self.__dict__[self._PROPERTY_[key]] = value
242
243 ## value = XXX[key]
244 def __getitem__(self, key):
245 return self.__dict__[self._PROPERTY_[key]]
246
247 ## "in" test support
248 def __contains__(self, key):
249 return key in self._PROPERTY_
250
251 ## Set all internal used members of DscBuildData to None
252 def _Clear(self):
253 self._Header = None
254 self._PlatformName = None
255 self._Guid = None
256 self._Version = None
257 self._DscSpecification = None
258 self._OutputDirectory = None
259 self._SupArchList = None
260 self._BuildTargets = None
261 self._SkuName = None
262 self._PcdInfoFlag = None
263 self._VarCheckFlag = None
264 self._FlashDefinition = None
265 self._Prebuild = None
266 self._Postbuild = None
267 self._BuildNumber = None
268 self._MakefileName = None
269 self._BsBaseAddress = None
270 self._RtBaseAddress = None
271 self._SkuIds = None
272 self._Modules = None
273 self._LibraryInstances = None
274 self._LibraryClasses = None
275 self._Pcds = None
276 self._DecPcds = None
277 self._BuildOptions = None
278 self._ModuleTypeOptions = None
279 self._LoadFixAddress = None
280 self._RFCLanguages = None
281 self._ISOLanguages = None
282 self._VpdToolGuid = None
283 self._MacroDict = None
284 self.DefaultStores = None
285 self.UsedStructurePcd = None
286
287 ## handle Override Path of Module
288 def _HandleOverridePath(self):
289 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
290 for Record in RecordList:
291 ModuleId = Record[6]
292 LineNo = Record[7]
293 ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
294 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
295 if RecordList != []:
296 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
297
298 # Check if the source override path exists
299 if not os.path.isdir(SourceOverridePath):
300 EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
301
302 # Add to GlobalData Variables
303 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
304
305 ## Get current effective macros
306 @property
307 def _Macros(self):
308 if self._MacroDict is None:
309 self._MacroDict = {}
310 self._MacroDict.update(GlobalData.gPlatformDefines)
311 self._MacroDict.update(GlobalData.gGlobalDefines)
312 self._MacroDict.update(GlobalData.gCommandLineDefines)
313 return self._MacroDict
314
315 ## Get architecture
316 @property
317 def Arch(self):
318 return self._Arch
319
320 ## Retrieve all information in [Defines] section
321 #
322 # (Retriving 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 ## Retrieve [Components] section information
710 @property
711 def Modules(self):
712 if self._Modules is not None:
713 return self._Modules
714
715 self._Modules = OrderedDict()
716 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
717 Macros = self._Macros
718 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
719 for Record in RecordList:
720 DuplicatedFile = False
721
722 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
723 ModuleId = Record[6]
724 LineNo = Record[7]
725
726 # check the file validation
727 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
728 if ErrorCode != 0:
729 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
730 ExtraData=ErrorInfo)
731 # Check duplication
732 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
733 if self._Arch != TAB_ARCH_COMMON and ModuleFile in self._Modules:
734 DuplicatedFile = True
735
736 Module = ModuleBuildClassObject()
737 Module.MetaFile = ModuleFile
738
739 # get module private library instance
740 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
741 for Record in RecordList:
742 LibraryClass = Record[0]
743 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
744 LineNo = Record[-1]
745
746 # check the file validation
747 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
748 if ErrorCode != 0:
749 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
750 ExtraData=ErrorInfo)
751
752 if LibraryClass == '' or LibraryClass == 'NULL':
753 self._NullLibraryNumber += 1
754 LibraryClass = 'NULL%d' % self._NullLibraryNumber
755 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
756 Module.LibraryClasses[LibraryClass] = LibraryPath
757 if LibraryPath not in self.LibraryInstances:
758 self.LibraryInstances.append(LibraryPath)
759
760 # get module private PCD setting
761 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
762 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
763 RecordList = self._RawData[Type, self._Arch, None, ModuleId]
764 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
765 TokenList = GetSplitValueList(Setting)
766 DefaultValue = TokenList[0]
767 # the format is PcdName| Value | VOID* | MaxDatumSize
768 if len(TokenList) > 2:
769 MaxDatumSize = TokenList[2]
770 else:
771 MaxDatumSize = ''
772 TypeString = self._PCD_TYPE_STRING_[Type]
773 Pcd = PcdClassObject(
774 PcdCName,
775 TokenSpaceGuid,
776 TypeString,
777 '',
778 DefaultValue,
779 '',
780 MaxDatumSize,
781 {},
782 False,
783 None
784 )
785 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
786
787 # get module private build options
788 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
789 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
790 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
791 Module.BuildOptions[ToolChainFamily, ToolChain] = Option
792 else:
793 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
794 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
795
796 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
797 if DuplicatedFile and not RecordList:
798 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
799 if RecordList:
800 if len(RecordList) != 1:
801 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
802 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
803 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
804 ModuleFile.Arch = self._Arch
805
806 self._Modules[ModuleFile] = Module
807 return self._Modules
808
809 ## Retrieve all possible library instances used in this platform
810 @property
811 def LibraryInstances(self):
812 if self._LibraryInstances is None:
813 self.LibraryClasses
814 return self._LibraryInstances
815
816 ## Retrieve [LibraryClasses] information
817 @property
818 def LibraryClasses(self):
819 if self._LibraryClasses is None:
820 self._LibraryInstances = []
821 #
822 # tdict is a special dict kind of type, used for selecting correct
823 # library instance for given library class and module type
824 #
825 LibraryClassDict = tdict(True, 3)
826 # track all library class names
827 LibraryClassSet = set()
828 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
829 Macros = self._Macros
830 for Record in RecordList:
831 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, Dummy, LineNo = Record
832 if LibraryClass == '' or LibraryClass == 'NULL':
833 self._NullLibraryNumber += 1
834 LibraryClass = 'NULL%d' % self._NullLibraryNumber
835 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
836 LibraryClassSet.add(LibraryClass)
837 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
838 # check the file validation
839 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
840 if ErrorCode != 0:
841 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
842 ExtraData=ErrorInfo)
843
844 if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST:
845 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
846 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
847 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
848 if LibraryInstance not in self._LibraryInstances:
849 self._LibraryInstances.append(LibraryInstance)
850
851 # resolve the specific library instance for each class and each module type
852 self._LibraryClasses = tdict(True)
853 for LibraryClass in LibraryClassSet:
854 # try all possible module types
855 for ModuleType in SUP_MODULE_LIST:
856 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
857 if LibraryInstance is None:
858 continue
859 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
860
861 # for Edk style library instances, which are listed in different section
862 Macros["EDK_SOURCE"] = GlobalData.gEcpSource
863 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
864 for Record in RecordList:
865 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
866 LineNo = Record[-1]
867 # check the file validation
868 ErrorCode, ErrorInfo = File.Validate('.inf')
869 if ErrorCode != 0:
870 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
871 ExtraData=ErrorInfo)
872 if File not in self._LibraryInstances:
873 self._LibraryInstances.append(File)
874 #
875 # we need the module name as the library class name, so we have
876 # to parse it here. (self._Bdb[] will trigger a file parse if it
877 # hasn't been parsed)
878 #
879 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
880 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
881 return self._LibraryClasses
882
883 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
884 if self._DecPcds is None:
885
886 FdfInfList = []
887 if GlobalData.gFdfParser:
888 FdfInfList = GlobalData.gFdfParser.Profile.InfList
889
890 PkgSet = set()
891 for Inf in FdfInfList:
892 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
893 if ModuleFile in self._Modules:
894 continue
895 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
896 PkgSet.update(ModuleData.Packages)
897
898 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
899 self._GuidDict.update(GlobalData.gPlatformPcds)
900
901 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
902 EdkLogger.error('build', PARSER_ERROR,
903 "Pcd (%s.%s) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
904 File=self.MetaFile, Line=LineNo)
905 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
906 if not IsValid:
907 if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
908 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
909 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
910 else:
911 if ValueList[2] == '-1':
912 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
913 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
914 if ValueList[Index]:
915 DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
916 try:
917 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
918 except BadExpression as Value:
919 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
920 ExtraData="PCD [%s.%s] Value \"%s\" " % (
921 TokenSpaceGuid, PcdCName, ValueList[Index]))
922 except EvaluationException as Excpt:
923 if hasattr(Excpt, 'Pcd'):
924 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
925 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
926 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
927 " of the DSC file" % Excpt.Pcd,
928 File=self.MetaFile, Line=LineNo)
929 else:
930 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
931 File=self.MetaFile, Line=LineNo)
932 else:
933 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
934 File=self.MetaFile, Line=LineNo)
935
936 if ValueList[Index]:
937 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
938 if not Valid:
939 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
940 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
941 if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
942 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
943 EdkLogger.error('build', FORMAT_INVALID, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file.", File=self.MetaFile, Line=LineNo,
944 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
945 if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
946 if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
947 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
948 return ValueList
949
950 def _FilterPcdBySkuUsage(self, Pcds):
951 available_sku = self.SkuIdMgr.AvailableSkuIdSet
952 sku_usage = self.SkuIdMgr.SkuUsageType
953 if sku_usage == SkuClass.SINGLE:
954 for pcdname in Pcds:
955 pcd = Pcds[pcdname]
956 Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
957 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
958 Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
959 else:
960 for pcdname in Pcds:
961 pcd = Pcds[pcdname]
962 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
963 if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
964 Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
965 return Pcds
966
967 def CompleteHiiPcdsDefaultStores(self, Pcds):
968 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]]]
969 DefaultStoreMgr = DefaultStore(self.DefaultStores)
970 for pcd in HiiPcd:
971 for skuid in pcd.SkuInfoList:
972 skuobj = pcd.SkuInfoList.get(skuid)
973 if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
974 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
975 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
976 skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
977 return Pcds
978
979 def RecoverCommandLinePcd(self):
980 def UpdateCommandLineValue(pcd):
981 if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
982 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
983 pcd.PcdValueFromComm = pcd.DefaultValue
984 elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
985 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
986 else:
987 pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
988 for pcd in self._Pcds:
989 if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
990 UpdateCommandLineValue(self._Pcds[pcd])
991
992 def __ParsePcdFromCommandLine(self):
993 if GlobalData.BuildOptionPcd:
994 for i, pcd in enumerate(GlobalData.BuildOptionPcd):
995 if isinstance(pcd, tuple):
996 continue
997 (pcdname, pcdvalue) = pcd.split('=')
998 if not pcdvalue:
999 EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
1000 if '.' in pcdname:
1001 (Name1, Name2) = pcdname.split('.', 1)
1002 if "." in Name2:
1003 (Name3, FieldName) = Name2.split(".", 1)
1004 if ((Name3, Name1)) in self.DecPcds:
1005 HasTokenSpace = True
1006 TokenCName = Name3
1007 TokenSpaceGuidCName = Name1
1008 else:
1009 FieldName = Name2
1010 TokenCName = Name1
1011 TokenSpaceGuidCName = ''
1012 HasTokenSpace = False
1013 else:
1014 if ((Name2, Name1)) in self.DecPcds:
1015 HasTokenSpace = True
1016 TokenCName = Name2
1017 TokenSpaceGuidCName = Name1
1018 FieldName =""
1019 else:
1020 FieldName = Name2
1021 TokenCName = Name1
1022 TokenSpaceGuidCName = ''
1023 HasTokenSpace = False
1024 else:
1025 FieldName = ""
1026 TokenCName = pcdname
1027 TokenSpaceGuidCName = ''
1028 HasTokenSpace = False
1029 TokenSpaceGuidCNameList = []
1030 FoundFlag = False
1031 PcdDatumType = ''
1032 DisplayName = TokenCName
1033 if FieldName:
1034 DisplayName = TokenCName + '.' + FieldName
1035 if not HasTokenSpace:
1036 for key in self.DecPcds:
1037 PcdItem = self.DecPcds[key]
1038 if TokenCName == PcdItem.TokenCName:
1039 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
1040 if len (TokenSpaceGuidCNameList) < 1:
1041 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
1042 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
1043 PcdDatumType = PcdItem.DatumType
1044 FoundFlag = True
1045 else:
1046 EdkLogger.error(
1047 'build',
1048 AUTOGEN_ERROR,
1049 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
1050 )
1051 else:
1052 if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
1053 PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
1054 FoundFlag = True
1055 if not FoundFlag:
1056 if HasTokenSpace:
1057 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
1058 else:
1059 EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
1060 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
1061 if FieldName:
1062 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
1063 else:
1064 pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
1065 IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
1066 if not IsValid:
1067 EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
1068 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
1069
1070 if GlobalData.BuildOptionPcd:
1071 for pcd in GlobalData.BuildOptionPcd:
1072 (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
1073 for BuildData in self._Bdb._CACHE_.values():
1074 if BuildData.Arch != self.Arch:
1075 continue
1076 if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
1077 continue
1078 for key in BuildData.Pcds:
1079 PcdItem = BuildData.Pcds[key]
1080 if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
1081 PcdItem.DefaultValue = pcdvalue
1082 PcdItem.PcdValueFromComm = pcdvalue
1083 #In command line, the latter full assign value in commandLine should override the former field assign value.
1084 #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
1085 delete_assign = []
1086 field_assign = {}
1087 if GlobalData.BuildOptionPcd:
1088 for pcdTuple in GlobalData.BuildOptionPcd:
1089 TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]
1090 if Field:
1091 if (TokenSpaceGuid, Token) not in field_assign:
1092 field_assign[TokenSpaceGuid, Token] = []
1093 field_assign[TokenSpaceGuid, Token].append(pcdTuple)
1094 else:
1095 if (TokenSpaceGuid, Token) in field_assign:
1096 delete_assign.extend(field_assign[TokenSpaceGuid, Token])
1097 field_assign[TokenSpaceGuid, Token] = []
1098 for item in delete_assign:
1099 GlobalData.BuildOptionPcd.remove(item)
1100
1101 @staticmethod
1102 def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
1103 if FieldName:
1104 IsArray = False
1105 TokenCName += '.' + FieldName
1106 if PcdValue.startswith('H'):
1107 if FieldName and IsFieldValueAnArray(PcdValue[1:]):
1108 PcdDatumType = TAB_VOID
1109 IsArray = True
1110 if FieldName and not IsArray:
1111 return PcdValue
1112 try:
1113 PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
1114 except BadExpression as Value:
1115 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1116 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1117 elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
1118 if FieldName and IsFieldValueAnArray(PcdValue):
1119 PcdDatumType = TAB_VOID
1120 IsArray = True
1121 if FieldName and not IsArray:
1122 return PcdValue
1123 try:
1124 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1125 except BadExpression as Value:
1126 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1127 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1128 elif PcdValue.startswith('L'):
1129 PcdValue = 'L"' + PcdValue[1:] + '"'
1130 if FieldName and IsFieldValueAnArray(PcdValue):
1131 PcdDatumType = TAB_VOID
1132 IsArray = True
1133 if FieldName and not IsArray:
1134 return PcdValue
1135 try:
1136 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1137 except BadExpression as Value:
1138 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1139 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1140 else:
1141 if PcdValue.upper() == 'FALSE':
1142 PcdValue = str(0)
1143 if PcdValue.upper() == 'TRUE':
1144 PcdValue = str(1)
1145 if not FieldName:
1146 if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
1147 PcdValue = '"' + PcdValue + '"'
1148 elif not PcdValue.isdigit() and not PcdValue.upper().startswith('0X'):
1149 PcdValue = '"' + PcdValue + '"'
1150 else:
1151 IsArray = False
1152 Base = 10
1153 if PcdValue.upper().startswith('0X'):
1154 Base = 16
1155 try:
1156 Num = int(PcdValue, Base)
1157 except:
1158 PcdValue = '"' + PcdValue + '"'
1159 if IsFieldValueAnArray(PcdValue):
1160 PcdDatumType = TAB_VOID
1161 IsArray = True
1162 if not IsArray:
1163 return PcdValue
1164 try:
1165 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
1166 except BadExpression as Value:
1167 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
1168 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
1169 return PcdValue
1170
1171 ## Retrieve all PCD settings in platform
1172 @property
1173 def Pcds(self):
1174 if self._Pcds is None:
1175 self._Pcds = OrderedDict()
1176 self.__ParsePcdFromCommandLine()
1177 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
1178 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
1179 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
1180 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
1181 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
1182 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
1183 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
1184 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
1185 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
1186
1187 self._Pcds = self.CompletePcdValues(self._Pcds)
1188 self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
1189 self._Pcds = self.OverrideByCommOverAll(self._Pcds)
1190 self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
1191 self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
1192 self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
1193
1194 self.RecoverCommandLinePcd()
1195 return self._Pcds
1196
1197 ## Retrieve [BuildOptions]
1198 @property
1199 def BuildOptions(self):
1200 if self._BuildOptions is None:
1201 self._BuildOptions = OrderedDict()
1202 #
1203 # Retrieve build option for EDKII and EDK style module
1204 #
1205 for CodeBase in (EDKII_NAME, EDK_NAME):
1206 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
1207 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1208 if Dummy3.upper() != TAB_COMMON:
1209 continue
1210 CurKey = (ToolChainFamily, ToolChain, CodeBase)
1211 #
1212 # Only flags can be appended
1213 #
1214 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1215 self._BuildOptions[CurKey] = Option
1216 else:
1217 if ' ' + Option not in self._BuildOptions[CurKey]:
1218 self._BuildOptions[CurKey] += ' ' + Option
1219 return self._BuildOptions
1220
1221 def GetBuildOptionsByModuleType(self, Edk, ModuleType):
1222 if self._ModuleTypeOptions is None:
1223 self._ModuleTypeOptions = OrderedDict()
1224 if (Edk, ModuleType) not in self._ModuleTypeOptions:
1225 options = OrderedDict()
1226 self._ModuleTypeOptions[Edk, ModuleType] = options
1227 DriverType = '%s.%s' % (Edk, ModuleType)
1228 CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
1229 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
1230 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
1231 Type = Dummy2 + '.' + Dummy3
1232 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
1233 Key = (ToolChainFamily, ToolChain, Edk)
1234 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
1235 options[Key] = Option
1236 else:
1237 if ' ' + Option not in options[Key]:
1238 options[Key] += ' ' + Option
1239 return self._ModuleTypeOptions[Edk, ModuleType]
1240
1241 @staticmethod
1242 def GetStructurePcdInfo(PcdSet):
1243 structure_pcd_data = defaultdict(list)
1244 for item in PcdSet:
1245 structure_pcd_data[(item[0], item[1])].append(item)
1246
1247 return structure_pcd_data
1248
1249 @staticmethod
1250 def OverrideByFdf(StruPcds,workspace):
1251 if GlobalData.gFdfParser is None:
1252 return StruPcds
1253 StructurePcdInFdf = OrderedDict()
1254 fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
1255 fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
1256 for item in fdfpcd :
1257 if len(item[2]) and (item[0],item[1]) in StruPcds:
1258 StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
1259 GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
1260 for Pcd in StruPcds.values():
1261 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
1262 continue
1263 FieldValues = OrderedDict()
1264 for item in StructurePcdInFdf:
1265 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
1266 FieldValues[item[2]] = StructurePcdInFdf[item]
1267 for field in FieldValues:
1268 if field not in Pcd.PcdFieldValueFromFdf:
1269 Pcd.PcdFieldValueFromFdf[field] = ["","",""]
1270 Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
1271 Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
1272 Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
1273
1274 return StruPcds
1275
1276 @staticmethod
1277 def OverrideByComm(StruPcds):
1278 StructurePcdInCom = OrderedDict()
1279 for item in GlobalData.BuildOptionPcd:
1280 if len(item) == 5 and (item[1], item[0]) in StruPcds:
1281 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
1282 GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
1283 for Pcd in StruPcds.values():
1284 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
1285 continue
1286 FieldValues = OrderedDict()
1287 for item in StructurePcdInCom:
1288 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
1289 FieldValues[item[2]] = StructurePcdInCom[item]
1290 for field in FieldValues:
1291 if field not in Pcd.PcdFieldValueFromComm:
1292 Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
1293 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
1294 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
1295 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
1296 return StruPcds
1297
1298 def OverrideByCommOverAll(self,AllPcds):
1299 def CheckStructureInComm(commpcds):
1300 if not commpcds:
1301 return False
1302 if len(commpcds[0]) == 5:
1303 return True
1304 return False
1305 NoFiledValues = OrderedDict()
1306 if CheckStructureInComm(GlobalData.BuildOptionPcd):
1307 StructurePcdInCom = OrderedDict()
1308 for item in GlobalData.BuildOptionPcd:
1309 StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
1310 for item in StructurePcdInCom:
1311 if not item[2]:
1312 NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]
1313 else:
1314 for item in GlobalData.BuildOptionPcd:
1315 NoFiledValues[(item[0], item[1])] = [item[2]]
1316 for Guid, Name in NoFiledValues:
1317 if (Name, Guid) in AllPcds:
1318 Pcd = AllPcds.get((Name, Guid))
1319 if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
1320 self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1321 else:
1322 Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1323 Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1324 for sku in Pcd.SkuInfoList:
1325 SkuInfo = Pcd.SkuInfoList[sku]
1326 if SkuInfo.DefaultValue:
1327 SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1328 else:
1329 SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1330 for defaultstore in SkuInfo.DefaultStoreDict:
1331 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
1332 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1333 if Pcd.DatumType == TAB_VOID:
1334 if not Pcd.MaxDatumSize:
1335 Pcd.MaxDatumSize = '0'
1336 CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1337 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1338 MaxSize = max(CurrentSize, OptionSize)
1339 Pcd.MaxDatumSize = str(MaxSize)
1340 else:
1341 PcdInDec = self.DecPcds.get((Name, Guid))
1342 if PcdInDec:
1343 PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
1344 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1345 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1346 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
1347 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1348 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1349 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1350 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
1351 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
1352 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
1353 self.Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
1354 return AllPcds
1355
1356 def OverrideByFdfOverAll(self,AllPcds):
1357
1358 if GlobalData.gFdfParser is None:
1359 return AllPcds
1360 NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
1361 for Name,Guid,Field in NoFiledValues:
1362 if len(Field):
1363 continue
1364 Value = NoFiledValues[(Name,Guid,Field)]
1365 if (Name,Guid) in AllPcds:
1366 Pcd = AllPcds.get((Name,Guid))
1367 if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
1368 self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
1369 else:
1370 Pcd.PcdValueFromComm = Value
1371 Pcd.DefaultValue = Value
1372 for sku in Pcd.SkuInfoList:
1373 SkuInfo = Pcd.SkuInfoList[sku]
1374 if SkuInfo.DefaultValue:
1375 SkuInfo.DefaultValue = Value
1376 else:
1377 SkuInfo.HiiDefaultValue = Value
1378 for defaultstore in SkuInfo.DefaultStoreDict:
1379 SkuInfo.DefaultStoreDict[defaultstore] = Value
1380 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
1381 if Pcd.DatumType == TAB_VOID:
1382 if not Pcd.MaxDatumSize:
1383 Pcd.MaxDatumSize = '0'
1384 CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
1385 OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
1386 MaxSize = max(CurrentSize, OptionSize)
1387 Pcd.MaxDatumSize = str(MaxSize)
1388 else:
1389 PcdInDec = self.DecPcds.get((Name,Guid))
1390 if PcdInDec:
1391 PcdInDec.PcdValueFromFdf = Value
1392 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1393 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1394 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
1395 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1396 self.Pcds[Name, Guid].DefaultValue = Value
1397 return AllPcds
1398
1399 def UpdateStructuredPcds(self, TypeList, AllPcds):
1400
1401 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1402 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1403 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1404 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1405 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1406 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
1407
1408 Pcds = AllPcds
1409 DefaultStoreMgr = DefaultStore(self.DefaultStores)
1410 SkuIds = self.SkuIds
1411 self.SkuIdMgr.AvailableSkuIdSet.update({TAB_DEFAULT:0})
1412 DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
1413 DefaultStores.add(TAB_DEFAULT_STORES_DEFAULT)
1414
1415 S_PcdSet = []
1416 # Find out all possible PCD candidates for self._Arch
1417 RecordList = []
1418
1419 for Type in TypeList:
1420 RecordList.extend(self._RawData[Type, self._Arch])
1421
1422 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
1423 SkuName = SkuName.upper()
1424 default_store = default_store.upper()
1425 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1426 if SkuName not in SkuIds:
1427 continue
1428
1429 if SkuName in SkuIds and "." in TokenSpaceGuid:
1430 S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
1431
1432 # handle pcd value override
1433 StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
1434 S_pcd_set = OrderedDict()
1435 for str_pcd in StrPcdSet:
1436 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1437 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1438 if not isinstance (str_pcd_dec, StructurePcd):
1439 EdkLogger.error('build', PARSER_ERROR,
1440 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1441 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1442 if str_pcd_dec:
1443 str_pcd_obj_str = StructurePcd()
1444 str_pcd_obj_str.copy(str_pcd_dec)
1445 if str_pcd_obj:
1446 str_pcd_obj_str.copy(str_pcd_obj)
1447 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1448 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}
1449 else:
1450 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}
1451 for str_pcd_data in StrPcdSet[str_pcd]:
1452 if str_pcd_data[3] in SkuIds:
1453 str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), TAB_DEFAULT if str_pcd_data[3] == TAB_COMMON else str_pcd_data[3], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[5])
1454 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1455 else:
1456 EdkLogger.error('build', PARSER_ERROR,
1457 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1458 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1459 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1460 for Pcd in self.DecPcds:
1461 if isinstance(self._DecPcds[Pcd], StructurePcd):
1462 if Pcd not in S_pcd_set:
1463 str_pcd_obj_str = StructurePcd()
1464 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1465 str_pcd_obj = Pcds.get(Pcd, None)
1466 if str_pcd_obj:
1467 str_pcd_obj_str.copy(str_pcd_obj)
1468 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1469 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}
1470 else:
1471 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}
1472 S_pcd_set[Pcd] = str_pcd_obj_str
1473 self.FilterStrcturePcd(S_pcd_set)
1474 if S_pcd_set:
1475 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1476 for stru_pcd in S_pcd_set.values():
1477 for skuid in SkuIds:
1478 if skuid in stru_pcd.SkuOverrideValues:
1479 continue
1480 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1481 NoDefault = False
1482 if skuid not in stru_pcd.SkuOverrideValues:
1483 while nextskuid not in stru_pcd.SkuOverrideValues:
1484 if nextskuid == TAB_DEFAULT:
1485 NoDefault = True
1486 break
1487 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1488 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})
1489 if not NoDefault:
1490 stru_pcd.ValueChain.add((skuid, ''))
1491 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1492 for skuid in SkuIds:
1493 nextskuid = skuid
1494 NoDefault = False
1495 if skuid not in stru_pcd.SkuOverrideValues:
1496 while nextskuid not in stru_pcd.SkuOverrideValues:
1497 if nextskuid == TAB_DEFAULT:
1498 NoDefault = True
1499 break
1500 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1501 if NoDefault:
1502 continue
1503 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
1504 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1505
1506 for defaultstoreid in DefaultStores:
1507 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1508 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1509 stru_pcd.ValueChain.add((skuid, defaultstoreid))
1510 S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
1511 S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
1512 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1513 if Str_Pcd_Values:
1514 for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
1515 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1516 if str_pcd_obj is None:
1517 print(PcdName, PcdGuid)
1518 raise
1519 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1520 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1521 if skuname not in str_pcd_obj.SkuInfoList:
1522 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1523 else:
1524 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1525 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1526 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1527 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1528 if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1529 str_pcd_obj.DefaultValue = PcdValue
1530 else:
1531 if skuname not in str_pcd_obj.SkuInfoList:
1532 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1533 NoDefault = False
1534 while nextskuid not in str_pcd_obj.SkuInfoList:
1535 if nextskuid == TAB_DEFAULT:
1536 NoDefault = True
1537 break
1538 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1539 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)
1540 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1541 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1542 else:
1543 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1544 for str_pcd_obj in S_pcd_set.values():
1545 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1546 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1547 continue
1548 PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
1549 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1550 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1551 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1552
1553 for str_pcd_obj in S_pcd_set.values():
1554
1555 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1556 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1557 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
1558
1559 for pcdkey in Pcds:
1560 pcd = Pcds[pcdkey]
1561 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1562 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
1563 del pcd.SkuInfoList[TAB_COMMON]
1564 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1565 del pcd.SkuInfoList[TAB_COMMON]
1566
1567 map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1568 return Pcds
1569 #Filter the StrucutrePcd that is not used by any module in dsc file and fdf file.
1570 def FilterStrcturePcd(self, S_pcd_set):
1571 if not self.UsedStructurePcd:
1572 FdfInfList = []
1573 if GlobalData.gFdfParser:
1574 FdfInfList = GlobalData.gFdfParser.Profile.InfList
1575 FdfModuleList = [PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) for Inf in FdfInfList]
1576 AllModulePcds = set()
1577 ModuleSet = set(self._Modules.keys() + self.LibraryInstances + FdfModuleList)
1578 for ModuleFile in ModuleSet:
1579 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
1580 AllModulePcds = AllModulePcds | set(ModuleData.Pcds.keys())
1581
1582 self.UsedStructurePcd = AllModulePcds
1583 UnusedStruPcds = set(S_pcd_set.keys()) - self.UsedStructurePcd
1584 for (Token, TokenSpaceGuid) in UnusedStruPcds:
1585 del S_pcd_set[(Token, TokenSpaceGuid)]
1586
1587 ## Retrieve non-dynamic PCD settings
1588 #
1589 # @param Type PCD type
1590 #
1591 # @retval a dict object contains settings of given PCD type
1592 #
1593 def _GetPcd(self, Type):
1594 Pcds = OrderedDict()
1595 #
1596 # tdict is a special dict kind of type, used for selecting correct
1597 # PCD settings for certain ARCH
1598 #
1599 AvailableSkuIdSet = copy.copy(self.SkuIds)
1600
1601 PcdDict = tdict(True, 4)
1602 PcdSet = set()
1603 # Find out all possible PCD candidates for self._Arch
1604 RecordList = self._RawData[Type, self._Arch]
1605 PcdValueDict = OrderedDict()
1606 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
1607 SkuName = SkuName.upper()
1608 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1609 if SkuName not in AvailableSkuIdSet:
1610 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1611 File=self.MetaFile, Line=Dummy5)
1612 if "." not in TokenSpaceGuid:
1613 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1614 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1615
1616 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1617 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1618 if Setting is None:
1619 continue
1620 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1621 if MaxDatumSize:
1622 if int(MaxDatumSize, 0) > 0xFFFF:
1623 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1624 File=self.MetaFile, Line=Dummy4)
1625 if int(MaxDatumSize, 0) < 0:
1626 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1627 File=self.MetaFile, Line=Dummy4)
1628 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1629 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1630 else:
1631 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1632
1633 for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.iteritems():
1634 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1635 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1636 elif TAB_DEFAULT in PcdSetting:
1637 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
1638 elif TAB_COMMON in PcdSetting:
1639 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
1640 else:
1641 PcdValue = None
1642 DatumType = None
1643 MaxDatumSize = None
1644
1645 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1646 PcdCName,
1647 TokenSpaceGuid,
1648 self._PCD_TYPE_STRING_[Type],
1649 DatumType,
1650 PcdValue,
1651 '',
1652 MaxDatumSize,
1653 {},
1654 False,
1655 None,
1656 IsDsc=True)
1657 for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
1658 Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
1659 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
1660 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
1661 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
1662 return Pcds
1663
1664 def GetStructurePcdMaxSize(self, str_pcd):
1665 pcd_default_value = str_pcd.DefaultValue
1666 sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
1667 sku_values.append(pcd_default_value)
1668
1669 def get_length(value):
1670 Value = value.strip()
1671 if len(value) > 1:
1672 if Value.startswith(TAB_GUID) and Value.endswith(')'):
1673 return 16
1674 if Value.startswith('L"') and Value.endswith('"'):
1675 return len(Value[2:-1])
1676 if Value[0] == '"' and Value[-1] == '"':
1677 return len(Value) - 2
1678 if Value[0] == '{' and Value[-1] == '}':
1679 return len(Value.split(","))
1680 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1681 return len(list(Value[2:-1]))
1682 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1683 return len(Value) - 2
1684 return len(Value)
1685
1686 return str(max(get_length(item) for item in sku_values))
1687
1688 @staticmethod
1689 def ExecuteCommand (Command):
1690 try:
1691 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1692 except:
1693 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1694 Result = Process.communicate()
1695 return Process.returncode, Result[0], Result[1]
1696
1697 @staticmethod
1698 def IntToCString(Value, ValueSize):
1699 Result = '"'
1700 if not isinstance (Value, str):
1701 for Index in range(0, ValueSize):
1702 Result = Result + '\\x%02x' % (Value & 0xff)
1703 Value = Value >> 8
1704 Result = Result + '"'
1705 return Result
1706
1707 def GenerateSizeFunction(self, Pcd):
1708 CApp = "// Default Value in Dec \n"
1709 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1710 for FieldList in [Pcd.DefaultValues]:
1711 if not FieldList:
1712 continue
1713 for FieldName in FieldList:
1714 FieldName = "." + FieldName
1715 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1716 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1717 try:
1718 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1719 except BadExpression:
1720 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1721 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1722 Value, ValueSize = ParseFieldValue(Value)
1723 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]);
1724 else:
1725 NewFieldName = ''
1726 FieldName_ori = FieldName.strip('.')
1727 while '[' in FieldName:
1728 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1729 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1730 FieldName = FieldName.split(']', 1)[1]
1731 FieldName = NewFieldName + FieldName
1732 while '[' in FieldName:
1733 FieldName = FieldName.rsplit('[', 1)[0]
1734 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1735 for skuname in Pcd.SkuOverrideValues:
1736 if skuname == TAB_COMMON:
1737 continue
1738 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
1739 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1740 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
1741 if not FieldList:
1742 continue
1743 for FieldName in FieldList:
1744 FieldName = "." + FieldName
1745 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1746 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1747 try:
1748 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1749 except BadExpression:
1750 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1751 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1752 Value, ValueSize = ParseFieldValue(Value)
1753 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]);
1754 else:
1755 NewFieldName = ''
1756 FieldName_ori = FieldName.strip('.')
1757 while '[' in FieldName:
1758 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1759 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1760 FieldName = FieldName.split(']', 1)[1]
1761 FieldName = NewFieldName + FieldName
1762 while '[' in FieldName:
1763 FieldName = FieldName.rsplit('[', 1)[0]
1764 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
1765 if Pcd.PcdFieldValueFromFdf:
1766 CApp = CApp + "// From fdf \n"
1767 for FieldName in Pcd.PcdFieldValueFromFdf:
1768 FieldName = "." + FieldName
1769 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
1770 if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
1771 try:
1772 Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1773 except BadExpression:
1774 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1775 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
1776 Value, ValueSize = ParseFieldValue(Value)
1777 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]);
1778 else:
1779 NewFieldName = ''
1780 FieldName_ori = FieldName.strip('.')
1781 while '[' in FieldName:
1782 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1783 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1784 FieldName = FieldName.split(']', 1)[1]
1785 FieldName = NewFieldName + FieldName
1786 while '[' in FieldName:
1787 FieldName = FieldName.rsplit('[', 1)[0]
1788 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
1789 if Pcd.PcdFieldValueFromComm:
1790 CApp = CApp + "// From Command Line \n"
1791 for FieldName in Pcd.PcdFieldValueFromComm:
1792 FieldName = "." + FieldName
1793 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
1794 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
1795 try:
1796 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[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('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
1800 Value, ValueSize = ParseFieldValue(Value)
1801 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]);
1802 else:
1803 NewFieldName = ''
1804 FieldName_ori = FieldName.strip('.')
1805 while '[' in FieldName:
1806 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1807 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1808 FieldName = FieldName.split(']', 1)[1]
1809 FieldName = NewFieldName + FieldName
1810 while '[' in FieldName:
1811 FieldName = FieldName.rsplit('[', 1)[0]
1812 CApp = CApp + ' __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
1813 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
1814 CApp = CApp + "}\n"
1815 return CApp
1816
1817 @staticmethod
1818 def GenerateSizeStatments(Pcd):
1819 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1820 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1821 return CApp
1822
1823 def GenerateDefaultValueAssignFunction(self, Pcd):
1824 CApp = "// Default value in Dec \n"
1825 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1826 CApp = CApp + ' UINT32 FieldSize;\n'
1827 CApp = CApp + ' CHAR8 *Value;\n'
1828 DefaultValueFromDec = Pcd.DefaultValueFromDec
1829 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
1830 if IsArray:
1831 try:
1832 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
1833 except BadExpression:
1834 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
1835 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
1836 DefaultValueFromDec = StringToArray(DefaultValueFromDec)
1837 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
1838 if isinstance(Value, str):
1839 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
1840 elif IsArray:
1841 #
1842 # Use memcpy() to copy value into field
1843 #
1844 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
1845 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1846 for FieldList in [Pcd.DefaultValues]:
1847 if not FieldList:
1848 continue
1849 for FieldName in FieldList:
1850 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1851 if IsArray:
1852 try:
1853 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1854 except BadExpression:
1855 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1856 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1857
1858 try:
1859 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1860 except Exception:
1861 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]))
1862 if isinstance(Value, str):
1863 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1864 elif IsArray:
1865 #
1866 # Use memcpy() to copy value into field
1867 #
1868 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1869 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1870 CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1871 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1872 else:
1873 if '[' in FieldName and ']' in FieldName:
1874 Index = int(FieldName.split('[')[1].split(']')[0])
1875 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)
1876 if ValueSize > 4:
1877 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1878 else:
1879 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1880 CApp = CApp + "}\n"
1881 return CApp
1882
1883 @staticmethod
1884 def GenerateDefaultValueAssignStatement(Pcd):
1885 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1886 return CApp
1887
1888 def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
1889 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
1890 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)
1891 CApp = CApp + ' UINT32 FieldSize;\n'
1892 CApp = CApp + ' CHAR8 *Value;\n'
1893
1894 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
1895 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
1896 if Pcd.Type in PCD_DYNAMIC_TYPE_SET or Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
1897 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1898 pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
1899 else:
1900 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
1901 else:
1902 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
1903 for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:
1904 if not FieldList:
1905 continue
1906 if pcddefaultvalue and FieldList == pcddefaultvalue:
1907 IsArray = IsFieldValueAnArray(FieldList)
1908 if IsArray:
1909 try:
1910 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1911 except BadExpression:
1912 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1913 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1914 Value, ValueSize = ParseFieldValue (FieldList)
1915
1916 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1917 if isinstance(Value, str):
1918 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)
1919 elif IsArray:
1920 #
1921 # Use memcpy() to copy value into field
1922 #
1923 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)
1924 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1925 else:
1926 if isinstance(Value, str):
1927 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1928 elif IsArray:
1929 #
1930 # Use memcpy() to copy value into field
1931 #
1932 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1933 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1934 continue
1935 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
1936 for FieldName in FieldList:
1937 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1938 if IsArray:
1939 try:
1940 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1941 except BadExpression:
1942 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1943 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1944 try:
1945 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1946 except Exception:
1947 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]))
1948 if isinstance(Value, str):
1949 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1950 elif IsArray:
1951 #
1952 # Use memcpy() to copy value into field
1953 #
1954 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1955 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1956 CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1957 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1958 else:
1959 if '[' in FieldName and ']' in FieldName:
1960 Index = int(FieldName.split('[')[1].split(']')[0])
1961 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)
1962 if ValueSize > 4:
1963 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1964 else:
1965 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1966 CApp = CApp + "}\n"
1967 return CApp
1968
1969 @staticmethod
1970 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
1971 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
1972 return CApp
1973
1974 def GenerateCommandLineValue(self, Pcd):
1975 CApp = "// Value in CommandLine\n"
1976 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1977 CApp = CApp + ' UINT32 FieldSize;\n'
1978 CApp = CApp + ' CHAR8 *Value;\n'
1979
1980 pcddefaultvalue = Pcd.PcdValueFromComm
1981 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
1982 if not FieldList:
1983 continue
1984 if pcddefaultvalue and FieldList == pcddefaultvalue:
1985 IsArray = IsFieldValueAnArray(FieldList)
1986 if IsArray:
1987 try:
1988 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1989 except BadExpression:
1990 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1991 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1992 Value, ValueSize = ParseFieldValue (FieldList)
1993
1994 if isinstance(Value, str):
1995 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1996 elif IsArray:
1997 #
1998 # Use memcpy() to copy value into field
1999 #
2000 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
2001 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
2002 continue
2003 for FieldName in FieldList:
2004 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2005 if IsArray:
2006 try:
2007 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2008 except BadExpression:
2009 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2010 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2011 except:
2012 print("error")
2013 try:
2014 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2015 except Exception:
2016 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]))
2017 if isinstance(Value, str):
2018 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2019 elif IsArray:
2020 #
2021 # Use memcpy() to copy value into field
2022 #
2023 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2024 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2025 CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2026 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2027 else:
2028 if '[' in FieldName and ']' in FieldName:
2029 Index = int(FieldName.split('[')[1].split(']')[0])
2030 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)
2031 if ValueSize > 4:
2032 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2033 else:
2034 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2035 CApp = CApp + "}\n"
2036 return CApp
2037
2038 @staticmethod
2039 def GenerateCommandLineValueStatement(Pcd):
2040 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2041 return CApp
2042 def GenerateFdfValue(self,Pcd):
2043 CApp = "// Value in Fdf\n"
2044 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
2045 CApp = CApp + ' UINT32 FieldSize;\n'
2046 CApp = CApp + ' CHAR8 *Value;\n'
2047
2048 pcddefaultvalue = Pcd.PcdValueFromFdf
2049 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
2050 if not FieldList:
2051 continue
2052 if pcddefaultvalue and FieldList == pcddefaultvalue:
2053 IsArray = IsFieldValueAnArray(FieldList)
2054 if IsArray:
2055 try:
2056 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
2057 except BadExpression:
2058 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
2059 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
2060 Value, ValueSize = ParseFieldValue (FieldList)
2061
2062 if isinstance(Value, str):
2063 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
2064 elif IsArray:
2065 #
2066 # Use memcpy() to copy value into field
2067 #
2068 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
2069 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
2070 continue
2071 for FieldName in FieldList:
2072 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2073 if IsArray:
2074 try:
2075 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2076 except BadExpression:
2077 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2078 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2079 except:
2080 print("error")
2081 try:
2082 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2083 except Exception:
2084 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]))
2085 if isinstance(Value, str):
2086 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2087 elif IsArray:
2088 #
2089 # Use memcpy() to copy value into field
2090 #
2091 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2092 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2093 CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2094 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2095 else:
2096 if '[' in FieldName and ']' in FieldName:
2097 Index = int(FieldName.split('[')[1].split(']')[0])
2098 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)
2099 if ValueSize > 4:
2100 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2101 else:
2102 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2103 CApp = CApp + "}\n"
2104 return CApp
2105
2106 @staticmethod
2107 def GenerateFdfValueStatement(Pcd):
2108 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2109 return CApp
2110
2111 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
2112 OverrideValues = {DefaultStore:""}
2113 if Pcd.SkuOverrideValues:
2114 OverrideValues = Pcd.SkuOverrideValues[SkuName]
2115 if not OverrideValues:
2116 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
2117 for DefaultStoreName in OverrideValues:
2118 CApp = CApp + 'void\n'
2119 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2120 CApp = CApp + ' void\n'
2121 CApp = CApp + ' )\n'
2122 CApp = CApp + '{\n'
2123 CApp = CApp + ' UINT32 Size;\n'
2124 CApp = CApp + ' UINT32 FieldSize;\n'
2125 CApp = CApp + ' CHAR8 *Value;\n'
2126 CApp = CApp + ' UINT32 OriginalSize;\n'
2127 CApp = CApp + ' VOID *OriginalPcd;\n'
2128 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
2129 CApp = CApp + '\n'
2130
2131 if SkuName in Pcd.SkuInfoList:
2132 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
2133 else:
2134 DefaultValue = Pcd.DefaultValue
2135 PcdDefaultValue = StringToArray(DefaultValue.strip())
2136
2137 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
2138
2139 #
2140 # Get current PCD value and size
2141 #
2142 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2143
2144 #
2145 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
2146 # the correct value. For structures with a flexible array member, the flexible
2147 # array member is detected, and the size is based on the highest index used with
2148 # the flexible array member. The flexible array member must be the last field
2149 # in a structure. The size formula for this case is:
2150 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
2151 #
2152 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)
2153
2154 #
2155 # Allocate and zero buffer for the PCD
2156 # Must handle cases where current value is smaller, larger, or same size
2157 # Always keep that larger one as the current size
2158 #
2159 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
2160 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
2161 CApp = CApp + ' memset (Pcd, 0, Size);\n'
2162
2163 #
2164 # Copy current PCD value into allocated buffer.
2165 #
2166 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
2167
2168 #
2169 # Assign field values in PCD
2170 #
2171 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
2172 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2173 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2174 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
2175 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
2176 for defaultstorenameitem in storeset:
2177 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
2178 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
2179 if skuname == SkuName:
2180 break
2181 else:
2182 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
2183 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2184 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
2185 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
2186 #
2187 # Set new PCD value and size
2188 #
2189 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2190
2191 #
2192 # Free PCD
2193 #
2194 CApp = CApp + ' free (Pcd);\n'
2195 CApp = CApp + '}\n'
2196 CApp = CApp + '\n'
2197 return InitByteValue, CApp
2198 def SkuOverrideValuesEmpty(self,OverrideValues):
2199 if not OverrideValues:
2200 return True
2201 for key in OverrideValues:
2202 if OverrideValues[key]:
2203 return False
2204 return True
2205
2206 def GenerateByteArrayValue (self, StructuredPcds):
2207 #
2208 # Generate/Compile/Run C application to determine if there are any flexible array members
2209 #
2210 if not StructuredPcds:
2211 return
2212
2213 InitByteValue = ""
2214 CApp = PcdMainCHeader
2215
2216 IncludeFiles = set()
2217 for PcdName in StructuredPcds:
2218 Pcd = StructuredPcds[PcdName]
2219 for IncludeFile in Pcd.StructuredPcdIncludeFile:
2220 if IncludeFile not in IncludeFiles:
2221 IncludeFiles.add(IncludeFile)
2222 CApp = CApp + '#include <%s>\n' % (IncludeFile)
2223 CApp = CApp + '\n'
2224 for PcdName in StructuredPcds:
2225 Pcd = StructuredPcds[PcdName]
2226 CApp = CApp + self.GenerateSizeFunction(Pcd)
2227 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
2228 CApp = CApp + self.GenerateFdfValue(Pcd)
2229 CApp = CApp + self.GenerateCommandLineValue(Pcd)
2230 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2231 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2232 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2233 else:
2234 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2235 if SkuName not in Pcd.SkuOverrideValues:
2236 continue
2237 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2238 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
2239 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2240 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2241 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
2242 else:
2243 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2244 if SkuName not in Pcd.SkuOverrideValues:
2245 continue
2246 for DefaultStoreName in Pcd.DefaultStoreName:
2247 Pcd = StructuredPcds[PcdName]
2248 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2249
2250 CApp = CApp + 'VOID\n'
2251 CApp = CApp + 'PcdEntryPoint(\n'
2252 CApp = CApp + ' VOID\n'
2253 CApp = CApp + ' )\n'
2254 CApp = CApp + '{\n'
2255 for Pcd in StructuredPcds.values():
2256 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]]:
2257 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2258 else:
2259 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2260 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
2261 continue
2262 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2263 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2264 CApp = CApp + '}\n'
2265
2266 CApp = CApp + PcdMainCEntry + '\n'
2267
2268 if not os.path.exists(self.OutputPath):
2269 os.makedirs(self.OutputPath)
2270 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2271 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2272
2273 MakeApp = PcdMakefileHeader
2274 if sys.platform == "win32":
2275 MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2276 else:
2277 MakeApp = MakeApp + PcdGccMakefile
2278 MakeApp = MakeApp + 'APPFILE = %s/%s\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2279 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2280
2281 IncSearchList = []
2282 PlatformInc = OrderedDict()
2283 for Cache in self._Bdb._CACHE_.values():
2284 if Cache.MetaFile.Ext.lower() != '.dec':
2285 continue
2286 if Cache.Includes:
2287 if str(Cache.MetaFile.Path) not in PlatformInc:
2288 PlatformInc[str(Cache.MetaFile.Path)] = []
2289 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
2290 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
2291
2292 PcdDependDEC = []
2293 for Pcd in StructuredPcds.values():
2294 for PackageDec in Pcd.PackageDecs:
2295 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2296 if not os.path.exists(Package):
2297 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2298 if Package not in PcdDependDEC:
2299 PcdDependDEC.append(Package)
2300
2301 if PlatformInc and PcdDependDEC:
2302 for pkg in PcdDependDEC:
2303 if pkg in PlatformInc:
2304 for inc in PlatformInc[pkg]:
2305 MakeApp += '-I' + str(inc) + ' '
2306 IncSearchList.append(inc)
2307 MakeApp = MakeApp + '\n'
2308
2309 CC_FLAGS = LinuxCFLAGS
2310 if sys.platform == "win32":
2311 CC_FLAGS = WindowsCFLAGS
2312 BuildOptions = OrderedDict()
2313 for Options in self.BuildOptions:
2314 if Options[2] != EDKII_NAME:
2315 continue
2316 Family = Options[0]
2317 if Family and Family != self.ToolChainFamily:
2318 continue
2319 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2320 if Tool != 'CC':
2321 continue
2322
2323 if Target == "*" or Target == self._Target:
2324 if Tag == "*" or Tag == self._Toolchain:
2325 if Arch == "*":
2326 if Tool not in BuildOptions:
2327 BuildOptions[Tool] = OrderedDict()
2328 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2329 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2330 else:
2331 # append options for the same tool except PATH
2332 if Attr != 'PATH':
2333 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2334 else:
2335 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2336 if BuildOptions:
2337 for Tool in BuildOptions:
2338 for Attr in BuildOptions[Tool]:
2339 if Attr == "FLAGS":
2340 Value = BuildOptions[Tool][Attr]
2341 ValueList = Value.split()
2342 if ValueList:
2343 for Id, Item in enumerate(ValueList):
2344 if Item in ['-D', '/D', '-U', '/U']:
2345 CC_FLAGS += ' ' + Item
2346 if Id + 1 < len(ValueList):
2347 CC_FLAGS += ' ' + ValueList[Id + 1]
2348 elif Item.startswith(('-D', '/D', '-U', '/U')):
2349 CC_FLAGS += ' ' + Item
2350 MakeApp += CC_FLAGS
2351
2352 if sys.platform == "win32":
2353 MakeApp = MakeApp + PcdMakefileEnd
2354 MakeApp = MakeApp + AppTarget % ("""\tcopy $(APPLICATION) $(APPFILE) /y """)
2355 else:
2356 MakeApp = MakeApp + AppTarget % ("""\tcp $(APPLICATION) $(APPFILE) """)
2357 MakeApp = MakeApp + '\n'
2358 IncludeFileFullPaths = []
2359 for includefile in IncludeFiles:
2360 for includepath in IncSearchList:
2361 includefullpath = os.path.join(str(includepath), includefile)
2362 if os.path.exists(includefullpath):
2363 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2364 break
2365 SearchPathList = []
2366 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2367 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2368 SearchPathList.extend(str(item) for item in IncSearchList)
2369 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
2370 for include_file in IncFileList:
2371 MakeApp += "$(OBJECTS) : %s\n" % include_file
2372 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2373 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2374 SaveFileOnChange(MakeFileName, MakeApp, False)
2375
2376 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2377 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2378 SaveFileOnChange(InputValueFile, InitByteValue, False)
2379
2380 Dest_PcdValueInitExe = PcdValueInitName
2381 if not sys.platform == "win32":
2382 Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName)
2383 else:
2384 Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName) +".exe"
2385 Messages = ''
2386 if sys.platform == "win32":
2387 MakeCommand = 'nmake -f %s' % (MakeFileName)
2388 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2389 Messages = StdOut
2390 else:
2391 MakeCommand = 'make -f %s' % (MakeFileName)
2392 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2393 Messages = StdErr
2394
2395 Messages = Messages.split('\n')
2396 MessageGroup = []
2397 if returncode != 0:
2398 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2399 File = open (CAppBaseFileName + '.c', 'r')
2400 FileData = File.readlines()
2401 File.close()
2402 for Message in Messages:
2403 if " error" in Message or "warning" in Message:
2404 FileInfo = Message.strip().split('(')
2405 if len (FileInfo) > 1:
2406 FileName = FileInfo [0]
2407 FileLine = FileInfo [1].split (')')[0]
2408 else:
2409 FileInfo = Message.strip().split(':')
2410 FileName = FileInfo [0]
2411 FileLine = FileInfo [1]
2412 if FileLine.isdigit():
2413 error_line = FileData[int (FileLine) - 1]
2414 if r"//" in error_line:
2415 c_line, dsc_line = error_line.split(r"//")
2416 else:
2417 dsc_line = error_line
2418 message_itmes = Message.split(":")
2419 Index = 0
2420 if "PcdValueInit.c" not in Message:
2421 if not MessageGroup:
2422 MessageGroup.append(Message)
2423 break
2424 else:
2425 for item in message_itmes:
2426 if "PcdValueInit.c" in item:
2427 Index = message_itmes.index(item)
2428 message_itmes[Index] = dsc_line.strip()
2429 break
2430 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2431 continue
2432 else:
2433 MessageGroup.append(Message)
2434 if MessageGroup:
2435 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2436 else:
2437 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2438
2439 if DscBuildData.NeedUpdateOutput(OutputValueFile, Dest_PcdValueInitExe, InputValueFile):
2440 Command = Dest_PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2441 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
2442 if returncode != 0:
2443 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2444
2445 File = open (OutputValueFile, 'r')
2446 FileBuffer = File.readlines()
2447 File.close()
2448
2449 StructurePcdSet = []
2450 for Pcd in FileBuffer:
2451 PcdValue = Pcd.split ('|')
2452 PcdInfo = PcdValue[0].split ('.')
2453 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2454 return StructurePcdSet
2455
2456 @staticmethod
2457 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
2458 if not os.path.exists(OutputFile):
2459 return True
2460 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2461 return True
2462 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2463 return True
2464 return False
2465
2466 ## Retrieve dynamic PCD settings
2467 #
2468 # @param Type PCD type
2469 #
2470 # @retval a dict object contains settings of given PCD type
2471 #
2472 def _GetDynamicPcd(self, Type):
2473
2474
2475 Pcds = OrderedDict()
2476 #
2477 # tdict is a special dict kind of type, used for selecting correct
2478 # PCD settings for certain ARCH and SKU
2479 #
2480 PcdDict = tdict(True, 4)
2481 PcdList = []
2482 # Find out all possible PCD candidates for self._Arch
2483 RecordList = self._RawData[Type, self._Arch]
2484 AvailableSkuIdSet = copy.copy(self.SkuIds)
2485
2486
2487 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2488 SkuName = SkuName.upper()
2489 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2490 if SkuName not in AvailableSkuIdSet:
2491 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2492 File=self.MetaFile, Line=Dummy5)
2493 if "." not in TokenSpaceGuid:
2494 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2495 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2496
2497 # Remove redundant PCD candidates, per the ARCH and SKU
2498 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2499
2500 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2501 if Setting is None:
2502 continue
2503
2504 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2505 if MaxDatumSize:
2506 if int(MaxDatumSize, 0) > 0xFFFF:
2507 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2508 File=self.MetaFile, Line=Dummy4)
2509 if int(MaxDatumSize, 0) < 0:
2510 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2511 File=self.MetaFile, Line=Dummy4)
2512 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2513 if (PcdCName, TokenSpaceGuid) in Pcds:
2514 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2515 pcdObject.SkuInfoList[SkuName] = SkuInfo
2516 if MaxDatumSize.strip():
2517 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2518 else:
2519 CurrentMaxSize = 0
2520 if pcdObject.MaxDatumSize:
2521 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2522 else:
2523 PcdMaxSize = 0
2524 if CurrentMaxSize > PcdMaxSize:
2525 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2526 else:
2527 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2528 PcdCName,
2529 TokenSpaceGuid,
2530 self._PCD_TYPE_STRING_[Type],
2531 DatumType,
2532 PcdValue,
2533 '',
2534 MaxDatumSize,
2535 OrderedDict({SkuName : SkuInfo}),
2536 False,
2537 None,
2538 IsDsc=True)
2539
2540 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2541 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2542 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
2543
2544 for pcd in Pcds.values():
2545 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2546 # Only fix the value while no value provided in DSC file.
2547 for sku in pcd.SkuInfoList.values():
2548 if not sku.DefaultValue:
2549 sku.DefaultValue = pcdDecObject.DefaultValue
2550 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2551 valuefromDec = pcdDecObject.DefaultValue
2552 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
2553 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2554 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2555 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2556 del pcd.SkuInfoList[TAB_COMMON]
2557 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2558 del pcd.SkuInfoList[TAB_COMMON]
2559
2560 map(self.FilterSkuSettings, Pcds.values())
2561
2562 return Pcds
2563
2564 def FilterSkuSettings(self, PcdObj):
2565
2566 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2567 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
2568 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
2569 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2570 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
2571 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
2572
2573 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2574 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
2575
2576 return PcdObj
2577
2578 @staticmethod
2579 def CompareVarAttr(Attr1, Attr2):
2580 if not Attr1 or not Attr2: # for empty string
2581 return True
2582 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2583 Attr1Set = set(Attr1s)
2584 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2585 Attr2Set = set(Attr2s)
2586 if Attr2Set == Attr1Set:
2587 return True
2588 else:
2589 return False
2590
2591 def CompletePcdValues(self, PcdSet):
2592 Pcds = OrderedDict()
2593 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2594 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
2595 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
2596 for PcdCName, TokenSpaceGuid in PcdSet:
2597 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2598
2599 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2600 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2601 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2602 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2603 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2604 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2605 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2606 continue
2607 PcdType = PcdObj.Type
2608 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2609 for skuid in PcdObj.SkuInfoList:
2610 skuobj = PcdObj.SkuInfoList[skuid]
2611 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
2612 for defaultstorename in DefaultStores:
2613 if defaultstorename not in skuobj.DefaultStoreDict:
2614 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2615 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2616 for skuname, skuid in SkuIds.items():
2617 if skuname not in PcdObj.SkuInfoList:
2618 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2619 while nextskuid not in PcdObj.SkuInfoList:
2620 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2621 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2622 PcdObj.SkuInfoList[skuname].SkuId = skuid
2623 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2624 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2625 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
2626 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2627 return Pcds
2628 ## Retrieve dynamic HII PCD settings
2629 #
2630 # @param Type PCD type
2631 #
2632 # @retval a dict object contains settings of given PCD type
2633 #
2634 def _GetDynamicHiiPcd(self, Type):
2635
2636 VariableAttrs = {}
2637
2638 Pcds = OrderedDict()
2639 UserDefinedDefaultStores = []
2640 #
2641 # tdict is a special dict kind of type, used for selecting correct
2642 # PCD settings for certain ARCH and SKU
2643 #
2644 PcdDict = tdict(True, 5)
2645 PcdSet = set()
2646 RecordList = self._RawData[Type, self._Arch]
2647 # Find out all possible PCD candidates for self._Arch
2648 AvailableSkuIdSet = copy.copy(self.SkuIds)
2649 DefaultStoresDefine = self._GetDefaultStores()
2650
2651 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
2652 SkuName = SkuName.upper()
2653 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2654 DefaultStore = DefaultStore.upper()
2655 if DefaultStore == TAB_COMMON:
2656 DefaultStore = TAB_DEFAULT_STORES_DEFAULT
2657 else:
2658 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
2659 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
2660 if SkuName not in AvailableSkuIdSet:
2661 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2662 File=self.MetaFile, Line=Dummy5)
2663 if DefaultStore not in DefaultStoresDefine:
2664 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2665 File=self.MetaFile, Line=Dummy5)
2666 if "." not in TokenSpaceGuid:
2667 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
2668 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
2669
2670
2671 # Remove redundant PCD candidates, per the ARCH and SKU
2672 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:
2673
2674 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
2675 if Setting is None:
2676 continue
2677 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2678
2679 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2680 if not rt:
2681 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2682 ExtraData="[%s]" % VarAttribute)
2683 ExceedMax = False
2684 FormatCorrect = True
2685 if VariableOffset.isdigit():
2686 if int(VariableOffset, 10) > 0xFFFF:
2687 ExceedMax = True
2688 elif variablePattern.match(VariableOffset):
2689 if int(VariableOffset, 16) > 0xFFFF:
2690 ExceedMax = True
2691 # For Offset written in "A.B"
2692 elif VariableOffset.find('.') > -1:
2693 VariableOffsetList = VariableOffset.split(".")
2694 if not (len(VariableOffsetList) == 2
2695 and IsValidWord(VariableOffsetList[0])
2696 and IsValidWord(VariableOffsetList[1])):
2697 FormatCorrect = False
2698 else:
2699 FormatCorrect = False
2700 if not FormatCorrect:
2701 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2702
2703 if ExceedMax:
2704 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2705 if (VariableName, VariableGuid) not in VariableAttrs:
2706 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2707 else:
2708 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2709 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)]))
2710
2711 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2712 if (PcdCName, TokenSpaceGuid) in Pcds:
2713 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2714 if SkuName in pcdObject.SkuInfoList:
2715 Skuitem = pcdObject.SkuInfoList[SkuName]
2716 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2717 else:
2718 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2719 pcdObject.SkuInfoList[SkuName] = SkuInfo
2720 else:
2721 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2722 PcdClassObj = PcdClassObject(
2723 PcdCName,
2724 TokenSpaceGuid,
2725 self._PCD_TYPE_STRING_[Type],
2726 '',
2727 DefaultValue,
2728 '',
2729 '',
2730 OrderedDict({SkuName : SkuInfo}),
2731 False,
2732 None,
2733 pcdDecObject.validateranges,
2734 pcdDecObject.validlists,
2735 pcdDecObject.expressions,
2736 IsDsc=True)
2737 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
2738 PcdClassObj.UserDefinedDefaultStoresFlag = True
2739 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
2740
2741 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
2742 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2743 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2744 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
2745 for pcd in Pcds.values():
2746 SkuInfoObj = pcd.SkuInfoList.values()[0]
2747 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2748 pcd.DatumType = pcdDecObject.DatumType
2749 # Only fix the value while no value provided in DSC file.
2750 for sku in pcd.SkuInfoList.values():
2751 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
2752 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2753 for default_store in sku.DefaultStoreDict:
2754 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2755 pcd.DefaultValue = pcdDecObject.DefaultValue
2756 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2757 valuefromDec = pcdDecObject.DefaultValue
2758 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
2759 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2760 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2761 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2762 del pcd.SkuInfoList[TAB_COMMON]
2763 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2764 del pcd.SkuInfoList[TAB_COMMON]
2765
2766 if pcd.MaxDatumSize.strip():
2767 MaxSize = int(pcd.MaxDatumSize, 0)
2768 else:
2769 MaxSize = 0
2770 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
2771 for (_, skuobj) in pcd.SkuInfoList.items():
2772 datalen = 0
2773 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2774 datalen = len(skuobj.HiiDefaultValue.split(","))
2775 if datalen > MaxSize:
2776 MaxSize = datalen
2777 for defaultst in skuobj.DefaultStoreDict:
2778 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2779 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2780 pcd.MaxDatumSize = str(MaxSize)
2781 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
2782 if not rt:
2783 invalidpcd = ",".join(invalidhii)
2784 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)
2785
2786 map(self.FilterSkuSettings, Pcds.values())
2787
2788 return Pcds
2789
2790 @staticmethod
2791 def CheckVariableNameAssignment(Pcds):
2792 invalidhii = []
2793 for pcdname in Pcds:
2794 pcd = Pcds[pcdname]
2795 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
2796 if len(varnameset) > 1:
2797 invalidhii.append(".".join((pcdname[1], pcdname[0])))
2798 if len(invalidhii):
2799 return False, invalidhii
2800 else:
2801 return True, []
2802 ## Retrieve dynamic VPD PCD settings
2803 #
2804 # @param Type PCD type
2805 #
2806 # @retval a dict object contains settings of given PCD type
2807 #
2808 def _GetDynamicVpdPcd(self, Type):
2809
2810
2811 Pcds = OrderedDict()
2812 #
2813 # tdict is a special dict kind of type, used for selecting correct
2814 # PCD settings for certain ARCH and SKU
2815 #
2816 PcdDict = tdict(True, 4)
2817 PcdList = []
2818
2819 # Find out all possible PCD candidates for self._Arch
2820 RecordList = self._RawData[Type, self._Arch]
2821 AvailableSkuIdSet = copy.copy(self.SkuIds)
2822
2823 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2824 SkuName = SkuName.upper()
2825 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2826 if SkuName not in AvailableSkuIdSet:
2827 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2828 File=self.MetaFile, Line=Dummy5)
2829 if "." not in TokenSpaceGuid:
2830 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2831 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2832
2833 # Remove redundant PCD candidates, per the ARCH and SKU
2834 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2835 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2836 if Setting is None:
2837 continue
2838 #
2839 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2840 # For the Integer & Boolean type, the optional data can only be InitialValue.
2841 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2842 # until the DEC parser has been called.
2843 #
2844 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2845 if MaxDatumSize:
2846 if int(MaxDatumSize, 0) > 0xFFFF:
2847 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2848 File=self.MetaFile, Line=Dummy4)
2849 if int(MaxDatumSize, 0) < 0:
2850 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2851 File=self.MetaFile, Line=Dummy4)
2852 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2853 if (PcdCName, TokenSpaceGuid) in Pcds:
2854 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2855 pcdObject.SkuInfoList[SkuName] = SkuInfo
2856 if MaxDatumSize.strip():
2857 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2858 else:
2859 CurrentMaxSize = 0
2860 if pcdObject.MaxDatumSize:
2861 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2862 else:
2863 PcdMaxSize = 0
2864 if CurrentMaxSize > PcdMaxSize:
2865 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2866 else:
2867 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2868 PcdCName,
2869 TokenSpaceGuid,
2870 self._PCD_TYPE_STRING_[Type],
2871 '',
2872 InitialValue,
2873 '',
2874 MaxDatumSize,
2875 OrderedDict({SkuName : SkuInfo}),
2876 False,
2877 None,
2878 IsDsc=True)
2879
2880 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2881 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2882 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
2883 for pcd in Pcds.values():
2884 SkuInfoObj = pcd.SkuInfoList.values()[0]
2885 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2886 pcd.DatumType = pcdDecObject.DatumType
2887 # Only fix the value while no value provided in DSC file.
2888 for sku in pcd.SkuInfoList.values():
2889 if not sku.DefaultValue:
2890 sku.DefaultValue = pcdDecObject.DefaultValue
2891 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2892 valuefromDec = pcdDecObject.DefaultValue
2893 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2894 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2895 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2896 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2897 del pcd.SkuInfoList[TAB_COMMON]
2898 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2899 del pcd.SkuInfoList[TAB_COMMON]
2900
2901 #For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
2902 #the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
2903 for pcd in Pcds.values():
2904 PcdValueTypeSet = set()
2905 for sku in pcd.SkuInfoList.values():
2906 PcdValueTypeSet.add("UnicodeString" if sku.DefaultValue.startswith(('L"',"L'")) else "OtherVOID*")
2907 if len(PcdValueTypeSet) > 1:
2908 for sku in pcd.SkuInfoList.values():
2909 sku.DefaultValue = StringToArray(sku.DefaultValue) if sku.DefaultValue.startswith(('L"',"L'")) else sku.DefaultValue
2910
2911 map(self.FilterSkuSettings, Pcds.values())
2912 return Pcds
2913
2914 ## Add external modules
2915 #
2916 # The external modules are mostly those listed in FDF file, which don't
2917 # need "build".
2918 #
2919 # @param FilePath The path of module description file
2920 #
2921 def AddModule(self, FilePath):
2922 FilePath = NormPath(FilePath)
2923 if FilePath not in self.Modules:
2924 Module = ModuleBuildClassObject()
2925 Module.MetaFile = FilePath
2926 self.Modules.append(Module)
2927
2928 @property
2929 def ToolChainFamily(self):
2930 self._ToolChainFamily = TAB_COMPILER_MSFT
2931 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2932 if os.path.isfile(BuildConfigurationFile) == True:
2933 TargetTxt = TargetTxtClassObject()
2934 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2935 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2936 if ToolDefinitionFile == '':
2937 ToolDefinitionFile = "tools_def.txt"
2938 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2939 if os.path.isfile(ToolDefinitionFile) == True:
2940 ToolDef = ToolDefClassObject()
2941 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2942 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2943 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2944 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2945 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2946 self._ToolChainFamily = TAB_COMPILER_MSFT
2947 else:
2948 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2949 return self._ToolChainFamily
2950
2951 ## Add external PCDs
2952 #
2953 # The external PCDs are mostly those listed in FDF file to specify address
2954 # or offset information.
2955 #
2956 # @param Name Name of the PCD
2957 # @param Guid Token space guid of the PCD
2958 # @param Value Value of the PCD
2959 #
2960 def AddPcd(self, Name, Guid, Value):
2961 if (Name, Guid) not in self.Pcds:
2962 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2963 self.Pcds[Name, Guid].DefaultValue = Value
2964
2965 @property
2966 def DecPcds(self):
2967 if self._DecPcds is None:
2968 FdfInfList = []
2969 if GlobalData.gFdfParser:
2970 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2971 PkgSet = set()
2972 for Inf in FdfInfList:
2973 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2974 if ModuleFile in self._Modules:
2975 continue
2976 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2977 PkgSet.update(ModuleData.Packages)
2978 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
2979 self._GuidDict.update(GlobalData.gPlatformPcds)
2980 return self._DecPcds