]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Workspace/DscBuildData.py
BaseTools: Add Feature Flag Pcd Type into Override list
[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.DatumType == "VOID*":
1258 if Pcd.MaxDatumSize is None:
1259 Pcd.MaxDatumSize = '0'
1260 MaxSize = int(Pcd.MaxDatumSize,10)
1261 if Pcd.DefaultValue.startswith("{") and Pcd.DefaultValue.endswith("}"):
1262 MaxSize = max([len(Pcd.DefaultValue.split(",")),MaxSize])
1263 elif Pcd.DefaultValue.startswith("\"") or Pcd.DefaultValue.startswith("\'"):
1264 MaxSize = max([len(Pcd.DefaultValue)-2+1,MaxSize])
1265 elif Pcd.DefaultValue.startswith("L\""):
1266 MaxSize = max([2*(len(Pcd.DefaultValue)-3+1),MaxSize])
1267 else:
1268 MaxSize = max([len(Pcd.DefaultValue),MaxSize])
1269 Pcd.MaxDatumSize = str(MaxSize)
1270 else:
1271 PcdInDec = self.DecPcds.get((Name,Guid))
1272 if PcdInDec:
1273 PcdInDec.PcdValueFromComm = NoFiledValues[(Guid,Name)][0]
1274 if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1275 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
1276 self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
1277 self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
1278 self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]
1279 return AllPcds
1280 def UpdateStructuredPcds(self, TypeList, AllPcds):
1281
1282 DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
1283 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1284 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
1285 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
1286 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
1287 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
1288
1289 Pcds = AllPcds
1290 DefaultStoreMgr = DefaultStore(self.DefaultStores)
1291 SkuIds = self.SkuIdMgr.AvailableSkuIdSet
1292 SkuIds.update({'DEFAULT':0})
1293 DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
1294
1295 S_PcdSet = []
1296 # Find out all possible PCD candidates for self._Arch
1297 RecordList = []
1298
1299 for Type in TypeList:
1300 RecordList.extend(self._RawData[Type, self._Arch])
1301
1302 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:
1303 SkuName = SkuName.upper()
1304 default_store = default_store.upper()
1305 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1306 if SkuName not in SkuIds:
1307 continue
1308
1309 if SkuName in SkuIds and "." in TokenSpaceGuid:
1310 S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]])
1311
1312 # handle pcd value override
1313 StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)
1314 S_pcd_set = OrderedDict()
1315 for str_pcd in StrPcdSet:
1316 str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
1317 str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
1318 if not isinstance (str_pcd_dec, StructurePcd):
1319 EdkLogger.error('build', PARSER_ERROR,
1320 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1321 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
1322 if str_pcd_dec:
1323 str_pcd_obj_str = StructurePcd()
1324 str_pcd_obj_str.copy(str_pcd_dec)
1325 if str_pcd_obj:
1326 str_pcd_obj_str.copy(str_pcd_obj)
1327 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1328 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}
1329 else:
1330 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}
1331 for str_pcd_data in StrPcdSet[str_pcd]:
1332 if str_pcd_data[3] in SkuIds:
1333 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])
1334 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
1335 else:
1336 EdkLogger.error('build', PARSER_ERROR,
1337 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
1338 File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
1339 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1340 for Pcd in self.DecPcds:
1341 if type (self._DecPcds[Pcd]) is StructurePcd:
1342 if Pcd not in S_pcd_set:
1343 str_pcd_obj_str = StructurePcd()
1344 str_pcd_obj_str.copy(self._DecPcds[Pcd])
1345 str_pcd_obj = Pcds.get(Pcd, None)
1346 if str_pcd_obj:
1347 str_pcd_obj_str.copy(str_pcd_obj)
1348 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1349 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}
1350 else:
1351 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}
1352 S_pcd_set[Pcd] = str_pcd_obj_str
1353 if S_pcd_set:
1354 GlobalData.gStructurePcd[self.Arch] = S_pcd_set
1355 for stru_pcd in S_pcd_set.values():
1356 for skuid in SkuIds:
1357 if skuid in stru_pcd.SkuOverrideValues:
1358 continue
1359 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
1360 NoDefault = False
1361 if skuid not in stru_pcd.SkuOverrideValues:
1362 while nextskuid not in stru_pcd.SkuOverrideValues:
1363 if nextskuid == "DEFAULT":
1364 NoDefault = True
1365 break
1366 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1367 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})
1368 if not NoDefault:
1369 stru_pcd.ValueChain[(skuid,'')]= (nextskuid,'')
1370 if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1371 for skuid in SkuIds:
1372 nextskuid = skuid
1373 NoDefault = False
1374 if skuid not in stru_pcd.SkuOverrideValues:
1375 while nextskuid not in stru_pcd.SkuOverrideValues:
1376 if nextskuid == "DEFAULT":
1377 NoDefault = True
1378 break
1379 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1380 if NoDefault:
1381 continue
1382 PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])
1383 mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
1384
1385 for defaultstoreid in DefaultStores:
1386 if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
1387 stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
1388 stru_pcd.ValueChain[(skuid,defaultstoreid)]= (nextskuid,mindefaultstorename)
1389 S_pcd_set = self.OverrideByFdfComm(S_pcd_set)
1390 Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
1391 if Str_Pcd_Values:
1392 for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:
1393 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
1394 if str_pcd_obj is None:
1395 print PcdName, PcdGuid
1396 raise
1397 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1398 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1399 if skuname not in str_pcd_obj.SkuInfoList:
1400 str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
1401 else:
1402 str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
1403 str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
1404 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1405 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1406 if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1407 str_pcd_obj.DefaultValue = PcdValue
1408 else:
1409 if skuname not in str_pcd_obj.SkuInfoList:
1410 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
1411 NoDefault = False
1412 while nextskuid not in str_pcd_obj.SkuInfoList:
1413 if nextskuid == "DEFAULT":
1414 NoDefault = True
1415 break
1416 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
1417 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)
1418 str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
1419 str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
1420 else:
1421 str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
1422 for str_pcd_obj in S_pcd_set.values():
1423 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
1424 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
1425 continue
1426 PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])
1427 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
1428 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
1429 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
1430
1431 for str_pcd_obj in S_pcd_set.values():
1432
1433 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
1434 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
1435
1436 for pcdkey in Pcds:
1437 pcd = Pcds[pcdkey]
1438 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1439 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
1440 del(pcd.SkuInfoList['COMMON'])
1441 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
1442 del(pcd.SkuInfoList['COMMON'])
1443
1444 map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
1445 return Pcds
1446
1447 ## Retrieve non-dynamic PCD settings
1448 #
1449 # @param Type PCD type
1450 #
1451 # @retval a dict object contains settings of given PCD type
1452 #
1453 def _GetPcd(self, Type):
1454 Pcds = sdict()
1455 #
1456 # tdict is a special dict kind of type, used for selecting correct
1457 # PCD settings for certain ARCH
1458 #
1459 AvailableSkuIdSet = copy.copy(self.SkuIds)
1460
1461 PcdDict = tdict(True, 3)
1462 PcdSet = set()
1463 # Find out all possible PCD candidates for self._Arch
1464 RecordList = self._RawData[Type, self._Arch]
1465 PcdValueDict = sdict()
1466 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
1467 SkuName = SkuName.upper()
1468 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
1469 if SkuName not in AvailableSkuIdSet:
1470 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
1471 File=self.MetaFile, Line=Dummy5)
1472 if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
1473 if "." not in TokenSpaceGuid:
1474 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
1475 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
1476
1477 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
1478 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
1479 if Setting == None:
1480 continue
1481 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
1482 if (PcdCName, TokenSpaceGuid) in PcdValueDict:
1483 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
1484 else:
1485 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
1486
1487 PcdsKeys = PcdValueDict.keys()
1488 for PcdCName, TokenSpaceGuid in PcdsKeys:
1489
1490 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
1491 PcdValue = None
1492 DatumType = None
1493 MaxDatumSize = None
1494 if 'COMMON' in PcdSetting:
1495 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']
1496 if 'DEFAULT' in PcdSetting:
1497 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']
1498 if self.SkuIdMgr.SystemSkuId in PcdSetting:
1499 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
1500
1501 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
1502 PcdCName,
1503 TokenSpaceGuid,
1504 self._PCD_TYPE_STRING_[Type],
1505 DatumType,
1506 PcdValue,
1507 '',
1508 MaxDatumSize,
1509 {},
1510 False,
1511 None,
1512 IsDsc=True)
1513
1514
1515 return Pcds
1516
1517 def __UNICODE2OCTList(self,Value):
1518 Value = Value.strip()
1519 Value = Value[2:-1]
1520 List = []
1521 for Item in Value:
1522 Temp = '%04X' % ord(Item)
1523 List.append('0x' + Temp[2:4])
1524 List.append('0x' + Temp[0:2])
1525 List.append('0x00')
1526 List.append('0x00')
1527 return List
1528 def __STRING2OCTList(self,Value):
1529 OCTList = []
1530 Value = Value.strip('"')
1531 for char in Value:
1532 Temp = '%02X' % ord(char)
1533 OCTList.append('0x' + Temp)
1534 OCTList.append('0x00')
1535 return OCTList
1536
1537 def GetStructurePcdMaxSize(self, str_pcd):
1538 pcd_default_value = str_pcd.DefaultValue
1539 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()]
1540 sku_values.append(pcd_default_value)
1541
1542 def get_length(value):
1543 Value = value.strip()
1544 if len(value) > 1:
1545 if Value.startswith('GUID') and Value.endswith(')'):
1546 return 16
1547 if Value.startswith('L"') and Value.endswith('"'):
1548 return len(Value[2:-1])
1549 if Value[0] == '"' and Value[-1] == '"':
1550 return len(Value) - 2
1551 if Value[0] == '{' and Value[-1] == '}':
1552 return len(Value.split(","))
1553 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
1554 return len(list(Value[2:-1]))
1555 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
1556 return len(Value) - 2
1557 return len(Value)
1558
1559 return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
1560
1561 def ExecuteCommand (self, Command):
1562 try:
1563 Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
1564 except:
1565 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
1566 Result = Process.communicate()
1567 return Process.returncode, Result[0], Result[1]
1568
1569 def IntToCString(self, Value, ValueSize):
1570 Result = '"'
1571 if not isinstance (Value, str):
1572 for Index in range(0, ValueSize):
1573 Result = Result + '\\x%02x' % (Value & 0xff)
1574 Value = Value >> 8
1575 Result = Result + '"'
1576 return Result
1577
1578 def GetPcdMaxSize(self,Pcd):
1579 MaxSize = int(Pcd.MaxDatumSize,10) if Pcd.MaxDatumSize else 0
1580 if Pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:
1581 if Pcd.PcdValueFromComm:
1582 if Pcd.PcdValueFromComm.startswith("{") and Pcd.PcdValueFromComm.endswith("}"):
1583 MaxSize = max([len(Pcd.PcdValueFromComm.split(",")),MaxSize])
1584 elif Pcd.PcdValueFromComm.startswith("\"") or Pcd.PcdValueFromComm.startswith("\'"):
1585 MaxSize = max([len(Pcd.PcdValueFromComm)-2+1,MaxSize])
1586 elif Pcd.PcdValueFromComm.startswith("L\""):
1587 MaxSize = max([2*(len(Pcd.PcdValueFromComm)-3+1),MaxSize])
1588 else:
1589 MaxSize = max([len(Pcd.PcdValueFromComm),MaxSize])
1590 elif Pcd.DatumType not in ['BOOLEAN','UINT8']:
1591 MaxSize = 1
1592 elif Pcd.DatumType == 'UINT16':
1593 MaxSize = 2
1594 elif Pcd.DatumType == 'UINT32':
1595 MaxSize = 4
1596 elif Pcd.DatumType == 'UINT64':
1597 MaxSize = 8
1598 return MaxSize
1599 def GenerateSizeFunction(self,Pcd):
1600 CApp = "// Default Value in Dec \n"
1601 CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1602 for FieldList in [Pcd.DefaultValues]:
1603 if not FieldList:
1604 continue
1605 for FieldName in FieldList:
1606 FieldName = "." + FieldName
1607 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1608 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1609 try:
1610 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
1611 except BadExpression:
1612 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1613 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1614 Value, ValueSize = ParseFieldValue(Value)
1615 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]);
1616 else:
1617 NewFieldName = ''
1618 FieldName_ori = FieldName.strip('.')
1619 while '[' in FieldName:
1620 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1621 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1622 FieldName = FieldName.split(']', 1)[1]
1623 FieldName = NewFieldName + FieldName
1624 while '[' in FieldName:
1625 FieldName = FieldName.rsplit('[', 1)[0]
1626 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])
1627 for skuname in Pcd.SkuOverrideValues:
1628 if skuname == "COMMON":
1629 continue
1630 for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
1631 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1632 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
1633 if not FieldList:
1634 continue
1635 for FieldName in FieldList:
1636 FieldName = "." + FieldName
1637 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
1638 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
1639 try:
1640 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
1641 except BadExpression:
1642 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1643 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
1644 Value, ValueSize = ParseFieldValue(Value)
1645 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]);
1646 else:
1647 NewFieldName = ''
1648 FieldName_ori = FieldName.strip('.')
1649 while '[' in FieldName:
1650 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1651 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1652 FieldName = FieldName.split(']', 1)[1]
1653 FieldName = NewFieldName + FieldName
1654 while '[' in FieldName:
1655 FieldName = FieldName.rsplit('[', 1)[0]
1656 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])
1657 if Pcd.PcdFieldValueFromComm:
1658 CApp = CApp + "// From Command Line \n"
1659 for FieldName in Pcd.PcdFieldValueFromComm:
1660 FieldName = "." + FieldName
1661 IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
1662 if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
1663 try:
1664 Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
1665 except BadExpression:
1666 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1667 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
1668 Value, ValueSize = ParseFieldValue(Value)
1669 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]);
1670 else:
1671 NewFieldName = ''
1672 FieldName_ori = FieldName.strip('.')
1673 while '[' in FieldName:
1674 NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
1675 ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
1676 FieldName = FieldName.split(']', 1)[1]
1677 FieldName = NewFieldName + FieldName
1678 while '[' in FieldName:
1679 FieldName = FieldName.rsplit('[', 1)[0]
1680 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])
1681 CApp = CApp + " *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd))
1682 CApp = CApp + "}\n"
1683 return CApp
1684 def GenerateSizeStatments(self,Pcd):
1685 CApp = ' Size = sizeof(%s);\n' % (Pcd.DatumType)
1686 CApp = CApp + ' Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1687 return CApp
1688 def GenerateDefaultValueAssignFunction(self,Pcd):
1689 CApp = "// Default value in Dec \n"
1690 CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
1691 CApp = CApp + ' UINT32 FieldSize;\n'
1692 CApp = CApp + ' CHAR8 *Value;\n'
1693 DefaultValueFromDec = Pcd.DefaultValueFromDec
1694 IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
1695 if IsArray:
1696 try:
1697 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)
1698 except BadExpression:
1699 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
1700 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
1701 DefaultValueFromDec = StringToArray(DefaultValueFromDec)
1702 Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
1703 if isinstance(Value, str):
1704 CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
1705 elif IsArray:
1706 #
1707 # Use memcpy() to copy value into field
1708 #
1709 CApp = CApp + ' Value = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
1710 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1711 for FieldList in [Pcd.DefaultValues]:
1712 if not FieldList:
1713 continue
1714 for FieldName in FieldList:
1715 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1716 if IsArray:
1717 try:
1718 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
1719 except BadExpression:
1720 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1721 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))
1722
1723 try:
1724 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1725 except Exception:
1726 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]))
1727 if isinstance(Value, str):
1728 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1729 elif IsArray:
1730 #
1731 # Use memcpy() to copy value into field
1732 #
1733 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1734 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1735 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1736 else:
1737 if ValueSize > 4:
1738 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1739 else:
1740 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1741 CApp = CApp + "}\n"
1742 return CApp
1743 def GenerateDefaultValueAssignStatement(self,Pcd):
1744 CApp = ' Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1745 return CApp
1746 def GenerateInitValueFunction(self,Pcd,SkuName,DefaultStoreName):
1747 CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,DefaultStoreName)
1748 CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName,Pcd.DatumType)
1749 CApp = CApp + ' UINT32 FieldSize;\n'
1750 CApp = CApp + ' CHAR8 *Value;\n'
1751
1752 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % ('DEFAULT', 'STANDARD')
1753 inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
1754 if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):
1755 pcddefaultvalue = Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue
1756 else:
1757 if not Pcd.DscRawValue:
1758 # handle the case that structure pcd is not appear in DSC
1759 self.CopyDscRawValue(Pcd)
1760 pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)
1761 for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]:
1762 if not FieldList:
1763 continue
1764 if pcddefaultvalue and FieldList == pcddefaultvalue:
1765 IsArray = IsFieldValueAnArray(FieldList)
1766 if IsArray:
1767 try:
1768 FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
1769 except BadExpression:
1770 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
1771 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1772 Value, ValueSize = ParseFieldValue (FieldList)
1773
1774 if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):
1775 if isinstance(Value, str):
1776 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)
1777 elif IsArray:
1778 #
1779 # Use memcpy() to copy value into field
1780 #
1781 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)
1782 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1783 else:
1784 if isinstance(Value, str):
1785 CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))
1786 elif IsArray:
1787 #
1788 # Use memcpy() to copy value into field
1789 #
1790 CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))
1791 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1792 continue
1793 if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )):
1794 for FieldName in FieldList:
1795 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1796 if IsArray:
1797 try:
1798 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
1799 except BadExpression:
1800 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1801 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1802 try:
1803 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1804 except Exception:
1805 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]))
1806 if isinstance(Value, str):
1807 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1808 elif IsArray:
1809 #
1810 # Use memcpy() to copy value into field
1811 #
1812 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1813 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1814 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1815 else:
1816 if ValueSize > 4:
1817 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1818 else:
1819 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1820 CApp = CApp + "}\n"
1821 return CApp
1822 def GenerateInitValueStatement(self,Pcd,SkuName,DefaultStoreName):
1823 CApp = ' Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName)
1824 return CApp
1825 def GenerateCommandLineValue(self,Pcd):
1826 CApp = "// Value in CommandLine\n"
1827 CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
1828 CApp = CApp + ' UINT32 FieldSize;\n'
1829 CApp = CApp + ' CHAR8 *Value;\n'
1830
1831 pcddefaultvalue = Pcd.PcdValueFromComm
1832 for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]:
1833 if not FieldList:
1834 continue
1835 if pcddefaultvalue and FieldList == pcddefaultvalue:
1836 IsArray = IsFieldValueAnArray(FieldList)
1837 if IsArray:
1838 try:
1839 FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
1840 except BadExpression:
1841 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
1842 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
1843 Value, ValueSize = ParseFieldValue (FieldList)
1844
1845 if isinstance(Value, str):
1846 CApp = CApp + ' Pcd = %s; // From Command Line \n' % (Value)
1847 elif IsArray:
1848 #
1849 # Use memcpy() to copy value into field
1850 #
1851 CApp = CApp + ' Value = %s; // From Command Line.\n' % (self.IntToCString(Value, ValueSize))
1852 CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
1853 continue
1854 for FieldName in FieldList:
1855 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
1856 if IsArray:
1857 try:
1858 FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
1859 except BadExpression:
1860 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
1861 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
1862 except:
1863 print "error"
1864 try:
1865 Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
1866 except Exception:
1867 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]))
1868 if isinstance(Value, str):
1869 CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1870 elif IsArray:
1871 #
1872 # Use memcpy() to copy value into field
1873 #
1874 CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
1875 CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1876 CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
1877 else:
1878 if ValueSize > 4:
1879 CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1880 else:
1881 CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
1882 CApp = CApp + "}\n"
1883 return CApp
1884 def GenerateCommandLineValueStatement(self,Pcd):
1885 CApp = ' Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1886 return CApp
1887 def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
1888 OverrideValues = {DefaultStore:""}
1889 if Pcd.SkuOverrideValues:
1890 OverrideValues = Pcd.SkuOverrideValues[SkuName]
1891 for DefaultStoreName in OverrideValues.keys():
1892 CApp = CApp + 'void\n'
1893 CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1894 CApp = CApp + ' void\n'
1895 CApp = CApp + ' )\n'
1896 CApp = CApp + '{\n'
1897 CApp = CApp + ' UINT32 Size;\n'
1898 CApp = CApp + ' UINT32 FieldSize;\n'
1899 CApp = CApp + ' CHAR8 *Value;\n'
1900 CApp = CApp + ' UINT32 OriginalSize;\n'
1901 CApp = CApp + ' VOID *OriginalPcd;\n'
1902 CApp = CApp + ' %s *Pcd; // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
1903 CApp = CApp + '\n'
1904
1905 if SkuName in Pcd.SkuInfoList:
1906 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue else Pcd.SkuInfoList[SkuName].DefaultValue)
1907 else:
1908 DefaultValue = Pcd.DefaultValue
1909 PcdDefaultValue = StringToArray(DefaultValue.strip())
1910
1911 InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
1912
1913 #
1914 # Get current PCD value and size
1915 #
1916 CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1917
1918 #
1919 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1920 # the correct value. For structures with a flexible array member, the flexible
1921 # array member is detected, and the size is based on the highest index used with
1922 # the flexible array member. The flexible array member must be the last field
1923 # in a structure. The size formula for this case is:
1924 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1925 #
1926 CApp = CApp + self.GenerateSizeStatments(Pcd)
1927
1928 #
1929 # Allocate and zero buffer for the PCD
1930 # Must handle cases where current value is smaller, larger, or same size
1931 # Always keep that larger one as the current size
1932 #
1933 CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1934 CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
1935 CApp = CApp + ' memset (Pcd, 0, Size);\n'
1936
1937 #
1938 # Copy current PCD value into allocated buffer.
1939 #
1940 CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1941
1942 #
1943 # Assign field values in PCD
1944 #
1945 CApp = CApp + self.GenerateDefaultValueAssignStatement(Pcd)
1946 if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1947 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1948 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
1949 storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
1950 for defaultstorenameitem in storeset:
1951 CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
1952 CApp = CApp + self.GenerateInitValueStatement(Pcd,skuname,defaultstorenameitem)
1953 if skuname == SkuName:
1954 break
1955 else:
1956 CApp = CApp + "// SkuName: %s, DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
1957 CApp = CApp + self.GenerateInitValueStatement(Pcd,self.SkuIdMgr.SystemSkuId,"STANDARD")
1958 CApp = CApp + self.GenerateCommandLineValueStatement(Pcd)
1959 #
1960 # Set new PCD value and size
1961 #
1962 CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
1963
1964 #
1965 # Free PCD
1966 #
1967 CApp = CApp + ' free (Pcd);\n'
1968 CApp = CApp + '}\n'
1969 CApp = CApp + '\n'
1970 return InitByteValue, CApp
1971
1972 def GenerateByteArrayValue (self, StructuredPcds):
1973 #
1974 # Generate/Compile/Run C application to determine if there are any flexible array members
1975 #
1976 if not StructuredPcds:
1977 return
1978
1979 InitByteValue = ""
1980 CApp = PcdMainCHeader
1981
1982 Includes = {}
1983 IncludeFiles = set()
1984 for PcdName in StructuredPcds:
1985 Pcd = StructuredPcds[PcdName]
1986 for IncludeFile in Pcd.StructuredPcdIncludeFile:
1987 if IncludeFile not in Includes:
1988 Includes[IncludeFile] = True
1989 IncludeFiles.add(IncludeFile)
1990 CApp = CApp + '#include <%s>\n' % (IncludeFile)
1991 CApp = CApp + '\n'
1992 for PcdName in StructuredPcds:
1993 Pcd = StructuredPcds[PcdName]
1994 CApp = CApp + self.GenerateSizeFunction(Pcd)
1995 CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
1996 CApp = CApp + self.GenerateCommandLineValue(Pcd)
1997 if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
1998 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
1999 CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, 'STANDARD')
2000 else:
2001 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2002 if SkuName not in Pcd.SkuOverrideValues:
2003 continue
2004 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2005 CApp = CApp + self.GenerateInitValueFunction(Pcd,SkuName,DefaultStoreName)
2006 if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
2007 self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2008 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)
2009 else:
2010 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2011 if SkuName not in Pcd.SkuOverrideValues:
2012 continue
2013 for DefaultStoreName in Pcd.DefaultStoreName:
2014 Pcd = StructuredPcds[PcdName]
2015 InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
2016
2017 CApp = CApp + 'VOID\n'
2018 CApp = CApp + 'PcdEntryPoint(\n'
2019 CApp = CApp + ' VOID\n'
2020 CApp = CApp + ' )\n'
2021 CApp = CApp + '{\n'
2022 for Pcd in StructuredPcds.values():
2023 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]]:
2024 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2025 else:
2026 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
2027 if SkuName not in Pcd.SkuOverrideValues:
2028 continue
2029 for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
2030 CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
2031 CApp = CApp + '}\n'
2032
2033 CApp = CApp + PcdMainCEntry + '\n'
2034
2035 if not os.path.exists(self.OutputPath):
2036 os.makedirs(self.OutputPath)
2037 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2038 SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
2039
2040 MakeApp = PcdMakefileHeader
2041 if sys.platform == "win32":
2042 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
2043 else:
2044 MakeApp = MakeApp + PcdGccMakefile
2045 MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
2046 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
2047
2048 IncSearchList = []
2049 PlatformInc = {}
2050 for Cache in self._Bdb._CACHE_.values():
2051 if Cache.MetaFile.Ext.lower() != '.dec':
2052 continue
2053 if Cache.Includes:
2054 if str(Cache.MetaFile.Path) not in PlatformInc:
2055 PlatformInc[str(Cache.MetaFile.Path)] = Cache.CommonIncludes
2056
2057 PcdDependDEC = []
2058 for Pcd in StructuredPcds.values():
2059 for PackageDec in Pcd.PackageDecs:
2060 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
2061 if not os.path.exists(Package):
2062 EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
2063 if Package not in PcdDependDEC:
2064 PcdDependDEC.append(Package)
2065
2066 if PlatformInc and PcdDependDEC:
2067 for pkg in PcdDependDEC:
2068 if pkg in PlatformInc:
2069 for inc in PlatformInc[pkg]:
2070 MakeApp += '-I' + str(inc) + ' '
2071 IncSearchList.append(inc)
2072 MakeApp = MakeApp + '\n'
2073
2074 CC_FLAGS = LinuxCFLAGS
2075 if sys.platform == "win32":
2076 CC_FLAGS = WindowsCFLAGS
2077 BuildOptions = {}
2078 for Options in self.BuildOptions:
2079 if Options[2] != EDKII_NAME:
2080 continue
2081 Family = Options[0]
2082 if Family and Family != self.ToolChainFamily:
2083 continue
2084 Target, Tag, Arch, Tool, Attr = Options[1].split("_")
2085 if Tool != 'CC':
2086 continue
2087
2088 if Target == "*" or Target == self._Target:
2089 if Tag == "*" or Tag == self._Toolchain:
2090 if Arch == "*" or Arch == self.Arch:
2091 if Tool not in BuildOptions:
2092 BuildOptions[Tool] = {}
2093 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
2094 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2095 else:
2096 # append options for the same tool except PATH
2097 if Attr != 'PATH':
2098 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
2099 else:
2100 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
2101 if BuildOptions:
2102 for Tool in BuildOptions:
2103 for Attr in BuildOptions[Tool]:
2104 if Attr == "FLAGS":
2105 Value = BuildOptions[Tool][Attr]
2106 ValueList = Value.split()
2107 if ValueList:
2108 for Id, Item in enumerate(ValueList):
2109 if Item == '-D' or Item == '/D':
2110 CC_FLAGS += ' ' + Item
2111 if Id + 1 < len(ValueList):
2112 CC_FLAGS += ' ' + ValueList[Id + 1]
2113 elif Item.startswith('/D') or Item.startswith('-D'):
2114 CC_FLAGS += ' ' + Item
2115 MakeApp += CC_FLAGS
2116
2117 if sys.platform == "win32":
2118 MakeApp = MakeApp + PcdMakefileEnd
2119 MakeApp = MakeApp + '\n'
2120 IncludeFileFullPaths = []
2121 for includefile in IncludeFiles:
2122 for includepath in IncSearchList:
2123 includefullpath = os.path.join(str(includepath),includefile)
2124 if os.path.exists(includefullpath):
2125 IncludeFileFullPaths.append(os.path.normpath(includefullpath))
2126 break
2127 SearchPathList = []
2128 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
2129 SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
2130 SearchPathList.extend([str(item) for item in IncSearchList])
2131 IncFileList = GetDependencyList(IncludeFileFullPaths,SearchPathList)
2132 for include_file in IncFileList:
2133 MakeApp += "$(OBJECTS) : %s\n" % include_file
2134 MakeFileName = os.path.join(self.OutputPath, 'Makefile')
2135 MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
2136 SaveFileOnChange(MakeFileName, MakeApp, False)
2137
2138 InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
2139 OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
2140 SaveFileOnChange(InputValueFile, InitByteValue, False)
2141
2142 PcdValueInitExe = PcdValueInitName
2143 if not sys.platform == "win32":
2144 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
2145 else:
2146 PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
2147
2148 Messages = ''
2149 if sys.platform == "win32":
2150 MakeCommand = 'nmake -f %s' % (MakeFileName)
2151 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
2152 Messages = StdOut
2153 else:
2154 MakeCommand = 'make -f %s' % (MakeFileName)
2155 returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
2156 Messages = StdErr
2157 Messages = Messages.split('\n')
2158 MessageGroup = []
2159 if returncode <>0:
2160 CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
2161 File = open (CAppBaseFileName + '.c', 'r')
2162 FileData = File.readlines()
2163 File.close()
2164 for Message in Messages:
2165 if " error" in Message or "warning" in Message:
2166 FileInfo = Message.strip().split('(')
2167 if len (FileInfo) > 1:
2168 FileName = FileInfo [0]
2169 FileLine = FileInfo [1].split (')')[0]
2170 else:
2171 FileInfo = Message.strip().split(':')
2172 FileName = FileInfo [0]
2173 FileLine = FileInfo [1]
2174 if FileLine.isdigit():
2175 error_line = FileData[int (FileLine) - 1]
2176 if r"//" in error_line:
2177 c_line,dsc_line = error_line.split(r"//")
2178 else:
2179 dsc_line = error_line
2180 message_itmes = Message.split(":")
2181 Index = 0
2182 if "PcdValueInit.c" not in Message:
2183 if not MessageGroup:
2184 MessageGroup.append(Message)
2185 break
2186 else:
2187 for item in message_itmes:
2188 if "PcdValueInit.c" in item:
2189 Index = message_itmes.index(item)
2190 message_itmes[Index] = dsc_line.strip()
2191 break
2192 MessageGroup.append(":".join(message_itmes[Index:]).strip())
2193 continue
2194 else:
2195 MessageGroup.append(Message)
2196 if MessageGroup:
2197 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
2198 else:
2199 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
2200
2201 if self.NeedUpdateOutput(OutputValueFile, PcdValueInitExe ,InputValueFile):
2202 Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
2203 returncode, StdOut, StdErr = self.ExecuteCommand (Command)
2204 if returncode <> 0:
2205 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
2206
2207 File = open (OutputValueFile, 'r')
2208 FileBuffer = File.readlines()
2209 File.close()
2210
2211 StructurePcdSet = []
2212 for Pcd in FileBuffer:
2213 PcdValue = Pcd.split ('|')
2214 PcdInfo = PcdValue[0].split ('.')
2215 StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
2216 return StructurePcdSet
2217
2218 def NeedUpdateOutput(self,OutputFile, ValueCFile, StructureInput):
2219 if not os.path.exists(OutputFile):
2220 return True
2221 if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
2222 return True
2223 if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
2224 return True
2225 return False
2226
2227 ## Retrieve dynamic PCD settings
2228 #
2229 # @param Type PCD type
2230 #
2231 # @retval a dict object contains settings of given PCD type
2232 #
2233 def _GetDynamicPcd(self, Type):
2234
2235
2236 Pcds = sdict()
2237 #
2238 # tdict is a special dict kind of type, used for selecting correct
2239 # PCD settings for certain ARCH and SKU
2240 #
2241 PcdDict = tdict(True, 4)
2242 PcdList = []
2243 # Find out all possible PCD candidates for self._Arch
2244 RecordList = self._RawData[Type, self._Arch]
2245 AvailableSkuIdSet = copy.copy(self.SkuIds)
2246
2247
2248 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
2249 SkuName = SkuName.upper()
2250 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2251 if SkuName not in AvailableSkuIdSet:
2252 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2253 File=self.MetaFile, Line=Dummy5)
2254 if "." not in TokenSpaceGuid:
2255 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2256 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2257
2258 # Remove redundant PCD candidates, per the ARCH and SKU
2259 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2260
2261 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2262 if Setting == None:
2263 continue
2264
2265 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2266 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
2267 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2268 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2269 pcdObject.SkuInfoList[SkuName] = SkuInfo
2270 if MaxDatumSize.strip():
2271 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2272 else:
2273 CurrentMaxSize = 0
2274 if pcdObject.MaxDatumSize:
2275 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2276 else:
2277 PcdMaxSize = 0
2278 if CurrentMaxSize > PcdMaxSize:
2279 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2280 else:
2281 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2282 PcdCName,
2283 TokenSpaceGuid,
2284 self._PCD_TYPE_STRING_[Type],
2285 DatumType,
2286 PcdValue,
2287 '',
2288 MaxDatumSize,
2289 {SkuName : SkuInfo},
2290 False,
2291 None,
2292 IsDsc=True)
2293
2294 for pcd in Pcds.values():
2295 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2296 # Only fix the value while no value provided in DSC file.
2297 for sku in pcd.SkuInfoList.values():
2298 if (sku.DefaultValue == "" or sku.DefaultValue==None):
2299 sku.DefaultValue = pcdDecObject.DefaultValue
2300 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2301 valuefromDec = pcdDecObject.DefaultValue
2302 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
2303 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2304 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2305 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2306 del(pcd.SkuInfoList['COMMON'])
2307 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2308 del(pcd.SkuInfoList['COMMON'])
2309
2310 map(self.FilterSkuSettings,Pcds.values())
2311
2312 return Pcds
2313
2314 def FilterSkuSettings(self, PcdObj):
2315
2316 if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
2317 if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():
2318 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']
2319 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
2320 PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'
2321 PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'
2322
2323 elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
2324 PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}
2325
2326 return PcdObj
2327
2328
2329 def CompareVarAttr(self, Attr1, Attr2):
2330 if not Attr1 or not Attr2: # for empty string
2331 return True
2332 Attr1s = [attr.strip() for attr in Attr1.split(",")]
2333 Attr1Set = set(Attr1s)
2334 Attr2s = [attr.strip() for attr in Attr2.split(",")]
2335 Attr2Set = set(Attr2s)
2336 if Attr2Set == Attr1Set:
2337 return True
2338 else:
2339 return False
2340 def CopyDscRawValue(self,Pcd):
2341 if Pcd.DscRawValue is None:
2342 Pcd.DscRawValue = dict()
2343 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
2344 if self.SkuIdMgr.SystemSkuId not in Pcd.DscRawValue:
2345 Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId] = {}
2346 Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId]['STANDARD'] = Pcd.DefaultValue
2347 for skuname in Pcd.SkuInfoList:
2348 Pcd.DscRawValue[skuname] = {}
2349 if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2350 for defaultstore in Pcd.SkuInfoList[skuname].DefaultStoreDict:
2351 Pcd.DscRawValue[skuname][defaultstore] = Pcd.SkuInfoList[skuname].DefaultStoreDict[defaultstore]
2352 else:
2353 Pcd.DscRawValue[skuname]['STANDARD'] = Pcd.SkuInfoList[skuname].DefaultValue
2354 def CompletePcdValues(self,PcdSet):
2355 Pcds = {}
2356 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
2357 SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}
2358 DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
2359 for PcdCName, TokenSpaceGuid in PcdSet:
2360 PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
2361 self.CopyDscRawValue(PcdObj)
2362 if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
2363 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
2364 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
2365 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
2366 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
2367 self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
2368 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2369 continue
2370 PcdType = PcdObj.Type
2371 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2372 for skuid in PcdObj.SkuInfoList:
2373 skuobj = PcdObj.SkuInfoList[skuid]
2374 mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict]))
2375 for defaultstorename in DefaultStores:
2376 if defaultstorename not in skuobj.DefaultStoreDict:
2377 skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
2378 skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
2379 for skuname,skuid in SkuIds.items():
2380 if skuname not in PcdObj.SkuInfoList:
2381 nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
2382 while nextskuid not in PcdObj.SkuInfoList:
2383 nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
2384 PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
2385 PcdObj.SkuInfoList[skuname].SkuId = skuid
2386 PcdObj.SkuInfoList[skuname].SkuIdName = skuname
2387 if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
2388 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue
2389 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
2390 return Pcds
2391 ## Retrieve dynamic HII PCD settings
2392 #
2393 # @param Type PCD type
2394 #
2395 # @retval a dict object contains settings of given PCD type
2396 #
2397 def _GetDynamicHiiPcd(self, Type):
2398
2399 VariableAttrs = {}
2400
2401 Pcds = sdict()
2402 #
2403 # tdict is a special dict kind of type, used for selecting correct
2404 # PCD settings for certain ARCH and SKU
2405 #
2406 PcdDict = tdict(True, 5)
2407 PcdSet = set()
2408 RecordList = self._RawData[Type, self._Arch]
2409 # Find out all possible PCD candidates for self._Arch
2410 AvailableSkuIdSet = copy.copy(self.SkuIds)
2411 DefaultStoresDefine = self._GetDefaultStores()
2412
2413 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:
2414 SkuName = SkuName.upper()
2415 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2416 DefaultStore = DefaultStore.upper()
2417 if DefaultStore == "COMMON":
2418 DefaultStore = "STANDARD"
2419 if SkuName not in AvailableSkuIdSet:
2420 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2421 File=self.MetaFile, Line=Dummy5)
2422 if DefaultStore not in DefaultStoresDefine:
2423 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
2424 File=self.MetaFile, Line=Dummy5)
2425 if "." not in TokenSpaceGuid:
2426 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5))
2427 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting
2428
2429
2430 # Remove redundant PCD candidates, per the ARCH and SKU
2431 for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:
2432
2433 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]
2434 if Setting == None:
2435 continue
2436 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2437
2438 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
2439 if not rt:
2440 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
2441 ExtraData="[%s]" % VarAttribute)
2442 ExceedMax = False
2443 FormatCorrect = True
2444 if VariableOffset.isdigit():
2445 if int(VariableOffset, 10) > 0xFFFF:
2446 ExceedMax = True
2447 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):
2448 if int(VariableOffset, 16) > 0xFFFF:
2449 ExceedMax = True
2450 # For Offset written in "A.B"
2451 elif VariableOffset.find('.') > -1:
2452 VariableOffsetList = VariableOffset.split(".")
2453 if not (len(VariableOffsetList) == 2
2454 and IsValidWord(VariableOffsetList[0])
2455 and IsValidWord(VariableOffsetList[1])):
2456 FormatCorrect = False
2457 else:
2458 FormatCorrect = False
2459 if not FormatCorrect:
2460 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2461
2462 if ExceedMax:
2463 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
2464 if (VariableName, VariableGuid) not in VariableAttrs:
2465 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
2466 else:
2467 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
2468 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)]))
2469
2470 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
2471 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2472 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2473 if SkuName in pcdObject.SkuInfoList:
2474 Skuitem = pcdObject.SkuInfoList[SkuName]
2475 Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
2476 else:
2477 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
2478 pcdObject.SkuInfoList[SkuName] = SkuInfo
2479 else:
2480 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
2481 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2482 PcdCName,
2483 TokenSpaceGuid,
2484 self._PCD_TYPE_STRING_[Type],
2485 '',
2486 DefaultValue,
2487 '',
2488 '',
2489 {SkuName : SkuInfo},
2490 False,
2491 None,
2492 pcdDecObject.validateranges,
2493 pcdDecObject.validlists,
2494 pcdDecObject.expressions,
2495 IsDsc=True)
2496
2497
2498 for pcd in Pcds.values():
2499 SkuInfoObj = pcd.SkuInfoList.values()[0]
2500 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2501 pcd.DatumType = pcdDecObject.DatumType
2502 # Only fix the value while no value provided in DSC file.
2503 for sku in pcd.SkuInfoList.values():
2504 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):
2505 sku.HiiDefaultValue = pcdDecObject.DefaultValue
2506 for default_store in sku.DefaultStoreDict:
2507 sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
2508 pcd.DefaultValue = pcdDecObject.DefaultValue
2509 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2510 valuefromDec = pcdDecObject.DefaultValue
2511 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})
2512 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2513 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2514 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2515 del(pcd.SkuInfoList['COMMON'])
2516 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2517 del(pcd.SkuInfoList['COMMON'])
2518
2519 if pcd.MaxDatumSize.strip():
2520 MaxSize = int(pcd.MaxDatumSize, 0)
2521 else:
2522 MaxSize = 0
2523 if pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:
2524 for (_, skuobj) in pcd.SkuInfoList.items():
2525 datalen = 0
2526 skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
2527 datalen = len(skuobj.HiiDefaultValue.split(","))
2528 if datalen > MaxSize:
2529 MaxSize = datalen
2530 for defaultst in skuobj.DefaultStoreDict:
2531 skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
2532 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
2533 pcd.MaxDatumSize = str(MaxSize)
2534 rt, invalidhii = self.CheckVariableNameAssignment(Pcds)
2535 if not rt:
2536 invalidpcd = ",".join(invalidhii)
2537 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)
2538
2539 map(self.FilterSkuSettings,Pcds.values())
2540
2541 return Pcds
2542
2543 def CheckVariableNameAssignment(self,Pcds):
2544 invalidhii = []
2545 for pcdname in Pcds:
2546 pcd = Pcds[pcdname]
2547 varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])
2548 if len(varnameset) > 1:
2549 invalidhii.append(".".join((pcdname[1],pcdname[0])))
2550 if len(invalidhii):
2551 return False,invalidhii
2552 else:
2553 return True, []
2554 ## Retrieve dynamic VPD PCD settings
2555 #
2556 # @param Type PCD type
2557 #
2558 # @retval a dict object contains settings of given PCD type
2559 #
2560 def _GetDynamicVpdPcd(self, Type):
2561
2562
2563 Pcds = sdict()
2564 #
2565 # tdict is a special dict kind of type, used for selecting correct
2566 # PCD settings for certain ARCH and SKU
2567 #
2568 PcdDict = tdict(True, 4)
2569 PcdList = []
2570
2571 # Find out all possible PCD candidates for self._Arch
2572 RecordList = self._RawData[Type, self._Arch]
2573 AvailableSkuIdSet = copy.copy(self.SkuIds)
2574
2575 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
2576 SkuName = SkuName.upper()
2577 SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
2578 if SkuName not in AvailableSkuIdSet:
2579 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
2580 File=self.MetaFile, Line=Dummy5)
2581 if "." not in TokenSpaceGuid:
2582 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
2583 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
2584
2585 # Remove redundant PCD candidates, per the ARCH and SKU
2586 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
2587 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
2588 if Setting == None:
2589 continue
2590 #
2591 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2592 # For the Integer & Boolean type, the optional data can only be InitialValue.
2593 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2594 # until the DEC parser has been called.
2595 #
2596 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
2597 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
2598 if (PcdCName, TokenSpaceGuid) in Pcds.keys():
2599 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
2600 pcdObject.SkuInfoList[SkuName] = SkuInfo
2601 if MaxDatumSize.strip():
2602 CurrentMaxSize = int(MaxDatumSize.strip(), 0)
2603 else:
2604 CurrentMaxSize = 0
2605 if pcdObject.MaxDatumSize:
2606 PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
2607 else:
2608 PcdMaxSize = 0
2609 if CurrentMaxSize > PcdMaxSize:
2610 pcdObject.MaxDatumSize = str(CurrentMaxSize)
2611 else:
2612 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
2613 PcdCName,
2614 TokenSpaceGuid,
2615 self._PCD_TYPE_STRING_[Type],
2616 '',
2617 InitialValue,
2618 '',
2619 MaxDatumSize,
2620 {SkuName : SkuInfo},
2621 False,
2622 None,
2623 IsDsc=True)
2624 for pcd in Pcds.values():
2625 SkuInfoObj = pcd.SkuInfoList.values()[0]
2626 pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
2627 pcd.DatumType = pcdDecObject.DatumType
2628 # Only fix the value while no value provided in DSC file.
2629 for sku in pcd.SkuInfoList.values():
2630 if (sku.DefaultValue == "" or sku.DefaultValue==None):
2631 sku.DefaultValue = pcdDecObject.DefaultValue
2632 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
2633 valuefromDec = pcdDecObject.DefaultValue
2634 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
2635 pcd.SkuInfoList['DEFAULT'] = SkuInfo
2636 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2637 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
2638 del(pcd.SkuInfoList['COMMON'])
2639 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
2640 del(pcd.SkuInfoList['COMMON'])
2641
2642
2643 map(self.FilterSkuSettings,Pcds.values())
2644 return Pcds
2645
2646 ## Add external modules
2647 #
2648 # The external modules are mostly those listed in FDF file, which don't
2649 # need "build".
2650 #
2651 # @param FilePath The path of module description file
2652 #
2653 def AddModule(self, FilePath):
2654 FilePath = NormPath(FilePath)
2655 if FilePath not in self.Modules:
2656 Module = ModuleBuildClassObject()
2657 Module.MetaFile = FilePath
2658 self.Modules.append(Module)
2659
2660 def _GetToolChainFamily(self):
2661 self._ToolChainFamily = "MSFT"
2662 BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
2663 if os.path.isfile(BuildConfigurationFile) == True:
2664 TargetTxt = TargetTxtClassObject()
2665 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
2666 ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
2667 if ToolDefinitionFile == '':
2668 ToolDefinitionFile = "tools_def.txt"
2669 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
2670 if os.path.isfile(ToolDefinitionFile) == True:
2671 ToolDef = ToolDefClassObject()
2672 ToolDef.LoadToolDefFile(ToolDefinitionFile)
2673 ToolDefinition = ToolDef.ToolsDefTxtDatabase
2674 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
2675 or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
2676 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
2677 self._ToolChainFamily = "MSFT"
2678 else:
2679 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
2680 return self._ToolChainFamily
2681
2682 ## Add external PCDs
2683 #
2684 # The external PCDs are mostly those listed in FDF file to specify address
2685 # or offset information.
2686 #
2687 # @param Name Name of the PCD
2688 # @param Guid Token space guid of the PCD
2689 # @param Value Value of the PCD
2690 #
2691 def AddPcd(self, Name, Guid, Value):
2692 if (Name, Guid) not in self.Pcds:
2693 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
2694 self.Pcds[Name, Guid].DefaultValue = Value
2695 @property
2696 def DecPcds(self):
2697 if self._DecPcds == None:
2698 FdfInfList = []
2699 if GlobalData.gFdfParser:
2700 FdfInfList = GlobalData.gFdfParser.Profile.InfList
2701 PkgSet = set()
2702 for Inf in FdfInfList:
2703 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
2704 if ModuleFile in self._Modules:
2705 continue
2706 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
2707 PkgSet.update(ModuleData.Packages)
2708 self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
2709 return self._DecPcds
2710 _Macros = property(_GetMacros)
2711 Arch = property(_GetArch, _SetArch)
2712 Platform = property(_GetPlatformName)
2713 PlatformName = property(_GetPlatformName)
2714 Guid = property(_GetFileGuid)
2715 Version = property(_GetVersion)
2716 DscSpecification = property(_GetDscSpec)
2717 OutputDirectory = property(_GetOutpuDir)
2718 SupArchList = property(_GetSupArch)
2719 BuildTargets = property(_GetBuildTarget)
2720 SkuName = property(_GetSkuName, _SetSkuName)
2721 PcdInfoFlag = property(_GetPcdInfoFlag)
2722 VarCheckFlag = property(_GetVarCheckFlag)
2723 FlashDefinition = property(_GetFdfFile)
2724 Prebuild = property(_GetPrebuild)
2725 Postbuild = property(_GetPostbuild)
2726 BuildNumber = property(_GetBuildNumber)
2727 MakefileName = property(_GetMakefileName)
2728 BsBaseAddress = property(_GetBsBaseAddress)
2729 RtBaseAddress = property(_GetRtBaseAddress)
2730 LoadFixAddress = property(_GetLoadFixAddress)
2731 RFCLanguages = property(_GetRFCLanguages)
2732 ISOLanguages = property(_GetISOLanguages)
2733 VpdToolGuid = property(_GetVpdToolGuid)
2734 SkuIds = property(_GetSkuIds)
2735 Modules = property(_GetModules)
2736 LibraryInstances = property(_GetLibraryInstances)
2737 LibraryClasses = property(_GetLibraryClasses)
2738 Pcds = property(_GetPcds)
2739 BuildOptions = property(_GetBuildOptions)
2740 ToolChainFamily = property(_GetToolChainFamily)