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
))
828 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
830 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
831 except WrnExpression
, Value
:
832 ValueList
[Index
] = Value
.result
833 except BadExpression
, Value
:
834 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
835 except EvaluationException
, Excpt
:
836 if hasattr(Excpt
, 'Pcd'):
837 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
838 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
839 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
840 " of the DSC file" % Excpt
.Pcd
,
841 File
=self
.MetaFile
, Line
=LineNo
)
843 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
844 File
=self
.MetaFile
, Line
=LineNo
)
846 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
847 File
=self
.MetaFile
, Line
=LineNo
)
849 DatumType
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
851 ValueList
[Index
] = ValueExpressionEx(ValueList
[Index
], DatumType
, self
._GuidDict
)(True)
852 except BadExpression
, Value
:
853 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=LineNo
,
854 ExtraData
="PCD [%s.%s] Value \"%s\" " % (TokenSpaceGuid
, PcdCName
, ValueList
[Index
]))
855 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
857 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
858 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
859 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
860 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
861 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
862 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
865 def _FilterPcdBySkuUsage(self
,Pcds
):
866 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
867 sku_usage
= self
.SkuIdMgr
.SkuUsageType
868 if sku_usage
== SkuClass
.SINGLE
:
871 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
872 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
873 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
877 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
878 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
879 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
881 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
882 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
]]]
883 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
885 for skuid
in pcd
.SkuInfoList
:
886 skuobj
= pcd
.SkuInfoList
.get(skuid
)
887 if "STANDARD" not in skuobj
.DefaultStoreDict
:
888 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
889 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
890 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
893 ## Retrieve all PCD settings in platform
895 if self
._Pcds
== None:
897 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
898 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
899 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
900 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
901 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
902 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
903 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
904 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
905 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
907 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
908 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
909 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
910 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
913 def _dumpPcdInfo(self
,Pcds
):
916 if not pcdobj
.TokenCName
.startswith("Test"):
918 for skuid
in pcdobj
.SkuInfoList
:
919 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
920 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
921 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
923 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
924 ## Retrieve [BuildOptions]
925 def _GetBuildOptions(self
):
926 if self
._BuildOptions
== None:
927 self
._BuildOptions
= sdict()
929 # Retrieve build option for EDKII and EDK style module
931 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
932 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
933 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
934 if Dummy3
.upper() != 'COMMON':
936 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
938 # Only flags can be appended
940 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
941 self
._BuildOptions
[CurKey
] = Option
943 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
944 self
._BuildOptions
[CurKey
] += ' ' + Option
945 return self
._BuildOptions
947 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
948 if self
._ModuleTypeOptions
== None:
949 self
._ModuleTypeOptions
= sdict()
950 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
952 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
953 DriverType
= '%s.%s' % (Edk
, ModuleType
)
954 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
955 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
956 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
957 Type
= Dummy2
+ '.' + Dummy3
958 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
959 Key
= (ToolChainFamily
, ToolChain
, Edk
)
960 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
961 options
[Key
] = Option
963 if ' ' + Option
not in options
[Key
]:
964 options
[Key
] += ' ' + Option
965 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
967 def GetStructurePcdInfo(self
, PcdSet
):
968 structure_pcd_data
= {}
970 if (item
[0],item
[1]) not in structure_pcd_data
:
971 structure_pcd_data
[(item
[0],item
[1])] = []
972 structure_pcd_data
[(item
[0],item
[1])].append(item
)
974 return structure_pcd_data
976 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
978 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
979 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
980 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
981 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
982 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
983 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
986 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
987 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
988 SkuIds
.update({'DEFAULT':0})
989 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
992 # Find out all possible PCD candidates for self._Arch
995 for Type
in TypeList
:
996 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
998 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
999 SkuName
= SkuName
.upper()
1000 default_store
= default_store
.upper()
1001 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1002 if SkuName
not in SkuIds
:
1005 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
1006 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
1008 # handle pcd value override
1009 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
1011 for str_pcd
in StrPcdSet
:
1012 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1013 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1015 str_pcd_obj_str
= StructurePcd()
1016 str_pcd_obj_str
.copy(str_pcd_dec
)
1018 str_pcd_obj_str
.copy(str_pcd_obj
)
1019 if str_pcd_obj
.DefaultValue
:
1020 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1021 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1022 if str_pcd_data
[3] in SkuIds
:
1023 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])
1024 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1026 EdkLogger
.error('build', PARSER_ERROR
,
1027 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1028 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1029 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1030 for Pcd
in self
.DecPcds
:
1031 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1032 if Pcd
not in S_pcd_set
:
1033 str_pcd_obj_str
= StructurePcd()
1034 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1035 str_pcd_obj
= Pcds
.get(Pcd
, None)
1037 str_pcd_obj_str
.copy(str_pcd_obj
)
1038 if str_pcd_obj
.DefaultValue
:
1039 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1040 S_pcd_set
[Pcd
] = str_pcd_obj_str
1042 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1043 for stru_pcd
in S_pcd_set
.values():
1044 for skuid
in SkuIds
:
1045 if skuid
in stru_pcd
.SkuOverrideValues
:
1047 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1049 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1050 if nextskuid
== "DEFAULT":
1053 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1054 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
})
1055 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1056 for skuid
in SkuIds
:
1059 if skuid
not in stru_pcd
.SkuOverrideValues
:
1060 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1061 if nextskuid
== "DEFAULT":
1064 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1067 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1068 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1070 for defaultstoreid
in DefaultStores
:
1071 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1072 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1074 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1076 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1077 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1078 if str_pcd_obj
is None:
1079 print PcdName
, PcdGuid
1081 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1082 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1083 if skuname
not in str_pcd_obj
.SkuInfoList
:
1084 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1086 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1087 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1088 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1089 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1090 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1091 str_pcd_obj
.DefaultValue
= PcdValue
1093 if skuname
not in str_pcd_obj
.SkuInfoList
:
1094 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1096 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1097 if nextskuid
== "DEFAULT":
1100 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1101 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
)
1102 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1103 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1105 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1106 for str_pcd_obj
in S_pcd_set
.values():
1107 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1108 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1110 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1111 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1112 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1113 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1115 for str_pcd_obj
in S_pcd_set
.values():
1117 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1118 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1122 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1123 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1124 del(pcd
.SkuInfoList
['COMMON'])
1125 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1126 del(pcd
.SkuInfoList
['COMMON'])
1128 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1131 ## Retrieve non-dynamic PCD settings
1133 # @param Type PCD type
1135 # @retval a dict object contains settings of given PCD type
1137 def _GetPcd(self
, Type
):
1140 # tdict is a special dict kind of type, used for selecting correct
1141 # PCD settings for certain ARCH
1143 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1145 PcdDict
= tdict(True, 3)
1147 # Find out all possible PCD candidates for self._Arch
1148 RecordList
= self
._RawData
[Type
, self
._Arch
]
1149 PcdValueDict
= sdict()
1150 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1151 SkuName
= SkuName
.upper()
1152 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1153 if SkuName
not in AvailableSkuIdSet
:
1154 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1155 File
=self
.MetaFile
, Line
=Dummy5
)
1156 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1157 if "." not in TokenSpaceGuid
:
1158 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1159 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1161 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1162 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1165 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1166 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1167 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1169 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1171 PcdsKeys
= PcdValueDict
.keys()
1172 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1174 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1178 if 'COMMON' in PcdSetting
:
1179 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1180 if 'DEFAULT' in PcdSetting
:
1181 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1182 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1183 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1185 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1188 self
._PCD
_TYPE
_STRING
_[Type
],
1201 def __UNICODE2OCTList(self
,Value
):
1202 Value
= Value
.strip()
1206 Temp
= '%04X' % ord(Item
)
1207 List
.append('0x' + Temp
[2:4])
1208 List
.append('0x' + Temp
[0:2])
1212 def __STRING2OCTList(self
,Value
):
1214 Value
= Value
.strip('"')
1216 Temp
= '%02X' % ord(char
)
1217 OCTList
.append('0x' + Temp
)
1218 OCTList
.append('0x00')
1221 def GetStructurePcdMaxSize(self
, str_pcd
):
1222 pcd_default_value
= str_pcd
.DefaultValue
1223 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()]
1224 sku_values
.append(pcd_default_value
)
1226 def get_length(value
):
1227 Value
= value
.strip()
1229 if Value
.startswith('GUID') and Value
.endswith(')'):
1231 if Value
.startswith('L"') and Value
.endswith('"'):
1232 return len(Value
[2:-1])
1233 if Value
[0] == '"' and Value
[-1] == '"':
1234 return len(Value
) - 2
1235 if Value
[0] == '{' and Value
[-1] == '}':
1236 return len(Value
.split(","))
1237 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1238 return len(list(Value
[2:-1]))
1239 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1240 return len(Value
) - 2
1243 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1245 def IsFieldValueAnArray (self
, Value
):
1246 Value
= Value
.strip()
1247 if Value
.startswith('GUID') and Value
.endswith(')'):
1249 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1251 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1253 if Value
[0] == '{' and Value
[-1] == '}':
1255 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1256 print 'foo = ', list(Value
[2:-1])
1258 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1259 print 'bar = ', list(Value
[1:-1])
1263 def ExecuteCommand (self
, Command
):
1265 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1267 print 'ERROR: Can not execute command:', Command
1269 Result
= Process
.communicate()
1270 if Process
.returncode
<> 0:
1271 print 'ERROR: Can not collect output from command:', Command
1272 return Result
[0], Result
[1]
1274 def IntToCString(self
, Value
, ValueSize
):
1276 if not isinstance (Value
, str):
1277 for Index
in range(0, ValueSize
):
1278 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1280 Result
= Result
+ '"'
1283 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1284 OverrideValues
= {DefaultStoreName
:""}
1285 if Pcd
.SkuOverrideValues
:
1286 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1287 for DefaultStoreName
in OverrideValues
.keys():
1288 CApp
= CApp
+ 'void\n'
1289 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1290 CApp
= CApp
+ ' void\n'
1291 CApp
= CApp
+ ' )\n'
1293 CApp
= CApp
+ ' UINT32 Size;\n'
1294 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1295 CApp
= CApp
+ ' CHAR8 *Value;\n'
1296 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1297 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1298 CApp
= CApp
+ ' %s *Pcd; // From %s Line %d \n' % (Pcd
.DatumType
, Pcd
.PkgPath
, Pcd
.PcdDefineLineNo
)
1301 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1302 PcdDefaultValue
= StringToArray(Pcd
.DefaultValue
)
1304 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1307 # Get current PCD value and size
1309 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1312 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1313 # the correct value. For structures with a flexible array member, the flexible
1314 # array member is detected, and the size is based on the highest index used with
1315 # the flexible array member. The flexible array member must be the last field
1316 # in a structure. The size formula for this case is:
1317 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1319 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1320 for FieldList
in [Pcd
.DefaultValues
]:
1323 for FieldName
in FieldList
:
1324 FieldName
= "." + FieldName
1325 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1327 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1328 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("."));
1331 while '[' in FieldName
:
1332 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1333 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1334 FieldName
= FieldName
.split(']', 1)[1]
1335 FieldName
= NewFieldName
+ FieldName
1336 while '[' in FieldName
:
1337 FieldName
= FieldName
.rsplit('[', 1)[0]
1338 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1339 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1340 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1341 for FieldList
in [inherit_OverrideValues
.get(DefaultStoreName
)]:
1344 for FieldName
in FieldList
:
1345 FieldName
= "." + FieldName
1346 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1348 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1349 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("."));
1352 while '[' in FieldName
:
1353 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1354 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1355 FieldName
= FieldName
.split(']', 1)[1]
1356 FieldName
= NewFieldName
+ FieldName
1357 while '[' in FieldName
:
1358 FieldName
= FieldName
.rsplit('[', 1)[0]
1359 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1360 if skuname
== SkuName
:
1364 # Allocate and zero buffer for the PCD
1365 # Must handle cases where current value is smaller, larger, or same size
1366 # Always keep that larger one as the current size
1368 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1369 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1370 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1373 # Copy current PCD value into allocated buffer.
1375 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1378 # Assign field values in PCD
1380 for FieldList
in [Pcd
.DefaultValues
]:
1383 for FieldName
in FieldList
:
1384 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1386 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1388 print FieldList
[FieldName
][0]
1389 if isinstance(Value
, str):
1390 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1393 # Use memcpy() to copy value into field
1395 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1396 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1397 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1400 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1402 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1403 for skuname
in self
.SkuIdMgr
.GetSkuChain(SkuName
):
1404 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1405 for FieldList
in [Pcd
.DefaultFromDSC
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1408 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1409 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1410 Value
, ValueSize
= ParseFieldValue (FieldList
)
1411 if isinstance(Value
, str):
1412 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1415 # Use memcpy() to copy value into field
1417 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1418 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1421 for FieldName
in FieldList
:
1422 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1424 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1426 print FieldList
[FieldName
][0]
1427 if isinstance(Value
, str):
1428 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1431 # Use memcpy() to copy value into field
1433 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1434 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1435 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1438 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1440 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1441 if skuname
== SkuName
:
1444 # Set new PCD value and size
1446 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1451 CApp
= CApp
+ ' free (Pcd);\n'
1454 return InitByteValue
, CApp
1456 def GenerateByteArrayValue (self
, StructuredPcds
):
1458 # Generate/Compile/Run C application to determine if there are any flexible array members
1460 if not StructuredPcds
:
1464 CApp
= PcdMainCHeader
1467 for PcdName
in StructuredPcds
:
1468 Pcd
= StructuredPcds
[PcdName
]
1469 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1470 if IncludeFile
not in Includes
:
1471 Includes
[IncludeFile
] = True
1472 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1475 for PcdName
in StructuredPcds
:
1476 Pcd
= StructuredPcds
[PcdName
]
1477 if not Pcd
.SkuOverrideValues
:
1478 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1480 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1481 if SkuName
not in Pcd
.SkuOverrideValues
:
1483 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1484 Pcd
= StructuredPcds
[PcdName
]
1485 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1487 CApp
= CApp
+ 'VOID\n'
1488 CApp
= CApp
+ 'PcdEntryPoint(\n'
1489 CApp
= CApp
+ ' VOID\n'
1490 CApp
= CApp
+ ' )\n'
1492 for Pcd
in StructuredPcds
.values():
1493 if not Pcd
.SkuOverrideValues
:
1494 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1496 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1497 if SkuName
not in Pcd
.SkuOverrideValues
:
1499 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1500 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1503 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1505 if not os
.path
.exists(self
.OutputPath
):
1506 os
.makedirs(self
.OutputPath
)
1507 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1508 File
= open (CAppBaseFileName
+ '.c', 'w')
1512 MakeApp
= PcdMakefileHeader
1513 if sys
.platform
== "win32":
1514 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1516 MakeApp
= MakeApp
+ PcdGccMakefile
1517 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1518 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1521 for Cache
in self
._Bdb
._CACHE
_.values():
1522 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1525 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1526 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1529 for Pcd
in StructuredPcds
.values():
1530 for PackageDec
in Pcd
.PackageDecs
:
1531 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1532 if not os
.path
.exists(Package
):
1533 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1534 if Package
not in PcdDependDEC
:
1535 PcdDependDEC
.append(Package
)
1537 if PlatformInc
and PcdDependDEC
:
1538 for pkg
in PcdDependDEC
:
1539 if pkg
in PlatformInc
:
1540 for inc
in PlatformInc
[pkg
]:
1541 MakeApp
+= '-I' + str(inc
) + ' '
1542 MakeApp
= MakeApp
+ '\n'
1544 CC_FLAGS
= LinuxCFLAGS
1545 if sys
.platform
== "win32":
1546 CC_FLAGS
= WindowsCFLAGS
1548 for Options
in self
.BuildOptions
:
1549 if Options
[2] != EDKII_NAME
:
1552 if Family
and Family
!= self
.ToolChainFamily
:
1554 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
1558 if Target
== "*" or Target
== self
._Target
:
1559 if Tag
== "*" or Tag
== self
._Toolchain
:
1560 if Arch
== "*" or Arch
== self
.Arch
:
1561 if Tool
not in BuildOptions
:
1562 BuildOptions
[Tool
] = {}
1563 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
1564 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1566 # append options for the same tool except PATH
1568 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
1570 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1572 for Tool
in BuildOptions
:
1573 for Attr
in BuildOptions
[Tool
]:
1575 Value
= BuildOptions
[Tool
][Attr
]
1576 ValueList
= Value
.split()
1578 for Id
, Item
in enumerate(ValueList
):
1579 if Item
== '-D' or Item
== '/D':
1580 CC_FLAGS
+= ' ' + Item
1581 if Id
+ 1 < len(ValueList
):
1582 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
1583 elif Item
.startswith('/D') or Item
.startswith('-D'):
1584 CC_FLAGS
+= ' ' + Item
1587 if sys
.platform
== "win32":
1588 MakeApp
= MakeApp
+ PcdMakefileEnd
1589 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1590 File
= open (MakeFileName
, 'w')
1594 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1595 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1596 File
= open (InputValueFile
, 'w')
1597 File
.write(InitByteValue
)
1601 if sys
.platform
== "win32":
1602 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1605 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1607 Messages
= Messages
.split('\n')
1608 for Message
in Messages
:
1609 if " error" in Message
:
1610 FileInfo
= Message
.strip().split('(')
1611 if len (FileInfo
) > 1:
1612 FileName
= FileInfo
[0]
1613 FileLine
= FileInfo
[1].split (')')[0]
1615 FileInfo
= Message
.strip().split(':')
1616 FileName
= FileInfo
[0]
1617 FileLine
= FileInfo
[1]
1619 File
= open (FileName
, 'r')
1620 FileData
= File
.readlines()
1622 error_line
= FileData
[int (FileLine
) - 1]
1623 if r
"//" in error_line
:
1624 c_line
,dsc_line
= error_line
.split(r
"//")
1626 dsc_line
= error_line
1628 message_itmes
= Message
.split(":")
1630 for item
in message_itmes
:
1631 if "PcdValueInit.c" in item
:
1632 Index
= message_itmes
.index(item
)
1633 message_itmes
[Index
] = dsc_line
.strip()
1636 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[Index
:]))
1638 PcdValueInitExe
= PcdValueInitName
1639 if not sys
.platform
== "win32":
1640 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1642 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1643 File
= open (OutputValueFile
, 'r')
1644 FileBuffer
= File
.readlines()
1647 StructurePcdSet
= []
1648 for Pcd
in FileBuffer
:
1649 PcdValue
= Pcd
.split ('|')
1650 PcdInfo
= PcdValue
[0].split ('.')
1651 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1652 return StructurePcdSet
1654 ## Retrieve dynamic PCD settings
1656 # @param Type PCD type
1658 # @retval a dict object contains settings of given PCD type
1660 def _GetDynamicPcd(self
, Type
):
1665 # tdict is a special dict kind of type, used for selecting correct
1666 # PCD settings for certain ARCH and SKU
1668 PcdDict
= tdict(True, 4)
1670 # Find out all possible PCD candidates for self._Arch
1671 RecordList
= self
._RawData
[Type
, self
._Arch
]
1672 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1675 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1676 SkuName
= SkuName
.upper()
1677 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1678 if SkuName
not in AvailableSkuIdSet
:
1679 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1680 File
=self
.MetaFile
, Line
=Dummy5
)
1681 if "." not in TokenSpaceGuid
:
1682 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1683 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1685 # Remove redundant PCD candidates, per the ARCH and SKU
1686 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1688 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1692 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1693 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1694 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1695 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1696 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1697 if MaxDatumSize
.strip():
1698 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1701 if pcdObject
.MaxDatumSize
:
1702 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1705 if CurrentMaxSize
> PcdMaxSize
:
1706 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1708 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1711 self
._PCD
_TYPE
_STRING
_[Type
],
1716 {SkuName
: SkuInfo
},
1721 for pcd
in Pcds
.values():
1722 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1723 # Only fix the value while no value provided in DSC file.
1724 for sku
in pcd
.SkuInfoList
.values():
1725 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1726 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1727 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1728 valuefromDec
= pcdDecObject
.DefaultValue
1729 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1730 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1731 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1732 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1733 del(pcd
.SkuInfoList
['COMMON'])
1734 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1735 del(pcd
.SkuInfoList
['COMMON'])
1737 map(self
.FilterSkuSettings
,Pcds
.values())
1741 def FilterSkuSettings(self
, PcdObj
):
1743 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1744 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1745 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1746 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1747 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1748 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1750 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1751 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1756 def CompareVarAttr(self
, Attr1
, Attr2
):
1757 if not Attr1
or not Attr2
: # for empty string
1759 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1760 Attr1Set
= set(Attr1s
)
1761 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1762 Attr2Set
= set(Attr2s
)
1763 if Attr2Set
== Attr1Set
:
1767 def CompletePcdValues(self
,PcdSet
):
1769 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1770 SkuIds
= {skuname
:skuid
for skuname
,skuid
in self
.SkuIdMgr
.AvailableSkuIdSet
.items() if skuname
!='COMMON'}
1771 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1772 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1773 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1774 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1775 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1776 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1777 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1778 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1779 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1780 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1782 PcdType
= PcdObj
.Type
1783 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1784 for skuid
in PcdObj
.SkuInfoList
:
1785 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1786 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1787 for defaultstorename
in DefaultStores
:
1788 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1789 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1790 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1791 for skuname
,skuid
in SkuIds
.items():
1792 if skuname
not in PcdObj
.SkuInfoList
:
1793 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1794 while nextskuid
not in PcdObj
.SkuInfoList
:
1795 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1796 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1797 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1798 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1799 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1800 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1801 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1803 ## Retrieve dynamic HII PCD settings
1805 # @param Type PCD type
1807 # @retval a dict object contains settings of given PCD type
1809 def _GetDynamicHiiPcd(self
, Type
):
1815 # tdict is a special dict kind of type, used for selecting correct
1816 # PCD settings for certain ARCH and SKU
1818 PcdDict
= tdict(True, 5)
1820 RecordList
= self
._RawData
[Type
, self
._Arch
]
1821 # Find out all possible PCD candidates for self._Arch
1822 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1823 DefaultStoresDefine
= self
._GetDefaultStores
()
1825 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1826 SkuName
= SkuName
.upper()
1827 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1828 DefaultStore
= DefaultStore
.upper()
1829 if DefaultStore
== "COMMON":
1830 DefaultStore
= "STANDARD"
1831 if SkuName
not in AvailableSkuIdSet
:
1832 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1833 File
=self
.MetaFile
, Line
=Dummy5
)
1834 if DefaultStore
not in DefaultStoresDefine
:
1835 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1836 File
=self
.MetaFile
, Line
=Dummy5
)
1837 if "." not in TokenSpaceGuid
:
1838 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1839 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1842 # Remove redundant PCD candidates, per the ARCH and SKU
1843 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1845 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1848 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1850 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1852 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1853 ExtraData
="[%s]" % VarAttribute
)
1855 FormatCorrect
= True
1856 if VariableOffset
.isdigit():
1857 if int(VariableOffset
, 10) > 0xFFFF:
1859 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1860 if int(VariableOffset
, 16) > 0xFFFF:
1862 # For Offset written in "A.B"
1863 elif VariableOffset
.find('.') > -1:
1864 VariableOffsetList
= VariableOffset
.split(".")
1865 if not (len(VariableOffsetList
) == 2
1866 and IsValidWord(VariableOffsetList
[0])
1867 and IsValidWord(VariableOffsetList
[1])):
1868 FormatCorrect
= False
1870 FormatCorrect
= False
1871 if not FormatCorrect
:
1872 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1875 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1876 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1877 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1879 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1880 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
)]))
1882 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1883 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1884 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1885 if SkuName
in pcdObject
.SkuInfoList
:
1886 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1887 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1889 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1890 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1892 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1893 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1896 self
._PCD
_TYPE
_STRING
_[Type
],
1901 {SkuName
: SkuInfo
},
1904 pcdDecObject
.validateranges
,
1905 pcdDecObject
.validlists
,
1906 pcdDecObject
.expressions
,
1910 for pcd
in Pcds
.values():
1911 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1912 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1913 # Only fix the value while no value provided in DSC file.
1914 for sku
in pcd
.SkuInfoList
.values():
1915 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1916 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1917 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1918 valuefromDec
= pcdDecObject
.DefaultValue
1919 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1920 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1921 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1922 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1923 del(pcd
.SkuInfoList
['COMMON'])
1924 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1925 del(pcd
.SkuInfoList
['COMMON'])
1927 if pcd
.MaxDatumSize
.strip():
1928 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1931 if pcdDecObject
.DatumType
== 'VOID*':
1932 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1934 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1935 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1936 if datalen
> MaxSize
:
1938 for defaultst
in skuobj
.DefaultStoreDict
:
1939 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1940 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1941 pcd
.MaxDatumSize
= str(MaxSize
)
1942 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1944 invalidpcd
= ",".join(invalidhii
)
1945 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
)
1947 map(self
.FilterSkuSettings
,Pcds
.values())
1951 def CheckVariableNameAssignment(self
,Pcds
):
1953 for pcdname
in Pcds
:
1955 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1956 if len(varnameset
) > 1:
1957 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1959 return False,invalidhii
1962 ## Retrieve dynamic VPD PCD settings
1964 # @param Type PCD type
1966 # @retval a dict object contains settings of given PCD type
1968 def _GetDynamicVpdPcd(self
, Type
):
1973 # tdict is a special dict kind of type, used for selecting correct
1974 # PCD settings for certain ARCH and SKU
1976 PcdDict
= tdict(True, 4)
1979 # Find out all possible PCD candidates for self._Arch
1980 RecordList
= self
._RawData
[Type
, self
._Arch
]
1981 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1983 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1984 SkuName
= SkuName
.upper()
1985 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1986 if SkuName
not in AvailableSkuIdSet
:
1987 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1988 File
=self
.MetaFile
, Line
=Dummy5
)
1989 if "." not in TokenSpaceGuid
:
1990 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1991 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1993 # Remove redundant PCD candidates, per the ARCH and SKU
1994 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1995 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1999 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
2000 # For the Integer & Boolean type, the optional data can only be InitialValue.
2001 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
2002 # until the DEC parser has been called.
2004 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
2005 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
2006 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
2007 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
2008 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2009 if MaxDatumSize
.strip():
2010 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2013 if pcdObject
.MaxDatumSize
:
2014 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2017 if CurrentMaxSize
> PcdMaxSize
:
2018 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2020 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2023 self
._PCD
_TYPE
_STRING
_[Type
],
2028 {SkuName
: SkuInfo
},
2032 for pcd
in Pcds
.values():
2033 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2034 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2035 # Only fix the value while no value provided in DSC file.
2036 for sku
in pcd
.SkuInfoList
.values():
2037 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
2038 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2039 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
2040 valuefromDec
= pcdDecObject
.DefaultValue
2041 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
2042 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
2043 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2044 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
2045 del(pcd
.SkuInfoList
['COMMON'])
2046 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2047 del(pcd
.SkuInfoList
['COMMON'])
2050 map(self
.FilterSkuSettings
,Pcds
.values())
2053 ## Add external modules
2055 # The external modules are mostly those listed in FDF file, which don't
2058 # @param FilePath The path of module description file
2060 def AddModule(self
, FilePath
):
2061 FilePath
= NormPath(FilePath
)
2062 if FilePath
not in self
.Modules
:
2063 Module
= ModuleBuildClassObject()
2064 Module
.MetaFile
= FilePath
2065 self
.Modules
.append(Module
)
2067 def _GetToolChainFamily(self
):
2068 self
._ToolChainFamily
= "MSFT"
2069 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2070 if os
.path
.isfile(BuildConfigurationFile
) == True:
2071 TargetTxt
= TargetTxtClassObject()
2072 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2073 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2074 if ToolDefinitionFile
== '':
2075 ToolDefinitionFile
= "tools_def.txt"
2076 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2077 if os
.path
.isfile(ToolDefinitionFile
) == True:
2078 ToolDef
= ToolDefClassObject()
2079 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2080 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2081 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2082 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2083 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2084 self
._ToolChainFamily
= "MSFT"
2086 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2087 return self
._ToolChainFamily
2089 ## Add external PCDs
2091 # The external PCDs are mostly those listed in FDF file to specify address
2092 # or offset information.
2094 # @param Name Name of the PCD
2095 # @param Guid Token space guid of the PCD
2096 # @param Value Value of the PCD
2098 def AddPcd(self
, Name
, Guid
, Value
):
2099 if (Name
, Guid
) not in self
.Pcds
:
2100 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2101 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2104 if self
._DecPcds
== None:
2106 if GlobalData
.gFdfParser
:
2107 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2109 for Inf
in FdfInfList
:
2110 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2111 if ModuleFile
in self
._Modules
:
2113 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2114 PkgSet
.update(ModuleData
.Packages
)
2115 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2116 return self
._DecPcds
2117 _Macros
= property(_GetMacros
)
2118 Arch
= property(_GetArch
, _SetArch
)
2119 Platform
= property(_GetPlatformName
)
2120 PlatformName
= property(_GetPlatformName
)
2121 Guid
= property(_GetFileGuid
)
2122 Version
= property(_GetVersion
)
2123 DscSpecification
= property(_GetDscSpec
)
2124 OutputDirectory
= property(_GetOutpuDir
)
2125 SupArchList
= property(_GetSupArch
)
2126 BuildTargets
= property(_GetBuildTarget
)
2127 SkuName
= property(_GetSkuName
, _SetSkuName
)
2128 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2129 VarCheckFlag
= property(_GetVarCheckFlag
)
2130 FlashDefinition
= property(_GetFdfFile
)
2131 Prebuild
= property(_GetPrebuild
)
2132 Postbuild
= property(_GetPostbuild
)
2133 BuildNumber
= property(_GetBuildNumber
)
2134 MakefileName
= property(_GetMakefileName
)
2135 BsBaseAddress
= property(_GetBsBaseAddress
)
2136 RtBaseAddress
= property(_GetRtBaseAddress
)
2137 LoadFixAddress
= property(_GetLoadFixAddress
)
2138 RFCLanguages
= property(_GetRFCLanguages
)
2139 ISOLanguages
= property(_GetISOLanguages
)
2140 VpdToolGuid
= property(_GetVpdToolGuid
)
2141 SkuIds
= property(_GetSkuIds
)
2142 Modules
= property(_GetModules
)
2143 LibraryInstances
= property(_GetLibraryInstances
)
2144 LibraryClasses
= property(_GetLibraryClasses
)
2145 Pcds
= property(_GetPcds
)
2146 BuildOptions
= property(_GetBuildOptions
)
2147 ToolChainFamily
= property(_GetToolChainFamily
)