2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 ## Platform build information from DSC file
17 # This class is used to retrieve information stored in database and convert them
18 # into PlatformBuildClassObject form for easier use for AutoGen.
20 from Common
.String
import *
21 from Common
.DataType
import *
22 from Common
.Misc
import *
25 from CommonDataClass
.CommonClass
import SkuInfoClass
26 from Common
.TargetTxtClassObject
import *
27 from Common
.ToolDefClassObject
import *
28 from MetaDataTable
import *
29 from MetaFileTable
import *
30 from MetaFileParser
import *
32 from WorkspaceCommon
import GetDeclaredPcd
33 from Common
.Misc
import AnalyzeDscPcd
34 from Common
.Misc
import ProcessDuplicatedInf
36 from Common
.Parsing
import IsValidWord
37 from Common
.VariableAttributes
import VariableAttributes
38 import Common
.GlobalData
as GlobalData
40 from Workspace
.BuildClassObject
import PlatformBuildClassObject
, StructurePcd
, PcdClassObject
, ModuleBuildClassObject
43 # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
45 PcdValueInitName
= 'PcdValueInit'
46 PcdSupportedBaseTypes
= ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
47 PcdSupportedBaseTypeWidth
= {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
48 PcdUnsupportedBaseTypes
= ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
59 #include <PcdValueCommon.h>
69 return PcdValueMain (argc, argv);
73 PcdMakefileHeader
= '''
76 # This file is auto-generated by build utility
81 WindowsCFLAGS
= 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
82 LinuxCFLAGS
= 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
84 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
86 LIBS = $(LIB_PATH)\Common.lib
88 !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
93 MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
97 class DscBuildData(PlatformBuildClassObject
):
98 # dict used to convert PCD type in database to string used by build tool
100 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
101 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
102 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
103 MODEL_PCD_DYNAMIC
: "Dynamic",
104 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
105 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
106 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
107 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
108 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
109 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
110 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
113 # dict used to convert part of [Defines] to members of DscBuildData directly
118 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
119 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
120 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
121 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
122 # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
123 # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
124 # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
125 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
126 # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
127 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
128 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
129 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
130 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
131 # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
132 # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
135 # used to compose dummy library class name for those forced library instances
136 _NullLibraryNumber
= 0
138 ## Constructor of DscBuildData
140 # Initialize object of DscBuildData
142 # @param FilePath The path of platform description file
143 # @param RawData The raw data of DSC file
144 # @param BuildDataBase Database used to retrieve module/package information
145 # @param Arch The target architecture
146 # @param Platform (not used for DscBuildData)
147 # @param Macros Macros used for replacement in DSC file
149 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
150 self
.MetaFile
= FilePath
151 self
._RawData
= RawData
152 self
._Bdb
= BuildDataBase
154 self
._Target
= Target
155 self
._Toolchain
= Toolchain
156 self
._ToolChainFamily
= None
158 self
._HandleOverridePath
()
159 if os
.getenv("WORKSPACE"):
160 self
.OutputPath
= os
.path
.join(os
.getenv("WORKSPACE"), 'Build', PcdValueInitName
)
162 self
.OutputPath
= os
.path
.dirname(self
.DscFile
)
163 self
.DefaultStores
= None
164 self
.SkuIdMgr
= SkuClass(self
.SkuName
, self
.SkuIds
)
165 arraystr
= self
.SkuIdMgr
.DumpSkuIdArrary()
168 def __setitem__(self
, key
, value
):
169 self
.__dict
__[self
._PROPERTY
_[key
]] = value
172 def __getitem__(self
, key
):
173 return self
.__dict
__[self
._PROPERTY
_[key
]]
176 def __contains__(self
, key
):
177 return key
in self
._PROPERTY
_
179 ## Set all internal used members of DscBuildData to None
182 self
._PlatformName
= None
185 self
._DscSpecification
= None
186 self
._OutputDirectory
= None
187 self
._SupArchList
= None
188 self
._BuildTargets
= None
190 self
._PcdInfoFlag
= None
191 self
._VarCheckFlag
= None
192 self
._FlashDefinition
= None
193 self
._Prebuild
= None
194 self
._Postbuild
= None
195 self
._BuildNumber
= None
196 self
._MakefileName
= None
197 self
._BsBaseAddress
= None
198 self
._RtBaseAddress
= None
201 self
._LibraryInstances
= None
202 self
._LibraryClasses
= None
205 self
._BuildOptions
= None
206 self
._ModuleTypeOptions
= None
207 self
._LoadFixAddress
= None
208 self
._RFCLanguages
= None
209 self
._ISOLanguages
= None
210 self
._VpdToolGuid
= None
212 self
.DefaultStores
= None
215 ## handle Override Path of Module
216 def _HandleOverridePath(self
):
217 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
218 Macros
= self
._Macros
219 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
220 for Record
in RecordList
:
223 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
224 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
226 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
228 # Check if the source override path exists
229 if not os
.path
.isdir(SourceOverridePath
):
230 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
232 # Add to GlobalData Variables
233 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
235 ## Get current effective macros
236 def _GetMacros(self
):
237 if self
.__Macros
== None:
239 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
240 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
241 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
250 # Changing the default ARCH to another may affect all other information
251 # because all information in a platform may be ARCH-related. That's
252 # why we need to clear all internal used members, in order to cause all
253 # information to be re-retrieved.
255 # @param Value The value of ARCH
257 def _SetArch(self
, Value
):
258 if self
._Arch
== Value
:
263 ## Retrieve all information in [Defines] section
265 # (Retriving all [Defines] information in one-shot is just to save time.)
267 def _GetHeaderInfo(self
):
268 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
269 for Record
in RecordList
:
271 # items defined _PROPERTY_ don't need additional processing
273 # some special items in [Defines] section need special treatment
274 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
275 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
276 if ' ' in self
._OutputDirectory
:
277 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
278 File
=self
.MetaFile
, Line
=Record
[-1],
279 ExtraData
=self
._OutputDirectory
)
280 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
281 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
282 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
284 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
286 elif Name
== TAB_DSC_PREBUILD
:
287 PrebuildValue
= Record
[2]
288 if Record
[2][0] == '"':
289 if Record
[2][-1] != '"':
290 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
291 File
=self
.MetaFile
, Line
=Record
[-1])
292 PrebuildValue
= Record
[2][1:-1]
293 self
._Prebuild
= PrebuildValue
294 elif Name
== TAB_DSC_POSTBUILD
:
295 PostbuildValue
= Record
[2]
296 if Record
[2][0] == '"':
297 if Record
[2][-1] != '"':
298 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
299 File
=self
.MetaFile
, Line
=Record
[-1])
300 PostbuildValue
= Record
[2][1:-1]
301 self
._Postbuild
= PostbuildValue
302 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
303 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
304 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
305 self
._BuildTargets
= GetSplitValueList(Record
[2])
306 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
307 if self
._SkuName
== None:
308 self
._SkuName
= Record
[2]
309 if GlobalData
.gSKUID_CMD
:
310 self
._SkuName
= GlobalData
.gSKUID_CMD
311 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
312 self
._PcdInfoFlag
= Record
[2]
313 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
314 self
._VarCheckFlag
= Record
[2]
315 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
317 self
._LoadFixAddress
= int (Record
[2], 0)
319 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
320 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
321 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
322 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
323 File
=self
.MetaFile
, Line
=Record
[-1])
324 LanguageCodes
= Record
[2][1:-1]
325 if not LanguageCodes
:
326 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
327 File
=self
.MetaFile
, Line
=Record
[-1])
328 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
329 # check whether there is empty entries in the list
330 if None in LanguageList
:
331 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
332 File
=self
.MetaFile
, Line
=Record
[-1])
333 self
._RFCLanguages
= LanguageList
334 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
335 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
336 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
337 File
=self
.MetaFile
, Line
=Record
[-1])
338 LanguageCodes
= Record
[2][1:-1]
339 if not LanguageCodes
:
340 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
341 File
=self
.MetaFile
, Line
=Record
[-1])
342 if len(LanguageCodes
) % 3:
343 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
344 File
=self
.MetaFile
, Line
=Record
[-1])
346 for i
in range(0, len(LanguageCodes
), 3):
347 LanguageList
.append(LanguageCodes
[i
:i
+ 3])
348 self
._ISOLanguages
= LanguageList
349 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
351 # try to convert GUID to a real UUID value to see whether the GUID is format
352 # for VPD_TOOL_GUID is correct.
357 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
358 self
._VpdToolGuid
= Record
[2]
360 self
[Name
] = Record
[2]
361 # set _Header to non-None in order to avoid database re-querying
362 self
._Header
= 'DUMMY'
364 ## Retrieve platform name
365 def _GetPlatformName(self
):
366 if self
._PlatformName
== None:
367 if self
._Header
== None:
368 self
._GetHeaderInfo
()
369 if self
._PlatformName
== None:
370 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
371 return self
._PlatformName
373 ## Retrieve file guid
374 def _GetFileGuid(self
):
375 if self
._Guid
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
378 if self
._Guid
== None:
379 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
382 ## Retrieve platform version
383 def _GetVersion(self
):
384 if self
._Version
== None:
385 if self
._Header
== None:
386 self
._GetHeaderInfo
()
387 if self
._Version
== None:
388 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
391 ## Retrieve platform description file version
392 def _GetDscSpec(self
):
393 if self
._DscSpecification
== None:
394 if self
._Header
== None:
395 self
._GetHeaderInfo
()
396 if self
._DscSpecification
== None:
397 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
398 return self
._DscSpecification
400 ## Retrieve OUTPUT_DIRECTORY
401 def _GetOutpuDir(self
):
402 if self
._OutputDirectory
== None:
403 if self
._Header
== None:
404 self
._GetHeaderInfo
()
405 if self
._OutputDirectory
== None:
406 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
407 return self
._OutputDirectory
409 ## Retrieve SUPPORTED_ARCHITECTURES
410 def _GetSupArch(self
):
411 if self
._SupArchList
== None:
412 if self
._Header
== None:
413 self
._GetHeaderInfo
()
414 if self
._SupArchList
== None:
415 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
416 return self
._SupArchList
418 ## Retrieve BUILD_TARGETS
419 def _GetBuildTarget(self
):
420 if self
._BuildTargets
== None:
421 if self
._Header
== None:
422 self
._GetHeaderInfo
()
423 if self
._BuildTargets
== None:
424 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
425 return self
._BuildTargets
427 def _GetPcdInfoFlag(self
):
428 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
430 elif self
._PcdInfoFlag
.upper() == 'TRUE':
434 def _GetVarCheckFlag(self
):
435 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
437 elif self
._VarCheckFlag
.upper() == 'TRUE':
442 # # Retrieve SKUID_IDENTIFIER
443 def _GetSkuName(self
):
444 if self
._SkuName
== None:
445 if self
._Header
== None:
446 self
._GetHeaderInfo
()
447 if self
._SkuName
== None:
448 self
._SkuName
= 'DEFAULT'
451 ## Override SKUID_IDENTIFIER
452 def _SetSkuName(self
, Value
):
453 self
._SkuName
= Value
456 def _GetFdfFile(self
):
457 if self
._FlashDefinition
== None:
458 if self
._Header
== None:
459 self
._GetHeaderInfo
()
460 if self
._FlashDefinition
== None:
461 self
._FlashDefinition
= ''
462 return self
._FlashDefinition
464 def _GetPrebuild(self
):
465 if self
._Prebuild
== None:
466 if self
._Header
== None:
467 self
._GetHeaderInfo
()
468 if self
._Prebuild
== None:
470 return self
._Prebuild
472 def _GetPostbuild(self
):
473 if self
._Postbuild
== None:
474 if self
._Header
== None:
475 self
._GetHeaderInfo
()
476 if self
._Postbuild
== None:
478 return self
._Postbuild
480 ## Retrieve FLASH_DEFINITION
481 def _GetBuildNumber(self
):
482 if self
._BuildNumber
== None:
483 if self
._Header
== None:
484 self
._GetHeaderInfo
()
485 if self
._BuildNumber
== None:
486 self
._BuildNumber
= ''
487 return self
._BuildNumber
489 ## Retrieve MAKEFILE_NAME
490 def _GetMakefileName(self
):
491 if self
._MakefileName
== None:
492 if self
._Header
== None:
493 self
._GetHeaderInfo
()
494 if self
._MakefileName
== None:
495 self
._MakefileName
= ''
496 return self
._MakefileName
498 ## Retrieve BsBaseAddress
499 def _GetBsBaseAddress(self
):
500 if self
._BsBaseAddress
== None:
501 if self
._Header
== None:
502 self
._GetHeaderInfo
()
503 if self
._BsBaseAddress
== None:
504 self
._BsBaseAddress
= ''
505 return self
._BsBaseAddress
507 ## Retrieve RtBaseAddress
508 def _GetRtBaseAddress(self
):
509 if self
._RtBaseAddress
== None:
510 if self
._Header
== None:
511 self
._GetHeaderInfo
()
512 if self
._RtBaseAddress
== None:
513 self
._RtBaseAddress
= ''
514 return self
._RtBaseAddress
516 ## Retrieve the top address for the load fix address
517 def _GetLoadFixAddress(self
):
518 if self
._LoadFixAddress
== None:
519 if self
._Header
== None:
520 self
._GetHeaderInfo
()
522 if self
._LoadFixAddress
== None:
523 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
526 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
528 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
531 # If command line defined, should override the value in DSC file.
533 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
535 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
537 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS']))
539 if self
._LoadFixAddress
< 0:
540 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
541 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
542 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
544 return self
._LoadFixAddress
546 ## Retrieve RFCLanguage filter
547 def _GetRFCLanguages(self
):
548 if self
._RFCLanguages
== None:
549 if self
._Header
== None:
550 self
._GetHeaderInfo
()
551 if self
._RFCLanguages
== None:
552 self
._RFCLanguages
= []
553 return self
._RFCLanguages
555 ## Retrieve ISOLanguage filter
556 def _GetISOLanguages(self
):
557 if self
._ISOLanguages
== None:
558 if self
._Header
== None:
559 self
._GetHeaderInfo
()
560 if self
._ISOLanguages
== None:
561 self
._ISOLanguages
= []
562 return self
._ISOLanguages
563 ## Retrieve the GUID string for VPD tool
564 def _GetVpdToolGuid(self
):
565 if self
._VpdToolGuid
== None:
566 if self
._Header
== None:
567 self
._GetHeaderInfo
()
568 if self
._VpdToolGuid
== None:
569 self
._VpdToolGuid
= ''
570 return self
._VpdToolGuid
572 ## Retrieve [SkuIds] section information
573 def _GetSkuIds(self
):
574 if self
._SkuIds
== None:
575 self
._SkuIds
= sdict()
576 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
577 for Record
in RecordList
:
578 if Record
[0] in [None, '']:
579 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
580 File
=self
.MetaFile
, Line
=Record
[-1])
581 if Record
[1] in [None, '']:
582 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
583 File
=self
.MetaFile
, Line
=Record
[-1])
584 Pattern
= re
.compile('^[1-9]\d*|0$')
585 if Pattern
.match(Record
[0]) == None:
586 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID number is invalid. The correct format is '{(0-9)} {(1-9)(0-9)+}'",
587 File
=self
.MetaFile
, Line
=Record
[-1])
588 if not IsValidWord(Record
[1]):
589 EdkLogger
.error('build', FORMAT_INVALID
, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
590 File
=self
.MetaFile
, Line
=Record
[-1])
591 self
._SkuIds
[Record
[1].upper()] = (Record
[0], Record
[1].upper(), Record
[2].upper())
592 if 'DEFAULT' not in self
._SkuIds
:
593 self
._SkuIds
['DEFAULT'] = ("0","DEFAULT","DEFAULT")
594 if 'COMMON' not in self
._SkuIds
:
595 self
._SkuIds
['COMMON'] = ("0","DEFAULT","DEFAULT")
597 def ToInt(self
,intstr
):
598 return int(intstr
,16) if intstr
.upper().startswith("0X") else int(intstr
)
599 def _GetDefaultStores(self
):
600 if self
.DefaultStores
== None:
601 self
.DefaultStores
= sdict()
602 RecordList
= self
._RawData
[MODEL_EFI_DEFAULT_STORES
, self
._Arch
]
603 for Record
in RecordList
:
604 if Record
[0] in [None, '']:
605 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID number',
606 File
=self
.MetaFile
, Line
=Record
[-1])
607 if Record
[1] in [None, '']:
608 EdkLogger
.error('build', FORMAT_INVALID
, 'No DefaultStores ID name',
609 File
=self
.MetaFile
, Line
=Record
[-1])
610 self
.DefaultStores
[Record
[1].upper()] = (self
.ToInt(Record
[0]),Record
[1].upper())
611 if TAB_DEFAULT_STORES_DEFAULT
not in self
.DefaultStores
:
612 self
.DefaultStores
[TAB_DEFAULT_STORES_DEFAULT
] = (0,TAB_DEFAULT_STORES_DEFAULT
)
613 GlobalData
.gDefaultStores
= self
.DefaultStores
.keys()
614 if GlobalData
.gDefaultStores
:
615 GlobalData
.gDefaultStores
.sort()
616 return self
.DefaultStores
618 ## Retrieve [Components] section information
619 def _GetModules(self
):
620 if self
._Modules
!= None:
623 self
._Modules
= sdict()
624 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
625 Macros
= self
._Macros
626 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
627 for Record
in RecordList
:
628 DuplicatedFile
= False
630 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
634 # check the file validation
635 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
637 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
640 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
641 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
642 DuplicatedFile
= True
644 Module
= ModuleBuildClassObject()
645 Module
.MetaFile
= ModuleFile
647 # get module private library instance
648 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
649 for Record
in RecordList
:
650 LibraryClass
= Record
[0]
651 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
654 # check the file validation
655 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
657 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
660 if LibraryClass
== '' or LibraryClass
== 'NULL':
661 self
._NullLibraryNumber
+= 1
662 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
663 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
664 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
665 if LibraryPath
not in self
.LibraryInstances
:
666 self
.LibraryInstances
.append(LibraryPath
)
668 # get module private PCD setting
669 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
670 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
671 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
672 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
673 TokenList
= GetSplitValueList(Setting
)
674 DefaultValue
= TokenList
[0]
675 if len(TokenList
) > 1:
676 MaxDatumSize
= TokenList
[1]
679 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
680 Pcd
= PcdClassObject(
692 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
694 # get module private build options
695 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
696 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
697 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
698 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
700 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
701 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
703 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
704 if DuplicatedFile
and not RecordList
:
705 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
707 if len(RecordList
) != 1:
708 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
709 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
710 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
711 ModuleFile
.Arch
= self
._Arch
713 self
._Modules
[ModuleFile
] = Module
716 ## Retrieve all possible library instances used in this platform
717 def _GetLibraryInstances(self
):
718 if self
._LibraryInstances
== None:
719 self
._GetLibraryClasses
()
720 return self
._LibraryInstances
722 ## Retrieve [LibraryClasses] information
723 def _GetLibraryClasses(self
):
724 if self
._LibraryClasses
== None:
725 self
._LibraryInstances
= []
727 # tdict is a special dict kind of type, used for selecting correct
728 # library instance for given library class and module type
730 LibraryClassDict
= tdict(True, 3)
731 # track all library class names
732 LibraryClassSet
= set()
733 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
734 Macros
= self
._Macros
735 for Record
in RecordList
:
736 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
,Dummy
, LineNo
= Record
737 if LibraryClass
== '' or LibraryClass
== 'NULL':
738 self
._NullLibraryNumber
+= 1
739 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
740 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
741 LibraryClassSet
.add(LibraryClass
)
742 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
743 # check the file validation
744 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
746 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
749 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
750 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
751 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
752 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
753 if LibraryInstance
not in self
._LibraryInstances
:
754 self
._LibraryInstances
.append(LibraryInstance
)
756 # resolve the specific library instance for each class and each module type
757 self
._LibraryClasses
= tdict(True)
758 for LibraryClass
in LibraryClassSet
:
759 # try all possible module types
760 for ModuleType
in SUP_MODULE_LIST
:
761 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
762 if LibraryInstance
== None:
764 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
766 # for Edk style library instances, which are listed in different section
767 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
768 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
769 for Record
in RecordList
:
770 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
772 # check the file validation
773 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
775 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
777 if File
not in self
._LibraryInstances
:
778 self
._LibraryInstances
.append(File
)
780 # we need the module name as the library class name, so we have
781 # to parse it here. (self._Bdb[] will trigger a file parse if it
782 # hasn't been parsed)
784 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
785 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
786 return self
._LibraryClasses
788 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
789 if self
._DecPcds
== None:
792 if GlobalData
.gFdfParser
:
793 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
796 for Inf
in FdfInfList
:
797 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
798 if ModuleFile
in self
._Modules
:
800 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
801 PkgSet
.update(ModuleData
.Packages
)
803 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
806 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
807 EdkLogger
.error('build', PARSER_ERROR
,
808 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
809 File
=self
.MetaFile
, Line
=LineNo
)
810 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
812 if PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
813 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
814 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
816 if ValueList
[2] == '-1':
817 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
818 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
819 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
821 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
822 except WrnExpression
, Value
:
823 ValueList
[Index
] = Value
.result
824 except BadExpression
, Value
:
825 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=self
._LineIndex
+ 1)
826 except EvaluationException
, Excpt
:
827 if hasattr(Excpt
, 'Pcd'):
828 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
829 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
830 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
831 " of the DSC file" % Excpt
.Pcd
,
832 File
=self
.MetaFile
, Line
=LineNo
)
834 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
835 File
=self
.MetaFile
, Line
=LineNo
)
837 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
838 File
=self
.MetaFile
, Line
=LineNo
)
840 DatumType
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
842 ValueList
[Index
] = ValueExpressionEx(ValueList
[Index
], DatumType
, self
._GuidDict
)(True)
843 except BadExpression
, Value
:
844 EdkLogger
.error('Parser', FORMAT_INVALID
, Value
, File
=self
.MetaFile
, Line
=LineNo
,
845 ExtraData
="PCD [%s.%s] Value \"%s\" " % (TokenSpaceGuid
, PcdCName
, ValueList
[Index
]))
846 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
848 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
849 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
850 if PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
851 if self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
.strip() != ValueList
[1].strip():
852 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
853 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
856 def _FilterPcdBySkuUsage(self
,Pcds
):
857 available_sku
= self
.SkuIdMgr
.AvailableSkuIdSet
858 sku_usage
= self
.SkuIdMgr
.SkuUsageType
859 if sku_usage
== SkuClass
.SINGLE
:
862 Pcds
[pcdname
].SkuInfoList
= {"DEFAULT":pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
863 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
864 Pcds
[pcdname
].SkuOverrideValues
= {"DEFAULT":pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
868 Pcds
[pcdname
].SkuInfoList
= {skuid
:pcd
.SkuInfoList
[skuid
] for skuid
in pcd
.SkuInfoList
if skuid
in available_sku
}
869 if type(pcd
) is StructurePcd
and pcd
.SkuOverrideValues
:
870 Pcds
[pcdname
].SkuOverrideValues
= {skuid
:pcd
.SkuOverrideValues
[skuid
] for skuid
in pcd
.SkuOverrideValues
if skuid
in available_sku
}
872 def CompleteHiiPcdsDefaultStores(self
,Pcds
):
873 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
]]]
874 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
876 for skuid
in pcd
.SkuInfoList
:
877 skuobj
= pcd
.SkuInfoList
.get(skuid
)
878 if "STANDARD" not in skuobj
.DefaultStoreDict
:
879 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
])
880 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
881 skuobj
.DefaultStoreDict
['STANDARD'] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
884 ## Retrieve all PCD settings in platform
886 if self
._Pcds
== None:
888 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
889 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
890 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
891 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
892 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
893 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
894 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
895 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
896 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
898 self
._Pcds
= self
.CompletePcdValues(self
._Pcds
)
899 self
._Pcds
= self
.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST
, self
._Pcds
)
900 self
._Pcds
= self
.CompleteHiiPcdsDefaultStores(self
._Pcds
)
901 self
._Pcds
= self
._FilterPcdBySkuUsage
(self
._Pcds
)
904 def _dumpPcdInfo(self
,Pcds
):
907 if not pcdobj
.TokenCName
.startswith("Test"):
909 for skuid
in pcdobj
.SkuInfoList
:
910 if pcdobj
.Type
in (self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]):
911 for storename
in pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
:
912 print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,storename
,str(pcdobj
.SkuInfoList
[skuid
].DefaultStoreDict
[storename
]))
914 print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj
.TokenSpaceGuidCName
, pcdobj
.TokenCName
)), skuid
,str(pcdobj
.SkuInfoList
[skuid
].DefaultValue
))
915 ## Retrieve [BuildOptions]
916 def _GetBuildOptions(self
):
917 if self
._BuildOptions
== None:
918 self
._BuildOptions
= sdict()
920 # Retrieve build option for EDKII and EDK style module
922 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
923 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
924 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
925 if Dummy3
.upper() != 'COMMON':
927 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
929 # Only flags can be appended
931 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
932 self
._BuildOptions
[CurKey
] = Option
934 if ' ' + Option
not in self
._BuildOptions
[CurKey
]:
935 self
._BuildOptions
[CurKey
] += ' ' + Option
936 return self
._BuildOptions
938 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
939 if self
._ModuleTypeOptions
== None:
940 self
._ModuleTypeOptions
= sdict()
941 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
943 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
944 DriverType
= '%s.%s' % (Edk
, ModuleType
)
945 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
946 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
]
947 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
948 Type
= Dummy2
+ '.' + Dummy3
949 if Type
.upper() == DriverType
.upper() or Type
.upper() == CommonDriverType
.upper():
950 Key
= (ToolChainFamily
, ToolChain
, Edk
)
951 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
952 options
[Key
] = Option
954 if ' ' + Option
not in options
[Key
]:
955 options
[Key
] += ' ' + Option
956 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
958 def GetStructurePcdInfo(self
, PcdSet
):
959 structure_pcd_data
= {}
961 if (item
[0],item
[1]) not in structure_pcd_data
:
962 structure_pcd_data
[(item
[0],item
[1])] = []
963 structure_pcd_data
[(item
[0],item
[1])].append(item
)
965 return structure_pcd_data
967 def UpdateStructuredPcds(self
, TypeList
, AllPcds
):
969 DynamicPcdType
= [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
970 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
971 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
972 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
973 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
974 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]
977 DefaultStoreMgr
= DefaultStore(self
.DefaultStores
)
978 SkuIds
= self
.SkuIdMgr
.AvailableSkuIdSet
979 SkuIds
.update({'DEFAULT':0})
980 DefaultStores
= set([storename
for pcdobj
in AllPcds
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
983 # Find out all possible PCD candidates for self._Arch
986 for Type
in TypeList
:
987 RecordList
.extend(self
._RawData
[Type
, self
._Arch
])
989 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, default_store
, Dummy4
,Dummy5
in RecordList
:
990 SkuName
= SkuName
.upper()
991 default_store
= default_store
.upper()
992 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
993 if SkuName
not in SkuIds
:
996 if SkuName
in SkuIds
and "." in TokenSpaceGuid
:
997 S_PcdSet
.append(( TokenSpaceGuid
.split(".")[0],TokenSpaceGuid
.split(".")[1], PcdCName
,SkuName
, default_store
,Dummy5
, AnalyzePcdExpression(Setting
)[0]))
999 # handle pcd value override
1000 StrPcdSet
= self
.GetStructurePcdInfo(S_PcdSet
)
1002 for str_pcd
in StrPcdSet
:
1003 str_pcd_obj
= Pcds
.get((str_pcd
[1], str_pcd
[0]), None)
1004 str_pcd_dec
= self
._DecPcds
.get((str_pcd
[1], str_pcd
[0]), None)
1006 str_pcd_obj_str
= StructurePcd()
1007 str_pcd_obj_str
.copy(str_pcd_dec
)
1009 str_pcd_obj_str
.copy(str_pcd_obj
)
1010 if str_pcd_obj
.DefaultValue
:
1011 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1012 for str_pcd_data
in StrPcdSet
[str_pcd
]:
1013 if str_pcd_data
[3] in SkuIds
:
1014 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])
1015 S_pcd_set
[str_pcd
[1], str_pcd
[0]] = str_pcd_obj_str
1017 EdkLogger
.error('build', PARSER_ERROR
,
1018 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd
[0], str_pcd
[1], self
._Arch
),
1019 File
=self
.MetaFile
,Line
= StrPcdSet
[str_pcd
][0][5])
1020 # Add the Structure PCD that only defined in DEC, don't have override in DSC file
1021 for Pcd
in self
.DecPcds
:
1022 if type (self
._DecPcds
[Pcd
]) is StructurePcd
:
1023 if Pcd
not in S_pcd_set
:
1024 str_pcd_obj_str
= StructurePcd()
1025 str_pcd_obj_str
.copy(self
._DecPcds
[Pcd
])
1026 str_pcd_obj
= Pcds
.get(Pcd
, None)
1028 str_pcd_obj_str
.copy(str_pcd_obj
)
1029 if str_pcd_obj
.DefaultValue
:
1030 str_pcd_obj_str
.DefaultFromDSC
= str_pcd_obj
.DefaultValue
1031 S_pcd_set
[Pcd
] = str_pcd_obj_str
1033 GlobalData
.gStructurePcd
[self
.Arch
] = S_pcd_set
1034 for stru_pcd
in S_pcd_set
.values():
1035 for skuid
in SkuIds
:
1036 if skuid
in stru_pcd
.SkuOverrideValues
:
1038 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuid
)
1040 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1041 if nextskuid
== "DEFAULT":
1044 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1045 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
})
1046 if stru_pcd
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1047 for skuid
in SkuIds
:
1050 if skuid
not in stru_pcd
.SkuOverrideValues
:
1051 while nextskuid
not in stru_pcd
.SkuOverrideValues
:
1052 if nextskuid
== "DEFAULT":
1055 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1058 PcdDefaultStoreSet
= set([defaultstorename
for defaultstorename
in stru_pcd
.SkuOverrideValues
[nextskuid
]])
1059 mindefaultstorename
= DefaultStoreMgr
.GetMin(PcdDefaultStoreSet
)
1061 for defaultstoreid
in DefaultStores
:
1062 if defaultstoreid
not in stru_pcd
.SkuOverrideValues
[skuid
]:
1063 stru_pcd
.SkuOverrideValues
[skuid
][defaultstoreid
] = copy
.deepcopy(stru_pcd
.SkuOverrideValues
[nextskuid
][mindefaultstorename
])
1065 Str_Pcd_Values
= self
.GenerateByteArrayValue(S_pcd_set
)
1067 for (skuname
,StoreName
,PcdGuid
,PcdName
,PcdValue
) in Str_Pcd_Values
:
1068 str_pcd_obj
= S_pcd_set
.get((PcdName
, PcdGuid
))
1069 if str_pcd_obj
is None:
1070 print PcdName
, PcdGuid
1072 if str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1073 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1074 if skuname
not in str_pcd_obj
.SkuInfoList
:
1075 str_pcd_obj
.SkuInfoList
[skuname
] = SkuInfoClass(SkuIdName
=skuname
, SkuId
=self
.SkuIds
[skuname
][0], HiiDefaultValue
=PcdValue
, DefaultStore
= {StoreName
:PcdValue
})
1077 str_pcd_obj
.SkuInfoList
[skuname
].HiiDefaultValue
= PcdValue
1078 str_pcd_obj
.SkuInfoList
[skuname
].DefaultStoreDict
.update({StoreName
:PcdValue
})
1079 elif str_pcd_obj
.Type
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_FIXED_AT_BUILD
],
1080 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_PATCHABLE_IN_MODULE
]]:
1081 if skuname
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1082 str_pcd_obj
.DefaultValue
= PcdValue
1084 if skuname
not in str_pcd_obj
.SkuInfoList
:
1085 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1087 while nextskuid
not in str_pcd_obj
.SkuInfoList
:
1088 if nextskuid
== "DEFAULT":
1091 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1092 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
)
1093 str_pcd_obj
.SkuInfoList
[skuname
].SkuId
= self
.SkuIds
[skuname
][0]
1094 str_pcd_obj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1096 str_pcd_obj
.SkuInfoList
[skuname
].DefaultValue
= PcdValue
1097 for str_pcd_obj
in S_pcd_set
.values():
1098 if str_pcd_obj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1099 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1101 PcdDefaultStoreSet
= set([defaultstorename
for skuobj
in str_pcd_obj
.SkuInfoList
.values() for defaultstorename
in skuobj
.DefaultStoreDict
])
1102 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1103 mindefaultstorename
= DefaultStoreObj
.GetMin(PcdDefaultStoreSet
)
1104 str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].HiiDefaultValue
= str_pcd_obj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
].DefaultStoreDict
[mindefaultstorename
]
1106 for str_pcd_obj
in S_pcd_set
.values():
1108 str_pcd_obj
.MaxDatumSize
= self
.GetStructurePcdMaxSize(str_pcd_obj
)
1109 Pcds
[str_pcd_obj
.TokenCName
, str_pcd_obj
.TokenSpaceGuidCName
] = str_pcd_obj
1113 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1114 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1115 del(pcd
.SkuInfoList
['COMMON'])
1116 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1117 del(pcd
.SkuInfoList
['COMMON'])
1119 map(self
.FilterSkuSettings
,[Pcds
[pcdkey
] for pcdkey
in Pcds
if Pcds
[pcdkey
].Type
in DynamicPcdType
])
1122 ## Retrieve non-dynamic PCD settings
1124 # @param Type PCD type
1126 # @retval a dict object contains settings of given PCD type
1128 def _GetPcd(self
, Type
):
1131 # tdict is a special dict kind of type, used for selecting correct
1132 # PCD settings for certain ARCH
1134 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1136 PcdDict
= tdict(True, 3)
1138 # Find out all possible PCD candidates for self._Arch
1139 RecordList
= self
._RawData
[Type
, self
._Arch
]
1140 PcdValueDict
= sdict()
1141 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1142 SkuName
= SkuName
.upper()
1143 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1144 if SkuName
not in AvailableSkuIdSet
:
1145 EdkLogger
.error('build ', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1146 File
=self
.MetaFile
, Line
=Dummy5
)
1147 if SkuName
in (self
.SkuIdMgr
.SystemSkuId
, 'DEFAULT', 'COMMON'):
1148 if "." not in TokenSpaceGuid
:
1149 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1150 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
, SkuName
] = Setting
1152 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdSet
:
1153 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
, SkuName
]
1156 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1157 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
1158 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
, DatumType
, MaxDatumSize
)
1160 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
, DatumType
, MaxDatumSize
)}
1162 PcdsKeys
= PcdValueDict
.keys()
1163 for PcdCName
, TokenSpaceGuid
in PcdsKeys
:
1165 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
1169 if 'COMMON' in PcdSetting
:
1170 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['COMMON']
1171 if 'DEFAULT' in PcdSetting
:
1172 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
['DEFAULT']
1173 if self
.SkuIdMgr
.SystemSkuId
in PcdSetting
:
1174 PcdValue
, DatumType
, MaxDatumSize
= PcdSetting
[self
.SkuIdMgr
.SystemSkuId
]
1176 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1179 self
._PCD
_TYPE
_STRING
_[Type
],
1192 def __UNICODE2OCTList(self
,Value
):
1193 Value
= Value
.strip()
1197 Temp
= '%04X' % ord(Item
)
1198 List
.append('0x' + Temp
[2:4])
1199 List
.append('0x' + Temp
[0:2])
1203 def __STRING2OCTList(self
,Value
):
1205 Value
= Value
.strip('"')
1207 Temp
= '%02X' % ord(char
)
1208 OCTList
.append('0x' + Temp
)
1209 OCTList
.append('0x00')
1212 def GetStructurePcdMaxSize(self
, str_pcd
):
1213 pcd_default_value
= str_pcd
.DefaultValue
1214 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()]
1215 sku_values
.append(pcd_default_value
)
1217 def get_length(value
):
1218 Value
= value
.strip()
1220 if Value
.startswith('GUID') and Value
.endswith(')'):
1222 if Value
.startswith('L"') and Value
.endswith('"'):
1223 return len(Value
[2:-1])
1224 if Value
[0] == '"' and Value
[-1] == '"':
1225 return len(Value
) - 2
1226 if Value
[0] == '{' and Value
[-1] == '}':
1227 return len(Value
.split(","))
1228 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1229 return len(list(Value
[2:-1]))
1230 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1231 return len(Value
) - 2
1234 return str(max([pcd_size
for pcd_size
in [get_length(item
) for item
in sku_values
]]))
1236 def IsFieldValueAnArray (self
, Value
):
1237 Value
= Value
.strip()
1238 if Value
.startswith('GUID') and Value
.endswith(')'):
1240 if Value
.startswith('L"') and Value
.endswith('"') and len(list(Value
[2:-1])) > 1:
1242 if Value
[0] == '"' and Value
[-1] == '"' and len(list(Value
[1:-1])) > 1:
1244 if Value
[0] == '{' and Value
[-1] == '}':
1246 if Value
.startswith("L'") and Value
.endswith("'") and len(list(Value
[2:-1])) > 1:
1247 print 'foo = ', list(Value
[2:-1])
1249 if Value
[0] == "'" and Value
[-1] == "'" and len(list(Value
[1:-1])) > 1:
1250 print 'bar = ', list(Value
[1:-1])
1254 def ExecuteCommand (self
, Command
):
1256 Process
= subprocess
.Popen(Command
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
1258 print 'ERROR: Can not execute command:', Command
1260 Result
= Process
.communicate()
1261 if Process
.returncode
<> 0:
1262 print 'ERROR: Can not collect output from command:', Command
1263 return Result
[0], Result
[1]
1265 def IntToCString(self
, Value
, ValueSize
):
1267 if not isinstance (Value
, str):
1268 for Index
in range(0, ValueSize
):
1269 Result
= Result
+ '\\x%02x' % (Value
& 0xff)
1271 Result
= Result
+ '"'
1274 def GenerateInitializeFunc(self
, SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
):
1275 OverrideValues
= {DefaultStoreName
:""}
1276 if Pcd
.SkuOverrideValues
:
1277 OverrideValues
= Pcd
.SkuOverrideValues
[SkuName
]
1278 for DefaultStoreName
in OverrideValues
.keys():
1279 CApp
= CApp
+ 'void\n'
1280 CApp
= CApp
+ 'Initialize_%s_%s_%s_%s(\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1281 CApp
= CApp
+ ' void\n'
1282 CApp
= CApp
+ ' )\n'
1284 CApp
= CApp
+ ' UINT32 Size;\n'
1285 CApp
= CApp
+ ' UINT32 FieldSize;\n'
1286 CApp
= CApp
+ ' CHAR8 *Value;\n'
1287 CApp
= CApp
+ ' UINT32 OriginalSize;\n'
1288 CApp
= CApp
+ ' VOID *OriginalPcd;\n'
1289 CApp
= CApp
+ ' %s *Pcd;\n' % (Pcd
.DatumType
)
1292 Pcd
.DefaultValue
= Pcd
.DefaultValue
.strip()
1293 PcdDefaultValue
= StringToArray(Pcd
.DefaultValue
)
1295 InitByteValue
+= '%s.%s.%s.%s|%s|%s\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DatumType
, PcdDefaultValue
)
1298 # Get current PCD value and size
1300 CApp
= CApp
+ ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1303 # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
1304 # the correct value. For structures with a flexible array member, the flexible
1305 # array member is detected, and the size is based on the highest index used with
1306 # the flexible array member. The flexible array member must be the last field
1307 # in a structure. The size formula for this case is:
1308 # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
1310 CApp
= CApp
+ ' Size = sizeof(%s);\n' % (Pcd
.DatumType
)
1311 for FieldList
in [Pcd
.DefaultValues
]:
1314 for FieldName
in FieldList
:
1315 FieldName
= "." + FieldName
1316 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1318 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1319 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("."));
1322 while '[' in FieldName
:
1323 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1324 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1325 FieldName
= FieldName
.split(']', 1)[1]
1326 FieldName
= NewFieldName
+ FieldName
1327 while '[' in FieldName
:
1328 FieldName
= FieldName
.rsplit('[', 1)[0]
1329 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1330 for skuname
in self
.SkuIdMgr
.SkuOverrideOrder():
1331 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1332 for FieldList
in [inherit_OverrideValues
.get(DefaultStoreName
)]:
1335 for FieldName
in FieldList
:
1336 FieldName
= "." + FieldName
1337 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
.strip(".")][0])
1339 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
.strip(".")][0])
1340 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("."));
1343 while '[' in FieldName
:
1344 NewFieldName
= NewFieldName
+ FieldName
.split('[', 1)[0] + '[0]'
1345 ArrayIndex
= int(FieldName
.split('[', 1)[1].split(']', 1)[0])
1346 FieldName
= FieldName
.split(']', 1)[1]
1347 FieldName
= NewFieldName
+ FieldName
1348 while '[' in FieldName
:
1349 FieldName
= FieldName
.rsplit('[', 1)[0]
1350 CApp
= CApp
+ ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd
.DatumType
, FieldName
.strip("."), ArrayIndex
+ 1)
1351 if skuname
== SkuName
:
1355 # Allocate and zero buffer for the PCD
1356 # Must handle cases where current value is smaller, larger, or same size
1357 # Always keep that larger one as the current size
1359 CApp
= CApp
+ ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
1360 CApp
= CApp
+ ' Pcd = (%s *)malloc (Size);\n' % (Pcd
.DatumType
)
1361 CApp
= CApp
+ ' memset (Pcd, 0, Size);\n'
1364 # Copy current PCD value into allocated buffer.
1366 CApp
= CApp
+ ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
1369 # Assign field values in PCD
1371 for FieldList
in [Pcd
.DefaultValues
]:
1374 for FieldName
in FieldList
:
1375 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1377 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1379 print FieldList
[FieldName
][0]
1380 if isinstance(Value
, str):
1381 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1384 # Use memcpy() to copy value into field
1386 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1387 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1388 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1391 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1393 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1394 for skuname
in self
.SkuIdMgr
.SkuOverrideOrder():
1395 inherit_OverrideValues
= Pcd
.SkuOverrideValues
[skuname
]
1396 for FieldList
in [Pcd
.DefaultFromDSC
,inherit_OverrideValues
.get(DefaultStoreName
)]:
1399 if Pcd
.DefaultFromDSC
and FieldList
== Pcd
.DefaultFromDSC
:
1400 IsArray
= self
.IsFieldValueAnArray(FieldList
)
1401 Value
, ValueSize
= ParseFieldValue (FieldList
)
1402 if isinstance(Value
, str):
1403 CApp
= CApp
+ ' Pcd = %s; // From DSC Default Value %s\n' % (Value
, Pcd
.DefaultFromDSC
)
1406 # Use memcpy() to copy value into field
1408 CApp
= CApp
+ ' Value = %s; // From DSC Default Value %s\n' % (self
.IntToCString(Value
, ValueSize
), Pcd
.DefaultFromDSC
)
1409 CApp
= CApp
+ ' memcpy (Pcd, Value, %d);\n' % (ValueSize
)
1412 for FieldName
in FieldList
:
1413 IsArray
= self
.IsFieldValueAnArray(FieldList
[FieldName
][0])
1415 Value
, ValueSize
= ParseFieldValue (FieldList
[FieldName
][0])
1417 print FieldList
[FieldName
][0]
1418 if isinstance(Value
, str):
1419 CApp
= CApp
+ ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1422 # Use memcpy() to copy value into field
1424 CApp
= CApp
+ ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd
.DatumType
, FieldName
)
1425 CApp
= CApp
+ ' Value = %s; // From %s Line %d Value %s\n' % (self
.IntToCString(Value
, ValueSize
), FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1426 CApp
= CApp
+ ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName
, ValueSize
, ValueSize
)
1429 CApp
= CApp
+ ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1431 CApp
= CApp
+ ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName
, Value
, FieldList
[FieldName
][1], FieldList
[FieldName
][2], FieldList
[FieldName
][0])
1432 if skuname
== SkuName
:
1435 # Set new PCD value and size
1437 CApp
= CApp
+ ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1442 CApp
= CApp
+ ' free (Pcd);\n'
1445 return InitByteValue
, CApp
1447 def GenerateByteArrayValue (self
, StructuredPcds
):
1449 # Generate/Compile/Run C application to determine if there are any flexible array members
1451 if not StructuredPcds
:
1455 CApp
= PcdMainCHeader
1458 for PcdName
in StructuredPcds
:
1459 Pcd
= StructuredPcds
[PcdName
]
1460 IncludeFile
= Pcd
.StructuredPcdIncludeFile
1461 if IncludeFile
not in Includes
:
1462 Includes
[IncludeFile
] = True
1463 CApp
= CApp
+ '#include <%s>\n' % (IncludeFile
)
1466 for PcdName
in StructuredPcds
:
1467 Pcd
= StructuredPcds
[PcdName
]
1468 if not Pcd
.SkuOverrideValues
:
1469 InitByteValue
, CApp
= self
.GenerateInitializeFunc(self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
, InitByteValue
, CApp
)
1471 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1472 if SkuName
not in Pcd
.SkuOverrideValues
:
1474 for DefaultStoreName
in Pcd
.DefaultStoreName
:
1475 Pcd
= StructuredPcds
[PcdName
]
1476 InitByteValue
, CApp
= self
.GenerateInitializeFunc(SkuName
, DefaultStoreName
, Pcd
, InitByteValue
, CApp
)
1478 CApp
= CApp
+ 'VOID\n'
1479 CApp
= CApp
+ 'PcdEntryPoint(\n'
1480 CApp
= CApp
+ ' VOID\n'
1481 CApp
= CApp
+ ' )\n'
1483 for Pcd
in StructuredPcds
.values():
1484 if not Pcd
.SkuOverrideValues
:
1485 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (self
.SkuIdMgr
.SystemSkuId
, 'STANDARD', Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1487 for SkuName
in self
.SkuIdMgr
.SkuOverrideOrder():
1488 if SkuName
not in Pcd
.SkuOverrideValues
:
1490 for DefaultStoreName
in Pcd
.SkuOverrideValues
[SkuName
]:
1491 CApp
= CApp
+ ' Initialize_%s_%s_%s_%s();\n' % (SkuName
, DefaultStoreName
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
)
1494 CApp
= CApp
+ PcdMainCEntry
+ '\n'
1496 if not os
.path
.exists(self
.OutputPath
):
1497 os
.makedirs(self
.OutputPath
)
1498 CAppBaseFileName
= os
.path
.join(self
.OutputPath
, PcdValueInitName
)
1499 File
= open (CAppBaseFileName
+ '.c', 'w')
1503 MakeApp
= PcdMakefileHeader
1504 if sys
.platform
== "win32":
1505 MakeApp
= MakeApp
+ 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s\%s.obj\n' % (self
.OutputPath
, PcdValueInitName
) + 'INC = '
1507 MakeApp
= MakeApp
+ PcdGccMakefile
1508 MakeApp
= MakeApp
+ 'APPNAME = %s\n' % (PcdValueInitName
) + 'OBJECTS = %s/%s.o\n' % (self
.OutputPath
, PcdValueInitName
) + \
1509 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
1512 for Cache
in self
._Bdb
._CACHE
_.values():
1513 if Cache
.MetaFile
.Ext
.lower() != '.dec':
1516 if str(Cache
.MetaFile
.Path
) not in PlatformInc
:
1517 PlatformInc
[str(Cache
.MetaFile
.Path
)] = Cache
.Includes
1520 for Pcd
in StructuredPcds
.values():
1521 for PackageDec
in Pcd
.PackageDecs
:
1522 Package
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, PackageDec
))
1523 if not os
.path
.exists(Package
):
1524 EdkLogger
.error('Build', RESOURCE_NOT_AVAILABLE
, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1525 if Package
not in PcdDependDEC
:
1526 PcdDependDEC
.append(Package
)
1528 if PlatformInc
and PcdDependDEC
:
1529 for pkg
in PcdDependDEC
:
1530 if pkg
in PlatformInc
:
1531 for inc
in PlatformInc
[pkg
]:
1532 MakeApp
+= '-I' + str(inc
) + ' '
1533 MakeApp
= MakeApp
+ '\n'
1535 CC_FLAGS
= LinuxCFLAGS
1536 if sys
.platform
== "win32":
1537 CC_FLAGS
= WindowsCFLAGS
1539 for Options
in self
.BuildOptions
:
1540 if Options
[2] != EDKII_NAME
:
1543 if Family
and Family
!= self
.ToolChainFamily
:
1545 Target
, Tag
, Arch
, Tool
, Attr
= Options
[1].split("_")
1549 if Target
== "*" or Target
== self
._Target
:
1550 if Tag
== "*" or Tag
== self
._Toolchain
:
1551 if Arch
== "*" or Arch
== self
.Arch
:
1552 if Tool
not in BuildOptions
:
1553 BuildOptions
[Tool
] = {}
1554 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or self
.BuildOptions
[Options
].startswith('='):
1555 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1557 # append options for the same tool except PATH
1559 BuildOptions
[Tool
][Attr
] += " " + self
.BuildOptions
[Options
]
1561 BuildOptions
[Tool
][Attr
] = self
.BuildOptions
[Options
]
1563 for Tool
in BuildOptions
:
1564 for Attr
in BuildOptions
[Tool
]:
1566 Value
= BuildOptions
[Tool
][Attr
]
1567 ValueList
= Value
.split()
1569 for Id
, Item
in enumerate(ValueList
):
1570 if Item
== '-D' or Item
== '/D':
1571 CC_FLAGS
+= ' ' + Item
1572 if Id
+ 1 < len(ValueList
):
1573 CC_FLAGS
+= ' ' + ValueList
[Id
+ 1]
1574 elif Item
.startswith('/D') or Item
.startswith('-D'):
1575 CC_FLAGS
+= ' ' + Item
1578 if sys
.platform
== "win32":
1579 MakeApp
= MakeApp
+ PcdMakefileEnd
1580 MakeFileName
= os
.path
.join(self
.OutputPath
, 'Makefile')
1581 File
= open (MakeFileName
, 'w')
1585 InputValueFile
= os
.path
.join(self
.OutputPath
, 'Input.txt')
1586 OutputValueFile
= os
.path
.join(self
.OutputPath
, 'Output.txt')
1587 File
= open (InputValueFile
, 'w')
1588 File
.write(InitByteValue
)
1592 if sys
.platform
== "win32":
1593 StdOut
, StdErr
= self
.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName
))
1596 StdOut
, StdErr
= self
.ExecuteCommand ('make clean & make -f %s' % (MakeFileName
))
1598 Messages
= Messages
.split('\n')
1599 for Message
in Messages
:
1600 if " error" in Message
:
1601 FileInfo
= Message
.strip().split('(')
1602 if len (FileInfo
) > 1:
1603 FileName
= FileInfo
[0]
1604 FileLine
= FileInfo
[1].split (')')[0]
1606 FileInfo
= Message
.strip().split(':')
1607 FileName
= FileInfo
[0]
1608 FileLine
= FileInfo
[1]
1610 File
= open (FileName
, 'r')
1611 FileData
= File
.readlines()
1613 error_line
= FileData
[int (FileLine
) - 1]
1614 if r
"//" in error_line
:
1615 c_line
,dsc_line
= error_line
.split(r
"//")
1617 dsc_line
= error_line
1619 message_itmes
= Message
.split(":")
1621 for item
in message_itmes
:
1622 if "PcdValueInit.c" in item
:
1623 Index
= message_itmes
.index(item
)
1624 message_itmes
[Index
] = dsc_line
.strip()
1627 EdkLogger
.error("build", PCD_STRUCTURE_PCD_ERROR
, ":".join(message_itmes
[Index
:]))
1629 PcdValueInitExe
= PcdValueInitName
1630 if not sys
.platform
== "win32":
1631 PcdValueInitExe
= os
.path
.join(os
.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName
)
1633 StdOut
, StdErr
= self
.ExecuteCommand (PcdValueInitExe
+ ' -i %s -o %s' % (InputValueFile
, OutputValueFile
))
1634 File
= open (OutputValueFile
, 'r')
1635 FileBuffer
= File
.readlines()
1638 StructurePcdSet
= []
1639 for Pcd
in FileBuffer
:
1640 PcdValue
= Pcd
.split ('|')
1641 PcdInfo
= PcdValue
[0].split ('.')
1642 StructurePcdSet
.append((PcdInfo
[0],PcdInfo
[1], PcdInfo
[2], PcdInfo
[3], PcdValue
[2].strip()))
1643 return StructurePcdSet
1645 ## Retrieve dynamic PCD settings
1647 # @param Type PCD type
1649 # @retval a dict object contains settings of given PCD type
1651 def _GetDynamicPcd(self
, Type
):
1656 # tdict is a special dict kind of type, used for selecting correct
1657 # PCD settings for certain ARCH and SKU
1659 PcdDict
= tdict(True, 4)
1661 # Find out all possible PCD candidates for self._Arch
1662 RecordList
= self
._RawData
[Type
, self
._Arch
]
1663 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1666 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1667 SkuName
= SkuName
.upper()
1668 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1669 if SkuName
not in AvailableSkuIdSet
:
1670 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1671 File
=self
.MetaFile
, Line
=Dummy5
)
1672 if "." not in TokenSpaceGuid
:
1673 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1674 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1676 # Remove redundant PCD candidates, per the ARCH and SKU
1677 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1679 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1683 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1684 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', '', PcdValue
)
1685 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1686 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1687 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1688 if MaxDatumSize
.strip():
1689 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
1692 if pcdObject
.MaxDatumSize
:
1693 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
1696 if CurrentMaxSize
> PcdMaxSize
:
1697 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1699 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1702 self
._PCD
_TYPE
_STRING
_[Type
],
1707 {SkuName
: SkuInfo
},
1712 for pcd
in Pcds
.values():
1713 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1714 # Only fix the value while no value provided in DSC file.
1715 for sku
in pcd
.SkuInfoList
.values():
1716 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
1717 sku
.DefaultValue
= pcdDecObject
.DefaultValue
1718 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1719 valuefromDec
= pcdDecObject
.DefaultValue
1720 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
1721 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1722 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1723 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1724 del(pcd
.SkuInfoList
['COMMON'])
1725 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1726 del(pcd
.SkuInfoList
['COMMON'])
1728 map(self
.FilterSkuSettings
,Pcds
.values())
1732 def FilterSkuSettings(self
, PcdObj
):
1734 if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
:
1735 if 'DEFAULT' in PcdObj
.SkuInfoList
.keys() and self
.SkuIdMgr
.SystemSkuId
not in PcdObj
.SkuInfoList
.keys():
1736 PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
] = PcdObj
.SkuInfoList
['DEFAULT']
1737 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
[self
.SkuIdMgr
.SystemSkuId
]}
1738 PcdObj
.SkuInfoList
['DEFAULT'].SkuIdName
= 'DEFAULT'
1739 PcdObj
.SkuInfoList
['DEFAULT'].SkuId
= '0'
1741 elif self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.DEFAULT
:
1742 PcdObj
.SkuInfoList
= {'DEFAULT':PcdObj
.SkuInfoList
['DEFAULT']}
1747 def CompareVarAttr(self
, Attr1
, Attr2
):
1748 if not Attr1
or not Attr2
: # for empty string
1750 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
1751 Attr1Set
= set(Attr1s
)
1752 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
1753 Attr2Set
= set(Attr2s
)
1754 if Attr2Set
== Attr1Set
:
1758 def CompletePcdValues(self
,PcdSet
):
1760 DefaultStoreObj
= DefaultStore(self
._GetDefaultStores
())
1761 SkuIds
= {skuname
:skuid
for skuname
,skuid
in self
.SkuIdMgr
.AvailableSkuIdSet
.items() if skuname
!='COMMON'}
1762 DefaultStores
= set([storename
for pcdobj
in PcdSet
.values() for skuobj
in pcdobj
.SkuInfoList
.values() for storename
in skuobj
.DefaultStoreDict
.keys()])
1763 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1764 PcdObj
= PcdSet
[(PcdCName
, TokenSpaceGuid
)]
1765 if PcdObj
.Type
not in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_DEFAULT
],
1766 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
],
1767 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_VPD
],
1768 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_DEFAULT
],
1769 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
],
1770 self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_VPD
]]:
1771 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1773 PcdType
= PcdObj
.Type
1774 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1775 for skuid
in PcdObj
.SkuInfoList
:
1776 skuobj
= PcdObj
.SkuInfoList
[skuid
]
1777 mindefaultstorename
= DefaultStoreObj
.GetMin(set([defaultstorename
for defaultstorename
in skuobj
.DefaultStoreDict
]))
1778 for defaultstorename
in DefaultStores
:
1779 if defaultstorename
not in skuobj
.DefaultStoreDict
:
1780 skuobj
.DefaultStoreDict
[defaultstorename
] = copy
.deepcopy(skuobj
.DefaultStoreDict
[mindefaultstorename
])
1781 skuobj
.HiiDefaultValue
= skuobj
.DefaultStoreDict
[mindefaultstorename
]
1782 for skuname
,skuid
in SkuIds
.items():
1783 if skuname
not in PcdObj
.SkuInfoList
:
1784 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(skuname
)
1785 while nextskuid
not in PcdObj
.SkuInfoList
:
1786 nextskuid
= self
.SkuIdMgr
.GetNextSkuId(nextskuid
)
1787 PcdObj
.SkuInfoList
[skuname
] = copy
.deepcopy(PcdObj
.SkuInfoList
[nextskuid
])
1788 PcdObj
.SkuInfoList
[skuname
].SkuId
= skuid
1789 PcdObj
.SkuInfoList
[skuname
].SkuIdName
= skuname
1790 if PcdType
in [self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_HII
], self
._PCD
_TYPE
_STRING
_[MODEL_PCD_DYNAMIC_EX_HII
]]:
1791 PcdObj
.DefaultValue
= PcdObj
.SkuInfoList
.values()[0].HiiDefaultValue
if self
.SkuIdMgr
.SkuUsageType
== self
.SkuIdMgr
.SINGLE
else PcdObj
.SkuInfoList
["DEFAULT"].HiiDefaultValue
1792 Pcds
[PcdCName
, TokenSpaceGuid
]= PcdObj
1794 ## Retrieve dynamic HII PCD settings
1796 # @param Type PCD type
1798 # @retval a dict object contains settings of given PCD type
1800 def _GetDynamicHiiPcd(self
, Type
):
1806 # tdict is a special dict kind of type, used for selecting correct
1807 # PCD settings for certain ARCH and SKU
1809 PcdDict
= tdict(True, 5)
1811 RecordList
= self
._RawData
[Type
, self
._Arch
]
1812 # Find out all possible PCD candidates for self._Arch
1813 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1814 DefaultStoresDefine
= self
._GetDefaultStores
()
1816 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, DefaultStore
, Dummy4
,Dummy5
in RecordList
:
1817 SkuName
= SkuName
.upper()
1818 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1819 DefaultStore
= DefaultStore
.upper()
1820 if DefaultStore
== "COMMON":
1821 DefaultStore
= "STANDARD"
1822 if SkuName
not in AvailableSkuIdSet
:
1823 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1824 File
=self
.MetaFile
, Line
=Dummy5
)
1825 if DefaultStore
not in DefaultStoresDefine
:
1826 EdkLogger
.error('build', PARAMETER_INVALID
, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore
,
1827 File
=self
.MetaFile
, Line
=Dummy5
)
1828 if "." not in TokenSpaceGuid
:
1829 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
))
1830 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
] = Setting
1833 # Remove redundant PCD candidates, per the ARCH and SKU
1834 for PcdCName
, TokenSpaceGuid
, SkuName
,DefaultStore
, Dummy4
in PcdSet
:
1836 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
,DefaultStore
]
1839 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1841 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1843 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1844 ExtraData
="[%s]" % VarAttribute
)
1846 FormatCorrect
= True
1847 if VariableOffset
.isdigit():
1848 if int(VariableOffset
, 10) > 0xFFFF:
1850 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset
):
1851 if int(VariableOffset
, 16) > 0xFFFF:
1853 # For Offset written in "A.B"
1854 elif VariableOffset
.find('.') > -1:
1855 VariableOffsetList
= VariableOffset
.split(".")
1856 if not (len(VariableOffsetList
) == 2
1857 and IsValidWord(VariableOffsetList
[0])
1858 and IsValidWord(VariableOffsetList
[1])):
1859 FormatCorrect
= False
1861 FormatCorrect
= False
1862 if not FormatCorrect
:
1863 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1866 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
, PcdCName
)))
1867 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1868 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1870 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1871 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
)]))
1873 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1874 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1875 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1876 if SkuName
in pcdObject
.SkuInfoList
:
1877 Skuitem
= pcdObject
.SkuInfoList
[SkuName
]
1878 Skuitem
.DefaultStoreDict
.update({DefaultStore
:DefaultValue
})
1880 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1881 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1883 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
=VarAttribute
,DefaultStore
={DefaultStore
:DefaultValue
})
1884 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1887 self
._PCD
_TYPE
_STRING
_[Type
],
1892 {SkuName
: SkuInfo
},
1895 pcdDecObject
.validateranges
,
1896 pcdDecObject
.validlists
,
1897 pcdDecObject
.expressions
,
1901 for pcd
in Pcds
.values():
1902 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1903 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
1904 # Only fix the value while no value provided in DSC file.
1905 for sku
in pcd
.SkuInfoList
.values():
1906 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
== None):
1907 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1908 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1909 valuefromDec
= pcdDecObject
.DefaultValue
1910 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
,VariableAttribute
=SkuInfoObj
.VariableAttribute
,DefaultStore
={DefaultStore
:valuefromDec
})
1911 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1912 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1913 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1914 del(pcd
.SkuInfoList
['COMMON'])
1915 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1916 del(pcd
.SkuInfoList
['COMMON'])
1918 if pcd
.MaxDatumSize
.strip():
1919 MaxSize
= int(pcd
.MaxDatumSize
, 0)
1922 if pcdDecObject
.DatumType
== 'VOID*':
1923 for (_
, skuobj
) in pcd
.SkuInfoList
.items():
1925 skuobj
.HiiDefaultValue
= StringToArray(skuobj
.HiiDefaultValue
)
1926 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1927 if datalen
> MaxSize
:
1929 for defaultst
in skuobj
.DefaultStoreDict
:
1930 skuobj
.DefaultStoreDict
[defaultst
] = StringToArray(skuobj
.DefaultStoreDict
[defaultst
])
1931 pcd
.DefaultValue
= StringToArray(pcd
.DefaultValue
)
1932 pcd
.MaxDatumSize
= str(MaxSize
)
1933 rt
, invalidhii
= self
.CheckVariableNameAssignment(Pcds
)
1935 invalidpcd
= ",".join(invalidhii
)
1936 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
)
1938 map(self
.FilterSkuSettings
,Pcds
.values())
1942 def CheckVariableNameAssignment(self
,Pcds
):
1944 for pcdname
in Pcds
:
1946 varnameset
= set([sku
.VariableName
for (skuid
,sku
) in pcd
.SkuInfoList
.items()])
1947 if len(varnameset
) > 1:
1948 invalidhii
.append(".".join((pcdname
[1],pcdname
[0])))
1950 return False,invalidhii
1953 ## Retrieve dynamic VPD PCD settings
1955 # @param Type PCD type
1957 # @retval a dict object contains settings of given PCD type
1959 def _GetDynamicVpdPcd(self
, Type
):
1964 # tdict is a special dict kind of type, used for selecting correct
1965 # PCD settings for certain ARCH and SKU
1967 PcdDict
= tdict(True, 4)
1970 # Find out all possible PCD candidates for self._Arch
1971 RecordList
= self
._RawData
[Type
, self
._Arch
]
1972 AvailableSkuIdSet
= copy
.copy(self
.SkuIds
)
1974 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
,Dummy5
in RecordList
:
1975 SkuName
= SkuName
.upper()
1976 SkuName
= 'DEFAULT' if SkuName
== 'COMMON' else SkuName
1977 if SkuName
not in AvailableSkuIdSet
:
1978 EdkLogger
.error('build', PARAMETER_INVALID
, 'Sku %s is not defined in [SkuIds] section' % SkuName
,
1979 File
=self
.MetaFile
, Line
=Dummy5
)
1980 if "." not in TokenSpaceGuid
:
1981 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
))
1982 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1984 # Remove redundant PCD candidates, per the ARCH and SKU
1985 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
1986 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1990 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1991 # For the Integer & Boolean type, the optional data can only be InitialValue.
1992 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1993 # until the DEC parser has been called.
1995 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1996 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
][0], '', '', '', '', VpdOffset
, InitialValue
)
1997 if (PcdCName
, TokenSpaceGuid
) in Pcds
.keys():
1998 pcdObject
= Pcds
[PcdCName
, TokenSpaceGuid
]
1999 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
2000 if MaxDatumSize
.strip():
2001 CurrentMaxSize
= int(MaxDatumSize
.strip(), 0)
2004 if pcdObject
.MaxDatumSize
:
2005 PcdMaxSize
= int(pcdObject
.MaxDatumSize
, 0)
2008 if CurrentMaxSize
> PcdMaxSize
:
2009 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
2011 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
2014 self
._PCD
_TYPE
_STRING
_[Type
],
2019 {SkuName
: SkuInfo
},
2023 for pcd
in Pcds
.values():
2024 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
2025 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
, pcd
.TokenSpaceGuidCName
]
2026 # Only fix the value while no value provided in DSC file.
2027 for sku
in pcd
.SkuInfoList
.values():
2028 if (sku
.DefaultValue
== "" or sku
.DefaultValue
==None):
2029 sku
.DefaultValue
= pcdDecObject
.DefaultValue
2030 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
2031 valuefromDec
= pcdDecObject
.DefaultValue
2032 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj
.VpdOffset
, valuefromDec
)
2033 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
2034 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2035 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
2036 del(pcd
.SkuInfoList
['COMMON'])
2037 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
2038 del(pcd
.SkuInfoList
['COMMON'])
2041 map(self
.FilterSkuSettings
,Pcds
.values())
2044 ## Add external modules
2046 # The external modules are mostly those listed in FDF file, which don't
2049 # @param FilePath The path of module description file
2051 def AddModule(self
, FilePath
):
2052 FilePath
= NormPath(FilePath
)
2053 if FilePath
not in self
.Modules
:
2054 Module
= ModuleBuildClassObject()
2055 Module
.MetaFile
= FilePath
2056 self
.Modules
.append(Module
)
2058 def _GetToolChainFamily(self
):
2059 self
._ToolChainFamily
= "MSFT"
2060 BuildConfigurationFile
= os
.path
.normpath(os
.path
.join(GlobalData
.gConfDirectory
, "target.txt"))
2061 if os
.path
.isfile(BuildConfigurationFile
) == True:
2062 TargetTxt
= TargetTxtClassObject()
2063 TargetTxt
.LoadTargetTxtFile(BuildConfigurationFile
)
2064 ToolDefinitionFile
= TargetTxt
.TargetTxtDictionary
[DataType
.TAB_TAT_DEFINES_TOOL_CHAIN_CONF
]
2065 if ToolDefinitionFile
== '':
2066 ToolDefinitionFile
= "tools_def.txt"
2067 ToolDefinitionFile
= os
.path
.normpath(mws
.join(self
.WorkspaceDir
, 'Conf', ToolDefinitionFile
))
2068 if os
.path
.isfile(ToolDefinitionFile
) == True:
2069 ToolDef
= ToolDefClassObject()
2070 ToolDef
.LoadToolDefFile(ToolDefinitionFile
)
2071 ToolDefinition
= ToolDef
.ToolsDefTxtDatabase
2072 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2073 or self
._Toolchain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2074 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]:
2075 self
._ToolChainFamily
= "MSFT"
2077 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
._Toolchain
]
2078 return self
._ToolChainFamily
2080 ## Add external PCDs
2082 # The external PCDs are mostly those listed in FDF file to specify address
2083 # or offset information.
2085 # @param Name Name of the PCD
2086 # @param Guid Token space guid of the PCD
2087 # @param Value Value of the PCD
2089 def AddPcd(self
, Name
, Guid
, Value
):
2090 if (Name
, Guid
) not in self
.Pcds
:
2091 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
2092 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
2095 if self
._DecPcds
== None:
2097 if GlobalData
.gFdfParser
:
2098 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
2100 for Inf
in FdfInfList
:
2101 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2102 if ModuleFile
in self
._Modules
:
2104 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
2105 PkgSet
.update(ModuleData
.Packages
)
2106 self
._DecPcds
, self
._GuidDict
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
,PkgSet
)
2107 return self
._DecPcds
2108 _Macros
= property(_GetMacros
)
2109 Arch
= property(_GetArch
, _SetArch
)
2110 Platform
= property(_GetPlatformName
)
2111 PlatformName
= property(_GetPlatformName
)
2112 Guid
= property(_GetFileGuid
)
2113 Version
= property(_GetVersion
)
2114 DscSpecification
= property(_GetDscSpec
)
2115 OutputDirectory
= property(_GetOutpuDir
)
2116 SupArchList
= property(_GetSupArch
)
2117 BuildTargets
= property(_GetBuildTarget
)
2118 SkuName
= property(_GetSkuName
, _SetSkuName
)
2119 PcdInfoFlag
= property(_GetPcdInfoFlag
)
2120 VarCheckFlag
= property(_GetVarCheckFlag
)
2121 FlashDefinition
= property(_GetFdfFile
)
2122 Prebuild
= property(_GetPrebuild
)
2123 Postbuild
= property(_GetPostbuild
)
2124 BuildNumber
= property(_GetBuildNumber
)
2125 MakefileName
= property(_GetMakefileName
)
2126 BsBaseAddress
= property(_GetBsBaseAddress
)
2127 RtBaseAddress
= property(_GetRtBaseAddress
)
2128 LoadFixAddress
= property(_GetLoadFixAddress
)
2129 RFCLanguages
= property(_GetRFCLanguages
)
2130 ISOLanguages
= property(_GetISOLanguages
)
2131 VpdToolGuid
= property(_GetVpdToolGuid
)
2132 SkuIds
= property(_GetSkuIds
)
2133 Modules
= property(_GetModules
)
2134 LibraryInstances
= property(_GetLibraryInstances
)
2135 LibraryClasses
= property(_GetLibraryClasses
)
2136 Pcds
= property(_GetPcds
)
2137 BuildOptions
= property(_GetBuildOptions
)
2138 ToolChainFamily
= property(_GetToolChainFamily
)