]> 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 dad6ecd49a071fb0f81cc6012441698cb22c8bfd..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 - 2010, 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
@@ -34,6 +35,13 @@ from MetaDataTable import *
 from MetaFileTable import *\r
 from MetaFileParser import *\r
 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
@@ -68,12 +76,14 @@ class DscBuildData(PlatformBuildClassObject):
         #TAB_DSC_DEFINES_OUTPUT_DIRECTORY        :   "_OutputDirectory",\r
         #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :   "_SupArchList",\r
         #TAB_DSC_DEFINES_BUILD_TARGETS           :   "_BuildTargets",\r
-        #TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",\r
+        TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",\r
         #TAB_DSC_DEFINES_FLASH_DEFINITION        :   "_FlashDefinition",\r
         TAB_DSC_DEFINES_BUILD_NUMBER            :   "_BuildNumber",\r
         TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",\r
         TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",\r
         TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",\r
+        #TAB_DSC_DEFINES_RFC_LANGUAGES           :   "_RFCLanguages",\r
+        #TAB_DSC_DEFINES_ISO_LANGUAGES           :   "_ISOLanguages",\r
     }\r
 \r
     # used to compose dummy library class name for those forced library instances\r
@@ -90,20 +100,15 @@ class DscBuildData(PlatformBuildClassObject):
     #   @param      Platform        (not used for DscBuildData)\r
     #   @param      Macros          Macros used for replacement in DSC file\r
     #\r
-    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
+    def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
         self.MetaFile = FilePath\r
         self._RawData = RawData\r
         self._Bdb = BuildDataBase\r
         self._Arch = Arch\r
-        self._Macros = Macros\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\r
         self._Clear()\r
-        RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch]\r
-        for Record in RecordList:\r
-            GlobalData.gEdkGlobal[Record[0]] = Record[1]\r
-        \r
-        RecordList = self._RawData[MODEL_META_DATA_GLOBAL_DEFINE, self._Arch]\r
-        for Record in RecordList:\r
-            GlobalData.gGlobalDefines[Record[0]] = Record[1]\r
+        self._HandleOverridePath()\r
 \r
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -128,7 +133,13 @@ class DscBuildData(PlatformBuildClassObject):
         self._SupArchList       = None\r
         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
@@ -138,10 +149,44 @@ class DscBuildData(PlatformBuildClassObject):
         self._LibraryInstances  = None\r
         self._LibraryClasses    = None\r
         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._VpdFileName       = 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
+            self.__Macros = {}\r
+            self.__Macros.update(GlobalData.gPlatformDefines)\r
+            self.__Macros.update(GlobalData.gGlobalDefines)\r
+            self.__Macros.update(GlobalData.gCommandLineDefines)\r
+        return self.__Macros\r
 \r
     ## Get architecture\r
     def _GetArch(self):\r
@@ -169,44 +214,85 @@ class DscBuildData(PlatformBuildClassObject):
     def _GetHeaderInfo(self):\r
         RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
         for Record in RecordList:\r
-            Name = Record[0]\r
+            Name = Record[1]\r
             # items defined _PROPERTY_ don't need additional processing\r
-            if Name in self:\r
-                self[Name] = Record[1]\r
+            \r
             # some special items in [Defines] section need special treatment\r
-            elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
-                self._OutputDirectory = NormPath(Record[1], self._Macros)\r
+            if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
+                self._OutputDirectory = NormPath(Record[2], self._Macros)\r
                 if ' ' in self._OutputDirectory:\r
                     EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
                                     File=self.MetaFile, Line=Record[-1],\r
                                     ExtraData=self._OutputDirectory)\r
             elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
-                self._FlashDefinition = PathClass(NormPath(Record[1], self._Macros), GlobalData.gWorkspace)\r
+                self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
                 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
                 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[1], TAB_VALUE_SPLIT)\r
+                self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
-                self._BuildTargets = GetSplitValueList(Record[1])\r
+                self._BuildTargets = GetSplitValueList(Record[2])\r
             elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
                 if self._SkuName == None:\r
-                    self._SkuName = Record[1]\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
-                self._LoadFixAddress = Record[1]\r
+                try:\r
+                    self._LoadFixAddress = int (Record[2], 0)\r
+                except:\r
+                    EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
+            elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
+                if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageCodes = Record[2][1:-1]\r
+                if not LanguageCodes:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                \r
+                LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
+                # check whether there is empty entries in the list\r
+                if None in LanguageList:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                      \r
+                self._RFCLanguages = LanguageList\r
+            elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
+                if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageCodes = Record[2][1:-1]\r
+                if not LanguageCodes:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
+                                    File=self.MetaFile, Line=Record[-1])                    \r
+                if len(LanguageCodes)%3:\r
+                    EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
+                                    File=self.MetaFile, Line=Record[-1])\r
+                LanguageList = []\r
+                for i in range(0, len(LanguageCodes), 3):\r
+                    LanguageList.append(LanguageCodes[i:i+3])\r
+                self._ISOLanguages = LanguageList               \r
             elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
                 #\r
                 # try to convert GUID to a real UUID value to see whether the GUID is format \r
                 # for VPD_TOOL_GUID is correct.\r
                 #\r
                 try:\r
-                    uuid.UUID(Record[1])\r
+                    uuid.UUID(Record[2])\r
                 except:\r
                     EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
-                self._VpdToolGuid = Record[1]               \r
-            elif Name == TAB_DSC_DEFINES_VPD_FILENAME:\r
-                self._VpdFileName = Record[1]       \r
+                self._VpdToolGuid = Record[2]                   \r
+            elif Name in self:\r
+                self[Name] = Record[2]                 \r
         # set _Header to non-None in order to avoid database re-querying\r
         self._Header = 'DUMMY'\r
 \r
@@ -225,7 +311,7 @@ class DscBuildData(PlatformBuildClassObject):
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
             if self._Guid == None:\r
-                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.MetaFile)\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)\r
         return self._Guid\r
 \r
     ## Retrieve platform version\r
@@ -234,7 +320,7 @@ class DscBuildData(PlatformBuildClassObject):
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
             if self._Version == None:\r
-                self._Version = ''\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\r
         return self._Version\r
 \r
     ## Retrieve platform description file version\r
@@ -243,7 +329,7 @@ class DscBuildData(PlatformBuildClassObject):
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
             if self._DscSpecification == None:\r
-                self._DscSpecification = ''\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)                \r
         return self._DscSpecification\r
 \r
     ## Retrieve OUTPUT_DIRECTORY\r
@@ -261,7 +347,7 @@ class DscBuildData(PlatformBuildClassObject):
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
             if self._SupArchList == None:\r
-                self._SupArchList = ARCH_LIST\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\r
         return self._SupArchList\r
 \r
     ## Retrieve BUILD_TARGETS\r
@@ -270,24 +356,47 @@ class DscBuildData(PlatformBuildClassObject):
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
             if self._BuildTargets == None:\r
-                self._BuildTargets = ['DEBUG', 'RELEASE']\r
+                EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
         return self._BuildTargets\r
-\r
+    \r
+    def _GetPcdInfoFlag(self):\r
+        if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
+            return False\r
+        elif self._PcdInfoFlag.upper() == 'TRUE':\r
+            return True\r
+        else:\r
+            return False\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
+        return self._SkuIdentifier\r
     ## Retrieve SKUID_IDENTIFIER\r
     def _GetSkuName(self):\r
         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
@@ -297,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
@@ -338,10 +463,48 @@ class DscBuildData(PlatformBuildClassObject):
         if self._LoadFixAddress == None:\r
             if self._Header == None:\r
                 self._GetHeaderInfo()\r
+\r
             if self._LoadFixAddress == None:\r
-                self._LoadFixAddress = ''\r
+                self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
+\r
+            try:\r
+                self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
+            except:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
+         \r
+        #\r
+        # If command line defined, should override the value in DSC file.\r
+        #\r
+        if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
+            try:\r
+                self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
+            except:\r
+                EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))\r
+                \r
+        if self._LoadFixAddress < 0:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
+        if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
+            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
+            \r
         return self._LoadFixAddress\r
 \r
+    ## Retrieve RFCLanguage filter\r
+    def _GetRFCLanguages(self):\r
+        if self._RFCLanguages == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._RFCLanguages == None:\r
+                self._RFCLanguages = []\r
+        return self._RFCLanguages\r
+\r
+    ## Retrieve ISOLanguage filter\r
+    def _GetISOLanguages(self):\r
+        if self._ISOLanguages == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._ISOLanguages == None:\r
+                self._ISOLanguages = []\r
+        return self._ISOLanguages\r
     ## Retrieve the GUID string for VPD tool\r
     def _GetVpdToolGuid(self):\r
         if self._VpdToolGuid == None:\r
@@ -350,21 +513,12 @@ class DscBuildData(PlatformBuildClassObject):
             if self._VpdToolGuid == None:\r
                 self._VpdToolGuid = ''\r
         return self._VpdToolGuid\r
-  \r
-    ## Retrieve the VPD file Name, this is optional in DSC file\r
-    def _GetVpdFileName(self):\r
-        if self._VpdFileName == None:\r
-            if self._Header == None:\r
-                self._GetHeaderInfo()\r
-            if self._VpdFileName == None:\r
-                self._VpdFileName = ''\r
-        return self._VpdFileName  \r
-    \r
+      \r
     ## Retrieve [SkuIds] section information\r
     def _GetSkuIds(self):\r
         if self._SkuIds == None:\r
-            self._SkuIds = {}\r
-            RecordList = self._RawData[MODEL_EFI_SKU_ID]\r
+            self._SkuIds = sdict()\r
+            RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
             for Record in RecordList:\r
                 if Record[0] in [None, '']:\r
                     EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
@@ -374,7 +528,9 @@ class DscBuildData(PlatformBuildClassObject):
                                     File=self.MetaFile, Line=Record[-1])\r
                 self._SkuIds[Record[1]] = Record[0]\r
             if 'DEFAULT' not in self._SkuIds:\r
-                self._SkuIds['DEFAULT'] = 0\r
+                self._SkuIds['DEFAULT'] = '0'\r
+            if 'COMMON' not in self._SkuIds:\r
+                self._SkuIds['COMMON'] = '0'\r
         return self._SkuIds\r
 \r
     ## Retrieve [Components] section information\r
@@ -384,9 +540,17 @@ class DscBuildData(PlatformBuildClassObject):
 \r
         self._Modules = sdict()\r
         RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
-        Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-        Macros.update(self._Macros)\r
+        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
@@ -397,24 +561,13 @@ class DscBuildData(PlatformBuildClassObject):
                 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
                                 ExtraData=ErrorInfo)\r
             # Check duplication\r
-            if ModuleFile in self._Modules:\r
-                EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\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
+                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
@@ -471,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
@@ -491,9 +654,8 @@ class DscBuildData(PlatformBuildClassObject):
             LibraryClassDict = tdict(True, 3)\r
             # track all library class names\r
             LibraryClassSet = set()\r
-            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-            Macros.update(self._Macros)\r
+            RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r
+            Macros = self._Macros\r
             for Record in RecordList:\r
                 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record\r
                 if LibraryClass == '' or LibraryClass == 'NULL':\r
@@ -525,7 +687,8 @@ class DscBuildData(PlatformBuildClassObject):
                         continue\r
                     self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
 \r
-            # for R8 style library instances, which are listed in different section\r
+            # for Edk style library instances, which are listed in different section\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
             for Record in RecordList:\r
                 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
@@ -542,14 +705,71 @@ class DscBuildData(PlatformBuildClassObject):
                 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
                 # hasn't been parsed)\r
                 #\r
-                Library = self._Bdb[File, self._Arch]\r
+                Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
                 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
         return self._LibraryClasses\r
 \r
+    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. 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
+            EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
+                            ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
+        if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
+            try:\r
+                ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
+            except WrnExpression, Value:\r
+                ValueList[Index] = Value.result\r
+            except EvaluationException, Excpt:\r
+                if hasattr(Excpt, 'Pcd'):\r
+                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
+                        EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
+                                        " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
+                                        " of the DSC file" % Excpt.Pcd,\r
+                                        File=self.MetaFile, Line=LineNo)\r
+                    else:\r
+                        EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
+                                        File=self.MetaFile, Line=LineNo)\r
+                else:\r
+                    EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
+                                    File=self.MetaFile, Line=LineNo)\r
+            if ValueList[Index] == 'True':\r
+                ValueList[Index] = '1'\r
+            elif ValueList[Index] == 'False':\r
+                ValueList[Index] = '0'\r
+        if ValueList[Index]:\r
+            Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
+            if not Valid:\r
+                EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
+                                ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
+        return ValueList\r
+\r
     ## Retrieve all PCD settings in platform\r
     def _GetPcds(self):\r
         if self._Pcds == None:\r
-            self._Pcds = {}\r
+            self._Pcds = sdict()\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
@@ -564,21 +784,40 @@ class DscBuildData(PlatformBuildClassObject):
     ## Retrieve [BuildOptions]\r
     def _GetBuildOptions(self):\r
         if self._BuildOptions == None:\r
-            self._BuildOptions = {}\r
-            #\r
-            # Retrieve build option for EDKII style module\r
-            #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDKII_NAME]\r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
+            self._BuildOptions = sdict()\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, 'COMMON', 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
@@ -586,27 +825,49 @@ class DscBuildData(PlatformBuildClassObject):
     #   @retval a dict object contains settings of given PCD type\r
     #\r
     def _GetPcd(self, Type):\r
-        Pcds = {}\r
+        Pcds = sdict()\r
         #\r
         # tdict is a special dict kind of type, used for selecting correct\r
         # PCD settings for certain ARCH\r
         #\r
+        \r
+        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        \r
         PcdDict = tdict(True, 3)\r
         PcdSet = set()\r
         # Find out all possible PCD candidates for self._Arch\r
         RecordList = self._RawData[Type, self._Arch]\r
+        PcdValueDict = sdict()\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
-            PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
-        # Remove redundant PCD candidates\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
-            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
+            if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
+                PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
+                PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
+        \r
+        #handle pcd value override        \r
+        for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:\r
+            Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            PcdValue, DatumType, MaxDatumSize = ValueList\r
+            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
+                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) \r
+            else:\r
+                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)}       \r
+        \r
+        PcdsKeys = PcdValueDict.keys()\r
+        for PcdCName,TokenSpaceGuid in PcdsKeys:\r
+            \r
+            PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
+            PcdValue = None\r
+            DatumType = None\r
+            MaxDatumSize = None\r
+            if 'COMMON' in PcdSetting:\r
+                PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']\r
+            if 'DEFAULT' in PcdSetting:\r
+                PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']\r
+            if SkuObj.SystemSkuId in PcdSetting:\r
+                PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
+                \r
             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
                                                 TokenSpaceGuid,\r
@@ -628,43 +889,92 @@ class DscBuildData(PlatformBuildClassObject):
     #   @retval a dict object contains settings of given PCD type\r
     #\r
     def _GetDynamicPcd(self, Type):\r
-        Pcds = {}\r
+        \r
+        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        \r
+        Pcds = sdict()\r
         #\r
         # tdict is a special dict kind of type, used for selecting correct\r
         # PCD settings for certain ARCH and SKU\r
         #\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\r
         # Find out all possible PCD candidates for self._Arch\r
         RecordList = self._RawData[Type, self._Arch]\r
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+        \r
+        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            if SkuName not in AvailableSkuIdSet:\r
+                continue\r
+            \r
+            PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
         # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+        for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
+            \r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            PcdValue, DatumType, MaxDatumSize = ValueList\r
-\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
-                                                PcdCName,\r
-                                                TokenSpaceGuid,\r
-                                                self._PCD_TYPE_STRING_[Type],\r
-                                                DatumType,\r
-                                                PcdValue,\r
-                                                '',\r
-                                                MaxDatumSize,\r
-                                                {self.SkuName : SkuInfo},\r
-                                                False,\r
-                                                None\r
-                                                )\r
+                      \r
+            PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
+            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
+                                                    DatumType,\r
+                                                    PcdValue,\r
+                                                    '',\r
+                                                    MaxDatumSize,\r
+                                                    {SkuName : SkuInfo},\r
+                                                    False,\r
+                                                    None\r
+                                                    )\r
+        \r
+        for pcd in Pcds.values():\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
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                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
         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
@@ -672,7 +982,11 @@ class DscBuildData(PlatformBuildClassObject):
     #   @retval a dict object contains settings of given PCD type\r
     #\r
     def _GetDynamicHiiPcd(self, Type):\r
-        Pcds = {}\r
+        \r
+        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        VariableAttrs = {}\r
+        \r
+        Pcds = sdict()\r
         #\r
         # tdict is a special dict kind of type, used for selecting correct\r
         # PCD settings for certain ARCH and SKU\r
@@ -681,20 +995,61 @@ class DscBuildData(PlatformBuildClassObject):
         PcdSet = set()\r
         RecordList = self._RawData[Type, self._Arch]\r
         # Find out all possible PCD candidates for self._Arch\r
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+        \r
+        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            if SkuName not in AvailableSkuIdSet:\r
+                continue\r
+            PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
         # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+        for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:\r
+            \r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\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
+            else:\r
+                Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
                                                 PcdCName,\r
                                                 TokenSpaceGuid,\r
                                                 self._PCD_TYPE_STRING_[Type],\r
@@ -702,10 +1057,54 @@ class DscBuildData(PlatformBuildClassObject):
                                                 DefaultValue,\r
                                                 '',\r
                                                 '',\r
-                                                {self.SkuName : SkuInfo},\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
+            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
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+                \r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                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
@@ -715,47 +1114,83 @@ class DscBuildData(PlatformBuildClassObject):
     #   @retval a dict object contains settings of given PCD type\r
     #\r
     def _GetDynamicVpdPcd(self, Type):\r
-        Pcds = {}\r
+        \r
+        SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
+        \r
+        Pcds = sdict()\r
         #\r
         # tdict is a special dict kind of type, used for selecting correct\r
         # PCD settings for certain ARCH and SKU\r
         #\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\r
         # Find out all possible PCD candidates for self._Arch\r
         RecordList = self._RawData[Type, self._Arch]\r
+        AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
+        \r
+        AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            if SkuName not in AvailableSkuIdSet:\r
+                continue\r
+\r
+            PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))\r
             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
         # Remove redundant PCD candidates, per the ARCH and SKU\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
-            Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]\r
+        for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:\r
+            Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
             #\r
             # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
             # For the Integer & Boolean type, the optional data can only be InitialValue.\r
             # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
             # until the DEC parser has been called.\r
             # \r
-            VpdOffset, MaxDatumSize, InitialValue = ValueList\r
-\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
+            VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
+            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
-                                                {self.SkuName : SkuInfo},\r
+                                                {SkuName : SkuInfo},\r
                                                 False,\r
                                                 None\r
                                                 )\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
+                valuefromDec = pcdDecObject.DefaultValue\r
+                SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
+                pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
+            elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
+                del(pcd.SkuInfoList['COMMON'])\r
+            if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
+                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
         return Pcds\r
 \r
     ## Add external modules\r
@@ -786,6 +1221,7 @@ class DscBuildData(PlatformBuildClassObject):
             self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
         self.Pcds[Name, Guid].DefaultValue = Value\r
 \r
+    _Macros             = property(_GetMacros)\r
     Arch                = property(_GetArch, _SetArch)\r
     Platform            = property(_GetPlatformName)\r
     PlatformName        = property(_GetPlatformName)\r
@@ -796,14 +1232,21 @@ class DscBuildData(PlatformBuildClassObject):
     SupArchList         = property(_GetSupArch)\r
     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
     RtBaseAddress       = property(_GetRtBaseAddress)\r
     LoadFixAddress      = property(_GetLoadFixAddress)\r
-    VpdToolGuid         = property(_GetVpdToolGuid)\r
-    VpdFileName         = property(_GetVpdFileName)    \r
+    RFCLanguages        = property(_GetRFCLanguages)\r
+    ISOLanguages        = property(_GetISOLanguages)\r
+    VpdToolGuid         = property(_GetVpdToolGuid)   \r
     SkuIds              = property(_GetSkuIds)\r
     Modules             = property(_GetModules)\r
     LibraryInstances    = property(_GetLibraryInstances)\r
@@ -855,13 +1298,14 @@ class DecBuildData(PackageBuildClassObject):
     #   @param      Platform        (not used for DecBuildData)\r
     #   @param      Macros          Macros used for replacement in DSC file\r
     #\r
-    def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):\r
+    def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
         self.MetaFile = File\r
         self._PackageDir = File.Dir\r
         self._RawData = RawData\r
         self._Bdb = BuildDataBase\r
         self._Arch = Arch\r
-        self._Macros = Macros\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\r
         self._Clear()\r
 \r
     ## XXX[key] = value\r
@@ -889,6 +1333,14 @@ class DecBuildData(PackageBuildClassObject):
         self._Includes          = None\r
         self._LibraryClasses    = None\r
         self._Pcds              = None\r
+        self.__Macros           = None\r
+\r
+    ## Get current effective macros\r
+    def _GetMacros(self):\r
+        if self.__Macros == None:\r
+            self.__Macros = {}\r
+            self.__Macros.update(GlobalData.gGlobalDefines)\r
+        return self.__Macros\r
 \r
     ## Get architecture\r
     def _GetArch(self):\r
@@ -914,11 +1366,11 @@ class DecBuildData(PackageBuildClassObject):
     #   (Retriving all [Defines] information in one-shot is just to save time.)\r
     #\r
     def _GetHeaderInfo(self):\r
-        RecordList = self._RawData[MODEL_META_DATA_HEADER]\r
+        RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
         for Record in RecordList:\r
-            Name = Record[0]\r
+            Name = Record[1]\r
             if Name in self:\r
-                self[Name] = Record[1]\r
+                self[Name] = Record[2]\r
         self._Header = 'DUMMY'\r
 \r
     ## Retrieve package name\r
@@ -1028,8 +1480,8 @@ class DecBuildData(PackageBuildClassObject):
         if self._Includes == None:\r
             self._Includes = []\r
             RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-            Macros.update(self._Macros)\r
+            Macros = self._Macros\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
             for Record in RecordList:\r
                 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
                 LineNo = Record[-1]\r
@@ -1053,8 +1505,7 @@ class DecBuildData(PackageBuildClassObject):
             LibraryClassDict = tdict(True)\r
             LibraryClassSet = set()\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-            Macros.update(self._Macros)\r
+            Macros = self._Macros\r
             for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
                 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
                 # check the file validation\r
@@ -1071,7 +1522,7 @@ class DecBuildData(PackageBuildClassObject):
     ## Retrieve PCD declarations\r
     def _GetPcds(self):\r
         if self._Pcds == None:\r
-            self._Pcds = {}\r
+            self._Pcds = sdict()\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
@@ -1081,7 +1532,7 @@ class DecBuildData(PackageBuildClassObject):
 \r
     ## Retrieve PCD declarations for given type\r
     def _GetPcd(self, Type):\r
-        Pcds = {}\r
+        Pcds = sdict()\r
         #\r
         # tdict is a special kind of dict, used for selecting correct\r
         # PCD declaration for given ARCH\r
@@ -1096,7 +1547,6 @@ class DecBuildData(PackageBuildClassObject):
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
 \r
         for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '', '']\r
             #\r
             # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
             # will automatically turn to 'common' ARCH and try again\r
@@ -1104,9 +1554,10 @@ class DecBuildData(PackageBuildClassObject):
             Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
             if Setting == None:\r
                 continue\r
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
-            DefaultValue, DatumType, TokenNumber = ValueList\r
+\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
@@ -1117,11 +1568,15 @@ 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
 \r
+    _Macros         = property(_GetMacros)\r
     Arch            = property(_GetArch, _SetArch)\r
     PackageName     = property(_GetPackageName)\r
     Guid            = property(_GetFileGuid)\r
@@ -1166,10 +1621,11 @@ class InfBuildData(ModuleBuildClassObject):
         #\r
         # Optional Fields\r
         #\r
-        TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
+        #TAB_INF_DEFINES_INF_VERSION                 : "_AutoGenVersion",\r
         TAB_INF_DEFINES_COMPONENT_TYPE              : "_ComponentType",\r
         TAB_INF_DEFINES_MAKEFILE_NAME               : "_MakefileName",\r
         #TAB_INF_DEFINES_CUSTOM_MAKEFILE             : "_CustomMakefile",\r
+        TAB_INF_DEFINES_DPX_SOURCE                  :"_DxsFile",\r
         TAB_INF_DEFINES_VERSION_NUMBER              : "_Version",\r
         TAB_INF_DEFINES_VERSION_STRING              : "_Version",\r
         TAB_INF_DEFINES_VERSION                     : "_Version",\r
@@ -1220,14 +1676,15 @@ class InfBuildData(ModuleBuildClassObject):
     #   @param      Platform        The name of platform employing this module\r
     #   @param      Macros          Macros used for replacement in DSC file\r
     #\r
-    def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}):\r
+    def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
         self.MetaFile = FilePath\r
         self._ModuleDir = FilePath.Dir\r
         self._RawData = RawData\r
         self._Bdb = BuildDatabase\r
         self._Arch = Arch\r
+        self._Target = Target\r
+        self._Toolchain = Toolchain\r
         self._Platform = 'COMMON'\r
-        self._Macros = Macros\r
         self._SourceOverridePath = None\r
         if FilePath.Key in GlobalData.gOverrideDir:\r
             self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
@@ -1247,9 +1704,12 @@ class InfBuildData(ModuleBuildClassObject):
 \r
     ## 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
+        self._DxsFile               = None\r
         self._ModuleType            = None\r
         self._ComponentType         = None\r
         self._BuildType             = None\r
@@ -1272,15 +1732,30 @@ class InfBuildData(ModuleBuildClassObject):
         self._LibraryClasses        = None\r
         self._Libraries             = None\r
         self._Protocols             = None\r
+        self._ProtocolComments = None\r
         self._Ppis                  = None\r
+        self._PpiComments = None\r
         self._Guids                 = None\r
+        self._GuidsUsedByPcd = sdict()\r
+        self._GuidComments = None\r
         self._Includes              = None\r
         self._Packages              = None\r
         self._Pcds                  = None\r
+        self._PcdComments = None\r
         self._BuildOptions          = None\r
         self._Depex                 = None\r
         self._DepexExpression       = None\r
-        #self._SourceOverridePath    = None\r
+        self.__Macros               = None\r
+\r
+    ## Get current effective macros\r
+    def _GetMacros(self):\r
+        if self.__Macros == None:\r
+            self.__Macros = {}\r
+            # EDK_GLOBAL defined macros can be applied to EDK module\r
+            if self.AutoGenVersion < 0x00010005:\r
+                self.__Macros.update(GlobalData.gEdkGlobal)\r
+                self.__Macros.update(GlobalData.gGlobalDefines)\r
+        return self.__Macros\r
 \r
     ## Get architecture\r
     def _GetArch(self):\r
@@ -1316,7 +1791,20 @@ class InfBuildData(ModuleBuildClassObject):
             return\r
         self._Platform = Value\r
         self._Clear()\r
-\r
+    def _GetHeaderComments(self):\r
+        if not self._HeaderComments:\r
+            self._HeaderComments = []\r
+            RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
+            for Record in RecordList:\r
+                self._HeaderComments.append(Record[0])\r
+        return self._HeaderComments\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
@@ -1324,28 +1812,28 @@ class InfBuildData(ModuleBuildClassObject):
     def _GetHeaderInfo(self):\r
         RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
         for Record in RecordList:\r
-            Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
-            Name = Record[0]\r
+            Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
             # items defined _PROPERTY_ don't need additional processing\r
             if Name in self:\r
-                self[Name] = Record[1]\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'):\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
+                    Name = 'UEFI_SPECIFICATION_VERSION'\r
                 if self._Specification == None:\r
                     self._Specification = sdict()\r
-                self._Specification['UEFI_SPECIFICATION_VERSION'] = Record[1]\r
-            elif Name == 'EDK_RELEASE_VERSION':\r
-                if self._Specification == None:\r
-                    self._Specification = sdict()\r
-                self._Specification[Name] = Record[1]\r
-            elif Name == 'PI_SPECIFICATION_VERSION':\r
-                if self._Specification == None:\r
-                    self._Specification = sdict()\r
-                self._Specification[Name] = Record[1]\r
+                self._Specification[Name] = GetHexVerValue(Value)\r
+                if self._Specification[Name] == None:\r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
+                                    "'%s' format is not supported for %s" % (Value, Name),\r
+                                    File=self.MetaFile, Line=Record[-1])\r
             elif Name == 'LIBRARY_CLASS':\r
                 if self._LibraryClass == None:\r
                     self._LibraryClass = []\r
-                ValueList = GetSplitValueList(Record[1])\r
+                ValueList = GetSplitValueList(Value)\r
                 LibraryClass = ValueList[0]\r
                 if len(ValueList) > 1:\r
                     SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
@@ -1355,27 +1843,27 @@ class InfBuildData(ModuleBuildClassObject):
             elif Name == 'ENTRY_POINT':\r
                 if self._ModuleEntryPointList == None:\r
                     self._ModuleEntryPointList = []\r
-                self._ModuleEntryPointList.append(Record[1])\r
+                self._ModuleEntryPointList.append(Value)\r
             elif Name == 'UNLOAD_IMAGE':\r
                 if self._ModuleUnloadImageList == None:\r
                     self._ModuleUnloadImageList = []\r
-                if Record[1] == '':\r
+                if not Value:\r
                     continue\r
-                self._ModuleUnloadImageList.append(Record[1])\r
+                self._ModuleUnloadImageList.append(Value)\r
             elif Name == 'CONSTRUCTOR':\r
                 if self._ConstructorList == None:\r
                     self._ConstructorList = []\r
-                if Record[1] == '':\r
+                if not Value:\r
                     continue\r
-                self._ConstructorList.append(Record[1])\r
+                self._ConstructorList.append(Value)\r
             elif Name == 'DESTRUCTOR':\r
                 if self._DestructorList == None:\r
                     self._DestructorList = []\r
-                if Record[1] == '':\r
+                if not Value:\r
                     continue\r
-                self._DestructorList.append(Record[1])\r
+                self._DestructorList.append(Value)\r
             elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
-                TokenList = GetSplitValueList(Record[1])\r
+                TokenList = GetSplitValueList(Value)\r
                 if self._CustomMakefile == None:\r
                     self._CustomMakefile = {}\r
                 if len(TokenList) < 2:\r
@@ -1390,18 +1878,28 @@ class InfBuildData(ModuleBuildClassObject):
             else:\r
                 if self._Defs == None:\r
                     self._Defs = sdict()\r
-                self._Defs[Name] = Record[1]\r
+                self._Defs[Name] = Value\r
 \r
         #\r
-        # Retrieve information in sections specific to R8.x modules\r
+        # Retrieve information in sections specific to Edk.x modules\r
         #\r
-        if self._AutoGenVersion >= 0x00010005:   # _AutoGenVersion may be None, which is less than anything\r
+        if self.AutoGenVersion >= 0x00010005:\r
             if not self._ModuleType:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
                                 "MODULE_TYPE is not given", File=self.MetaFile)\r
-            if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (self._Specification['PI_SPECIFICATION_VERSION'] < 0x0001000A):\r
+            if self._ModuleType not in SUP_MODULE_LIST:\r
+                RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
+                for Record in RecordList:\r
+                    Name = Record[1]\r
+                    if Name == "MODULE_TYPE":\r
+                        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
+                                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
@@ -1410,29 +1908,39 @@ class InfBuildData(ModuleBuildClassObject):
                 self._BuildType = 'UEFI_HII'\r
             else:\r
                 self._BuildType = self._ModuleType.upper()\r
-        else:\r
-            self._BuildType = self._ComponentType.upper()\r
+\r
+            if self._DxsFile:\r
+                File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
+                # check the file validation\r
+                ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
+                if ErrorCode != 0:\r
+                    EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
+                                    File=self.MetaFile, Line=LineNo)\r
+                if self.Sources == None:\r
+                    self._Sources = []\r
+                self._Sources.append(File)\r
+        else:  \r
             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
             if self._ComponentType in self._MODULE_TYPE_:\r
                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
             if self._ComponentType == 'LIBRARY':\r
                 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
             # make use some [nmake] section macros\r
+            Macros = self._Macros\r
+            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
-                Value = Value.replace('$(PROCESSOR)', self._Arch)\r
-                Name = Name.replace('$(PROCESSOR)', self._Arch)\r
-                Name, Value = ReplaceMacros((Name, Value), GlobalData.gEdkGlobal, True)\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
                         self._ModuleEntryPointList = []\r
                     self._ModuleEntryPointList.append(Value)\r
                 elif Name == "DPX_SOURCE":\r
-                    Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-                    Macros.update(self._Macros)\r
-                    File = PathClass(NormPath(Value, Macros), self._ModuleDir, Arch=self._Arch)\r
+                    File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
                     # check the file validation\r
                     ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
                     if ErrorCode != 0:\r
@@ -1456,9 +1964,9 @@ class InfBuildData(ModuleBuildClassObject):
                         else:\r
                             Tool = ToolList[0]\r
                         ToolChain = "*_*_*_%s_FLAGS" % Tool\r
-                        ToolChainFamily = 'MSFT'    # R8.x only support MSFT tool chain\r
+                        ToolChainFamily = 'MSFT'    # Edk.x only support MSFT tool chain\r
                         #ignore not replaced macros in value\r
-                        ValueList = GetSplitValueList(' ' + Value, '/D')\r
+                        ValueList = GetSplitList(' ' + Value, '/D')\r
                         Dummy = ValueList[0]\r
                         for Index in range(1, len(ValueList)):\r
                             if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
@@ -1476,8 +1984,17 @@ class InfBuildData(ModuleBuildClassObject):
     ## Retrieve file version\r
     def _GetInfVersion(self):\r
         if self._AutoGenVersion == None:\r
-            if self._Header_ == None:\r
-                self._GetHeaderInfo()\r
+            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
+                    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
         return self._AutoGenVersion\r
@@ -1491,6 +2008,15 @@ class InfBuildData(ModuleBuildClassObject):
                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
         return self._BaseName\r
 \r
+    ## Retrieve DxsFile\r
+    def _GetDxsFile(self):\r
+        if self._DxsFile == None:\r
+            if self._Header_ == None:\r
+                self._GetHeaderInfo()\r
+            if self._DxsFile == None:\r
+                self._DxsFile = ''\r
+        return self._DxsFile\r
+\r
     ## Retrieve MODULE_TYPE\r
     def _GetModuleType(self):\r
         if self._ModuleType == None:\r
@@ -1526,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
@@ -1631,14 +2157,14 @@ 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
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}\r
-            Macros.update(self._Macros)\r
+            Macros = self._Macros\r
+            Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+            Macros['PROCESSOR'] = self._Arch\r
             for Record in RecordList:\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
                 FileType = Record[0]\r
                 LineNo = Record[-1]\r
                 Target = 'COMMON'\r
@@ -1658,23 +2184,45 @@ 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
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}\r
-            Macros.update(self._Macros)\r
+            Macros = self._Macros\r
             for Record in RecordList:\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
                 LineNo = Record[-1]\r
                 ToolChainFamily = Record[1]\r
                 TagName = Record[2]\r
                 ToolCode = Record[3]\r
                 FeatureFlag = Record[4]\r
-                if self._AutoGenVersion < 0x00010005:\r
-                    # old module source files (R8)\r
-                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
+                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(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
@@ -1702,31 +2250,34 @@ class InfBuildData(ModuleBuildClassObject):
             self._LibraryClasses = sdict()\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
             for Record in RecordList:\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
                 Lib = Record[0]\r
                 Instance = Record[1]\r
-                if Instance != None and Instance != '':\r
+                if Instance:\r
                     Instance = NormPath(Instance, self._Macros)\r
                 self._LibraryClasses[Lib] = Instance\r
         return self._LibraryClasses\r
 \r
-    ## Retrieve library names (for R8.x style of modules)\r
+    ## Retrieve library names (for Edk.x style of modules)\r
     def _GetLibraryNames(self):\r
         if self._Libraries == None:\r
             self._Libraries = []\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
             for Record in RecordList:\r
-                # in case of name with '.lib' extension, which is unusual in R8.x inf\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
-                LibraryName = os.path.splitext(Record[0])[0]\r
+                LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
+                # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
+                LibraryName = os.path.splitext(LibraryName)[0]\r
                 if LibraryName not in self._Libraries:\r
                     self._Libraries.append(LibraryName)\r
         return self._Libraries\r
 \r
+    def _GetProtocolComments(self):\r
+        self._GetProtocols()\r
+        return self._ProtocolComments\r
     ## Retrieve protocols consumed/produced by this module\r
     def _GetProtocols(self):\r
         if self._Protocols == None:\r
             self._Protocols = sdict()\r
+            self._ProtocolComments = sdict()\r
             RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
@@ -1737,12 +2288,21 @@ class InfBuildData(ModuleBuildClassObject):
                                     "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
                                     ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
                 self._Protocols[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._ProtocolComments[CName] = Comments\r
         return self._Protocols\r
 \r
+    def _GetPpiComments(self):\r
+        self._GetPpis()\r
+        return self._PpiComments\r
     ## Retrieve PPIs consumed/produced by this module\r
     def _GetPpis(self):\r
         if self._Ppis == None:\r
             self._Ppis = sdict()\r
+            self._PpiComments = sdict()\r
             RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
@@ -1753,12 +2313,21 @@ class InfBuildData(ModuleBuildClassObject):
                                     "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
                                     ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
                 self._Ppis[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._PpiComments[CName] = Comments\r
         return self._Ppis\r
 \r
+    def _GetGuidComments(self):\r
+        self._GetGuids()\r
+        return self._GuidComments\r
     ## Retrieve GUIDs consumed/produced by this module\r
     def _GetGuids(self):\r
         if self._Guids == None:\r
             self._Guids = sdict()\r
+            self._GuidComments = sdict()\r
             RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
@@ -1769,25 +2338,30 @@ class InfBuildData(ModuleBuildClassObject):
                                     "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
                                     ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
                 self._Guids[CName] = Value\r
+                CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
+                Comments = []\r
+                for CmtRec in CommentRecords:\r
+                    Comments.append(CmtRec[0])\r
+                self._GuidComments[CName] = Comments\r
         return self._Guids\r
 \r
-    ## Retrieve include paths necessary for this module (for R8.x style of modules)\r
+    ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
     def _GetIncludes(self):\r
         if self._Includes == None:\r
             self._Includes = []\r
             if self._SourceOverridePath:\r
                 self._Includes.append(self._SourceOverridePath)\r
+\r
+            Macros = self._Macros\r
+            if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
+                Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
+            else:\r
+                Macros['PROCESSOR'] = self._Arch\r
             RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
-            # [includes] section must be used only in old (R8.x) inf file\r
-            if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0:\r
-                EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed",\r
-                                File=self.MetaFile, Line=RecordList[0][-1]-1)\r
             for Record in RecordList:\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
-                Record[0] = Record[0].replace('$(PROCESSOR)', self._Arch)\r
-                Record[0] = ReplaceMacro(Record[0], {'EFI_SOURCE' : GlobalData.gEfiSource}, False)\r
                 if Record[0].find('EDK_SOURCE') > -1:\r
-                    File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEcpSource}, False), self._Macros)\r
+                    Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
+                    File = NormPath(Record[0], self._Macros)\r
                     if File[0] == '.':\r
                         File = os.path.join(self._ModuleDir, File)\r
                     else:\r
@@ -1797,7 +2371,8 @@ class InfBuildData(ModuleBuildClassObject):
                         self._Includes.append(File)\r
 \r
                     #TRICK: let compiler to choose correct header file\r
-                    File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEdkSource}, False), self._Macros)\r
+                    Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
+                    File = NormPath(Record[0], self._Macros)\r
                     if File[0] == '.':\r
                         File = os.path.join(self._ModuleDir, File)\r
                     else:\r
@@ -1806,14 +2381,25 @@ class InfBuildData(ModuleBuildClassObject):
                     if File:\r
                         self._Includes.append(File)\r
                 else:\r
-                    File = NormPath(Record[0], self._Macros)\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 = 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
@@ -1821,8 +2407,8 @@ class InfBuildData(ModuleBuildClassObject):
         if self._Packages == None:\r
             self._Packages = []\r
             RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
-            Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}\r
-            Macros.update(self._Macros)\r
+            Macros = self._Macros\r
+            Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
             for Record in RecordList:\r
                 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
                 LineNo = Record[-1]\r
@@ -1831,14 +2417,19 @@ class InfBuildData(ModuleBuildClassObject):
                 if ErrorCode != 0:\r
                     EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
                 # parse this package now. we need it to get protocol/ppi/guid value\r
-                Package = self._Bdb[File, self._Arch]\r
+                Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
                 self._Packages.append(Package)\r
         return self._Packages\r
 \r
+    ## Retrieve PCD comments\r
+    def _GetPcdComments(self):\r
+        self._GetPcds()\r
+        return self._PcdComments\r
     ## Retrieve PCDs used in this module\r
     def _GetPcds(self):\r
         if self._Pcds == None:\r
-            self._Pcds = {}\r
+            self._Pcds = sdict()\r
+            self._PcdComments = sdict()\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
@@ -1855,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
@@ -1863,12 +2454,17 @@ class InfBuildData(ModuleBuildClassObject):
                     self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
         return self._BuildOptions\r
 \r
-    ## Retrieve depedency expression\r
+    ## Retrieve dependency expression\r
     def _GetDepex(self):\r
         if self._Depex == None:\r
             self._Depex = tdict(False, 2)\r
             RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-\r
+            \r
+            # If the module has only Binaries and no Sources, then ignore [Depex] \r
+            if self.Sources == None or self.Sources == []:\r
+                if self.Binaries != None and self.Binaries != []:\r
+                    return self._Depex\r
+                \r
             # PEIM and DXE drivers must have a valid [Depex] section\r
             if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
                 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
@@ -1876,12 +2472,19 @@ 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
-            Depex = {}\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
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
+                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
                 Arch = Record[3]\r
                 ModuleType = Record[4]\r
-                TokenList = Record[0].split()\r
+                TokenList = DepexStr.split()\r
                 if (Arch, ModuleType) not in Depex:\r
                     Depex[Arch, ModuleType] = []\r
                 DepexList = Depex[Arch, ModuleType]\r
@@ -1917,12 +2520,12 @@ class InfBuildData(ModuleBuildClassObject):
         if self._DepexExpression == None:\r
             self._DepexExpression = tdict(False, 2)\r
             RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
-            DepexExpression = {}\r
+            DepexExpression = sdict()\r
             for Record in RecordList:\r
-                Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)\r
+                DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
                 Arch = Record[3]\r
                 ModuleType = Record[4]\r
-                TokenList = Record[0].split()\r
+                TokenList = DepexStr.split()\r
                 if (Arch, ModuleType) not in DepexExpression:\r
                     DepexExpression[Arch, ModuleType] = ''\r
                 for Token in TokenList:\r
@@ -1931,15 +2534,17 @@ class InfBuildData(ModuleBuildClassObject):
                 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
         return self._DepexExpression\r
 \r
+    def GetGuidsUsedByPcd(self):\r
+        return self._GuidsUsedByPcd\r
     ## Retrieve PCD for given type\r
     def _GetPcd(self, Type):\r
-        Pcds = {}\r
+        Pcds = sdict()\r
         PcdDict = tdict(True, 4)\r
-        PcdSet = set()\r
+        PcdList = []\r
         RecordList = self._RawData[Type, self._Arch, self._Platform]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList:\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
             PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
-            PcdSet.add((PcdCName, TokenSpaceGuid))\r
+            PcdList.append((PcdCName, TokenSpaceGuid))\r
             # get the guid value\r
             if TokenSpaceGuid not in self.Guids:\r
                 Value = GuidValue(TokenSpaceGuid, self.Packages)\r
@@ -1949,15 +2554,20 @@ class InfBuildData(ModuleBuildClassObject):
                                     "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
                                     ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
                 self.Guids[TokenSpaceGuid] = Value\r
+                self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
+            CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
+            Comments = []\r
+            for CmtRec in CommentRecords:\r
+                Comments.append(CmtRec[0])\r
+            self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
 \r
         # resolve PCD type, value, datum info, etc. by getting its definition from package\r
-        for PcdCName, TokenSpaceGuid in PcdSet:\r
-            ValueList = ['', '']\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
-            TokenList = Setting.split(TAB_VALUE_SPLIT)\r
-            ValueList[0:len(TokenList)] = TokenList\r
+            ValueList = AnalyzePcdData(Setting)\r
             DefaultValue = ValueList[0]\r
             Pcd = PcdClassObject(\r
                     PcdCName,\r
@@ -1971,6 +2581,30 @@ class InfBuildData(ModuleBuildClassObject):
                     False,\r
                     self.Guids[TokenSpaceGuid]\r
                     )\r
+            if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
+                # 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
@@ -1985,16 +2619,86 @@ 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
                     Pcd.Type = PcdType\r
                     Pcd.TokenValue = PcdInPackage.TokenValue\r
+                    \r
+                    #\r
+                    # Check whether the token value exist or not.\r
+                    #\r
+                    if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
+                        EdkLogger.error(\r
+                                'build',\r
+                                FORMAT_INVALID,\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
+                    # Check hexadecimal token value length and format.\r
+                    #\r
+                    ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
+                    if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
+                        if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\r
+                            EdkLogger.error(\r
+                                    'build',\r
+                                    FORMAT_INVALID,\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
+                    #\r
+                    # Check decimal token value length and format.\r
+                    #                            \r
+                    else:\r
+                        try:\r
+                            TokenValueInt = int (Pcd.TokenValue, 10)\r
+                            if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
+                                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, PcdRealName, str(Package)),\r
+                                            File=self.MetaFile, Line=LineNo,\r
+                                            ExtraData=None\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, PcdRealName, str(Package)),\r
+                                        File=self.MetaFile, Line=LineNo,\r
+                                        ExtraData=None\r
+                                        )\r
+\r
                     Pcd.DatumType = PcdInPackage.DatumType\r
                     Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
                     Pcd.InfDefaultValue = Pcd.DefaultValue\r
@@ -2004,17 +2708,30 @@ class InfBuildData(ModuleBuildClassObject):
             else:\r
                 EdkLogger.error(\r
                             'build',\r
-                            PARSER_ERROR,\r
-                            "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
-                            File =self.MetaFile, Line=LineNo,\r
+                            FORMAT_INVALID,\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
+\r
         return Pcds\r
 \r
-    Arch                    = property(_GetArch, _SetArch)\r
-    Platform                = property(_GetPlatform, _SetPlatform)\r
+    ## check whether current module is binary module\r
+    def _IsBinaryModule(self):\r
+        if self.Binaries and not self.Sources:\r
+            return True\r
+        elif GlobalData.gIgnoreSource:\r
+            return True\r
+        else:\r
+            return False\r
 \r
+    _Macros = property(_GetMacros)\r
+    Arch = property(_GetArch, _SetArch)\r
+    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
@@ -2032,20 +2749,27 @@ class InfBuildData(ModuleBuildClassObject):
     ConstructorList         = property(_GetConstructor)\r
     DestructorList          = property(_GetDestructor)\r
     Defines                 = property(_GetDefines)\r
-\r
+    DxsFile                 = property(_GetDxsFile)\r
+    \r
     Binaries                = property(_GetBinaryFiles)\r
     Sources                 = property(_GetSourceFiles)\r
     LibraryClasses          = property(_GetLibraryClassUses)\r
     Libraries               = property(_GetLibraryNames)\r
     Protocols               = property(_GetProtocols)\r
+    ProtocolComments = property(_GetProtocolComments)\r
     Ppis                    = property(_GetPpis)\r
+    PpiComments = property(_GetPpiComments)\r
     Guids                   = property(_GetGuids)\r
+    GuidComments = property(_GetGuidComments)\r
     Includes                = property(_GetIncludes)\r
     Packages                = property(_GetPackages)\r
     Pcds                    = property(_GetPcds)\r
+    PcdComments = property(_GetPcdComments)\r
     BuildOptions            = property(_GetBuildOptions)\r
     Depex                   = property(_GetDepex)\r
     DepexExpression         = property(_GetDepexExpression)\r
+    IsBinaryModule = property(_IsBinaryModule)\r
+    IsSupportedArch = property(_IsSupportedArch)\r
 \r
 ## Database\r
 #\r
@@ -2058,35 +2782,25 @@ class InfBuildData(ModuleBuildClassObject):
 # @prarm RenewDb=False      Create new database file if it's already there\r
 #\r
 class WorkspaceDatabase(object):\r
-    # file parser\r
-    _FILE_PARSER_ = {\r
-        MODEL_FILE_INF  :   InfParser,\r
-        MODEL_FILE_DEC  :   DecParser,\r
-        MODEL_FILE_DSC  :   DscParser,\r
-        MODEL_FILE_FDF  :   None, #FdfParser,\r
-        MODEL_FILE_CIF  :   None\r
-    }\r
 \r
-    # file table\r
-    _FILE_TABLE_ = {\r
-        MODEL_FILE_INF  :   ModuleTable,\r
-        MODEL_FILE_DEC  :   PackageTable,\r
-        MODEL_FILE_DSC  :   PlatformTable,\r
-    }\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
     # to avoid unnecessary re-parsing\r
     #\r
     class BuildObjectFactory(object):\r
+\r
         _FILE_TYPE_ = {\r
             ".inf"  : MODEL_FILE_INF,\r
             ".dec"  : MODEL_FILE_DEC,\r
             ".dsc"  : MODEL_FILE_DSC,\r
-            ".fdf"  : MODEL_FILE_FDF,\r
+        }\r
+\r
+        # file parser\r
+        _FILE_PARSER_ = {\r
+            MODEL_FILE_INF  :   InfParser,\r
+            MODEL_FILE_DEC  :   DecParser,\r
+            MODEL_FILE_DSC  :   DscParser,\r
         }\r
 \r
         # convert to xxxBuildData object\r
@@ -2094,7 +2808,6 @@ class WorkspaceDatabase(object):
             MODEL_FILE_INF  :   InfBuildData,\r
             MODEL_FILE_DEC  :   DecBuildData,\r
             MODEL_FILE_DSC  :   DscBuildData,\r
-            MODEL_FILE_FDF  :   None #FlashDefTable,\r
         }\r
 \r
         _CACHE_ = {}    # (FilePath, Arch)  : <object>\r
@@ -2103,46 +2816,61 @@ class WorkspaceDatabase(object):
         def __init__(self, WorkspaceDb):\r
             self.WorkspaceDb = WorkspaceDb\r
 \r
-        # key = (FilePath, Arch='COMMON')\r
+        # key = (FilePath, Arch=None)\r
         def __contains__(self, Key):\r
             FilePath = Key[0]\r
-            Arch = 'COMMON'\r
             if len(Key) > 1:\r
                 Arch = Key[1]\r
+            else:\r
+                Arch = None\r
             return (FilePath, Arch) in self._CACHE_\r
 \r
-        # key = (FilePath, Arch='COMMON')\r
+        # key = (FilePath, Arch=None, Target=None, Toochain=None)\r
         def __getitem__(self, Key):\r
             FilePath = Key[0]\r
-            Arch = 'COMMON'\r
-            Platform = 'COMMON'\r
-            if len(Key) > 1:\r
+            KeyLength = len(Key)\r
+            if KeyLength > 1:\r
                 Arch = Key[1]\r
-            if len(Key) > 2:\r
-                Platform = Key[2]\r
+            else:\r
+                Arch = None\r
+            if KeyLength > 2:\r
+                Target = Key[2]\r
+            else:\r
+                Target = None\r
+            if KeyLength > 3:\r
+                Toolchain = Key[3]\r
+            else:\r
+                Toolchain = None\r
 \r
             # if it's generated before, just return the cached one\r
-            Key = (FilePath, Arch)\r
+            Key = (FilePath, Arch, Target, Toolchain)\r
             if Key in self._CACHE_:\r
                 return self._CACHE_[Key]\r
 \r
             # check file type\r
-            Ext = FilePath.Ext.lower()\r
+            Ext = FilePath.Type\r
             if Ext not in self._FILE_TYPE_:\r
                 return None\r
             FileType = self._FILE_TYPE_[Ext]\r
             if FileType not in self._GENERATOR_:\r
                 return None\r
 \r
-            # get table for current file\r
-            MetaFile = self.WorkspaceDb[FilePath, FileType, self.WorkspaceDb._GlobalMacros]\r
+            # get the parser ready for this file\r
+            MetaFile = self._FILE_PARSER_[FileType](\r
+                                FilePath, \r
+                                FileType, \r
+                                MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)\r
+                                )\r
+            # alwasy do post-process, in case of macros change\r
+            MetaFile.DoPostProcess()\r
+            # object the build is based on\r
             BuildObject = self._GENERATOR_[FileType](\r
                                     FilePath,\r
                                     MetaFile,\r
                                     self,\r
                                     Arch,\r
-                                    Platform,\r
-                                    self.WorkspaceDb._GlobalMacros,\r
+                                    Target,\r
+                                    Toolchain\r
                                     )\r
             self._CACHE_[Key] = BuildObject\r
             return BuildObject\r
@@ -2162,11 +2890,10 @@ class WorkspaceDatabase(object):
     # @param GlobalMacros       Global macros used for replacement during file parsing\r
     # @prarm RenewDb=False      Create new database file if it's already there\r
     #\r
-    def __init__(self, DbPath, GlobalMacros={}, RenewDb=False):\r
-        self._GlobalMacros = GlobalMacros\r
-\r
-        if DbPath == None or DbPath == '':\r
-            DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))\r
+    def __init__(self, DbPath, RenewDb=False):\r
+        self._DbClosedFlag = False\r
+        if not DbPath:\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
@@ -2193,6 +2920,7 @@ class WorkspaceDatabase(object):
         # create table for internal uses\r
         self.TblDataModel = TableDataModel(self.Cur)\r
         self.TblFile = TableFile(self.Cur)\r
+        self.Platform = None\r
 \r
         # conversion object for build or file format conversion purpose\r
         self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
@@ -2211,41 +2939,6 @@ class WorkspaceDatabase(object):
     #  @return Bool value for whether need renew workspace databse\r
     #\r
     def _CheckWhetherDbNeedRenew (self, force, DbPath):\r
-        DbDir = os.path.split(DbPath)[0]\r
-        MacroFilePath = os.path.normpath(os.path.join(DbDir, "build.mac"))\r
-        MacroMatch = False\r
-        if os.path.exists(MacroFilePath) and os.path.isfile(MacroFilePath):\r
-            LastMacros = None\r
-            try:\r
-                f = open(MacroFilePath,'r')\r
-                LastMacros = pickle.load(f)\r
-                f.close()\r
-            except IOError:\r
-                pass\r
-            except:\r
-                f.close()\r
-\r
-            if LastMacros != None and type(LastMacros) is DictType:\r
-                if LastMacros == self._GlobalMacros:\r
-                    MacroMatch = True\r
-                    for Macro in LastMacros.keys():\r
-                        if not (Macro in self._GlobalMacros and LastMacros[Macro] == self._GlobalMacros[Macro]):\r
-                            MacroMatch = False;\r
-                            break;\r
-\r
-        if not MacroMatch:\r
-            # save command line macros to file\r
-            try:\r
-                f = open(MacroFilePath,'w')\r
-                pickle.dump(self._GlobalMacros, f, 2)\r
-                f.close()\r
-            except IOError:\r
-                pass\r
-            except:\r
-                f.close()\r
-\r
-            force = True\r
-\r
         # if database does not exist, we need do nothing\r
         if not os.path.exists(DbPath): return False\r
             \r
@@ -2310,93 +3003,43 @@ determine whether database file is out of date!\n")
     def QueryTable(self, Table):\r
         Table.Query()\r
 \r
+    def __del__(self):\r
+        self.Close()\r
+\r
     ## Close entire database\r
     #\r
     # Commit all first\r
     # Close the connection and cursor\r
     #\r
     def Close(self):\r
-        self.Conn.commit()\r
-        self.Cur.close()\r
-        self.Conn.close()\r
-\r
-    ## Get unique file ID for the gvien file\r
-    def GetFileId(self, FilePath):\r
-        return self.TblFile.GetFileId(FilePath)\r
-\r
-    ## Get file type value for the gvien file ID\r
-    def GetFileType(self, FileId):\r
-        return self.TblFile.GetFileType(FileId)\r
-\r
-    ## Get time stamp stored in file table\r
-    def GetTimeStamp(self, FileId):\r
-        return self.TblFile.GetFileTimeStamp(FileId)\r
-\r
-    ## Update time stamp in file table\r
-    def SetTimeStamp(self, FileId, TimeStamp):\r
-        return self.TblFile.SetFileTimeStamp(FileId, TimeStamp)\r
-\r
-    ## Check if a table integrity flag exists or not\r
-    def CheckIntegrity(self, TableName):\r
-        try:\r
-            Result = self.Cur.execute("select min(ID) from %s" % (TableName)).fetchall()\r
-            if Result[0][0] != -1:\r
-                return False\r
-            #\r
-            # Check whether the meta data file has external dependency by comparing the time stamp\r
-            #\r
-            Sql = "select Value1, Value2 from %s where Model=%d" % (TableName, MODEL_EXTERNAL_DEPENDENCY)\r
-            for Dependency in self.Cur.execute(Sql).fetchall():\r
-                if str(os.stat(Dependency[0])[8]) != Dependency[1]:\r
-                    return False\r
-        except:\r
-            return False\r
-        return True\r
-\r
-    ## Compose table name for given file type and file ID\r
-    def GetTableName(self, FileType, FileId):\r
-        return "_%s_%s" % (FileType, FileId)\r
-\r
-    ## Return a temp table containing all content of the given file\r
-    #\r
-    #   @param  FileInfo    The tuple containing path and type of a file\r
-    #\r
-    def __getitem__(self, FileInfo):\r
-        FilePath, FileType, Macros = FileInfo\r
-        if FileType not in self._FILE_TABLE_:\r
-            return None\r
-\r
-        # flag used to indicate if it's parsed or not\r
-        FilePath = str(FilePath)\r
-        Parsed = False\r
-        FileId = self.GetFileId(FilePath)\r
-        if FileId != None:\r
-            TimeStamp = os.stat(FilePath)[8]\r
-            TableName = self.GetTableName(FileType, FileId)\r
-            if TimeStamp != self.GetTimeStamp(FileId):\r
-                # update the timestamp in database\r
-                self.SetTimeStamp(FileId, TimeStamp)\r
-            else:\r
-                # if the table exists and is integrity, don't parse it\r
-                Parsed = self.CheckIntegrity(TableName)\r
-        else:\r
-            FileId = self.TblFile.InsertFile(FilePath, FileType)\r
-            TableName = self.GetTableName(FileType, FileId)\r
-\r
-        FileTable = self._FILE_TABLE_[FileType](self.Cur, TableName, FileId)\r
-        FileTable.Create(not Parsed)\r
-        Parser = self._FILE_PARSER_[FileType](FilePath, FileType, FileTable, Macros)\r
-        # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)\r
-        Parser.Finished = Parsed\r
-        return Parser\r
+        if not self._DbClosedFlag:\r
+            self.Conn.commit()\r
+            self.Cur.close()\r
+            self.Conn.close()\r
+            self._DbClosedFlag = True\r
 \r
     ## Summarize all packages in the database\r
-    def _GetPackageList(self):\r
+    def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
+        self.Platform = Platform\r
         PackageList = []\r
-        for Module in self.ModuleList:\r
-            for Package in Module.Packages:\r
+        Pa = self.BuildObject[self.Platform, 'COMMON']\r
+        #\r
+        # Get Package related to Modules\r
+        #\r
+        for Module in Pa.Modules:\r
+            ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r
+            for Package in ModuleObj.Packages:\r
+                if Package not in PackageList:\r
+                    PackageList.append(Package)\r
+        #\r
+        # Get Packages related to Libraries\r
+        #\r
+        for Lib in Pa.LibraryInstances:\r
+            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
         return PackageList\r
 \r
     ## Summarize all platforms in the database\r
@@ -2411,21 +3054,13 @@ determine whether database file is out of date!\n")
                 PlatformList.append(Platform)\r
         return PlatformList\r
 \r
-    ## Summarize all modules in the database\r
-    def _GetModuleList(self):\r
-        ModuleList = []\r
-        for ModuleFile in self.TblFile.GetFileList(MODEL_FILE_INF):\r
-            try:\r
-                Module = self.BuildObject[PathClass(ModuleFile), 'COMMON']\r
-            except:\r
-                Module = None\r
-            if Module != None:\r
-                ModuleList.append(Module)\r
-        return ModuleList\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
-    PackageList = property(_GetPackageList)\r
-    ModuleList = property(_GetModuleList)\r
 \r
 ##\r
 #\r