]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools:Fix issue caused by 84a52d4d030185a44f2d8736142c6f0b19c6e9b1
[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 self.SkuIdMgr.AvailableSkuIdSet.update({TAB_DEFAULT:0})
1419 DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
1420
1421 S_PcdSet = []
1422 # Find out all possible PCD candidates for self._Arch
1423 RecordList = []
1424
1425 for Type in TypeList:
1426 RecordList.extend(self._RawData[Type, self._Arch])
1427
1428 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
1429 SkuName = SkuName.upper()
1430 default_store = default_store.upper()
1431 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1432 if SkuName not in SkuIds:
1433 continue
1434
1435 if SkuName in SkuIds and "." in TokenSpaceGuid:
1436 S_PcdSet.append([ TokenSpaceGuid.split(".")[0], TokenSpaceGuid.split(".")[1], PcdCName, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
1437
1438 # handle pcd value override
1439 StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
1440 S_pcd_set = OrderedDict()
1441 for str_pcd in StrPcdSet:
1442 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1443 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1444 if not isinstance (str_pcd_dec, StructurePcd):
1445 EdkLogger.error('build', PARSER_ERROR,
1446 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1447 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1448 if str_pcd_dec:
1449 str_pcd_obj_str = StructurePcd()
1450 str_pcd_obj_str.copy(str_pcd_dec)
1451 if str_pcd_obj:
1452 str_pcd_obj_str.copy(str_pcd_obj)
1453 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1454 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}
1455 else:
1456 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}
1457 for str_pcd_data in StrPcdSet[str_pcd]:
1458 if str_pcd_data[3] in SkuIds:
1459 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])
1460 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1461 else:
1462 EdkLogger.error('build', PARSER_ERROR,
1463 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1464 File=self.MetaFile, Line = StrPcdSet[str_pcd][0][5])
1465 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1466 for Pcd in self.DecPcds:
1467 if isinstance(self._DecPcds[Pcd], StructurePcd):
1468 if Pcd not in S_pcd_set:
1469 str_pcd_obj_str = StructurePcd()
1470 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1471 str_pcd_obj = Pcds.get(Pcd, None)
1472 if str_pcd_obj:
1473 str_pcd_obj_str.copy(str_pcd_obj)
1474 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1475 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}
1476 else:
1477 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}
1478 S_pcd_set[Pcd] = str_pcd_obj_str
1479 if S_pcd_set:
1480 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1481 for stru_pcd in S_pcd_set.values():
1482 for skuid in SkuIds:
1483 if skuid in stru_pcd.SkuOverrideValues:
1484 continue
1485 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1486 NoDefault = False
1487 if skuid not in stru_pcd.SkuOverrideValues:
1488 while nextskuid not in stru_pcd.SkuOverrideValues:
1489 if nextskuid == TAB_DEFAULT:
1490 NoDefault = True
1491 break
1492 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1493 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})
1494 if not NoDefault:
1495 stru_pcd.ValueChain.add((skuid, ''))
1496 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1497 for skuid in SkuIds:
1498 nextskuid = skuid
1499 NoDefault = False
1500 if skuid not in stru_pcd.SkuOverrideValues:
1501 while nextskuid not in stru_pcd.SkuOverrideValues:
1502 if nextskuid == TAB_DEFAULT:
1503 NoDefault = True
1504 break
1505 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1506 if NoDefault:
1507 continue
1508 PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
1509 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1510
1511 for defaultstoreid in DefaultStores:
1512 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1513 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1514 stru_pcd.ValueChain.add((skuid, defaultstoreid))
1515 S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
1516 S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
1517 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1518 if Str_Pcd_Values:
1519 for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
1520 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1521 if str_pcd_obj is None:
1522 print(PcdName, PcdGuid)
1523 raise
1524 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1525 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1526 if skuname not in str_pcd_obj.SkuInfoList:
1527 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1528 else:
1529 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1530 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1531 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1532 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1533 if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1534 str_pcd_obj.DefaultValue = PcdValue
1535 else:
1536 if skuname not in str_pcd_obj.SkuInfoList:
1537 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1538 NoDefault = False
1539 while nextskuid not in str_pcd_obj.SkuInfoList:
1540 if nextskuid == TAB_DEFAULT:
1541 NoDefault = True
1542 break
1543 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1544 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)
1545 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1546 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1547 else:
1548 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1549 for str_pcd_obj in S_pcd_set.values():
1550 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1551 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1552 continue
1553 PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
1554 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1555 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1556 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1557
1558 for str_pcd_obj in S_pcd_set.values():
1559
1560 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1561 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1562 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
1563
1564 for pcdkey in Pcds:
1565 pcd = Pcds[pcdkey]
1566 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1567 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
1568 del pcd.SkuInfoList[TAB_COMMON]
1569 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
1570 del pcd.SkuInfoList[TAB_COMMON]
1571
1572 map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1573 return Pcds
1574
1575 ## Retrieve non-dynamic PCD settings
1576 #
1577 # @param Type PCD type
1578 #
1579 # @retval a dict object contains settings of given PCD type
1580 #
1581 def _GetPcd(self, Type):
1582 Pcds = OrderedDict()
1583 #
1584 # tdict is a special dict kind of type, used for selecting correct
1585 # PCD settings for certain ARCH
1586 #
1587 AvailableSkuIdSet = copy.copy(self.SkuIds)
1588
1589 PcdDict = tdict(True, 3)
1590 PcdSet = set()
1591 # Find out all possible PCD candidates for self._Arch
1592 RecordList = self._RawData[Type, self._Arch]
1593 PcdValueDict = OrderedDict()
1594 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
1595 SkuName = SkuName.upper()
1596 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
1597 if SkuName not in AvailableSkuIdSet:
1598 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1599 File=self.MetaFile, Line=Dummy5)
1600 if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
1601 if "." not in TokenSpaceGuid:
1602 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1603 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1604
1605 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1606 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1607 if Setting is None:
1608 continue
1609 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1610 if MaxDatumSize:
1611 if int(MaxDatumSize, 0) > 0xFFFF:
1612 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1613 File=self.MetaFile, Line=Dummy4)
1614 if int(MaxDatumSize, 0) < 0:
1615 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
1616 File=self.MetaFile, Line=Dummy4)
1617 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1618 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1619 else:
1620 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1621
1622 for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.iteritems():
1623 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1624 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1625 elif TAB_DEFAULT in PcdSetting:
1626 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
1627 elif TAB_COMMON in PcdSetting:
1628 PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
1629 else:
1630 PcdValue = None
1631 DatumType = None
1632 MaxDatumSize = None
1633
1634 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1635 PcdCName,
1636 TokenSpaceGuid,
1637 self._PCD_TYPE_STRING_[Type],
1638 DatumType,
1639 PcdValue,
1640 '',
1641 MaxDatumSize,
1642 {},
1643 False,
1644 None,
1645 IsDsc=True)
1646
1647 if self.SkuIdMgr.SystemSkuId not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
1648 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId] = {}
1649 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[self.SkuIdMgr.SystemSkuId][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
1650 return Pcds
1651
1652 def GetStructurePcdMaxSize(self, str_pcd):
1653 pcd_default_value = str_pcd.DefaultValue
1654 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()]
1655 sku_values.append(pcd_default_value)
1656
1657 def get_length(value):
1658 Value = value.strip()
1659 if len(value) > 1:
1660 if Value.startswith(TAB_GUID) and Value.endswith(')'):
1661 return 16
1662 if Value.startswith('L"') and Value.endswith('"'):
1663 return len(Value[2:-1])
1664 if Value[0] == '"' and Value[-1] == '"':
1665 return len(Value) - 2
1666 if Value[0] == '{' and Value[-1] == '}':
1667 return len(Value.split(","))
1668 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1669 return len(list(Value[2:-1]))
1670 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1671 return len(Value) - 2
1672 return len(Value)
1673
1674 return str(max(get_length(item) for item in sku_values))
1675
1676 @staticmethod
1677 def ExecuteCommand (Command):
1678 try:
1679 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1680 except:
1681 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1682 Result = Process.communicate()
1683 return Process.returncode, Result[0], Result[1]
1684
1685 @staticmethod
1686 def IntToCString(Value, ValueSize):
1687 Result = '"'
1688 if not isinstance (Value, str):
1689 for Index in range(0, ValueSize):
1690 Result = Result + '\\x%02x' % (Value & 0xff)
1691 Value = Value >> 8
1692 Result = Result + '"'
1693 return Result
1694
1695 def GenerateSizeFunction(self, Pcd):
1696 CApp = "// Default Value in Dec \n"
1697 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1698 for FieldList in [Pcd.DefaultValues]:
1699 if not FieldList:
1700 continue
1701 for FieldName in FieldList:
1702 FieldName = "." + FieldName
1703 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1704 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1705 try:
1706 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1707 except BadExpression:
1708 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1709 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1710 Value, ValueSize = ParseFieldValue(Value)
1711 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]);
1712 else:
1713 NewFieldName = ''
1714 FieldName_ori = FieldName.strip('.')
1715 while '[' in FieldName:
1716 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1717 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1718 FieldName = FieldName.split(']', 1)[1]
1719 FieldName = NewFieldName + FieldName
1720 while '[' in FieldName:
1721 FieldName = FieldName.rsplit('[', 1)[0]
1722 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])
1723 for skuname in Pcd.SkuOverrideValues:
1724 if skuname == TAB_COMMON:
1725 continue
1726 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
1727 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1728 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
1729 if not FieldList:
1730 continue
1731 for FieldName in FieldList:
1732 FieldName = "." + FieldName
1733 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1734 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1735 try:
1736 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1737 except BadExpression:
1738 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1739 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1740 Value, ValueSize = ParseFieldValue(Value)
1741 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]);
1742 else:
1743 NewFieldName = ''
1744 FieldName_ori = FieldName.strip('.')
1745 while '[' in FieldName:
1746 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1747 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1748 FieldName = FieldName.split(']', 1)[1]
1749 FieldName = NewFieldName + FieldName
1750 while '[' in FieldName:
1751 FieldName = FieldName.rsplit('[', 1)[0]
1752 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])
1753 if Pcd.PcdFieldValueFromFdf:
1754 CApp = CApp + "// From fdf \n"
1755 for FieldName in Pcd.PcdFieldValueFromFdf:
1756 FieldName = "." + FieldName
1757 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
1758 if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
1759 try:
1760 Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1761 except BadExpression:
1762 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1763 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
1764 Value, ValueSize = ParseFieldValue(Value)
1765 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]);
1766 else:
1767 NewFieldName = ''
1768 FieldName_ori = FieldName.strip('.')
1769 while '[' in FieldName:
1770 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1771 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1772 FieldName = FieldName.split(']', 1)[1]
1773 FieldName = NewFieldName + FieldName
1774 while '[' in FieldName:
1775 FieldName = FieldName.rsplit('[', 1)[0]
1776 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])
1777 if Pcd.PcdFieldValueFromComm:
1778 CApp = CApp + "// From Command Line \n"
1779 for FieldName in Pcd.PcdFieldValueFromComm:
1780 FieldName = "." + FieldName
1781 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
1782 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
1783 try:
1784 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
1785 except BadExpression:
1786 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1787 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
1788 Value, ValueSize = ParseFieldValue(Value)
1789 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]);
1790 else:
1791 NewFieldName = ''
1792 FieldName_ori = FieldName.strip('.')
1793 while '[' in FieldName:
1794 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1795 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1796 FieldName = FieldName.split(']', 1)[1]
1797 FieldName = NewFieldName + FieldName
1798 while '[' in FieldName:
1799 FieldName = FieldName.rsplit('[', 1)[0]
1800 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])
1801 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
1802 CApp = CApp + "}\n"
1803 return CApp
1804
1805 @staticmethod
1806 def GenerateSizeStatments(Pcd):
1807 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1808 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1809 return CApp
1810
1811 def GenerateDefaultValueAssignFunction(self, Pcd):
1812 CApp = "// Default value in Dec \n"
1813 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1814 CApp = CApp + ' UINT32 FieldSize;\n'
1815 CApp = CApp + ' CHAR8 *Value;\n'
1816 DefaultValueFromDec = Pcd.DefaultValueFromDec
1817 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
1818 if IsArray:
1819 try:
1820 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
1821 except BadExpression:
1822 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
1823 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
1824 DefaultValueFromDec = StringToArray(DefaultValueFromDec)
1825 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
1826 if isinstance(Value, str):
1827 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
1828 elif IsArray:
1829 #
1830 # Use memcpy() to copy value into field
1831 #
1832 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
1833 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1834 for FieldList in [Pcd.DefaultValues]:
1835 if not FieldList:
1836 continue
1837 for FieldName in FieldList:
1838 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1839 if IsArray:
1840 try:
1841 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1842 except BadExpression:
1843 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1844 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1845
1846 try:
1847 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1848 except Exception:
1849 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]))
1850 if isinstance(Value, str):
1851 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1852 elif IsArray:
1853 #
1854 # Use memcpy() to copy value into field
1855 #
1856 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1857 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1858 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])
1859 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1860 else:
1861 if '[' in FieldName and ']' in FieldName:
1862 Index = int(FieldName.split('[')[1].split(']')[0])
1863 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)
1864 if ValueSize > 4:
1865 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1866 else:
1867 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1868 CApp = CApp + "}\n"
1869 return CApp
1870
1871 @staticmethod
1872 def GenerateDefaultValueAssignStatement(Pcd):
1873 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1874 return CApp
1875
1876 def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
1877 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
1878 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.DatumType)
1879 CApp = CApp + ' UINT32 FieldSize;\n'
1880 CApp = CApp + ' CHAR8 *Value;\n'
1881
1882 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
1883 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
1884 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1885 pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
1886 else:
1887 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
1888 for FieldList in [pcddefaultvalue, inherit_OverrideValues.get(DefaultStoreName)]:
1889 if not FieldList:
1890 continue
1891 if pcddefaultvalue and FieldList == pcddefaultvalue:
1892 IsArray = IsFieldValueAnArray(FieldList)
1893 if IsArray:
1894 try:
1895 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1896 except BadExpression:
1897 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1898 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1899 Value, ValueSize = ParseFieldValue (FieldList)
1900
1901 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
1902 if isinstance(Value, str):
1903 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)
1904 elif IsArray:
1905 #
1906 # Use memcpy() to copy value into field
1907 #
1908 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)
1909 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1910 else:
1911 if isinstance(Value, str):
1912 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1913 elif IsArray:
1914 #
1915 # Use memcpy() to copy value into field
1916 #
1917 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
1918 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1919 continue
1920 if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
1921 for FieldName in FieldList:
1922 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1923 if IsArray:
1924 try:
1925 FieldValue = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1926 except BadExpression:
1927 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1928 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1929 try:
1930 if IsArray:
1931 Value, ValueSize = ParseFieldValue (FieldValue)
1932 else:
1933 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1934 except Exception:
1935 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]))
1936 if isinstance(Value, str):
1937 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1938 elif IsArray:
1939 #
1940 # Use memcpy() to copy value into field
1941 #
1942 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1943 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1944 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])
1945 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1946 else:
1947 if '[' in FieldName and ']' in FieldName:
1948 Index = int(FieldName.split('[')[1].split(']')[0])
1949 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)
1950 if ValueSize > 4:
1951 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1952 else:
1953 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1954 CApp = CApp + "}\n"
1955 return CApp
1956
1957 @staticmethod
1958 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
1959 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
1960 return CApp
1961
1962 def GenerateCommandLineValue(self, Pcd):
1963 CApp = "// Value in CommandLine\n"
1964 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1965 CApp = CApp + ' UINT32 FieldSize;\n'
1966 CApp = CApp + ' CHAR8 *Value;\n'
1967
1968 pcddefaultvalue = Pcd.PcdValueFromComm
1969 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
1970 if not FieldList:
1971 continue
1972 if pcddefaultvalue and FieldList == pcddefaultvalue:
1973 IsArray = IsFieldValueAnArray(FieldList)
1974 if IsArray:
1975 try:
1976 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1977 except BadExpression:
1978 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1979 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1980 Value, ValueSize = ParseFieldValue (FieldList)
1981
1982 if isinstance(Value, str):
1983 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1984 elif IsArray:
1985 #
1986 # Use memcpy() to copy value into field
1987 #
1988 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
1989 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1990 continue
1991 for FieldName in FieldList:
1992 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1993 if IsArray:
1994 try:
1995 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1996 except BadExpression:
1997 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1998 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1999 except:
2000 print("error")
2001 try:
2002 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2003 except Exception:
2004 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]))
2005 if isinstance(Value, str):
2006 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2007 elif IsArray:
2008 #
2009 # Use memcpy() to copy value into field
2010 #
2011 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2012 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2013 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2014 else:
2015 if ValueSize > 4:
2016 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2017 else:
2018 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2019 CApp = CApp + "}\n"
2020 return CApp
2021
2022 @staticmethod
2023 def GenerateCommandLineValueStatement(Pcd):
2024 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2025 return CApp
2026 def GenerateFdfValue(self,Pcd):
2027 CApp = "// Value in Fdf\n"
2028 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
2029 CApp = CApp + ' UINT32 FieldSize;\n'
2030 CApp = CApp + ' CHAR8 *Value;\n'
2031
2032 pcddefaultvalue = Pcd.PcdValueFromFdf
2033 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
2034 if not FieldList:
2035 continue
2036 if pcddefaultvalue and FieldList == pcddefaultvalue:
2037 IsArray = IsFieldValueAnArray(FieldList)
2038 if IsArray:
2039 try:
2040 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
2041 except BadExpression:
2042 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
2043 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
2044 Value, ValueSize = ParseFieldValue (FieldList)
2045
2046 if isinstance(Value, str):
2047 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
2048 elif IsArray:
2049 #
2050 # Use memcpy() to copy value into field
2051 #
2052 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
2053 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
2054 continue
2055 for FieldName in FieldList:
2056 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2057 if IsArray:
2058 try:
2059 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2060 except BadExpression:
2061 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2062 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2063 except:
2064 print("error")
2065 try:
2066 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2067 except Exception:
2068 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]))
2069 if isinstance(Value, str):
2070 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2071 elif IsArray:
2072 #
2073 # Use memcpy() to copy value into field
2074 #
2075 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2076 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2077 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2078 else:
2079 if ValueSize > 4:
2080 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2081 else:
2082 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2083 CApp = CApp + "}\n"
2084 return CApp
2085
2086 @staticmethod
2087 def GenerateFdfValueStatement(Pcd):
2088 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2089 return CApp
2090
2091 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
2092 OverrideValues = {DefaultStore:""}
2093 if Pcd.SkuOverrideValues:
2094 OverrideValues = Pcd.SkuOverrideValues[SkuName]
2095 if not OverrideValues:
2096 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
2097 for DefaultStoreName in OverrideValues:
2098 CApp = CApp + 'void\n'
2099 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2100 CApp = CApp + ' void\n'
2101 CApp = CApp + ' )\n'
2102 CApp = CApp + '{\n'
2103 CApp = CApp + ' UINT32 Size;\n'
2104 CApp = CApp + ' UINT32 FieldSize;\n'
2105 CApp = CApp + ' CHAR8 *Value;\n'
2106 CApp = CApp + ' UINT32 OriginalSize;\n'
2107 CApp = CApp + ' VOID *OriginalPcd;\n'
2108 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
2109 CApp = CApp + '\n'
2110
2111 if SkuName in Pcd.SkuInfoList:
2112 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
2113 else:
2114 DefaultValue = Pcd.DefaultValue
2115 PcdDefaultValue = StringToArray(DefaultValue.strip())
2116
2117 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
2118
2119 #
2120 # Get current PCD value and size
2121 #
2122 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2123
2124 #
2125 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
2126 # the correct value. For structures with a flexible array member, the flexible
2127 # array member is detected, and the size is based on the highest index used with
2128 # the flexible array member. The flexible array member must be the last field
2129 # in a structure. The size formula for this case is:
2130 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
2131 #
2132 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)
2133
2134 #
2135 # Allocate and zero buffer for the PCD
2136 # Must handle cases where current value is smaller, larger, or same size
2137 # Always keep that larger one as the current size
2138 #
2139 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
2140 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
2141 CApp = CApp + ' memset (Pcd, 0, Size);\n'
2142
2143 #
2144 # Copy current PCD value into allocated buffer.
2145 #
2146 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
2147
2148 #
2149 # Assign field values in PCD
2150 #
2151 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
2152 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2153 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2154 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
2155 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
2156 for defaultstorenameitem in storeset:
2157 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
2158 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
2159 if skuname == SkuName:
2160 break
2161 else:
2162 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
2163 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2164 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
2165 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
2166 #
2167 # Set new PCD value and size
2168 #
2169 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2170
2171 #
2172 # Free PCD
2173 #
2174 CApp = CApp + ' free (Pcd);\n'
2175 CApp = CApp + '}\n'
2176 CApp = CApp + '\n'
2177 return InitByteValue, CApp
2178 def SkuOverrideValuesEmpty(self,OverrideValues):
2179 if not OverrideValues:
2180 return True
2181 for key in OverrideValues:
2182 if OverrideValues[key]:
2183 return False
2184 return True
2185
2186 def GenerateByteArrayValue (self, StructuredPcds):
2187 #
2188 # Generate/Compile/Run C application to determine if there are any flexible array members
2189 #
2190 if not StructuredPcds:
2191 return
2192
2193 InitByteValue = ""
2194 CApp = PcdMainCHeader
2195
2196 IncludeFiles = set()
2197 for PcdName in StructuredPcds:
2198 Pcd = StructuredPcds[PcdName]
2199 for IncludeFile in Pcd.StructuredPcdIncludeFile:
2200 if IncludeFile not in IncludeFiles:
2201 IncludeFiles.add(IncludeFile)
2202 CApp = CApp + '#include <%s>\n' % (IncludeFile)
2203 CApp = CApp + '\n'
2204 for PcdName in StructuredPcds:
2205 Pcd = StructuredPcds[PcdName]
2206 CApp = CApp + self.GenerateSizeFunction(Pcd)
2207 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
2208 CApp = CApp + self.GenerateFdfValue(Pcd)
2209 CApp = CApp + self.GenerateCommandLineValue(Pcd)
2210 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2211 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2212 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2213 else:
2214 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2215 if SkuName not in Pcd.SkuOverrideValues:
2216 continue
2217 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2218 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
2219 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2220 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2221 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
2222 else:
2223 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2224 if SkuName not in Pcd.SkuOverrideValues:
2225 continue
2226 for DefaultStoreName in Pcd.DefaultStoreName:
2227 Pcd = StructuredPcds[PcdName]
2228 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2229
2230 CApp = CApp + 'VOID\n'
2231 CApp = CApp + 'PcdEntryPoint(\n'
2232 CApp = CApp + ' VOID\n'
2233 CApp = CApp + ' )\n'
2234 CApp = CApp + '{\n'
2235 for Pcd in StructuredPcds.values():
2236 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]]:
2237 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2238 else:
2239 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2240 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
2241 continue
2242 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2243 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2244 CApp = CApp + '}\n'
2245
2246 CApp = CApp + PcdMainCEntry + '\n'
2247
2248 if not os.path.exists(self.OutputPath):
2249 os.makedirs(self.OutputPath)
2250 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2251 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2252
2253 MakeApp = PcdMakefileHeader
2254 if sys.platform == "win32":
2255 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2256 else:
2257 MakeApp = MakeApp + PcdGccMakefile
2258 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2259 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2260
2261 IncSearchList = []
2262 PlatformInc = OrderedDict()
2263 for Cache in self._Bdb._CACHE_.values():
2264 if Cache.MetaFile.Ext.lower() != '.dec':
2265 continue
2266 if Cache.Includes:
2267 if str(Cache.MetaFile.Path) not in PlatformInc:
2268 PlatformInc[str(Cache.MetaFile.Path)] = []
2269 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
2270 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
2271
2272 PcdDependDEC = []
2273 for Pcd in StructuredPcds.values():
2274 for PackageDec in Pcd.PackageDecs:
2275 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2276 if not os.path.exists(Package):
2277 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2278 if Package not in PcdDependDEC:
2279 PcdDependDEC.append(Package)
2280
2281 if PlatformInc and PcdDependDEC:
2282 for pkg in PcdDependDEC:
2283 if pkg in PlatformInc:
2284 for inc in PlatformInc[pkg]:
2285 MakeApp += '-I' + str(inc) + ' '
2286 IncSearchList.append(inc)
2287 MakeApp = MakeApp + '\n'
2288
2289 CC_FLAGS = LinuxCFLAGS
2290 if sys.platform == "win32":
2291 CC_FLAGS = WindowsCFLAGS
2292 BuildOptions = OrderedDict()
2293 for Options in self.BuildOptions:
2294 if Options[2] != EDKII_NAME:
2295 continue
2296 Family = Options[0]
2297 if Family and Family != self.ToolChainFamily:
2298 continue
2299 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2300 if Tool != 'CC':
2301 continue
2302
2303 if Target == "*" or Target == self._Target:
2304 if Tag == "*" or Tag == self._Toolchain:
2305 if Arch == "*" or Arch == self.Arch:
2306 if Tool not in BuildOptions:
2307 BuildOptions[Tool] = OrderedDict()
2308 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2309 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2310 else:
2311 # append options for the same tool except PATH
2312 if Attr != 'PATH':
2313 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2314 else:
2315 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2316 if BuildOptions:
2317 for Tool in BuildOptions:
2318 for Attr in BuildOptions[Tool]:
2319 if Attr == "FLAGS":
2320 Value = BuildOptions[Tool][Attr]
2321 ValueList = Value.split()
2322 if ValueList:
2323 for Id, Item in enumerate(ValueList):
2324 if Item in ['-D', '/D', '-U', '/U']:
2325 CC_FLAGS += ' ' + Item
2326 if Id + 1 < len(ValueList):
2327 CC_FLAGS += ' ' + ValueList[Id + 1]
2328 elif Item.startswith(('-D', '/D', '-U', '/U')):
2329 CC_FLAGS += ' ' + Item
2330 MakeApp += CC_FLAGS
2331
2332 if sys.platform == "win32":
2333 MakeApp = MakeApp + PcdMakefileEnd
2334 MakeApp = MakeApp + '\n'
2335 IncludeFileFullPaths = []
2336 for includefile in IncludeFiles:
2337 for includepath in IncSearchList:
2338 includefullpath = os.path.join(str(includepath), includefile)
2339 if os.path.exists(includefullpath):
2340 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2341 break
2342 SearchPathList = []
2343 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2344 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2345 SearchPathList.extend(str(item) for item in IncSearchList)
2346 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
2347 for include_file in IncFileList:
2348 MakeApp += "$(OBJECTS) : %s\n" % include_file
2349 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2350 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2351 SaveFileOnChange(MakeFileName, MakeApp, False)
2352
2353 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2354 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2355 SaveFileOnChange(InputValueFile, InitByteValue, False)
2356
2357 PcdValueInitExe = PcdValueInitName
2358 if not sys.platform == "win32":
2359 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
2360 else:
2361 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
2362
2363 Messages = ''
2364 if sys.platform == "win32":
2365 MakeCommand = 'nmake -f %s' % (MakeFileName)
2366 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2367 Messages = StdOut
2368 else:
2369 MakeCommand = 'make -f %s' % (MakeFileName)
2370 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2371 Messages = StdErr
2372 Messages = Messages.split('\n')
2373 MessageGroup = []
2374 if returncode != 0:
2375 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2376 File = open (CAppBaseFileName + '.c', 'r')
2377 FileData = File.readlines()
2378 File.close()
2379 for Message in Messages:
2380 if " error" in Message or "warning" in Message:
2381 FileInfo = Message.strip().split('(')
2382 if len (FileInfo) > 1:
2383 FileName = FileInfo [0]
2384 FileLine = FileInfo [1].split (')')[0]
2385 else:
2386 FileInfo = Message.strip().split(':')
2387 FileName = FileInfo [0]
2388 FileLine = FileInfo [1]
2389 if FileLine.isdigit():
2390 error_line = FileData[int (FileLine) - 1]
2391 if r"//" in error_line:
2392 c_line, dsc_line = error_line.split(r"//")
2393 else:
2394 dsc_line = error_line
2395 message_itmes = Message.split(":")
2396 Index = 0
2397 if "PcdValueInit.c" not in Message:
2398 if not MessageGroup:
2399 MessageGroup.append(Message)
2400 break
2401 else:
2402 for item in message_itmes:
2403 if "PcdValueInit.c" in item:
2404 Index = message_itmes.index(item)
2405 message_itmes[Index] = dsc_line.strip()
2406 break
2407 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2408 continue
2409 else:
2410 MessageGroup.append(Message)
2411 if MessageGroup:
2412 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2413 else:
2414 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2415
2416 if DscBuildData.NeedUpdateOutput(OutputValueFile, PcdValueInitExe, InputValueFile):
2417 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2418 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
2419 if returncode != 0:
2420 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2421
2422 File = open (OutputValueFile, 'r')
2423 FileBuffer = File.readlines()
2424 File.close()
2425
2426 StructurePcdSet = []
2427 for Pcd in FileBuffer:
2428 PcdValue = Pcd.split ('|')
2429 PcdInfo = PcdValue[0].split ('.')
2430 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2431 return StructurePcdSet
2432
2433 @staticmethod
2434 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
2435 if not os.path.exists(OutputFile):
2436 return True
2437 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2438 return True
2439 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2440 return True
2441 return False
2442
2443 ## Retrieve dynamic PCD settings
2444 #
2445 # @param Type PCD type
2446 #
2447 # @retval a dict object contains settings of given PCD type
2448 #
2449 def _GetDynamicPcd(self, Type):
2450
2451
2452 Pcds = OrderedDict()
2453 #
2454 # tdict is a special dict kind of type, used for selecting correct
2455 # PCD settings for certain ARCH and SKU
2456 #
2457 PcdDict = tdict(True, 4)
2458 PcdList = []
2459 # Find out all possible PCD candidates for self._Arch
2460 RecordList = self._RawData[Type, self._Arch]
2461 AvailableSkuIdSet = copy.copy(self.SkuIds)
2462
2463
2464 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2465 SkuName = SkuName.upper()
2466 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2467 if SkuName not in AvailableSkuIdSet:
2468 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2469 File=self.MetaFile, Line=Dummy5)
2470 if "." not in TokenSpaceGuid:
2471 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2472 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2473
2474 # Remove redundant PCD candidates, per the ARCH and SKU
2475 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2476
2477 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2478 if Setting is None:
2479 continue
2480
2481 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2482 if MaxDatumSize:
2483 if int(MaxDatumSize, 0) > 0xFFFF:
2484 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2485 File=self.MetaFile, Line=Dummy4)
2486 if int(MaxDatumSize, 0) < 0:
2487 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2488 File=self.MetaFile, Line=Dummy4)
2489 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2490 if (PcdCName, TokenSpaceGuid) in Pcds:
2491 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2492 pcdObject.SkuInfoList[SkuName] = SkuInfo
2493 if MaxDatumSize.strip():
2494 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2495 else:
2496 CurrentMaxSize = 0
2497 if pcdObject.MaxDatumSize:
2498 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2499 else:
2500 PcdMaxSize = 0
2501 if CurrentMaxSize > PcdMaxSize:
2502 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2503 else:
2504 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2505 PcdCName,
2506 TokenSpaceGuid,
2507 self._PCD_TYPE_STRING_[Type],
2508 DatumType,
2509 PcdValue,
2510 '',
2511 MaxDatumSize,
2512 OrderedDict({SkuName : SkuInfo}),
2513 False,
2514 None,
2515 IsDsc=True)
2516
2517 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2518 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2519 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
2520
2521 for pcd in Pcds.values():
2522 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2523 # Only fix the value while no value provided in DSC file.
2524 for sku in pcd.SkuInfoList.values():
2525 if not sku.DefaultValue:
2526 sku.DefaultValue = pcdDecObject.DefaultValue
2527 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2528 valuefromDec = pcdDecObject.DefaultValue
2529 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
2530 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2531 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2532 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2533 del pcd.SkuInfoList[TAB_COMMON]
2534 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2535 del pcd.SkuInfoList[TAB_COMMON]
2536
2537 map(self.FilterSkuSettings, Pcds.values())
2538
2539 return Pcds
2540
2541 def FilterSkuSettings(self, PcdObj):
2542
2543 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2544 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
2545 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
2546 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2547 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
2548 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
2549
2550 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2551 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
2552
2553 return PcdObj
2554
2555 @staticmethod
2556 def CompareVarAttr(Attr1, Attr2):
2557 if not Attr1 or not Attr2: # for empty string
2558 return True
2559 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2560 Attr1Set = set(Attr1s)
2561 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2562 Attr2Set = set(Attr2s)
2563 if Attr2Set == Attr1Set:
2564 return True
2565 else:
2566 return False
2567
2568 def CompletePcdValues(self, PcdSet):
2569 Pcds = OrderedDict()
2570 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2571 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
2572 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
2573 for PcdCName, TokenSpaceGuid in PcdSet:
2574 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2575
2576 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2577 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2578 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2579 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2580 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2581 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2582 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2583 continue
2584 PcdType = PcdObj.Type
2585 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2586 for skuid in PcdObj.SkuInfoList:
2587 skuobj = PcdObj.SkuInfoList[skuid]
2588 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
2589 for defaultstorename in DefaultStores:
2590 if defaultstorename not in skuobj.DefaultStoreDict:
2591 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2592 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2593 for skuname, skuid in SkuIds.items():
2594 if skuname not in PcdObj.SkuInfoList:
2595 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2596 while nextskuid not in PcdObj.SkuInfoList:
2597 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2598 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2599 PcdObj.SkuInfoList[skuname].SkuId = skuid
2600 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2601 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2602 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
2603 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2604 return Pcds
2605 ## Retrieve dynamic HII PCD settings
2606 #
2607 # @param Type PCD type
2608 #
2609 # @retval a dict object contains settings of given PCD type
2610 #
2611 def _GetDynamicHiiPcd(self, Type):
2612
2613 VariableAttrs = {}
2614
2615 Pcds = OrderedDict()
2616 UserDefinedDefaultStores = []
2617 #
2618 # tdict is a special dict kind of type, used for selecting correct
2619 # PCD settings for certain ARCH and SKU
2620 #
2621 PcdDict = tdict(True, 5)
2622 PcdSet = set()
2623 RecordList = self._RawData[Type, self._Arch]
2624 # Find out all possible PCD candidates for self._Arch
2625 AvailableSkuIdSet = copy.copy(self.SkuIds)
2626 DefaultStoresDefine = self._GetDefaultStores()
2627
2628 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
2629 SkuName = SkuName.upper()
2630 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2631 DefaultStore = DefaultStore.upper()
2632 if DefaultStore == TAB_COMMON:
2633 DefaultStore = TAB_DEFAULT_STORES_DEFAULT
2634 else:
2635 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
2636 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
2637 if SkuName not in AvailableSkuIdSet:
2638 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2639 File=self.MetaFile, Line=Dummy5)
2640 if DefaultStore not in DefaultStoresDefine:
2641 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2642 File=self.MetaFile, Line=Dummy5)
2643 if "." not in TokenSpaceGuid:
2644 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
2645 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
2646
2647
2648 # Remove redundant PCD candidates, per the ARCH and SKU
2649 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:
2650
2651 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
2652 if Setting is None:
2653 continue
2654 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2655
2656 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2657 if not rt:
2658 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2659 ExtraData="[%s]" % VarAttribute)
2660 ExceedMax = False
2661 FormatCorrect = True
2662 if VariableOffset.isdigit():
2663 if int(VariableOffset, 10) > 0xFFFF:
2664 ExceedMax = True
2665 elif variablePattern.match(VariableOffset):
2666 if int(VariableOffset, 16) > 0xFFFF:
2667 ExceedMax = True
2668 # For Offset written in "A.B"
2669 elif VariableOffset.find('.') > -1:
2670 VariableOffsetList = VariableOffset.split(".")
2671 if not (len(VariableOffsetList) == 2
2672 and IsValidWord(VariableOffsetList[0])
2673 and IsValidWord(VariableOffsetList[1])):
2674 FormatCorrect = False
2675 else:
2676 FormatCorrect = False
2677 if not FormatCorrect:
2678 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2679
2680 if ExceedMax:
2681 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2682 if (VariableName, VariableGuid) not in VariableAttrs:
2683 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2684 else:
2685 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2686 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)]))
2687
2688 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2689 if (PcdCName, TokenSpaceGuid) in Pcds:
2690 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2691 if SkuName in pcdObject.SkuInfoList:
2692 Skuitem = pcdObject.SkuInfoList[SkuName]
2693 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2694 else:
2695 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2696 pcdObject.SkuInfoList[SkuName] = SkuInfo
2697 else:
2698 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2699 PcdClassObj = PcdClassObject(
2700 PcdCName,
2701 TokenSpaceGuid,
2702 self._PCD_TYPE_STRING_[Type],
2703 '',
2704 DefaultValue,
2705 '',
2706 '',
2707 OrderedDict({SkuName : SkuInfo}),
2708 False,
2709 None,
2710 pcdDecObject.validateranges,
2711 pcdDecObject.validlists,
2712 pcdDecObject.expressions,
2713 IsDsc=True)
2714 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
2715 PcdClassObj.UserDefinedDefaultStoresFlag = True
2716 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
2717
2718 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
2719 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2720 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2721 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
2722 for pcd in Pcds.values():
2723 SkuInfoObj = pcd.SkuInfoList.values()[0]
2724 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2725 pcd.DatumType = pcdDecObject.DatumType
2726 # Only fix the value while no value provided in DSC file.
2727 for sku in pcd.SkuInfoList.values():
2728 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
2729 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2730 for default_store in sku.DefaultStoreDict:
2731 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2732 pcd.DefaultValue = pcdDecObject.DefaultValue
2733 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2734 valuefromDec = pcdDecObject.DefaultValue
2735 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
2736 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2737 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2738 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2739 del pcd.SkuInfoList[TAB_COMMON]
2740 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2741 del pcd.SkuInfoList[TAB_COMMON]
2742
2743 if pcd.MaxDatumSize.strip():
2744 MaxSize = int(pcd.MaxDatumSize, 0)
2745 else:
2746 MaxSize = 0
2747 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
2748 for (_, skuobj) in pcd.SkuInfoList.items():
2749 datalen = 0
2750 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2751 datalen = len(skuobj.HiiDefaultValue.split(","))
2752 if datalen > MaxSize:
2753 MaxSize = datalen
2754 for defaultst in skuobj.DefaultStoreDict:
2755 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2756 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2757 pcd.MaxDatumSize = str(MaxSize)
2758 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
2759 if not rt:
2760 invalidpcd = ",".join(invalidhii)
2761 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)
2762
2763 map(self.FilterSkuSettings, Pcds.values())
2764
2765 return Pcds
2766
2767 @staticmethod
2768 def CheckVariableNameAssignment(Pcds):
2769 invalidhii = []
2770 for pcdname in Pcds:
2771 pcd = Pcds[pcdname]
2772 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
2773 if len(varnameset) > 1:
2774 invalidhii.append(".".join((pcdname[1], pcdname[0])))
2775 if len(invalidhii):
2776 return False, invalidhii
2777 else:
2778 return True, []
2779 ## Retrieve dynamic VPD PCD settings
2780 #
2781 # @param Type PCD type
2782 #
2783 # @retval a dict object contains settings of given PCD type
2784 #
2785 def _GetDynamicVpdPcd(self, Type):
2786
2787
2788 Pcds = OrderedDict()
2789 #
2790 # tdict is a special dict kind of type, used for selecting correct
2791 # PCD settings for certain ARCH and SKU
2792 #
2793 PcdDict = tdict(True, 4)
2794 PcdList = []
2795
2796 # Find out all possible PCD candidates for self._Arch
2797 RecordList = self._RawData[Type, self._Arch]
2798 AvailableSkuIdSet = copy.copy(self.SkuIds)
2799
2800 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2801 SkuName = SkuName.upper()
2802 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2803 if SkuName not in AvailableSkuIdSet:
2804 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2805 File=self.MetaFile, Line=Dummy5)
2806 if "." not in TokenSpaceGuid:
2807 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2808 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2809
2810 # Remove redundant PCD candidates, per the ARCH and SKU
2811 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2812 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2813 if Setting is None:
2814 continue
2815 #
2816 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2817 # For the Integer & Boolean type, the optional data can only be InitialValue.
2818 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2819 # until the DEC parser has been called.
2820 #
2821 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2822 if MaxDatumSize:
2823 if int(MaxDatumSize, 0) > 0xFFFF:
2824 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2825 File=self.MetaFile, Line=Dummy4)
2826 if int(MaxDatumSize, 0) < 0:
2827 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2828 File=self.MetaFile, Line=Dummy4)
2829 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2830 if (PcdCName, TokenSpaceGuid) in Pcds:
2831 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2832 pcdObject.SkuInfoList[SkuName] = SkuInfo
2833 if MaxDatumSize.strip():
2834 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2835 else:
2836 CurrentMaxSize = 0
2837 if pcdObject.MaxDatumSize:
2838 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2839 else:
2840 PcdMaxSize = 0
2841 if CurrentMaxSize > PcdMaxSize:
2842 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2843 else:
2844 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2845 PcdCName,
2846 TokenSpaceGuid,
2847 self._PCD_TYPE_STRING_[Type],
2848 '',
2849 InitialValue,
2850 '',
2851 MaxDatumSize,
2852 OrderedDict({SkuName : SkuInfo}),
2853 False,
2854 None,
2855 IsDsc=True)
2856
2857 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2858 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2859 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
2860 for pcd in Pcds.values():
2861 SkuInfoObj = pcd.SkuInfoList.values()[0]
2862 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2863 pcd.DatumType = pcdDecObject.DatumType
2864 # Only fix the value while no value provided in DSC file.
2865 for sku in pcd.SkuInfoList.values():
2866 if not sku.DefaultValue:
2867 sku.DefaultValue = pcdDecObject.DefaultValue
2868 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2869 valuefromDec = pcdDecObject.DefaultValue
2870 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2871 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2872 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2873 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2874 del pcd.SkuInfoList[TAB_COMMON]
2875 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2876 del pcd.SkuInfoList[TAB_COMMON]
2877
2878
2879 map(self.FilterSkuSettings, Pcds.values())
2880 return Pcds
2881
2882 ## Add external modules
2883 #
2884 # The external modules are mostly those listed in FDF file, which don't
2885 # need "build".
2886 #
2887 # @param FilePath The path of module description file
2888 #
2889 def AddModule(self, FilePath):
2890 FilePath = NormPath(FilePath)
2891 if FilePath not in self.Modules:
2892 Module = ModuleBuildClassObject()
2893 Module.MetaFile = FilePath
2894 self.Modules.append(Module)
2895
2896 @property
2897 def ToolChainFamily(self):
2898 self._ToolChainFamily = TAB_COMPILER_MSFT
2899 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2900 if os.path.isfile(BuildConfigurationFile) == True:
2901 TargetTxt = TargetTxtClassObject()
2902 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2903 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2904 if ToolDefinitionFile == '':
2905 ToolDefinitionFile = "tools_def.txt"
2906 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2907 if os.path.isfile(ToolDefinitionFile) == True:
2908 ToolDef = ToolDefClassObject()
2909 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2910 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2911 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2912 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2913 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2914 self._ToolChainFamily = TAB_COMPILER_MSFT
2915 else:
2916 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2917 return self._ToolChainFamily
2918
2919 ## Add external PCDs
2920 #
2921 # The external PCDs are mostly those listed in FDF file to specify address
2922 # or offset information.
2923 #
2924 # @param Name Name of the PCD
2925 # @param Guid Token space guid of the PCD
2926 # @param Value Value of the PCD
2927 #
2928 def AddPcd(self, Name, Guid, Value):
2929 if (Name, Guid) not in self.Pcds:
2930 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2931 self.Pcds[Name, Guid].DefaultValue = Value
2932
2933 @property
2934 def DecPcds(self):
2935 if self._DecPcds is None:
2936 FdfInfList = []
2937 if GlobalData.gFdfParser:
2938 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2939 PkgSet = set()
2940 for Inf in FdfInfList:
2941 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2942 if ModuleFile in self._Modules:
2943 continue
2944 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2945 PkgSet.update(ModuleData.Packages)
2946 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
2947 return self._DecPcds