]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools: Add mixed PCD support feature
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
index 04e3d14dff7c1cf3b1d494aba3c4a925b2dd7c08..2e6c68e33aaef2a1961c1a02b4589f9d61c88ba8 100644 (file)
@@ -1,7 +1,8 @@
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
-# Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 # Import Modules\r
 #\r
 import sqlite3\r
-import os\r
-import os.path\r
+import Common.LongFilePathOs as os\r
 import pickle\r
 import uuid\r
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 \r
 from Common.String import *\r
 from Common.DataType import *\r
@@ -36,6 +37,11 @@ from MetaFileParser import *
 from BuildClassObject import *\r
 from WorkspaceCommon import GetDeclaredPcd\r
 from Common.Misc import AnalyzeDscPcd\r
+from Common.Misc import ProcessDuplicatedInf\r
+import re\r
+from Common.Parsing import IsValidWord\r
+from Common.VariableAttributes import VariableAttributes\r
+import Common.GlobalData as GlobalData\r
 \r
 ## Platform build information from DSC file\r
 #\r
@@ -102,6 +108,7 @@ class DscBuildData(PlatformBuildClassObject):
         self._Target = Target\r
         self._Toolchain = Toolchain\r
         self._Clear()\r
+        self._HandleOverridePath()\r
 \r
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -127,8 +134,12 @@ class DscBuildData(PlatformBuildClassObject):
         self._BuildTargets      = None\r
         self._SkuName           = None\r
         self._SkuIdentifier     = None\r
+        self._AvilableSkuIds = None\r
         self._PcdInfoFlag       = None\r
+        self._VarCheckFlag = None\r
         self._FlashDefinition   = None\r
+        self._Prebuild          = None\r
+        self._Postbuild         = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
         self._BsBaseAddress     = None\r
@@ -140,12 +151,34 @@ class DscBuildData(PlatformBuildClassObject):
         self._Pcds              = None\r
         self._DecPcds           = None\r
         self._BuildOptions      = None\r
+        self._ModuleTypeOptions = None\r
         self._LoadFixAddress    = None\r
         self._RFCLanguages      = None\r
         self._ISOLanguages      = None\r
         self._VpdToolGuid       = None\r
         self.__Macros            = None\r
 \r
+\r
+    ## handle Override Path of Module\r
+    def _HandleOverridePath(self):\r
+        RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
+        Macros = self._Macros\r
+        Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+        for Record in RecordList:\r
+            ModuleId = Record[5]\r
+            LineNo = Record[6]\r
+            ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
+            RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
+            if RecordList != []:\r
+                SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
+\r
+                # Check if the source override path exists\r
+                if not os.path.isdir(SourceOverridePath):\r
+                    EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)\r
+\r
+                #Add to GlobalData Variables\r
+                GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath\r
+\r
     ## Get current effective macros\r
     def _GetMacros(self):\r
         if self.__Macros == None:\r
@@ -197,6 +230,10 @@ class DscBuildData(PlatformBuildClassObject):
                 if ErrorCode != 0:\r
                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
                                     ExtraData=ErrorInfo)\r
+            elif Name == TAB_DSC_PREBUILD:\r
+                self._Prebuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
+            elif Name == TAB_DSC_POSTBUILD:\r
+                self._Postbuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
             elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
                 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
@@ -205,8 +242,11 @@ class DscBuildData(PlatformBuildClassObject):
                 if self._SkuName == None:\r
                     self._SkuName = Record[2]\r
                 self._SkuIdentifier = Record[2]\r
+                self._AvilableSkuIds = Record[2]\r
             elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
                 self._PcdInfoFlag = Record[2]\r
+            elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:\r
+                self._VarCheckFlag = Record[2]\r
             elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
                 try:\r
                     self._LoadFixAddress = int (Record[2], 0)\r
@@ -326,8 +366,20 @@ class DscBuildData(PlatformBuildClassObject):
             return True\r
         else:\r
             return False\r
-            \r
+    def _GetVarCheckFlag(self):  \r
+        if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':\r
+            return False\r
+        elif self._VarCheckFlag.upper() == 'TRUE':\r
+            return True\r
+        else:\r
+            return False\r
+    def _GetAviableSkuIds(self):\r
+        if self._AvilableSkuIds:\r
+            return self._AvilableSkuIds\r
+        return self.SkuIdentifier\r
     def _GetSkuIdentifier(self):\r
+        if self._SkuName:\r
+            return self._SkuName\r
         if self._SkuIdentifier == None:\r
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
@@ -337,16 +389,14 @@ class DscBuildData(PlatformBuildClassObject):
         if self._SkuName == None:\r
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
-            if self._SkuName == None or self._SkuName not in self.SkuIds:\r
+            if (self._SkuName == None or self._SkuName not in self.SkuIds):\r
                 self._SkuName = 'DEFAULT'\r
         return self._SkuName\r
 \r
     ## Override SKUID_IDENTIFIER\r
     def _SetSkuName(self, Value):\r
-        if Value in self.SkuIds:\r
-            self._SkuName = Value\r
-            # Needs to re-retrieve the PCD information\r
-            self._Pcds = None\r
+        self._SkuName = Value\r
+        self._Pcds = None\r
 \r
     def _GetFdfFile(self):\r
         if self._FlashDefinition == None:\r
@@ -356,6 +406,22 @@ class DscBuildData(PlatformBuildClassObject):
                 self._FlashDefinition = ''\r
         return self._FlashDefinition\r
 \r
+    def _GetPrebuild(self):\r
+        if self._Prebuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Prebuild == None:\r
+                self._Prebuild = ''\r
+        return self._Prebuild\r
+\r
+    def _GetPostbuild(self):\r
+        if self._Postbuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Postbuild == None:\r
+                self._Postbuild = ''\r
+        return self._Postbuild\r
+\r
     ## Retrieve FLASH_DEFINITION\r
     def _GetBuildNumber(self):\r
         if self._BuildNumber == None:\r
@@ -460,7 +526,7 @@ class DscBuildData(PlatformBuildClassObject):
                 if Record[1] in [None, '']:\r
                     EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
                                     File=self.MetaFile, Line=Record[-1])\r
-                self._SkuIds[Record[1].upper()] = Record[0]\r
+                self._SkuIds[Record[1]] = Record[0]\r
             if 'DEFAULT' not in self._SkuIds:\r
                 self._SkuIds['DEFAULT'] = '0'\r
             if 'COMMON' not in self._SkuIds:\r
@@ -477,6 +543,14 @@ class DscBuildData(PlatformBuildClassObject):
         Macros = self._Macros\r
         Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
         for Record in RecordList:\r
+            DuplicatedFile = False\r
+\r
+            # process only records COMMON and self.Arch\r
+            SectionArch = Record[3].upper()\r
+            if SectionArch != 'COMMON':\r
+                if SectionArch != self.Arch:\r
+                    continue\r
+\r
             ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
             ModuleId = Record[5]\r
             LineNo = Record[6]\r
@@ -489,23 +563,11 @@ class DscBuildData(PlatformBuildClassObject):
             # Check duplication\r
             # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
             if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
-                EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
+                DuplicatedFile = True\r
 \r
             Module = ModuleBuildClassObject()\r
             Module.MetaFile = ModuleFile\r
 \r
-            # get module override path\r
-            RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
-            if RecordList != []:\r
-                Module.SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0], Macros))\r
-\r
-                # Check if the source override path exists\r
-                if not os.path.isdir(Module.SourceOverridePath):\r
-                    EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo)\r
-                \r
-                #Add to GlobalData Variables\r
-                GlobalData.gOverrideDir[ModuleFile.Key] = Module.SourceOverridePath\r
-\r
             # get module private library instance\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
             for Record in RecordList:\r
@@ -562,6 +624,16 @@ class DscBuildData(PlatformBuildClassObject):
                     OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
                     Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
 \r
+            RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]\r
+            if DuplicatedFile and not RecordList:\r
+                EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
+            if RecordList:\r
+                if len(RecordList) != 1:\r
+                    EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',\r
+                                    File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
+                ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)\r
+                ModuleFile.Arch = self._Arch\r
+\r
             self._Modules[ModuleFile] = Module\r
         return self._Modules\r
 \r
@@ -640,9 +712,26 @@ class DscBuildData(PlatformBuildClassObject):
     def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
         if self._DecPcds == None:\r
             self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)\r
+            FdfInfList = []\r
+            if GlobalData.gFdfParser:\r
+                FdfInfList = GlobalData.gFdfParser.Profile.InfList\r
+\r
+            PkgSet = set()\r
+            for Inf in FdfInfList:\r
+                ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)\r
+                if ModuleFile in self._Modules:\r
+                    continue\r
+                ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]\r
+                PkgSet.update(ModuleData.Packages)\r
+            DecPcds = {}\r
+            for Pkg in PkgSet:\r
+                for Pcd in Pkg.Pcds:\r
+                    DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]\r
+            self._DecPcds.update(DecPcds)\r
+\r
         if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
             EdkLogger.error('build', PARSER_ERROR,\r
-                            "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid, PcdCName),\r
+                            "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),\r
                             File=self.MetaFile, Line=LineNo)\r
         ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
         if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
@@ -697,19 +786,38 @@ class DscBuildData(PlatformBuildClassObject):
         if self._BuildOptions == None:\r
             self._BuildOptions = sdict()\r
             #\r
-            # Retrieve build option for EDKII style module\r
-            #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDKII_NAME]\r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
-            #\r
-            # Retrieve build option for EDK style module\r
+            # Retrieve build option for EDKII and EDK style module\r
             #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDK_NAME]     \r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option\r
+            for CodeBase in (EDKII_NAME, EDK_NAME):\r
+                RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
+                for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                    CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
+                    #\r
+                    # Only flags can be appended\r
+                    #\r
+                    if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        self._BuildOptions[CurKey] = Option\r
+                    else:\r
+                        self._BuildOptions[CurKey] += ' ' + Option\r
         return self._BuildOptions\r
 \r
+    def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
+        if self._ModuleTypeOptions == None:\r
+            self._ModuleTypeOptions = sdict()\r
+        if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
+            options = sdict()\r
+            self._ModuleTypeOptions[Edk, ModuleType] = options\r
+            DriverType = '%s.%s' % (Edk, ModuleType)\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
+            for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
+                if Type == DriverType:\r
+                    Key = (ToolChainFamily, ToolChain, Edk)\r
+                    if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        options[Key] = Option\r
+                    else:\r
+                        options[Key] += ' ' + Option\r
+        return self._ModuleTypeOptions[Edk, ModuleType]\r
+\r
     ## Retrieve non-dynamic PCD settings\r
     #\r
     #   @param  Type    PCD type\r
@@ -731,7 +839,6 @@ class DscBuildData(PlatformBuildClassObject):
         RecordList = self._RawData[Type, self._Arch]\r
         PcdValueDict = sdict()\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            SkuName = SkuName.upper()\r
             if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
                 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
                 PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
@@ -798,7 +905,6 @@ class DscBuildData(PlatformBuildClassObject):
         \r
         AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            SkuName = SkuName.upper()\r
             if SkuName not in AvailableSkuIdSet:\r
                 continue\r
             \r
@@ -816,6 +922,16 @@ class DscBuildData(PlatformBuildClassObject):
             if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
                 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
                 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
+                if MaxDatumSize.strip():\r
+                    CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
+                else:\r
+                    CurrentMaxSize = 0\r
+                if pcdObject.MaxDatumSize:\r
+                    PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
+                else:\r
+                    PcdMaxSize = 0\r
+                if CurrentMaxSize > PcdMaxSize:\r
+                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
             else:               \r
                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                     PcdCName,\r
@@ -831,8 +947,8 @@ class DscBuildData(PlatformBuildClassObject):
                                                     )\r
         \r
         for pcd in Pcds.values():\r
-            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
-                pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
+            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():                \r
                 valuefromDec = pcdDecObject.DefaultValue\r
                 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
                 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
@@ -845,19 +961,20 @@ class DscBuildData(PlatformBuildClassObject):
                 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
                     pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
                 del(pcd.SkuInfoList['DEFAULT'])\r
-            \r
-            if SkuObj.SkuUsageType == SkuObj.MULTIPLE:\r
-                    if pcd.DatumType == "VOID*": \r
-                        MaxSize = int(pcd.MaxDatumSize,0)\r
-                        for (skuname,skuobj) in pcd.SkuInfoList.items():\r
-                            datalen = len(skuobj.DefaultValue)\r
-                            if datalen>MaxSize:\r
-                                MaxSize = datalen\r
-                        pcd.MaxDatumSize = str(MaxSize)\r
-                    \r
-                \r
+               \r
         return Pcds\r
 \r
+    def CompareVarAttr(self, Attr1, Attr2):\r
+        if not Attr1 or not Attr2:  # for empty string\r
+            return True\r
+        Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
+        Attr1Set = set(Attr1s)\r
+        Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
+        Attr2Set = set(Attr2s)\r
+        if Attr2Set == Attr1Set:\r
+            return True\r
+        else:\r
+            return False\r
     ## Retrieve dynamic HII PCD settings\r
     #\r
     #   @param  Type    PCD type\r
@@ -867,6 +984,7 @@ class DscBuildData(PlatformBuildClassObject):
     def _GetDynamicHiiPcd(self, Type):\r
         \r
         SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        VariableAttrs = {}\r
         \r
         Pcds = sdict()\r
         #\r
@@ -881,7 +999,6 @@ class DscBuildData(PlatformBuildClassObject):
         \r
         AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            SkuName = SkuName.upper()\r
             if SkuName not in AvailableSkuIdSet:\r
                 continue\r
             PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
@@ -892,8 +1009,42 @@ class DscBuildData(PlatformBuildClassObject):
             Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            VariableName, VariableGuid, VariableOffset, DefaultValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
-            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
+            VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            \r
+            rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
+            if not rt:\r
+                EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
+                        ExtraData = "[%s]" % VarAttribute)\r
+            ExceedMax = False\r
+            FormatCorrect = True\r
+            if VariableOffset.isdigit():\r
+                if int(VariableOffset,10) > 0xFFFF:\r
+                    ExceedMax = True\r
+            elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):\r
+                if int(VariableOffset,16) > 0xFFFF:\r
+                    ExceedMax = True\r
+            # For Offset written in "A.B"\r
+            elif VariableOffset.find('.') > -1:\r
+                VariableOffsetList = VariableOffset.split(".")\r
+                if not (len(VariableOffsetList) == 2\r
+                        and IsValidWord(VariableOffsetList[0])\r
+                        and IsValidWord(VariableOffsetList[1])):\r
+                    FormatCorrect = False\r
+            else:\r
+                FormatCorrect = False\r
+            if not FormatCorrect:\r
+                EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
+            \r
+            if ExceedMax:\r
+                EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
+            if (VariableName, VariableGuid) not in VariableAttrs:\r
+                VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
+            else:\r
+                if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
+                    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)]))\r
+            \r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)\r
+            pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
             if (PcdCName,TokenSpaceGuid) in Pcds.keys():  \r
                 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
                 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
@@ -908,14 +1059,21 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 {SkuName : SkuInfo},\r
                                                 False,\r
-                                                None\r
+                                                None,\r
+                                                pcdDecObject.validateranges,\r
+                                                pcdDecObject.validlists,\r
+                                                pcdDecObject.expressions\r
                                                 )\r
                 \r
 \r
         for pcd in Pcds.values():\r
             SkuInfoObj = pcd.SkuInfoList.values()[0]\r
-            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
-                pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
+            # Only fix the value while no value provided in DSC file.\r
+            for sku in pcd.SkuInfoList.values():\r
+                if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):\r
+                    sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
+            if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():              \r
                 valuefromDec = pcdDecObject.DefaultValue\r
                 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
                 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
@@ -929,6 +1087,24 @@ class DscBuildData(PlatformBuildClassObject):
                 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
                     pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
                 del(pcd.SkuInfoList['DEFAULT'])\r
+            \r
+            \r
+            if pcd.MaxDatumSize.strip(): \r
+                MaxSize = int(pcd.MaxDatumSize,0)\r
+            else:\r
+                MaxSize = 0\r
+            if pcdDecObject.DatumType == 'VOID*':\r
+                for (skuname,skuobj) in pcd.SkuInfoList.items():\r
+                    datalen = 0\r
+                    if skuobj.HiiDefaultValue.startswith("L"):\r
+                        datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2\r
+                    elif skuobj.HiiDefaultValue.startswith("{"):\r
+                        datalen = len(skuobj.HiiDefaultValue.split(","))\r
+                    else:\r
+                        datalen = len(skuobj.HiiDefaultValue) -2 + 1 \r
+                    if datalen>MaxSize:\r
+                        MaxSize = datalen\r
+                pcd.MaxDatumSize = str(MaxSize)\r
         return Pcds\r
 \r
     ## Retrieve dynamic VPD PCD settings\r
@@ -954,7 +1130,6 @@ class DscBuildData(PlatformBuildClassObject):
         \r
         AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            SkuName = SkuName.upper()\r
             if SkuName not in AvailableSkuIdSet:\r
                 continue\r
 \r
@@ -976,13 +1151,23 @@ class DscBuildData(PlatformBuildClassObject):
             if (PcdCName,TokenSpaceGuid) in Pcds.keys():  \r
                 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
                 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
+                if MaxDatumSize.strip():\r
+                    CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
+                else:\r
+                    CurrentMaxSize = 0\r
+                if pcdObject.MaxDatumSize:\r
+                    PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
+                else:\r
+                    PcdMaxSize = 0\r
+                if CurrentMaxSize > PcdMaxSize:\r
+                    pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
             else:\r
                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
                                                 TokenSpaceGuid,\r
                                                 self._PCD_TYPE_STRING_[Type],\r
                                                 '',\r
-                                                '',\r
+                                                InitialValue,\r
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {SkuName : SkuInfo},\r
@@ -991,8 +1176,8 @@ class DscBuildData(PlatformBuildClassObject):
                                                 )\r
         for pcd in Pcds.values():\r
             SkuInfoObj = pcd.SkuInfoList.values()[0]\r
+            pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
-                pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
                 valuefromDec = pcdDecObject.DefaultValue\r
                 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
                 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
@@ -1006,14 +1191,6 @@ class DscBuildData(PlatformBuildClassObject):
                     pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
                 del(pcd.SkuInfoList['DEFAULT'])\r
             \r
-            if SkuObj.SkuUsageType == SkuObj.MULTIPLE:\r
-                    if pcd.MaxDatumSize.strip(): \r
-                        MaxSize = int(pcd.MaxDatumSize,0)\r
-                        for (skuname,skuobj) in pcd.SkuInfoList.items():\r
-                            datalen = len(skuobj.DefaultValue)\r
-                            if datalen>MaxSize:\r
-                                MaxSize = datalen\r
-                        pcd.MaxDatumSize = str(MaxSize)\r
         return Pcds\r
 \r
     ## Add external modules\r
@@ -1056,8 +1233,12 @@ class DscBuildData(PlatformBuildClassObject):
     BuildTargets        = property(_GetBuildTarget)\r
     SkuName             = property(_GetSkuName, _SetSkuName)\r
     SkuIdentifier       = property(_GetSkuIdentifier)\r
+    AvilableSkuIds = property(_GetAviableSkuIds)\r
     PcdInfoFlag         = property(_GetPcdInfoFlag)\r
+    VarCheckFlag = property(_GetVarCheckFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
+    Prebuild            = property(_GetPrebuild)\r
+    Postbuild           = property(_GetPostbuild)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
     BsBaseAddress       = property(_GetBsBaseAddress)\r
@@ -1376,6 +1557,7 @@ class DecBuildData(PackageBuildClassObject):
 \r
             DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
                                        \r
+            validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)                          \r
             Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
                                                                             PcdCName,\r
                                                                             TokenSpaceGuid,\r
@@ -1386,7 +1568,10 @@ class DecBuildData(PackageBuildClassObject):
                                                                             '',\r
                                                                             {},\r
                                                                             False,\r
-                                                                            None\r
+                                                                            None,\r
+                                                                            list(validateranges),\r
+                                                                            list(validlists),\r
+                                                                            list(expressions)\r
                                                                             )\r
         return Pcds\r
 \r
@@ -1520,6 +1705,7 @@ class InfBuildData(ModuleBuildClassObject):
     ## Set all internal used members of InfBuildData to None\r
     def _Clear(self):\r
         self._HeaderComments = None\r
+        self._TailComments = None\r
         self._Header_               = None\r
         self._AutoGenVersion        = None\r
         self._BaseName              = None\r
@@ -1612,7 +1798,13 @@ class InfBuildData(ModuleBuildClassObject):
             for Record in RecordList:\r
                 self._HeaderComments.append(Record[0])\r
         return self._HeaderComments\r
-\r
+    def _GetTailComments(self):\r
+        if not self._TailComments:\r
+            self._TailComments = []\r
+            RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
+            for Record in RecordList:\r
+                self._TailComments.append(Record[0])\r
+        return self._TailComments\r
     ## Retrieve all information in [Defines] section\r
     #\r
     #   (Retriving all [Defines] information in one-shot is just to save time.)\r
@@ -1624,6 +1816,9 @@ class InfBuildData(ModuleBuildClassObject):
             # items defined _PROPERTY_ don't need additional processing\r
             if Name in self:\r
                 self[Name] = Value\r
+                if self._Defs == None:\r
+                    self._Defs = sdict()\r
+                self._Defs[Name] = Value\r
             # some special items in [Defines] section need special treatment\r
             elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
                 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
@@ -1700,11 +1895,11 @@ class InfBuildData(ModuleBuildClassObject):
                         LineNo = Record[6]\r
                         break\r
                 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)), \r
+                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),\r
                                 File=self.MetaFile, Line=LineNo)\r
             if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
                 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)                \r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)\r
             if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
                and 'PCI_CLASS_CODE' in self._Defs:\r
                 self._BuildType = 'UEFI_OPTIONROM'\r
@@ -1713,7 +1908,7 @@ class InfBuildData(ModuleBuildClassObject):
                 self._BuildType = 'UEFI_HII'\r
             else:\r
                 self._BuildType = self._ModuleType.upper()\r
-            \r
+\r
             if self._DxsFile:\r
                 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
                 # check the file validation\r
@@ -1728,7 +1923,7 @@ class InfBuildData(ModuleBuildClassObject):
             if not self._ComponentType:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
                                 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
-            self._BuildType = self._ComponentType.upper()                \r
+            self._BuildType = self._ComponentType.upper()\r
             if self._ComponentType in self._MODULE_TYPE_:\r
                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
             if self._ComponentType == 'LIBRARY':\r
@@ -1738,7 +1933,7 @@ class InfBuildData(ModuleBuildClassObject):
             Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
             Macros['PROCESSOR'] = self._Arch\r
             RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
-            for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
+            for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
                 Value = ReplaceMacro(Value, Macros, True)\r
                 if Name == "IMAGE_ENTRY_POINT":\r
                     if self._ModuleEntryPointList == None:\r
@@ -1792,7 +1987,13 @@ class InfBuildData(ModuleBuildClassObject):
             RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
-                    self._AutoGenVersion = int(Record[2], 0)\r
+                    if '.' in Record[2]:\r
+                        ValueList = Record[2].split('.')\r
+                        Major = '%04o' % int(ValueList[0], 0)\r
+                        Minor = '%04o' % int(ValueList[1], 0)\r
+                        self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
+                    else:\r
+                        self._AutoGenVersion = int(Record[2], 0)\r
                     break\r
             if self._AutoGenVersion == None:\r
                 self._AutoGenVersion = 0x00010000\r
@@ -1851,7 +2052,7 @@ class InfBuildData(ModuleBuildClassObject):
             if self._Header_ == None:\r
                 self._GetHeaderInfo()\r
             if self._Guid == None:\r
-                self._Guid = '00000000-0000-0000-000000000000'\r
+                self._Guid = '00000000-0000-0000-0000-000000000000'\r
         return self._Guid\r
 \r
     ## Retrieve module version\r
@@ -1956,7 +2157,7 @@ class InfBuildData(ModuleBuildClassObject):
         return self._Defs\r
 \r
     ## Retrieve binary files\r
-    def _GetBinaryFiles(self):\r
+    def _GetBinaries(self):\r
         if self._Binaries == None:\r
             self._Binaries = []\r
             RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
@@ -1983,8 +2184,27 @@ class InfBuildData(ModuleBuildClassObject):
                 self._Binaries.append(File)\r
         return self._Binaries\r
 \r
+    ## Retrieve binary files with error check.\r
+    def _GetBinaryFiles(self):\r
+        Binaries = self._GetBinaries()\r
+        if GlobalData.gIgnoreSource and Binaries == []:\r
+            ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
+            EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
+\r
+        return Binaries\r
+    ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
+    def _IsSupportedArch(self):\r
+        if self._GetBinaries() and not self._GetSourceFiles():\r
+            return True\r
+        else:\r
+            return False\r
     ## Retrieve source files\r
     def _GetSourceFiles(self):\r
+        #Ignore all source files in a binary build mode\r
+        if GlobalData.gIgnoreSource:\r
+            self._Sources = []\r
+            return self._Sources\r
+\r
         if self._Sources == None:\r
             self._Sources = []\r
             RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
@@ -1998,8 +2218,11 @@ class InfBuildData(ModuleBuildClassObject):
                 if self.AutoGenVersion < 0x00010005:\r
                     Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
                     Macros['PROCESSOR'] = self._Arch\r
+                    SourceFile = NormPath(Record[0], Macros)\r
+                    if SourceFile[0] == os.path.sep:\r
+                        SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
                     # old module source files (Edk)\r
-                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
+                    File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
                                      '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
                     # check the file validation\r
                     ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
@@ -2162,10 +2385,21 @@ class InfBuildData(ModuleBuildClassObject):
                     if File[0] == '.':\r
                         File = os.path.join(self._ModuleDir, File)\r
                     else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
+                        File = mws.join(GlobalData.gWorkspace, File)\r
                     File = RealPath(os.path.normpath(File))\r
                     if File:\r
                         self._Includes.append(File)\r
+                    if not File and Record[0].find('EFI_SOURCE') > -1:\r
+                        # tricky to regard WorkSpace as EFI_SOURCE\r
+                        Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
+                        File = NormPath(Record[0], Macros)\r
+                        if File[0] == '.':\r
+                            File = os.path.join(self._ModuleDir, File)\r
+                        else:\r
+                            File = os.path.join(GlobalData.gWorkspace, File)\r
+                        File = RealPath(os.path.normpath(File))\r
+                        if File:\r
+                            self._Includes.append(File)\r
         return self._Includes\r
 \r
     ## Retrieve packages this module depends on\r
@@ -2212,7 +2446,7 @@ class InfBuildData(ModuleBuildClassObject):
                 ToolChainFamily = Record[0]\r
                 ToolChain = Record[1]\r
                 Option = Record[2]\r
-                if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
+                if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
                     self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
                 else:\r
                     # concatenate the option string if they're for the same tool\r
@@ -2238,6 +2472,13 @@ class InfBuildData(ModuleBuildClassObject):
                     EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
                                     % self.ModuleType, File=self.MetaFile)\r
 \r
+            if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':\r
+                for Record in RecordList:\r
+                    if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:\r
+                        EdkLogger.error('build', FORMAT_INVALID,\r
+                                        "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
+                                        File=self.MetaFile)\r
+\r
             Depex = sdict()\r
             for Record in RecordList:\r
                 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
@@ -2322,6 +2563,7 @@ class InfBuildData(ModuleBuildClassObject):
 \r
         # resolve PCD type, value, datum info, etc. by getting its definition from package\r
         for PcdCName, TokenSpaceGuid in PcdList:\r
+            PcdRealName = PcdCName\r
             Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
@@ -2343,6 +2585,27 @@ class InfBuildData(ModuleBuildClassObject):
                 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
                 Pcd.Offset = ValueList[1]\r
 \r
+            if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                for Package in self.Packages:\r
+                    for key in Package.Pcds:\r
+                        if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
+                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                                Pcd_Type = item[0].split('_')[-1]\r
+                                if Pcd_Type == Package.Pcds[key].Type:\r
+                                    Value = Package.Pcds[key]\r
+                                    Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
+                                    if len(key) == 2:\r
+                                        newkey = (Value.TokenCName, key[1])\r
+                                    elif len(key) == 3:\r
+                                        newkey = (Value.TokenCName, key[1], key[2])\r
+                                    del Package.Pcds[key]\r
+                                    Package.Pcds[newkey] = Value\r
+                                    break\r
+                                else:\r
+                                    pass\r
+                        else:\r
+                            pass\r
+\r
             # get necessary info from package declaring this PCD\r
             for Package in self.Packages:\r
                 #\r
@@ -2356,11 +2619,32 @@ class InfBuildData(ModuleBuildClassObject):
                 if Type == MODEL_PCD_DYNAMIC:\r
                     Pcd.Pending = True\r
                     for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
-                        if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
-                            PcdType = T\r
+                        if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                            for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                                if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
+                                    PcdType = T\r
+                                    PcdCName = item[0]\r
+                                    break\r
+                                else:\r
+                                    pass\r
                             break\r
+                        else:\r
+                            if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
+                                PcdType = T\r
+                                break\r
+\r
                 else:\r
                     Pcd.Pending = False\r
+                    if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
+                        for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
+                            Pcd_Type = item[0].split('_')[-1]\r
+                            if Pcd_Type == PcdType:\r
+                                PcdCName = item[0]\r
+                                break\r
+                            else:\r
+                                pass\r
+                    else:\r
+                        pass\r
 \r
                 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
                     PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
@@ -2374,8 +2658,8 @@ class InfBuildData(ModuleBuildClassObject):
                         EdkLogger.error(\r
                                 'build',\r
                                 FORMAT_INVALID,\r
-                                "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
-                                File =self.MetaFile, Line=LineNo,\r
+                                "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),\r
+                                File=self.MetaFile, Line=LineNo,\r
                                 ExtraData=None\r
                                 )                        \r
                     #\r
@@ -2387,8 +2671,8 @@ class InfBuildData(ModuleBuildClassObject):
                             EdkLogger.error(\r
                                     'build',\r
                                     FORMAT_INVALID,\r
-                                    "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
-                                    File =self.MetaFile, Line=LineNo,\r
+                                    "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),\r
+                                    File=self.MetaFile, Line=LineNo,\r
                                     ExtraData=None\r
                                     )\r
                             \r
@@ -2402,19 +2686,19 @@ class InfBuildData(ModuleBuildClassObject):
                                 EdkLogger.error(\r
                                             'build',\r
                                             FORMAT_INVALID,\r
-                                            "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)),\r
-                                            File =self.MetaFile, Line=LineNo,\r
+                                            "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)),\r
+                                            File=self.MetaFile, Line=LineNo,\r
                                             ExtraData=None\r
-                                            )                                \r
+                                            )\r
                         except:\r
                             EdkLogger.error(\r
                                         'build',\r
                                         FORMAT_INVALID,\r
-                                        "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)),\r
-                                        File =self.MetaFile, Line=LineNo,\r
+                                        "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)),\r
+                                        File=self.MetaFile, Line=LineNo,\r
                                         ExtraData=None\r
                                         )\r
-                    \r
+\r
                     Pcd.DatumType = PcdInPackage.DatumType\r
                     Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
                     Pcd.InfDefaultValue = Pcd.DefaultValue\r
@@ -2425,8 +2709,8 @@ class InfBuildData(ModuleBuildClassObject):
                 EdkLogger.error(\r
                             'build',\r
                             FORMAT_INVALID,\r
-                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
-                            File =self.MetaFile, Line=LineNo,\r
+                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),\r
+                            File=self.MetaFile, Line=LineNo,\r
                             ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
                             )\r
             Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
@@ -2447,6 +2731,7 @@ class InfBuildData(ModuleBuildClassObject):
     Platform = property(_GetPlatform, _SetPlatform)\r
 \r
     HeaderComments = property(_GetHeaderComments)\r
+    TailComments = property(_GetTailComments)\r
     AutoGenVersion          = property(_GetInfVersion)\r
     BaseName                = property(_GetBaseName)\r
     ModuleType              = property(_GetModuleType)\r
@@ -2484,6 +2769,7 @@ class InfBuildData(ModuleBuildClassObject):
     Depex                   = property(_GetDepex)\r
     DepexExpression         = property(_GetDepexExpression)\r
     IsBinaryModule = property(_IsBinaryModule)\r
+    IsSupportedArch = property(_IsSupportedArch)\r
 \r
 ## Database\r
 #\r
@@ -2497,8 +2783,6 @@ class InfBuildData(ModuleBuildClassObject):
 #\r
 class WorkspaceDatabase(object):\r
 \r
-    # default database file path\r
-    _DB_PATH_ = "Conf/.cache/build.db"\r
 \r
     #\r
     # internal class used for call corresponding file parser and caching the result\r
@@ -2609,7 +2893,7 @@ class WorkspaceDatabase(object):
     def __init__(self, DbPath, RenewDb=False):\r
         self._DbClosedFlag = False\r
         if not DbPath:\r
-            DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))\r
+            DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))\r
 \r
         # don't create necessary path for db in memory\r
         if DbPath != ':memory:':\r
@@ -2737,7 +3021,7 @@ determine whether database file is out of date!\n")
     ## Summarize all packages in the database\r
     def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
         self.Platform = Platform\r
-        PackageList =[]\r
+        PackageList = []\r
         Pa = self.BuildObject[self.Platform, 'COMMON']\r
         #\r
         # Get Package related to Modules\r
@@ -2754,8 +3038,8 @@ determine whether database file is out of date!\n")
             LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r
             for Package in LibObj.Packages:\r
                 if Package not in PackageList:\r
-                    PackageList.append(Package)            \r
-        \r
+                    PackageList.append(Package)\r
+\r
         return PackageList\r
 \r
     ## Summarize all platforms in the database\r
@@ -2770,6 +3054,12 @@ determine whether database file is out of date!\n")
                 PlatformList.append(Platform)\r
         return PlatformList\r
 \r
+    def _MapPlatform(self, Dscfile):\r
+        Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']\r
+        if Platform == None:\r
+            EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)\r
+        return Platform\r
+\r
     PlatformList = property(_GetPlatformList)\r
 \r
 ##\r