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