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