]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Remove Arch specific build options for PcdValueInit tool.
[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 FieldList[FieldName][0] = 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 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1912 except Exception:
1913 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]))
1914 if isinstance(Value, str):
1915 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1916 elif IsArray:
1917 #
1918 # Use memcpy() to copy value into field
1919 #
1920 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1921 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1922 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])
1923 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1924 else:
1925 if '[' in FieldName and ']' in FieldName:
1926 Index = int(FieldName.split('[')[1].split(']')[0])
1927 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)
1928 if ValueSize > 4:
1929 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1930 else:
1931 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1932 CApp = CApp + "}\n"
1933 return CApp
1934
1935 @staticmethod
1936 def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
1937 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
1938 return CApp
1939
1940 def GenerateCommandLineValue(self, Pcd):
1941 CApp = "// Value in CommandLine\n"
1942 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType)
1943 CApp = CApp + ' UINT32 FieldSize;\n'
1944 CApp = CApp + ' CHAR8 *Value;\n'
1945
1946 pcddefaultvalue = Pcd.PcdValueFromComm
1947 for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
1948 if not FieldList:
1949 continue
1950 if pcddefaultvalue and FieldList == pcddefaultvalue:
1951 IsArray = IsFieldValueAnArray(FieldList)
1952 if IsArray:
1953 try:
1954 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
1955 except BadExpression:
1956 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1957 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1958 Value, ValueSize = ParseFieldValue (FieldList)
1959
1960 if isinstance(Value, str):
1961 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1962 elif IsArray:
1963 #
1964 # Use memcpy() to copy value into field
1965 #
1966 CApp = CApp + ' Value = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
1967 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1968 continue
1969 for FieldName in FieldList:
1970 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1971 if IsArray:
1972 try:
1973 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
1974 except BadExpression:
1975 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1976 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1977 except:
1978 print("error")
1979 try:
1980 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1981 except Exception:
1982 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]))
1983 if isinstance(Value, str):
1984 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1985 elif IsArray:
1986 #
1987 # Use memcpy() to copy value into field
1988 #
1989 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1990 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1991 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])
1992 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1993 else:
1994 if '[' in FieldName and ']' in FieldName:
1995 Index = int(FieldName.split('[')[1].split(']')[0])
1996 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)
1997 if ValueSize > 4:
1998 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1999 else:
2000 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2001 CApp = CApp + "}\n"
2002 return CApp
2003
2004 @staticmethod
2005 def GenerateCommandLineValueStatement(Pcd):
2006 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2007 return CApp
2008 def GenerateFdfValue(self,Pcd):
2009 CApp = "// Value in Fdf\n"
2010 CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
2011 CApp = CApp + ' UINT32 FieldSize;\n'
2012 CApp = CApp + ' CHAR8 *Value;\n'
2013
2014 pcddefaultvalue = Pcd.PcdValueFromFdf
2015 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
2016 if not FieldList:
2017 continue
2018 if pcddefaultvalue and FieldList == pcddefaultvalue:
2019 IsArray = IsFieldValueAnArray(FieldList)
2020 if IsArray:
2021 try:
2022 FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
2023 except BadExpression:
2024 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
2025 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
2026 Value, ValueSize = ParseFieldValue (FieldList)
2027
2028 if isinstance(Value, str):
2029 CApp = CApp + ' Pcd = %s; // From Fdf \n' % (Value)
2030 elif IsArray:
2031 #
2032 # Use memcpy() to copy value into field
2033 #
2034 CApp = CApp + ' Value = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
2035 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
2036 continue
2037 for FieldName in FieldList:
2038 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
2039 if IsArray:
2040 try:
2041 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
2042 except BadExpression:
2043 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
2044 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
2045 except:
2046 print("error")
2047 try:
2048 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
2049 except Exception:
2050 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]))
2051 if isinstance(Value, str):
2052 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2053 elif IsArray:
2054 #
2055 # Use memcpy() to copy value into field
2056 #
2057 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
2058 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2059 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])
2060 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
2061 else:
2062 if '[' in FieldName and ']' in FieldName:
2063 Index = int(FieldName.split('[')[1].split(']')[0])
2064 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)
2065 if ValueSize > 4:
2066 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2067 else:
2068 CApp = CApp + ' Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
2069 CApp = CApp + "}\n"
2070 return CApp
2071
2072 @staticmethod
2073 def GenerateFdfValueStatement(Pcd):
2074 CApp = ' Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2075 return CApp
2076
2077 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
2078 OverrideValues = {DefaultStore:""}
2079 if Pcd.SkuOverrideValues:
2080 OverrideValues = Pcd.SkuOverrideValues[SkuName]
2081 if not OverrideValues:
2082 OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
2083 for DefaultStoreName in OverrideValues:
2084 CApp = CApp + 'void\n'
2085 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2086 CApp = CApp + ' void\n'
2087 CApp = CApp + ' )\n'
2088 CApp = CApp + '{\n'
2089 CApp = CApp + ' UINT32 Size;\n'
2090 CApp = CApp + ' UINT32 FieldSize;\n'
2091 CApp = CApp + ' CHAR8 *Value;\n'
2092 CApp = CApp + ' UINT32 OriginalSize;\n'
2093 CApp = CApp + ' VOID *OriginalPcd;\n'
2094 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
2095 CApp = CApp + '\n'
2096
2097 if SkuName in Pcd.SkuInfoList:
2098 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName, Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
2099 else:
2100 DefaultValue = Pcd.DefaultValue
2101 PcdDefaultValue = StringToArray(DefaultValue.strip())
2102
2103 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
2104
2105 #
2106 # Get current PCD value and size
2107 #
2108 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2109
2110 #
2111 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
2112 # the correct value. For structures with a flexible array member, the flexible
2113 # array member is detected, and the size is based on the highest index used with
2114 # the flexible array member. The flexible array member must be the last field
2115 # in a structure. The size formula for this case is:
2116 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
2117 #
2118 CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd)
2119
2120 #
2121 # Allocate and zero buffer for the PCD
2122 # Must handle cases where current value is smaller, larger, or same size
2123 # Always keep that larger one as the current size
2124 #
2125 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
2126 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
2127 CApp = CApp + ' memset (Pcd, 0, Size);\n'
2128
2129 #
2130 # Copy current PCD value into allocated buffer.
2131 #
2132 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
2133
2134 #
2135 # Assign field values in PCD
2136 #
2137 CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
2138 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2139 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2140 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
2141 storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
2142 for defaultstorenameitem in storeset:
2143 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
2144 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
2145 if skuname == SkuName:
2146 break
2147 else:
2148 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
2149 CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2150 CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
2151 CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
2152 #
2153 # Set new PCD value and size
2154 #
2155 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2156
2157 #
2158 # Free PCD
2159 #
2160 CApp = CApp + ' free (Pcd);\n'
2161 CApp = CApp + '}\n'
2162 CApp = CApp + '\n'
2163 return InitByteValue, CApp
2164 def SkuOverrideValuesEmpty(self,OverrideValues):
2165 if not OverrideValues:
2166 return True
2167 for key in OverrideValues:
2168 if OverrideValues[key]:
2169 return False
2170 return True
2171
2172 def GenerateByteArrayValue (self, StructuredPcds):
2173 #
2174 # Generate/Compile/Run C application to determine if there are any flexible array members
2175 #
2176 if not StructuredPcds:
2177 return
2178
2179 InitByteValue = ""
2180 CApp = PcdMainCHeader
2181
2182 IncludeFiles = set()
2183 for PcdName in StructuredPcds:
2184 Pcd = StructuredPcds[PcdName]
2185 for IncludeFile in Pcd.StructuredPcdIncludeFile:
2186 if IncludeFile not in IncludeFiles:
2187 IncludeFiles.add(IncludeFile)
2188 CApp = CApp + '#include <%s>\n' % (IncludeFile)
2189 CApp = CApp + '\n'
2190 for PcdName in StructuredPcds:
2191 Pcd = StructuredPcds[PcdName]
2192 CApp = CApp + self.GenerateSizeFunction(Pcd)
2193 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
2194 CApp = CApp + self.GenerateFdfValue(Pcd)
2195 CApp = CApp + self.GenerateCommandLineValue(Pcd)
2196 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2197 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2198 CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
2199 else:
2200 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2201 if SkuName not in Pcd.SkuOverrideValues:
2202 continue
2203 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2204 CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
2205 if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2206 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2207 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
2208 else:
2209 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2210 if SkuName not in Pcd.SkuOverrideValues:
2211 continue
2212 for DefaultStoreName in Pcd.DefaultStoreName:
2213 Pcd = StructuredPcds[PcdName]
2214 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2215
2216 CApp = CApp + 'VOID\n'
2217 CApp = CApp + 'PcdEntryPoint(\n'
2218 CApp = CApp + ' VOID\n'
2219 CApp = CApp + ' )\n'
2220 CApp = CApp + '{\n'
2221 for Pcd in StructuredPcds.values():
2222 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]]:
2223 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2224 else:
2225 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2226 if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
2227 continue
2228 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2229 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2230 CApp = CApp + '}\n'
2231
2232 CApp = CApp + PcdMainCEntry + '\n'
2233
2234 if not os.path.exists(self.OutputPath):
2235 os.makedirs(self.OutputPath)
2236 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2237 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2238
2239 MakeApp = PcdMakefileHeader
2240 if sys.platform == "win32":
2241 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2242 else:
2243 MakeApp = MakeApp + PcdGccMakefile
2244 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2245 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2246
2247 IncSearchList = []
2248 PlatformInc = OrderedDict()
2249 for Cache in self._Bdb._CACHE_.values():
2250 if Cache.MetaFile.Ext.lower() != '.dec':
2251 continue
2252 if Cache.Includes:
2253 if str(Cache.MetaFile.Path) not in PlatformInc:
2254 PlatformInc[str(Cache.MetaFile.Path)] = []
2255 PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
2256 PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
2257
2258 PcdDependDEC = []
2259 for Pcd in StructuredPcds.values():
2260 for PackageDec in Pcd.PackageDecs:
2261 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2262 if not os.path.exists(Package):
2263 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2264 if Package not in PcdDependDEC:
2265 PcdDependDEC.append(Package)
2266
2267 if PlatformInc and PcdDependDEC:
2268 for pkg in PcdDependDEC:
2269 if pkg in PlatformInc:
2270 for inc in PlatformInc[pkg]:
2271 MakeApp += '-I' + str(inc) + ' '
2272 IncSearchList.append(inc)
2273 MakeApp = MakeApp + '\n'
2274
2275 CC_FLAGS = LinuxCFLAGS
2276 if sys.platform == "win32":
2277 CC_FLAGS = WindowsCFLAGS
2278 BuildOptions = OrderedDict()
2279 for Options in self.BuildOptions:
2280 if Options[2] != EDKII_NAME:
2281 continue
2282 Family = Options[0]
2283 if Family and Family != self.ToolChainFamily:
2284 continue
2285 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2286 if Tool != 'CC':
2287 continue
2288
2289 if Target == "*" or Target == self._Target:
2290 if Tag == "*" or Tag == self._Toolchain:
2291 if Arch == "*":
2292 if Tool not in BuildOptions:
2293 BuildOptions[Tool] = OrderedDict()
2294 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2295 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2296 else:
2297 # append options for the same tool except PATH
2298 if Attr != 'PATH':
2299 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2300 else:
2301 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2302 if BuildOptions:
2303 for Tool in BuildOptions:
2304 for Attr in BuildOptions[Tool]:
2305 if Attr == "FLAGS":
2306 Value = BuildOptions[Tool][Attr]
2307 ValueList = Value.split()
2308 if ValueList:
2309 for Id, Item in enumerate(ValueList):
2310 if Item in ['-D', '/D', '-U', '/U']:
2311 CC_FLAGS += ' ' + Item
2312 if Id + 1 < len(ValueList):
2313 CC_FLAGS += ' ' + ValueList[Id + 1]
2314 elif Item.startswith(('-D', '/D', '-U', '/U')):
2315 CC_FLAGS += ' ' + Item
2316 MakeApp += CC_FLAGS
2317
2318 if sys.platform == "win32":
2319 MakeApp = MakeApp + PcdMakefileEnd
2320 MakeApp = MakeApp + '\n'
2321 IncludeFileFullPaths = []
2322 for includefile in IncludeFiles:
2323 for includepath in IncSearchList:
2324 includefullpath = os.path.join(str(includepath), includefile)
2325 if os.path.exists(includefullpath):
2326 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2327 break
2328 SearchPathList = []
2329 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2330 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2331 SearchPathList.extend(str(item) for item in IncSearchList)
2332 IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
2333 for include_file in IncFileList:
2334 MakeApp += "$(OBJECTS) : %s\n" % include_file
2335 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2336 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2337 SaveFileOnChange(MakeFileName, MakeApp, False)
2338
2339 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2340 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2341 SaveFileOnChange(InputValueFile, InitByteValue, False)
2342
2343 PcdValueInitExe = PcdValueInitName
2344 if not sys.platform == "win32":
2345 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
2346 else:
2347 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
2348
2349 Messages = ''
2350 if sys.platform == "win32":
2351 MakeCommand = 'nmake -f %s' % (MakeFileName)
2352 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2353 Messages = StdOut
2354 else:
2355 MakeCommand = 'make -f %s' % (MakeFileName)
2356 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
2357 Messages = StdErr
2358 Messages = Messages.split('\n')
2359 MessageGroup = []
2360 if returncode != 0:
2361 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2362 File = open (CAppBaseFileName + '.c', 'r')
2363 FileData = File.readlines()
2364 File.close()
2365 for Message in Messages:
2366 if " error" in Message or "warning" in Message:
2367 FileInfo = Message.strip().split('(')
2368 if len (FileInfo) > 1:
2369 FileName = FileInfo [0]
2370 FileLine = FileInfo [1].split (')')[0]
2371 else:
2372 FileInfo = Message.strip().split(':')
2373 FileName = FileInfo [0]
2374 FileLine = FileInfo [1]
2375 if FileLine.isdigit():
2376 error_line = FileData[int (FileLine) - 1]
2377 if r"//" in error_line:
2378 c_line, dsc_line = error_line.split(r"//")
2379 else:
2380 dsc_line = error_line
2381 message_itmes = Message.split(":")
2382 Index = 0
2383 if "PcdValueInit.c" not in Message:
2384 if not MessageGroup:
2385 MessageGroup.append(Message)
2386 break
2387 else:
2388 for item in message_itmes:
2389 if "PcdValueInit.c" in item:
2390 Index = message_itmes.index(item)
2391 message_itmes[Index] = dsc_line.strip()
2392 break
2393 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2394 continue
2395 else:
2396 MessageGroup.append(Message)
2397 if MessageGroup:
2398 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2399 else:
2400 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2401
2402 if DscBuildData.NeedUpdateOutput(OutputValueFile, PcdValueInitExe, InputValueFile):
2403 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2404 returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
2405 if returncode != 0:
2406 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2407
2408 File = open (OutputValueFile, 'r')
2409 FileBuffer = File.readlines()
2410 File.close()
2411
2412 StructurePcdSet = []
2413 for Pcd in FileBuffer:
2414 PcdValue = Pcd.split ('|')
2415 PcdInfo = PcdValue[0].split ('.')
2416 StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2417 return StructurePcdSet
2418
2419 @staticmethod
2420 def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
2421 if not os.path.exists(OutputFile):
2422 return True
2423 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2424 return True
2425 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2426 return True
2427 return False
2428
2429 ## Retrieve dynamic PCD settings
2430 #
2431 # @param Type PCD type
2432 #
2433 # @retval a dict object contains settings of given PCD type
2434 #
2435 def _GetDynamicPcd(self, Type):
2436
2437
2438 Pcds = OrderedDict()
2439 #
2440 # tdict is a special dict kind of type, used for selecting correct
2441 # PCD settings for certain ARCH and SKU
2442 #
2443 PcdDict = tdict(True, 4)
2444 PcdList = []
2445 # Find out all possible PCD candidates for self._Arch
2446 RecordList = self._RawData[Type, self._Arch]
2447 AvailableSkuIdSet = copy.copy(self.SkuIds)
2448
2449
2450 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2451 SkuName = SkuName.upper()
2452 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2453 if SkuName not in AvailableSkuIdSet:
2454 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2455 File=self.MetaFile, Line=Dummy5)
2456 if "." not in TokenSpaceGuid:
2457 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2458 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2459
2460 # Remove redundant PCD candidates, per the ARCH and SKU
2461 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2462
2463 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2464 if Setting is None:
2465 continue
2466
2467 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2468 if MaxDatumSize:
2469 if int(MaxDatumSize, 0) > 0xFFFF:
2470 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2471 File=self.MetaFile, Line=Dummy4)
2472 if int(MaxDatumSize, 0) < 0:
2473 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2474 File=self.MetaFile, Line=Dummy4)
2475 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2476 if (PcdCName, TokenSpaceGuid) in Pcds:
2477 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2478 pcdObject.SkuInfoList[SkuName] = SkuInfo
2479 if MaxDatumSize.strip():
2480 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2481 else:
2482 CurrentMaxSize = 0
2483 if pcdObject.MaxDatumSize:
2484 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2485 else:
2486 PcdMaxSize = 0
2487 if CurrentMaxSize > PcdMaxSize:
2488 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2489 else:
2490 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2491 PcdCName,
2492 TokenSpaceGuid,
2493 self._PCD_TYPE_STRING_[Type],
2494 DatumType,
2495 PcdValue,
2496 '',
2497 MaxDatumSize,
2498 OrderedDict({SkuName : SkuInfo}),
2499 False,
2500 None,
2501 IsDsc=True)
2502
2503 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2504 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2505 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
2506
2507 for pcd in Pcds.values():
2508 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2509 # Only fix the value while no value provided in DSC file.
2510 for sku in pcd.SkuInfoList.values():
2511 if not sku.DefaultValue:
2512 sku.DefaultValue = pcdDecObject.DefaultValue
2513 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2514 valuefromDec = pcdDecObject.DefaultValue
2515 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
2516 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2517 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2518 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2519 del pcd.SkuInfoList[TAB_COMMON]
2520 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2521 del pcd.SkuInfoList[TAB_COMMON]
2522
2523 map(self.FilterSkuSettings, Pcds.values())
2524
2525 return Pcds
2526
2527 def FilterSkuSettings(self, PcdObj):
2528
2529 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2530 if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
2531 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
2532 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2533 PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
2534 PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
2535
2536 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2537 PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
2538
2539 return PcdObj
2540
2541 @staticmethod
2542 def CompareVarAttr(Attr1, Attr2):
2543 if not Attr1 or not Attr2: # for empty string
2544 return True
2545 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2546 Attr1Set = set(Attr1s)
2547 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2548 Attr2Set = set(Attr2s)
2549 if Attr2Set == Attr1Set:
2550 return True
2551 else:
2552 return False
2553
2554 def CompletePcdValues(self, PcdSet):
2555 Pcds = OrderedDict()
2556 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2557 SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
2558 DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
2559 for PcdCName, TokenSpaceGuid in PcdSet:
2560 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2561
2562 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2563 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2564 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2565 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2566 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2567 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2568 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2569 continue
2570 PcdType = PcdObj.Type
2571 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2572 for skuid in PcdObj.SkuInfoList:
2573 skuobj = PcdObj.SkuInfoList[skuid]
2574 mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
2575 for defaultstorename in DefaultStores:
2576 if defaultstorename not in skuobj.DefaultStoreDict:
2577 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2578 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2579 for skuname, skuid in SkuIds.items():
2580 if skuname not in PcdObj.SkuInfoList:
2581 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2582 while nextskuid not in PcdObj.SkuInfoList:
2583 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2584 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2585 PcdObj.SkuInfoList[skuname].SkuId = skuid
2586 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2587 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2588 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
2589 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2590 return Pcds
2591 ## Retrieve dynamic HII PCD settings
2592 #
2593 # @param Type PCD type
2594 #
2595 # @retval a dict object contains settings of given PCD type
2596 #
2597 def _GetDynamicHiiPcd(self, Type):
2598
2599 VariableAttrs = {}
2600
2601 Pcds = OrderedDict()
2602 UserDefinedDefaultStores = []
2603 #
2604 # tdict is a special dict kind of type, used for selecting correct
2605 # PCD settings for certain ARCH and SKU
2606 #
2607 PcdDict = tdict(True, 5)
2608 PcdSet = set()
2609 RecordList = self._RawData[Type, self._Arch]
2610 # Find out all possible PCD candidates for self._Arch
2611 AvailableSkuIdSet = copy.copy(self.SkuIds)
2612 DefaultStoresDefine = self._GetDefaultStores()
2613
2614 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
2615 SkuName = SkuName.upper()
2616 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2617 DefaultStore = DefaultStore.upper()
2618 if DefaultStore == TAB_COMMON:
2619 DefaultStore = TAB_DEFAULT_STORES_DEFAULT
2620 else:
2621 #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
2622 UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
2623 if SkuName not in AvailableSkuIdSet:
2624 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2625 File=self.MetaFile, Line=Dummy5)
2626 if DefaultStore not in DefaultStoresDefine:
2627 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2628 File=self.MetaFile, Line=Dummy5)
2629 if "." not in TokenSpaceGuid:
2630 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
2631 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
2632
2633
2634 # Remove redundant PCD candidates, per the ARCH and SKU
2635 for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdSet:
2636
2637 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
2638 if Setting is None:
2639 continue
2640 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2641
2642 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2643 if not rt:
2644 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2645 ExtraData="[%s]" % VarAttribute)
2646 ExceedMax = False
2647 FormatCorrect = True
2648 if VariableOffset.isdigit():
2649 if int(VariableOffset, 10) > 0xFFFF:
2650 ExceedMax = True
2651 elif variablePattern.match(VariableOffset):
2652 if int(VariableOffset, 16) > 0xFFFF:
2653 ExceedMax = True
2654 # For Offset written in "A.B"
2655 elif VariableOffset.find('.') > -1:
2656 VariableOffsetList = VariableOffset.split(".")
2657 if not (len(VariableOffsetList) == 2
2658 and IsValidWord(VariableOffsetList[0])
2659 and IsValidWord(VariableOffsetList[1])):
2660 FormatCorrect = False
2661 else:
2662 FormatCorrect = False
2663 if not FormatCorrect:
2664 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2665
2666 if ExceedMax:
2667 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2668 if (VariableName, VariableGuid) not in VariableAttrs:
2669 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2670 else:
2671 if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2672 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)]))
2673
2674 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2675 if (PcdCName, TokenSpaceGuid) in Pcds:
2676 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2677 if SkuName in pcdObject.SkuInfoList:
2678 Skuitem = pcdObject.SkuInfoList[SkuName]
2679 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2680 else:
2681 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2682 pcdObject.SkuInfoList[SkuName] = SkuInfo
2683 else:
2684 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
2685 PcdClassObj = PcdClassObject(
2686 PcdCName,
2687 TokenSpaceGuid,
2688 self._PCD_TYPE_STRING_[Type],
2689 '',
2690 DefaultValue,
2691 '',
2692 '',
2693 OrderedDict({SkuName : SkuInfo}),
2694 False,
2695 None,
2696 pcdDecObject.validateranges,
2697 pcdDecObject.validlists,
2698 pcdDecObject.expressions,
2699 IsDsc=True)
2700 if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
2701 PcdClassObj.UserDefinedDefaultStoresFlag = True
2702 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
2703
2704 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
2705 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2706 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2707 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
2708 for pcd in Pcds.values():
2709 SkuInfoObj = pcd.SkuInfoList.values()[0]
2710 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2711 pcd.DatumType = pcdDecObject.DatumType
2712 # Only fix the value while no value provided in DSC file.
2713 for sku in pcd.SkuInfoList.values():
2714 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
2715 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2716 for default_store in sku.DefaultStoreDict:
2717 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2718 pcd.DefaultValue = pcdDecObject.DefaultValue
2719 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2720 valuefromDec = pcdDecObject.DefaultValue
2721 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
2722 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2723 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2724 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2725 del pcd.SkuInfoList[TAB_COMMON]
2726 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2727 del pcd.SkuInfoList[TAB_COMMON]
2728
2729 if pcd.MaxDatumSize.strip():
2730 MaxSize = int(pcd.MaxDatumSize, 0)
2731 else:
2732 MaxSize = 0
2733 if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
2734 for (_, skuobj) in pcd.SkuInfoList.items():
2735 datalen = 0
2736 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2737 datalen = len(skuobj.HiiDefaultValue.split(","))
2738 if datalen > MaxSize:
2739 MaxSize = datalen
2740 for defaultst in skuobj.DefaultStoreDict:
2741 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2742 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2743 pcd.MaxDatumSize = str(MaxSize)
2744 rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
2745 if not rt:
2746 invalidpcd = ",".join(invalidhii)
2747 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)
2748
2749 map(self.FilterSkuSettings, Pcds.values())
2750
2751 return Pcds
2752
2753 @staticmethod
2754 def CheckVariableNameAssignment(Pcds):
2755 invalidhii = []
2756 for pcdname in Pcds:
2757 pcd = Pcds[pcdname]
2758 varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
2759 if len(varnameset) > 1:
2760 invalidhii.append(".".join((pcdname[1], pcdname[0])))
2761 if len(invalidhii):
2762 return False, invalidhii
2763 else:
2764 return True, []
2765 ## Retrieve dynamic VPD PCD settings
2766 #
2767 # @param Type PCD type
2768 #
2769 # @retval a dict object contains settings of given PCD type
2770 #
2771 def _GetDynamicVpdPcd(self, Type):
2772
2773
2774 Pcds = OrderedDict()
2775 #
2776 # tdict is a special dict kind of type, used for selecting correct
2777 # PCD settings for certain ARCH and SKU
2778 #
2779 PcdDict = tdict(True, 4)
2780 PcdList = []
2781
2782 # Find out all possible PCD candidates for self._Arch
2783 RecordList = self._RawData[Type, self._Arch]
2784 AvailableSkuIdSet = copy.copy(self.SkuIds)
2785
2786 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
2787 SkuName = SkuName.upper()
2788 SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
2789 if SkuName not in AvailableSkuIdSet:
2790 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2791 File=self.MetaFile, Line=Dummy5)
2792 if "." not in TokenSpaceGuid:
2793 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2794 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2795
2796 # Remove redundant PCD candidates, per the ARCH and SKU
2797 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2798 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2799 if Setting is None:
2800 continue
2801 #
2802 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2803 # For the Integer & Boolean type, the optional data can only be InitialValue.
2804 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2805 # until the DEC parser has been called.
2806 #
2807 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2808 if MaxDatumSize:
2809 if int(MaxDatumSize, 0) > 0xFFFF:
2810 EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2811 File=self.MetaFile, Line=Dummy4)
2812 if int(MaxDatumSize, 0) < 0:
2813 EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
2814 File=self.MetaFile, Line=Dummy4)
2815 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2816 if (PcdCName, TokenSpaceGuid) in Pcds:
2817 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2818 pcdObject.SkuInfoList[SkuName] = SkuInfo
2819 if MaxDatumSize.strip():
2820 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2821 else:
2822 CurrentMaxSize = 0
2823 if pcdObject.MaxDatumSize:
2824 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2825 else:
2826 PcdMaxSize = 0
2827 if CurrentMaxSize > PcdMaxSize:
2828 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2829 else:
2830 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2831 PcdCName,
2832 TokenSpaceGuid,
2833 self._PCD_TYPE_STRING_[Type],
2834 '',
2835 InitialValue,
2836 '',
2837 MaxDatumSize,
2838 OrderedDict({SkuName : SkuInfo}),
2839 False,
2840 None,
2841 IsDsc=True)
2842
2843 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
2844 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
2845 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
2846 for pcd in Pcds.values():
2847 SkuInfoObj = pcd.SkuInfoList.values()[0]
2848 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2849 pcd.DatumType = pcdDecObject.DatumType
2850 # Only fix the value while no value provided in DSC file.
2851 for sku in pcd.SkuInfoList.values():
2852 if not sku.DefaultValue:
2853 sku.DefaultValue = pcdDecObject.DefaultValue
2854 if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
2855 valuefromDec = pcdDecObject.DefaultValue
2856 SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2857 pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
2858 elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2859 pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
2860 del pcd.SkuInfoList[TAB_COMMON]
2861 elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
2862 del pcd.SkuInfoList[TAB_COMMON]
2863
2864 #For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
2865 #the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
2866 for pcd in Pcds.values():
2867 PcdValueTypeSet = set()
2868 for sku in pcd.SkuInfoList.values():
2869 PcdValueTypeSet.add("UnicodeString" if sku.DefaultValue.startswith(('L"',"L'")) else "OtherVOID*")
2870 if len(PcdValueTypeSet) > 1:
2871 for sku in pcd.SkuInfoList.values():
2872 sku.DefaultValue = StringToArray(sku.DefaultValue) if sku.DefaultValue.startswith(('L"',"L'")) else sku.DefaultValue
2873
2874 map(self.FilterSkuSettings, Pcds.values())
2875 return Pcds
2876
2877 ## Add external modules
2878 #
2879 # The external modules are mostly those listed in FDF file, which don't
2880 # need "build".
2881 #
2882 # @param FilePath The path of module description file
2883 #
2884 def AddModule(self, FilePath):
2885 FilePath = NormPath(FilePath)
2886 if FilePath not in self.Modules:
2887 Module = ModuleBuildClassObject()
2888 Module.MetaFile = FilePath
2889 self.Modules.append(Module)
2890
2891 @property
2892 def ToolChainFamily(self):
2893 self._ToolChainFamily = TAB_COMPILER_MSFT
2894 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2895 if os.path.isfile(BuildConfigurationFile) == True:
2896 TargetTxt = TargetTxtClassObject()
2897 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2898 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2899 if ToolDefinitionFile == '':
2900 ToolDefinitionFile = "tools_def.txt"
2901 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2902 if os.path.isfile(ToolDefinitionFile) == True:
2903 ToolDef = ToolDefClassObject()
2904 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2905 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2906 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2907 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2908 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2909 self._ToolChainFamily = TAB_COMPILER_MSFT
2910 else:
2911 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2912 return self._ToolChainFamily
2913
2914 ## Add external PCDs
2915 #
2916 # The external PCDs are mostly those listed in FDF file to specify address
2917 # or offset information.
2918 #
2919 # @param Name Name of the PCD
2920 # @param Guid Token space guid of the PCD
2921 # @param Value Value of the PCD
2922 #
2923 def AddPcd(self, Name, Guid, Value):
2924 if (Name, Guid) not in self.Pcds:
2925 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2926 self.Pcds[Name, Guid].DefaultValue = Value
2927
2928 @property
2929 def DecPcds(self):
2930 if self._DecPcds is None:
2931 FdfInfList = []
2932 if GlobalData.gFdfParser:
2933 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2934 PkgSet = set()
2935 for Inf in FdfInfList:
2936 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2937 if ModuleFile in self._Modules:
2938 continue
2939 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2940 PkgSet.update(ModuleData.Packages)
2941 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
2942 self._GuidDict.update(GlobalData.gPlatformPcds)
2943 return self._DecPcds