2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
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 HexPattern
= re
.compile(r
'0[xX][0-9a-fA-F]+$')
586 if Pattern
.match(Record
[0]) == None and HexPattern
.match(Record
[0]) == None:
587 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
588 File
=self
.MetaFile
, Line
=Record
[-1])
589 if not IsValidWord(Record
[1]):
590 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_-.)*'",
591 File
=self
.MetaFile
, Line
=Record
[-1])
592 self
._SkuIds
[Record
[1].upper()] = (str(self
.ToInt(Record
[0])), Record
[1].upper(), Record
[2].upper())
593 if 'DEFAULT' not in self
._SkuIds
:
594 self
._SkuIds
['DEFAULT'] = ("0","DEFAULT","DEFAULT")
595 if 'COMMON' not in self
._SkuIds
:
596 self
._SkuIds
['COMMON'] = ("0","DEFAULT","DEFAULT")
598 def ToInt(self
,intstr
):
599 return int(intstr
,16) if intstr
.upper().startswith("0X") else int(intstr
)
600 def _GetDefaultStores(self
):
601 if self
.DefaultStores
== None:
602 self
.DefaultStores
= sdict()
603 RecordList
= self
._RawData
[MODEL_EFI_DEFAULT_STORES
, self
._Arch
]
604 for Record
in RecordList
:
605 if Record
[0] in [None, '']:
606 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID number',
607 File
=self
.MetaFile
, Line
=Record
[-1])
608 if Record
[1] in [None, '']:
609 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID name',
610 File
=self
.MetaFile
, Line
=Record
[-1])
611 self
.DefaultStores
[Record
[1].upper()] = (self
.ToInt(Record
[0]),Record
[1].upper())
612 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
613 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
614 GlobalData
.gDefaultStores
= self
.DefaultStores
.keys()
615 if GlobalData
.gDefaultStores
:
616 GlobalData
.gDefaultStores
.sort()
617 return self
.DefaultStores
619 ## Retrieve [Components] section information
620 def _GetModules(self
):
621 if self
._Modules
!= None:
624 self
._Modules
= sdict()
625 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
626 Macros
= self
._Macros
627 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
628 for Record
in RecordList
:
629 DuplicatedFile
= False
631 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
635 # check the file validation
636 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
638 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
641 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
642 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
643 DuplicatedFile
= True
645 Module
= ModuleBuildClassObject()
646 Module
.MetaFile
= ModuleFile
648 # get module private library instance
649 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
650 for Record
in RecordList
:
651 LibraryClass
= Record
[0]
652 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
655 # check the file validation
656 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
658 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
661 if LibraryClass
== '' or LibraryClass
== 'NULL':
662 self
._NullLibraryNumber
+= 1
663 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
664 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
665 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
666 if LibraryPath
not in self
.LibraryInstances
:
667 self
.LibraryInstances
.append(LibraryPath
)
669 # get module private PCD setting
670 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
671 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
672 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
673 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
674 TokenList
= GetSplitValueList(Setting
)
675 DefaultValue
= TokenList
[0]
676 if len(TokenList
) > 1:
677 MaxDatumSize
= TokenList
[1]
680 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
681 Pcd
= PcdClassObject(
693 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
695 # get module private build options
696 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
697 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
698 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
699 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
701 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
702 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
704 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
705 if DuplicatedFile
and not RecordList
:
706 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
708 if len(RecordList
) != 1:
709 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
710 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
711 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
712 ModuleFile
.Arch
= self
._Arch
714 self
._Modules
[ModuleFile
] = Module
717 ## Retrieve all possible library instances used in this platform
718 def _GetLibraryInstances(self
):
719 if self
._LibraryInstances
== None:
720 self
._GetLibraryClasses
()
721 return self
._LibraryInstances
723 ## Retrieve [LibraryClasses] information
724 def _GetLibraryClasses(self
):
725 if self
._LibraryClasses
== None:
726 self
._LibraryInstances
= []
728 # tdict is a special dict kind of type, used for selecting correct
729 # library instance for given library class and module type
731 LibraryClassDict
= tdict(True, 3)
732 # track all library class names
733 LibraryClassSet
= set()
734 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
735 Macros
= self
._Macros
736 for Record
in RecordList
:
737 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
738 if LibraryClass
== '' or LibraryClass
== 'NULL':
739 self
._NullLibraryNumber
+= 1
740 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
741 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
742 LibraryClassSet
.add(LibraryClass
)
743 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
744 # check the file validation
745 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
747 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
750 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
751 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
752 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
753 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
754 if LibraryInstance
not in self
._LibraryInstances
:
755 self
._LibraryInstances
.append(LibraryInstance
)
757 # resolve the specific library instance for each class and each module type
758 self
._LibraryClasses
= tdict(True)
759 for LibraryClass
in LibraryClassSet
:
760 # try all possible module types
761 for ModuleType
in SUP_MODULE_LIST
:
762 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
763 if LibraryInstance
== None:
765 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
767 # for Edk style library instances, which are listed in different section
768 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
769 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
770 for Record
in RecordList
:
771 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
773 # check the file validation
774 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
776 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
778 if File
not in self
._LibraryInstances
:
779 self
._LibraryInstances
.append(File
)
781 # we need the module name as the library class name, so we have
782 # to parse it here. (self._Bdb[] will trigger a file parse if it
783 # hasn't been parsed)
785 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
786 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
787 return self
._LibraryClasses
789 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
790 if self
._DecPcds
== None:
793 if GlobalData
.gFdfParser
:
794 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
797 for Inf
in FdfInfList
:
798 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
799 if ModuleFile
in self
._Modules
:
801 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
802 PkgSet
.update(ModuleData
.Packages
)
804 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
807 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
808 EdkLogger
.error('build', PARSER_ERROR
,
809 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
810 File
=self
.MetaFile
, Line
=LineNo
)
811 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
813 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
814 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
815 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
817 if ValueList
[2] == '-1':
818 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
819 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
820 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
822 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
823 except WrnExpression
, Value
:
824 ValueList
[Index
] = Value
.result
825 except BadExpression
, Value
:
826 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
827 except EvaluationException
, Excpt
:
828 if hasattr(Excpt
, 'Pcd'):
829 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
830 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
831 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
832 " of the DSC file" % Excpt
.Pcd
,
833 File
=self
.MetaFile
, Line
=LineNo
)
835 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
836 File
=self
.MetaFile
, Line
=LineNo
)
838 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
839 File
=self
.MetaFile
, Line
=LineNo
)
841 DatumType
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
843 ValueList
[Index
] = ValueExpressionEx(ValueList
[Index
], DatumType
, self
._GuidDict
)(True)
844 except BadExpression
, Value
:
845 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=LineNo
,
846 ExtraData
="PCD [%s.%s] Value \"%s\" " % (TokenSpaceGuid
, PcdCName
, ValueList
[Index
]))
847 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
849 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
850 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
851 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
852 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
853 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
854 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
857 def _FilterPcdBySkuUsage(self
,Pcds
):
858 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
859 sku_usage
= self
.SkuIdMgr
.SkuUsageType
860 if sku_usage
== SkuClass
.SINGLE
:
863 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
864 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
865 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
869 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
870 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
871 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
873 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
874 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
]]]
875 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
877 for skuid
in pcd
.SkuInfoList
:
878 skuobj
= pcd
.SkuInfoList
.get(skuid
)
879 if "STANDARD" not in skuobj
.DefaultStoreDict
:
880 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
881 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
882 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
885 ## Retrieve all PCD settings in platform
887 if self
._Pcds
== None:
889 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
890 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
891 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
892 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
893 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
894 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
895 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
896 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
897 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
899 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
900 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
901 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
902 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
905 def _dumpPcdInfo(self
,Pcds
):
908 if not pcdobj
.TokenCName
.startswith("Test"):
910 for skuid
in pcdobj
.SkuInfoList
:
911 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
912 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
913 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
915 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
916 ## Retrieve [BuildOptions]
917 def _GetBuildOptions(self
):
918 if self
._BuildOptions
== None:
919 self
._BuildOptions
= sdict()
921 # Retrieve build option for EDKII and EDK style module
923 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
924 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
925 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
926 if Dummy3
.upper() != 'COMMON':
928 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
930 # Only flags can be appended
932 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
933 self
._BuildOptions
[CurKey
] = Option
935 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
936 self
._BuildOptions
[CurKey
] += ' ' + Option
937 return self
._BuildOptions
939 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
940 if self
._ModuleTypeOptions
== None:
941 self
._ModuleTypeOptions
= sdict()
942 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
944 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
945 DriverType
= '%s.%s' % (Edk
, ModuleType
)
946 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
947 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
948 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
949 Type
= Dummy2
+ '.' + Dummy3
950 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
951 Key
= (ToolChainFamily
, ToolChain
, Edk
)
952 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
953 options
[Key
] = Option
955 if ' ' + Option
not in options
[Key
]:
956 options
[Key
] += ' ' + Option
957 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
959 def GetStructurePcdInfo(self
, PcdSet
):
960 structure_pcd_data
= {}
962 if (item
[0],item
[1]) not in structure_pcd_data
:
963 structure_pcd_data
[(item
[0],item
[1])] = []
964 structure_pcd_data
[(item
[0],item
[1])].append(item
)
966 return structure_pcd_data
968 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
970 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
971 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
972 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
973 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
974 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
975 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
978 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
979 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
980 SkuIds
.update({'DEFAULT':0})
981 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
984 # Find out all possible PCD candidates for self._Arch
987 for Type
in TypeList
:
988 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
990 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
991 SkuName
= SkuName
.upper()
992 default_store
= default_store
.upper()
993 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
994 if SkuName
not in SkuIds
:
997 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
998 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
1000 # handle pcd value override
1001 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
1003 for str_pcd
in StrPcdSet
:
1004 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1005 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1007 str_pcd_obj_str
= StructurePcd()
1008 str_pcd_obj_str
.copy(str_pcd_dec
)
1010 str_pcd_obj_str
.copy(str_pcd_obj
)
1011 if str_pcd_obj
.DefaultValue
:
1012 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1013 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1014 if str_pcd_data
[3] in SkuIds
:
1015 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])
1016 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1018 EdkLogger
.error('build', PARSER_ERROR
,
1019 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1020 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1021 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1022 for Pcd
in self
.DecPcds
:
1023 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1024 if Pcd
not in S_pcd_set
:
1025 str_pcd_obj_str
= StructurePcd()
1026 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1027 str_pcd_obj
= Pcds
.get(Pcd
, None)
1029 str_pcd_obj_str
.copy(str_pcd_obj
)
1030 if str_pcd_obj
.DefaultValue
:
1031 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1032 S_pcd_set
[Pcd
] = str_pcd_obj_str
1034 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1035 for stru_pcd
in S_pcd_set
.values():
1036 for skuid
in SkuIds
:
1037 if skuid
in stru_pcd
.SkuOverrideValues
:
1039 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1041 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1042 if nextskuid
== "DEFAULT":
1045 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1046 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
})
1047 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1048 for skuid
in SkuIds
:
1051 if skuid
not in stru_pcd
.SkuOverrideValues
:
1052 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1053 if nextskuid
== "DEFAULT":
1056 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1059 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1060 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1062 for defaultstoreid
in DefaultStores
:
1063 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1064 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1066 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1068 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1069 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1070 if str_pcd_obj
is None:
1071 print PcdName
, PcdGuid
1073 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1074 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1075 if skuname
not in str_pcd_obj
.SkuInfoList
:
1076 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1078 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1079 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1080 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1081 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1082 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1083 str_pcd_obj
.DefaultValue
= PcdValue
1085 if skuname
not in str_pcd_obj
.SkuInfoList
:
1086 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1088 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1089 if nextskuid
== "DEFAULT":
1092 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1093 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
)
1094 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1095 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1097 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1098 for str_pcd_obj
in S_pcd_set
.values():
1099 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1100 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1102 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1103 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1104 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1105 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1107 for str_pcd_obj
in S_pcd_set
.values():
1109 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1110 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1114 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1115 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1116 del(pcd
.SkuInfoList
['COMMON'])
1117 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1118 del(pcd
.SkuInfoList
['COMMON'])
1120 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1123 ## Retrieve non-dynamic PCD settings
1125 # @param Type PCD type
1127 # @retval a dict object contains settings of given PCD type
1129 def _GetPcd(self
, Type
):
1132 # tdict is a special dict kind of type, used for selecting correct
1133 # PCD settings for certain ARCH
1135 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1137 PcdDict
= tdict(True, 3)
1139 # Find out all possible PCD candidates for self._Arch
1140 RecordList
= self
._RawData
[Type
, self
._Arch
]
1141 PcdValueDict
= sdict()
1142 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1143 SkuName
= SkuName
.upper()
1144 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1145 if SkuName
not in AvailableSkuIdSet
:
1146 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1147 File
=self
.MetaFile
, Line
=Dummy5
)
1148 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1149 if "." not in TokenSpaceGuid
:
1150 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1151 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1153 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1154 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1157 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1158 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1159 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1161 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1163 PcdsKeys
= PcdValueDict
.keys()
1164 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1166 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1170 if 'COMMON' in PcdSetting
:
1171 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1172 if 'DEFAULT' in PcdSetting
:
1173 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1174 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1175 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1177 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1180 self
._PCD
_TYPE
_STRING
_[Type
],
1193 def __UNICODE2OCTList(self
,Value
):
1194 Value
= Value
.strip()
1198 Temp
= '%04X' % ord(Item
)
1199 List
.append('0x' + Temp
[2:4])
1200 List
.append('0x' + Temp
[0:2])
1204 def __STRING2OCTList(self
,Value
):
1206 Value
= Value
.strip('"')
1208 Temp
= '%02X' % ord(char
)
1209 OCTList
.append('0x' + Temp
)
1210 OCTList
.append('0x00')
1213 def GetStructurePcdMaxSize(self
, str_pcd
):
1214 pcd_default_value
= str_pcd
.DefaultValue
1215 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()]
1216 sku_values
.append(pcd_default_value
)
1218 def get_length(value
):
1219 Value
= value
.strip()
1221 if Value
.startswith('GUID') and Value
.endswith(')'):
1223 if Value
.startswith('L"') and Value
.endswith('"'):
1224 return len(Value
[2:-1])
1225 if Value
[0] == '"' and Value
[-1] == '"':
1226 return len(Value
) - 2
1227 if Value
[0] == '{' and Value
[-1] == '}':
1228 return len(Value
.split(","))
1229 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1230 return len(list(Value
[2:-1]))
1231 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1232 return len(Value
) - 2
1235 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1237 def IsFieldValueAnArray (self
, Value
):
1238 Value
= Value
.strip()
1239 if Value
.startswith('GUID') and Value
.endswith(')'):
1241 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1243 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1245 if Value
[0] == '{' and Value
[-1] == '}':
1247 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1248 print 'foo = ', list(Value
[2:-1])
1250 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1251 print 'bar = ', list(Value
[1:-1])
1255 def ExecuteCommand (self
, Command
):
1257 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1259 print 'ERROR: Can not execute command:', Command
1261 Result
= Process
.communicate()
1262 if Process
.returncode
<> 0:
1263 print 'ERROR: Can not collect output from command:', Command
1264 return Result
[0], Result
[1]
1266 def IntToCString(self
, Value
, ValueSize
):
1268 if not isinstance (Value
, str):
1269 for Index
in range(0, ValueSize
):
1270 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1272 Result
= Result
+ '"'
1275 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1276 OverrideValues
= {DefaultStoreName
:""}
1277 if Pcd
.SkuOverrideValues
:
1278 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1279 for DefaultStoreName
in OverrideValues
.keys():
1280 CApp
= CApp
+ 'void\n'
1281 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1282 CApp
= CApp
+ ' void\n'
1283 CApp
= CApp
+ ' )\n'
1285 CApp
= CApp
+ ' UINT32 Size;\n'
1286 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1287 CApp
= CApp
+ ' CHAR8 *Value;\n'
1288 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1289 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1290 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1293 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1294 PcdDefaultValue
= StringToArray(Pcd
.DefaultValue
)
1296 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1299 # Get current PCD value and size
1301 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1304 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1305 # the correct value. For structures with a flexible array member, the flexible
1306 # array member is detected, and the size is based on the highest index used with
1307 # the flexible array member. The flexible array member must be the last field
1308 # in a structure. The size formula for this case is:
1309 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1311 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1312 for FieldList
in [Pcd
.DefaultValues
]:
1315 for FieldName
in FieldList
:
1316 FieldName
= "." + FieldName
1317 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1319 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1320 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("."));
1323 while '[' in FieldName
:
1324 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1325 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1326 FieldName
= FieldName
.split(']', 1)[1]
1327 FieldName
= NewFieldName
+ FieldName
1328 while '[' in FieldName
:
1329 FieldName
= FieldName
.rsplit('[', 1)[0]
1330 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1331 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1332 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1333 for FieldList
in [inherit_OverrideValues
.get(DefaultStoreName
)]:
1336 for FieldName
in FieldList
:
1337 FieldName
= "." + FieldName
1338 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1340 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1341 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("."));
1344 while '[' in FieldName
:
1345 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1346 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1347 FieldName
= FieldName
.split(']', 1)[1]
1348 FieldName
= NewFieldName
+ FieldName
1349 while '[' in FieldName
:
1350 FieldName
= FieldName
.rsplit('[', 1)[0]
1351 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1352 if skuname
== SkuName
:
1356 # Allocate and zero buffer for the PCD
1357 # Must handle cases where current value is smaller, larger, or same size
1358 # Always keep that larger one as the current size
1360 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1361 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1362 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1365 # Copy current PCD value into allocated buffer.
1367 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1370 # Assign field values in PCD
1372 for FieldList
in [Pcd
.DefaultValues
]:
1375 for FieldName
in FieldList
:
1376 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1378 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1380 print FieldList
[FieldName
][0]
1381 if isinstance(Value
, str):
1382 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1385 # Use memcpy() to copy value into field
1387 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1388 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1389 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1392 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1394 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1395 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1396 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1397 for FieldList
in [Pcd
.DefaultFromDSC
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1400 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1401 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1402 Value
, ValueSize
= ParseFieldValue (FieldList
)
1403 if isinstance(Value
, str):
1404 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1407 # Use memcpy() to copy value into field
1409 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1410 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1413 for FieldName
in FieldList
:
1414 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1416 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1418 print FieldList
[FieldName
][0]
1419 if isinstance(Value
, str):
1420 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1423 # Use memcpy() to copy value into field
1425 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1426 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1427 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1430 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1432 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1433 if skuname
== SkuName
:
1436 # Set new PCD value and size
1438 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1443 CApp
= CApp
+ ' free (Pcd);\n'
1446 return InitByteValue
, CApp
1448 def GenerateByteArrayValue (self
, StructuredPcds
):
1450 # Generate/Compile/Run C application to determine if there are any flexible array members
1452 if not StructuredPcds
:
1456 CApp
= PcdMainCHeader
1459 for PcdName
in StructuredPcds
:
1460 Pcd
= StructuredPcds
[PcdName
]
1461 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1462 if IncludeFile
not in Includes
:
1463 Includes
[IncludeFile
] = True
1464 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1467 for PcdName
in StructuredPcds
:
1468 Pcd
= StructuredPcds
[PcdName
]
1469 if not Pcd
.SkuOverrideValues
:
1470 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1472 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1473 if SkuName
not in Pcd
.SkuOverrideValues
:
1475 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1476 Pcd
= StructuredPcds
[PcdName
]
1477 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1479 CApp
= CApp
+ 'VOID\n'
1480 CApp
= CApp
+ 'PcdEntryPoint(\n'
1481 CApp
= CApp
+ ' VOID\n'
1482 CApp
= CApp
+ ' )\n'
1484 for Pcd
in StructuredPcds
.values():
1485 if not Pcd
.SkuOverrideValues
:
1486 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1488 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1489 if SkuName
not in Pcd
.SkuOverrideValues
:
1491 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1492 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1495 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1497 if not os
.path
.exists(self
.OutputPath
):
1498 os
.makedirs(self
.OutputPath
)
1499 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1500 File
= open (CAppBaseFileName
+ '.c', 'w')
1504 MakeApp
= PcdMakefileHeader
1505 if sys
.platform
== "win32":
1506 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1508 MakeApp
= MakeApp
+ PcdGccMakefile
1509 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1510 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1513 for Cache
in self
._Bdb
._CACHE
_.values():
1514 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1517 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1518 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1521 for Pcd
in StructuredPcds
.values():
1522 for PackageDec
in Pcd
.PackageDecs
:
1523 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1524 if not os
.path
.exists(Package
):
1525 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1526 if Package
not in PcdDependDEC
:
1527 PcdDependDEC
.append(Package
)
1529 if PlatformInc
and PcdDependDEC
:
1530 for pkg
in PcdDependDEC
:
1531 if pkg
in PlatformInc
:
1532 for inc
in PlatformInc
[pkg
]:
1533 MakeApp
+= '-I' + str(inc
) + ' '
1534 MakeApp
= MakeApp
+ '\n'
1536 CC_FLAGS
= LinuxCFLAGS
1537 if sys
.platform
== "win32":
1538 CC_FLAGS
= WindowsCFLAGS
1540 for Options
in self
.BuildOptions
:
1541 if Options
[2] != EDKII_NAME
:
1544 if Family
and Family
!= self
.ToolChainFamily
:
1546 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
1550 if Target
== "*" or Target
== self
._Target
:
1551 if Tag
== "*" or Tag
== self
._Toolchain
:
1552 if Arch
== "*" or Arch
== self
.Arch
:
1553 if Tool
not in BuildOptions
:
1554 BuildOptions
[Tool
] = {}
1555 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
1556 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1558 # append options for the same tool except PATH
1560 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
1562 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1564 for Tool
in BuildOptions
:
1565 for Attr
in BuildOptions
[Tool
]:
1567 Value
= BuildOptions
[Tool
][Attr
]
1568 ValueList
= Value
.split()
1570 for Id
, Item
in enumerate(ValueList
):
1571 if Item
== '-D' or Item
== '/D':
1572 CC_FLAGS
+= ' ' + Item
1573 if Id
+ 1 < len(ValueList
):
1574 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
1575 elif Item
.startswith('/D') or Item
.startswith('-D'):
1576 CC_FLAGS
+= ' ' + Item
1579 if sys
.platform
== "win32":
1580 MakeApp
= MakeApp
+ PcdMakefileEnd
1581 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1582 File
= open (MakeFileName
, 'w')
1586 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1587 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1588 File
= open (InputValueFile
, 'w')
1589 File
.write(InitByteValue
)
1593 if sys
.platform
== "win32":
1594 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1597 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1599 Messages
= Messages
.split('\n')
1600 for Message
in Messages
:
1601 if " error" in Message
:
1602 FileInfo
= Message
.strip().split('(')
1603 if len (FileInfo
) > 1:
1604 FileName
= FileInfo
[0]
1605 FileLine
= FileInfo
[1].split (')')[0]
1607 FileInfo
= Message
.strip().split(':')
1608 FileName
= FileInfo
[0]
1609 FileLine
= FileInfo
[1]
1611 File
= open (FileName
, 'r')
1612 FileData
= File
.readlines()
1614 error_line
= FileData
[int (FileLine
) - 1]
1615 if r
"//" in error_line
:
1616 c_line
,dsc_line
= error_line
.split(r
"//")
1618 dsc_line
= error_line
1620 message_itmes
= Message
.split(":")
1622 for item
in message_itmes
:
1623 if "PcdValueInit.c" in item
:
1624 Index
= message_itmes
.index(item
)
1625 message_itmes
[Index
] = dsc_line
.strip()
1628 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[Index
:]))
1630 PcdValueInitExe
= PcdValueInitName
1631 if not sys
.platform
== "win32":
1632 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1634 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1635 File
= open (OutputValueFile
, 'r')
1636 FileBuffer
= File
.readlines()
1639 StructurePcdSet
= []
1640 for Pcd
in FileBuffer
:
1641 PcdValue
= Pcd
.split ('|')
1642 PcdInfo
= PcdValue
[0].split ('.')
1643 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1644 return StructurePcdSet
1646 ## Retrieve dynamic PCD settings
1648 # @param Type PCD type
1650 # @retval a dict object contains settings of given PCD type
1652 def _GetDynamicPcd(self
, Type
):
1657 # tdict is a special dict kind of type, used for selecting correct
1658 # PCD settings for certain ARCH and SKU
1660 PcdDict
= tdict(True, 4)
1662 # Find out all possible PCD candidates for self._Arch
1663 RecordList
= self
._RawData
[Type
, self
._Arch
]
1664 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1667 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1668 SkuName
= SkuName
.upper()
1669 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1670 if SkuName
not in AvailableSkuIdSet
:
1671 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1672 File
=self
.MetaFile
, Line
=Dummy5
)
1673 if "." not in TokenSpaceGuid
:
1674 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1675 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1677 # Remove redundant PCD candidates, per the ARCH and SKU
1678 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1680 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1684 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1685 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1686 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1687 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1688 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1689 if MaxDatumSize
.strip():
1690 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1693 if pcdObject
.MaxDatumSize
:
1694 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1697 if CurrentMaxSize
> PcdMaxSize
:
1698 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1700 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1703 self
._PCD
_TYPE
_STRING
_[Type
],
1708 {SkuName
: SkuInfo
},
1713 for pcd
in Pcds
.values():
1714 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1715 # Only fix the value while no value provided in DSC file.
1716 for sku
in pcd
.SkuInfoList
.values():
1717 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1718 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1719 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1720 valuefromDec
= pcdDecObject
.DefaultValue
1721 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1722 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1723 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1724 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1725 del(pcd
.SkuInfoList
['COMMON'])
1726 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1727 del(pcd
.SkuInfoList
['COMMON'])
1729 map(self
.FilterSkuSettings
,Pcds
.values())
1733 def FilterSkuSettings(self
, PcdObj
):
1735 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1736 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1737 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1738 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1739 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1740 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1742 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1743 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1748 def CompareVarAttr(self
, Attr1
, Attr2
):
1749 if not Attr1
or not Attr2
: # for empty string
1751 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1752 Attr1Set
= set(Attr1s
)
1753 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1754 Attr2Set
= set(Attr2s
)
1755 if Attr2Set
== Attr1Set
:
1759 def CompletePcdValues(self
,PcdSet
):
1761 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1762 SkuIds
= {skuname
:skuid
for skuname
,skuid
in self
.SkuIdMgr
.AvailableSkuIdSet
.items() if skuname
!='COMMON'}
1763 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1764 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1765 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1766 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1767 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1768 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1769 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1770 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1771 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1772 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1774 PcdType
= PcdObj
.Type
1775 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1776 for skuid
in PcdObj
.SkuInfoList
:
1777 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1778 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1779 for defaultstorename
in DefaultStores
:
1780 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1781 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1782 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1783 for skuname
,skuid
in SkuIds
.items():
1784 if skuname
not in PcdObj
.SkuInfoList
:
1785 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1786 while nextskuid
not in PcdObj
.SkuInfoList
:
1787 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1788 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1789 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1790 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1791 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1792 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1793 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1795 ## Retrieve dynamic HII PCD settings
1797 # @param Type PCD type
1799 # @retval a dict object contains settings of given PCD type
1801 def _GetDynamicHiiPcd(self
, Type
):
1807 # tdict is a special dict kind of type, used for selecting correct
1808 # PCD settings for certain ARCH and SKU
1810 PcdDict
= tdict(True, 5)
1812 RecordList
= self
._RawData
[Type
, self
._Arch
]
1813 # Find out all possible PCD candidates for self._Arch
1814 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1815 DefaultStoresDefine
= self
._GetDefaultStores
()
1817 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1818 SkuName
= SkuName
.upper()
1819 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1820 DefaultStore
= DefaultStore
.upper()
1821 if DefaultStore
== "COMMON":
1822 DefaultStore
= "STANDARD"
1823 if SkuName
not in AvailableSkuIdSet
:
1824 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1825 File
=self
.MetaFile
, Line
=Dummy5
)
1826 if DefaultStore
not in DefaultStoresDefine
:
1827 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1828 File
=self
.MetaFile
, Line
=Dummy5
)
1829 if "." not in TokenSpaceGuid
:
1830 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1831 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1834 # Remove redundant PCD candidates, per the ARCH and SKU
1835 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1837 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1840 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1842 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1844 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1845 ExtraData
="[%s]" % VarAttribute
)
1847 FormatCorrect
= True
1848 if VariableOffset
.isdigit():
1849 if int(VariableOffset
, 10) > 0xFFFF:
1851 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1852 if int(VariableOffset
, 16) > 0xFFFF:
1854 # For Offset written in "A.B"
1855 elif VariableOffset
.find('.') > -1:
1856 VariableOffsetList
= VariableOffset
.split(".")
1857 if not (len(VariableOffsetList
) == 2
1858 and IsValidWord(VariableOffsetList
[0])
1859 and IsValidWord(VariableOffsetList
[1])):
1860 FormatCorrect
= False
1862 FormatCorrect
= False
1863 if not FormatCorrect
:
1864 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1867 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1868 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1869 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1871 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1872 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
)]))
1874 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1875 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1876 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1877 if SkuName
in pcdObject
.SkuInfoList
:
1878 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1879 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1881 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1882 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1884 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1885 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1888 self
._PCD
_TYPE
_STRING
_[Type
],
1893 {SkuName
: SkuInfo
},
1896 pcdDecObject
.validateranges
,
1897 pcdDecObject
.validlists
,
1898 pcdDecObject
.expressions
,
1902 for pcd
in Pcds
.values():
1903 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1904 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1905 # Only fix the value while no value provided in DSC file.
1906 for sku
in pcd
.SkuInfoList
.values():
1907 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1908 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1909 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1910 valuefromDec
= pcdDecObject
.DefaultValue
1911 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1912 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1913 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1914 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1915 del(pcd
.SkuInfoList
['COMMON'])
1916 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1917 del(pcd
.SkuInfoList
['COMMON'])
1919 if pcd
.MaxDatumSize
.strip():
1920 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1923 if pcdDecObject
.DatumType
== 'VOID*':
1924 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1926 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1927 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1928 if datalen
> MaxSize
:
1930 for defaultst
in skuobj
.DefaultStoreDict
:
1931 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1932 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1933 pcd
.MaxDatumSize
= str(MaxSize
)
1934 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1936 invalidpcd
= ",".join(invalidhii
)
1937 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
)
1939 map(self
.FilterSkuSettings
,Pcds
.values())
1943 def CheckVariableNameAssignment(self
,Pcds
):
1945 for pcdname
in Pcds
:
1947 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1948 if len(varnameset
) > 1:
1949 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1951 return False,invalidhii
1954 ## Retrieve dynamic VPD PCD settings
1956 # @param Type PCD type
1958 # @retval a dict object contains settings of given PCD type
1960 def _GetDynamicVpdPcd(self
, Type
):
1965 # tdict is a special dict kind of type, used for selecting correct
1966 # PCD settings for certain ARCH and SKU
1968 PcdDict
= tdict(True, 4)
1971 # Find out all possible PCD candidates for self._Arch
1972 RecordList
= self
._RawData
[Type
, self
._Arch
]
1973 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1975 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1976 SkuName
= SkuName
.upper()
1977 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1978 if SkuName
not in AvailableSkuIdSet
:
1979 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1980 File
=self
.MetaFile
, Line
=Dummy5
)
1981 if "." not in TokenSpaceGuid
:
1982 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1983 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1985 # Remove redundant PCD candidates, per the ARCH and SKU
1986 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1987 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1991 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1992 # For the Integer & Boolean type, the optional data can only be InitialValue.
1993 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1994 # until the DEC parser has been called.
1996 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1997 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
1998 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1999 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2000 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2001 if MaxDatumSize
.strip():
2002 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2005 if pcdObject
.MaxDatumSize
:
2006 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2009 if CurrentMaxSize
> PcdMaxSize
:
2010 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2012 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2015 self
._PCD
_TYPE
_STRING
_[Type
],
2020 {SkuName
: SkuInfo
},
2024 for pcd
in Pcds
.values():
2025 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2026 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2027 # Only fix the value while no value provided in DSC file.
2028 for sku
in pcd
.SkuInfoList
.values():
2029 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
2030 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2031 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
2032 valuefromDec
= pcdDecObject
.DefaultValue
2033 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
2034 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
2035 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2036 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
2037 del(pcd
.SkuInfoList
['COMMON'])
2038 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2039 del(pcd
.SkuInfoList
['COMMON'])
2042 map(self
.FilterSkuSettings
,Pcds
.values())
2045 ## Add external modules
2047 # The external modules are mostly those listed in FDF file, which don't
2050 # @param FilePath The path of module description file
2052 def AddModule(self
, FilePath
):
2053 FilePath
= NormPath(FilePath
)
2054 if FilePath
not in self
.Modules
:
2055 Module
= ModuleBuildClassObject()
2056 Module
.MetaFile
= FilePath
2057 self
.Modules
.append(Module
)
2059 def _GetToolChainFamily(self
):
2060 self
._ToolChainFamily
= "MSFT"
2061 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2062 if os
.path
.isfile(BuildConfigurationFile
) == True:
2063 TargetTxt
= TargetTxtClassObject()
2064 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2065 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2066 if ToolDefinitionFile
== '':
2067 ToolDefinitionFile
= "tools_def.txt"
2068 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2069 if os
.path
.isfile(ToolDefinitionFile
) == True:
2070 ToolDef
= ToolDefClassObject()
2071 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2072 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2073 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2074 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2075 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2076 self
._ToolChainFamily
= "MSFT"
2078 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2079 return self
._ToolChainFamily
2081 ## Add external PCDs
2083 # The external PCDs are mostly those listed in FDF file to specify address
2084 # or offset information.
2086 # @param Name Name of the PCD
2087 # @param Guid Token space guid of the PCD
2088 # @param Value Value of the PCD
2090 def AddPcd(self
, Name
, Guid
, Value
):
2091 if (Name
, Guid
) not in self
.Pcds
:
2092 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2093 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2096 if self
._DecPcds
== None:
2098 if GlobalData
.gFdfParser
:
2099 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2101 for Inf
in FdfInfList
:
2102 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2103 if ModuleFile
in self
._Modules
:
2105 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2106 PkgSet
.update(ModuleData
.Packages
)
2107 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2108 return self
._DecPcds
2109 _Macros
= property(_GetMacros
)
2110 Arch
= property(_GetArch
, _SetArch
)
2111 Platform
= property(_GetPlatformName
)
2112 PlatformName
= property(_GetPlatformName
)
2113 Guid
= property(_GetFileGuid
)
2114 Version
= property(_GetVersion
)
2115 DscSpecification
= property(_GetDscSpec
)
2116 OutputDirectory
= property(_GetOutpuDir
)
2117 SupArchList
= property(_GetSupArch
)
2118 BuildTargets
= property(_GetBuildTarget
)
2119 SkuName
= property(_GetSkuName
, _SetSkuName
)
2120 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2121 VarCheckFlag
= property(_GetVarCheckFlag
)
2122 FlashDefinition
= property(_GetFdfFile
)
2123 Prebuild
= property(_GetPrebuild
)
2124 Postbuild
= property(_GetPostbuild
)
2125 BuildNumber
= property(_GetBuildNumber
)
2126 MakefileName
= property(_GetMakefileName
)
2127 BsBaseAddress
= property(_GetBsBaseAddress
)
2128 RtBaseAddress
= property(_GetRtBaseAddress
)
2129 LoadFixAddress
= property(_GetLoadFixAddress
)
2130 RFCLanguages
= property(_GetRFCLanguages
)
2131 ISOLanguages
= property(_GetISOLanguages
)
2132 VpdToolGuid
= property(_GetVpdToolGuid
)
2133 SkuIds
= property(_GetSkuIds
)
2134 Modules
= property(_GetModules
)
2135 LibraryInstances
= property(_GetLibraryInstances
)
2136 LibraryClasses
= property(_GetLibraryClasses
)
2137 Pcds
= property(_GetPcds
)
2138 BuildOptions
= property(_GetBuildOptions
)
2139 ToolChainFamily
= property(_GetToolChainFamily
)