]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
Sync BaseTool trunk (version r2670) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
index 3aabd545d5d65c9182fae588f13c300998efce99..6ebb7ee87d5e4ed3d264a1da13de76323b341f25 100644 (file)
@@ -1,7 +1,7 @@
 ## @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 - 2014, Intel Corporation. All rights reserved.<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
@@ -18,6 +18,7 @@ import sqlite3
 import os\r
 import os.path\r
 import pickle\r
+import uuid\r
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
@@ -33,6 +34,10 @@ 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
+import re\r
+from Common.Parsing import IsValidWord\r
 \r
 ## Platform build information from DSC file\r
 #\r
@@ -67,12 +72,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
@@ -89,16 +96,14 @@ 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
     ## XXX[key] = value\r
     def __setitem__(self, key, value):\r
@@ -123,6 +128,8 @@ class DscBuildData(PlatformBuildClassObject):
         self._SupArchList       = None\r
         self._BuildTargets      = None\r
         self._SkuName           = None\r
+        self._SkuIdentifier     = None\r
+        self._PcdInfoFlag       = None\r
         self._FlashDefinition   = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
@@ -133,8 +140,22 @@ class DscBuildData(PlatformBuildClassObject):
         self._LibraryInstances  = None\r
         self._LibraryClasses    = None\r
         self._Pcds              = None\r
+        self._DecPcds           = None\r
         self._BuildOptions      = None\r
         self._LoadFixAddress    = None\r
+        self._RFCLanguages      = None\r
+        self._ISOLanguages      = None\r
+        self._VpdToolGuid       = 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.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
@@ -162,32 +183,78 @@ 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_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
+            elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
+                self._PcdInfoFlag = 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[2])\r
+                except:\r
+                    EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\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
@@ -206,7 +273,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
@@ -215,7 +282,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
@@ -224,7 +291,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
@@ -242,7 +309,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
@@ -251,22 +318,37 @@ 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
+            \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
+        self._SkuName = Value\r
+        self._Pcds = None\r
 \r
     def _GetFdfFile(self):\r
         if self._FlashDefinition == None:\r
@@ -317,15 +399,62 @@ 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
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._VpdToolGuid == None:\r
+                self._VpdToolGuid = ''\r
+        return self._VpdToolGuid\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
@@ -335,7 +464,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
@@ -345,8 +476,8 @@ 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
             ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
             ModuleId = Record[5]\r
@@ -358,7 +489,8 @@ 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
+            # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
+            if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
                 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
 \r
             Module = ModuleBuildClassObject()\r
@@ -418,6 +550,7 @@ class DscBuildData(PlatformBuildClassObject):
                             '',\r
                             MaxDatumSize,\r
                             {},\r
+                            False,\r
                             None\r
                             )\r
                     Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
@@ -451,9 +584,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
@@ -485,7 +617,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
@@ -502,14 +635,54 @@ 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
+        if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
+            EdkLogger.error('build', PARSER_ERROR,\r
+                            "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid, PcdCName),\r
+                            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
@@ -524,17 +697,17 @@ class DscBuildData(PlatformBuildClassObject):
     ## Retrieve [BuildOptions]\r
     def _GetBuildOptions(self):\r
         if self._BuildOptions == None:\r
-            self._BuildOptions = {}\r
+            self._BuildOptions = sdict()\r
             #\r
             # Retrieve build option for EDKII style module\r
             #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDKII_NAME]\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDKII_NAME]\r
             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
                 self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
             #\r
             # Retrieve build option for EDK style module\r
             #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDK_NAME]     \r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDK_NAME]     \r
             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
                 self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option\r
         return self._BuildOptions\r
@@ -546,27 +719,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
@@ -576,6 +771,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {},\r
+                                                False,\r
                                                 None\r
                                                 )\r
         return Pcds\r
@@ -587,40 +783,79 @@ 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
-                                                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
     ## Retrieve dynamic HII PCD settings\r
@@ -630,7 +865,10 @@ 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
+        \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
@@ -639,20 +877,51 @@ 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 = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
+            \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
+            \r
+            SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\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
@@ -660,9 +929,51 @@ class DscBuildData(PlatformBuildClassObject):
                                                 DefaultValue,\r
                                                 '',\r
                                                 '',\r
-                                                {self.SkuName : SkuInfo},\r
+                                                {SkuName : SkuInfo},\r
+                                                False,\r
                                                 None\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
@@ -672,30 +983,55 @@ 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
-            VpdOffset, MaxDatumSize = ValueList\r
-\r
-            SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset)\r
-            Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\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 = 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
@@ -703,9 +1039,27 @@ class DscBuildData(PlatformBuildClassObject):
                                                 '',\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
@@ -733,9 +1087,10 @@ class DscBuildData(PlatformBuildClassObject):
     #\r
     def AddPcd(self, Name, Guid, Value):\r
         if (Name, Guid) not in self.Pcds:\r
-            self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, None)\r
+            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
@@ -746,13 +1101,17 @@ class DscBuildData(PlatformBuildClassObject):
     SupArchList         = property(_GetSupArch)\r
     BuildTargets        = property(_GetBuildTarget)\r
     SkuName             = property(_GetSkuName, _SetSkuName)\r
+    SkuIdentifier       = property(_GetSkuIdentifier)\r
+    PcdInfoFlag         = property(_GetPcdInfoFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
     BsBaseAddress       = property(_GetBsBaseAddress)\r
     RtBaseAddress       = property(_GetRtBaseAddress)\r
     LoadFixAddress      = property(_GetLoadFixAddress)\r
-\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
@@ -760,7 +1119,7 @@ class DscBuildData(PlatformBuildClassObject):
     Pcds                = property(_GetPcds)\r
     BuildOptions        = property(_GetBuildOptions)\r
 \r
-## Platform build information from DSC file\r
+## Platform build information from DEC file\r
 #\r
 #  This class is used to retrieve information stored in database and convert them\r
 # into PackageBuildClassObject form for easier use for AutoGen.\r
@@ -789,6 +1148,7 @@ class DecBuildData(PackageBuildClassObject):
         TAB_DEC_DEFINES_PACKAGE_NAME                : "_PackageName",\r
         TAB_DEC_DEFINES_PACKAGE_GUID                : "_Guid",\r
         TAB_DEC_DEFINES_PACKAGE_VERSION             : "_Version",\r
+        TAB_DEC_DEFINES_PKG_UNI_FILE                : "_PkgUniFile",\r
     }\r
 \r
 \r
@@ -803,13 +1163,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
@@ -830,12 +1191,21 @@ class DecBuildData(PackageBuildClassObject):
         self._PackageName       = None\r
         self._Guid              = None\r
         self._Version           = None\r
+        self._PkgUniFile        = None\r
         self._Protocols         = None\r
         self._Ppis              = None\r
         self._Guids             = None\r
         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
@@ -861,11 +1231,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
@@ -975,8 +1345,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
@@ -1000,8 +1370,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
@@ -1018,7 +1387,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
@@ -1028,7 +1397,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
@@ -1043,7 +1412,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
@@ -1051,9 +1419,9 @@ 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
             Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
                                                                             PcdCName,\r
                                                                             TokenSpaceGuid,\r
@@ -1063,11 +1431,13 @@ class DecBuildData(PackageBuildClassObject):
                                                                             TokenNumber,\r
                                                                             '',\r
                                                                             {},\r
+                                                                            False,\r
                                                                             None\r
                                                                             )\r
         return Pcds\r
 \r
 \r
+    _Macros         = property(_GetMacros)\r
     Arch            = property(_GetArch, _SetArch)\r
     PackageName     = property(_GetPackageName)\r
     Guid            = property(_GetFileGuid)\r
@@ -1112,10 +1482,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
@@ -1166,14 +1537,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
@@ -1193,9 +1565,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
@@ -1218,15 +1593,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
@@ -1262,7 +1652,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
@@ -1270,28 +1673,25 @@ 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
             # some special items in [Defines] section need special treatment\r
-            elif Name in ('EFI_SPECIFICATION_VERSION', '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
+            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[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
@@ -1301,27 +1701,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
@@ -1336,16 +1736,26 @@ 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
             if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
@@ -1356,29 +1766,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
+                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
@@ -1402,9 +1822,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
@@ -1422,8 +1842,11 @@ 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
+                    self._AutoGenVersion = int(Record[2], 0)\r
+                    break\r
             if self._AutoGenVersion == None:\r
                 self._AutoGenVersion = 0x00010000\r
         return self._AutoGenVersion\r
@@ -1437,6 +1860,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
@@ -1581,10 +2013,10 @@ class InfBuildData(ModuleBuildClassObject):
         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
@@ -1609,17 +2041,17 @@ class InfBuildData(ModuleBuildClassObject):
         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
+                if self.AutoGenVersion < 0x00010005:\r
+                    Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
+                    Macros['PROCESSOR'] = self._Arch\r
+                    # old module source files (Edk)\r
                     File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
                                      '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
                     # check the file validation\r
@@ -1648,31 +2080,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
@@ -1683,12 +2118,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
@@ -1699,12 +2143,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
@@ -1715,25 +2168,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
@@ -1743,7 +2201,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
@@ -1752,7 +2211,7 @@ 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
@@ -1767,8 +2226,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
@@ -1777,14 +2236,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
@@ -1809,12 +2273,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
@@ -1822,12 +2291,12 @@ 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
+            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
@@ -1863,12 +2332,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
@@ -1877,15 +2346,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
@@ -1895,15 +2366,19 @@ 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
             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
@@ -1914,8 +2389,12 @@ class InfBuildData(ModuleBuildClassObject):
                     '',\r
                     '',\r
                     {},\r
+                    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
             # get necessary info from package declaring this PCD\r
             for Package in self.Packages:\r
@@ -1927,7 +2406,7 @@ class InfBuildData(ModuleBuildClassObject):
                 #   "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
                 #\r
                 PcdType = self._PCD_TYPE_STRING_[Type]\r
-                if Type in [MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
+                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
@@ -1940,6 +2419,55 @@ class InfBuildData(ModuleBuildClassObject):
                     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, PcdCName, 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, PcdCName, 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, PcdCName, 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, PcdCName, 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
@@ -1949,17 +2477,30 @@ class InfBuildData(ModuleBuildClassObject):
             else:\r
                 EdkLogger.error(\r
                             'build',\r
-                            PARSER_ERROR,\r
+                            FORMAT_INVALID,\r
                             "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
                             File =self.MetaFile, Line=LineNo,\r
                             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
@@ -1977,24 +2518,30 @@ 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
 \r
 ## Database\r
 #\r
-#   This class defined the build databse for all modules, packages and platform.\r
+#   This class defined the build database for all modules, packages and platform.\r
 # It will call corresponding parser for the given file if it cannot find it in\r
 # the database.\r
 #\r
@@ -2003,21 +2550,6 @@ 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
@@ -2027,11 +2559,18 @@ class WorkspaceDatabase(object):
     # 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
@@ -2039,7 +2578,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
@@ -2048,46 +2586,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
@@ -2107,10 +2660,9 @@ 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
+    def __init__(self, DbPath, RenewDb=False):\r
+        self._DbClosedFlag = False\r
+        if not DbPath:\r
             DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))\r
 \r
         # don't create necessary path for db in memory\r
@@ -2138,6 +2690,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
@@ -2156,41 +2709,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
@@ -2255,93 +2773,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
-        PackageList = []\r
-        for Module in self.ModuleList:\r
-            for Package in Module.Packages:\r
+    def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
+        self.Platform = Platform\r
+        PackageList =[]\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
@@ -2356,21 +2824,7 @@ 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
-\r
     PlatformList = property(_GetPlatformList)\r
-    PackageList = property(_GetPackageList)\r
-    ModuleList = property(_GetModuleList)\r
 \r
 ##\r
 #\r