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