From 2a29017e3e305a10ee1003354c0d0c037923341d Mon Sep 17 00:00:00 2001
From: Yonghong Zhu <yonghong.zhu@intel.com>
Date: Tue, 12 Apr 2016 10:31:55 +0800
Subject: [PATCH] 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>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py    | 205 ++++++++++++++++--
 BaseTools/Source/Python/AutoGen/GenC.py       | 126 ++++++-----
 BaseTools/Source/Python/AutoGen/GenPcdDb.py   |  22 +-
 BaseTools/Source/Python/Common/GlobalData.py  |   5 +
 BaseTools/Source/Python/Common/VpdInfoFile.py |  15 +-
 .../Python/Workspace/WorkspaceCommon.py       |  13 +-
 .../Python/Workspace/WorkspaceDatabase.py     |  57 ++++-
 BaseTools/Source/Python/build/BuildReport.py  |   8 +
 8 files changed, 362 insertions(+), 89 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 50d585f6aa..2cc6970325 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -413,6 +413,129 @@ class WorkspaceAutoGen(AutoGen):
                     if (TokenCName, TokenSpaceGuidCName) in PcdSet:
                         PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue
 
+            SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
+            BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}
+            SourcePcdDict_Keys = SourcePcdDict.keys()
+            BinaryPcdDict_Keys = BinaryPcdDict.keys()
+
+            # generate the SourcePcdDict and BinaryPcdDict
+            for BuildData in PGen.BuildDatabase._CACHE_.values():
+                if BuildData.Arch != Arch:
+                    continue
+                if BuildData.MetaFile.Ext == '.inf':
+                    for key in BuildData.Pcds:
+                        if BuildData.Pcds[key].Pending:
+                            if key in Platform.Pcds:
+                                PcdInPlatform = Platform.Pcds[key]
+                                if PcdInPlatform.Type not in [None, '']:
+                                    BuildData.Pcds[key].Type = PcdInPlatform.Type
+
+                            if BuildData.MetaFile in Platform.Modules:
+                                PlatformModule = Platform.Modules[str(BuildData.MetaFile)]
+                                if key in PlatformModule.Pcds:
+                                    PcdInPlatform = PlatformModule.Pcds[key]
+                                    if PcdInPlatform.Type not in [None, '']:
+                                        BuildData.Pcds[key].Type = PcdInPlatform.Type
+
+                        if 'DynamicEx' in BuildData.Pcds[key].Type:
+                            if BuildData.IsBinaryModule:
+                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:
+                                    BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+                            else:
+                                if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:
+                                    SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+
+                        elif 'PatchableInModule' in BuildData.Pcds[key].Type:
+                            if BuildData.MetaFile.Ext == '.inf':
+                                if BuildData.IsBinaryModule:
+                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:
+                                        BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+                                else:
+                                    if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:
+                                        SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+
+                        elif 'Dynamic' in BuildData.Pcds[key].Type:
+                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:
+                                SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+                        elif 'FixedAtBuild' in BuildData.Pcds[key].Type:
+                            if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:
+                                SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
+                else:
+                    pass
+
+            #
+            # intersection the BinaryPCD for Mixed PCD
+            #
+            for i in BinaryPcdDict_Keys:
+                for j in BinaryPcdDict_Keys:
+                    if i != j:
+                        IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))
+                        for item in IntersectionList:
+                            NewPcd1 = (item[0] + '_' + i, item[1])
+                            NewPcd2 = (item[0] + '_' + j, item[1])
+                            if item not in GlobalData.MixedPcd:
+                                GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
+                            else:
+                                if NewPcd1 not in GlobalData.MixedPcd[item]:
+                                    GlobalData.MixedPcd[item].append(NewPcd1)
+                                if NewPcd2 not in GlobalData.MixedPcd[item]:
+                                    GlobalData.MixedPcd[item].append(NewPcd2)
+                    else:
+                        pass
+
+            #
+            # intersection the SourcePCD and BinaryPCD for Mixed PCD
+            #
+            for i in SourcePcdDict_Keys:
+                for j in BinaryPcdDict_Keys:
+                    if i != j:
+                        IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))
+                        for item in IntersectionList:
+                            NewPcd1 = (item[0] + '_' + i, item[1])
+                            NewPcd2 = (item[0] + '_' + j, item[1])
+                            if item not in GlobalData.MixedPcd:
+                                GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
+                            else:
+                                if NewPcd1 not in GlobalData.MixedPcd[item]:
+                                    GlobalData.MixedPcd[item].append(NewPcd1)
+                                if NewPcd2 not in GlobalData.MixedPcd[item]:
+                                    GlobalData.MixedPcd[item].append(NewPcd2)
+                    else:
+                        pass
+
+            for BuildData in PGen.BuildDatabase._CACHE_.values():
+                if BuildData.Arch != Arch:
+                    continue
+                for key in BuildData.Pcds:
+                    for SinglePcd in GlobalData.MixedPcd:
+                        if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
+                            for item in GlobalData.MixedPcd[SinglePcd]:
+                                Pcd_Type = item[0].split('_')[-1]
+                                if (Pcd_Type == BuildData.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and BuildData.Pcds[key].Type in GenC.gDynamicExPcd) or \
+                                   (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in GenC.gDynamicPcd):
+                                    Value = BuildData.Pcds[key]
+                                    Value.TokenCName = BuildData.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 BuildData.Pcds[key]
+                                    BuildData.Pcds[newkey] = Value
+                                    break
+                                else:
+                                    pass
+                            break
+                        else:
+                            pass
+
+            # handle the mixed pcd in FDF file
+            for key in PcdSet:
+                if key in GlobalData.MixedPcd:
+                    Value = PcdSet[key]
+                    del PcdSet[key]
+                    for item in GlobalData.MixedPcd[key]:
+                        PcdSet[item] = Value
+
             #Collect package set information from INF of FDF
             PkgSet = set()
             for Inf in ModuleList:
@@ -770,17 +893,23 @@ class WorkspaceAutoGen(AutoGen):
                         SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
                         SameTokenValuePcdListCount = 0
                         while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):
+                            Flag = False
                             TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]
                             TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]
 
                             if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):
-                                EdkLogger.error(
-                                            'build',
-                                            FORMAT_INVALID,
-                                            "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
-                                            % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),
-                                            ExtraData=None
-                                            )
+                                for PcdItem in GlobalData.MixedPcd:
+                                    if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \
+                                        (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                                        Flag = True
+                                if not Flag:
+                                    EdkLogger.error(
+                                                'build',
+                                                FORMAT_INVALID,
+                                                "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
+                                                % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),
+                                                ExtraData=None
+                                                )
                             SameTokenValuePcdListCount += 1
                         Count += SameTokenValuePcdListCount
                     Count += 1
@@ -1055,6 +1184,28 @@ class PlatformAutoGen(AutoGen):
                             Sku.DefaultValue = PcdItem[2]
                         break
 
+        for key in self.Platform.Pcds:
+            for SinglePcd in GlobalData.MixedPcd:
+                if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
+                    for item in GlobalData.MixedPcd[SinglePcd]:
+                        Pcd_Type = item[0].split('_')[-1]
+                        if (Pcd_Type == self.Platform.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and self.Platform.Pcds[key].Type in GenC.gDynamicExPcd) or \
+                           (Pcd_Type == TAB_PCDS_DYNAMIC and self.Platform.Pcds[key].Type in GenC.gDynamicPcd):
+                            Value = self.Platform.Pcds[key]
+                            Value.TokenCName = self.Platform.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 self.Platform.Pcds[key]
+                            self.Platform.Pcds[newkey] = Value
+                            break
+                        else:
+                            pass
+                    break
+                else:
+                    pass
+
         # for gathering error information
         NoDatumTypePcdList = set()
         PcdNotInDb = []
@@ -1931,7 +2082,17 @@ class PlatformAutoGen(AutoGen):
         # at this point, ToPcd.Type has the type found from dependent
         # package
         #
+        TokenCName = ToPcd.TokenCName
+        for PcdItem in GlobalData.MixedPcd:
+            if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                TokenCName = PcdItem[0]
+                break
         if FromPcd != None:
+            if GlobalData.BuildOptionPcd:
+                for pcd in GlobalData.BuildOptionPcd:
+                    if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):
+                        FromPcd.DefaultValue = pcd[2]
+                        break
             if ToPcd.Pending and FromPcd.Type not in [None, '']:
                 ToPcd.Type = FromPcd.Type
             elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\
@@ -1942,7 +2103,7 @@ class PlatformAutoGen(AutoGen):
                 and ToPcd.Type != FromPcd.Type:
                 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
                                 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
-                                          % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,
+                                          % (ToPcd.TokenSpaceGuidCName, TokenCName,
                                              ToPcd.Type, Module, FromPcd.Type),
                                           File=self.MetaFile)
 
@@ -1963,14 +2124,14 @@ class PlatformAutoGen(AutoGen):
             IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
             if not IsValid:
                 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
-                                ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
+                                ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))
             ToPcd.validateranges = FromPcd.validateranges
             ToPcd.validlists = FromPcd.validlists
             ToPcd.expressions = FromPcd.expressions
 
         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
-                            % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
+                            % (ToPcd.TokenSpaceGuidCName, TokenCName))
             Value = ToPcd.DefaultValue
             if Value in [None, '']:
                 ToPcd.MaxDatumSize = '1'
@@ -3572,9 +3733,14 @@ class ModuleAutoGen(AutoGen):
                         )
         if PatchList:
             for PatchPcd in PatchList:
-                if PatchPcd[0] not in PatchablePcds:
+                if PatchPcd[0] in PatchablePcds:
+                    key = PatchPcd[0]
+                elif PatchPcd[0] + '_PatchableInModule' in PatchablePcds:
+                    key = PatchPcd[0] + '_PatchableInModule'
+                else:
                     continue
-                Pcd = PatchablePcds[PatchPcd[0]]
+                Pcd = PatchablePcds[key]
+                TokenCName = PatchPcd[0]
                 PcdValue = ''
                 if Pcd.DatumType != 'VOID*':
                     HexFormat = '0x%02x'
@@ -3588,7 +3754,7 @@ class ModuleAutoGen(AutoGen):
                 else:
                     if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
                         EdkLogger.error("build", AUTOGEN_ERROR,
-                                        "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                                        "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)
                                         )
                     ArraySize = int(Pcd.MaxDatumSize, 0)
                     PcdValue = Pcd.DefaultValue
@@ -3612,7 +3778,7 @@ class ModuleAutoGen(AutoGen):
                             ArraySize = ArraySize / 2
                         if ArraySize < (len(PcdValue) + 1):
                             EdkLogger.error("build", AUTOGEN_ERROR,
-                                            "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                                            "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                             )
                         if ArraySize > len(PcdValue) + 1:
                             NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)
@@ -3622,10 +3788,10 @@ class ModuleAutoGen(AutoGen):
                         PcdValue += '}'
                     else:
                         EdkLogger.error("build", AUTOGEN_ERROR,
-                                        "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                                        "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
                                         )
                 PcdItem = '%s.%s|%s|0x%X' % \
-                    (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, PcdValue, PatchPcd[1])
+                    (Pcd.TokenSpaceGuidCName, TokenCName, PcdValue, PatchPcd[1])
                 PcdComments = ''
                 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
                     PcdComments = '\n  '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])
@@ -3639,6 +3805,11 @@ class ModuleAutoGen(AutoGen):
             PcdCommentList = []
             HiiInfo = ''
             SkuId = ''
+            TokenCName = Pcd.TokenCName
+            for PcdItem in GlobalData.MixedPcd:
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                    TokenCName = PcdItem[0]
+                    break
             if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
                 for SkuName in Pcd.SkuInfoList:
                     SkuInfo = Pcd.SkuInfoList[SkuName]
@@ -3669,7 +3840,7 @@ class ModuleAutoGen(AutoGen):
                 else:
                     PcdCommentList.append('## UNDEFINED ' + HiiInfo)
             PcdComments = '\n  '.join(PcdCommentList)
-            PcdEntry = Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName
+            PcdEntry = Pcd.TokenSpaceGuidCName + '.' + TokenCName
             if PcdComments:
                 PcdEntry = PcdComments + '\n  ' + PcdEntry
             AsBuiltInfDict['pcd_item'] += [PcdEntry]
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 842d8bd666..d25d371a46 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -693,15 +693,20 @@ def DynExPcdTokenNumberMapping(Info, AutoGenH):
         Index = 0
         Count = ExTokenCNameList.count(TokenCName)
         for Pcd in PcdExList:
+            RealTokenCName = Pcd.TokenCName
+            for PcdItem in GlobalData.MixedPcd:
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                    RealTokenCName = PcdItem[0]
+                    break
             if Pcd.TokenCName == TokenCName:
                 Index = Index + 1
                 if Index == 1:
-                    AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr)  (' % (Pcd.TokenCName))
+                    AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr)  (' % (RealTokenCName))
                     AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:' 
-                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
                 else:
                     AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:' 
-                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
                 if Index == Count:
                     AutoGenH.Append('0 \\\n  )\n')
                 TokenCNameList.append(TokenCName)
@@ -713,16 +718,21 @@ def DynExPcdTokenNumberMapping(Info, AutoGenH):
         Index = 0
         Count = ExTokenCNameList.count(TokenCName)
         for Pcd in PcdExList:
+            RealTokenCName = Pcd.TokenCName
+            for PcdItem in GlobalData.MixedPcd:
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                    RealTokenCName = PcdItem[0]
+                    break
             if Pcd.Type in gDynamicExPcd and Pcd.TokenCName == TokenCName:
                 Index = Index + 1
                 if Index == 1:
-                    AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr)  (' % (Pcd.TokenCName))
+                    AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr)  (' % (RealTokenCName))
                     AutoGenH.Append('\\\n  (GuidPtr == NULL) ? 0:')
                     AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:' 
-                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
                 else:
                     AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:' 
-                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
                 if Index == Count:
                     AutoGenH.Append('0 \\\n  )\n')
                     # Autogen internal worker macro to compare GUIDs.  Guid1 is a pointer to a GUID.  
@@ -730,7 +740,7 @@ def DynExPcdTokenNumberMapping(Info, AutoGenH):
                     # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().
                     #  COMPAREGUID() will only be used if the Guid passed in is local to the module.
                     AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr)   __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr)  \n'
-                                    % (Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
+                                    % (RealTokenCName, RealTokenCName, RealTokenCName, RealTokenCName))
                 TokenCNameList.append(TokenCName)
 
 def GetPcdSize(Pcd):
@@ -766,26 +776,30 @@ def GetPcdSize(Pcd):
 def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
     TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]
     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
-
-    if GlobalData.BuildOptionPcd:
-        for PcdItem in GlobalData.BuildOptionPcd:
-            if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]):
-                Pcd.DefaultValue = PcdItem[2]
-                break
-
     #
     # Write PCDs
     #
-    PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
-    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + Pcd.TokenCName +'_SIZE'
-    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + Pcd.TokenCName
-    FixPcdSizeTokenName = '_PCD_SIZE_' + Pcd.TokenCName
+    TokenCName = Pcd.TokenCName
+    for PcdItem in GlobalData.MixedPcd:
+        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+            TokenCName = PcdItem[0]
+            break
+    PcdTokenName = '_PCD_TOKEN_' + TokenCName
+    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + TokenCName +'_SIZE'
+    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + TokenCName
+    FixPcdSizeTokenName = '_PCD_SIZE_' + TokenCName
+
+    if GlobalData.BuildOptionPcd:
+        for PcdItem in GlobalData.BuildOptionPcd:
+            if (Pcd.TokenSpaceGuidCName, TokenCName) == (PcdItem[0], PcdItem[1]):
+                Pcd.DefaultValue = PcdItem[2]
+                break
     
     if Pcd.Type in gDynamicExPcd:
         TokenNumber = int(Pcd.TokenValue, 0)
         # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with 
         # different Guids but same TokenCName
-        PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + Pcd.TokenCName
+        PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + TokenCName
         AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
     else:
         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
@@ -801,28 +815,28 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
                 TokenNumber = 0
             else:
                 EdkLogger.error("build", AUTOGEN_ERROR,
-                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, TokenCName),
                                 ExtraData="[%s]" % str(Info))
         else:
             TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
         AutoGenH.Append('\n#define %s  %dU\n' % (PcdTokenName, TokenNumber))
 
-    EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
+    EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + TokenCName + "." + Pcd.TokenSpaceGuidCName)
     if Pcd.Type not in gItemTypeStringDatabase:
         EdkLogger.error("build", AUTOGEN_ERROR,
-                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
                         ExtraData="[%s]" % str(Info))
     if Pcd.DatumType not in gDatumSizeStringDatabase:
         EdkLogger.error("build", AUTOGEN_ERROR,
-                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                         ExtraData="[%s]" % str(Info))
 
     DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
     DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
-    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
-    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
-    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + Pcd.TokenCName
-    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + Pcd.TokenCName
+    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName
+    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName
+    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName
+    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
     
     PcdExCNameList  = []
     if Pcd.Type in gDynamicExPcd:
@@ -866,7 +880,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             if PcdModule.Type in gDynamicPcd:
                 PcdCNameList.append(PcdModule.TokenCName)
         if PcdCNameList.count(Pcd.TokenCName) > 1:
-            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName. They need to be changed to DynamicEx type to avoid the confliction.\n" % (Pcd.TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
+            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName. They need to be changed to DynamicEx type to avoid the confliction.\n" % (TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
         else:
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
@@ -877,7 +891,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
                 AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
                 AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
     else:
-        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + Pcd.TokenCName
+        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName
         Const = 'const'
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
             Const = ''
@@ -902,56 +916,56 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
                     ValueNumber = int (Value)
             except:
                 EdkLogger.error("build", AUTOGEN_ERROR,
-                                "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                 ExtraData="[%s]" % str(Info))
             if Pcd.DatumType == 'UINT64':
                 if ValueNumber < 0:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 elif ValueNumber >= 0x10000000000000000:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 if not Value.endswith('ULL'):
                     Value += 'ULL'
             elif Pcd.DatumType == 'UINT32':
                 if ValueNumber < 0:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 elif ValueNumber >= 0x100000000:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 if not Value.endswith('U'):
                     Value += 'U'
             elif Pcd.DatumType == 'UINT16':
                 if ValueNumber < 0:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 elif ValueNumber >= 0x10000:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 if not Value.endswith('U'):
                     Value += 'U'                    
             elif Pcd.DatumType == 'UINT8':
                 if ValueNumber < 0:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 elif ValueNumber >= 0x100:
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 if not Value.endswith('U'):
                     Value += 'U'
         if Pcd.DatumType == 'VOID*':
             if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
                 EdkLogger.error("build", AUTOGEN_ERROR,
-                                "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),
                                 ExtraData="[%s]" % str(Info))
 
             ArraySize = int(Pcd.MaxDatumSize, 0)
@@ -973,7 +987,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
 
                 if ArraySize < (len(Value) + 1):
                     EdkLogger.error("build", AUTOGEN_ERROR,
-                                    "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                    "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName),
                                     ExtraData="[%s]" % str(Info))
                 Value = NewValue + '0 }'
             Array = '[%d]' % ArraySize
@@ -985,9 +999,9 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
             Value = "((%s)%s)" % (Pcd.DatumType, Value)
 
         if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
-            PcdValueName = '_PCD_PATCHABLE_VALUE_' + Pcd.TokenCName
+            PcdValueName = '_PCD_PATCHABLE_VALUE_' + TokenCName
         else:
-            PcdValueName = '_PCD_VALUE_' + Pcd.TokenCName
+            PcdValueName = '_PCD_VALUE_' + TokenCName
             
         if Pcd.DatumType == 'VOID*':
             #
@@ -1057,14 +1071,18 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
     TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
     TokenCName  = Pcd.TokenCName
+    for PcdItem in GlobalData.MixedPcd:
+        if (TokenCName, TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+            TokenCName = PcdItem[0]
+            break
     PcdTokenName = '_PCD_TOKEN_' + TokenCName
-    FixPcdSizeTokenName = '_PCD_SIZE_' + Pcd.TokenCName
-    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + Pcd.TokenCName +'_SIZE'
-    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + Pcd.TokenCName
+    FixPcdSizeTokenName = '_PCD_SIZE_' + TokenCName
+    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + TokenCName +'_SIZE'
+    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + TokenCName
 
     if GlobalData.BuildOptionPcd:
         for PcdItem in GlobalData.BuildOptionPcd:
-            if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]):
+            if (Pcd.TokenSpaceGuidCName, TokenCName) == (PcdItem[0], PcdItem[1]):
                 Pcd.DefaultValue = PcdItem[2]
                 break
 
@@ -1087,18 +1105,18 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
                 TokenNumber = 0
             else:
                 EdkLogger.error("build", AUTOGEN_ERROR,
-                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, TokenCName),
                                 ExtraData="[%s]" % str(Info))
         else:
             TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
 
     if Pcd.Type not in gItemTypeStringDatabase:
         EdkLogger.error("build", AUTOGEN_ERROR,
-                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
                         ExtraData="[%s]" % str(Info))
     if Pcd.DatumType not in gDatumSizeStringDatabase:
         EdkLogger.error("build", AUTOGEN_ERROR,
-                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+                        "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
                         ExtraData="[%s]" % str(Info))
 
     DatumType   = Pcd.DatumType
@@ -1107,7 +1125,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
     SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
     SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName
-    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + Pcd.TokenCName
+    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
 
     Type = ''
     Array = ''
@@ -1118,7 +1136,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
     PcdItemType = Pcd.Type
     PcdExCNameList  = []
     if PcdItemType in gDynamicExPcd:
-        PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + Pcd.TokenCName
+        PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + TokenCName
         AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
         
         if Info.IsLibrary:
@@ -1163,7 +1181,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             if PcdModule.Type in gDynamicPcd:
                 PcdCNameList.append(PcdModule.TokenCName)
         if PcdCNameList.count(Pcd.TokenCName) > 1:
-            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName.They need to be changed to DynamicEx type to avoid the confliction.\n" % (Pcd.TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
+            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName.They need to be changed to DynamicEx type to avoid the confliction.\n" % (TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
         else:
             AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
             AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
@@ -1186,8 +1204,8 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
             AutoGenH.Append('extern volatile  %s  %s%s;\n' % (DatumType, PcdVariableName, Array))
         AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
         if Pcd.DatumType == 'VOID*':
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
-            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, TokenCName, TokenCName, TokenCName))
+            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, TokenCName, TokenCName, TokenCName))
         else:
             AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
             AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS)\n' % (SetModeStatusName, PcdVariableName))
diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
index 76d1254e72..d5997f0e66 100644
--- a/BaseTools/Source/Python/AutoGen/GenPcdDb.py
+++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
@@ -1141,9 +1141,13 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
         CName = Pcd.TokenCName
         TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
 
+        for PcdItem in GlobalData.MixedPcd:
+            if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                CName = PcdItem[0]
+
         if GlobalData.BuildOptionPcd:
             for PcdItem in GlobalData.BuildOptionPcd:
-                if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]):
+                if (Pcd.TokenSpaceGuidCName, CName) == (PcdItem[0], PcdItem[1]):
                     Pcd.DefaultValue = PcdItem[2]
                     break
 
@@ -1461,11 +1465,6 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
         TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
         if Pcd.Phase != Phase:
             continue
-        if GlobalData.BuildOptionPcd:
-            for PcdItem in GlobalData.BuildOptionPcd:
-                if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]):
-                    Pcd.DefaultValue = PcdItem[2]
-                    break
 
         TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
         GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
@@ -1475,6 +1474,17 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
         if len(Pcd.SkuInfoList) > 1:
             Dict['PCD_ORDER_TOKEN_NUMBER_MAP'][GeneratedTokenNumber] = SkuEnablePcdIndex
             SkuEnablePcdIndex += 1
+
+        for PcdItem in GlobalData.MixedPcd:
+            if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                CName = PcdItem[0]
+
+        if GlobalData.BuildOptionPcd:
+            for PcdItem in GlobalData.BuildOptionPcd:
+                if (Pcd.TokenSpaceGuidCName, CName) == (PcdItem[0], PcdItem[1]):
+                    Pcd.DefaultValue = PcdItem[2]
+                    break
+
         EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName))
         EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
         EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index 51e370925d..667877e907 100644
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -80,5 +80,10 @@ gTempInfs = []
 
 BuildOptionPcd = []
 
+#
+# Mixed PCD name dict
+#
+MixedPcd = {}
+
 # Pcd name for the Pcd which used in the Conditional directives
 gConditionalPcds = []
diff --git a/BaseTools/Source/Python/Common/VpdInfoFile.py b/BaseTools/Source/Python/Common/VpdInfoFile.py
index dc8ece9608..cc79ee275f 100644
--- a/BaseTools/Source/Python/Common/VpdInfoFile.py
+++ b/BaseTools/Source/Python/Common/VpdInfoFile.py
@@ -20,6 +20,7 @@ import re
 import Common.EdkLogger as EdkLogger
 import Common.BuildToolError as BuildToolError
 import subprocess
+import Common.GlobalData as GlobalData
 from Common.LongFilePathSupport import OpenLongFilePath as open
 from Common.Misc import SaveFileOnChange
 
@@ -131,12 +132,16 @@ class VpdInfoFile:
         Pcds.sort()
         for Pcd in Pcds:
             i = 0
+            PcdTokenCName = Pcd.TokenCName
+            for PcdItem in GlobalData.MixedPcd:
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                    PcdTokenCName = PcdItem[0]
             for Offset in self._VpdArray[Pcd]:
                 PcdValue = str(Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[i]].DefaultValue).strip()
                 if PcdValue == "" :
                     PcdValue  = Pcd.DefaultValue
 
-                Content += "%s.%s|%s|%s|%s|%s  \n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, str(Pcd.SkuInfoList.keys()[i]),str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue)
+                Content += "%s.%s|%s|%s|%s|%s  \n" % (Pcd.TokenSpaceGuidCName, PcdTokenCName, str(Pcd.SkuInfoList.keys()[i]),str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue)
                 i += 1
 
         return SaveFileOnChange(FilePath, Content, False)
@@ -174,8 +179,12 @@ class VpdInfoFile:
             Found = False
             
             for VpdObject in self._VpdArray.keys():
-                for sku in VpdObject.SkuInfoList.keys(): 
-                    if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObject.TokenCName == PcdTokenName.strip() and sku == SkuId:
+                VpdObjectTokenCName = VpdObject.TokenCName
+                for PcdItem in GlobalData.MixedPcd:
+                    if (VpdObject.TokenCName, VpdObject.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
+                        VpdObjectTokenCName = PcdItem[0]
+                for sku in VpdObject.SkuInfoList.keys():
+                    if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObjectTokenCName == PcdTokenName.strip() and sku == SkuId:
                         if self._VpdArray[VpdObject][VpdObject.SkuInfoList.keys().index(sku)] == "*":
                             if Offset == "*":
                                 EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The offset of %s has not been fixed up by third-party BPDG tool." % PcdName)                              
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index 60acc914e9..c224b8e0e6 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -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
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 6c548ac709..2e6c68e33a 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -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])
                             )
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index 27a5d9736e..ef99989857 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -1676,6 +1676,14 @@ class PlatformReport(object):
         FileWrite(File, "Build Duration:       %s" % BuildDuration)
         FileWrite(File, "Report Content:       %s" % ", ".join(ReportType))
 
+        if GlobalData.MixedPcd:
+            FileWrite(File, gSectionStart)
+            FileWrite(File, "The following PCDs use different access methods:")
+            FileWrite(File, gSectionSep)
+            for PcdItem in GlobalData.MixedPcd:
+                FileWrite(File, "%s.%s" % (str(PcdItem[1]), str(PcdItem[0])))
+            FileWrite(File, gSectionEnd)
+
         if not self._IsModuleBuild:
             if "PCD" in ReportType:
                 self.PcdReport.GenerateReport(File, None)