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