]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/build/BuildReport.py
BaseTools: Fix VPD PCD Sub-section display bug
[mirror_edk2.git] / BaseTools / Source / Python / build / BuildReport.py
index e06c352330bcf014cf36c0716ce72fc4c36364ba..ea98ef7ed55c2386d866f390124a8c42d8641dd4 100644 (file)
@@ -28,12 +28,11 @@ import hashlib
 import subprocess\r
 import threading\r
 from datetime import datetime\r
 import subprocess\r
 import threading\r
 from datetime import datetime\r
-from StringIO import StringIO\r
+from io import BytesIO\r
 from Common import EdkLogger\r
 from Common.Misc import SaveFileOnChange\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
 from Common.Misc import GuidStructureStringToGuidString\r
 from Common import EdkLogger\r
 from Common.Misc import SaveFileOnChange\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
 from Common.Misc import GuidStructureStringToGuidString\r
-from Common.InfClassObject import gComponentType2ModuleType\r
 from Common.BuildToolError import FILE_WRITE_FAILURE\r
 from Common.BuildToolError import CODE_ERROR\r
 from Common.BuildToolError import COMMAND_FAILURE\r
 from Common.BuildToolError import FILE_WRITE_FAILURE\r
 from Common.BuildToolError import CODE_ERROR\r
 from Common.BuildToolError import COMMAND_FAILURE\r
@@ -43,7 +42,7 @@ from Common.MultipleWorkspace import MultipleWorkspace as mws
 import Common.GlobalData as GlobalData\r
 from AutoGen.AutoGen import ModuleAutoGen\r
 from Common.Misc import PathClass\r
 import Common.GlobalData as GlobalData\r
 from AutoGen.AutoGen import ModuleAutoGen\r
 from Common.Misc import PathClass\r
-from Common.String import NormPath\r
+from Common.StringUtils import NormPath\r
 from Common.DataType import *\r
 import collections\r
 from Common.Expression import *\r
 from Common.DataType import *\r
 import collections\r
 from Common.Expression import *\r
@@ -95,38 +94,41 @@ gSubSectionSep = "-" * gLineMaxLength
 \r
 ## The look up table to map PCD type to pair of report display type and DEC type\r
 gPcdTypeMap = {\r
 \r
 ## The look up table to map PCD type to pair of report display type and DEC type\r
 gPcdTypeMap = {\r
-  'FixedAtBuild'     : ('FIXED',  'FixedAtBuild'),\r
-  'PatchableInModule': ('PATCH',  'PatchableInModule'),\r
-  'FeatureFlag'      : ('FLAG',   'FeatureFlag'),\r
-  'Dynamic'          : ('DYN',    'Dynamic'),\r
-  'DynamicHii'       : ('DYNHII', 'Dynamic'),\r
-  'DynamicVpd'       : ('DYNVPD', 'Dynamic'),\r
-  'DynamicEx'        : ('DEX',    'DynamicEx'),\r
-  'DynamicExHii'     : ('DEXHII', 'DynamicEx'),\r
-  'DynamicExVpd'     : ('DEXVPD', 'DynamicEx'),\r
+  TAB_PCDS_FIXED_AT_BUILD     : ('FIXED',  TAB_PCDS_FIXED_AT_BUILD),\r
+  TAB_PCDS_PATCHABLE_IN_MODULE: ('PATCH',  TAB_PCDS_PATCHABLE_IN_MODULE),\r
+  TAB_PCDS_FEATURE_FLAG       : ('FLAG',   TAB_PCDS_FEATURE_FLAG),\r
+  TAB_PCDS_DYNAMIC            : ('DYN',    TAB_PCDS_DYNAMIC),\r
+  TAB_PCDS_DYNAMIC_HII        : ('DYNHII', TAB_PCDS_DYNAMIC),\r
+  TAB_PCDS_DYNAMIC_VPD        : ('DYNVPD', TAB_PCDS_DYNAMIC),\r
+  TAB_PCDS_DYNAMIC_EX         : ('DEX',    TAB_PCDS_DYNAMIC_EX),\r
+  TAB_PCDS_DYNAMIC_EX_HII     : ('DEXHII', TAB_PCDS_DYNAMIC_EX),\r
+  TAB_PCDS_DYNAMIC_EX_VPD     : ('DEXVPD', TAB_PCDS_DYNAMIC_EX),\r
   }\r
 \r
 ## The look up table to map module type to driver type\r
 gDriverTypeMap = {\r
   }\r
 \r
 ## The look up table to map module type to driver type\r
 gDriverTypeMap = {\r
-  'SEC'               : '0x3 (SECURITY_CORE)',\r
-  'PEI_CORE'          : '0x4 (PEI_CORE)',\r
-  'PEIM'              : '0x6 (PEIM)',\r
-  'DXE_CORE'          : '0x5 (DXE_CORE)',\r
-  'DXE_DRIVER'        : '0x7 (DRIVER)',\r
-  'DXE_SAL_DRIVER'    : '0x7 (DRIVER)',\r
-  'DXE_SMM_DRIVER'    : '0x7 (DRIVER)',\r
-  'DXE_RUNTIME_DRIVER': '0x7 (DRIVER)',\r
-  'UEFI_DRIVER'       : '0x7 (DRIVER)',\r
-  'UEFI_APPLICATION'  : '0x9 (APPLICATION)',\r
-  'SMM_CORE'          : '0xD (SMM_CORE)',\r
+  SUP_MODULE_SEC               : '0x3 (SECURITY_CORE)',\r
+  SUP_MODULE_PEI_CORE          : '0x4 (PEI_CORE)',\r
+  SUP_MODULE_PEIM              : '0x6 (PEIM)',\r
+  SUP_MODULE_DXE_CORE          : '0x5 (DXE_CORE)',\r
+  SUP_MODULE_DXE_DRIVER        : '0x7 (DRIVER)',\r
+  SUP_MODULE_DXE_SAL_DRIVER    : '0x7 (DRIVER)',\r
+  SUP_MODULE_DXE_SMM_DRIVER    : '0x7 (DRIVER)',\r
+  SUP_MODULE_DXE_RUNTIME_DRIVER: '0x7 (DRIVER)',\r
+  SUP_MODULE_UEFI_DRIVER       : '0x7 (DRIVER)',\r
+  SUP_MODULE_UEFI_APPLICATION  : '0x9 (APPLICATION)',\r
+  SUP_MODULE_SMM_CORE          : '0xD (SMM_CORE)',\r
   'SMM_DRIVER'        : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers\r
   'SMM_DRIVER'        : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers\r
-  'MM_STANDALONE'     : '0xE (MM_STANDALONE)',\r
-  'MM_CORE_STANDALONE' : '0xF (MM_CORE_STANDALONE)'\r
+  SUP_MODULE_MM_STANDALONE     : '0xE (MM_STANDALONE)',\r
+  SUP_MODULE_MM_CORE_STANDALONE : '0xF (MM_CORE_STANDALONE)'\r
   }\r
 \r
 ## The look up table of the supported opcode in the dependency expression binaries\r
 gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"]\r
 \r
   }\r
 \r
 ## The look up table of the supported opcode in the dependency expression binaries\r
 gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"]\r
 \r
+## Save VPD Pcd\r
+VPDPcdList = []\r
+\r
 ##\r
 # Writes a string to the file object.\r
 #\r
 ##\r
 # Writes a string to the file object.\r
 #\r
@@ -209,7 +211,7 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
             FileName = "Protocol/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
         elif "PPI" in Type:\r
             FileName = "Ppi/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
             FileName = "Protocol/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
         elif "PPI" in Type:\r
             FileName = "Ppi/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
-        elif "GUID" in Type:\r
+        elif TAB_GUID in Type:\r
             FileName = "Guid/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
         else:\r
             continue\r
             FileName = "Guid/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
         else:\r
             continue\r
@@ -221,7 +223,7 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
 \r
 ## Split each lines in file\r
 #\r
 \r
 ## Split each lines in file\r
 #\r
-#  This method is used to split the lines in file to make the length of each line \r
+#  This method is used to split the lines in file to make the length of each line\r
 #  less than MaxLength.\r
 #\r
 #  @param      Content           The content of file\r
 #  less than MaxLength.\r
 #\r
 #  @param      Content           The content of file\r
@@ -246,12 +248,12 @@ def FileLinesSplit(Content=None, MaxLength=None):
             NewContentList.append(Line)\r
     for NewLine in NewContentList:\r
         NewContent += NewLine + TAB_LINE_BREAK\r
             NewContentList.append(Line)\r
     for NewLine in NewContentList:\r
         NewContent += NewLine + TAB_LINE_BREAK\r
-    \r
+\r
     NewContent = NewContent.replace(TAB_LINE_BREAK, gEndOfLine).replace('\r\r\n', gEndOfLine)\r
     return NewContent\r
     NewContent = NewContent.replace(TAB_LINE_BREAK, gEndOfLine).replace('\r\r\n', gEndOfLine)\r
     return NewContent\r
-    \r
-    \r
-    \r
+\r
+\r
+\r
 ##\r
 # Parse binary dependency expression section\r
 #\r
 ##\r
 # Parse binary dependency expression section\r
 #\r
@@ -281,10 +283,15 @@ class DepexParser(object):
                 for Guid in Package.Guids:\r
                     GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
                     self._GuidDb[GuidValue.upper()] = Guid\r
                 for Guid in Package.Guids:\r
                     GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
                     self._GuidDb[GuidValue.upper()] = Guid\r
-    \r
+            for Ma in Pa.ModuleAutoGenList:\r
+                for Pcd in Ma.FixedVoidTypePcds:\r
+                    PcdValue = Ma.FixedVoidTypePcds[Pcd]\r
+                    if len(PcdValue.split(',')) == 16:\r
+                        GuidValue = GuidStructureByteArrayToGuidString(PcdValue)\r
+                        self._GuidDb[GuidValue.upper()] = Pcd\r
     ##\r
     # Parse the binary dependency expression files.\r
     ##\r
     # Parse the binary dependency expression files.\r
-    # \r
+    #\r
     # This function parses the binary dependency expression file and translate it\r
     # to the instruction list.\r
     #\r
     # This function parses the binary dependency expression file and translate it\r
     # to the instruction list.\r
     #\r
@@ -299,14 +306,14 @@ class DepexParser(object):
             Statement = gOpCodeList[struct.unpack("B", OpCode)[0]]\r
             if Statement in ["BEFORE", "AFTER", "PUSH"]:\r
                 GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \\r
             Statement = gOpCodeList[struct.unpack("B", OpCode)[0]]\r
             if Statement in ["BEFORE", "AFTER", "PUSH"]:\r
                 GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \\r
-                            struct.unpack("=LHHBBBBBBBB", DepexFile.read(16))\r
+                            struct.unpack(PACK_PATTERN_GUID, DepexFile.read(16))\r
                 GuidString = self._GuidDb.get(GuidValue, GuidValue)\r
                 Statement = "%s %s" % (Statement, GuidString)\r
             DepexStatement.append(Statement)\r
             OpCode = DepexFile.read(1)\r
 \r
         return DepexStatement\r
                 GuidString = self._GuidDb.get(GuidValue, GuidValue)\r
                 Statement = "%s %s" % (Statement, GuidString)\r
             DepexStatement.append(Statement)\r
             OpCode = DepexFile.read(1)\r
 \r
         return DepexStatement\r
-    \r
+\r
 ##\r
 # Reports library information\r
 #\r
 ##\r
 # Reports library information\r
 #\r
@@ -408,11 +415,11 @@ class DepexReport(object):
         self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex")\r
         ModuleType = M.ModuleType\r
         if not ModuleType:\r
         self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex")\r
         ModuleType = M.ModuleType\r
         if not ModuleType:\r
-            ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
+            ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "")\r
 \r
 \r
-        if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "MM_CORE_STANDALONE", "UEFI_APPLICATION"]:\r
+        if ModuleType in [SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_DXE_CORE, SUP_MODULE_SMM_CORE, SUP_MODULE_MM_CORE_STANDALONE, SUP_MODULE_UEFI_APPLICATION]:\r
             return\r
             return\r
-      \r
+\r
         for Source in M.SourceFileList:\r
             if os.path.splitext(Source.Path)[1].lower() == ".dxs":\r
                 Match = gDxsDependencyPattern.search(open(Source.Path).read())\r
         for Source in M.SourceFileList:\r
             if os.path.splitext(Source.Path)[1].lower() == ".dxs":\r
                 Match = gDxsDependencyPattern.search(open(Source.Path).read())\r
@@ -421,7 +428,7 @@ class DepexReport(object):
                     self.Source = "DXS"\r
                     break\r
         else:\r
                     self.Source = "DXS"\r
                     break\r
         else:\r
-            self.Depex = M.DepexExpressionList.get(M.ModuleType, "")\r
+            self.Depex = M.DepexExpressionDict.get(M.ModuleType, "")\r
             self.ModuleDepex = " ".join(M.Module.DepexExpression[M.Arch, M.ModuleType])\r
             if not self.ModuleDepex:\r
                 self.ModuleDepex = "(None)"\r
             self.ModuleDepex = " ".join(M.Module.DepexExpression[M.Arch, M.ModuleType])\r
             if not self.ModuleDepex:\r
                 self.ModuleDepex = "(None)"\r
@@ -458,16 +465,16 @@ class DepexReport(object):
                 FileWrite(File, gSubSectionSep)\r
             except:\r
                 EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName)\r
                 FileWrite(File, gSubSectionSep)\r
             except:\r
                 EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName)\r
-        \r
+\r
         FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)\r
 \r
         if self.Source == "INF":\r
         FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)\r
 \r
         if self.Source == "INF":\r
-            FileWrite(File, "%s" % self.Depex, True)\r
+            FileWrite(File, self.Depex, True)\r
             FileWrite(File, gSubSectionSep)\r
             FileWrite(File, "From Module INF:  %s" % self.ModuleDepex, True)\r
             FileWrite(File, "From Library INF: %s" % self.LibraryDepex, True)\r
         else:\r
             FileWrite(File, gSubSectionSep)\r
             FileWrite(File, "From Module INF:  %s" % self.ModuleDepex, True)\r
             FileWrite(File, "From Library INF: %s" % self.LibraryDepex, True)\r
         else:\r
-            FileWrite(File, "%s" % self.Depex)\r
+            FileWrite(File, self.Depex)\r
         FileWrite(File, gSubSectionEnd)\r
 \r
 ##\r
         FileWrite(File, gSubSectionEnd)\r
 \r
 ##\r
@@ -573,11 +580,11 @@ class ModuleReport(object):
         if not M.IsLibrary:\r
             ModuleType = M.ModuleType\r
             if not ModuleType:\r
         if not M.IsLibrary:\r
             ModuleType = M.ModuleType\r
             if not ModuleType:\r
-                ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
+                ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "")\r
             #\r
             # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER"\r
             #\r
             #\r
             # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER"\r
             #\r
-            if ModuleType == "DXE_SMM_DRIVER":\r
+            if ModuleType == SUP_MODULE_DXE_SMM_DRIVER:\r
                 PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")\r
                 if int(PiSpec, 0) >= 0x0001000A:\r
                     ModuleType = "SMM_DRIVER"\r
                 PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")\r
                 if int(PiSpec, 0) >= 0x0001000A:\r
                     ModuleType = "SMM_DRIVER"\r
@@ -650,7 +657,7 @@ class ModuleReport(object):
                 cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile]\r
                 try:\r
                     PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
                 cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile]\r
                 try:\r
                     PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
-                except Exception, X:\r
+                except Exception as X:\r
                     EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
                 EndOfProcedure = threading.Event()\r
                 EndOfProcedure.clear()\r
                     EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
                 EndOfProcedure = threading.Event()\r
                 EndOfProcedure.clear()\r
@@ -785,7 +792,7 @@ class PcdReport(object):
                 Pcd = Pa.Platform.Pcds[item]\r
                 if not Pcd.Type:\r
                     # check the Pcd in FDF file, whether it is used in module first\r
                 Pcd = Pa.Platform.Pcds[item]\r
                 if not Pcd.Type:\r
                     # check the Pcd in FDF file, whether it is used in module first\r
-                    for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
+                    for T in PCD_TYPE_LIST:\r
                         PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(T, [])\r
                         if Pcd in PcdList:\r
                             Pcd.Type = T\r
                         PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(T, [])\r
                         if Pcd in PcdList:\r
                             Pcd.Type = T\r
@@ -793,7 +800,7 @@ class PcdReport(object):
                 if not Pcd.Type:\r
                     PcdTypeFlag = False\r
                     for package in Pa.PackageList:\r
                 if not Pcd.Type:\r
                     PcdTypeFlag = False\r
                     for package in Pa.PackageList:\r
-                        for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
+                        for T in PCD_TYPE_LIST:\r
                             if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds:\r
                                 Pcd.Type = T\r
                                 PcdTypeFlag = True\r
                             if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds:\r
                                 Pcd.Type = T\r
                                 PcdTypeFlag = True\r
@@ -805,16 +812,19 @@ class PcdReport(object):
                 if not Pcd.DatumType:\r
                     PcdType = Pcd.Type\r
                     # Try to remove Hii and Vpd suffix\r
                 if not Pcd.DatumType:\r
                     PcdType = Pcd.Type\r
                     # Try to remove Hii and Vpd suffix\r
-                    if PcdType.startswith("DynamicEx"):\r
-                        PcdType = "DynamicEx"\r
-                    elif PcdType.startswith("Dynamic"):\r
-                        PcdType = "Dynamic"\r
+                    if PcdType.startswith(TAB_PCDS_DYNAMIC_EX):\r
+                        PcdType = TAB_PCDS_DYNAMIC_EX\r
+                    elif PcdType.startswith(TAB_PCDS_DYNAMIC):\r
+                        PcdType = TAB_PCDS_DYNAMIC\r
                     for package in Pa.PackageList:\r
                         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType) in package.Pcds:\r
                             Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType)].DatumType\r
                             break\r
 \r
                 PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
                     for package in Pa.PackageList:\r
                         if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType) in package.Pcds:\r
                             Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType)].DatumType\r
                             break\r
 \r
                 PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
+                UnusedPcdList = self.UnusedPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
+                if Pcd in UnusedPcdList:\r
+                    UnusedPcdList.remove(Pcd)\r
                 if Pcd not in PcdList and Pcd not in UnusedPcdFullList:\r
                     UnusedPcdFullList.append(Pcd)\r
                 if len(Pcd.TokenCName) > self.MaxLen:\r
                 if Pcd not in PcdList and Pcd not in UnusedPcdFullList:\r
                     UnusedPcdFullList.append(Pcd)\r
                 if len(Pcd.TokenCName) > self.MaxLen:\r
@@ -824,7 +834,7 @@ class PcdReport(object):
                 for PcdItem in GlobalData.gConditionalPcds:\r
                     if '.' in PcdItem:\r
                         (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.')\r
                 for PcdItem in GlobalData.gConditionalPcds:\r
                     if '.' in PcdItem:\r
                         (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.')\r
-                        if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds.keys():\r
+                        if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds:\r
                             Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)]\r
                             PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
                             if Pcd not in PcdList:\r
                             Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)]\r
                             PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
                             if Pcd not in PcdList:\r
@@ -881,7 +891,17 @@ class PcdReport(object):
             if self.ConditionalPcds:\r
                 self.GenerateReportDetail(File, ModulePcdSet, 1)\r
             if self.UnusedPcds:\r
             if self.ConditionalPcds:\r
                 self.GenerateReportDetail(File, ModulePcdSet, 1)\r
             if self.UnusedPcds:\r
-                self.GenerateReportDetail(File, ModulePcdSet, 2)\r
+                IsEmpty = True\r
+                for Token in self.UnusedPcds:\r
+                    TokenDict = self.UnusedPcds[Token]\r
+                    for Type in TokenDict:\r
+                        if TokenDict[Type]:\r
+                            IsEmpty = False\r
+                            break\r
+                    if not IsEmpty:\r
+                        break\r
+                if not IsEmpty:\r
+                    self.GenerateReportDetail(File, ModulePcdSet, 2)\r
         self.GenerateReportDetail(File, ModulePcdSet)\r
 \r
     ##\r
         self.GenerateReportDetail(File, ModulePcdSet)\r
 \r
     ##\r
@@ -928,190 +948,250 @@ class PcdReport(object):
                 FileWrite(File, gSubSectionStart)\r
                 FileWrite(File, TAB_BRG_PCD)\r
                 FileWrite(File, gSubSectionSep)\r
                 FileWrite(File, gSubSectionStart)\r
                 FileWrite(File, TAB_BRG_PCD)\r
                 FileWrite(File, gSubSectionSep)\r
-\r
+        AllPcdDict = {}\r
         for Key in PcdDict:\r
         for Key in PcdDict:\r
+            AllPcdDict[Key] = {}\r
+            for Type in PcdDict[Key]:\r
+                for Pcd in PcdDict[Key][Type]:\r
+                    AllPcdDict[Key][(Pcd.TokenCName, Type)] = Pcd\r
+        for Key in sorted(AllPcdDict):\r
             #\r
             # Group PCD by their token space GUID C Name\r
             #\r
             First = True\r
             #\r
             # Group PCD by their token space GUID C Name\r
             #\r
             First = True\r
-            for Type in PcdDict[Key]:\r
+            for PcdTokenCName, Type in sorted(AllPcdDict[Key]):\r
                 #\r
                 # Group PCD by their usage type\r
                 #\r
                 #\r
                 # Group PCD by their usage type\r
                 #\r
+                Pcd = AllPcdDict[Key][(PcdTokenCName, Type)]\r
                 TypeName, DecType = gPcdTypeMap.get(Type, ("", Type))\r
                 TypeName, DecType = gPcdTypeMap.get(Type, ("", Type))\r
-                for Pcd in PcdDict[Key][Type]:\r
-                    PcdTokenCName = Pcd.TokenCName\r
-                    MixedPcdFlag = False\r
-                    if GlobalData.MixedPcd:\r
-                        for PcdKey in GlobalData.MixedPcd:\r
-                            if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdKey]:\r
-                                PcdTokenCName = PcdKey[0]\r
-                                MixedPcdFlag = True\r
-                        if MixedPcdFlag and not ModulePcdSet:\r
-                            continue\r
-                    #\r
-                    # Get PCD default value and their override relationship\r
-                    #\r
-                    DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))\r
-                    DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
-                    DscDefaultValBak = DscDefaultValue\r
-                    DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue)\r
-                    if DscDefaultValue != DscDefaultValBak:\r
-                        try:\r
-                            DscDefaultValue = ValueExpressionEx(DscDefaultValue, Pcd.DatumType, self._GuidDict)(True)\r
-                        except BadExpression, DscDefaultValue:\r
-                            EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" %(DscDefaultValue, Pcd.DatumType))\r
+                MixedPcdFlag = False\r
+                if GlobalData.MixedPcd:\r
+                    for PcdKey in GlobalData.MixedPcd:\r
+                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdKey]:\r
+                            PcdTokenCName = PcdKey[0]\r
+                            MixedPcdFlag = True\r
+                    if MixedPcdFlag and not ModulePcdSet:\r
+                        continue\r
+                #\r
+                # Get PCD default value and their override relationship\r
+                #\r
+                DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))\r
+                DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))\r
+                DscDefaultValBak = DscDefaultValue\r
+                Field = ''\r
+                for (CName, Guid, Field) in self.FdfPcdSet:\r
+                    if CName == PcdTokenCName and Guid == Key:\r
+                        DscDefaultValue = self.FdfPcdSet[(CName, Guid, Field)]\r
+                        break\r
+                if DscDefaultValue != DscDefaultValBak:\r
+                    try:\r
+                        DscDefaultValue = ValueExpressionEx(DscDefaultValue, Pcd.DatumType, self._GuidDict)(True)\r
+                    except BadExpression as DscDefaultValue:\r
+                        EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" %(DscDefaultValue, Pcd.DatumType))\r
 \r
 \r
-                    InfDefaultValue = None\r
-                    \r
-                    PcdValue = DecDefaultValue\r
-                    if DscDefaultValue:\r
-                        PcdValue = DscDefaultValue\r
-                    if ModulePcdSet is not None:\r
-                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:\r
-                            continue\r
-                        InfDefault, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]\r
+                InfDefaultValue = None\r
+\r
+                PcdValue = DecDefaultValue\r
+                if DscDefaultValue:\r
+                    PcdValue = DscDefaultValue\r
+                #The DefaultValue of StructurePcd already be the latest, no need to update.\r
+                if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):\r
+                    Pcd.DefaultValue = PcdValue\r
+                if ModulePcdSet is not None:\r
+                    if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:\r
+                        continue\r
+                    InfDefaultValue, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]\r
+                    #The DefaultValue of StructurePcd already be the latest, no need to update.\r
+                    if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):\r
                         Pcd.DefaultValue = PcdValue\r
                         Pcd.DefaultValue = PcdValue\r
-                        if InfDefault == "":\r
-                            InfDefault = None\r
-\r
-                    BuildOptionMatch = False\r
-                    if GlobalData.BuildOptionPcd:\r
-                        for pcd in GlobalData.BuildOptionPcd:\r
-                            if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]):\r
-                                if pcd[2]:\r
-                                    continue\r
-                                PcdValue = pcd[3]\r
+                    if InfDefaultValue:\r
+                        try:\r
+                            InfDefaultValue = ValueExpressionEx(InfDefaultValue, Pcd.DatumType, self._GuidDict)(True)\r
+                        except BadExpression as InfDefaultValue:\r
+                            EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" % (InfDefaultValue, Pcd.DatumType))\r
+                    if InfDefaultValue == "":\r
+                        InfDefaultValue = None\r
+\r
+                BuildOptionMatch = False\r
+                if GlobalData.BuildOptionPcd:\r
+                    for pcd in GlobalData.BuildOptionPcd:\r
+                        if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]):\r
+                            if pcd[2]:\r
+                                continue\r
+                            PcdValue = pcd[3]\r
+                            #The DefaultValue of StructurePcd already be the latest, no need to update.\r
+                            if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):\r
                                 Pcd.DefaultValue = PcdValue\r
                                 Pcd.DefaultValue = PcdValue\r
-                                BuildOptionMatch = True\r
-                                break\r
+                            BuildOptionMatch = True\r
+                            break\r
 \r
 \r
-                    if First:\r
-                        if ModulePcdSet is None:\r
-                            FileWrite(File, "")\r
-                        FileWrite(File, Key)\r
-                        First = False\r
+                if First:\r
+                    if ModulePcdSet is None:\r
+                        FileWrite(File, "")\r
+                    FileWrite(File, Key)\r
+                    First = False\r
 \r
 \r
 \r
 \r
-                    if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):\r
-                        PcdValueNumber = int(PcdValue.strip(), 0)\r
-                        if DecDefaultValue is None:\r
-                            DecMatch = True\r
-                        else:\r
-                            DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)\r
-                            DecMatch = (DecDefaultValueNumber == PcdValueNumber)\r
+                if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
+                    PcdValueNumber = int(PcdValue.strip(), 0)\r
+                    if DecDefaultValue is None:\r
+                        DecMatch = True\r
+                    else:\r
+                        DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)\r
+                        DecMatch = (DecDefaultValueNumber == PcdValueNumber)\r
 \r
 \r
-                        if InfDefaultValue is None:\r
-                            InfMatch = True\r
-                        else:\r
-                            InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)\r
-                            InfMatch = (InfDefaultValueNumber == PcdValueNumber)\r
+                    if InfDefaultValue is None:\r
+                        InfMatch = True\r
+                    else:\r
+                        InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)\r
+                        InfMatch = (InfDefaultValueNumber == PcdValueNumber)\r
 \r
 \r
-                        if DscDefaultValue is None:\r
-                            DscMatch = True\r
-                        else:\r
-                            DscDefaultValueNumber = int(DscDefaultValue.strip(), 0)\r
-                            DscMatch = (DscDefaultValueNumber == PcdValueNumber)\r
+                    if DscDefaultValue is None:\r
+                        DscMatch = True\r
                     else:\r
                     else:\r
-                        if DecDefaultValue is None:\r
-                            DecMatch = True\r
-                        else:\r
-                            DecMatch = (DecDefaultValue.strip() == PcdValue.strip())\r
+                        DscDefaultValueNumber = int(DscDefaultValue.strip(), 0)\r
+                        DscMatch = (DscDefaultValueNumber == PcdValueNumber)\r
+                else:\r
+                    if DecDefaultValue is None:\r
+                        DecMatch = True\r
+                    else:\r
+                        DecMatch = (DecDefaultValue.strip() == PcdValue.strip())\r
 \r
 \r
-                        if InfDefaultValue is None:\r
-                            InfMatch = True\r
-                        else:\r
-                            InfMatch = (InfDefaultValue.strip() == PcdValue.strip())\r
+                    if InfDefaultValue is None:\r
+                        InfMatch = True\r
+                    else:\r
+                        InfMatch = (InfDefaultValue.strip() == PcdValue.strip())\r
 \r
 \r
-                        if DscDefaultValue is None:\r
-                            DscMatch = True\r
+                    if DscDefaultValue is None:\r
+                        DscMatch = True\r
+                    else:\r
+                        DscMatch = (DscDefaultValue.strip() == PcdValue.strip())\r
+\r
+                IsStructure = False\r
+                if self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):\r
+                    IsStructure = True\r
+                    if TypeName in ('DYNVPD', 'DEXVPD'):\r
+                        SkuInfoList = Pcd.SkuInfoList\r
+                    Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)]\r
+                    Pcd.DatumType = Pcd.StructName\r
+                    if TypeName in ('DYNVPD', 'DEXVPD'):\r
+                        Pcd.SkuInfoList = SkuInfoList\r
+                    if Pcd.PcdValueFromComm or Pcd.PcdFieldValueFromComm:\r
+                        BuildOptionMatch = True\r
+                        DecMatch = False\r
+                    elif Pcd.PcdValueFromFdf or Pcd.PcdFieldValueFromFdf:\r
+                        DscDefaultValue = True\r
+                        DscMatch = True\r
+                        DecMatch = False\r
+                    elif Pcd.SkuOverrideValues:\r
+                        DscOverride = False\r
+                        if Pcd.DefaultFromDSC:\r
+                            DscOverride = True\r
                         else:\r
                         else:\r
-                            DscMatch = (DscDefaultValue.strip() == PcdValue.strip())\r
-\r
-                    IsStructure = False\r
-                    if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd.keys()) and ((Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.gStructurePcd[self.Arch]):\r
-                        IsStructure = True\r
-                        if TypeName in ('DYNVPD', 'DEXVPD'):\r
-                            SkuInfoList = Pcd.SkuInfoList\r
-                        Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)]\r
-                        Pcd.DatumType = Pcd.StructName\r
-                        if TypeName in ('DYNVPD', 'DEXVPD'):\r
-                            Pcd.SkuInfoList = SkuInfoList\r
-                        if Pcd.PcdFieldValueFromComm:\r
-                            BuildOptionMatch = True\r
-                            DecMatch = False\r
-                        elif Pcd.SkuOverrideValues:\r
-                            DscOverride = False\r
-                            if not Pcd.SkuInfoList:\r
-                                OverrideValues = Pcd.SkuOverrideValues\r
-                                if OverrideValues:\r
-                                    Keys = OverrideValues.keys()\r
-                                    Data = OverrideValues[Keys[0]]\r
-                                    Struct = Data.values()[0]\r
-                                    DscOverride = self.ParseStruct(Struct)\r
+                            DictLen = 0\r
+                            for item in Pcd.SkuOverrideValues:\r
+                                DictLen += len(Pcd.SkuOverrideValues[item])\r
+                            if not DictLen:\r
+                                DscOverride = False\r
                             else:\r
                             else:\r
-                                SkuList = sorted(Pcd.SkuInfoList.keys())\r
-                                for Sku in SkuList:\r
-                                    SkuInfo = Pcd.SkuInfoList[Sku]\r
-                                    if TypeName in ('DYNHII', 'DEXHII'):\r
-                                        if SkuInfo.DefaultStoreDict:\r
-                                            DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys())\r
-                                            for DefaultStore in DefaultStoreList:\r
-                                                OverrideValues = Pcd.SkuOverrideValues[Sku]\r
-                                                DscOverride = self.ParseStruct(OverrideValues[DefaultStore])\r
-                                                if DscOverride:\r
-                                                    break\r
-                                    else:\r
-                                        OverrideValues = Pcd.SkuOverrideValues[Sku]\r
-                                        if OverrideValues:\r
-                                            Keys = OverrideValues.keys()\r
-                                            OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]])\r
-                                            DscOverride = self.ParseStruct(OverrideFieldStruct)\r
-                                    if DscOverride:\r
-                                        break\r
-                            if DscOverride:\r
-                                DscMatch = True\r
-                                DecMatch = False\r
-\r
-                    #\r
-                    # Report PCD item according to their override relationship\r
-                    #\r
-                    if DecMatch and InfMatch:\r
-                        self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '  ')\r
-                    elif BuildOptionMatch:\r
-                        self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*B')\r
+                                if not Pcd.SkuInfoList:\r
+                                    OverrideValues = Pcd.SkuOverrideValues\r
+                                    if OverrideValues:\r
+                                        for Data in OverrideValues.values():\r
+                                            Struct = list(Data.values())\r
+                                            if Struct:\r
+                                                DscOverride = self.ParseStruct(Struct[0])\r
+                                                break\r
+                                else:\r
+                                    SkuList = sorted(Pcd.SkuInfoList.keys())\r
+                                    for Sku in SkuList:\r
+                                        SkuInfo = Pcd.SkuInfoList[Sku]\r
+                                        if TypeName in ('DYNHII', 'DEXHII'):\r
+                                            if SkuInfo.DefaultStoreDict:\r
+                                                DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys())\r
+                                                for DefaultStore in DefaultStoreList:\r
+                                                    OverrideValues = Pcd.SkuOverrideValues[Sku]\r
+                                                    DscOverride = self.ParseStruct(OverrideValues[DefaultStore])\r
+                                                    if DscOverride:\r
+                                                        break\r
+                                        else:\r
+                                            OverrideValues = Pcd.SkuOverrideValues[Sku]\r
+                                            if OverrideValues:\r
+                                                Keys = list(OverrideValues.keys())\r
+                                                OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]])\r
+                                                DscOverride = self.ParseStruct(OverrideFieldStruct)\r
+                                        if DscOverride:\r
+                                            break\r
+                        if DscOverride:\r
+                            DscDefaultValue = True\r
+                            DscMatch = True\r
+                            DecMatch = False\r
+                        else:\r
+                            DecMatch = True\r
                     else:\r
                     else:\r
-                        if DscMatch:\r
-                            if (Pcd.TokenCName, Key) in self.FdfPcdSet:\r
-                                self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')\r
-                            else:\r
-                                self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')\r
+                        DscDefaultValue = True\r
+                        DscMatch = True\r
+                        DecMatch = False\r
+\r
+                #\r
+                # Report PCD item according to their override relationship\r
+                #\r
+                if Pcd.DatumType == 'BOOLEAN':\r
+                    if DscDefaultValue:\r
+                        DscDefaultValue = str(int(DscDefaultValue, 0))\r
+                    if DecDefaultValue:\r
+                        DecDefaultValue = str(int(DecDefaultValue, 0))\r
+                    if InfDefaultValue:\r
+                        InfDefaultValue = str(int(InfDefaultValue, 0))\r
+                    if Pcd.DefaultValue:\r
+                        Pcd.DefaultValue = str(int(Pcd.DefaultValue, 0))\r
+                if DecMatch:\r
+                    self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '  ')\r
+                elif InfDefaultValue and InfMatch:\r
+                    self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')\r
+                elif BuildOptionMatch:\r
+                    self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*B')\r
+                else:\r
+                    if DscDefaultValue and DscMatch:\r
+                        if (Pcd.TokenCName, Key, Field) in self.FdfPcdSet:\r
+                            self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F')\r
                         else:\r
                         else:\r
-                            self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')\r
+                            self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P')\r
+                    else:\r
+                        self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')\r
 \r
 \r
-                    if ModulePcdSet is None:\r
-                        if IsStructure:\r
-                            continue\r
-                        if not TypeName in ('PATCH', 'FLAG', 'FIXED'):\r
-                            continue\r
-                        if not BuildOptionMatch:\r
-                            ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {})\r
-                            for ModulePath in ModuleOverride:\r
-                                ModuleDefault = ModuleOverride[ModulePath]\r
-                                if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):\r
-                                    ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0)\r
-                                    Match = (ModulePcdDefaultValueNumber == PcdValueNumber)\r
-                                else:\r
-                                    Match = (ModuleDefault.strip() == PcdValue.strip())\r
-                                if Match:\r
-                                    continue\r
-                                IsByteArray, ArrayList = ByteArrayForamt(ModuleDefault.strip())\r
-                                if IsByteArray:\r
-                                    FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, '{'))\r
-                                    for Array in ArrayList:\r
-                                        FileWrite(File, '%s' % (Array))\r
-                                else:\r
-                                    FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip()))\r
+                if ModulePcdSet is None:\r
+                    if IsStructure:\r
+                        continue\r
+                    if not TypeName in ('PATCH', 'FLAG', 'FIXED'):\r
+                        continue\r
+                    if not BuildOptionMatch:\r
+                        ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {})\r
+                        for ModulePath in ModuleOverride:\r
+                            ModuleDefault = ModuleOverride[ModulePath]\r
+                            if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
+                                ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0)\r
+                                Match = (ModulePcdDefaultValueNumber == PcdValueNumber)\r
+                                if Pcd.DatumType == 'BOOLEAN':\r
+                                    ModuleDefault = str(ModulePcdDefaultValueNumber)\r
+                            else:\r
+                                Match = (ModuleDefault.strip() == PcdValue.strip())\r
+                            if Match:\r
+                                continue\r
+                            IsByteArray, ArrayList = ByteArrayForamt(ModuleDefault.strip())\r
+                            if IsByteArray:\r
+                                FileWrite(File, ' *M     %-*s = %s' % (self.MaxLen + 15, ModulePath, '{'))\r
+                                for Array in ArrayList:\r
+                                    FileWrite(File, Array)\r
+                            else:\r
+                                Value =  ModuleDefault.strip()\r
+                                if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                                    if Value.startswith(('0x', '0X')):\r
+                                        Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                                    else:\r
+                                        Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
+                                FileWrite(File, ' *M     %-*s = %s' % (self.MaxLen + 15, ModulePath, Value))\r
 \r
         if ModulePcdSet is None:\r
             FileWrite(File, gSectionEnd)\r
 \r
         if ModulePcdSet is None:\r
             FileWrite(File, gSectionEnd)\r
@@ -1135,8 +1215,13 @@ class PcdReport(object):
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', "{"))\r
                 for Array in ArrayList:\r
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', "{"))\r
                 for Array in ArrayList:\r
-                    FileWrite(File, '%s' % (Array))\r
+                    FileWrite(File, Array)\r
             else:\r
             else:\r
+                if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                    if Value.startswith(('0x', '0X')):\r
+                        Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                    else:\r
+                        Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', Value))\r
         if not InfMatch and InfDefaultValue is not None:\r
             Value = InfDefaultValue.strip()\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', Value))\r
         if not InfMatch and InfDefaultValue is not None:\r
             Value = InfDefaultValue.strip()\r
@@ -1144,8 +1229,13 @@ class PcdReport(object):
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', "{"))\r
                 for Array in ArrayList:\r
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', "{"))\r
                 for Array in ArrayList:\r
-                    FileWrite(File, '%s' % (Array))\r
+                    FileWrite(File, Array)\r
             else:\r
             else:\r
+                if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                    if Value.startswith(('0x', '0X')):\r
+                        Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                    else:\r
+                        Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', Value))\r
 \r
         if not DecMatch and DecDefaultValue is not None:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', Value))\r
 \r
         if not DecMatch and DecDefaultValue is not None:\r
@@ -1154,8 +1244,13 @@ class PcdReport(object):
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', "{"))\r
                 for Array in ArrayList:\r
             if IsByteArray:\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', "{"))\r
                 for Array in ArrayList:\r
-                    FileWrite(File, '%s' % (Array))\r
+                    FileWrite(File, Array)\r
             else:\r
             else:\r
+                if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                    if Value.startswith(('0x', '0X')):\r
+                        Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                    else:\r
+                        Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', Value))\r
             if IsStructure:\r
                 self.PrintStructureInfo(File, Pcd.DefaultValues)\r
                 FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', Value))\r
             if IsStructure:\r
                 self.PrintStructureInfo(File, Pcd.DefaultValues)\r
@@ -1169,16 +1264,27 @@ class PcdReport(object):
             if IsByteArray:\r
                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))\r
                 for Array in ArrayList:\r
             if IsByteArray:\r
                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))\r
                 for Array in ArrayList:\r
-                    FileWrite(File, '%s' % (Array))\r
+                    FileWrite(File, Array)\r
             else:\r
             else:\r
+                if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                    if Value.startswith(('0x', '0X')):\r
+                        Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                    else:\r
+                        Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
             if IsStructure:\r
                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
             if IsStructure:\r
+                FiledOverrideFlag = False\r
                 OverrideValues = Pcd.SkuOverrideValues\r
                 if OverrideValues:\r
                 OverrideValues = Pcd.SkuOverrideValues\r
                 if OverrideValues:\r
-                    Keys = OverrideValues.keys()\r
-                    Data = OverrideValues[Keys[0]]\r
-                    Struct = Data.values()[0]\r
-                    OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct)\r
+                    for Data in OverrideValues.values():\r
+                        Struct = list(Data.values())\r
+                        if Struct:\r
+                            OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct[0])\r
+                            self.PrintStructureInfo(File, OverrideFieldStruct)\r
+                            FiledOverrideFlag = True\r
+                            break\r
+                if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):\r
+                    OverrideFieldStruct = self.OverrideFieldValue(Pcd, {})\r
                     self.PrintStructureInfo(File, OverrideFieldStruct)\r
             self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
         else:\r
                     self.PrintStructureInfo(File, OverrideFieldStruct)\r
             self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
         else:\r
@@ -1193,6 +1299,8 @@ class PcdReport(object):
                         for DefaultStore in DefaultStoreList:\r
                             Value = SkuInfo.DefaultStoreDict[DefaultStore]\r
                             IsByteArray, ArrayList = ByteArrayForamt(Value)\r
                         for DefaultStore in DefaultStoreList:\r
                             Value = SkuInfo.DefaultStoreDict[DefaultStore]\r
                             IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+                            if Pcd.DatumType == 'BOOLEAN':\r
+                                Value = str(int(Value, 0))\r
                             if FirstPrint:\r
                                 FirstPrint = False\r
                                 if IsByteArray:\r
                             if FirstPrint:\r
                                 FirstPrint = False\r
                                 if IsByteArray:\r
@@ -1205,8 +1313,13 @@ class PcdReport(object):
                                     else:\r
                                         FileWrite(File, ' %-*s   : %6s %10s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
                                     for Array in ArrayList:\r
                                     else:\r
                                         FileWrite(File, ' %-*s   : %6s %10s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
                                     for Array in ArrayList:\r
-                                        FileWrite(File, '%s' % (Array))\r
+                                        FileWrite(File, Array)\r
                                 else:\r
                                 else:\r
+                                    if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                                        if Value.startswith(('0x', '0X')):\r
+                                            Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                                        else:\r
+                                            Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                                     if self.DefaultStoreSingle and self.SkuSingle:\r
                                         FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
                                     elif self.DefaultStoreSingle and not self.SkuSingle:\r
                                     if self.DefaultStoreSingle and self.SkuSingle:\r
                                         FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
                                     elif self.DefaultStoreSingle and not self.SkuSingle:\r
@@ -1226,8 +1339,13 @@ class PcdReport(object):
                                     else:\r
                                         FileWrite(File, ' %-*s   : %6s %10s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
                                     for Array in ArrayList:\r
                                     else:\r
                                         FileWrite(File, ' %-*s   : %6s %10s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
                                     for Array in ArrayList:\r
-                                        FileWrite(File, '%s' % (Array))\r
+                                        FileWrite(File, Array)\r
                                 else:\r
                                 else:\r
+                                    if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                                        if Value.startswith(('0x', '0X')):\r
+                                            Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                                        else:\r
+                                            Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                                     if self.DefaultStoreSingle and self.SkuSingle:\r
                                         FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')',  Value))\r
                                     elif self.DefaultStoreSingle and not self.SkuSingle:\r
                                     if self.DefaultStoreSingle and self.SkuSingle:\r
                                         FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')',  Value))\r
                                     elif self.DefaultStoreSingle and not self.SkuSingle:\r
@@ -1245,6 +1363,8 @@ class PcdReport(object):
                 else:\r
                     Value = SkuInfo.DefaultValue\r
                     IsByteArray, ArrayList = ByteArrayForamt(Value)\r
                 else:\r
                     Value = SkuInfo.DefaultValue\r
                     IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+                    if Pcd.DatumType == 'BOOLEAN':\r
+                        Value = str(int(Value, 0))\r
                     if FirstPrint:\r
                         FirstPrint = False\r
                         if IsByteArray:\r
                     if FirstPrint:\r
                         FirstPrint = False\r
                         if IsByteArray:\r
@@ -1253,8 +1373,13 @@ class PcdReport(object):
                             else:\r
                                 FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{"))\r
                             for Array in ArrayList:\r
                             else:\r
                                 FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{"))\r
                             for Array in ArrayList:\r
-                                FileWrite(File, '%s' % (Array))\r
+                                FileWrite(File, Array)\r
                         else:\r
                         else:\r
+                            if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                                if Value.startswith(('0x', '0X')):\r
+                                    Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                                else:\r
+                                    Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                             if self.SkuSingle:\r
                                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
                             else:\r
                             if self.SkuSingle:\r
                                 FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value))\r
                             else:\r
@@ -1262,24 +1387,37 @@ class PcdReport(object):
                     else:\r
                         if IsByteArray:\r
                             if self.SkuSingle:\r
                     else:\r
                         if IsByteArray:\r
                             if self.SkuSingle:\r
-                                FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', "{"))\r
+                                FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', "{"))\r
                             else:\r
                             else:\r
-                                FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{"))\r
+                                FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{"))\r
                             for Array in ArrayList:\r
                             for Array in ArrayList:\r
-                                FileWrite(File, '%s' % (Array))\r
+                                FileWrite(File, Array)\r
                         else:\r
                         else:\r
+                            if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+                                if Value.startswith(('0x', '0X')):\r
+                                    Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+                                else:\r
+                                    Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
                             if self.SkuSingle:\r
                             if self.SkuSingle:\r
-                                FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', Value))\r
+                                FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', Value))\r
                             else:\r
                             else:\r
-                                FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value))\r
+                                FileWrite(File, ' %-*s   : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value))\r
                     if TypeName in ('DYNVPD', 'DEXVPD'):\r
                         FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset))\r
                     if TypeName in ('DYNVPD', 'DEXVPD'):\r
                         FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset))\r
+                        VPDPcdItem = (Pcd.TokenSpaceGuidCName + '.' + PcdTokenCName, SkuIdName, SkuInfo.VpdOffset, Pcd.MaxDatumSize, SkuInfo.DefaultValue)\r
+                        if VPDPcdItem not in VPDPcdList:\r
+                            VPDPcdList.append(VPDPcdItem)\r
                     if IsStructure:\r
                     if IsStructure:\r
+                        FiledOverrideFlag = False\r
                         OverrideValues = Pcd.SkuOverrideValues[Sku]\r
                         if OverrideValues:\r
                             Keys = OverrideValues.keys()\r
                             OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]])\r
                             self.PrintStructureInfo(File, OverrideFieldStruct)\r
                         OverrideValues = Pcd.SkuOverrideValues[Sku]\r
                         if OverrideValues:\r
                             Keys = OverrideValues.keys()\r
                             OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]])\r
                             self.PrintStructureInfo(File, OverrideFieldStruct)\r
+                            FiledOverrideFlag = True\r
+                        if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):\r
+                            OverrideFieldStruct = self.OverrideFieldValue(Pcd, {})\r
+                            self.PrintStructureInfo(File, OverrideFieldStruct)\r
                     self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
 \r
     def OverrideFieldValue(self, Pcd, OverrideStruct):\r
                     self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
 \r
     def OverrideFieldValue(self, Pcd, OverrideStruct):\r
@@ -1288,15 +1426,24 @@ class PcdReport(object):
             for Key, Values in OverrideStruct.items():\r
                 if Values[1] and Values[1].endswith('.dsc'):\r
                     OverrideFieldStruct[Key] = Values\r
             for Key, Values in OverrideStruct.items():\r
                 if Values[1] and Values[1].endswith('.dsc'):\r
                     OverrideFieldStruct[Key] = Values\r
+        if Pcd.PcdFieldValueFromFdf:\r
+            for Key, Values in Pcd.PcdFieldValueFromFdf.items():\r
+                if Key in OverrideFieldStruct and Values[0] == OverrideFieldStruct[Key][0]:\r
+                    continue\r
+                OverrideFieldStruct[Key] = Values\r
         if Pcd.PcdFieldValueFromComm:\r
             for Key, Values in Pcd.PcdFieldValueFromComm.items():\r
         if Pcd.PcdFieldValueFromComm:\r
             for Key, Values in Pcd.PcdFieldValueFromComm.items():\r
+                if Key in OverrideFieldStruct and Values[0] == OverrideFieldStruct[Key][0]:\r
+                    continue\r
                 OverrideFieldStruct[Key] = Values\r
         return OverrideFieldStruct\r
 \r
     def PrintStructureInfo(self, File, Struct):\r
                 OverrideFieldStruct[Key] = Values\r
         return OverrideFieldStruct\r
 \r
     def PrintStructureInfo(self, File, Struct):\r
-        for Key, Value in Struct.items():\r
+        for Key, Value in sorted(Struct.items(), key=lambda x: x[0]):\r
             if Value[1] and 'build command options' in Value[1]:\r
                 FileWrite(File, '    *B  %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0]))\r
             if Value[1] and 'build command options' in Value[1]:\r
                 FileWrite(File, '    *B  %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0]))\r
+            elif Value[1] and Value[1].endswith('.fdf'):\r
+                FileWrite(File, '    *F  %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0]))\r
             else:\r
                 FileWrite(File, '        %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0]))\r
 \r
             else:\r
                 FileWrite(File, '        %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0]))\r
 \r
@@ -1330,6 +1477,12 @@ class PcdReport(object):
             else:\r
                 return value\r
 \r
             else:\r
                 return value\r
 \r
+    def IsStructurePcd(self, PcdToken, PcdTokenSpaceGuid):\r
+        if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd) and ((PcdToken, PcdTokenSpaceGuid) in GlobalData.gStructurePcd[self.Arch]):\r
+            return True\r
+        else:\r
+            return False\r
+\r
 ##\r
 # Reports platform and module Prediction information\r
 #\r
 ##\r
 # Reports platform and module Prediction information\r
 #\r
@@ -1368,7 +1521,7 @@ class PredictionReport(object):
                 # their source code to find PPI/Protocol produce or consume\r
                 # information.\r
                 #\r
                 # their source code to find PPI/Protocol produce or consume\r
                 # information.\r
                 #\r
-                if Module.ModuleType == "BASE":\r
+                if Module.ModuleType == SUP_MODULE_BASE:\r
                     continue\r
                 #\r
                 # Add module referenced source files\r
                     continue\r
                 #\r
                 # Add module referenced source files\r
@@ -1411,7 +1564,7 @@ class PredictionReport(object):
         if Wa.FdfProfile:\r
             for Fd in Wa.FdfProfile.FdDict:\r
                 for FdRegion in Wa.FdfProfile.FdDict[Fd].RegionList:\r
         if Wa.FdfProfile:\r
             for Fd in Wa.FdfProfile.FdDict:\r
                 for FdRegion in Wa.FdfProfile.FdDict[Fd].RegionList:\r
-                    if FdRegion.RegionType != "FV":\r
+                    if FdRegion.RegionType != BINARY_FILE_TYPE_FV:\r
                         continue\r
                     for FvName in FdRegion.RegionDataList:\r
                         if FvName in self._FvList:\r
                         continue\r
                     for FvName in FdRegion.RegionDataList:\r
                         if FvName in self._FvList:\r
@@ -1494,7 +1647,7 @@ class PredictionReport(object):
         TempFile.close()\r
 \r
         try:\r
         TempFile.close()\r
 \r
         try:\r
-            from Eot.Eot import Eot\r
+            from Eot.EotMain import Eot\r
 \r
             #\r
             # Invoke EOT tool and echo its runtime performance\r
 \r
             #\r
             # Invoke EOT tool and echo its runtime performance\r
@@ -1505,7 +1658,7 @@ class PredictionReport(object):
             EotEndTime = time.time()\r
             EotDuration = time.strftime("%H:%M:%S", time.gmtime(int(round(EotEndTime - EotStartTime))))\r
             EdkLogger.quiet("EOT run time: %s\n" % EotDuration)\r
             EotEndTime = time.time()\r
             EotDuration = time.strftime("%H:%M:%S", time.gmtime(int(round(EotEndTime - EotStartTime))))\r
             EdkLogger.quiet("EOT run time: %s\n" % EotDuration)\r
-            \r
+\r
             #\r
             # Parse the output of EOT tool\r
             #\r
             #\r
             # Parse the output of EOT tool\r
             #\r
@@ -1687,7 +1840,7 @@ class FdRegionReport(object):
         # If the input FdRegion is not a firmware volume,\r
         # we are done.\r
         #\r
         # If the input FdRegion is not a firmware volume,\r
         # we are done.\r
         #\r
-        if self.Type != "FV":\r
+        if self.Type != BINARY_FILE_TYPE_FV:\r
             return\r
 \r
         #\r
             return\r
 \r
         #\r
@@ -1703,7 +1856,7 @@ class FdRegionReport(object):
         PlatformPcds = {}\r
         #\r
         # Collect PCDs declared in DEC files.\r
         PlatformPcds = {}\r
         #\r
         # Collect PCDs declared in DEC files.\r
-        #        \r
+        #\r
         for Pa in Wa.AutoGenObjectList:\r
             for Package in Pa.PackageList:\r
                 for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
         for Pa in Wa.AutoGenObjectList:\r
             for Package in Pa.PackageList:\r
                 for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
@@ -1781,7 +1934,7 @@ class FdRegionReport(object):
         FileWrite(File, "Type:               %s" % Type)\r
         FileWrite(File, "Base Address:       0x%X" % BaseAddress)\r
 \r
         FileWrite(File, "Type:               %s" % Type)\r
         FileWrite(File, "Base Address:       0x%X" % BaseAddress)\r
 \r
-        if self.Type == "FV":\r
+        if self.Type == BINARY_FILE_TYPE_FV:\r
             FvTotalSize = 0\r
             FvTakenSize = 0\r
             FvFreeSize  = 0\r
             FvTotalSize = 0\r
             FvTakenSize = 0\r
             FvFreeSize  = 0\r
@@ -1822,8 +1975,7 @@ class FdRegionReport(object):
                 for Match in gOffsetGuidPattern.finditer(FvReport):\r
                     Guid = Match.group(2).upper()\r
                     OffsetInfo[Match.group(1)] = self._GuidsDb.get(Guid, Guid)\r
                 for Match in gOffsetGuidPattern.finditer(FvReport):\r
                     Guid = Match.group(2).upper()\r
                     OffsetInfo[Match.group(1)] = self._GuidsDb.get(Guid, Guid)\r
-                OffsetList = OffsetInfo.keys()\r
-                OffsetList.sort()\r
+                OffsetList = sorted(OffsetInfo.keys())\r
                 for Offset in OffsetList:\r
                     FileWrite (File, "%s %s" % (Offset, OffsetInfo[Offset]))\r
             except IOError:\r
                 for Offset in OffsetList:\r
                     FileWrite (File, "%s %s" % (Offset, OffsetInfo[Offset]))\r
             except IOError:\r
@@ -1844,7 +1996,7 @@ class FdRegionReport(object):
         if (len(self.FvList) > 0):\r
             for FvItem in self.FvList:\r
                 Info = self.FvInfo[FvItem]\r
         if (len(self.FvList) > 0):\r
             for FvItem in self.FvList:\r
                 Info = self.FvInfo[FvItem]\r
-                self._GenerateReport(File, Info[0], "FV", Info[1], Info[2], FvItem)\r
+                self._GenerateReport(File, Info[0], TAB_FV_DIRECTORY, Info[1], Info[2], FvItem)\r
         else:\r
             self._GenerateReport(File, "FD Region", self.Type, self.BaseAddress, self.Size)\r
 \r
         else:\r
             self._GenerateReport(File, "FD Region", self.Type, self.BaseAddress, self.Size)\r
 \r
@@ -1870,36 +2022,15 @@ class FdReport(object):
         self.BaseAddress = Fd.BaseAddress\r
         self.Size = Fd.Size\r
         self.FdRegionList = [FdRegionReport(FdRegion, Wa) for FdRegion in Fd.RegionList]\r
         self.BaseAddress = Fd.BaseAddress\r
         self.Size = Fd.Size\r
         self.FdRegionList = [FdRegionReport(FdRegion, Wa) for FdRegion in Fd.RegionList]\r
-        self.FvPath = os.path.join(Wa.BuildDir, "FV")\r
-        self.VpdFilePath = os.path.join(self.FvPath, "%s.map" % Wa.Platform.VpdToolGuid)\r
+        self.FvPath = os.path.join(Wa.BuildDir, TAB_FV_DIRECTORY)\r
         self.VPDBaseAddress = 0\r
         self.VPDSize = 0\r
         self.VPDBaseAddress = 0\r
         self.VPDSize = 0\r
-        self.VPDInfoList = []\r
         for index, FdRegion in enumerate(Fd.RegionList):\r
             if str(FdRegion.RegionType) is 'FILE' and Wa.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r
                 self.VPDBaseAddress = self.FdRegionList[index].BaseAddress\r
                 self.VPDSize = self.FdRegionList[index].Size\r
                 break\r
 \r
         for index, FdRegion in enumerate(Fd.RegionList):\r
             if str(FdRegion.RegionType) is 'FILE' and Wa.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r
                 self.VPDBaseAddress = self.FdRegionList[index].BaseAddress\r
                 self.VPDSize = self.FdRegionList[index].Size\r
                 break\r
 \r
-        if os.path.isfile(self.VpdFilePath):\r
-            fd = open(self.VpdFilePath, "r")\r
-            Lines = fd.readlines()\r
-            for Line in Lines:\r
-                Line = Line.strip()\r
-                if len(Line) == 0 or Line.startswith("#"):\r
-                    continue\r
-                try:\r
-                    PcdName, SkuId, Offset, Size, Value = Line.split("#")[0].split("|")\r
-                    PcdName, SkuId, Offset, Size, Value = PcdName.strip(), SkuId.strip(), Offset.strip(), Size.strip(), Value.strip()\r
-                    if Offset.lower().startswith('0x'):\r
-                        Offset = '0x%08X' % (int(Offset, 16) + self.VPDBaseAddress)\r
-                    else:\r
-                        Offset = '0x%08X' % (int(Offset, 10) + self.VPDBaseAddress)\r
-                    self.VPDInfoList.append("%s | %s | %s | %s | %s" % (PcdName, SkuId, Offset, Size, Value))\r
-                except:\r
-                    EdkLogger.error("BuildReport", CODE_ERROR, "Fail to parse VPD information file %s" % self.VpdFilePath)\r
-            fd.close()\r
-\r
     ##\r
     # Generate report for the firmware device.\r
     #\r
     ##\r
     # Generate report for the firmware device.\r
     #\r
@@ -1919,23 +2050,26 @@ class FdReport(object):
             for FdRegionItem in self.FdRegionList:\r
                 FdRegionItem.GenerateReport(File)\r
 \r
             for FdRegionItem in self.FdRegionList:\r
                 FdRegionItem.GenerateReport(File)\r
 \r
-        if len(self.VPDInfoList) > 0:\r
+        if VPDPcdList:\r
+            VPDPcdList.sort(key=lambda x: int(x[2], 0))\r
             FileWrite(File, gSubSectionStart)\r
             FileWrite(File, "FD VPD Region")\r
             FileWrite(File, "Base Address:       0x%X" % self.VPDBaseAddress)\r
             FileWrite(File, "Size:               0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0))\r
             FileWrite(File, gSubSectionSep)\r
             FileWrite(File, gSubSectionStart)\r
             FileWrite(File, "FD VPD Region")\r
             FileWrite(File, "Base Address:       0x%X" % self.VPDBaseAddress)\r
             FileWrite(File, "Size:               0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0))\r
             FileWrite(File, gSubSectionSep)\r
-            for item in self.VPDInfoList:\r
-                ValueList = item.split('|')\r
-                Value = ValueList[-1].strip()\r
-                IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+            for item in VPDPcdList:\r
+                # Add BaseAddress for offset\r
+                Offset = '0x%08X' % (int(item[2], 16) + self.VPDBaseAddress)\r
+                IsByteArray, ArrayList = ByteArrayForamt(item[-1])\r
+                Skuinfo = item[1]\r
+                if len(GlobalData.gSkuids) == 1 :\r
+                    Skuinfo = GlobalData.gSkuids[0]\r
                 if IsByteArray:\r
                 if IsByteArray:\r
-                    ValueList[-1] = ' {'\r
-                    FileWrite(File, '|'.join(ValueList))\r
+                    FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], '{'))\r
                     for Array in ArrayList:\r
                     for Array in ArrayList:\r
-                        FileWrite(File, '%s' % (Array))\r
+                        FileWrite(File, Array)\r
                 else:\r
                 else:\r
-                    FileWrite(File, item)\r
+                    FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], item[-1]))\r
             FileWrite(File, gSubSectionEnd)\r
         FileWrite(File, gSectionEnd)\r
 \r
             FileWrite(File, gSubSectionEnd)\r
         FileWrite(File, gSectionEnd)\r
 \r
@@ -1984,7 +2118,7 @@ class PlatformReport(object):
         self.DepexParser = None\r
         if "DEPEX" in ReportType:\r
             self.DepexParser = DepexParser(Wa)\r
         self.DepexParser = None\r
         if "DEPEX" in ReportType:\r
             self.DepexParser = DepexParser(Wa)\r
-            \r
+\r
         self.ModuleReportList = []\r
         if MaList is not None:\r
             self._IsModuleBuild = True\r
         self.ModuleReportList = []\r
         if MaList is not None:\r
             self._IsModuleBuild = True\r
@@ -2059,7 +2193,7 @@ class PlatformReport(object):
         if not self._IsModuleBuild:\r
             if "PCD" in ReportType:\r
                 self.PcdReport.GenerateReport(File, None)\r
         if not self._IsModuleBuild:\r
             if "PCD" in ReportType:\r
                 self.PcdReport.GenerateReport(File, None)\r
-    \r
+\r
             if "FLASH" in ReportType:\r
                 for FdReportListItem in self.FdReportList:\r
                     FdReportListItem.GenerateReport(File)\r
             if "FLASH" in ReportType:\r
                 for FdReportListItem in self.FdReportList:\r
                     FdReportListItem.GenerateReport(File)\r
@@ -2093,7 +2227,7 @@ class BuildReport(object):
         if ReportFile:\r
             self.ReportList = []\r
             self.ReportType = []\r
         if ReportFile:\r
             self.ReportList = []\r
             self.ReportType = []\r
-            if ReportType: \r
+            if ReportType:\r
                 for ReportTypeItem in ReportType:\r
                     if ReportTypeItem not in self.ReportType:\r
                         self.ReportType.append(ReportTypeItem)\r
                 for ReportTypeItem in ReportType:\r
                     if ReportTypeItem not in self.ReportType:\r
                         self.ReportType.append(ReportTypeItem)\r
@@ -2127,7 +2261,7 @@ class BuildReport(object):
     def GenerateReport(self, BuildDuration, AutoGenTime, MakeTime, GenFdsTime):\r
         if self.ReportFile:\r
             try:\r
     def GenerateReport(self, BuildDuration, AutoGenTime, MakeTime, GenFdsTime):\r
         if self.ReportFile:\r
             try:\r
-                File = StringIO('')\r
+                File = BytesIO('')\r
                 for (Wa, MaList) in self.ReportList:\r
                     PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, self.ReportType)\r
                 Content = FileLinesSplit(File.getvalue(), gLineMaxLength)\r
                 for (Wa, MaList) in self.ReportList:\r
                     PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, self.ReportType)\r
                 Content = FileLinesSplit(File.getvalue(), gLineMaxLength)\r
@@ -2139,7 +2273,7 @@ class BuildReport(object):
                 EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False)\r
                 EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc()))\r
             File.close()\r
                 EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False)\r
                 EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc()))\r
             File.close()\r
-            \r
+\r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
     pass\r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
     pass\r