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