BaseTools: add the support for --pcd feature to patch the binary efi

the original --pcd feature can override the Pcd value when build the
source driver, while it missed the binary driver. this patch add the
support to patch the binary efi for --pcd feature.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Yonghong Zhu
2016-04-20 09:32:52 +08:00
parent 2a29017e3e
commit 6b17c11b6f
4 changed files with 101 additions and 5 deletions

View File

@ -1427,6 +1427,11 @@ class TopLevelMakefile(BuildFile):
if GlobalData.gIgnoreSource: if GlobalData.gIgnoreSource:
ExtraOption += " --ignore-sources" ExtraOption += " --ignore-sources"
if GlobalData.BuildOptionPcd:
for index, option in enumerate(GlobalData.gCommand):
if "--pcd" == option and GlobalData.gCommand[index+1]:
ExtraOption += " --pcd " + GlobalData.gCommand[index+1]
MakefileName = self._FILE_NAME_[self._FileType] MakefileName = self._FILE_NAME_[self._FileType]
SubBuildCommandList = [] SubBuildCommandList = []
for A in PlatformInfo.ArchList: for A in PlatformInfo.ArchList:

View File

@ -1,7 +1,7 @@
## @file ## @file
# process FFS generation from INF statement # process FFS generation from INF statement
# #
# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR> # Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
# #
# This program and the accompanying materials # This program and the accompanying materials
@ -43,6 +43,7 @@ from AutoGen.GenDepex import DependencyExpression
from PatchPcdValue.PatchPcdValue import PatchBinaryFile from PatchPcdValue.PatchPcdValue import PatchBinaryFile
from Common.LongFilePathSupport import CopyLongFilePath from Common.LongFilePathSupport import CopyLongFilePath
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
import Common.GlobalData as GlobalData
## generate FFS from INF ## generate FFS from INF
# #
@ -260,7 +261,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
DefaultValue = FdfPcdDict[PcdKey] DefaultValue = FdfPcdDict[PcdKey]
FdfOverride = True FdfOverride = True
if not DscOverride and not FdfOverride: # Override Patchable PCD value by the value from Build Option
BuildOptionOverride = False
if GlobalData.BuildOptionPcd:
for pcd in GlobalData.BuildOptionPcd:
if PcdKey == (pcd[1], pcd[0]):
DefaultValue = pcd[2]
BuildOptionOverride = True
break
if not DscOverride and not FdfOverride and not BuildOptionOverride:
continue continue
# Check value, if value are equal, no need to patch # Check value, if value are equal, no need to patch
if Pcd.DatumType == "VOID*": if Pcd.DatumType == "VOID*":

View File

@ -38,13 +38,14 @@ from Common.Misc import DirCache, PathClass
from Common.Misc import SaveFileOnChange from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString from Common.Misc import GuidStructureStringToGuidString
from Common.Misc import CheckPcdDatum
from Common.BuildVersion import gBUILD_VERSION from Common.BuildVersion import gBUILD_VERSION
from Common.MultipleWorkspace import MultipleWorkspace as mws from Common.MultipleWorkspace import MultipleWorkspace as mws
## Version and Copyright ## Version and Copyright
versionNumber = "1.0" + ' ' + gBUILD_VERSION versionNumber = "1.0" + ' ' + gBUILD_VERSION
__version__ = "%prog Version " + versionNumber __version__ = "%prog Version " + versionNumber
__copyright__ = "Copyright (c) 2007 - 2014, Intel Corporation All rights reserved." __copyright__ = "Copyright (c) 2007 - 2016, Intel Corporation All rights reserved."
## Tool entrance method ## Tool entrance method
# #
@ -266,6 +267,14 @@ def main():
EdkLogger.error("GenFds", OPTION_VALUE_INVALID, EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
"No such a Capsule in FDF file: %s" % Options.uiCapName) "No such a Capsule in FDF file: %s" % Options.uiCapName)
GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
if ArchList != None:
GenFdsGlobalVariable.ArchList = ArchList
if Options.OptionPcd:
GlobalData.BuildOptionPcd = Options.OptionPcd
CheckBuildOptionPcd()
"""Modify images from build output if the feature of loading driver at fixed address is on.""" """Modify images from build output if the feature of loading driver at fixed address is on."""
if GenFdsGlobalVariable.FixedLoadAddress: if GenFdsGlobalVariable.FixedLoadAddress:
GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
@ -309,6 +318,79 @@ def SingleCheckCallback(option, opt_str, value, parser):
else: else:
parser.error("Option %s only allows one instance in command line!" % option) parser.error("Option %s only allows one instance in command line!" % option)
def CheckBuildOptionPcd():
for Arch in GenFdsGlobalVariable.ArchList:
PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)
for i, pcd in enumerate(GlobalData.BuildOptionPcd):
if type(pcd) is tuple:
continue
(pcdname, pcdvalue) = pcd.split('=')
if not pcdvalue:
EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))
if '.' in pcdname:
(TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
HasTokenSpace = True
else:
TokenCName = pcdname
TokenSpaceGuidCName = ''
HasTokenSpace = False
TokenSpaceGuidCNameList = []
FoundFlag = False
PcdDatumType = ''
NewValue = ''
for package in PkgList:
for key in package.Pcds:
PcdItem = package.Pcds[key]
if HasTokenSpace:
if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
PcdDatumType = PcdItem.DatumType
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
if PcdItem.TokenCName == TokenCName:
if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
if len (TokenSpaceGuidCNameList) < 1:
TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
PcdDatumType = PcdItem.DatumType
TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
FoundFlag = True
else:
EdkLogger.error(
'GenFds',
PCD_VALIDATION_INFO_ERROR,
"The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
)
GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)
def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
if PcdDatumType == 'VOID*':
if Value.startswith('L'):
if not Value[1]:
EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
Value = Value[0] + '"' + Value[1:] + '"'
elif Value.startswith('B'):
if not Value[1]:
EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
Value = Value[1:]
else:
if not Value[0]:
EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
Value = '"' + Value + '"'
IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)
if not IsValid:
EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
if PcdDatumType == 'BOOLEAN':
Value = Value.upper()
if Value == 'TRUE' or Value == '1':
Value = '1'
elif Value == 'FALSE' or Value == '0':
Value = '0'
return Value
## Parse command line options ## Parse command line options
# #
# Using standard Python module optparse to parse command line option of this tool. # Using standard Python module optparse to parse command line option of this tool.
@ -341,6 +423,7 @@ def myOptionParser():
Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.") Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.") Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files") Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
(Options, args) = Parser.parse_args() (Options, args) = Parser.parse_args()
return Options return Options

View File

@ -285,8 +285,6 @@ class GenFdsGlobalVariable:
GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
if not os.path.exists(GenFdsGlobalVariable.FfsDir) : if not os.path.exists(GenFdsGlobalVariable.FfsDir) :
os.makedirs(GenFdsGlobalVariable.FfsDir) os.makedirs(GenFdsGlobalVariable.FfsDir)
if ArchList != None:
GenFdsGlobalVariable.ArchList = ArchList
T_CHAR_LF = '\n' T_CHAR_LF = '\n'
# #