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