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