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