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