BaseTools: Add mixed PCD support feature

Problem statement:
The current build system requires that a PCD must use the same access
method for all modules. A Binary Module may use a different PCD access
method than: 1.A source tree build it is integrated into. 2.Other Binary
Modules in platform build that use the same PCD.

Solution:
1. Source build:
No change. PCDs must use the same access method for building all Source
Modules.
2. Mixed Source & Binary Builds or Binary Only Builds:
1) Source Modules - No changes
2) Module that is interpreted as a Binary Module
a.DSC file may optionally override default value of PatchableInModule
PCDs in scope of Binary Module.
b.DSC file must declare DynamicEx PCD subtype for all DynamicEx PCDs
from Binary Modules.
c.FDF file must list Binary Module INF

Build update:
1. PCDs in a binary module are permitted to use the PatchableInModule
or DynamicEx access methods (the Binary INF clearly identifies the PCD
access method for each PCD). The build must support binary modules that
use the same or different PCD access method than the Source INFs or
other Binary INFs.
2. Build report list PCDs that have mixed PCD access methods.

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-12 10:31:55 +08:00
parent 90bb4c577d
commit 2a29017e3e
8 changed files with 362 additions and 89 deletions

View File

@ -1,7 +1,7 @@
## @file
# Common routines used by workspace
#
# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@ -14,6 +14,7 @@
from Common.Misc import sdict
from Common.DataType import SUP_MODULE_USER_DEFINED
from BuildClassObject import LibraryClassObject
import Common.GlobalData as GlobalData
## Get all packages from platform for specified arch, target and toolchain
#
@ -47,7 +48,15 @@ def GetDeclaredPcd(Platform, BuildDatabase, Arch, Target, Toolchain):
DecPcds = {}
for Pkg in PkgList:
for Pcd in Pkg.Pcds:
DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
PcdCName = Pcd[0]
PcdTokenName = Pcd[1]
if GlobalData.MixedPcd:
for PcdItem in GlobalData.MixedPcd.keys():
if (PcdCName, PcdTokenName) in GlobalData.MixedPcd[PcdItem]:
PcdCName = PcdItem[0]
break
if (PcdCName, PcdTokenName) not in DecPcds.keys():
DecPcds[PcdCName, PcdTokenName] = Pkg.Pcds[Pcd]
return DecPcds
## Get all dependent libraries for a module

View File

@ -2563,6 +2563,7 @@ class InfBuildData(ModuleBuildClassObject):
# resolve PCD type, value, datum info, etc. by getting its definition from package
for PcdCName, TokenSpaceGuid in PcdList:
PcdRealName = PcdCName
Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
@ -2584,6 +2585,27 @@ class InfBuildData(ModuleBuildClassObject):
# Patch PCD: TokenSpace.PcdCName|Value|Offset
Pcd.Offset = ValueList[1]
if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
for Package in self.Packages:
for key in Package.Pcds:
if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):
for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
Pcd_Type = item[0].split('_')[-1]
if Pcd_Type == Package.Pcds[key].Type:
Value = Package.Pcds[key]
Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type
if len(key) == 2:
newkey = (Value.TokenCName, key[1])
elif len(key) == 3:
newkey = (Value.TokenCName, key[1], key[2])
del Package.Pcds[key]
Package.Pcds[newkey] = Value
break
else:
pass
else:
pass
# get necessary info from package declaring this PCD
for Package in self.Packages:
#
@ -2597,11 +2619,32 @@ class InfBuildData(ModuleBuildClassObject):
if Type == MODEL_PCD_DYNAMIC:
Pcd.Pending = True
for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:
PcdType = T
if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:
PcdType = T
PcdCName = item[0]
break
else:
pass
break
else:
if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:
PcdType = T
break
else:
Pcd.Pending = False
if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
Pcd_Type = item[0].split('_')[-1]
if Pcd_Type == PcdType:
PcdCName = item[0]
break
else:
pass
else:
pass
if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:
PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]
@ -2615,7 +2658,7 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error(
'build',
FORMAT_INVALID,
"No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),
"No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),
File=self.MetaFile, Line=LineNo,
ExtraData=None
)
@ -2628,7 +2671,7 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error(
'build',
FORMAT_INVALID,
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
File=self.MetaFile, Line=LineNo,
ExtraData=None
)
@ -2643,7 +2686,7 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error(
'build',
FORMAT_INVALID,
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
File=self.MetaFile, Line=LineNo,
ExtraData=None
)
@ -2651,7 +2694,7 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error(
'build',
FORMAT_INVALID,
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
File=self.MetaFile, Line=LineNo,
ExtraData=None
)
@ -2666,7 +2709,7 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error(
'build',
FORMAT_INVALID,
"PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),
"PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),
File=self.MetaFile, Line=LineNo,
ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])
)