2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 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
26 from Common
.TargetTxtClassObject
import *
27 from Common
.ToolDefClassObject
import *
28 from MetaDataTable
import *
29 from MetaFileTable
import *
30 from MetaFileParser
import *
32 from WorkspaceCommon
import GetDeclaredPcd
33 from Common
.Misc
import AnalyzeDscPcd
34 from Common
.Misc
import ProcessDuplicatedInf
36 from Common
.Parsing
import IsValidWord
37 from Common
.VariableAttributes
import VariableAttributes
38 import Common
.GlobalData
as GlobalData
40 from Workspace
.BuildClassObject
import PlatformBuildClassObject
, StructurePcd
, PcdClassObject
, ModuleBuildClassObject
43 # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
45 PcdValueInitName
= 'PcdValueInit'
46 PcdSupportedBaseTypes
= ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
47 PcdSupportedBaseTypeWidth
= {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
48 PcdUnsupportedBaseTypes
= ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
59 #include <PcdValueCommon.h>
69 return PcdValueMain (argc, argv);
73 PcdMakefileHeader
= '''
76 # This file is auto-generated by build utility
81 WindowsCFLAGS
= 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
82 LinuxCFLAGS
= 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
84 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
86 LIBS = $(LIB_PATH)\Common.lib
88 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
93 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
97 class DscBuildData(PlatformBuildClassObject
):
98 # dict used to convert PCD type in database to string used by build tool
100 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
101 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
102 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
103 MODEL_PCD_DYNAMIC
: "Dynamic",
104 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
105 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
106 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
107 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
108 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
109 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
110 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
113 # dict used to convert part of [Defines] to members of DscBuildData directly
118 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
119 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
120 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
121 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
122 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
123 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
124 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
125 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
126 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
127 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
128 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
129 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
130 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
131 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
132 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
135 # used to compose dummy library class name for those forced library instances
136 _NullLibraryNumber
= 0
138 ## Constructor of DscBuildData
140 # Initialize object of DscBuildData
142 # @param FilePath The path of platform description file
143 # @param RawData The raw data of DSC file
144 # @param BuildDataBase Database used to retrieve module/package information
145 # @param Arch The target architecture
146 # @param Platform (not used for DscBuildData)
147 # @param Macros Macros used for replacement in DSC file
149 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
150 self
.MetaFile
= FilePath
151 self
._RawData
= RawData
152 self
._Bdb
= BuildDataBase
154 self
._Target
= Target
155 self
._Toolchain
= Toolchain
156 self
._ToolChainFamily
= None
158 self
._HandleOverridePath
()
159 if os
.getenv("WORKSPACE"):
160 self
.OutputPath
= os
.path
.join(os
.getenv("WORKSPACE"), 'Build', PcdValueInitName
)
162 self
.OutputPath
= os
.path
.dirname(self
.DscFile
)
163 self
.DefaultStores
= None
164 self
.SkuIdMgr
= SkuClass(self
.SkuName
, self
.SkuIds
)
165 arraystr
= self
.SkuIdMgr
.DumpSkuIdArrary()
168 def __setitem__(self
, key
, value
):
169 self
.__dict
__[self
._PROPERTY
_[key
]] = value
172 def __getitem__(self
, key
):
173 return self
.__dict
__[self
._PROPERTY
_[key
]]
176 def __contains__(self
, key
):
177 return key
in self
._PROPERTY
_
179 ## Set all internal used members of DscBuildData to None
182 self
._PlatformName
= None
185 self
._DscSpecification
= None
186 self
._OutputDirectory
= None
187 self
._SupArchList
= None
188 self
._BuildTargets
= None
190 self
._PcdInfoFlag
= None
191 self
._VarCheckFlag
= None
192 self
._FlashDefinition
= None
193 self
._Prebuild
= None
194 self
._Postbuild
= None
195 self
._BuildNumber
= None
196 self
._MakefileName
= None
197 self
._BsBaseAddress
= None
198 self
._RtBaseAddress
= None
201 self
._LibraryInstances
= None
202 self
._LibraryClasses
= None
205 self
._BuildOptions
= None
206 self
._ModuleTypeOptions
= None
207 self
._LoadFixAddress
= None
208 self
._RFCLanguages
= None
209 self
._ISOLanguages
= None
210 self
._VpdToolGuid
= None
212 self
.DefaultStores
= None
215 ## handle Override Path of Module
216 def _HandleOverridePath(self
):
217 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
218 Macros
= self
._Macros
219 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
220 for Record
in RecordList
:
223 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
224 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
226 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
228 # Check if the source override path exists
229 if not os
.path
.isdir(SourceOverridePath
):
230 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
232 # Add to GlobalData Variables
233 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
235 ## Get current effective macros
236 def _GetMacros(self
):
237 if self
.__Macros
== None:
239 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
240 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
241 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
250 # Changing the default ARCH to another may affect all other information
251 # because all information in a platform may be ARCH-related. That's
252 # why we need to clear all internal used members, in order to cause all
253 # information to be re-retrieved.
255 # @param Value The value of ARCH
257 def _SetArch(self
, Value
):
258 if self
._Arch
== Value
:
263 ## Retrieve all information in [Defines] section
265 # (Retriving all [Defines] information in one-shot is just to save time.)
267 def _GetHeaderInfo(self
):
268 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
269 for Record
in RecordList
:
271 # items defined _PROPERTY_ don't need additional processing
273 # some special items in [Defines] section need special treatment
274 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
275 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
276 if ' ' in self
._OutputDirectory
:
277 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
278 File
=self
.MetaFile
, Line
=Record
[-1],
279 ExtraData
=self
._OutputDirectory
)
280 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
281 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
282 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
284 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
286 elif Name
== TAB_DSC_PREBUILD
:
287 PrebuildValue
= Record
[2]
288 if Record
[2][0] == '"':
289 if Record
[2][-1] != '"':
290 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
291 File
=self
.MetaFile
, Line
=Record
[-1])
292 PrebuildValue
= Record
[2][1:-1]
293 self
._Prebuild
= PrebuildValue
294 elif Name
== TAB_DSC_POSTBUILD
:
295 PostbuildValue
= Record
[2]
296 if Record
[2][0] == '"':
297 if Record
[2][-1] != '"':
298 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
299 File
=self
.MetaFile
, Line
=Record
[-1])
300 PostbuildValue
= Record
[2][1:-1]
301 self
._Postbuild
= PostbuildValue
302 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
303 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
304 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
305 self
._BuildTargets
= GetSplitValueList(Record
[2])
306 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
307 if self
._SkuName
== None:
308 self
._SkuName
= Record
[2]
309 if GlobalData
.gSKUID_CMD
:
310 self
._SkuName
= GlobalData
.gSKUID_CMD
311 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
312 self
._PcdInfoFlag
= Record
[2]
313 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
314 self
._VarCheckFlag
= Record
[2]
315 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
317 self
._LoadFixAddress
= int (Record
[2], 0)
319 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
320 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
321 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
322 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"',
323 File
=self
.MetaFile
, Line
=Record
[-1])
324 LanguageCodes
= Record
[2][1:-1]
325 if not LanguageCodes
:
326 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
327 File
=self
.MetaFile
, Line
=Record
[-1])
328 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
329 # check whether there is empty entries in the list
330 if None in LanguageList
:
331 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
332 File
=self
.MetaFile
, Line
=Record
[-1])
333 self
._RFCLanguages
= LanguageList
334 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
335 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
336 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
337 File
=self
.MetaFile
, Line
=Record
[-1])
338 LanguageCodes
= Record
[2][1:-1]
339 if not LanguageCodes
:
340 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
341 File
=self
.MetaFile
, Line
=Record
[-1])
342 if len(LanguageCodes
) % 3:
343 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
344 File
=self
.MetaFile
, Line
=Record
[-1])
346 for i
in range(0, len(LanguageCodes
), 3):
347 LanguageList
.append(LanguageCodes
[i
:i
+ 3])
348 self
._ISOLanguages
= LanguageList
349 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
351 # try to convert GUID to a real UUID value to see whether the GUID is format
352 # for VPD_TOOL_GUID is correct.
357 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
358 self
._VpdToolGuid
= Record
[2]
360 self
[Name
] = Record
[2]
361 # set _Header to non-None in order to avoid database re-querying
362 self
._Header
= 'DUMMY'
364 ## Retrieve platform name
365 def _GetPlatformName(self
):
366 if self
._PlatformName
== None:
367 if self
._Header
== None:
368 self
._GetHeaderInfo
()
369 if self
._PlatformName
== None:
370 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
371 return self
._PlatformName
373 ## Retrieve file guid
374 def _GetFileGuid(self
):
375 if self
._Guid
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
378 if self
._Guid
== None:
379 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
382 ## Retrieve platform version
383 def _GetVersion(self
):
384 if self
._Version
== None:
385 if self
._Header
== None:
386 self
._GetHeaderInfo
()
387 if self
._Version
== None:
388 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
391 ## Retrieve platform description file version
392 def _GetDscSpec(self
):
393 if self
._DscSpecification
== None:
394 if self
._Header
== None:
395 self
._GetHeaderInfo
()
396 if self
._DscSpecification
== None:
397 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
398 return self
._DscSpecification
400 ## Retrieve OUTPUT_DIRECTORY
401 def _GetOutpuDir(self
):
402 if self
._OutputDirectory
== None:
403 if self
._Header
== None:
404 self
._GetHeaderInfo
()
405 if self
._OutputDirectory
== None:
406 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
407 return self
._OutputDirectory
409 ## Retrieve SUPPORTED_ARCHITECTURES
410 def _GetSupArch(self
):
411 if self
._SupArchList
== None:
412 if self
._Header
== None:
413 self
._GetHeaderInfo
()
414 if self
._SupArchList
== None:
415 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
416 return self
._SupArchList
418 ## Retrieve BUILD_TARGETS
419 def _GetBuildTarget(self
):
420 if self
._BuildTargets
== None:
421 if self
._Header
== None:
422 self
._GetHeaderInfo
()
423 if self
._BuildTargets
== None:
424 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
425 return self
._BuildTargets
427 def _GetPcdInfoFlag(self
):
428 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
430 elif self
._PcdInfoFlag
.upper() == 'TRUE':
434 def _GetVarCheckFlag(self
):
435 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
437 elif self
._VarCheckFlag
.upper() == 'TRUE':
442 # # Retrieve SKUID_IDENTIFIER
443 def _GetSkuName(self
):
444 if self
._SkuName
== None:
445 if self
._Header
== None:
446 self
._GetHeaderInfo
()
447 if self
._SkuName
== None:
448 self
._SkuName
= 'DEFAULT'
451 ## Override SKUID_IDENTIFIER
452 def _SetSkuName(self
, Value
):
453 self
._SkuName
= Value
456 def _GetFdfFile(self
):
457 if self
._FlashDefinition
== None:
458 if self
._Header
== None:
459 self
._GetHeaderInfo
()
460 if self
._FlashDefinition
== None:
461 self
._FlashDefinition
= ''
462 return self
._FlashDefinition
464 def _GetPrebuild(self
):
465 if self
._Prebuild
== None:
466 if self
._Header
== None:
467 self
._GetHeaderInfo
()
468 if self
._Prebuild
== None:
470 return self
._Prebuild
472 def _GetPostbuild(self
):
473 if self
._Postbuild
== None:
474 if self
._Header
== None:
475 self
._GetHeaderInfo
()
476 if self
._Postbuild
== None:
478 return self
._Postbuild
480 ## Retrieve FLASH_DEFINITION
481 def _GetBuildNumber(self
):
482 if self
._BuildNumber
== None:
483 if self
._Header
== None:
484 self
._GetHeaderInfo
()
485 if self
._BuildNumber
== None:
486 self
._BuildNumber
= ''
487 return self
._BuildNumber
489 ## Retrieve MAKEFILE_NAME
490 def _GetMakefileName(self
):
491 if self
._MakefileName
== None:
492 if self
._Header
== None:
493 self
._GetHeaderInfo
()
494 if self
._MakefileName
== None:
495 self
._MakefileName
= ''
496 return self
._MakefileName
498 ## Retrieve BsBaseAddress
499 def _GetBsBaseAddress(self
):
500 if self
._BsBaseAddress
== None:
501 if self
._Header
== None:
502 self
._GetHeaderInfo
()
503 if self
._BsBaseAddress
== None:
504 self
._BsBaseAddress
= ''
505 return self
._BsBaseAddress
507 ## Retrieve RtBaseAddress
508 def _GetRtBaseAddress(self
):
509 if self
._RtBaseAddress
== None:
510 if self
._Header
== None:
511 self
._GetHeaderInfo
()
512 if self
._RtBaseAddress
== None:
513 self
._RtBaseAddress
= ''
514 return self
._RtBaseAddress
516 ## Retrieve the top address for the load fix address
517 def _GetLoadFixAddress(self
):
518 if self
._LoadFixAddress
== None:
519 if self
._Header
== None:
520 self
._GetHeaderInfo
()
522 if self
._LoadFixAddress
== None:
523 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
526 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
528 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
531 # If command line defined, should override the value in DSC file.
533 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
535 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
537 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']))
539 if self
._LoadFixAddress
< 0:
540 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
541 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
542 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
544 return self
._LoadFixAddress
546 ## Retrieve RFCLanguage filter
547 def _GetRFCLanguages(self
):
548 if self
._RFCLanguages
== None:
549 if self
._Header
== None:
550 self
._GetHeaderInfo
()
551 if self
._RFCLanguages
== None:
552 self
._RFCLanguages
= []
553 return self
._RFCLanguages
555 ## Retrieve ISOLanguage filter
556 def _GetISOLanguages(self
):
557 if self
._ISOLanguages
== None:
558 if self
._Header
== None:
559 self
._GetHeaderInfo
()
560 if self
._ISOLanguages
== None:
561 self
._ISOLanguages
= []
562 return self
._ISOLanguages
563 ## Retrieve the GUID string for VPD tool
564 def _GetVpdToolGuid(self
):
565 if self
._VpdToolGuid
== None:
566 if self
._Header
== None:
567 self
._GetHeaderInfo
()
568 if self
._VpdToolGuid
== None:
569 self
._VpdToolGuid
= ''
570 return self
._VpdToolGuid
572 ## Retrieve [SkuIds] section information
573 def _GetSkuIds(self
):
574 if self
._SkuIds
== None:
575 self
._SkuIds
= sdict()
576 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
577 for Record
in RecordList
:
578 if Record
[0] in [None, '']:
579 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
580 File
=self
.MetaFile
, Line
=Record
[-1])
581 if Record
[1] in [None, '']:
582 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
583 File
=self
.MetaFile
, Line
=Record
[-1])
584 Pattern
= re
.compile('^[1-9]\d*|0$')
585 if Pattern
.match(Record
[0]) == None:
586 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID number is invalid. The correct format is '{(0-9)} {(1-9)(0-9)+}'",
587 File
=self
.MetaFile
, Line
=Record
[-1])
588 if not IsValidWord(Record
[1]):
589 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_-.)*'",
590 File
=self
.MetaFile
, Line
=Record
[-1])
591 self
._SkuIds
[Record
[1].upper()] = (Record
[0], Record
[1].upper(), Record
[2].upper())
592 if 'DEFAULT' not in self
._SkuIds
:
593 self
._SkuIds
['DEFAULT'] = ("0","DEFAULT","DEFAULT")
594 if 'COMMON' not in self
._SkuIds
:
595 self
._SkuIds
['COMMON'] = ("0","DEFAULT","DEFAULT")
597 def ToInt(self
,intstr
):
598 return int(intstr
,16) if intstr
.upper().startswith("0X") else int(intstr
)
599 def _GetDefaultStores(self
):
600 if self
.DefaultStores
== None:
601 self
.DefaultStores
= sdict()
602 RecordList
= self
._RawData
[MODEL_EFI_DEFAULT_STORES
, self
._Arch
]
603 for Record
in RecordList
:
604 if Record
[0] in [None, '']:
605 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID number',
606 File
=self
.MetaFile
, Line
=Record
[-1])
607 if Record
[1] in [None, '']:
608 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID name',
609 File
=self
.MetaFile
, Line
=Record
[-1])
610 self
.DefaultStores
[Record
[1].upper()] = (self
.ToInt(Record
[0]),Record
[1].upper())
611 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
612 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
613 GlobalData
.gDefaultStores
= self
.DefaultStores
.keys()
614 if GlobalData
.gDefaultStores
:
615 GlobalData
.gDefaultStores
.sort()
616 return self
.DefaultStores
618 ## Retrieve [Components] section information
619 def _GetModules(self
):
620 if self
._Modules
!= None:
623 self
._Modules
= sdict()
624 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
625 Macros
= self
._Macros
626 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
627 for Record
in RecordList
:
628 DuplicatedFile
= False
630 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
634 # check the file validation
635 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
637 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
640 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
641 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
642 DuplicatedFile
= True
644 Module
= ModuleBuildClassObject()
645 Module
.MetaFile
= ModuleFile
647 # get module private library instance
648 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
649 for Record
in RecordList
:
650 LibraryClass
= Record
[0]
651 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
654 # check the file validation
655 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
657 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
660 if LibraryClass
== '' or LibraryClass
== 'NULL':
661 self
._NullLibraryNumber
+= 1
662 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
663 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
664 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
665 if LibraryPath
not in self
.LibraryInstances
:
666 self
.LibraryInstances
.append(LibraryPath
)
668 # get module private PCD setting
669 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
670 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
671 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
672 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
673 TokenList
= GetSplitValueList(Setting
)
674 DefaultValue
= TokenList
[0]
675 if len(TokenList
) > 1:
676 MaxDatumSize
= TokenList
[1]
679 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
680 Pcd
= PcdClassObject(
692 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
694 # get module private build options
695 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
696 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
697 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
698 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
700 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
701 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
703 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
704 if DuplicatedFile
and not RecordList
:
705 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
707 if len(RecordList
) != 1:
708 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
709 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
710 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
711 ModuleFile
.Arch
= self
._Arch
713 self
._Modules
[ModuleFile
] = Module
716 ## Retrieve all possible library instances used in this platform
717 def _GetLibraryInstances(self
):
718 if self
._LibraryInstances
== None:
719 self
._GetLibraryClasses
()
720 return self
._LibraryInstances
722 ## Retrieve [LibraryClasses] information
723 def _GetLibraryClasses(self
):
724 if self
._LibraryClasses
== None:
725 self
._LibraryInstances
= []
727 # tdict is a special dict kind of type, used for selecting correct
728 # library instance for given library class and module type
730 LibraryClassDict
= tdict(True, 3)
731 # track all library class names
732 LibraryClassSet
= set()
733 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
734 Macros
= self
._Macros
735 for Record
in RecordList
:
736 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
737 if LibraryClass
== '' or LibraryClass
== 'NULL':
738 self
._NullLibraryNumber
+= 1
739 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
740 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
741 LibraryClassSet
.add(LibraryClass
)
742 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
743 # check the file validation
744 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
746 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
749 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
750 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
751 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
752 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
753 if LibraryInstance
not in self
._LibraryInstances
:
754 self
._LibraryInstances
.append(LibraryInstance
)
756 # resolve the specific library instance for each class and each module type
757 self
._LibraryClasses
= tdict(True)
758 for LibraryClass
in LibraryClassSet
:
759 # try all possible module types
760 for ModuleType
in SUP_MODULE_LIST
:
761 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
762 if LibraryInstance
== None:
764 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
766 # for Edk style library instances, which are listed in different section
767 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
768 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
769 for Record
in RecordList
:
770 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
772 # check the file validation
773 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
775 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
777 if File
not in self
._LibraryInstances
:
778 self
._LibraryInstances
.append(File
)
780 # we need the module name as the library class name, so we have
781 # to parse it here. (self._Bdb[] will trigger a file parse if it
782 # hasn't been parsed)
784 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
785 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
786 return self
._LibraryClasses
788 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
789 if self
._DecPcds
== None:
792 if GlobalData
.gFdfParser
:
793 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
796 for Inf
in FdfInfList
:
797 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
798 if ModuleFile
in self
._Modules
:
800 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
801 PkgSet
.update(ModuleData
.Packages
)
803 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
806 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
807 EdkLogger
.error('build', PARSER_ERROR
,
808 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
809 File
=self
.MetaFile
, Line
=LineNo
)
810 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
812 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
813 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
814 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
816 if ValueList
[2] == '-1':
817 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
818 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
819 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
821 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
822 except WrnExpression
, Value
:
823 ValueList
[Index
] = Value
.result
824 except EvaluationException
, Excpt
:
825 if hasattr(Excpt
, 'Pcd'):
826 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
827 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
828 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
829 " of the DSC file" % Excpt
.Pcd
,
830 File
=self
.MetaFile
, Line
=LineNo
)
832 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
833 File
=self
.MetaFile
, Line
=LineNo
)
835 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
836 File
=self
.MetaFile
, Line
=LineNo
)
837 if ValueList
[Index
] == 'True':
838 ValueList
[Index
] = '1'
839 elif ValueList
[Index
] == 'False':
840 ValueList
[Index
] = '0'
842 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
844 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
845 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
846 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
847 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
848 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
849 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
852 def _FilterPcdBySkuUsage(self
,Pcds
):
853 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
854 sku_usage
= self
.SkuIdMgr
.SkuUsageType
855 if sku_usage
== SkuClass
.SINGLE
:
858 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
859 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
860 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
864 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
865 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
866 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
868 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
869 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
]]]
870 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
872 for skuid
in pcd
.SkuInfoList
:
873 skuobj
= pcd
.SkuInfoList
.get(skuid
)
874 if "STANDARD" not in skuobj
.DefaultStoreDict
:
875 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
876 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
877 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
880 ## Retrieve all PCD settings in platform
882 if self
._Pcds
== None:
884 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
885 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
886 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
887 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
888 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
889 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
890 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
891 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
892 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
894 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
895 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
896 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
897 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
900 def _dumpPcdInfo(self
,Pcds
):
903 if not pcdobj
.TokenCName
.startswith("Test"):
905 for skuid
in pcdobj
.SkuInfoList
:
906 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
907 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
908 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
910 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
911 ## Retrieve [BuildOptions]
912 def _GetBuildOptions(self
):
913 if self
._BuildOptions
== None:
914 self
._BuildOptions
= sdict()
916 # Retrieve build option for EDKII and EDK style module
918 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
919 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
920 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
921 if Dummy3
.upper() != 'COMMON':
923 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
925 # Only flags can be appended
927 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
928 self
._BuildOptions
[CurKey
] = Option
930 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
931 self
._BuildOptions
[CurKey
] += ' ' + Option
932 return self
._BuildOptions
934 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
935 if self
._ModuleTypeOptions
== None:
936 self
._ModuleTypeOptions
= sdict()
937 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
939 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
940 DriverType
= '%s.%s' % (Edk
, ModuleType
)
941 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
942 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
943 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
944 Type
= Dummy2
+ '.' + Dummy3
945 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
946 Key
= (ToolChainFamily
, ToolChain
, Edk
)
947 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
948 options
[Key
] = Option
950 if ' ' + Option
not in options
[Key
]:
951 options
[Key
] += ' ' + Option
952 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
954 def GetStructurePcdInfo(self
, PcdSet
):
955 structure_pcd_data
= {}
957 if (item
[0],item
[1]) not in structure_pcd_data
:
958 structure_pcd_data
[(item
[0],item
[1])] = []
959 structure_pcd_data
[(item
[0],item
[1])].append(item
)
961 return structure_pcd_data
963 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
965 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
966 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
967 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
968 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
969 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
970 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
973 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
974 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
975 SkuIds
.update({'DEFAULT':0})
976 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
979 # Find out all possible PCD candidates for self._Arch
982 for Type
in TypeList
:
983 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
985 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
986 SkuName
= SkuName
.upper()
987 default_store
= default_store
.upper()
988 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
989 if SkuName
not in SkuIds
:
992 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
993 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
995 # handle pcd value override
996 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
998 for str_pcd
in StrPcdSet
:
999 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1000 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1002 str_pcd_obj_str
= StructurePcd()
1003 str_pcd_obj_str
.copy(str_pcd_dec
)
1005 str_pcd_obj_str
.copy(str_pcd_obj
)
1006 if str_pcd_obj
.DefaultValue
:
1007 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1008 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1009 if str_pcd_data
[3] in SkuIds
:
1010 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])
1011 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1013 EdkLogger
.error('build', PARSER_ERROR
,
1014 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1015 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1016 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1017 for Pcd
in self
.DecPcds
:
1018 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1019 if Pcd
not in S_pcd_set
:
1020 str_pcd_obj_str
= StructurePcd()
1021 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1022 str_pcd_obj
= Pcds
.get(Pcd
, None)
1024 str_pcd_obj_str
.copy(str_pcd_obj
)
1025 if str_pcd_obj
.DefaultValue
:
1026 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1027 S_pcd_set
[Pcd
] = str_pcd_obj_str
1029 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1030 for stru_pcd
in S_pcd_set
.values():
1031 for skuid
in SkuIds
:
1032 if skuid
in stru_pcd
.SkuOverrideValues
:
1034 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1036 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1037 if nextskuid
== "DEFAULT":
1040 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1041 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
})
1042 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1043 for skuid
in SkuIds
:
1046 if skuid
not in stru_pcd
.SkuOverrideValues
:
1047 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1048 if nextskuid
== "DEFAULT":
1051 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1054 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1055 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1057 for defaultstoreid
in DefaultStores
:
1058 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1059 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1061 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1063 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1064 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1065 if str_pcd_obj
is None:
1066 print PcdName
, PcdGuid
1068 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1069 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1070 if skuname
not in str_pcd_obj
.SkuInfoList
:
1071 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1073 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1074 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1075 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1076 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1077 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1078 str_pcd_obj
.DefaultValue
= PcdValue
1080 if skuname
not in str_pcd_obj
.SkuInfoList
:
1081 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1083 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1084 if nextskuid
== "DEFAULT":
1087 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1088 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
)
1089 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1090 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1092 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1093 for str_pcd_obj
in S_pcd_set
.values():
1094 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1095 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1097 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1098 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1099 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1100 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1102 for str_pcd_obj
in S_pcd_set
.values():
1104 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1105 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1109 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1110 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1111 del(pcd
.SkuInfoList
['COMMON'])
1112 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1113 del(pcd
.SkuInfoList
['COMMON'])
1115 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1118 ## Retrieve non-dynamic PCD settings
1120 # @param Type PCD type
1122 # @retval a dict object contains settings of given PCD type
1124 def _GetPcd(self
, Type
):
1127 # tdict is a special dict kind of type, used for selecting correct
1128 # PCD settings for certain ARCH
1130 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1132 PcdDict
= tdict(True, 3)
1134 # Find out all possible PCD candidates for self._Arch
1135 RecordList
= self
._RawData
[Type
, self
._Arch
]
1136 PcdValueDict
= sdict()
1137 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1138 SkuName
= SkuName
.upper()
1139 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1140 if SkuName
not in AvailableSkuIdSet
:
1141 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1142 File
=self
.MetaFile
, Line
=Dummy5
)
1143 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1144 if "." not in TokenSpaceGuid
:
1145 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1146 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1148 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1149 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1152 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1153 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1154 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1156 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1158 PcdsKeys
= PcdValueDict
.keys()
1159 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1161 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1165 if 'COMMON' in PcdSetting
:
1166 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1167 if 'DEFAULT' in PcdSetting
:
1168 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1169 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1170 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1172 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1175 self
._PCD
_TYPE
_STRING
_[Type
],
1188 def __UNICODE2OCTList(self
,Value
):
1189 Value
= Value
.strip()
1193 Temp
= '%04X' % ord(Item
)
1194 List
.append('0x' + Temp
[2:4])
1195 List
.append('0x' + Temp
[0:2])
1199 def __STRING2OCTList(self
,Value
):
1201 Value
= Value
.strip('"')
1203 Temp
= '%02X' % ord(char
)
1204 OCTList
.append('0x' + Temp
)
1205 OCTList
.append('0x00')
1208 def GetStructurePcdMaxSize(self
, str_pcd
):
1209 pcd_default_value
= str_pcd
.DefaultValue
1210 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()]
1211 sku_values
.append(pcd_default_value
)
1213 def get_length(value
):
1214 Value
= value
.strip()
1216 if Value
.startswith('GUID') and Value
.endswith(')'):
1218 if Value
.startswith('L"') and Value
.endswith('"'):
1219 return len(Value
[2:-1])
1220 if Value
[0] == '"' and Value
[-1] == '"':
1221 return len(Value
) - 2
1222 if Value
[0] == '{' and Value
[-1] == '}':
1223 return len(Value
.split(","))
1224 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1225 return len(list(Value
[2:-1]))
1226 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1227 return len(Value
) - 2
1230 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1232 def IsFieldValueAnArray (self
, Value
):
1233 Value
= Value
.strip()
1234 if Value
.startswith('GUID') and Value
.endswith(')'):
1236 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1238 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1240 if Value
[0] == '{' and Value
[-1] == '}':
1242 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1243 print 'foo = ', list(Value
[2:-1])
1245 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1246 print 'bar = ', list(Value
[1:-1])
1250 def ExecuteCommand (self
, Command
):
1252 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1254 print 'ERROR: Can not execute command:', Command
1256 Result
= Process
.communicate()
1257 if Process
.returncode
<> 0:
1258 print 'ERROR: Can not collect output from command:', Command
1259 return Result
[0], Result
[1]
1261 def IntToCString(self
, Value
, ValueSize
):
1263 if not isinstance (Value
, str):
1264 for Index
in range(0, ValueSize
):
1265 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1267 Result
= Result
+ '"'
1270 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1271 OverrideValues
= {DefaultStoreName
:""}
1272 if Pcd
.SkuOverrideValues
:
1273 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1274 for DefaultStoreName
in OverrideValues
.keys():
1275 CApp
= CApp
+ 'void\n'
1276 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1277 CApp
= CApp
+ ' void\n'
1278 CApp
= CApp
+ ' )\n'
1280 CApp
= CApp
+ ' UINT32 Size;\n'
1281 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1282 CApp
= CApp
+ ' CHAR8 *Value;\n'
1283 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1284 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1285 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1288 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1289 PcdDefaultValue
= StringToArray(Pcd
.DefaultValue
)
1291 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1294 # Get current PCD value and size
1296 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1299 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1300 # the correct value. For structures with a flexible array member, the flexible
1301 # array member is detected, and the size is based on the highest index used with
1302 # the flexible array member. The flexible array member must be the last field
1303 # in a structure. The size formula for this case is:
1304 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1306 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1307 for skuname
in self
.SkuIdMgr
.SkuOverrideOrder():
1308 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1309 for FieldList
in [Pcd
.DefaultValues
, inherit_OverrideValues
.get(DefaultStoreName
)]:
1312 for FieldName
in FieldList
:
1313 FieldName
= "." + FieldName
1314 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1316 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1317 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."));
1320 while '[' in FieldName
:
1321 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1322 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1323 FieldName
= FieldName
.split(']', 1)[1]
1324 FieldName
= NewFieldName
+ FieldName
1325 while '[' in FieldName
:
1326 FieldName
= FieldName
.rsplit('[', 1)[0]
1327 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1328 if skuname
== SkuName
:
1332 # Allocate and zero buffer for the PCD
1333 # Must handle cases where current value is smaller, larger, or same size
1334 # Always keep that larger one as the current size
1336 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1337 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1338 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1341 # Copy current PCD value into allocated buffer.
1343 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1346 # Assign field values in PCD
1348 for skuname
in self
.SkuIdMgr
.SkuOverrideOrder():
1349 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1350 for FieldList
in [Pcd
.DefaultValues
, Pcd
.DefaultFromDSC
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1353 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1354 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1355 Value
, ValueSize
= ParseFieldValue (FieldList
)
1356 if isinstance(Value
, str):
1357 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1360 # Use memcpy() to copy value into field
1362 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1363 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1366 for FieldName
in FieldList
:
1367 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1369 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1371 print FieldList
[FieldName
][0]
1372 if isinstance(Value
, str):
1373 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1376 # Use memcpy() to copy value into field
1378 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1379 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1380 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1383 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1385 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1386 if skuname
== SkuName
:
1389 # Set new PCD value and size
1391 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1396 CApp
= CApp
+ ' free (Pcd);\n'
1399 return InitByteValue
, CApp
1401 def GenerateByteArrayValue (self
, StructuredPcds
):
1403 # Generate/Compile/Run C application to determine if there are any flexible array members
1405 if not StructuredPcds
:
1409 CApp
= PcdMainCHeader
1412 for PcdName
in StructuredPcds
:
1413 Pcd
= StructuredPcds
[PcdName
]
1414 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1415 if IncludeFile
not in Includes
:
1416 Includes
[IncludeFile
] = True
1417 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1420 for PcdName
in StructuredPcds
:
1421 Pcd
= StructuredPcds
[PcdName
]
1422 if not Pcd
.SkuOverrideValues
:
1423 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1425 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1426 if SkuName
not in Pcd
.SkuOverrideValues
:
1428 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1429 Pcd
= StructuredPcds
[PcdName
]
1430 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1432 CApp
= CApp
+ 'VOID\n'
1433 CApp
= CApp
+ 'PcdEntryPoint(\n'
1434 CApp
= CApp
+ ' VOID\n'
1435 CApp
= CApp
+ ' )\n'
1437 for Pcd
in StructuredPcds
.values():
1438 if not Pcd
.SkuOverrideValues
:
1439 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1441 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1442 if SkuName
not in Pcd
.SkuOverrideValues
:
1444 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1445 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1448 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1450 if not os
.path
.exists(self
.OutputPath
):
1451 os
.makedirs(self
.OutputPath
)
1452 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1453 File
= open (CAppBaseFileName
+ '.c', 'w')
1457 MakeApp
= PcdMakefileHeader
1458 if sys
.platform
== "win32":
1459 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1461 MakeApp
= MakeApp
+ PcdGccMakefile
1462 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1463 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1466 for Cache
in self
._Bdb
._CACHE
_.values():
1467 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1470 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1471 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1474 for Pcd
in StructuredPcds
.values():
1475 for PackageDec
in Pcd
.PackageDecs
:
1476 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1477 if not os
.path
.exists(Package
):
1478 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1479 if Package
not in PcdDependDEC
:
1480 PcdDependDEC
.append(Package
)
1482 if PlatformInc
and PcdDependDEC
:
1483 for pkg
in PcdDependDEC
:
1484 if pkg
in PlatformInc
:
1485 for inc
in PlatformInc
[pkg
]:
1486 MakeApp
+= '-I' + str(inc
) + ' '
1487 MakeApp
= MakeApp
+ '\n'
1489 CC_FLAGS
= LinuxCFLAGS
1490 if sys
.platform
== "win32":
1491 CC_FLAGS
= WindowsCFLAGS
1493 for Options
in self
.BuildOptions
:
1494 if Options
[2] != EDKII_NAME
:
1497 if Family
and Family
!= self
.ToolChainFamily
:
1499 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
1503 if Target
== "*" or Target
== self
._Target
:
1504 if Tag
== "*" or Tag
== self
._Toolchain
:
1505 if Arch
== "*" or Arch
== self
.Arch
:
1506 if Tool
not in BuildOptions
:
1507 BuildOptions
[Tool
] = {}
1508 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
1509 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1511 # append options for the same tool except PATH
1513 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
1515 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1517 for Tool
in BuildOptions
:
1518 for Attr
in BuildOptions
[Tool
]:
1520 Value
= BuildOptions
[Tool
][Attr
]
1521 ValueList
= Value
.split()
1523 for Id
, Item
in enumerate(ValueList
):
1524 if Item
== '-D' or Item
== '/D':
1525 CC_FLAGS
+= ' ' + Item
1526 if Id
+ 1 < len(ValueList
):
1527 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
1528 elif Item
.startswith('/D') or Item
.startswith('-D'):
1529 CC_FLAGS
+= ' ' + Item
1532 if sys
.platform
== "win32":
1533 MakeApp
= MakeApp
+ PcdMakefileEnd
1534 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1535 File
= open (MakeFileName
, 'w')
1539 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1540 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1541 File
= open (InputValueFile
, 'w')
1542 File
.write(InitByteValue
)
1546 if sys
.platform
== "win32":
1547 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1550 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1552 Messages
= Messages
.split('\n')
1553 for Message
in Messages
:
1554 if " error" in Message
:
1555 FileInfo
= Message
.strip().split('(')
1556 if len (FileInfo
) > 1:
1557 FileName
= FileInfo
[0]
1558 FileLine
= FileInfo
[1].split (')')[0]
1560 FileInfo
= Message
.strip().split(':')
1561 FileName
= FileInfo
[0]
1562 FileLine
= FileInfo
[1]
1564 File
= open (FileName
, 'r')
1565 FileData
= File
.readlines()
1567 error_line
= FileData
[int (FileLine
) - 1]
1568 if r
"//" in error_line
:
1569 c_line
,dsc_line
= error_line
.split(r
"//")
1571 dsc_line
= error_line
1573 message_itmes
= Message
.split(":")
1575 for item
in message_itmes
:
1576 if "PcdValueInit.c" in item
:
1577 Index
= message_itmes
.index(item
)
1578 message_itmes
[Index
] = dsc_line
.strip()
1581 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[Index
:]))
1583 PcdValueInitExe
= PcdValueInitName
1584 if not sys
.platform
== "win32":
1585 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1587 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1588 File
= open (OutputValueFile
, 'r')
1589 FileBuffer
= File
.readlines()
1592 StructurePcdSet
= []
1593 for Pcd
in FileBuffer
:
1594 PcdValue
= Pcd
.split ('|')
1595 PcdInfo
= PcdValue
[0].split ('.')
1596 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1597 return StructurePcdSet
1599 ## Retrieve dynamic PCD settings
1601 # @param Type PCD type
1603 # @retval a dict object contains settings of given PCD type
1605 def _GetDynamicPcd(self
, Type
):
1610 # tdict is a special dict kind of type, used for selecting correct
1611 # PCD settings for certain ARCH and SKU
1613 PcdDict
= tdict(True, 4)
1615 # Find out all possible PCD candidates for self._Arch
1616 RecordList
= self
._RawData
[Type
, self
._Arch
]
1617 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1620 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1621 SkuName
= SkuName
.upper()
1622 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1623 if SkuName
not in AvailableSkuIdSet
:
1624 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1625 File
=self
.MetaFile
, Line
=Dummy5
)
1626 if "." not in TokenSpaceGuid
:
1627 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1628 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1630 # Remove redundant PCD candidates, per the ARCH and SKU
1631 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1633 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1637 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1638 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1639 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1640 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1641 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1642 if MaxDatumSize
.strip():
1643 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1646 if pcdObject
.MaxDatumSize
:
1647 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1650 if CurrentMaxSize
> PcdMaxSize
:
1651 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1653 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1656 self
._PCD
_TYPE
_STRING
_[Type
],
1661 {SkuName
: SkuInfo
},
1666 for pcd
in Pcds
.values():
1667 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1668 # Only fix the value while no value provided in DSC file.
1669 for sku
in pcd
.SkuInfoList
.values():
1670 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1671 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1672 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1673 valuefromDec
= pcdDecObject
.DefaultValue
1674 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1675 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1676 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1677 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1678 del(pcd
.SkuInfoList
['COMMON'])
1679 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1680 del(pcd
.SkuInfoList
['COMMON'])
1682 map(self
.FilterSkuSettings
,Pcds
.values())
1686 def FilterSkuSettings(self
, PcdObj
):
1688 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1689 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1690 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1691 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1692 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1693 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1695 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1696 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1701 def CompareVarAttr(self
, Attr1
, Attr2
):
1702 if not Attr1
or not Attr2
: # for empty string
1704 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1705 Attr1Set
= set(Attr1s
)
1706 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1707 Attr2Set
= set(Attr2s
)
1708 if Attr2Set
== Attr1Set
:
1712 def CompletePcdValues(self
,PcdSet
):
1714 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1715 SkuIds
= set([(skuid
,skuobj
.SkuId
) for pcdobj
in PcdSet
.values() for skuid
,skuobj
in pcdobj
.SkuInfoList
.items()])
1716 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
1717 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1718 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1719 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1720 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1721 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1722 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1723 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1724 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1725 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1726 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1728 PcdType
= PcdObj
.Type
1729 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1730 for skuid
in PcdObj
.SkuInfoList
:
1731 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1732 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1733 for defaultstorename
in DefaultStores
:
1734 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1735 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1736 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1737 for skuname
,skuid
in SkuIds
.items():
1738 if skuname
not in PcdObj
.SkuInfoList
:
1739 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1740 while nextskuid
not in PcdObj
.SkuInfoList
:
1741 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1742 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1743 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1744 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1745 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1746 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1747 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1749 ## Retrieve dynamic HII PCD settings
1751 # @param Type PCD type
1753 # @retval a dict object contains settings of given PCD type
1755 def _GetDynamicHiiPcd(self
, Type
):
1761 # tdict is a special dict kind of type, used for selecting correct
1762 # PCD settings for certain ARCH and SKU
1764 PcdDict
= tdict(True, 5)
1766 RecordList
= self
._RawData
[Type
, self
._Arch
]
1767 # Find out all possible PCD candidates for self._Arch
1768 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1769 DefaultStoresDefine
= self
._GetDefaultStores
()
1771 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1772 SkuName
= SkuName
.upper()
1773 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1774 DefaultStore
= DefaultStore
.upper()
1775 if DefaultStore
== "COMMON":
1776 DefaultStore
= "STANDARD"
1777 if SkuName
not in AvailableSkuIdSet
:
1778 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1779 File
=self
.MetaFile
, Line
=Dummy5
)
1780 if DefaultStore
not in DefaultStoresDefine
:
1781 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1782 File
=self
.MetaFile
, Line
=Dummy5
)
1783 if "." not in TokenSpaceGuid
:
1784 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1785 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1788 # Remove redundant PCD candidates, per the ARCH and SKU
1789 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1791 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1794 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1796 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1798 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1799 ExtraData
="[%s]" % VarAttribute
)
1801 FormatCorrect
= True
1802 if VariableOffset
.isdigit():
1803 if int(VariableOffset
, 10) > 0xFFFF:
1805 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1806 if int(VariableOffset
, 16) > 0xFFFF:
1808 # For Offset written in "A.B"
1809 elif VariableOffset
.find('.') > -1:
1810 VariableOffsetList
= VariableOffset
.split(".")
1811 if not (len(VariableOffsetList
) == 2
1812 and IsValidWord(VariableOffsetList
[0])
1813 and IsValidWord(VariableOffsetList
[1])):
1814 FormatCorrect
= False
1816 FormatCorrect
= False
1817 if not FormatCorrect
:
1818 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1821 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1822 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1823 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1825 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1826 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
)]))
1828 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1829 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1830 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1831 if SkuName
in pcdObject
.SkuInfoList
:
1832 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1833 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1835 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1836 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1838 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1839 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1842 self
._PCD
_TYPE
_STRING
_[Type
],
1847 {SkuName
: SkuInfo
},
1850 pcdDecObject
.validateranges
,
1851 pcdDecObject
.validlists
,
1852 pcdDecObject
.expressions
,
1856 for pcd
in Pcds
.values():
1857 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1858 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1859 # Only fix the value while no value provided in DSC file.
1860 for sku
in pcd
.SkuInfoList
.values():
1861 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1862 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1863 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1864 valuefromDec
= pcdDecObject
.DefaultValue
1865 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1866 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1867 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1868 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1869 del(pcd
.SkuInfoList
['COMMON'])
1870 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1871 del(pcd
.SkuInfoList
['COMMON'])
1873 if pcd
.MaxDatumSize
.strip():
1874 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1877 if pcdDecObject
.DatumType
== 'VOID*':
1878 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1880 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1881 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1882 if datalen
> MaxSize
:
1884 for defaultst
in skuobj
.DefaultStoreDict
:
1885 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1886 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1887 pcd
.MaxDatumSize
= str(MaxSize
)
1888 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1890 invalidpcd
= ",".join(invalidhii
)
1891 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
)
1893 map(self
.FilterSkuSettings
,Pcds
.values())
1897 def CheckVariableNameAssignment(self
,Pcds
):
1899 for pcdname
in Pcds
:
1901 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1902 if len(varnameset
) > 1:
1903 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1905 return False,invalidhii
1908 ## Retrieve dynamic VPD PCD settings
1910 # @param Type PCD type
1912 # @retval a dict object contains settings of given PCD type
1914 def _GetDynamicVpdPcd(self
, Type
):
1919 # tdict is a special dict kind of type, used for selecting correct
1920 # PCD settings for certain ARCH and SKU
1922 PcdDict
= tdict(True, 4)
1925 # Find out all possible PCD candidates for self._Arch
1926 RecordList
= self
._RawData
[Type
, self
._Arch
]
1927 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1929 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1930 SkuName
= SkuName
.upper()
1931 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1932 if SkuName
not in AvailableSkuIdSet
:
1933 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1934 File
=self
.MetaFile
, Line
=Dummy5
)
1935 if "." not in TokenSpaceGuid
:
1936 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1937 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1939 # Remove redundant PCD candidates, per the ARCH and SKU
1940 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1941 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1945 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1946 # For the Integer & Boolean type, the optional data can only be InitialValue.
1947 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1948 # until the DEC parser has been called.
1950 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1951 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
1952 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1953 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1954 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1955 if MaxDatumSize
.strip():
1956 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1959 if pcdObject
.MaxDatumSize
:
1960 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1963 if CurrentMaxSize
> PcdMaxSize
:
1964 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1966 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1969 self
._PCD
_TYPE
_STRING
_[Type
],
1974 {SkuName
: SkuInfo
},
1978 for pcd
in Pcds
.values():
1979 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1980 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1981 # Only fix the value while no value provided in DSC file.
1982 for sku
in pcd
.SkuInfoList
.values():
1983 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1984 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1985 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1986 valuefromDec
= pcdDecObject
.DefaultValue
1987 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
1988 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1989 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1990 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1991 del(pcd
.SkuInfoList
['COMMON'])
1992 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1993 del(pcd
.SkuInfoList
['COMMON'])
1996 map(self
.FilterSkuSettings
,Pcds
.values())
1999 ## Add external modules
2001 # The external modules are mostly those listed in FDF file, which don't
2004 # @param FilePath The path of module description file
2006 def AddModule(self
, FilePath
):
2007 FilePath
= NormPath(FilePath
)
2008 if FilePath
not in self
.Modules
:
2009 Module
= ModuleBuildClassObject()
2010 Module
.MetaFile
= FilePath
2011 self
.Modules
.append(Module
)
2013 def _GetToolChainFamily(self
):
2014 self
._ToolChainFamily
= "MSFT"
2015 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2016 if os
.path
.isfile(BuildConfigurationFile
) == True:
2017 TargetTxt
= TargetTxtClassObject()
2018 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2019 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2020 if ToolDefinitionFile
== '':
2021 ToolDefinitionFile
= "tools_def.txt"
2022 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2023 if os
.path
.isfile(ToolDefinitionFile
) == True:
2024 ToolDef
= ToolDefClassObject()
2025 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2026 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2027 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2028 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2029 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2030 self
._ToolChainFamily
= "MSFT"
2032 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2033 return self
._ToolChainFamily
2035 ## Add external PCDs
2037 # The external PCDs are mostly those listed in FDF file to specify address
2038 # or offset information.
2040 # @param Name Name of the PCD
2041 # @param Guid Token space guid of the PCD
2042 # @param Value Value of the PCD
2044 def AddPcd(self
, Name
, Guid
, Value
):
2045 if (Name
, Guid
) not in self
.Pcds
:
2046 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2047 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2050 if self
._DecPcds
== None:
2052 if GlobalData
.gFdfParser
:
2053 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2055 for Inf
in FdfInfList
:
2056 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2057 if ModuleFile
in self
._Modules
:
2059 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2060 PkgSet
.update(ModuleData
.Packages
)
2061 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2062 return self
._DecPcds
2063 _Macros
= property(_GetMacros
)
2064 Arch
= property(_GetArch
, _SetArch
)
2065 Platform
= property(_GetPlatformName
)
2066 PlatformName
= property(_GetPlatformName
)
2067 Guid
= property(_GetFileGuid
)
2068 Version
= property(_GetVersion
)
2069 DscSpecification
= property(_GetDscSpec
)
2070 OutputDirectory
= property(_GetOutpuDir
)
2071 SupArchList
= property(_GetSupArch
)
2072 BuildTargets
= property(_GetBuildTarget
)
2073 SkuName
= property(_GetSkuName
, _SetSkuName
)
2074 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2075 VarCheckFlag
= property(_GetVarCheckFlag
)
2076 FlashDefinition
= property(_GetFdfFile
)
2077 Prebuild
= property(_GetPrebuild
)
2078 Postbuild
= property(_GetPostbuild
)
2079 BuildNumber
= property(_GetBuildNumber
)
2080 MakefileName
= property(_GetMakefileName
)
2081 BsBaseAddress
= property(_GetBsBaseAddress
)
2082 RtBaseAddress
= property(_GetRtBaseAddress
)
2083 LoadFixAddress
= property(_GetLoadFixAddress
)
2084 RFCLanguages
= property(_GetRFCLanguages
)
2085 ISOLanguages
= property(_GetISOLanguages
)
2086 VpdToolGuid
= property(_GetVpdToolGuid
)
2087 SkuIds
= property(_GetSkuIds
)
2088 Modules
= property(_GetModules
)
2089 LibraryInstances
= property(_GetLibraryInstances
)
2090 LibraryClasses
= property(_GetLibraryClasses
)
2091 Pcds
= property(_GetPcds
)
2092 BuildOptions
= property(_GetBuildOptions
)
2093 ToolChainFamily
= property(_GetToolChainFamily
)