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