]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/build/BuildReport.py
BaseTools/EOT: Change to call a program instead of calling Python API.
[mirror_edk2.git] / BaseTools / Source / Python / build / BuildReport.py
index c4647d068a6b91ed336cb9d078b3599e657f7706..14143b3396c05e1cba888db05dccf5766d51bb77 100644 (file)
@@ -28,7 +28,7 @@ import hashlib
 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
@@ -42,26 +42,11 @@ 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
-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
 \r
-gComponentType2ModuleType = {\r
-    "LIBRARY"               :   "BASE",\r
-    "SECURITY_CORE"         :   "SEC",\r
-    "PEI_CORE"              :   "PEI_CORE",\r
-    "COMBINED_PEIM_DRIVER"  :   "PEIM",\r
-    "PIC_PEIM"              :   "PEIM",\r
-    "RELOCATABLE_PEIM"      :   "PEIM",\r
-    "PE32_PEIM"             :   "PEIM",\r
-    "BS_DRIVER"             :   "DXE_DRIVER",\r
-    "RT_DRIVER"             :   "DXE_RUNTIME_DRIVER",\r
-    "SAL_RT_DRIVER"         :   "DXE_SAL_DRIVER",\r
-    "APPLICATION"           :   "UEFI_APPLICATION",\r
-    "LOGO"                  :   "BASE",\r
-}\r
-\r
 ## Pattern to extract contents in EDK DXS files\r
 gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)\r
 \r
@@ -109,33 +94,33 @@ gSubSectionSep = "-" * gLineMaxLength
 \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
-  '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
-  '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
@@ -223,7 +208,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
-        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
@@ -235,7 +220,7 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
 \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
@@ -260,12 +245,12 @@ def FileLinesSplit(Content=None, MaxLength=None):
             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
-    \r
-    \r
-    \r
+\r
+\r
+\r
 ##\r
 # Parse binary dependency expression section\r
 #\r
@@ -295,10 +280,15 @@ class DepexParser(object):
                 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
+    #\r
     # This function parses the binary dependency expression file and translate it\r
     # to the instruction list.\r
     #\r
@@ -313,14 +303,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
-                            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
-    \r
+\r
 ##\r
 # Reports library information\r
 #\r
@@ -422,11 +412,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
-            ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
+            ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "")\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
-      \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
@@ -435,7 +425,7 @@ class DepexReport(object):
                     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
@@ -472,16 +462,16 @@ class DepexReport(object):
                 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, "%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, "%s" % self.Depex)\r
+            FileWrite(File, self.Depex)\r
         FileWrite(File, gSubSectionEnd)\r
 \r
 ##\r
@@ -587,11 +577,11 @@ class ModuleReport(object):
         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
-            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
@@ -664,7 +654,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
-                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
@@ -799,7 +789,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
-                    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
@@ -807,7 +797,7 @@ class PcdReport(object):
                 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
@@ -819,16 +809,19 @@ class PcdReport(object):
                 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
+                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
@@ -895,7 +888,17 @@ class PcdReport(object):
             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
@@ -942,190 +945,245 @@ class PcdReport(object):
                 FileWrite(File, gSubSectionStart)\r
                 FileWrite(File, TAB_BRG_PCD)\r
                 FileWrite(File, gSubSectionSep)\r
-\r
+        AllPcdDict = {}\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
-            for Type in PcdDict[Key]:\r
+            for PcdTokenCName, Type in sorted(AllPcdDict[Key]):\r
                 #\r
                 # Group PCD by their usage type\r
                 #\r
+                Pcd = AllPcdDict[Key][(PcdTokenCName, 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
-                    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
-                        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
-                                BuildOptionMatch = True\r
-                                break\r
+                            BuildOptionMatch = True\r
+                            break\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
-                    if Pcd.DatumType in TAB_PCD_CLEAN_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
+                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
-                        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
-                        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
-                        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
-                        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
-                        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.PcdFieldValueFromComm:\r
+                        BuildOptionMatch = True\r
+                        DecMatch = False\r
+                    elif Pcd.SkuOverrideValues:\r
+                        DscOverride = False\r
+                        if Pcd.DefaultFromDSC:\r
+                            DscOverride = True\r
                         else:\r
-                            DscMatch = (DscDefaultValue.strip() == PcdValue.strip())\r
-\r
-                    IsStructure = False\r
-                    if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd) 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
-                                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
+                                        Keys = list(OverrideValues.keys())\r
+                                        Data = OverrideValues[Keys[0]]\r
+                                        Struct = list(Data.values())\r
+                                        DscOverride = self.ParseStruct(Struct[0])\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
-                        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
-                            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
-                    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 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
-                                    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 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
@@ -1149,8 +1207,13 @@ class PcdReport(object):
             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
+                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
@@ -1158,8 +1221,13 @@ class PcdReport(object):
             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
+                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
@@ -1168,8 +1236,13 @@ class PcdReport(object):
             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
+                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
@@ -1183,17 +1256,23 @@ 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
-                    FileWrite(File, '%s' % (Array))\r
+                    FileWrite(File, Array)\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
                 OverrideValues = Pcd.SkuOverrideValues\r
                 if OverrideValues:\r
-                    Keys = OverrideValues.keys()\r
+                    Keys = list(OverrideValues.keys())\r
                     Data = OverrideValues[Keys[0]]\r
-                    Struct = Data.values()[0]\r
-                    OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct)\r
-                    self.PrintStructureInfo(File, OverrideFieldStruct)\r
+                    Struct = list(Data.values())\r
+                    if Struct:\r
+                        OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct[0])\r
+                        self.PrintStructureInfo(File, OverrideFieldStruct)\r
             self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
         else:\r
             FirstPrint = True\r
@@ -1207,6 +1286,8 @@ class PcdReport(object):
                         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
@@ -1219,8 +1300,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
-                                        FileWrite(File, '%s' % (Array))\r
+                                        FileWrite(File, Array)\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
@@ -1240,8 +1326,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
-                                        FileWrite(File, '%s' % (Array))\r
+                                        FileWrite(File, Array)\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
@@ -1259,6 +1350,8 @@ class PcdReport(object):
                 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
@@ -1267,8 +1360,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
-                                FileWrite(File, '%s' % (Array))\r
+                                FileWrite(File, Array)\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
@@ -1276,16 +1374,21 @@ class PcdReport(object):
                     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
-                                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
-                                FileWrite(File, '%s' % (Array))\r
+                                FileWrite(File, Array)\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, ' ' , TypeName, '(' + Pcd.DatumType + ')', Value))\r
+                                FileWrite(File, ' %-*s   : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', Value))\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 IsStructure:\r
@@ -1302,15 +1405,24 @@ class PcdReport(object):
             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 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
-        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
+            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
@@ -1344,6 +1456,12 @@ class PcdReport(object):
             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
@@ -1382,7 +1500,7 @@ class PredictionReport(object):
                 # 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
@@ -1425,7 +1543,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 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
@@ -1508,7 +1626,7 @@ class PredictionReport(object):
         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
@@ -1519,7 +1637,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
-            \r
+\r
             #\r
             # Parse the output of EOT tool\r
             #\r
@@ -1701,7 +1819,7 @@ class FdRegionReport(object):
         # 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
@@ -1717,7 +1835,7 @@ class FdRegionReport(object):
         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
@@ -1795,7 +1913,7 @@ class FdRegionReport(object):
         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
@@ -1836,8 +1954,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
-                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
@@ -1858,7 +1975,7 @@ class FdRegionReport(object):
         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
@@ -1884,7 +2001,7 @@ 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.FvPath = os.path.join(Wa.BuildDir, "FV")\r
+        self.FvPath = os.path.join(Wa.BuildDir, TAB_FV_DIRECTORY)\r
         self.VpdFilePath = os.path.join(self.FvPath, "%s.map" % Wa.Platform.VpdToolGuid)\r
         self.VPDBaseAddress = 0\r
         self.VPDSize = 0\r
@@ -1947,7 +2064,7 @@ class FdReport(object):
                     ValueList[-1] = ' {'\r
                     FileWrite(File, '|'.join(ValueList))\r
                     for Array in ArrayList:\r
-                        FileWrite(File, '%s' % (Array))\r
+                        FileWrite(File, Array)\r
                 else:\r
                     FileWrite(File, item)\r
             FileWrite(File, gSubSectionEnd)\r
@@ -1998,7 +2115,7 @@ class PlatformReport(object):
         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
@@ -2073,7 +2190,7 @@ class PlatformReport(object):
         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
@@ -2107,7 +2224,7 @@ class BuildReport(object):
         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
@@ -2141,7 +2258,7 @@ class BuildReport(object):
     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
@@ -2153,7 +2270,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
-            \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