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
)
161 self
.DefaultStores
= None
162 self
.SkuIdMgr
= SkuClass(self
.SkuName
, self
.SkuIds
)
163 arraystr
= self
.SkuIdMgr
.DumpSkuIdArrary()
166 def __setitem__(self
, key
, value
):
167 self
.__dict
__[self
._PROPERTY
_[key
]] = value
170 def __getitem__(self
, key
):
171 return self
.__dict
__[self
._PROPERTY
_[key
]]
174 def __contains__(self
, key
):
175 return key
in self
._PROPERTY
_
177 ## Set all internal used members of DscBuildData to None
180 self
._PlatformName
= None
183 self
._DscSpecification
= None
184 self
._OutputDirectory
= None
185 self
._SupArchList
= None
186 self
._BuildTargets
= None
188 self
._PcdInfoFlag
= None
189 self
._VarCheckFlag
= None
190 self
._FlashDefinition
= None
191 self
._Prebuild
= None
192 self
._Postbuild
= None
193 self
._BuildNumber
= None
194 self
._MakefileName
= None
195 self
._BsBaseAddress
= None
196 self
._RtBaseAddress
= None
199 self
._LibraryInstances
= None
200 self
._LibraryClasses
= None
203 self
._BuildOptions
= None
204 self
._ModuleTypeOptions
= None
205 self
._LoadFixAddress
= None
206 self
._RFCLanguages
= None
207 self
._ISOLanguages
= None
208 self
._VpdToolGuid
= None
210 self
.DefaultStores
= None
213 ## handle Override Path of Module
214 def _HandleOverridePath(self
):
215 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
216 Macros
= self
._Macros
217 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
218 for Record
in RecordList
:
221 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
222 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
224 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
226 # Check if the source override path exists
227 if not os
.path
.isdir(SourceOverridePath
):
228 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
230 # Add to GlobalData Variables
231 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
233 ## Get current effective macros
234 def _GetMacros(self
):
235 if self
.__Macros
== None:
237 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
238 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
239 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
248 # Changing the default ARCH to another may affect all other information
249 # because all information in a platform may be ARCH-related. That's
250 # why we need to clear all internal used members, in order to cause all
251 # information to be re-retrieved.
253 # @param Value The value of ARCH
255 def _SetArch(self
, Value
):
256 if self
._Arch
== Value
:
261 ## Retrieve all information in [Defines] section
263 # (Retriving all [Defines] information in one-shot is just to save time.)
265 def _GetHeaderInfo(self
):
266 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
267 for Record
in RecordList
:
269 # items defined _PROPERTY_ don't need additional processing
271 # some special items in [Defines] section need special treatment
272 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
273 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
274 if ' ' in self
._OutputDirectory
:
275 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
276 File
=self
.MetaFile
, Line
=Record
[-1],
277 ExtraData
=self
._OutputDirectory
)
278 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
279 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
280 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
282 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
284 elif Name
== TAB_DSC_PREBUILD
:
285 PrebuildValue
= Record
[2]
286 if Record
[2][0] == '"':
287 if Record
[2][-1] != '"':
288 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
289 File
=self
.MetaFile
, Line
=Record
[-1])
290 PrebuildValue
= Record
[2][1:-1]
291 self
._Prebuild
= PrebuildValue
292 elif Name
== TAB_DSC_POSTBUILD
:
293 PostbuildValue
= Record
[2]
294 if Record
[2][0] == '"':
295 if Record
[2][-1] != '"':
296 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
297 File
=self
.MetaFile
, Line
=Record
[-1])
298 PostbuildValue
= Record
[2][1:-1]
299 self
._Postbuild
= PostbuildValue
300 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
301 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
302 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
303 self
._BuildTargets
= GetSplitValueList(Record
[2])
304 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
305 if self
._SkuName
== None:
306 self
._SkuName
= Record
[2]
307 if GlobalData
.gSKUID_CMD
:
308 self
._SkuName
= GlobalData
.gSKUID_CMD
309 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
310 self
._PcdInfoFlag
= Record
[2]
311 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
312 self
._VarCheckFlag
= Record
[2]
313 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
315 self
._LoadFixAddress
= int (Record
[2], 0)
317 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
318 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
319 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
320 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"',
321 File
=self
.MetaFile
, Line
=Record
[-1])
322 LanguageCodes
= Record
[2][1:-1]
323 if not LanguageCodes
:
324 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
325 File
=self
.MetaFile
, Line
=Record
[-1])
326 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
327 # check whether there is empty entries in the list
328 if None in LanguageList
:
329 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
330 File
=self
.MetaFile
, Line
=Record
[-1])
331 self
._RFCLanguages
= LanguageList
332 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
333 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
334 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
335 File
=self
.MetaFile
, Line
=Record
[-1])
336 LanguageCodes
= Record
[2][1:-1]
337 if not LanguageCodes
:
338 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
339 File
=self
.MetaFile
, Line
=Record
[-1])
340 if len(LanguageCodes
) % 3:
341 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
342 File
=self
.MetaFile
, Line
=Record
[-1])
344 for i
in range(0, len(LanguageCodes
), 3):
345 LanguageList
.append(LanguageCodes
[i
:i
+ 3])
346 self
._ISOLanguages
= LanguageList
347 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
349 # try to convert GUID to a real UUID value to see whether the GUID is format
350 # for VPD_TOOL_GUID is correct.
355 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
356 self
._VpdToolGuid
= Record
[2]
358 self
[Name
] = Record
[2]
359 # set _Header to non-None in order to avoid database re-querying
360 self
._Header
= 'DUMMY'
362 ## Retrieve platform name
363 def _GetPlatformName(self
):
364 if self
._PlatformName
== None:
365 if self
._Header
== None:
366 self
._GetHeaderInfo
()
367 if self
._PlatformName
== None:
368 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
369 return self
._PlatformName
371 ## Retrieve file guid
372 def _GetFileGuid(self
):
373 if self
._Guid
== None:
374 if self
._Header
== None:
375 self
._GetHeaderInfo
()
376 if self
._Guid
== None:
377 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
380 ## Retrieve platform version
381 def _GetVersion(self
):
382 if self
._Version
== None:
383 if self
._Header
== None:
384 self
._GetHeaderInfo
()
385 if self
._Version
== None:
386 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
389 ## Retrieve platform description file version
390 def _GetDscSpec(self
):
391 if self
._DscSpecification
== None:
392 if self
._Header
== None:
393 self
._GetHeaderInfo
()
394 if self
._DscSpecification
== None:
395 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
396 return self
._DscSpecification
398 ## Retrieve OUTPUT_DIRECTORY
399 def _GetOutpuDir(self
):
400 if self
._OutputDirectory
== None:
401 if self
._Header
== None:
402 self
._GetHeaderInfo
()
403 if self
._OutputDirectory
== None:
404 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
405 return self
._OutputDirectory
407 ## Retrieve SUPPORTED_ARCHITECTURES
408 def _GetSupArch(self
):
409 if self
._SupArchList
== None:
410 if self
._Header
== None:
411 self
._GetHeaderInfo
()
412 if self
._SupArchList
== None:
413 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
414 return self
._SupArchList
416 ## Retrieve BUILD_TARGETS
417 def _GetBuildTarget(self
):
418 if self
._BuildTargets
== None:
419 if self
._Header
== None:
420 self
._GetHeaderInfo
()
421 if self
._BuildTargets
== None:
422 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
423 return self
._BuildTargets
425 def _GetPcdInfoFlag(self
):
426 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
428 elif self
._PcdInfoFlag
.upper() == 'TRUE':
432 def _GetVarCheckFlag(self
):
433 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
435 elif self
._VarCheckFlag
.upper() == 'TRUE':
440 # # Retrieve SKUID_IDENTIFIER
441 def _GetSkuName(self
):
442 if self
._SkuName
== None:
443 if self
._Header
== None:
444 self
._GetHeaderInfo
()
445 if self
._SkuName
== None:
446 self
._SkuName
= 'DEFAULT'
449 ## Override SKUID_IDENTIFIER
450 def _SetSkuName(self
, Value
):
451 self
._SkuName
= Value
454 def _GetFdfFile(self
):
455 if self
._FlashDefinition
== None:
456 if self
._Header
== None:
457 self
._GetHeaderInfo
()
458 if self
._FlashDefinition
== None:
459 self
._FlashDefinition
= ''
460 return self
._FlashDefinition
462 def _GetPrebuild(self
):
463 if self
._Prebuild
== None:
464 if self
._Header
== None:
465 self
._GetHeaderInfo
()
466 if self
._Prebuild
== None:
468 return self
._Prebuild
470 def _GetPostbuild(self
):
471 if self
._Postbuild
== None:
472 if self
._Header
== None:
473 self
._GetHeaderInfo
()
474 if self
._Postbuild
== None:
476 return self
._Postbuild
478 ## Retrieve FLASH_DEFINITION
479 def _GetBuildNumber(self
):
480 if self
._BuildNumber
== None:
481 if self
._Header
== None:
482 self
._GetHeaderInfo
()
483 if self
._BuildNumber
== None:
484 self
._BuildNumber
= ''
485 return self
._BuildNumber
487 ## Retrieve MAKEFILE_NAME
488 def _GetMakefileName(self
):
489 if self
._MakefileName
== None:
490 if self
._Header
== None:
491 self
._GetHeaderInfo
()
492 if self
._MakefileName
== None:
493 self
._MakefileName
= ''
494 return self
._MakefileName
496 ## Retrieve BsBaseAddress
497 def _GetBsBaseAddress(self
):
498 if self
._BsBaseAddress
== None:
499 if self
._Header
== None:
500 self
._GetHeaderInfo
()
501 if self
._BsBaseAddress
== None:
502 self
._BsBaseAddress
= ''
503 return self
._BsBaseAddress
505 ## Retrieve RtBaseAddress
506 def _GetRtBaseAddress(self
):
507 if self
._RtBaseAddress
== None:
508 if self
._Header
== None:
509 self
._GetHeaderInfo
()
510 if self
._RtBaseAddress
== None:
511 self
._RtBaseAddress
= ''
512 return self
._RtBaseAddress
514 ## Retrieve the top address for the load fix address
515 def _GetLoadFixAddress(self
):
516 if self
._LoadFixAddress
== None:
517 if self
._Header
== None:
518 self
._GetHeaderInfo
()
520 if self
._LoadFixAddress
== None:
521 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
524 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
526 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
529 # If command line defined, should override the value in DSC file.
531 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
533 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
535 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']))
537 if self
._LoadFixAddress
< 0:
538 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
539 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
540 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
542 return self
._LoadFixAddress
544 ## Retrieve RFCLanguage filter
545 def _GetRFCLanguages(self
):
546 if self
._RFCLanguages
== None:
547 if self
._Header
== None:
548 self
._GetHeaderInfo
()
549 if self
._RFCLanguages
== None:
550 self
._RFCLanguages
= []
551 return self
._RFCLanguages
553 ## Retrieve ISOLanguage filter
554 def _GetISOLanguages(self
):
555 if self
._ISOLanguages
== None:
556 if self
._Header
== None:
557 self
._GetHeaderInfo
()
558 if self
._ISOLanguages
== None:
559 self
._ISOLanguages
= []
560 return self
._ISOLanguages
561 ## Retrieve the GUID string for VPD tool
562 def _GetVpdToolGuid(self
):
563 if self
._VpdToolGuid
== None:
564 if self
._Header
== None:
565 self
._GetHeaderInfo
()
566 if self
._VpdToolGuid
== None:
567 self
._VpdToolGuid
= ''
568 return self
._VpdToolGuid
570 ## Retrieve [SkuIds] section information
571 def _GetSkuIds(self
):
572 if self
._SkuIds
== None:
573 self
._SkuIds
= sdict()
574 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
575 for Record
in RecordList
:
576 if Record
[0] in [None, '']:
577 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
578 File
=self
.MetaFile
, Line
=Record
[-1])
579 if Record
[1] in [None, '']:
580 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
581 File
=self
.MetaFile
, Line
=Record
[-1])
582 Pattern
= re
.compile('^[1-9]\d*|0$')
583 if Pattern
.match(Record
[0]) == None:
584 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID number is invalid. The correct format is '{(0-9)} {(1-9)(0-9)+}'",
585 File
=self
.MetaFile
, Line
=Record
[-1])
586 if not IsValidWord(Record
[1]):
587 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_-.)*'",
588 File
=self
.MetaFile
, Line
=Record
[-1])
589 self
._SkuIds
[Record
[1].upper()] = (Record
[0], Record
[1].upper(), Record
[2].upper())
590 if 'DEFAULT' not in self
._SkuIds
:
591 self
._SkuIds
['DEFAULT'] = ("0","DEFAULT","DEFAULT")
592 if 'COMMON' not in self
._SkuIds
:
593 self
._SkuIds
['COMMON'] = ("0","DEFAULT","DEFAULT")
595 def ToInt(self
,intstr
):
596 return int(intstr
,16) if intstr
.upper().startswith("0X") else int(intstr
)
597 def _GetDefaultStores(self
):
598 if self
.DefaultStores
== None:
599 self
.DefaultStores
= sdict()
600 RecordList
= self
._RawData
[MODEL_EFI_DEFAULT_STORES
, self
._Arch
]
601 for Record
in RecordList
:
602 if Record
[0] in [None, '']:
603 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID number',
604 File
=self
.MetaFile
, Line
=Record
[-1])
605 if Record
[1] in [None, '']:
606 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID name',
607 File
=self
.MetaFile
, Line
=Record
[-1])
608 self
.DefaultStores
[Record
[1].upper()] = (self
.ToInt(Record
[0]),Record
[1].upper())
609 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
610 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
611 GlobalData
.gDefaultStores
= self
.DefaultStores
.keys()
612 if GlobalData
.gDefaultStores
:
613 GlobalData
.gDefaultStores
.sort()
614 return self
.DefaultStores
616 ## Retrieve [Components] section information
617 def _GetModules(self
):
618 if self
._Modules
!= None:
621 self
._Modules
= sdict()
622 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
623 Macros
= self
._Macros
624 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
625 for Record
in RecordList
:
626 DuplicatedFile
= False
628 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
632 # check the file validation
633 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
635 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
638 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
639 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
640 DuplicatedFile
= True
642 Module
= ModuleBuildClassObject()
643 Module
.MetaFile
= ModuleFile
645 # get module private library instance
646 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
647 for Record
in RecordList
:
648 LibraryClass
= Record
[0]
649 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
652 # check the file validation
653 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
655 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
658 if LibraryClass
== '' or LibraryClass
== 'NULL':
659 self
._NullLibraryNumber
+= 1
660 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
661 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
662 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
663 if LibraryPath
not in self
.LibraryInstances
:
664 self
.LibraryInstances
.append(LibraryPath
)
666 # get module private PCD setting
667 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
668 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
669 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
670 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
671 TokenList
= GetSplitValueList(Setting
)
672 DefaultValue
= TokenList
[0]
673 if len(TokenList
) > 1:
674 MaxDatumSize
= TokenList
[1]
677 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
678 Pcd
= PcdClassObject(
690 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
692 # get module private build options
693 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
694 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
695 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
696 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
698 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
699 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
701 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
702 if DuplicatedFile
and not RecordList
:
703 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
705 if len(RecordList
) != 1:
706 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
707 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
708 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
709 ModuleFile
.Arch
= self
._Arch
711 self
._Modules
[ModuleFile
] = Module
714 ## Retrieve all possible library instances used in this platform
715 def _GetLibraryInstances(self
):
716 if self
._LibraryInstances
== None:
717 self
._GetLibraryClasses
()
718 return self
._LibraryInstances
720 ## Retrieve [LibraryClasses] information
721 def _GetLibraryClasses(self
):
722 if self
._LibraryClasses
== None:
723 self
._LibraryInstances
= []
725 # tdict is a special dict kind of type, used for selecting correct
726 # library instance for given library class and module type
728 LibraryClassDict
= tdict(True, 3)
729 # track all library class names
730 LibraryClassSet
= set()
731 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
732 Macros
= self
._Macros
733 for Record
in RecordList
:
734 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
735 if LibraryClass
== '' or LibraryClass
== 'NULL':
736 self
._NullLibraryNumber
+= 1
737 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
738 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
739 LibraryClassSet
.add(LibraryClass
)
740 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
741 # check the file validation
742 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
744 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
747 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
748 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
749 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
750 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
751 if LibraryInstance
not in self
._LibraryInstances
:
752 self
._LibraryInstances
.append(LibraryInstance
)
754 # resolve the specific library instance for each class and each module type
755 self
._LibraryClasses
= tdict(True)
756 for LibraryClass
in LibraryClassSet
:
757 # try all possible module types
758 for ModuleType
in SUP_MODULE_LIST
:
759 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
760 if LibraryInstance
== None:
762 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
764 # for Edk style library instances, which are listed in different section
765 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
766 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
767 for Record
in RecordList
:
768 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
770 # check the file validation
771 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
773 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
775 if File
not in self
._LibraryInstances
:
776 self
._LibraryInstances
.append(File
)
778 # we need the module name as the library class name, so we have
779 # to parse it here. (self._Bdb[] will trigger a file parse if it
780 # hasn't been parsed)
782 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
783 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
784 return self
._LibraryClasses
786 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
787 if self
._DecPcds
== None:
790 if GlobalData
.gFdfParser
:
791 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
794 for Inf
in FdfInfList
:
795 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
796 if ModuleFile
in self
._Modules
:
798 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
799 PkgSet
.update(ModuleData
.Packages
)
801 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
804 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
805 EdkLogger
.error('build', PARSER_ERROR
,
806 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
807 File
=self
.MetaFile
, Line
=LineNo
)
808 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
810 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
811 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
812 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
814 if ValueList
[2] == '-1':
815 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
816 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
817 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
819 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
820 except WrnExpression
, Value
:
821 ValueList
[Index
] = Value
.result
822 except EvaluationException
, Excpt
:
823 if hasattr(Excpt
, 'Pcd'):
824 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
825 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
826 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
827 " of the DSC file" % Excpt
.Pcd
,
828 File
=self
.MetaFile
, Line
=LineNo
)
830 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
831 File
=self
.MetaFile
, Line
=LineNo
)
833 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
834 File
=self
.MetaFile
, Line
=LineNo
)
835 if ValueList
[Index
] == 'True':
836 ValueList
[Index
] = '1'
837 elif ValueList
[Index
] == 'False':
838 ValueList
[Index
] = '0'
840 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
842 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
843 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
844 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
845 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
846 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
847 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
850 def _FilterPcdBySkuUsage(self
,Pcds
):
851 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
852 sku_usage
= self
.SkuIdMgr
.SkuUsageType
853 if sku_usage
== SkuClass
.SINGLE
:
856 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
857 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
858 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
862 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
863 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
864 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
866 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
867 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
]]]
868 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
870 for skuid
in pcd
.SkuInfoList
:
871 skuobj
= pcd
.SkuInfoList
.get(skuid
)
872 if "STANDARD" not in skuobj
.DefaultStoreDict
:
873 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
874 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
875 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
878 ## Retrieve all PCD settings in platform
880 if self
._Pcds
== None:
882 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
883 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
884 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
885 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
886 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
887 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
888 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
889 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
890 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
892 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
893 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
894 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
895 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
898 def _dumpPcdInfo(self
,Pcds
):
901 if not pcdobj
.TokenCName
.startswith("Test"):
903 for skuid
in pcdobj
.SkuInfoList
:
904 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
905 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
906 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
908 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
909 ## Retrieve [BuildOptions]
910 def _GetBuildOptions(self
):
911 if self
._BuildOptions
== None:
912 self
._BuildOptions
= sdict()
914 # Retrieve build option for EDKII and EDK style module
916 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
917 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
918 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
919 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
921 # Only flags can be appended
923 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
924 self
._BuildOptions
[CurKey
] = Option
926 self
._BuildOptions
[CurKey
] += ' ' + Option
927 return self
._BuildOptions
929 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
930 if self
._ModuleTypeOptions
== None:
931 self
._ModuleTypeOptions
= sdict()
932 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
934 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
935 DriverType
= '%s.%s' % (Edk
, ModuleType
)
936 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
937 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
938 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
939 if Type
== DriverType
or Type
== CommonDriverType
:
940 Key
= (ToolChainFamily
, ToolChain
, Edk
)
941 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
942 options
[Key
] = Option
944 options
[Key
] += ' ' + Option
945 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
947 def GetStructurePcdInfo(self
, PcdSet
):
948 structure_pcd_data
= {}
950 if (item
[0],item
[1]) not in structure_pcd_data
:
951 structure_pcd_data
[(item
[0],item
[1])] = []
952 structure_pcd_data
[(item
[0],item
[1])].append(item
)
954 return structure_pcd_data
956 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
958 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
959 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
960 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
961 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
962 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
963 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
966 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
967 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
968 SkuIds
.update({'DEFAULT':0})
969 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
972 # Find out all possible PCD candidates for self._Arch
975 for Type
in TypeList
:
976 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
978 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
979 SkuName
= SkuName
.upper()
980 default_store
= default_store
.upper()
981 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
982 if SkuName
not in SkuIds
:
985 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
986 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
988 # handle pcd value override
989 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
991 for str_pcd
in StrPcdSet
:
992 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
993 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
995 str_pcd_obj_str
= StructurePcd()
996 str_pcd_obj_str
.copy(str_pcd_dec
)
998 str_pcd_obj_str
.copy(str_pcd_obj
)
999 if str_pcd_obj
.DefaultValue
:
1000 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1001 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1002 if str_pcd_data
[3] in SkuIds
:
1003 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
,LineNo
=str_pcd_data
[5])
1004 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1006 EdkLogger
.error('build', PARSER_ERROR
,
1007 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1008 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1009 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1010 for Pcd
in self
._DecPcds
:
1011 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1012 if Pcd
not in S_pcd_set
:
1013 str_pcd_obj_str
= StructurePcd()
1014 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1015 str_pcd_obj
= Pcds
.get(Pcd
, None)
1017 str_pcd_obj_str
.copy(str_pcd_obj
)
1018 if str_pcd_obj
.DefaultValue
:
1019 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1020 S_pcd_set
[Pcd
] = str_pcd_obj_str
1022 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1023 for stru_pcd
in S_pcd_set
.values():
1024 if stru_pcd
.Type
not in DynamicPcdType
:
1026 for skuid
in SkuIds
:
1027 if skuid
in stru_pcd
.SkuOverrideValues
:
1029 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1031 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1032 if nextskuid
== "DEFAULT":
1035 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1036 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
})
1037 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1038 for skuid
in SkuIds
:
1041 if skuid
not in stru_pcd
.SkuOverrideValues
:
1042 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1043 if nextskuid
== "DEFAULT":
1046 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1049 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1050 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1052 for defaultstoreid
in DefaultStores
:
1053 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1054 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1056 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1058 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1059 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1060 if str_pcd_obj
is None:
1061 print PcdName
, PcdGuid
1063 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1064 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1065 if skuname
not in str_pcd_obj
.SkuInfoList
:
1066 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1068 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1069 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1070 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1071 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1072 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1073 str_pcd_obj
.DefaultValue
= PcdValue
1075 if skuname
not in str_pcd_obj
.SkuInfoList
:
1076 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1078 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1079 if nextskuid
== "DEFAULT":
1082 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1083 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
)
1084 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1085 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1087 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1088 for str_pcd_obj
in S_pcd_set
.values():
1089 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1090 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1092 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1093 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1094 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1095 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1097 for str_pcd_obj
in S_pcd_set
.values():
1099 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1100 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1104 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1105 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1106 del(pcd
.SkuInfoList
['COMMON'])
1107 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1108 del(pcd
.SkuInfoList
['COMMON'])
1110 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1113 ## Retrieve non-dynamic PCD settings
1115 # @param Type PCD type
1117 # @retval a dict object contains settings of given PCD type
1119 def _GetPcd(self
, Type
):
1122 # tdict is a special dict kind of type, used for selecting correct
1123 # PCD settings for certain ARCH
1125 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1127 PcdDict
= tdict(True, 3)
1129 # Find out all possible PCD candidates for self._Arch
1130 RecordList
= self
._RawData
[Type
, self
._Arch
]
1131 PcdValueDict
= sdict()
1132 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1133 SkuName
= SkuName
.upper()
1134 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1135 if SkuName
not in AvailableSkuIdSet
:
1136 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1137 File
=self
.MetaFile
, Line
=Dummy5
)
1138 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1139 if "." not in TokenSpaceGuid
:
1140 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1141 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1143 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1144 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1147 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1148 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1149 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1151 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1153 PcdsKeys
= PcdValueDict
.keys()
1154 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1156 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1160 if 'COMMON' in PcdSetting
:
1161 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1162 if 'DEFAULT' in PcdSetting
:
1163 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1164 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1165 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1167 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1170 self
._PCD
_TYPE
_STRING
_[Type
],
1183 def __UNICODE2OCTList(self
,Value
):
1184 Value
= Value
.strip()
1188 Temp
= '%04X' % ord(Item
)
1189 List
.append('0x' + Temp
[2:4])
1190 List
.append('0x' + Temp
[0:2])
1194 def __STRING2OCTList(self
,Value
):
1196 Value
= Value
.strip('"')
1198 Temp
= '%02X' % ord(char
)
1199 OCTList
.append('0x' + Temp
)
1200 OCTList
.append('0x00')
1203 def GetStructurePcdMaxSize(self
, str_pcd
):
1204 pcd_default_value
= str_pcd
.DefaultValue
1205 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()]
1206 sku_values
.append(pcd_default_value
)
1208 def get_length(value
):
1209 Value
= value
.strip()
1210 if Value
.startswith('GUID') and Value
.endswith(')'):
1212 if Value
.startswith('L"') and Value
.endswith('"'):
1213 return len(Value
[2:-1])
1214 if Value
[0] == '"' and Value
[-1] == '"':
1215 return len(Value
) - 2
1216 if Value
[0] == '{' and Value
[-1] == '}':
1217 return len(Value
.split(","))
1218 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1219 return len(list(Value
[2:-1]))
1220 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1221 return len(Value
) - 2
1224 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1226 def IsFieldValueAnArray (self
, Value
):
1227 Value
= Value
.strip()
1228 if Value
.startswith('GUID') and Value
.endswith(')'):
1230 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1232 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1234 if Value
[0] == '{' and Value
[-1] == '}':
1236 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1237 print 'foo = ', list(Value
[2:-1])
1239 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1240 print 'bar = ', list(Value
[1:-1])
1244 def ExecuteCommand (self
, Command
):
1246 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1248 print 'ERROR: Can not execute command:', Command
1250 Result
= Process
.communicate()
1251 if Process
.returncode
<> 0:
1252 print 'ERROR: Can not collect output from command:', Command
1253 return Result
[0], Result
[1]
1255 def IntToCString(self
, Value
, ValueSize
):
1257 if not isinstance (Value
, str):
1258 for Index
in range(0, ValueSize
):
1259 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1261 Result
= Result
+ '"'
1264 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1265 OverrideValues
= {DefaultStoreName
:""}
1266 if Pcd
.SkuOverrideValues
:
1267 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1268 for DefaultStoreName
in OverrideValues
.keys():
1269 CApp
= CApp
+ 'void\n'
1270 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1271 CApp
= CApp
+ ' void\n'
1272 CApp
= CApp
+ ' )\n'
1274 CApp
= CApp
+ ' UINT32 Size;\n'
1275 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1276 CApp
= CApp
+ ' CHAR8 *Value;\n'
1277 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1278 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1279 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1282 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1283 PcdDefaultValue
= StringToArray(Pcd
.DefaultValue
)
1285 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1288 # Get current PCD value and size
1290 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1293 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1294 # the correct value. For structures with a flexible array member, the flexible
1295 # array member is detected, and the size is based on the highest index used with
1296 # the flexible array member. The flexible array member must be the last field
1297 # in a structure. The size formula for this case is:
1298 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1300 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1301 for FieldList
in [Pcd
.DefaultValues
, OverrideValues
.get(DefaultStoreName
)]:
1304 for FieldName
in FieldList
:
1305 FieldName
= "." + FieldName
1306 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1308 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1309 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."));
1312 while '[' in FieldName
:
1313 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1314 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1315 FieldName
= FieldName
.split(']', 1)[1]
1316 FieldName
= NewFieldName
+ FieldName
1317 while '[' in FieldName
:
1318 FieldName
= FieldName
.rsplit('[', 1)[0]
1319 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1322 # Allocate and zero buffer for the PCD
1323 # Must handle cases where current value is smaller, larger, or same size
1324 # Always keep that larger one as the current size
1326 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1327 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1328 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1331 # Copy current PCD value into allocated buffer.
1333 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1336 # Assign field values in PCD
1338 for FieldList
in [Pcd
.DefaultValues
, Pcd
.DefaultFromDSC
,OverrideValues
.get(DefaultStoreName
)]:
1341 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1342 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1343 Value
, ValueSize
= ParseFieldValue (FieldList
)
1344 if isinstance(Value
, str):
1345 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1348 # Use memcpy() to copy value into field
1350 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1351 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1354 for FieldName
in FieldList
:
1355 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1357 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1359 print FieldList
[FieldName
][0]
1360 if isinstance(Value
, str):
1361 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1364 # Use memcpy() to copy value into field
1366 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1367 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1368 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1371 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1373 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1376 # Set new PCD value and size
1378 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1383 CApp
= CApp
+ ' free (Pcd);\n'
1386 return InitByteValue
, CApp
1388 def GenerateByteArrayValue (self
, StructuredPcds
):
1390 # Generate/Compile/Run C application to determine if there are any flexible array members
1392 if not StructuredPcds
:
1396 CApp
= PcdMainCHeader
1399 for PcdName
in StructuredPcds
:
1400 Pcd
= StructuredPcds
[PcdName
]
1401 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1402 if IncludeFile
not in Includes
:
1403 Includes
[IncludeFile
] = True
1404 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1407 for PcdName
in StructuredPcds
:
1408 Pcd
= StructuredPcds
[PcdName
]
1409 if not Pcd
.SkuOverrideValues
:
1410 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1412 for SkuName
in Pcd
.SkuOverrideValues
:
1413 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1414 Pcd
= StructuredPcds
[PcdName
]
1415 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1417 CApp
= CApp
+ 'VOID\n'
1418 CApp
= CApp
+ 'PcdEntryPoint(\n'
1419 CApp
= CApp
+ ' VOID\n'
1420 CApp
= CApp
+ ' )\n'
1422 for Pcd
in StructuredPcds
.values():
1423 if not Pcd
.SkuOverrideValues
:
1424 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1426 for SkuName
in Pcd
.SkuOverrideValues
:
1427 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1428 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1431 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1433 if not os
.path
.exists(self
.OutputPath
):
1434 os
.makedirs(self
.OutputPath
)
1435 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1436 File
= open (CAppBaseFileName
+ '.c', 'w')
1440 MakeApp
= PcdMakefileHeader
1441 if sys
.platform
== "win32":
1442 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1444 MakeApp
= MakeApp
+ PcdGccMakefile
1445 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1446 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable\n' + 'INCLUDE +='
1449 for Cache
in self
._Bdb
._CACHE
_.values():
1450 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1453 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1454 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1457 for Pcd
in StructuredPcds
.values():
1458 for PackageDec
in Pcd
.PackageDecs
:
1459 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1460 if not os
.path
.exists(Package
):
1461 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1462 if Package
not in PcdDependDEC
:
1463 PcdDependDEC
.append(Package
)
1465 if PlatformInc
and PcdDependDEC
:
1466 for pkg
in PcdDependDEC
:
1467 if pkg
in PlatformInc
:
1468 for inc
in PlatformInc
[pkg
]:
1469 MakeApp
+= '-I' + str(inc
) + ' '
1470 MakeApp
= MakeApp
+ '\n'
1471 if sys
.platform
== "win32":
1472 MakeApp
= MakeApp
+ PcdMakefileEnd
1473 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1474 File
= open (MakeFileName
, 'w')
1478 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1479 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1480 File
= open (InputValueFile
, 'w')
1481 File
.write(InitByteValue
)
1485 if sys
.platform
== "win32":
1486 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1489 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1491 Messages
= Messages
.split('\n')
1492 for Message
in Messages
:
1493 if " error" in Message
:
1494 FileInfo
= Message
.strip().split('(')
1495 if len (FileInfo
) > 1:
1496 FileName
= FileInfo
[0]
1497 FileLine
= FileInfo
[1].split (')')[0]
1499 FileInfo
= Message
.strip().split(':')
1500 FileName
= FileInfo
[0]
1501 FileLine
= FileInfo
[1]
1503 File
= open (FileName
, 'r')
1504 FileData
= File
.readlines()
1506 error_line
= FileData
[int (FileLine
) - 1]
1507 if r
"//" in error_line
:
1508 c_line
,dsc_line
= error_line
.split(r
"//")
1510 dsc_line
= error_line
1512 message_itmes
= Message
.split(":")
1514 for item
in message_itmes
:
1515 if "PcdValueInit.c" in item
:
1516 Index
= message_itmes
.index(item
)
1517 message_itmes
[Index
] = dsc_line
.strip()
1520 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[Index
:]))
1522 PcdValueInitExe
= PcdValueInitName
1523 if not sys
.platform
== "win32":
1524 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1526 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1527 File
= open (OutputValueFile
, 'r')
1528 FileBuffer
= File
.readlines()
1531 StructurePcdSet
= []
1532 for Pcd
in FileBuffer
:
1533 PcdValue
= Pcd
.split ('|')
1534 PcdInfo
= PcdValue
[0].split ('.')
1535 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1536 return StructurePcdSet
1538 ## Retrieve dynamic PCD settings
1540 # @param Type PCD type
1542 # @retval a dict object contains settings of given PCD type
1544 def _GetDynamicPcd(self
, Type
):
1549 # tdict is a special dict kind of type, used for selecting correct
1550 # PCD settings for certain ARCH and SKU
1552 PcdDict
= tdict(True, 4)
1554 # Find out all possible PCD candidates for self._Arch
1555 RecordList
= self
._RawData
[Type
, self
._Arch
]
1556 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1559 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1560 SkuName
= SkuName
.upper()
1561 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1562 if SkuName
not in AvailableSkuIdSet
:
1563 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1564 File
=self
.MetaFile
, Line
=Dummy5
)
1565 if "." not in TokenSpaceGuid
:
1566 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1567 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1569 # Remove redundant PCD candidates, per the ARCH and SKU
1570 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1572 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1576 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1577 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1578 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1579 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1580 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1581 if MaxDatumSize
.strip():
1582 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1585 if pcdObject
.MaxDatumSize
:
1586 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1589 if CurrentMaxSize
> PcdMaxSize
:
1590 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1592 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1595 self
._PCD
_TYPE
_STRING
_[Type
],
1600 {SkuName
: SkuInfo
},
1605 for pcd
in Pcds
.values():
1606 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1607 # Only fix the value while no value provided in DSC file.
1608 for sku
in pcd
.SkuInfoList
.values():
1609 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1610 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1611 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1612 valuefromDec
= pcdDecObject
.DefaultValue
1613 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1614 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1615 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1616 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1617 del(pcd
.SkuInfoList
['COMMON'])
1618 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1619 del(pcd
.SkuInfoList
['COMMON'])
1621 map(self
.FilterSkuSettings
,Pcds
.values())
1625 def FilterSkuSettings(self
, PcdObj
):
1627 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1628 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1629 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1630 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1631 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1632 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1634 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1635 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1640 def CompareVarAttr(self
, Attr1
, Attr2
):
1641 if not Attr1
or not Attr2
: # for empty string
1643 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1644 Attr1Set
= set(Attr1s
)
1645 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1646 Attr2Set
= set(Attr2s
)
1647 if Attr2Set
== Attr1Set
:
1651 def CompletePcdValues(self
,PcdSet
):
1653 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1654 SkuIds
= set([(skuid
,skuobj
.SkuId
) for pcdobj
in PcdSet
.values() for skuid
,skuobj
in pcdobj
.SkuInfoList
.items()])
1655 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1656 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1657 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1658 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1659 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1660 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1661 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1662 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1663 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1664 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1666 PcdType
= PcdObj
.Type
1667 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1668 for skuid
in PcdObj
.SkuInfoList
:
1669 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1670 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1671 for defaultstorename
in DefaultStores
:
1672 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1673 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1674 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1675 for skuname
,skuid
in SkuIds
:
1676 if skuname
not in PcdObj
.SkuInfoList
:
1677 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1678 while nextskuid
not in PcdObj
.SkuInfoList
:
1679 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1680 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1681 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1682 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1683 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1684 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1685 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1687 ## Retrieve dynamic HII PCD settings
1689 # @param Type PCD type
1691 # @retval a dict object contains settings of given PCD type
1693 def _GetDynamicHiiPcd(self
, Type
):
1699 # tdict is a special dict kind of type, used for selecting correct
1700 # PCD settings for certain ARCH and SKU
1702 PcdDict
= tdict(True, 5)
1704 RecordList
= self
._RawData
[Type
, self
._Arch
]
1705 # Find out all possible PCD candidates for self._Arch
1706 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1707 DefaultStoresDefine
= self
._GetDefaultStores
()
1709 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1710 SkuName
= SkuName
.upper()
1711 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1712 DefaultStore
= DefaultStore
.upper()
1713 if DefaultStore
== "COMMON":
1714 DefaultStore
= "STANDARD"
1715 if SkuName
not in AvailableSkuIdSet
:
1716 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1717 File
=self
.MetaFile
, Line
=Dummy5
)
1718 if DefaultStore
not in DefaultStoresDefine
:
1719 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1720 File
=self
.MetaFile
, Line
=Dummy5
)
1721 if "." not in TokenSpaceGuid
:
1722 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1723 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1726 # Remove redundant PCD candidates, per the ARCH and SKU
1727 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1729 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1732 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1734 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1736 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1737 ExtraData
="[%s]" % VarAttribute
)
1739 FormatCorrect
= True
1740 if VariableOffset
.isdigit():
1741 if int(VariableOffset
, 10) > 0xFFFF:
1743 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1744 if int(VariableOffset
, 16) > 0xFFFF:
1746 # For Offset written in "A.B"
1747 elif VariableOffset
.find('.') > -1:
1748 VariableOffsetList
= VariableOffset
.split(".")
1749 if not (len(VariableOffsetList
) == 2
1750 and IsValidWord(VariableOffsetList
[0])
1751 and IsValidWord(VariableOffsetList
[1])):
1752 FormatCorrect
= False
1754 FormatCorrect
= False
1755 if not FormatCorrect
:
1756 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1759 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1760 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1761 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1763 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1764 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
)]))
1766 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1767 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1768 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1769 if SkuName
in pcdObject
.SkuInfoList
:
1770 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1771 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1773 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1774 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1776 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1777 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1780 self
._PCD
_TYPE
_STRING
_[Type
],
1785 {SkuName
: SkuInfo
},
1788 pcdDecObject
.validateranges
,
1789 pcdDecObject
.validlists
,
1790 pcdDecObject
.expressions
,
1794 for pcd
in Pcds
.values():
1795 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1796 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1797 # Only fix the value while no value provided in DSC file.
1798 for sku
in pcd
.SkuInfoList
.values():
1799 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1800 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1801 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1802 valuefromDec
= pcdDecObject
.DefaultValue
1803 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1804 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1805 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1806 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1807 del(pcd
.SkuInfoList
['COMMON'])
1808 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1809 del(pcd
.SkuInfoList
['COMMON'])
1811 if pcd
.MaxDatumSize
.strip():
1812 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1815 if pcdDecObject
.DatumType
== 'VOID*':
1816 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1818 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1819 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1820 if datalen
> MaxSize
:
1822 for defaultst
in skuobj
.DefaultStoreDict
:
1823 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1824 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1825 pcd
.MaxDatumSize
= str(MaxSize
)
1826 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1828 invalidpcd
= ",".join(invalidhii
)
1829 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
)
1831 map(self
.FilterSkuSettings
,Pcds
.values())
1835 def CheckVariableNameAssignment(self
,Pcds
):
1837 for pcdname
in Pcds
:
1839 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1840 if len(varnameset
) > 1:
1841 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1843 return False,invalidhii
1846 ## Retrieve dynamic VPD PCD settings
1848 # @param Type PCD type
1850 # @retval a dict object contains settings of given PCD type
1852 def _GetDynamicVpdPcd(self
, Type
):
1857 # tdict is a special dict kind of type, used for selecting correct
1858 # PCD settings for certain ARCH and SKU
1860 PcdDict
= tdict(True, 4)
1863 # Find out all possible PCD candidates for self._Arch
1864 RecordList
= self
._RawData
[Type
, self
._Arch
]
1865 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1867 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1868 SkuName
= SkuName
.upper()
1869 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1870 if SkuName
not in AvailableSkuIdSet
:
1871 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1872 File
=self
.MetaFile
, Line
=Dummy5
)
1873 if "." not in TokenSpaceGuid
:
1874 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1875 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1877 # Remove redundant PCD candidates, per the ARCH and SKU
1878 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1879 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1883 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1884 # For the Integer & Boolean type, the optional data can only be InitialValue.
1885 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1886 # until the DEC parser has been called.
1888 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1889 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
1890 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1891 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1892 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1893 if MaxDatumSize
.strip():
1894 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1897 if pcdObject
.MaxDatumSize
:
1898 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1901 if CurrentMaxSize
> PcdMaxSize
:
1902 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1904 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1907 self
._PCD
_TYPE
_STRING
_[Type
],
1912 {SkuName
: SkuInfo
},
1916 for pcd
in Pcds
.values():
1917 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1918 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1919 # Only fix the value while no value provided in DSC file.
1920 for sku
in pcd
.SkuInfoList
.values():
1921 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1922 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1923 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1924 valuefromDec
= pcdDecObject
.DefaultValue
1925 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
1926 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1927 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1928 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1929 del(pcd
.SkuInfoList
['COMMON'])
1930 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1931 del(pcd
.SkuInfoList
['COMMON'])
1934 map(self
.FilterSkuSettings
,Pcds
.values())
1937 ## Add external modules
1939 # The external modules are mostly those listed in FDF file, which don't
1942 # @param FilePath The path of module description file
1944 def AddModule(self
, FilePath
):
1945 FilePath
= NormPath(FilePath
)
1946 if FilePath
not in self
.Modules
:
1947 Module
= ModuleBuildClassObject()
1948 Module
.MetaFile
= FilePath
1949 self
.Modules
.append(Module
)
1951 ## Add external PCDs
1953 # The external PCDs are mostly those listed in FDF file to specify address
1954 # or offset information.
1956 # @param Name Name of the PCD
1957 # @param Guid Token space guid of the PCD
1958 # @param Value Value of the PCD
1960 def AddPcd(self
, Name
, Guid
, Value
):
1961 if (Name
, Guid
) not in self
.Pcds
:
1962 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1963 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1965 _Macros
= property(_GetMacros
)
1966 Arch
= property(_GetArch
, _SetArch
)
1967 Platform
= property(_GetPlatformName
)
1968 PlatformName
= property(_GetPlatformName
)
1969 Guid
= property(_GetFileGuid
)
1970 Version
= property(_GetVersion
)
1971 DscSpecification
= property(_GetDscSpec
)
1972 OutputDirectory
= property(_GetOutpuDir
)
1973 SupArchList
= property(_GetSupArch
)
1974 BuildTargets
= property(_GetBuildTarget
)
1975 SkuName
= property(_GetSkuName
, _SetSkuName
)
1976 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1977 VarCheckFlag
= property(_GetVarCheckFlag
)
1978 FlashDefinition
= property(_GetFdfFile
)
1979 Prebuild
= property(_GetPrebuild
)
1980 Postbuild
= property(_GetPostbuild
)
1981 BuildNumber
= property(_GetBuildNumber
)
1982 MakefileName
= property(_GetMakefileName
)
1983 BsBaseAddress
= property(_GetBsBaseAddress
)
1984 RtBaseAddress
= property(_GetRtBaseAddress
)
1985 LoadFixAddress
= property(_GetLoadFixAddress
)
1986 RFCLanguages
= property(_GetRFCLanguages
)
1987 ISOLanguages
= property(_GetISOLanguages
)
1988 VpdToolGuid
= property(_GetVpdToolGuid
)
1989 SkuIds
= property(_GetSkuIds
)
1990 Modules
= property(_GetModules
)
1991 LibraryInstances
= property(_GetLibraryInstances
)
1992 LibraryClasses
= property(_GetLibraryClasses
)
1993 Pcds
= property(_GetPcds
)
1994 BuildOptions
= property(_GetBuildOptions
)