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 Pattern
= re
.compile('^[1-9]\d*|0$')
612 HexPattern
= re
.compile(r
'0[xX][0-9a-fA-F]+$')
613 if Pattern
.match(Record
[0]) == None and HexPattern
.match(Record
[0]) == None:
614 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
615 File
=self
.MetaFile
, Line
=Record
[-1])
616 if not IsValidWord(Record
[1]):
617 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
618 File
=self
.MetaFile
, Line
=Record
[-1])
619 self
.DefaultStores
[Record
[1].upper()] = (self
.ToInt(Record
[0]),Record
[1].upper())
620 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
621 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
622 GlobalData
.gDefaultStores
= self
.DefaultStores
.keys()
623 if GlobalData
.gDefaultStores
:
624 GlobalData
.gDefaultStores
.sort()
625 return self
.DefaultStores
627 ## Retrieve [Components] section information
628 def _GetModules(self
):
629 if self
._Modules
!= None:
632 self
._Modules
= sdict()
633 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
634 Macros
= self
._Macros
635 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
636 for Record
in RecordList
:
637 DuplicatedFile
= False
639 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
643 # check the file validation
644 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
646 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
649 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
650 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
651 DuplicatedFile
= True
653 Module
= ModuleBuildClassObject()
654 Module
.MetaFile
= ModuleFile
656 # get module private library instance
657 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
658 for Record
in RecordList
:
659 LibraryClass
= Record
[0]
660 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
663 # check the file validation
664 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
666 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
669 if LibraryClass
== '' or LibraryClass
== 'NULL':
670 self
._NullLibraryNumber
+= 1
671 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
672 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
673 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
674 if LibraryPath
not in self
.LibraryInstances
:
675 self
.LibraryInstances
.append(LibraryPath
)
677 # get module private PCD setting
678 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
679 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
680 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
681 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
682 TokenList
= GetSplitValueList(Setting
)
683 DefaultValue
= TokenList
[0]
684 if len(TokenList
) > 1:
685 MaxDatumSize
= TokenList
[1]
688 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
689 Pcd
= PcdClassObject(
701 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
703 # get module private build options
704 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
705 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
706 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
707 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
709 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
710 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
712 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
713 if DuplicatedFile
and not RecordList
:
714 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
716 if len(RecordList
) != 1:
717 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
718 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
719 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
720 ModuleFile
.Arch
= self
._Arch
722 self
._Modules
[ModuleFile
] = Module
725 ## Retrieve all possible library instances used in this platform
726 def _GetLibraryInstances(self
):
727 if self
._LibraryInstances
== None:
728 self
._GetLibraryClasses
()
729 return self
._LibraryInstances
731 ## Retrieve [LibraryClasses] information
732 def _GetLibraryClasses(self
):
733 if self
._LibraryClasses
== None:
734 self
._LibraryInstances
= []
736 # tdict is a special dict kind of type, used for selecting correct
737 # library instance for given library class and module type
739 LibraryClassDict
= tdict(True, 3)
740 # track all library class names
741 LibraryClassSet
= set()
742 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
743 Macros
= self
._Macros
744 for Record
in RecordList
:
745 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
746 if LibraryClass
== '' or LibraryClass
== 'NULL':
747 self
._NullLibraryNumber
+= 1
748 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
749 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
750 LibraryClassSet
.add(LibraryClass
)
751 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
752 # check the file validation
753 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
755 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
758 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
759 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
760 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
761 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
762 if LibraryInstance
not in self
._LibraryInstances
:
763 self
._LibraryInstances
.append(LibraryInstance
)
765 # resolve the specific library instance for each class and each module type
766 self
._LibraryClasses
= tdict(True)
767 for LibraryClass
in LibraryClassSet
:
768 # try all possible module types
769 for ModuleType
in SUP_MODULE_LIST
:
770 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
771 if LibraryInstance
== None:
773 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
775 # for Edk style library instances, which are listed in different section
776 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
777 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
778 for Record
in RecordList
:
779 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
781 # check the file validation
782 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
784 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
786 if File
not in self
._LibraryInstances
:
787 self
._LibraryInstances
.append(File
)
789 # we need the module name as the library class name, so we have
790 # to parse it here. (self._Bdb[] will trigger a file parse if it
791 # hasn't been parsed)
793 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
794 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
795 return self
._LibraryClasses
797 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
798 if self
._DecPcds
== None:
801 if GlobalData
.gFdfParser
:
802 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
805 for Inf
in FdfInfList
:
806 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
807 if ModuleFile
in self
._Modules
:
809 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
810 PkgSet
.update(ModuleData
.Packages
)
812 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
815 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
816 EdkLogger
.error('build', PARSER_ERROR
,
817 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
818 File
=self
.MetaFile
, Line
=LineNo
)
819 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
821 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
822 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
823 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
825 if ValueList
[2] == '-1':
826 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
827 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
829 DatumType
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
831 ValueList
[Index
] = ValueExpressionEx(ValueList
[Index
], DatumType
, self
._GuidDict
)(True)
832 except BadExpression
, Value
:
833 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=LineNo
,
834 ExtraData
="PCD [%s.%s] Value \"%s\" " % (
835 TokenSpaceGuid
, PcdCName
, ValueList
[Index
]))
836 except EvaluationException
, Excpt
:
837 if hasattr(Excpt
, 'Pcd'):
838 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
839 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
840 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
841 " of the DSC file" % Excpt
.Pcd
,
842 File
=self
.MetaFile
, Line
=LineNo
)
844 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
845 File
=self
.MetaFile
, Line
=LineNo
)
847 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
848 File
=self
.MetaFile
, Line
=LineNo
)
851 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
853 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
854 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
855 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
856 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
857 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file." , File
=self
.MetaFile
, Line
=LineNo
,
858 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
859 if (TokenSpaceGuid
+ '.' + PcdCName
) in GlobalData
.gPlatformPcds
:
860 if GlobalData
.gPlatformPcds
[TokenSpaceGuid
+ '.' + PcdCName
] != ValueList
[Index
]:
861 GlobalData
.gPlatformPcds
[TokenSpaceGuid
+ '.' + PcdCName
] = ValueList
[Index
]
864 def _FilterPcdBySkuUsage(self
,Pcds
):
865 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
866 sku_usage
= self
.SkuIdMgr
.SkuUsageType
867 if sku_usage
== SkuClass
.SINGLE
:
870 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
871 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
872 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
876 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
877 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
878 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
880 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
881 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
]]]
882 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
884 for skuid
in pcd
.SkuInfoList
:
885 skuobj
= pcd
.SkuInfoList
.get(skuid
)
886 if "STANDARD" not in skuobj
.DefaultStoreDict
:
887 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
888 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
889 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
892 ## Retrieve all PCD settings in platform
894 if self
._Pcds
== None:
896 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
897 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
898 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
899 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
900 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
901 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
902 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
903 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
904 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
906 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
907 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
908 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
909 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
912 def _dumpPcdInfo(self
,Pcds
):
915 if not pcdobj
.TokenCName
.startswith("Test"):
917 for skuid
in pcdobj
.SkuInfoList
:
918 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
919 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
920 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
922 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
923 ## Retrieve [BuildOptions]
924 def _GetBuildOptions(self
):
925 if self
._BuildOptions
== None:
926 self
._BuildOptions
= sdict()
928 # Retrieve build option for EDKII and EDK style module
930 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
931 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
932 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
933 if Dummy3
.upper() != 'COMMON':
935 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
937 # Only flags can be appended
939 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
940 self
._BuildOptions
[CurKey
] = Option
942 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
943 self
._BuildOptions
[CurKey
] += ' ' + Option
944 return self
._BuildOptions
946 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
947 if self
._ModuleTypeOptions
== None:
948 self
._ModuleTypeOptions
= sdict()
949 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
951 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
952 DriverType
= '%s.%s' % (Edk
, ModuleType
)
953 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
954 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
955 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
956 Type
= Dummy2
+ '.' + Dummy3
957 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
958 Key
= (ToolChainFamily
, ToolChain
, Edk
)
959 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
960 options
[Key
] = Option
962 if ' ' + Option
not in options
[Key
]:
963 options
[Key
] += ' ' + Option
964 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
966 def GetStructurePcdInfo(self
, PcdSet
):
967 structure_pcd_data
= {}
969 if (item
[0],item
[1]) not in structure_pcd_data
:
970 structure_pcd_data
[(item
[0],item
[1])] = []
971 structure_pcd_data
[(item
[0],item
[1])].append(item
)
973 return structure_pcd_data
975 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
977 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
978 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
979 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
980 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
981 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
982 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
985 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
986 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
987 SkuIds
.update({'DEFAULT':0})
988 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
991 # Find out all possible PCD candidates for self._Arch
994 for Type
in TypeList
:
995 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
997 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
998 SkuName
= SkuName
.upper()
999 default_store
= default_store
.upper()
1000 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1001 if SkuName
not in SkuIds
:
1004 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
1005 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
1007 # handle pcd value override
1008 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
1010 for str_pcd
in StrPcdSet
:
1011 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1012 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1013 if not isinstance (str_pcd_dec
, StructurePcd
):
1014 EdkLogger
.error('build', PARSER_ERROR
,
1015 "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1016 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1018 str_pcd_obj_str
= StructurePcd()
1019 str_pcd_obj_str
.copy(str_pcd_dec
)
1021 str_pcd_obj_str
.copy(str_pcd_obj
)
1022 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj_str
.DefaultValue
1023 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1024 if str_pcd_data
[3] in SkuIds
:
1025 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])
1026 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1028 EdkLogger
.error('build', PARSER_ERROR
,
1029 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1030 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1031 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1032 for Pcd
in self
.DecPcds
:
1033 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1034 if Pcd
not in S_pcd_set
:
1035 str_pcd_obj_str
= StructurePcd()
1036 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1037 str_pcd_obj
= Pcds
.get(Pcd
, None)
1039 str_pcd_obj_str
.copy(str_pcd_obj
)
1040 if str_pcd_obj
.DefaultValue
:
1041 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1042 S_pcd_set
[Pcd
] = str_pcd_obj_str
1044 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1045 for stru_pcd
in S_pcd_set
.values():
1046 for skuid
in SkuIds
:
1047 if skuid
in stru_pcd
.SkuOverrideValues
:
1049 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1051 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1052 if nextskuid
== "DEFAULT":
1055 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1056 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
})
1057 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1058 for skuid
in SkuIds
:
1061 if skuid
not in stru_pcd
.SkuOverrideValues
:
1062 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1063 if nextskuid
== "DEFAULT":
1066 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1069 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1070 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1072 for defaultstoreid
in DefaultStores
:
1073 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1074 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1076 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1078 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1079 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1080 if str_pcd_obj
is None:
1081 print PcdName
, PcdGuid
1083 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1084 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1085 if skuname
not in str_pcd_obj
.SkuInfoList
:
1086 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1088 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1089 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1090 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1091 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1092 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1093 str_pcd_obj
.DefaultValue
= PcdValue
1095 if skuname
not in str_pcd_obj
.SkuInfoList
:
1096 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1098 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1099 if nextskuid
== "DEFAULT":
1102 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1103 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
)
1104 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1105 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1107 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1108 for str_pcd_obj
in S_pcd_set
.values():
1109 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1110 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1112 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1113 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1114 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1115 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1117 for str_pcd_obj
in S_pcd_set
.values():
1119 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1120 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1124 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1125 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1126 del(pcd
.SkuInfoList
['COMMON'])
1127 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1128 del(pcd
.SkuInfoList
['COMMON'])
1130 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1133 ## Retrieve non-dynamic PCD settings
1135 # @param Type PCD type
1137 # @retval a dict object contains settings of given PCD type
1139 def _GetPcd(self
, Type
):
1142 # tdict is a special dict kind of type, used for selecting correct
1143 # PCD settings for certain ARCH
1145 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1147 PcdDict
= tdict(True, 3)
1149 # Find out all possible PCD candidates for self._Arch
1150 RecordList
= self
._RawData
[Type
, self
._Arch
]
1151 PcdValueDict
= sdict()
1152 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1153 SkuName
= SkuName
.upper()
1154 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1155 if SkuName
not in AvailableSkuIdSet
:
1156 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1157 File
=self
.MetaFile
, Line
=Dummy5
)
1158 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1159 if "." not in TokenSpaceGuid
:
1160 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
1161 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1163 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1164 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1167 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1168 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1169 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1171 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1173 PcdsKeys
= PcdValueDict
.keys()
1174 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1176 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1180 if 'COMMON' in PcdSetting
:
1181 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1182 if 'DEFAULT' in PcdSetting
:
1183 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1184 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1185 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1187 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1190 self
._PCD
_TYPE
_STRING
_[Type
],
1203 def __UNICODE2OCTList(self
,Value
):
1204 Value
= Value
.strip()
1208 Temp
= '%04X' % ord(Item
)
1209 List
.append('0x' + Temp
[2:4])
1210 List
.append('0x' + Temp
[0:2])
1214 def __STRING2OCTList(self
,Value
):
1216 Value
= Value
.strip('"')
1218 Temp
= '%02X' % ord(char
)
1219 OCTList
.append('0x' + Temp
)
1220 OCTList
.append('0x00')
1223 def GetStructurePcdMaxSize(self
, str_pcd
):
1224 pcd_default_value
= str_pcd
.DefaultValue
1225 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()]
1226 sku_values
.append(pcd_default_value
)
1228 def get_length(value
):
1229 Value
= value
.strip()
1231 if Value
.startswith('GUID') and Value
.endswith(')'):
1233 if Value
.startswith('L"') and Value
.endswith('"'):
1234 return len(Value
[2:-1])
1235 if Value
[0] == '"' and Value
[-1] == '"':
1236 return len(Value
) - 2
1237 if Value
[0] == '{' and Value
[-1] == '}':
1238 return len(Value
.split(","))
1239 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1240 return len(list(Value
[2:-1]))
1241 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1242 return len(Value
) - 2
1245 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1247 def IsFieldValueAnArray (self
, Value
):
1248 Value
= Value
.strip()
1249 if Value
.startswith('GUID') and Value
.endswith(')'):
1251 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1253 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1255 if Value
[0] == '{' and Value
[-1] == '}':
1257 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1258 print 'foo = ', list(Value
[2:-1])
1260 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1261 print 'bar = ', list(Value
[1:-1])
1265 def ExecuteCommand (self
, Command
):
1267 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1269 EdkLogger
.error('Build', COMMAND_FAILURE
, 'Can not execute command: %s' % Command
)
1270 Result
= Process
.communicate()
1271 return Process
.returncode
, Result
[0], Result
[1]
1273 def IntToCString(self
, Value
, ValueSize
):
1275 if not isinstance (Value
, str):
1276 for Index
in range(0, ValueSize
):
1277 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1279 Result
= Result
+ '"'
1282 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1283 OverrideValues
= {DefaultStoreName
:""}
1284 if Pcd
.SkuOverrideValues
:
1285 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1286 for DefaultStoreName
in OverrideValues
.keys():
1287 CApp
= CApp
+ 'void\n'
1288 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1289 CApp
= CApp
+ ' void\n'
1290 CApp
= CApp
+ ' )\n'
1292 CApp
= CApp
+ ' UINT32 Size;\n'
1293 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1294 CApp
= CApp
+ ' CHAR8 *Value;\n'
1295 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1296 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1297 CApp
= CApp
+ ' %s *Pcd; // From %s Line %d \n' % (Pcd
.DatumType
, Pcd
.PkgPath
, Pcd
.PcdDefineLineNo
)
1300 if SkuName
in Pcd
.SkuInfoList
:
1301 DefaultValue
= Pcd
.SkuInfoList
[SkuName
].DefaultStoreDict
.get(DefaultStoreName
,Pcd
.SkuInfoList
[SkuName
].HiiDefaultValue
) if Pcd
.SkuInfoList
[SkuName
].HiiDefaultValue
else Pcd
.SkuInfoList
[SkuName
].DefaultValue
1303 DefaultValue
= Pcd
.DefaultValue
1304 PcdDefaultValue
= StringToArray(DefaultValue
.strip())
1306 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1309 # Get current PCD value and size
1311 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1314 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1315 # the correct value. For structures with a flexible array member, the flexible
1316 # array member is detected, and the size is based on the highest index used with
1317 # the flexible array member. The flexible array member must be the last field
1318 # in a structure. The size formula for this case is:
1319 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1321 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1322 for FieldList
in [Pcd
.DefaultValues
]:
1325 for FieldName
in FieldList
:
1326 FieldName
= "." + FieldName
1327 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1329 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1330 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s \n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2], FieldList
[FieldName
.strip(".")][0]);
1333 FieldName_ori
= FieldName
.strip('.')
1334 while '[' in FieldName
:
1335 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1336 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1337 FieldName
= FieldName
.split(']', 1)[1]
1338 FieldName
= NewFieldName
+ FieldName
1339 while '[' in FieldName
:
1340 FieldName
= FieldName
.rsplit('[', 1)[0]
1341 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1, FieldList
[FieldName_ori
][1], FieldList
[FieldName_ori
][2], FieldList
[FieldName_ori
][0])
1342 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1343 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1344 for FieldList
in [inherit_OverrideValues
.get(DefaultStoreName
)]:
1347 for FieldName
in FieldList
:
1348 FieldName
= "." + FieldName
1349 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1351 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1352 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), ValueSize
, Pcd
.DatumType
, FieldName
.strip("."), FieldList
[FieldName
.strip(".")][1], FieldList
[FieldName
.strip(".")][2], FieldList
[FieldName
.strip(".")][0]);
1355 FieldName_ori
= FieldName
.strip('.')
1356 while '[' in FieldName
:
1357 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1358 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1359 FieldName
= FieldName
.split(']', 1)[1]
1360 FieldName
= NewFieldName
+ FieldName
1361 while '[' in FieldName
:
1362 FieldName
= FieldName
.rsplit('[', 1)[0]
1363 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1, FieldList
[FieldName_ori
][1], FieldList
[FieldName_ori
][2], FieldList
[FieldName_ori
][0])
1364 if skuname
== SkuName
:
1368 # Allocate and zero buffer for the PCD
1369 # Must handle cases where current value is smaller, larger, or same size
1370 # Always keep that larger one as the current size
1372 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1373 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1374 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1377 # Copy current PCD value into allocated buffer.
1379 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1382 # Assign field values in PCD
1384 for FieldList
in [Pcd
.DefaultValues
]:
1387 for FieldName
in FieldList
:
1388 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1390 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1392 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
,FieldName
)),FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1393 if isinstance(Value
, str):
1394 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1397 # Use memcpy() to copy value into field
1399 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1400 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1401 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1404 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1406 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1407 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1408 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1409 for FieldList
in [Pcd
.DefaultFromDSC
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1412 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1413 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1414 Value
, ValueSize
= ParseFieldValue (FieldList
)
1415 if isinstance(Value
, str):
1416 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1419 # Use memcpy() to copy value into field
1421 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1422 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1425 for FieldName
in FieldList
:
1426 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1428 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1430 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
,FieldName
)),FieldList
[FieldName
][1], FieldList
[FieldName
][2]))
1431 if isinstance(Value
, str):
1432 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1435 # Use memcpy() to copy value into field
1437 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1438 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1439 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1442 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1444 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1445 if skuname
== SkuName
:
1448 # Set new PCD value and size
1450 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1455 CApp
= CApp
+ ' free (Pcd);\n'
1458 return InitByteValue
, CApp
1460 def GenerateByteArrayValue (self
, StructuredPcds
):
1462 # Generate/Compile/Run C application to determine if there are any flexible array members
1464 if not StructuredPcds
:
1468 CApp
= PcdMainCHeader
1471 for PcdName
in StructuredPcds
:
1472 Pcd
= StructuredPcds
[PcdName
]
1473 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1474 if IncludeFile
not in Includes
:
1475 Includes
[IncludeFile
] = True
1476 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1479 for PcdName
in StructuredPcds
:
1480 Pcd
= StructuredPcds
[PcdName
]
1481 if not Pcd
.SkuOverrideValues
:
1482 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1484 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1485 if SkuName
not in Pcd
.SkuOverrideValues
:
1487 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1488 Pcd
= StructuredPcds
[PcdName
]
1489 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1491 CApp
= CApp
+ 'VOID\n'
1492 CApp
= CApp
+ 'PcdEntryPoint(\n'
1493 CApp
= CApp
+ ' VOID\n'
1494 CApp
= CApp
+ ' )\n'
1496 for Pcd
in StructuredPcds
.values():
1497 if not Pcd
.SkuOverrideValues
:
1498 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1500 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1501 if SkuName
not in Pcd
.SkuOverrideValues
:
1503 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1504 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1507 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1509 if not os
.path
.exists(self
.OutputPath
):
1510 os
.makedirs(self
.OutputPath
)
1511 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1512 File
= open (CAppBaseFileName
+ '.c', 'w')
1516 MakeApp
= PcdMakefileHeader
1517 if sys
.platform
== "win32":
1518 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1520 MakeApp
= MakeApp
+ PcdGccMakefile
1521 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1522 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1525 for Cache
in self
._Bdb
._CACHE
_.values():
1526 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1529 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1530 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1533 for Pcd
in StructuredPcds
.values():
1534 for PackageDec
in Pcd
.PackageDecs
:
1535 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1536 if not os
.path
.exists(Package
):
1537 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1538 if Package
not in PcdDependDEC
:
1539 PcdDependDEC
.append(Package
)
1541 if PlatformInc
and PcdDependDEC
:
1542 for pkg
in PcdDependDEC
:
1543 if pkg
in PlatformInc
:
1544 for inc
in PlatformInc
[pkg
]:
1545 MakeApp
+= '-I' + str(inc
) + ' '
1546 MakeApp
= MakeApp
+ '\n'
1548 CC_FLAGS
= LinuxCFLAGS
1549 if sys
.platform
== "win32":
1550 CC_FLAGS
= WindowsCFLAGS
1552 for Options
in self
.BuildOptions
:
1553 if Options
[2] != EDKII_NAME
:
1556 if Family
and Family
!= self
.ToolChainFamily
:
1558 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
1562 if Target
== "*" or Target
== self
._Target
:
1563 if Tag
== "*" or Tag
== self
._Toolchain
:
1564 if Arch
== "*" or Arch
== self
.Arch
:
1565 if Tool
not in BuildOptions
:
1566 BuildOptions
[Tool
] = {}
1567 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
1568 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1570 # append options for the same tool except PATH
1572 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
1574 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1576 for Tool
in BuildOptions
:
1577 for Attr
in BuildOptions
[Tool
]:
1579 Value
= BuildOptions
[Tool
][Attr
]
1580 ValueList
= Value
.split()
1582 for Id
, Item
in enumerate(ValueList
):
1583 if Item
== '-D' or Item
== '/D':
1584 CC_FLAGS
+= ' ' + Item
1585 if Id
+ 1 < len(ValueList
):
1586 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
1587 elif Item
.startswith('/D') or Item
.startswith('-D'):
1588 CC_FLAGS
+= ' ' + Item
1591 if sys
.platform
== "win32":
1592 MakeApp
= MakeApp
+ PcdMakefileEnd
1593 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1594 File
= open (MakeFileName
, 'w')
1598 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1599 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1600 File
= open (InputValueFile
, 'w')
1601 File
.write(InitByteValue
)
1605 if sys
.platform
== "win32":
1606 MakeCommand
= 'nmake clean & nmake -f %s' % (MakeFileName
)
1607 returncode
, StdOut
, StdErr
= self
.ExecuteCommand (MakeCommand
)
1610 MakeCommand
= 'make clean & make -f %s' % (MakeFileName
)
1611 returncode
, StdOut
, StdErr
= self
.ExecuteCommand (MakeCommand
)
1613 Messages
= Messages
.split('\n')
1616 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1617 File
= open (CAppBaseFileName
+ '.c', 'r')
1618 FileData
= File
.readlines()
1620 for Message
in Messages
:
1621 if " error" in Message
or "warning" in Message
:
1622 FileInfo
= Message
.strip().split('(')
1623 if len (FileInfo
) > 1:
1624 FileName
= FileInfo
[0]
1625 FileLine
= FileInfo
[1].split (')')[0]
1627 FileInfo
= Message
.strip().split(':')
1628 FileName
= FileInfo
[0]
1629 FileLine
= FileInfo
[1]
1630 if FileLine
.isdigit():
1631 error_line
= FileData
[int (FileLine
) - 1]
1632 if r
"//" in error_line
:
1633 c_line
,dsc_line
= error_line
.split(r
"//")
1635 dsc_line
= error_line
1636 message_itmes
= Message
.split(":")
1638 if "PcdValueInit.c" not in Message
:
1641 for item
in message_itmes
:
1642 if "PcdValueInit.c" in item
:
1643 Index
= message_itmes
.index(item
)
1644 message_itmes
[Index
] = dsc_line
.strip()
1646 MessageGroup
.append(":".join(message_itmes
[Index
:]).strip())
1649 MessageGroup
.append(Message
)
1651 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, "\n".join(MessageGroup
) )
1653 EdkLogger
.error('Build', COMMAND_FAILURE
, 'Can not execute command: %s' % MakeCommand
)
1655 PcdValueInitExe
= PcdValueInitName
1656 if not sys
.platform
== "win32":
1657 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1659 Command
= PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
)
1660 returncode
, StdOut
, StdErr
= self
.ExecuteCommand (Command
)
1662 EdkLogger
.warn('Build', COMMAND_FAILURE
, 'Can not collect output from command: %s' % Command
)
1665 File
= open (OutputValueFile
, 'r')
1666 FileBuffer
= File
.readlines()
1669 StructurePcdSet
= []
1670 for Pcd
in FileBuffer
:
1671 PcdValue
= Pcd
.split ('|')
1672 PcdInfo
= PcdValue
[0].split ('.')
1673 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1674 return StructurePcdSet
1676 ## Retrieve dynamic PCD settings
1678 # @param Type PCD type
1680 # @retval a dict object contains settings of given PCD type
1682 def _GetDynamicPcd(self
, Type
):
1687 # tdict is a special dict kind of type, used for selecting correct
1688 # PCD settings for certain ARCH and SKU
1690 PcdDict
= tdict(True, 4)
1692 # Find out all possible PCD candidates for self._Arch
1693 RecordList
= self
._RawData
[Type
, self
._Arch
]
1694 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1697 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1698 SkuName
= SkuName
.upper()
1699 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1700 if SkuName
not in AvailableSkuIdSet
:
1701 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1702 File
=self
.MetaFile
, Line
=Dummy5
)
1703 if "." not in TokenSpaceGuid
:
1704 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
1705 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1707 # Remove redundant PCD candidates, per the ARCH and SKU
1708 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1710 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1714 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1715 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1716 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1717 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1718 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1719 if MaxDatumSize
.strip():
1720 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1723 if pcdObject
.MaxDatumSize
:
1724 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1727 if CurrentMaxSize
> PcdMaxSize
:
1728 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1730 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1733 self
._PCD
_TYPE
_STRING
_[Type
],
1738 {SkuName
: SkuInfo
},
1743 for pcd
in Pcds
.values():
1744 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1745 # Only fix the value while no value provided in DSC file.
1746 for sku
in pcd
.SkuInfoList
.values():
1747 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1748 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1749 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1750 valuefromDec
= pcdDecObject
.DefaultValue
1751 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1752 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1753 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1754 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1755 del(pcd
.SkuInfoList
['COMMON'])
1756 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1757 del(pcd
.SkuInfoList
['COMMON'])
1759 map(self
.FilterSkuSettings
,Pcds
.values())
1763 def FilterSkuSettings(self
, PcdObj
):
1765 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1766 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1767 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1768 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1769 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1770 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1772 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1773 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1778 def CompareVarAttr(self
, Attr1
, Attr2
):
1779 if not Attr1
or not Attr2
: # for empty string
1781 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1782 Attr1Set
= set(Attr1s
)
1783 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1784 Attr2Set
= set(Attr2s
)
1785 if Attr2Set
== Attr1Set
:
1789 def CompletePcdValues(self
,PcdSet
):
1791 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1792 SkuIds
= {skuname
:skuid
for skuname
,skuid
in self
.SkuIdMgr
.AvailableSkuIdSet
.items() if skuname
!='COMMON'}
1793 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1794 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1795 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1796 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1797 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1798 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1799 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1800 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1801 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1802 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1804 PcdType
= PcdObj
.Type
1805 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1806 for skuid
in PcdObj
.SkuInfoList
:
1807 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1808 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1809 for defaultstorename
in DefaultStores
:
1810 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1811 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1812 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1813 for skuname
,skuid
in SkuIds
.items():
1814 if skuname
not in PcdObj
.SkuInfoList
:
1815 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1816 while nextskuid
not in PcdObj
.SkuInfoList
:
1817 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1818 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1819 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1820 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1821 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1822 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1823 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1825 ## Retrieve dynamic HII PCD settings
1827 # @param Type PCD type
1829 # @retval a dict object contains settings of given PCD type
1831 def _GetDynamicHiiPcd(self
, Type
):
1837 # tdict is a special dict kind of type, used for selecting correct
1838 # PCD settings for certain ARCH and SKU
1840 PcdDict
= tdict(True, 5)
1842 RecordList
= self
._RawData
[Type
, self
._Arch
]
1843 # Find out all possible PCD candidates for self._Arch
1844 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1845 DefaultStoresDefine
= self
._GetDefaultStores
()
1847 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1848 SkuName
= SkuName
.upper()
1849 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1850 DefaultStore
= DefaultStore
.upper()
1851 if DefaultStore
== "COMMON":
1852 DefaultStore
= "STANDARD"
1853 if SkuName
not in AvailableSkuIdSet
:
1854 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1855 File
=self
.MetaFile
, Line
=Dummy5
)
1856 if DefaultStore
not in DefaultStoresDefine
:
1857 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1858 File
=self
.MetaFile
, Line
=Dummy5
)
1859 if "." not in TokenSpaceGuid
:
1860 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy5
))
1861 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1864 # Remove redundant PCD candidates, per the ARCH and SKU
1865 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1867 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1870 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1872 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1874 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1875 ExtraData
="[%s]" % VarAttribute
)
1877 FormatCorrect
= True
1878 if VariableOffset
.isdigit():
1879 if int(VariableOffset
, 10) > 0xFFFF:
1881 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1882 if int(VariableOffset
, 16) > 0xFFFF:
1884 # For Offset written in "A.B"
1885 elif VariableOffset
.find('.') > -1:
1886 VariableOffsetList
= VariableOffset
.split(".")
1887 if not (len(VariableOffsetList
) == 2
1888 and IsValidWord(VariableOffsetList
[0])
1889 and IsValidWord(VariableOffsetList
[1])):
1890 FormatCorrect
= False
1892 FormatCorrect
= False
1893 if not FormatCorrect
:
1894 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1897 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1898 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1899 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1901 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1902 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
)]))
1904 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1905 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1906 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1907 if SkuName
in pcdObject
.SkuInfoList
:
1908 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1909 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1911 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1912 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1914 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1915 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1918 self
._PCD
_TYPE
_STRING
_[Type
],
1923 {SkuName
: SkuInfo
},
1926 pcdDecObject
.validateranges
,
1927 pcdDecObject
.validlists
,
1928 pcdDecObject
.expressions
,
1932 for pcd
in Pcds
.values():
1933 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1934 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1935 # Only fix the value while no value provided in DSC file.
1936 for sku
in pcd
.SkuInfoList
.values():
1937 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1938 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1939 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1940 valuefromDec
= pcdDecObject
.DefaultValue
1941 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1942 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1943 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1944 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1945 del(pcd
.SkuInfoList
['COMMON'])
1946 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1947 del(pcd
.SkuInfoList
['COMMON'])
1949 if pcd
.MaxDatumSize
.strip():
1950 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1953 if pcdDecObject
.DatumType
== 'VOID*':
1954 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1956 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1957 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1958 if datalen
> MaxSize
:
1960 for defaultst
in skuobj
.DefaultStoreDict
:
1961 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1962 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1963 pcd
.MaxDatumSize
= str(MaxSize
)
1964 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1966 invalidpcd
= ",".join(invalidhii
)
1967 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
)
1969 map(self
.FilterSkuSettings
,Pcds
.values())
1973 def CheckVariableNameAssignment(self
,Pcds
):
1975 for pcdname
in Pcds
:
1977 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1978 if len(varnameset
) > 1:
1979 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1981 return False,invalidhii
1984 ## Retrieve dynamic VPD PCD settings
1986 # @param Type PCD type
1988 # @retval a dict object contains settings of given PCD type
1990 def _GetDynamicVpdPcd(self
, Type
):
1995 # tdict is a special dict kind of type, used for selecting correct
1996 # PCD settings for certain ARCH and SKU
1998 PcdDict
= tdict(True, 4)
2001 # Find out all possible PCD candidates for self._Arch
2002 RecordList
= self
._RawData
[Type
, self
._Arch
]
2003 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
2005 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
2006 SkuName
= SkuName
.upper()
2007 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
2008 if SkuName
not in AvailableSkuIdSet
:
2009 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
2010 File
=self
.MetaFile
, Line
=Dummy5
)
2011 if "." not in TokenSpaceGuid
:
2012 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy5
))
2013 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
2015 # Remove redundant PCD candidates, per the ARCH and SKU
2016 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
2017 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
2021 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2022 # For the Integer & Boolean type, the optional data can only be InitialValue.
2023 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2024 # until the DEC parser has been called.
2026 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
2027 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
2028 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
2029 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2030 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2031 if MaxDatumSize
.strip():
2032 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2035 if pcdObject
.MaxDatumSize
:
2036 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2039 if CurrentMaxSize
> PcdMaxSize
:
2040 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2042 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2045 self
._PCD
_TYPE
_STRING
_[Type
],
2050 {SkuName
: SkuInfo
},
2054 for pcd
in Pcds
.values():
2055 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2056 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2057 # Only fix the value while no value provided in DSC file.
2058 for sku
in pcd
.SkuInfoList
.values():
2059 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
2060 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2061 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
2062 valuefromDec
= pcdDecObject
.DefaultValue
2063 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
2064 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
2065 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2066 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
2067 del(pcd
.SkuInfoList
['COMMON'])
2068 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2069 del(pcd
.SkuInfoList
['COMMON'])
2072 map(self
.FilterSkuSettings
,Pcds
.values())
2075 ## Add external modules
2077 # The external modules are mostly those listed in FDF file, which don't
2080 # @param FilePath The path of module description file
2082 def AddModule(self
, FilePath
):
2083 FilePath
= NormPath(FilePath
)
2084 if FilePath
not in self
.Modules
:
2085 Module
= ModuleBuildClassObject()
2086 Module
.MetaFile
= FilePath
2087 self
.Modules
.append(Module
)
2089 def _GetToolChainFamily(self
):
2090 self
._ToolChainFamily
= "MSFT"
2091 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2092 if os
.path
.isfile(BuildConfigurationFile
) == True:
2093 TargetTxt
= TargetTxtClassObject()
2094 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2095 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2096 if ToolDefinitionFile
== '':
2097 ToolDefinitionFile
= "tools_def.txt"
2098 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2099 if os
.path
.isfile(ToolDefinitionFile
) == True:
2100 ToolDef
= ToolDefClassObject()
2101 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2102 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2103 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2104 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2105 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2106 self
._ToolChainFamily
= "MSFT"
2108 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2109 return self
._ToolChainFamily
2111 ## Add external PCDs
2113 # The external PCDs are mostly those listed in FDF file to specify address
2114 # or offset information.
2116 # @param Name Name of the PCD
2117 # @param Guid Token space guid of the PCD
2118 # @param Value Value of the PCD
2120 def AddPcd(self
, Name
, Guid
, Value
):
2121 if (Name
, Guid
) not in self
.Pcds
:
2122 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2123 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2126 if self
._DecPcds
== None:
2128 if GlobalData
.gFdfParser
:
2129 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2131 for Inf
in FdfInfList
:
2132 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2133 if ModuleFile
in self
._Modules
:
2135 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2136 PkgSet
.update(ModuleData
.Packages
)
2137 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2138 return self
._DecPcds
2139 _Macros
= property(_GetMacros
)
2140 Arch
= property(_GetArch
, _SetArch
)
2141 Platform
= property(_GetPlatformName
)
2142 PlatformName
= property(_GetPlatformName
)
2143 Guid
= property(_GetFileGuid
)
2144 Version
= property(_GetVersion
)
2145 DscSpecification
= property(_GetDscSpec
)
2146 OutputDirectory
= property(_GetOutpuDir
)
2147 SupArchList
= property(_GetSupArch
)
2148 BuildTargets
= property(_GetBuildTarget
)
2149 SkuName
= property(_GetSkuName
, _SetSkuName
)
2150 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2151 VarCheckFlag
= property(_GetVarCheckFlag
)
2152 FlashDefinition
= property(_GetFdfFile
)
2153 Prebuild
= property(_GetPrebuild
)
2154 Postbuild
= property(_GetPostbuild
)
2155 BuildNumber
= property(_GetBuildNumber
)
2156 MakefileName
= property(_GetMakefileName
)
2157 BsBaseAddress
= property(_GetBsBaseAddress
)
2158 RtBaseAddress
= property(_GetRtBaseAddress
)
2159 LoadFixAddress
= property(_GetLoadFixAddress
)
2160 RFCLanguages
= property(_GetRFCLanguages
)
2161 ISOLanguages
= property(_GetISOLanguages
)
2162 VpdToolGuid
= property(_GetVpdToolGuid
)
2163 SkuIds
= property(_GetSkuIds
)
2164 Modules
= property(_GetModules
)
2165 LibraryInstances
= property(_GetLibraryInstances
)
2166 LibraryClasses
= property(_GetLibraryClasses
)
2167 Pcds
= property(_GetPcds
)
2168 BuildOptions
= property(_GetBuildOptions
)
2169 ToolChainFamily
= property(_GetToolChainFamily
)