2 # This file is used to create a database used by build tool
4 # Copyright (c) 2017, 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
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.
15 ## Platform build information from DSC file
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
20 from Common
.String
import *
21 from Common
.DataType
import *
22 from Common
.Misc
import *
25 from CommonDataClass
.CommonClass
import SkuInfoClass
27 from MetaDataTable
import *
28 from MetaFileTable
import *
29 from MetaFileParser
import *
31 from WorkspaceCommon
import GetDeclaredPcd
32 from Common
.Misc
import AnalyzeDscPcd
33 from Common
.Misc
import ProcessDuplicatedInf
35 from Common
.Parsing
import IsValidWord
36 from Common
.VariableAttributes
import VariableAttributes
37 import Common
.GlobalData
as GlobalData
39 from Workspace
.BuildClassObject
import PlatformBuildClassObject
, StructurePcd
, PcdClassObject
, ModuleBuildClassObject
42 # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
44 PcdValueInitName
= 'PcdValueInit'
45 PcdSupportedBaseTypes
= ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
46 PcdSupportedBaseTypeWidth
= {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
47 PcdUnsupportedBaseTypes
= ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
58 #include <PcdValueCommon.h>
68 return PcdValueMain (argc, argv);
72 PcdMakefileHeader
= '''
75 # This file is auto-generated by build utility
81 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
83 CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101
85 LIBS = $(LIB_PATH)\Common.lib
87 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
92 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
96 class DscBuildData(PlatformBuildClassObject
):
97 # dict used to convert PCD type in database to string used by build tool
99 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
100 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
101 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
102 MODEL_PCD_DYNAMIC
: "Dynamic",
103 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
104 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
105 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
106 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
107 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
108 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
109 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
112 # dict used to convert part of [Defines] to members of DscBuildData directly
117 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
118 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
119 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
120 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
121 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
122 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
123 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
124 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
125 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
126 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
127 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
128 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
129 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
130 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
131 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
134 # used to compose dummy library class name for those forced library instances
135 _NullLibraryNumber
= 0
137 ## Constructor of DscBuildData
139 # Initialize object of DscBuildData
141 # @param FilePath The path of platform description file
142 # @param RawData The raw data of DSC file
143 # @param BuildDataBase Database used to retrieve module/package information
144 # @param Arch The target architecture
145 # @param Platform (not used for DscBuildData)
146 # @param Macros Macros used for replacement in DSC file
148 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
149 self
.MetaFile
= FilePath
150 self
._RawData
= RawData
151 self
._Bdb
= BuildDataBase
153 self
._Target
= Target
154 self
._Toolchain
= Toolchain
156 self
._HandleOverridePath
()
157 if os
.getenv("WORKSPACE"):
158 self
.OutputPath
= os
.path
.join(os
.getenv("WORKSPACE"), 'Build', PcdValueInitName
)
160 self
.OutputPath
= os
.path
.dirname(self
.DscFile
)
163 def __setitem__(self
, key
, value
):
164 self
.__dict
__[self
._PROPERTY
_[key
]] = value
167 def __getitem__(self
, key
):
168 return self
.__dict
__[self
._PROPERTY
_[key
]]
171 def __contains__(self
, key
):
172 return key
in self
._PROPERTY
_
174 ## Set all internal used members of DscBuildData to None
177 self
._PlatformName
= None
180 self
._DscSpecification
= None
181 self
._OutputDirectory
= None
182 self
._SupArchList
= None
183 self
._BuildTargets
= None
185 self
._SkuIdentifier
= None
186 self
._AvilableSkuIds
= None
187 self
._PcdInfoFlag
= None
188 self
._VarCheckFlag
= None
189 self
._FlashDefinition
= None
190 self
._Prebuild
= None
191 self
._Postbuild
= None
192 self
._BuildNumber
= None
193 self
._MakefileName
= None
194 self
._BsBaseAddress
= None
195 self
._RtBaseAddress
= None
198 self
._LibraryInstances
= None
199 self
._LibraryClasses
= None
202 self
._BuildOptions
= None
203 self
._ModuleTypeOptions
= None
204 self
._LoadFixAddress
= None
205 self
._RFCLanguages
= None
206 self
._ISOLanguages
= None
207 self
._VpdToolGuid
= None
211 ## handle Override Path of Module
212 def _HandleOverridePath(self
):
213 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
214 Macros
= self
._Macros
215 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
216 for Record
in RecordList
:
219 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
220 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
222 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
224 # Check if the source override path exists
225 if not os
.path
.isdir(SourceOverridePath
):
226 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
228 # Add to GlobalData Variables
229 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
231 ## Get current effective macros
232 def _GetMacros(self
):
233 if self
.__Macros
== None:
235 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
236 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
237 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
246 # Changing the default ARCH to another may affect all other information
247 # because all information in a platform may be ARCH-related. That's
248 # why we need to clear all internal used members, in order to cause all
249 # information to be re-retrieved.
251 # @param Value The value of ARCH
253 def _SetArch(self
, Value
):
254 if self
._Arch
== Value
:
259 ## Retrieve all information in [Defines] section
261 # (Retriving all [Defines] information in one-shot is just to save time.)
263 def _GetHeaderInfo(self
):
264 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
265 for Record
in RecordList
:
267 # items defined _PROPERTY_ don't need additional processing
269 # some special items in [Defines] section need special treatment
270 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
271 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
272 if ' ' in self
._OutputDirectory
:
273 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
274 File
=self
.MetaFile
, Line
=Record
[-1],
275 ExtraData
=self
._OutputDirectory
)
276 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
277 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
278 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
280 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
282 elif Name
== TAB_DSC_PREBUILD
:
283 PrebuildValue
= Record
[2]
284 if Record
[2][0] == '"':
285 if Record
[2][-1] != '"':
286 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
287 File
=self
.MetaFile
, Line
=Record
[-1])
288 PrebuildValue
= Record
[2][1:-1]
289 self
._Prebuild
= PrebuildValue
290 elif Name
== TAB_DSC_POSTBUILD
:
291 PostbuildValue
= Record
[2]
292 if Record
[2][0] == '"':
293 if Record
[2][-1] != '"':
294 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
295 File
=self
.MetaFile
, Line
=Record
[-1])
296 PostbuildValue
= Record
[2][1:-1]
297 self
._Postbuild
= PostbuildValue
298 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
299 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
300 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
301 self
._BuildTargets
= GetSplitValueList(Record
[2])
302 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
303 if self
._SkuName
== None:
304 self
._SkuName
= Record
[2]
305 self
._SkuIdentifier
= Record
[2]
306 self
._AvilableSkuIds
= Record
[2]
307 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
308 self
._PcdInfoFlag
= Record
[2]
309 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
310 self
._VarCheckFlag
= Record
[2]
311 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
313 self
._LoadFixAddress
= int (Record
[2], 0)
315 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
316 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
317 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
318 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"',
319 File
=self
.MetaFile
, Line
=Record
[-1])
320 LanguageCodes
= Record
[2][1:-1]
321 if not LanguageCodes
:
322 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
323 File
=self
.MetaFile
, Line
=Record
[-1])
324 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
325 # check whether there is empty entries in the list
326 if None in LanguageList
:
327 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
328 File
=self
.MetaFile
, Line
=Record
[-1])
329 self
._RFCLanguages
= LanguageList
330 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
331 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
332 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
333 File
=self
.MetaFile
, Line
=Record
[-1])
334 LanguageCodes
= Record
[2][1:-1]
335 if not LanguageCodes
:
336 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
337 File
=self
.MetaFile
, Line
=Record
[-1])
338 if len(LanguageCodes
) % 3:
339 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
340 File
=self
.MetaFile
, Line
=Record
[-1])
342 for i
in range(0, len(LanguageCodes
), 3):
343 LanguageList
.append(LanguageCodes
[i
:i
+ 3])
344 self
._ISOLanguages
= LanguageList
345 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
347 # try to convert GUID to a real UUID value to see whether the GUID is format
348 # for VPD_TOOL_GUID is correct.
353 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
354 self
._VpdToolGuid
= Record
[2]
356 self
[Name
] = Record
[2]
357 # set _Header to non-None in order to avoid database re-querying
358 self
._Header
= 'DUMMY'
360 ## Retrieve platform name
361 def _GetPlatformName(self
):
362 if self
._PlatformName
== None:
363 if self
._Header
== None:
364 self
._GetHeaderInfo
()
365 if self
._PlatformName
== None:
366 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
367 return self
._PlatformName
369 ## Retrieve file guid
370 def _GetFileGuid(self
):
371 if self
._Guid
== None:
372 if self
._Header
== None:
373 self
._GetHeaderInfo
()
374 if self
._Guid
== None:
375 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
378 ## Retrieve platform version
379 def _GetVersion(self
):
380 if self
._Version
== None:
381 if self
._Header
== None:
382 self
._GetHeaderInfo
()
383 if self
._Version
== None:
384 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
387 ## Retrieve platform description file version
388 def _GetDscSpec(self
):
389 if self
._DscSpecification
== None:
390 if self
._Header
== None:
391 self
._GetHeaderInfo
()
392 if self
._DscSpecification
== None:
393 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
394 return self
._DscSpecification
396 ## Retrieve OUTPUT_DIRECTORY
397 def _GetOutpuDir(self
):
398 if self
._OutputDirectory
== None:
399 if self
._Header
== None:
400 self
._GetHeaderInfo
()
401 if self
._OutputDirectory
== None:
402 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
403 return self
._OutputDirectory
405 ## Retrieve SUPPORTED_ARCHITECTURES
406 def _GetSupArch(self
):
407 if self
._SupArchList
== None:
408 if self
._Header
== None:
409 self
._GetHeaderInfo
()
410 if self
._SupArchList
== None:
411 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
412 return self
._SupArchList
414 ## Retrieve BUILD_TARGETS
415 def _GetBuildTarget(self
):
416 if self
._BuildTargets
== None:
417 if self
._Header
== None:
418 self
._GetHeaderInfo
()
419 if self
._BuildTargets
== None:
420 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
421 return self
._BuildTargets
423 def _GetPcdInfoFlag(self
):
424 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
426 elif self
._PcdInfoFlag
.upper() == 'TRUE':
430 def _GetVarCheckFlag(self
):
431 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
433 elif self
._VarCheckFlag
.upper() == 'TRUE':
437 def _GetAviableSkuIds(self
):
438 if self
._AvilableSkuIds
:
439 return self
._AvilableSkuIds
440 return self
.SkuIdentifier
441 def _GetSkuIdentifier(self
):
444 if self
._SkuIdentifier
== None:
445 if self
._Header
== None:
446 self
._GetHeaderInfo
()
447 return self
._SkuIdentifier
448 ## Retrieve SKUID_IDENTIFIER
449 def _GetSkuName(self
):
450 if self
._SkuName
== None:
451 if self
._Header
== None:
452 self
._GetHeaderInfo
()
453 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
454 self
._SkuName
= 'DEFAULT'
457 ## Override SKUID_IDENTIFIER
458 def _SetSkuName(self
, Value
):
459 self
._SkuName
= Value
462 def _GetFdfFile(self
):
463 if self
._FlashDefinition
== None:
464 if self
._Header
== None:
465 self
._GetHeaderInfo
()
466 if self
._FlashDefinition
== None:
467 self
._FlashDefinition
= ''
468 return self
._FlashDefinition
470 def _GetPrebuild(self
):
471 if self
._Prebuild
== None:
472 if self
._Header
== None:
473 self
._GetHeaderInfo
()
474 if self
._Prebuild
== None:
476 return self
._Prebuild
478 def _GetPostbuild(self
):
479 if self
._Postbuild
== None:
480 if self
._Header
== None:
481 self
._GetHeaderInfo
()
482 if self
._Postbuild
== None:
484 return self
._Postbuild
486 ## Retrieve FLASH_DEFINITION
487 def _GetBuildNumber(self
):
488 if self
._BuildNumber
== None:
489 if self
._Header
== None:
490 self
._GetHeaderInfo
()
491 if self
._BuildNumber
== None:
492 self
._BuildNumber
= ''
493 return self
._BuildNumber
495 ## Retrieve MAKEFILE_NAME
496 def _GetMakefileName(self
):
497 if self
._MakefileName
== None:
498 if self
._Header
== None:
499 self
._GetHeaderInfo
()
500 if self
._MakefileName
== None:
501 self
._MakefileName
= ''
502 return self
._MakefileName
504 ## Retrieve BsBaseAddress
505 def _GetBsBaseAddress(self
):
506 if self
._BsBaseAddress
== None:
507 if self
._Header
== None:
508 self
._GetHeaderInfo
()
509 if self
._BsBaseAddress
== None:
510 self
._BsBaseAddress
= ''
511 return self
._BsBaseAddress
513 ## Retrieve RtBaseAddress
514 def _GetRtBaseAddress(self
):
515 if self
._RtBaseAddress
== None:
516 if self
._Header
== None:
517 self
._GetHeaderInfo
()
518 if self
._RtBaseAddress
== None:
519 self
._RtBaseAddress
= ''
520 return self
._RtBaseAddress
522 ## Retrieve the top address for the load fix address
523 def _GetLoadFixAddress(self
):
524 if self
._LoadFixAddress
== None:
525 if self
._Header
== None:
526 self
._GetHeaderInfo
()
528 if self
._LoadFixAddress
== None:
529 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
532 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
534 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
537 # If command line defined, should override the value in DSC file.
539 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
541 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
543 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']))
545 if self
._LoadFixAddress
< 0:
546 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
547 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
548 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
550 return self
._LoadFixAddress
552 ## Retrieve RFCLanguage filter
553 def _GetRFCLanguages(self
):
554 if self
._RFCLanguages
== None:
555 if self
._Header
== None:
556 self
._GetHeaderInfo
()
557 if self
._RFCLanguages
== None:
558 self
._RFCLanguages
= []
559 return self
._RFCLanguages
561 ## Retrieve ISOLanguage filter
562 def _GetISOLanguages(self
):
563 if self
._ISOLanguages
== None:
564 if self
._Header
== None:
565 self
._GetHeaderInfo
()
566 if self
._ISOLanguages
== None:
567 self
._ISOLanguages
= []
568 return self
._ISOLanguages
569 ## Retrieve the GUID string for VPD tool
570 def _GetVpdToolGuid(self
):
571 if self
._VpdToolGuid
== None:
572 if self
._Header
== None:
573 self
._GetHeaderInfo
()
574 if self
._VpdToolGuid
== None:
575 self
._VpdToolGuid
= ''
576 return self
._VpdToolGuid
578 ## Retrieve [SkuIds] section information
579 def _GetSkuIds(self
):
580 if self
._SkuIds
== None:
581 self
._SkuIds
= sdict()
582 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
583 for Record
in RecordList
:
584 if Record
[0] in [None, '']:
585 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
586 File
=self
.MetaFile
, Line
=Record
[-1])
587 if Record
[1] in [None, '']:
588 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
589 File
=self
.MetaFile
, Line
=Record
[-1])
590 self
._SkuIds
[Record
[1]] = Record
[0]
591 if 'DEFAULT' not in self
._SkuIds
:
592 self
._SkuIds
['DEFAULT'] = '0'
593 if 'COMMON' not in self
._SkuIds
:
594 self
._SkuIds
['COMMON'] = '0'
597 ## Retrieve [Components] section information
598 def _GetModules(self
):
599 if self
._Modules
!= None:
602 self
._Modules
= sdict()
603 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
604 Macros
= self
._Macros
605 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
606 for Record
in RecordList
:
607 DuplicatedFile
= False
609 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
613 # check the file validation
614 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
616 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
619 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
620 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
621 DuplicatedFile
= True
623 Module
= ModuleBuildClassObject()
624 Module
.MetaFile
= ModuleFile
626 # get module private library instance
627 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
628 for Record
in RecordList
:
629 LibraryClass
= Record
[0]
630 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
633 # check the file validation
634 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
636 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
639 if LibraryClass
== '' or LibraryClass
== 'NULL':
640 self
._NullLibraryNumber
+= 1
641 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
642 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
643 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
644 if LibraryPath
not in self
.LibraryInstances
:
645 self
.LibraryInstances
.append(LibraryPath
)
647 # get module private PCD setting
648 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
649 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
650 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
651 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
652 TokenList
= GetSplitValueList(Setting
)
653 DefaultValue
= TokenList
[0]
654 if len(TokenList
) > 1:
655 MaxDatumSize
= TokenList
[1]
658 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
659 Pcd
= PcdClassObject(
671 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
673 # get module private build options
674 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
675 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
676 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
677 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
679 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
680 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
682 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
683 if DuplicatedFile
and not RecordList
:
684 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
686 if len(RecordList
) != 1:
687 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
688 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
689 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
690 ModuleFile
.Arch
= self
._Arch
692 self
._Modules
[ModuleFile
] = Module
695 ## Retrieve all possible library instances used in this platform
696 def _GetLibraryInstances(self
):
697 if self
._LibraryInstances
== None:
698 self
._GetLibraryClasses
()
699 return self
._LibraryInstances
701 ## Retrieve [LibraryClasses] information
702 def _GetLibraryClasses(self
):
703 if self
._LibraryClasses
== None:
704 self
._LibraryInstances
= []
706 # tdict is a special dict kind of type, used for selecting correct
707 # library instance for given library class and module type
709 LibraryClassDict
= tdict(True, 3)
710 # track all library class names
711 LibraryClassSet
= set()
712 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
713 Macros
= self
._Macros
714 for Record
in RecordList
:
715 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
716 if LibraryClass
== '' or LibraryClass
== 'NULL':
717 self
._NullLibraryNumber
+= 1
718 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
719 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
720 LibraryClassSet
.add(LibraryClass
)
721 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
722 # check the file validation
723 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
725 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
728 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
729 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
730 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
731 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
732 if LibraryInstance
not in self
._LibraryInstances
:
733 self
._LibraryInstances
.append(LibraryInstance
)
735 # resolve the specific library instance for each class and each module type
736 self
._LibraryClasses
= tdict(True)
737 for LibraryClass
in LibraryClassSet
:
738 # try all possible module types
739 for ModuleType
in SUP_MODULE_LIST
:
740 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
741 if LibraryInstance
== None:
743 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
745 # for Edk style library instances, which are listed in different section
746 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
747 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
748 for Record
in RecordList
:
749 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
751 # check the file validation
752 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
754 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
756 if File
not in self
._LibraryInstances
:
757 self
._LibraryInstances
.append(File
)
759 # we need the module name as the library class name, so we have
760 # to parse it here. (self._Bdb[] will trigger a file parse if it
761 # hasn't been parsed)
763 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
764 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
765 return self
._LibraryClasses
767 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
768 if self
._DecPcds
== None:
769 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
771 if GlobalData
.gFdfParser
:
772 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
775 for Inf
in FdfInfList
:
776 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
777 if ModuleFile
in self
._Modules
:
779 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
780 PkgSet
.update(ModuleData
.Packages
)
784 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
785 self
._DecPcds
.update(DecPcds
)
787 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
and "." in TokenSpaceGuid
and (TokenSpaceGuid
.split(".")[1], TokenSpaceGuid
.split(".")[0]) not in self
._DecPcds
:
788 EdkLogger
.error('build', PARSER_ERROR
,
789 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
790 File
=self
.MetaFile
, Line
=LineNo
)
791 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
792 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
793 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
794 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
795 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
797 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
798 except WrnExpression
, Value
:
799 ValueList
[Index
] = Value
.result
800 except EvaluationException
, Excpt
:
801 if hasattr(Excpt
, 'Pcd'):
802 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
803 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
804 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
805 " of the DSC file" % Excpt
.Pcd
,
806 File
=self
.MetaFile
, Line
=LineNo
)
808 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
809 File
=self
.MetaFile
, Line
=LineNo
)
811 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
812 File
=self
.MetaFile
, Line
=LineNo
)
813 if ValueList
[Index
] == 'True':
814 ValueList
[Index
] = '1'
815 elif ValueList
[Index
] == 'False':
816 ValueList
[Index
] = '0'
818 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
820 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
821 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
824 ## Retrieve all PCD settings in platform
826 if self
._Pcds
== None:
828 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
829 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
830 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
831 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
832 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
833 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
834 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
835 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
836 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
838 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
841 ## Retrieve [BuildOptions]
842 def _GetBuildOptions(self
):
843 if self
._BuildOptions
== None:
844 self
._BuildOptions
= sdict()
846 # Retrieve build option for EDKII and EDK style module
848 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
849 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
850 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
851 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
853 # Only flags can be appended
855 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
856 self
._BuildOptions
[CurKey
] = Option
858 self
._BuildOptions
[CurKey
] += ' ' + Option
859 return self
._BuildOptions
861 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
862 if self
._ModuleTypeOptions
== None:
863 self
._ModuleTypeOptions
= sdict()
864 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
866 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
867 DriverType
= '%s.%s' % (Edk
, ModuleType
)
868 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
869 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
870 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
871 if Type
== DriverType
or Type
== CommonDriverType
:
872 Key
= (ToolChainFamily
, ToolChain
, Edk
)
873 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
874 options
[Key
] = Option
876 options
[Key
] += ' ' + Option
877 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
879 def GetStructurePcdInfo(self
, PcdSet
):
880 structure_pcd_data
= {}
882 if item
[1] not in structure_pcd_data
:
883 structure_pcd_data
[item
[1]] = []
884 structure_pcd_data
[item
[1]].append(item
)
886 return structure_pcd_data
888 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
890 SkuObj
= SkuClass(self
.SkuIdentifier
, self
.SkuIds
)
893 # Find out all possible PCD candidates for self._Arch
895 for Type
in TypeList
:
896 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
898 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
899 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
900 if SkuName
in SkuObj
.SkuIdSet
and "." in TokenSpaceGuid
:
901 S_PcdSet
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
, AnalyzePcdExpression(Setting
)[0]))
903 # handle pcd value override
904 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
906 for str_pcd
in StrPcdSet
:
907 str_pcd_obj
= Pcds
.get((str_pcd
.split(".")[1], str_pcd
.split(".")[0]), None)
908 str_pcd_dec
= self
._DecPcds
.get((str_pcd
.split(".")[1], str_pcd
.split(".")[0]), None)
910 str_pcd_obj_str
= StructurePcd()
911 str_pcd_obj_str
.copy(str_pcd_dec
)
913 str_pcd_obj_str
.copy(str_pcd_obj
)
914 if str_pcd_obj
.DefaultValue
:
915 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
916 for str_pcd_data
in StrPcdSet
[str_pcd
]:
917 if str_pcd_data
[2] in SkuObj
.SkuIdSet
:
918 str_pcd_obj_str
.AddOverrideValue(str_pcd_data
[0], str(str_pcd_data
[4]), 'DEFAULT' if str_pcd_data
[2] == 'COMMON' else str_pcd_data
[2],self
.MetaFile
.File
,LineNo
=str_pcd_data
[3])
919 S_pcd_set
[str_pcd
.split(".")[1], str_pcd
.split(".")[0]] = str_pcd_obj_str
920 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
921 for Pcd
in self
._DecPcds
:
922 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
923 if Pcd
not in S_pcd_set
:
924 str_pcd_obj_str
= StructurePcd()
925 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
926 str_pcd_obj
= Pcds
.get(Pcd
, None)
928 str_pcd_obj_str
.copy(str_pcd_obj
)
929 if str_pcd_obj
.DefaultValue
:
930 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
931 S_pcd_set
[Pcd
] = str_pcd_obj_str
933 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
934 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
936 for item
in Str_Pcd_Values
:
937 str_pcd_obj
= S_pcd_set
.get((item
[2], item
[1]))
938 if str_pcd_obj
is None:
940 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
941 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
942 if item
[0] not in str_pcd_obj
.SkuInfoList
:
943 str_pcd_obj
.SkuInfoList
[item
[0]] = SkuInfoClass(SkuIdName
=item
[0], SkuId
=self
.SkuIds
[item
[0]], HiiDefaultValue
=item
[3])
945 str_pcd_obj
.SkuInfoList
[item
[0]].HiiDefaultValue
= item
[3]
946 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
947 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
948 if item
[0] in (SkuObj
.SystemSkuId
, 'DEFAULT', 'COMMON'):
949 str_pcd_obj
.DefaultValue
= item
[3]
951 if item
[0] not in str_pcd_obj
.SkuInfoList
:
952 str_pcd_obj
.SkuInfoList
[item
[0]] = SkuInfoClass(SkuIdName
=item
[0], SkuId
=self
.SkuIds
[item
[0]], DefaultValue
=item
[3])
954 str_pcd_obj
.SkuInfoList
[item
[0]].DefaultValue
= item
[3]
956 for str_pcd_obj
in S_pcd_set
.values():
957 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
958 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
962 ## Retrieve non-dynamic PCD settings
964 # @param Type PCD type
966 # @retval a dict object contains settings of given PCD type
968 def _GetPcd(self
, Type
):
971 # tdict is a special dict kind of type, used for selecting correct
972 # PCD settings for certain ARCH
975 SkuObj
= SkuClass(self
.SkuIdentifier
, self
.SkuIds
)
977 PcdDict
= tdict(True, 3)
979 # Find out all possible PCD candidates for self._Arch
980 RecordList
= self
._RawData
[Type
, self
._Arch
]
981 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
982 AvailableSkuIdSet
.update({'DEFAULT':0, 'COMMON':0})
983 PcdValueDict
= sdict()
984 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
985 if SkuName
not in AvailableSkuIdSet
:
986 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The SKUID name %s is not supported by the platform." % SkuName
)
987 if "." not in TokenSpaceGuid
:
988 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
989 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
991 TokenSpaceGuid
, PcdCName
= TokenSpaceGuid
.split('.')
993 for PcdItem
in RecordList
:
994 if (TokenSpaceGuid
, PcdCName
) == (PcdItem
[0], PcdItem
[1]):
998 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, 0))
999 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = ''
1001 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1002 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1005 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1006 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1007 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1009 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1011 PcdsKeys
= PcdValueDict
.keys()
1012 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1014 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1018 if 'COMMON' in PcdSetting
:
1019 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1020 if 'DEFAULT' in PcdSetting
:
1021 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1022 if SkuObj
.SystemSkuId
in PcdSetting
:
1023 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
1025 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1028 self
._PCD
_TYPE
_STRING
_[Type
],
1041 def GetStructurePcdMaxSize(self
, str_pcd
):
1042 pcd_default_value
= str_pcd
.DefaultValue
1043 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()]
1044 sku_values
.append(pcd_default_value
)
1046 def get_length(value
):
1047 Value
= value
.strip()
1048 if Value
.startswith('GUID') and Value
.endswith(')'):
1050 if Value
.startswith('L"') and Value
.endswith('"'):
1051 return len(Value
[2:-1])
1052 if Value
[0] == '"' and Value
[-1] == '"':
1053 return len(Value
) - 2
1054 if Value
[0] == '{' and Value
[-1] == '}':
1055 return len(Value
.split(","))
1056 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1057 return len(list(Value
[2:-1]))
1058 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1059 return len(Value
) - 2
1062 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1064 def IsFieldValueAnArray (self
, Value
):
1065 Value
= Value
.strip()
1066 if Value
.startswith('GUID') and Value
.endswith(')'):
1068 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1070 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1072 if Value
[0] == '{' and Value
[-1] == '}':
1074 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1075 print 'foo = ', list(Value
[2:-1])
1077 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1078 print 'bar = ', list(Value
[1:-1])
1082 def ExecuteCommand (self
, Command
):
1084 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1086 print 'ERROR: Can not execute command:', Command
1088 Result
= Process
.communicate()
1089 if Process
.returncode
<> 0:
1090 print 'ERROR: Can not collect output from command:', Command
1091 return Result
[0], Result
[1]
1093 def IntToCString(self
, Value
, ValueSize
):
1095 if not isinstance (Value
, str):
1096 for Index
in range(0, ValueSize
):
1097 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1099 Result
= Result
+ '"'
1102 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1103 OverrideValues
= None
1104 if Pcd
.SkuOverrideValues
:
1105 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1106 CApp
= CApp
+ 'void\n'
1107 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1108 CApp
= CApp
+ ' void\n'
1109 CApp
= CApp
+ ' )\n'
1111 CApp
= CApp
+ ' UINT32 Size;\n'
1112 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1113 CApp
= CApp
+ ' UINT8 *Value;\n'
1114 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1115 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1116 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1118 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, Pcd
.DefaultValue
)
1121 # Get current PCD value and size
1123 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1126 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1127 # the correct value. For structures with a flexible array member, the flexible
1128 # array member is detected, and the size is based on the highest index used with
1129 # the flexible array member. The flexible array member must be the last field
1130 # in a structure. The size formula for this case is:
1131 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1133 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1134 for FieldList
in [Pcd
.DefaultValues
, OverrideValues
]:
1137 for FieldName
in FieldList
:
1138 FieldName
= "." + FieldName
1139 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1141 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1142 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."))
1145 while '[' in FieldName
:
1146 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1147 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1148 FieldName
= FieldName
.split(']', 1)[1]
1149 FieldName
= NewFieldName
+ FieldName
1150 while '[' in FieldName
:
1151 FieldName
= FieldName
.rsplit('[', 1)[0]
1152 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1155 # Allocate and zero buffer for the PCD
1156 # Must handle cases where current value is smaller, larger, or same size
1157 # Always keep that larger one as the current size
1159 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1160 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1161 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1164 # Copy current PCD value into allocated buffer.
1166 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1167 CApp
= CApp
+ ' free (OriginalPcd);\n'
1170 # Assign field values in PCD
1172 for FieldList
in [Pcd
.DefaultValues
, Pcd
.DefaultFromDSC
, OverrideValues
]:
1175 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1176 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1177 Value
, ValueSize
= ParseFieldValue (FieldList
)
1178 if isinstance(Value
, str):
1179 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1182 # Use memcpy() to copy value into field
1184 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1185 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1188 for FieldName
in FieldList
:
1189 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1190 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1191 if isinstance(Value
, str):
1192 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1195 # Use memcpy() to copy value into field
1197 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1198 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1199 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1202 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1204 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1207 # Set new PCD value and size
1209 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1214 CApp
= CApp
+ ' free (Pcd);\n'
1217 return InitByteValue
, CApp
1219 def GenerateByteArrayValue (self
, StructuredPcds
):
1221 # Generate/Compile/Run C application to determine if there are any flexible array members
1223 if not StructuredPcds
:
1227 CApp
= PcdMainCHeader
1230 for PcdName
in StructuredPcds
:
1231 Pcd
= StructuredPcds
[PcdName
]
1232 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1233 if IncludeFile
not in Includes
:
1234 Includes
[IncludeFile
] = True
1235 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1238 for PcdName
in StructuredPcds
:
1239 Pcd
= StructuredPcds
[PcdName
]
1240 if not Pcd
.SkuOverrideValues
:
1241 InitByteValue
, CApp
= self
.GenerateInitializeFunc('DEFAULT', 'STANDARD', Pcd
, InitByteValue
, CApp
)
1243 for SkuName
in Pcd
.SkuOverrideValues
:
1244 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1245 Pcd
= StructuredPcds
[PcdName
]
1246 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1248 CApp
= CApp
+ 'VOID\n'
1249 CApp
= CApp
+ 'PcdEntryPoint(\n'
1250 CApp
= CApp
+ ' VOID\n'
1251 CApp
= CApp
+ ' )\n'
1253 for Pcd
in StructuredPcds
.values():
1254 if not Pcd
.SkuOverrideValues
:
1255 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % ('DEFAULT', 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1257 for SkuName
in Pcd
.SkuOverrideValues
:
1258 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1259 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1262 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1264 if not os
.path
.exists(self
.OutputPath
):
1265 os
.makedirs(self
.OutputPath
)
1266 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1267 File
= open (CAppBaseFileName
+ '.c', 'w')
1271 MakeApp
= PcdMakefileHeader
1272 if sys
.platform
== "win32":
1273 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1275 MakeApp
= MakeApp
+ PcdGccMakefile
1276 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1277 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='
1280 for Cache
in self
._Bdb
._CACHE
_.values():
1281 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1284 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1285 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1288 for Pcd
in StructuredPcds
.values():
1289 for PackageDec
in Pcd
.PackageDecs
:
1290 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1291 if not os
.path
.exists(Package
):
1292 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1293 if Package
not in PcdDependDEC
:
1294 PcdDependDEC
.append(Package
)
1296 if PlatformInc
and PcdDependDEC
:
1297 for pkg
in PcdDependDEC
:
1298 if pkg
in PlatformInc
:
1299 for inc
in PlatformInc
[pkg
]:
1300 MakeApp
+= '-I' + str(inc
) + ' '
1301 MakeApp
= MakeApp
+ '\n'
1302 if sys
.platform
== "win32":
1303 MakeApp
= MakeApp
+ PcdMakefileEnd
1304 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1305 File
= open (MakeFileName
, 'w')
1309 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1310 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1311 File
= open (InputValueFile
, 'w')
1312 File
.write(InitByteValue
)
1315 if sys
.platform
== "win32":
1316 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1318 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1319 Messages
= StdOut
.split('\r')
1320 for Message
in Messages
:
1321 if " error " in Message
:
1322 FileInfo
= Message
.strip().split('(')
1323 if len (FileInfo
) > 0:
1324 FileName
= FileInfo
[0]
1325 FileLine
= FileInfo
[1].split (')')[0]
1327 FileInfo
= Message
.strip().split(':')
1328 FileName
= FileInfo
[0]
1329 FileLine
= FileInfo
[1]
1331 File
= open (FileName
, 'r')
1332 FileData
= File
.readlines()
1334 error_line
= FileData
[int (FileLine
) - 1]
1335 if r
"//" in error_line
:
1336 c_line
,dsc_line
= error_line
.split(r
"//")
1338 dsc_line
= error_line
1340 message_itmes
= Message
.split(":")
1341 for item
in message_itmes
:
1342 if "PcdValueInit.c" in item
:
1343 message_itmes
[message_itmes
.index(item
)] = dsc_line
.strip()
1345 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[1:]))
1347 PcdValueInitExe
= PcdValueInitName
1348 if not sys
.platform
== "win32":
1349 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1351 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1352 File
= open (OutputValueFile
, 'r')
1353 FileBuffer
= File
.readlines()
1356 StructurePcdSet
= []
1357 for Pcd
in FileBuffer
:
1358 PcdValue
= Pcd
.split ('|')
1359 PcdInfo
= PcdValue
[0].split ('.')
1360 StructurePcdSet
.append((PcdInfo
[0], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1361 return StructurePcdSet
1363 ## Retrieve dynamic PCD settings
1365 # @param Type PCD type
1367 # @retval a dict object contains settings of given PCD type
1369 def _GetDynamicPcd(self
, Type
):
1371 SkuObj
= SkuClass(self
.SkuIdentifier
, self
.SkuIds
)
1375 # tdict is a special dict kind of type, used for selecting correct
1376 # PCD settings for certain ARCH and SKU
1378 PcdDict
= tdict(True, 4)
1380 # Find out all possible PCD candidates for self._Arch
1381 RecordList
= self
._RawData
[Type
, self
._Arch
]
1382 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1384 AvailableSkuIdSet
.update({'DEFAULT':0, 'COMMON':0})
1386 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1387 if SkuName
not in AvailableSkuIdSet
:
1388 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The SKUID name %s is not supported by the platform." % SkuName
)
1389 if "." not in TokenSpaceGuid
:
1390 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1391 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1393 # Remove redundant PCD candidates, per the ARCH and SKU
1394 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1396 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1400 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1401 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
1402 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1403 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1404 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1405 if MaxDatumSize
.strip():
1406 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1409 if pcdObject
.MaxDatumSize
:
1410 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1413 if CurrentMaxSize
> PcdMaxSize
:
1414 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1416 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1419 self
._PCD
_TYPE
_STRING
_[Type
],
1424 {SkuName
: SkuInfo
},
1429 for pcd
in Pcds
.values():
1430 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1431 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1432 valuefromDec
= pcdDecObject
.DefaultValue
1433 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1434 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1435 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1436 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1437 del(pcd
.SkuInfoList
['COMMON'])
1438 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1439 del(pcd
.SkuInfoList
['COMMON'])
1440 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1441 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1442 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1443 del(pcd
.SkuInfoList
['DEFAULT'])
1447 def CompareVarAttr(self
, Attr1
, Attr2
):
1448 if not Attr1
or not Attr2
: # for empty string
1450 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1451 Attr1Set
= set(Attr1s
)
1452 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1453 Attr2Set
= set(Attr2s
)
1454 if Attr2Set
== Attr1Set
:
1458 ## Retrieve dynamic HII PCD settings
1460 # @param Type PCD type
1462 # @retval a dict object contains settings of given PCD type
1464 def _GetDynamicHiiPcd(self
, Type
):
1466 SkuObj
= SkuClass(self
.SkuIdentifier
, self
.SkuIds
)
1471 # tdict is a special dict kind of type, used for selecting correct
1472 # PCD settings for certain ARCH and SKU
1474 PcdDict
= tdict(True, 4)
1476 RecordList
= self
._RawData
[Type
, self
._Arch
]
1477 # Find out all possible PCD candidates for self._Arch
1478 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1480 AvailableSkuIdSet
.update({'DEFAULT':0, 'COMMON':0})
1481 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1482 if SkuName
not in AvailableSkuIdSet
:
1483 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The SKUID name %s is not supported by the platform." % SkuName
)
1484 if "." not in TokenSpaceGuid
:
1485 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1486 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1489 # Remove redundant PCD candidates, per the ARCH and SKU
1490 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1492 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1495 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1497 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1499 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1500 ExtraData
="[%s]" % VarAttribute
)
1502 FormatCorrect
= True
1503 if VariableOffset
.isdigit():
1504 if int(VariableOffset
, 10) > 0xFFFF:
1506 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1507 if int(VariableOffset
, 16) > 0xFFFF:
1509 # For Offset written in "A.B"
1510 elif VariableOffset
.find('.') > -1:
1511 VariableOffsetList
= VariableOffset
.split(".")
1512 if not (len(VariableOffsetList
) == 2
1513 and IsValidWord(VariableOffsetList
[0])
1514 and IsValidWord(VariableOffsetList
[1])):
1515 FormatCorrect
= False
1517 FormatCorrect
= False
1518 if not FormatCorrect
:
1519 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1522 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1523 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1524 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1526 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1527 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
)]))
1529 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
)
1530 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1531 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1532 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1533 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1535 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1538 self
._PCD
_TYPE
_STRING
_[Type
],
1543 {SkuName
: SkuInfo
},
1546 pcdDecObject
.validateranges
,
1547 pcdDecObject
.validlists
,
1548 pcdDecObject
.expressions
,
1552 for pcd
in Pcds
.values():
1553 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1554 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1555 # Only fix the value while no value provided in DSC file.
1556 for sku
in pcd
.SkuInfoList
.values():
1557 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1558 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1559 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1560 valuefromDec
= pcdDecObject
.DefaultValue
1561 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1562 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1563 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1564 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1565 del(pcd
.SkuInfoList
['COMMON'])
1566 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1567 del(pcd
.SkuInfoList
['COMMON'])
1569 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1570 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1571 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1572 del(pcd
.SkuInfoList
['DEFAULT'])
1574 if pcd
.MaxDatumSize
.strip():
1575 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1578 if pcdDecObject
.DatumType
== 'VOID*':
1579 for (skuname
, skuobj
) in pcd
.SkuInfoList
.items():
1581 if skuobj
.HiiDefaultValue
.startswith("L"):
1582 datalen
= (len(skuobj
.HiiDefaultValue
) - 3 + 1) * 2
1583 elif skuobj
.HiiDefaultValue
.startswith("{"):
1584 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1586 datalen
= len(skuobj
.HiiDefaultValue
) - 2 + 1
1587 if datalen
> MaxSize
:
1589 pcd
.MaxDatumSize
= str(MaxSize
)
1593 ## Retrieve dynamic VPD PCD settings
1595 # @param Type PCD type
1597 # @retval a dict object contains settings of given PCD type
1599 def _GetDynamicVpdPcd(self
, Type
):
1601 SkuObj
= SkuClass(self
.SkuIdentifier
, self
.SkuIds
)
1605 # tdict is a special dict kind of type, used for selecting correct
1606 # PCD settings for certain ARCH and SKU
1608 PcdDict
= tdict(True, 4)
1611 # Find out all possible PCD candidates for self._Arch
1612 RecordList
= self
._RawData
[Type
, self
._Arch
]
1613 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1615 AvailableSkuIdSet
.update({'DEFAULT':0, 'COMMON':0})
1616 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1617 if SkuName
not in AvailableSkuIdSet
:
1618 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The SKUID name %s is not supported by the platform." % SkuName
)
1619 if "." not in TokenSpaceGuid
:
1620 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1621 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1623 # Remove redundant PCD candidates, per the ARCH and SKU
1624 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1625 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1629 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1630 # For the Integer & Boolean type, the optional data can only be InitialValue.
1631 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1632 # until the DEC parser has been called.
1634 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1635 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1636 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1637 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1638 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1639 if MaxDatumSize
.strip():
1640 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1643 if pcdObject
.MaxDatumSize
:
1644 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1647 if CurrentMaxSize
> PcdMaxSize
:
1648 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1650 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1653 self
._PCD
_TYPE
_STRING
_[Type
],
1658 {SkuName
: SkuInfo
},
1662 for pcd
in Pcds
.values():
1663 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1664 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1665 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1666 valuefromDec
= pcdDecObject
.DefaultValue
1667 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
1668 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1669 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1670 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1671 del(pcd
.SkuInfoList
['COMMON'])
1672 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1673 del(pcd
.SkuInfoList
['COMMON'])
1674 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1675 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1676 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1677 del(pcd
.SkuInfoList
['DEFAULT'])
1681 ## Add external modules
1683 # The external modules are mostly those listed in FDF file, which don't
1686 # @param FilePath The path of module description file
1688 def AddModule(self
, FilePath
):
1689 FilePath
= NormPath(FilePath
)
1690 if FilePath
not in self
.Modules
:
1691 Module
= ModuleBuildClassObject()
1692 Module
.MetaFile
= FilePath
1693 self
.Modules
.append(Module
)
1695 ## Add external PCDs
1697 # The external PCDs are mostly those listed in FDF file to specify address
1698 # or offset information.
1700 # @param Name Name of the PCD
1701 # @param Guid Token space guid of the PCD
1702 # @param Value Value of the PCD
1704 def AddPcd(self
, Name
, Guid
, Value
):
1705 if (Name
, Guid
) not in self
.Pcds
:
1706 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1707 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1709 _Macros
= property(_GetMacros
)
1710 Arch
= property(_GetArch
, _SetArch
)
1711 Platform
= property(_GetPlatformName
)
1712 PlatformName
= property(_GetPlatformName
)
1713 Guid
= property(_GetFileGuid
)
1714 Version
= property(_GetVersion
)
1715 DscSpecification
= property(_GetDscSpec
)
1716 OutputDirectory
= property(_GetOutpuDir
)
1717 SupArchList
= property(_GetSupArch
)
1718 BuildTargets
= property(_GetBuildTarget
)
1719 SkuName
= property(_GetSkuName
, _SetSkuName
)
1720 SkuIdentifier
= property(_GetSkuIdentifier
)
1721 AvilableSkuIds
= property(_GetAviableSkuIds
)
1722 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1723 VarCheckFlag
= property(_GetVarCheckFlag
)
1724 FlashDefinition
= property(_GetFdfFile
)
1725 Prebuild
= property(_GetPrebuild
)
1726 Postbuild
= property(_GetPostbuild
)
1727 BuildNumber
= property(_GetBuildNumber
)
1728 MakefileName
= property(_GetMakefileName
)
1729 BsBaseAddress
= property(_GetBsBaseAddress
)
1730 RtBaseAddress
= property(_GetRtBaseAddress
)
1731 LoadFixAddress
= property(_GetLoadFixAddress
)
1732 RFCLanguages
= property(_GetRFCLanguages
)
1733 ISOLanguages
= property(_GetISOLanguages
)
1734 VpdToolGuid
= property(_GetVpdToolGuid
)
1735 SkuIds
= property(_GetSkuIds
)
1736 Modules
= property(_GetModules
)
1737 LibraryInstances
= property(_GetLibraryInstances
)
1738 LibraryClasses
= property(_GetLibraryClasses
)
1739 Pcds
= property(_GetPcds
)
1740 BuildOptions
= property(_GetBuildOptions
)