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
)
809 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
810 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
811 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
812 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
814 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
815 except WrnExpression
, Value
:
816 ValueList
[Index
] = Value
.result
817 except EvaluationException
, Excpt
:
818 if hasattr(Excpt
, 'Pcd'):
819 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
820 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
821 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
822 " of the DSC file" % Excpt
.Pcd
,
823 File
=self
.MetaFile
, Line
=LineNo
)
825 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
826 File
=self
.MetaFile
, Line
=LineNo
)
828 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
829 File
=self
.MetaFile
, Line
=LineNo
)
830 if ValueList
[Index
] == 'True':
831 ValueList
[Index
] = '1'
832 elif ValueList
[Index
] == 'False':
833 ValueList
[Index
] = '0'
835 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
837 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
838 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
841 def _FilterPcdBySkuUsage(self
,Pcds
):
842 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
843 sku_usage
= self
.SkuIdMgr
.SkuUsageType
844 if sku_usage
== SkuClass
.SINGLE
:
847 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
848 if type(pcd
) is StructurePcd
and pcd
.OverrideValues
:
849 Pcds
[pcdname
].OverrideValues
= {"DEFAULT":pcd
.OverrideValues
[skuid
] for skuid
in pcd
.OverrideValues
if skuid
in available_sku
}
853 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
854 if type(pcd
) is StructurePcd
and pcd
.OverrideValues
:
855 Pcds
[pcdname
].OverrideValues
= {skuid
:pcd
.OverrideValues
[skuid
] for skuid
in pcd
.OverrideValues
if skuid
in available_sku
}
857 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
858 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
]]]
859 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
861 for skuid
in pcd
.SkuInfoList
:
862 skuobj
= pcd
.SkuInfoList
.get(skuid
)
863 if "STANDARD" not in skuobj
.DefaultStoreDict
:
864 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
865 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
866 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
869 ## Retrieve all PCD settings in platform
871 if self
._Pcds
== None:
873 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
874 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
875 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
876 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
877 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
878 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
879 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
880 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
881 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
883 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
884 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
885 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
886 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
889 def _dumpPcdInfo(self
,Pcds
):
892 if not pcdobj
.TokenCName
.startswith("Test"):
894 for skuid
in pcdobj
.SkuInfoList
:
895 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
896 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
897 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
899 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
900 ## Retrieve [BuildOptions]
901 def _GetBuildOptions(self
):
902 if self
._BuildOptions
== None:
903 self
._BuildOptions
= sdict()
905 # Retrieve build option for EDKII and EDK style module
907 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
908 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
909 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
910 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
912 # Only flags can be appended
914 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
915 self
._BuildOptions
[CurKey
] = Option
917 self
._BuildOptions
[CurKey
] += ' ' + Option
918 return self
._BuildOptions
920 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
921 if self
._ModuleTypeOptions
== None:
922 self
._ModuleTypeOptions
= sdict()
923 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
925 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
926 DriverType
= '%s.%s' % (Edk
, ModuleType
)
927 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
928 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
929 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
930 if Type
== DriverType
or Type
== CommonDriverType
:
931 Key
= (ToolChainFamily
, ToolChain
, Edk
)
932 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
933 options
[Key
] = Option
935 options
[Key
] += ' ' + Option
936 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
938 def GetStructurePcdInfo(self
, PcdSet
):
939 structure_pcd_data
= {}
941 if (item
[0],item
[1]) not in structure_pcd_data
:
942 structure_pcd_data
[(item
[0],item
[1])] = []
943 structure_pcd_data
[(item
[0],item
[1])].append(item
)
945 return structure_pcd_data
947 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
949 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
950 SkuIds
= set([skuid
for pcdobj
in AllPcds
.values() for skuid
in pcdobj
.SkuInfoList
.keys()])
951 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
954 # Find out all possible PCD candidates for self._Arch
957 for Type
in TypeList
:
958 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
960 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
961 SkuName
= SkuName
.upper()
962 default_store
= default_store
.upper()
963 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
964 if SkuName
not in SkuIds
:
967 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
968 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
970 # handle pcd value override
971 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
973 for str_pcd
in StrPcdSet
:
974 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
975 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
977 str_pcd_obj_str
= StructurePcd()
978 str_pcd_obj_str
.copy(str_pcd_dec
)
980 str_pcd_obj_str
.copy(str_pcd_obj
)
981 if str_pcd_obj
.DefaultValue
:
982 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
983 for str_pcd_data
in StrPcdSet
[str_pcd
]:
984 if str_pcd_data
[3] in SkuIds
:
985 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])
986 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
988 EdkLogger
.error('build', PARSER_ERROR
,
989 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
990 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
991 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
992 for Pcd
in self
._DecPcds
:
993 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
994 if Pcd
not in S_pcd_set
:
995 str_pcd_obj_str
= StructurePcd()
996 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
997 str_pcd_obj
= Pcds
.get(Pcd
, None)
999 str_pcd_obj_str
.copy(str_pcd_obj
)
1000 if str_pcd_obj
.DefaultValue
:
1001 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1002 S_pcd_set
[Pcd
] = str_pcd_obj_str
1004 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1005 for stru_pcd
in S_pcd_set
.values():
1006 if stru_pcd
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1007 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1008 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1009 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1010 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1011 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1013 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1014 for skuid
in SkuIds
:
1017 if skuid
not in stru_pcd
.SkuOverrideValues
:
1018 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1019 if nextskuid
== "DEFAULT":
1022 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1023 stru_pcd
.SkuOverrideValues
[skuid
] = {}
1026 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1027 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1029 for defaultstoreid
in DefaultStores
:
1030 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1031 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1032 for skuid
in SkuIds
:
1033 if skuid
in stru_pcd
.SkuOverrideValues
:
1035 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1037 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1038 if nextskuid
== "DEFAULT":
1041 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1042 stru_pcd
.SkuOverrideValues
[skuid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
]) if not NoDefault
else copy
.deepcopy({defaultstorename
: stru_pcd
.DefaultValues
for defaultstorename
in DefaultStores
})
1043 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1045 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1046 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1047 if str_pcd_obj
is None:
1049 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1050 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1051 if skuname
not in str_pcd_obj
.SkuInfoList
:
1052 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1054 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1055 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1056 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1057 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1058 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1059 str_pcd_obj
.DefaultValue
= PcdValue
1061 if skuname
not in str_pcd_obj
.SkuInfoList
:
1062 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], DefaultValue
=PcdValue
)
1064 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1065 for str_pcd_obj
in S_pcd_set
.values():
1066 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1067 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1069 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1070 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1071 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1072 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1074 for str_pcd_obj
in S_pcd_set
.values():
1076 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1077 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1081 ## Retrieve non-dynamic PCD settings
1083 # @param Type PCD type
1085 # @retval a dict object contains settings of given PCD type
1087 def _GetPcd(self
, Type
):
1090 # tdict is a special dict kind of type, used for selecting correct
1091 # PCD settings for certain ARCH
1093 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1095 PcdDict
= tdict(True, 3)
1097 # Find out all possible PCD candidates for self._Arch
1098 RecordList
= self
._RawData
[Type
, self
._Arch
]
1099 PcdValueDict
= sdict()
1100 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1101 SkuName
= SkuName
.upper()
1102 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1103 if SkuName
not in AvailableSkuIdSet
:
1104 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1105 File
=self
.MetaFile
, Line
=Dummy5
)
1106 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1107 if "." not in TokenSpaceGuid
:
1108 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1109 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1111 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1112 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1115 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1116 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1117 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1119 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1121 PcdsKeys
= PcdValueDict
.keys()
1122 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1124 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1128 if 'COMMON' in PcdSetting
:
1129 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1130 if 'DEFAULT' in PcdSetting
:
1131 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1132 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1133 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1135 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1138 self
._PCD
_TYPE
_STRING
_[Type
],
1151 def __UNICODE2OCTList(self
,Value
):
1152 Value
= Value
.strip()
1156 Temp
= '%04X' % ord(Item
)
1157 List
.append('0x' + Temp
[2:4])
1158 List
.append('0x' + Temp
[0:2])
1162 def __STRING2OCTList(self
,Value
):
1164 Value
= Value
.strip('"')
1166 Temp
= '%02X' % ord(char
)
1167 OCTList
.append('0x' + Temp
)
1168 OCTList
.append('0x00')
1171 def GetStructurePcdMaxSize(self
, str_pcd
):
1172 pcd_default_value
= str_pcd
.DefaultValue
1173 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()]
1174 sku_values
.append(pcd_default_value
)
1176 def get_length(value
):
1177 Value
= value
.strip()
1178 if Value
.startswith('GUID') and Value
.endswith(')'):
1180 if Value
.startswith('L"') and Value
.endswith('"'):
1181 return len(Value
[2:-1])
1182 if Value
[0] == '"' and Value
[-1] == '"':
1183 return len(Value
) - 2
1184 if Value
[0] == '{' and Value
[-1] == '}':
1185 return len(Value
.split(","))
1186 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1187 return len(list(Value
[2:-1]))
1188 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1189 return len(Value
) - 2
1192 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1194 def IsFieldValueAnArray (self
, Value
):
1195 Value
= Value
.strip()
1196 if Value
.startswith('GUID') and Value
.endswith(')'):
1198 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1200 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1202 if Value
[0] == '{' and Value
[-1] == '}':
1204 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1205 print 'foo = ', list(Value
[2:-1])
1207 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1208 print 'bar = ', list(Value
[1:-1])
1212 def ExecuteCommand (self
, Command
):
1214 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1216 print 'ERROR: Can not execute command:', Command
1218 Result
= Process
.communicate()
1219 if Process
.returncode
<> 0:
1220 print 'ERROR: Can not collect output from command:', Command
1221 return Result
[0], Result
[1]
1223 def IntToCString(self
, Value
, ValueSize
):
1225 if not isinstance (Value
, str):
1226 for Index
in range(0, ValueSize
):
1227 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1229 Result
= Result
+ '"'
1232 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1233 OverrideValues
= {DefaultStoreName
:""}
1234 if Pcd
.SkuOverrideValues
:
1235 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1236 for DefaultStoreName
in OverrideValues
.keys():
1237 CApp
= CApp
+ 'void\n'
1238 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1239 CApp
= CApp
+ ' void\n'
1240 CApp
= CApp
+ ' )\n'
1242 CApp
= CApp
+ ' UINT32 Size;\n'
1243 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1244 CApp
= CApp
+ ' UINT8 *Value;\n'
1245 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1246 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1247 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1249 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1250 if Pcd
.DefaultValue
.startswith('L"') and Pcd
.DefaultValue
.endswith('"'):
1251 PcdDefaultValue
= "{" + ",".join(self
.__UNICODE
2OCTList
(Pcd
.DefaultValue
)) + "}"
1252 elif Pcd
.DefaultValue
.startswith('"') and Pcd
.DefaultValue
.endswith('"'):
1253 PcdDefaultValue
= "{" + ",".join(self
.__STRING
2OCTList
(Pcd
.DefaultValue
)) + "}"
1255 PcdDefaultValue
= Pcd
.DefaultValue
1256 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1259 # Get current PCD value and size
1261 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1264 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1265 # the correct value. For structures with a flexible array member, the flexible
1266 # array member is detected, and the size is based on the highest index used with
1267 # the flexible array member. The flexible array member must be the last field
1268 # in a structure. The size formula for this case is:
1269 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1271 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1272 for FieldList
in [Pcd
.DefaultValues
, OverrideValues
.get(DefaultStoreName
)]:
1275 for FieldName
in FieldList
:
1276 FieldName
= "." + FieldName
1277 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1279 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1280 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."));
1283 while '[' in FieldName
:
1284 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1285 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1286 FieldName
= FieldName
.split(']', 1)[1]
1287 FieldName
= NewFieldName
+ FieldName
1288 while '[' in FieldName
:
1289 FieldName
= FieldName
.rsplit('[', 1)[0]
1290 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1293 # Allocate and zero buffer for the PCD
1294 # Must handle cases where current value is smaller, larger, or same size
1295 # Always keep that larger one as the current size
1297 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1298 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1299 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1302 # Copy current PCD value into allocated buffer.
1304 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1307 # Assign field values in PCD
1309 for FieldList
in [Pcd
.DefaultValues
, Pcd
.DefaultFromDSC
,OverrideValues
.get(DefaultStoreName
)]:
1312 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1313 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1314 Value
, ValueSize
= ParseFieldValue (FieldList
)
1315 if isinstance(Value
, str):
1316 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1319 # Use memcpy() to copy value into field
1321 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1322 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1325 for FieldName
in FieldList
:
1326 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1328 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1330 print FieldList
[FieldName
][0]
1331 if isinstance(Value
, str):
1332 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1335 # Use memcpy() to copy value into field
1337 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1338 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1339 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1342 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1344 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1347 # Set new PCD value and size
1349 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1354 CApp
= CApp
+ ' free (Pcd);\n'
1357 return InitByteValue
, CApp
1359 def GenerateByteArrayValue (self
, StructuredPcds
):
1361 # Generate/Compile/Run C application to determine if there are any flexible array members
1363 if not StructuredPcds
:
1367 CApp
= PcdMainCHeader
1370 for PcdName
in StructuredPcds
:
1371 Pcd
= StructuredPcds
[PcdName
]
1372 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1373 if IncludeFile
not in Includes
:
1374 Includes
[IncludeFile
] = True
1375 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1378 for PcdName
in StructuredPcds
:
1379 Pcd
= StructuredPcds
[PcdName
]
1380 if not Pcd
.SkuOverrideValues
:
1381 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1383 for SkuName
in Pcd
.SkuOverrideValues
:
1384 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1385 Pcd
= StructuredPcds
[PcdName
]
1386 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1388 CApp
= CApp
+ 'VOID\n'
1389 CApp
= CApp
+ 'PcdEntryPoint(\n'
1390 CApp
= CApp
+ ' VOID\n'
1391 CApp
= CApp
+ ' )\n'
1393 for Pcd
in StructuredPcds
.values():
1394 if not Pcd
.SkuOverrideValues
:
1395 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1397 for SkuName
in Pcd
.SkuOverrideValues
:
1398 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1399 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1402 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1404 if not os
.path
.exists(self
.OutputPath
):
1405 os
.makedirs(self
.OutputPath
)
1406 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1407 File
= open (CAppBaseFileName
+ '.c', 'w')
1411 MakeApp
= PcdMakefileHeader
1412 if sys
.platform
== "win32":
1413 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1415 MakeApp
= MakeApp
+ PcdGccMakefile
1416 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1417 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='
1420 for Cache
in self
._Bdb
._CACHE
_.values():
1421 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1424 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1425 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1428 for Pcd
in StructuredPcds
.values():
1429 for PackageDec
in Pcd
.PackageDecs
:
1430 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1431 if not os
.path
.exists(Package
):
1432 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1433 if Package
not in PcdDependDEC
:
1434 PcdDependDEC
.append(Package
)
1436 if PlatformInc
and PcdDependDEC
:
1437 for pkg
in PcdDependDEC
:
1438 if pkg
in PlatformInc
:
1439 for inc
in PlatformInc
[pkg
]:
1440 MakeApp
+= '-I' + str(inc
) + ' '
1441 MakeApp
= MakeApp
+ '\n'
1442 if sys
.platform
== "win32":
1443 MakeApp
= MakeApp
+ PcdMakefileEnd
1444 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1445 File
= open (MakeFileName
, 'w')
1449 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1450 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1451 File
= open (InputValueFile
, 'w')
1452 File
.write(InitByteValue
)
1455 if sys
.platform
== "win32":
1456 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1458 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1459 Messages
= StdOut
.split('\r')
1460 for Message
in Messages
:
1461 if " error " in Message
:
1462 FileInfo
= Message
.strip().split('(')
1463 if len (FileInfo
) > 0:
1464 FileName
= FileInfo
[0]
1465 FileLine
= FileInfo
[1].split (')')[0]
1467 FileInfo
= Message
.strip().split(':')
1468 FileName
= FileInfo
[0]
1469 FileLine
= FileInfo
[1]
1471 File
= open (FileName
, 'r')
1472 FileData
= File
.readlines()
1474 error_line
= FileData
[int (FileLine
) - 1]
1475 if r
"//" in error_line
:
1476 c_line
,dsc_line
= error_line
.split(r
"//")
1478 dsc_line
= error_line
1480 message_itmes
= Message
.split(":")
1481 for item
in message_itmes
:
1482 if "PcdValueInit.c" in item
:
1483 message_itmes
[message_itmes
.index(item
)] = dsc_line
.strip()
1485 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[1:]))
1487 PcdValueInitExe
= PcdValueInitName
1488 if not sys
.platform
== "win32":
1489 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1491 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1492 File
= open (OutputValueFile
, 'r')
1493 FileBuffer
= File
.readlines()
1496 StructurePcdSet
= []
1497 for Pcd
in FileBuffer
:
1498 PcdValue
= Pcd
.split ('|')
1499 PcdInfo
= PcdValue
[0].split ('.')
1500 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1501 return StructurePcdSet
1503 ## Retrieve dynamic PCD settings
1505 # @param Type PCD type
1507 # @retval a dict object contains settings of given PCD type
1509 def _GetDynamicPcd(self
, Type
):
1514 # tdict is a special dict kind of type, used for selecting correct
1515 # PCD settings for certain ARCH and SKU
1517 PcdDict
= tdict(True, 4)
1519 # Find out all possible PCD candidates for self._Arch
1520 RecordList
= self
._RawData
[Type
, self
._Arch
]
1521 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1524 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1525 SkuName
= SkuName
.upper()
1526 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1527 if SkuName
not in AvailableSkuIdSet
:
1528 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1529 File
=self
.MetaFile
, Line
=Dummy5
)
1530 if "." not in TokenSpaceGuid
:
1531 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1532 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1534 # Remove redundant PCD candidates, per the ARCH and SKU
1535 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1537 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1541 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1542 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1543 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1544 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1545 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1546 if MaxDatumSize
.strip():
1547 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1550 if pcdObject
.MaxDatumSize
:
1551 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1554 if CurrentMaxSize
> PcdMaxSize
:
1555 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1557 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1560 self
._PCD
_TYPE
_STRING
_[Type
],
1565 {SkuName
: SkuInfo
},
1570 for pcd
in Pcds
.values():
1571 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1572 # Only fix the value while no value provided in DSC file.
1573 for sku
in pcd
.SkuInfoList
.values():
1574 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1575 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1576 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1577 valuefromDec
= pcdDecObject
.DefaultValue
1578 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1579 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1580 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1581 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1582 del(pcd
.SkuInfoList
['COMMON'])
1583 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1584 del(pcd
.SkuInfoList
['COMMON'])
1585 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1586 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1587 pcd
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1588 del(pcd
.SkuInfoList
['DEFAULT'])
1592 def CompareVarAttr(self
, Attr1
, Attr2
):
1593 if not Attr1
or not Attr2
: # for empty string
1595 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1596 Attr1Set
= set(Attr1s
)
1597 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1598 Attr2Set
= set(Attr2s
)
1599 if Attr2Set
== Attr1Set
:
1603 def CompletePcdValues(self
,PcdSet
):
1605 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1606 SkuIds
= set([(skuid
,skuobj
.SkuId
) for pcdobj
in PcdSet
.values() for skuid
,skuobj
in pcdobj
.SkuInfoList
.items()])
1607 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1608 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1609 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1610 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1611 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1612 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1613 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1614 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1615 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1616 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1618 PcdType
= PcdObj
.Type
1619 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1620 for skuid
in PcdObj
.SkuInfoList
:
1621 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1622 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1623 for defaultstorename
in DefaultStores
:
1624 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1625 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1626 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1627 for skuname
,skuid
in SkuIds
:
1628 if skuname
not in PcdObj
.SkuInfoList
:
1629 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1630 while nextskuid
not in PcdObj
.SkuInfoList
:
1631 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1632 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1633 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1634 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1635 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1636 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1637 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1639 ## Retrieve dynamic HII PCD settings
1641 # @param Type PCD type
1643 # @retval a dict object contains settings of given PCD type
1645 def _GetDynamicHiiPcd(self
, Type
):
1651 # tdict is a special dict kind of type, used for selecting correct
1652 # PCD settings for certain ARCH and SKU
1654 PcdDict
= tdict(True, 5)
1656 RecordList
= self
._RawData
[Type
, self
._Arch
]
1657 # Find out all possible PCD candidates for self._Arch
1658 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1659 DefaultStoresDefine
= self
._GetDefaultStores
()
1661 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1662 SkuName
= SkuName
.upper()
1663 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1664 DefaultStore
= DefaultStore
.upper()
1665 if DefaultStore
== "COMMON":
1666 DefaultStore
= "STANDARD"
1667 if SkuName
not in AvailableSkuIdSet
:
1668 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1669 File
=self
.MetaFile
, Line
=Dummy5
)
1670 if DefaultStore
not in DefaultStoresDefine
:
1671 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1672 File
=self
.MetaFile
, Line
=Dummy5
)
1673 if "." not in TokenSpaceGuid
:
1674 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1675 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1678 # Remove redundant PCD candidates, per the ARCH and SKU
1679 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1681 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1684 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1686 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1688 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1689 ExtraData
="[%s]" % VarAttribute
)
1691 FormatCorrect
= True
1692 if VariableOffset
.isdigit():
1693 if int(VariableOffset
, 10) > 0xFFFF:
1695 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1696 if int(VariableOffset
, 16) > 0xFFFF:
1698 # For Offset written in "A.B"
1699 elif VariableOffset
.find('.') > -1:
1700 VariableOffsetList
= VariableOffset
.split(".")
1701 if not (len(VariableOffsetList
) == 2
1702 and IsValidWord(VariableOffsetList
[0])
1703 and IsValidWord(VariableOffsetList
[1])):
1704 FormatCorrect
= False
1706 FormatCorrect
= False
1707 if not FormatCorrect
:
1708 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1711 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1712 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1713 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1715 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1716 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
)]))
1718 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1719 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1720 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1721 if SkuName
in pcdObject
.SkuInfoList
:
1722 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1723 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1725 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1726 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1728 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1729 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1732 self
._PCD
_TYPE
_STRING
_[Type
],
1737 {SkuName
: SkuInfo
},
1740 pcdDecObject
.validateranges
,
1741 pcdDecObject
.validlists
,
1742 pcdDecObject
.expressions
,
1746 for pcd
in Pcds
.values():
1747 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1748 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1749 # Only fix the value while no value provided in DSC file.
1750 for sku
in pcd
.SkuInfoList
.values():
1751 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1752 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1753 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1754 valuefromDec
= pcdDecObject
.DefaultValue
1755 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1756 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1757 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1758 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1759 del(pcd
.SkuInfoList
['COMMON'])
1760 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1761 del(pcd
.SkuInfoList
['COMMON'])
1763 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1764 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1765 pcd
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1766 del(pcd
.SkuInfoList
['DEFAULT'])
1768 if pcd
.MaxDatumSize
.strip():
1769 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1772 if pcdDecObject
.DatumType
== 'VOID*':
1773 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1775 if skuobj
.HiiDefaultValue
.startswith("L"):
1776 datalen
= (len(skuobj
.HiiDefaultValue
) - 3 + 1) * 2
1777 elif skuobj
.HiiDefaultValue
.startswith("{"):
1778 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1780 datalen
= len(skuobj
.HiiDefaultValue
) - 2 + 1
1781 if datalen
> MaxSize
:
1783 pcd
.MaxDatumSize
= str(MaxSize
)
1784 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1786 invalidpcd
= ",".join(invalidhii
)
1787 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
)
1790 def CheckVariableNameAssignment(self
,Pcds
):
1792 for pcdname
in Pcds
:
1794 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1795 if len(varnameset
) > 1:
1796 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1798 return False,invalidhii
1801 ## Retrieve dynamic VPD PCD settings
1803 # @param Type PCD type
1805 # @retval a dict object contains settings of given PCD type
1807 def _GetDynamicVpdPcd(self
, Type
):
1812 # tdict is a special dict kind of type, used for selecting correct
1813 # PCD settings for certain ARCH and SKU
1815 PcdDict
= tdict(True, 4)
1818 # Find out all possible PCD candidates for self._Arch
1819 RecordList
= self
._RawData
[Type
, self
._Arch
]
1820 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1822 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1823 SkuName
= SkuName
.upper()
1824 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1825 if SkuName
not in AvailableSkuIdSet
:
1826 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1827 File
=self
.MetaFile
, Line
=Dummy5
)
1828 if "." not in TokenSpaceGuid
:
1829 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1830 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1832 # Remove redundant PCD candidates, per the ARCH and SKU
1833 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1834 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1838 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1839 # For the Integer & Boolean type, the optional data can only be InitialValue.
1840 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1841 # until the DEC parser has been called.
1843 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1844 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
1845 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1846 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1847 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1848 if MaxDatumSize
.strip():
1849 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1852 if pcdObject
.MaxDatumSize
:
1853 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1856 if CurrentMaxSize
> PcdMaxSize
:
1857 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1859 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1862 self
._PCD
_TYPE
_STRING
_[Type
],
1867 {SkuName
: SkuInfo
},
1871 for pcd
in Pcds
.values():
1872 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1873 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1874 # Only fix the value while no value provided in DSC file.
1875 for sku
in pcd
.SkuInfoList
.values():
1876 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1877 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1878 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1879 valuefromDec
= pcdDecObject
.DefaultValue
1880 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
1881 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1882 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1883 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1884 del(pcd
.SkuInfoList
['COMMON'])
1885 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1886 del(pcd
.SkuInfoList
['COMMON'])
1887 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1888 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1889 pcd
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1890 del(pcd
.SkuInfoList
['DEFAULT'])
1894 ## Add external modules
1896 # The external modules are mostly those listed in FDF file, which don't
1899 # @param FilePath The path of module description file
1901 def AddModule(self
, FilePath
):
1902 FilePath
= NormPath(FilePath
)
1903 if FilePath
not in self
.Modules
:
1904 Module
= ModuleBuildClassObject()
1905 Module
.MetaFile
= FilePath
1906 self
.Modules
.append(Module
)
1908 ## Add external PCDs
1910 # The external PCDs are mostly those listed in FDF file to specify address
1911 # or offset information.
1913 # @param Name Name of the PCD
1914 # @param Guid Token space guid of the PCD
1915 # @param Value Value of the PCD
1917 def AddPcd(self
, Name
, Guid
, Value
):
1918 if (Name
, Guid
) not in self
.Pcds
:
1919 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1920 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1922 _Macros
= property(_GetMacros
)
1923 Arch
= property(_GetArch
, _SetArch
)
1924 Platform
= property(_GetPlatformName
)
1925 PlatformName
= property(_GetPlatformName
)
1926 Guid
= property(_GetFileGuid
)
1927 Version
= property(_GetVersion
)
1928 DscSpecification
= property(_GetDscSpec
)
1929 OutputDirectory
= property(_GetOutpuDir
)
1930 SupArchList
= property(_GetSupArch
)
1931 BuildTargets
= property(_GetBuildTarget
)
1932 SkuName
= property(_GetSkuName
, _SetSkuName
)
1933 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1934 VarCheckFlag
= property(_GetVarCheckFlag
)
1935 FlashDefinition
= property(_GetFdfFile
)
1936 Prebuild
= property(_GetPrebuild
)
1937 Postbuild
= property(_GetPostbuild
)
1938 BuildNumber
= property(_GetBuildNumber
)
1939 MakefileName
= property(_GetMakefileName
)
1940 BsBaseAddress
= property(_GetBsBaseAddress
)
1941 RtBaseAddress
= property(_GetRtBaseAddress
)
1942 LoadFixAddress
= property(_GetLoadFixAddress
)
1943 RFCLanguages
= property(_GetRFCLanguages
)
1944 ISOLanguages
= property(_GetISOLanguages
)
1945 VpdToolGuid
= property(_GetVpdToolGuid
)
1946 SkuIds
= property(_GetSkuIds
)
1947 Modules
= property(_GetModules
)
1948 LibraryInstances
= property(_GetLibraryInstances
)
1949 LibraryClasses
= property(_GetLibraryClasses
)
1950 Pcds
= property(_GetPcds
)
1951 BuildOptions
= property(_GetBuildOptions
)