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