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