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