X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2Fbuild%2FBuildReport.py;h=942631c8795abfa1504cdcf9a8442d7722dfd7d6;hb=0eccea3fbe2f6d4999d972d9310d4f2717f5100c;hp=53d0039c51495fccd7032bafd771f8c8289dc52a;hpb=35f613d96ce43c7b23cd77aab063424ec4422e0c;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 53d0039c51..942631c879 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -5,13 +5,7 @@ # build all target completes successfully. # # Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# SPDX-License-Identifier: BSD-2-Clause-Patent # ## Import Modules @@ -28,12 +22,11 @@ import hashlib import subprocess import threading from datetime import datetime -from StringIO import StringIO +from io import BytesIO from Common import EdkLogger from Common.Misc import SaveFileOnChange from Common.Misc import GuidStructureByteArrayToGuidString from Common.Misc import GuidStructureStringToGuidString -from Common.InfClassObject import gComponentType2ModuleType from Common.BuildToolError import FILE_WRITE_FAILURE from Common.BuildToolError import CODE_ERROR from Common.BuildToolError import COMMAND_FAILURE @@ -43,10 +36,11 @@ from Common.MultipleWorkspace import MultipleWorkspace as mws import Common.GlobalData as GlobalData from AutoGen.AutoGen import ModuleAutoGen from Common.Misc import PathClass -from Common.String import NormPath +from Common.StringUtils import NormPath from Common.DataType import * import collections from Common.Expression import * +from GenFds.AprioriSection import DXE_APRIORI_GUID, PEI_APRIORI_GUID ## Pattern to extract contents in EDK DXS files gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL) @@ -95,38 +89,41 @@ gSubSectionSep = "-" * gLineMaxLength ## The look up table to map PCD type to pair of report display type and DEC type gPcdTypeMap = { - 'FixedAtBuild' : ('FIXED', 'FixedAtBuild'), - 'PatchableInModule': ('PATCH', 'PatchableInModule'), - 'FeatureFlag' : ('FLAG', 'FeatureFlag'), - 'Dynamic' : ('DYN', 'Dynamic'), - 'DynamicHii' : ('DYNHII', 'Dynamic'), - 'DynamicVpd' : ('DYNVPD', 'Dynamic'), - 'DynamicEx' : ('DEX', 'DynamicEx'), - 'DynamicExHii' : ('DEXHII', 'DynamicEx'), - 'DynamicExVpd' : ('DEXVPD', 'DynamicEx'), + TAB_PCDS_FIXED_AT_BUILD : ('FIXED', TAB_PCDS_FIXED_AT_BUILD), + TAB_PCDS_PATCHABLE_IN_MODULE: ('PATCH', TAB_PCDS_PATCHABLE_IN_MODULE), + TAB_PCDS_FEATURE_FLAG : ('FLAG', TAB_PCDS_FEATURE_FLAG), + TAB_PCDS_DYNAMIC : ('DYN', TAB_PCDS_DYNAMIC), + TAB_PCDS_DYNAMIC_HII : ('DYNHII', TAB_PCDS_DYNAMIC), + TAB_PCDS_DYNAMIC_VPD : ('DYNVPD', TAB_PCDS_DYNAMIC), + TAB_PCDS_DYNAMIC_EX : ('DEX', TAB_PCDS_DYNAMIC_EX), + TAB_PCDS_DYNAMIC_EX_HII : ('DEXHII', TAB_PCDS_DYNAMIC_EX), + TAB_PCDS_DYNAMIC_EX_VPD : ('DEXVPD', TAB_PCDS_DYNAMIC_EX), } ## The look up table to map module type to driver type gDriverTypeMap = { - 'SEC' : '0x3 (SECURITY_CORE)', - 'PEI_CORE' : '0x4 (PEI_CORE)', - 'PEIM' : '0x6 (PEIM)', - 'DXE_CORE' : '0x5 (DXE_CORE)', - 'DXE_DRIVER' : '0x7 (DRIVER)', - 'DXE_SAL_DRIVER' : '0x7 (DRIVER)', - 'DXE_SMM_DRIVER' : '0x7 (DRIVER)', - 'DXE_RUNTIME_DRIVER': '0x7 (DRIVER)', - 'UEFI_DRIVER' : '0x7 (DRIVER)', - 'UEFI_APPLICATION' : '0x9 (APPLICATION)', - 'SMM_CORE' : '0xD (SMM_CORE)', + SUP_MODULE_SEC : '0x3 (SECURITY_CORE)', + SUP_MODULE_PEI_CORE : '0x4 (PEI_CORE)', + SUP_MODULE_PEIM : '0x6 (PEIM)', + SUP_MODULE_DXE_CORE : '0x5 (DXE_CORE)', + SUP_MODULE_DXE_DRIVER : '0x7 (DRIVER)', + SUP_MODULE_DXE_SAL_DRIVER : '0x7 (DRIVER)', + SUP_MODULE_DXE_SMM_DRIVER : '0x7 (DRIVER)', + SUP_MODULE_DXE_RUNTIME_DRIVER: '0x7 (DRIVER)', + SUP_MODULE_UEFI_DRIVER : '0x7 (DRIVER)', + SUP_MODULE_UEFI_APPLICATION : '0x9 (APPLICATION)', + SUP_MODULE_SMM_CORE : '0xD (SMM_CORE)', 'SMM_DRIVER' : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers - 'MM_STANDALONE' : '0xE (MM_STANDALONE)', - 'MM_CORE_STANDALONE' : '0xF (MM_CORE_STANDALONE)' + SUP_MODULE_MM_STANDALONE : '0xE (MM_STANDALONE)', + SUP_MODULE_MM_CORE_STANDALONE : '0xF (MM_CORE_STANDALONE)' } ## The look up table of the supported opcode in the dependency expression binaries gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"] +## Save VPD Pcd +VPDPcdList = [] + ## # Writes a string to the file object. # @@ -140,13 +137,13 @@ gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", " def FileWrite(File, String, Wrapper=False): if Wrapper: String = textwrap.fill(String, 120) - File.write(String + gEndOfLine) + File.append(String + gEndOfLine) def ByteArrayForamt(Value): IsByteArray = False SplitNum = 16 ArrayList = [] - if Value.startswith('{') and Value.endswith('}'): + if Value.startswith('{') and Value.endswith('}') and not Value.startswith("{CODE("): Value = Value[1:-1] ValueList = Value.split(',') if len(ValueList) >= SplitNum: @@ -209,7 +206,7 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles): FileName = "Protocol/%(Key)s/%(Key)s.h" % {"Key" : Key} elif "PPI" in Type: FileName = "Ppi/%(Key)s/%(Key)s.h" % {"Key" : Key} - elif "GUID" in Type: + elif TAB_GUID in Type: FileName = "Guid/%(Key)s/%(Key)s.h" % {"Key" : Key} else: continue @@ -221,7 +218,7 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles): ## Split each lines in file # -# This method is used to split the lines in file to make the length of each line +# This method is used to split the lines in file to make the length of each line # less than MaxLength. # # @param Content The content of file @@ -246,12 +243,12 @@ def FileLinesSplit(Content=None, MaxLength=None): NewContentList.append(Line) for NewLine in NewContentList: NewContent += NewLine + TAB_LINE_BREAK - - NewContent = NewContent.replace(TAB_LINE_BREAK, gEndOfLine).replace('\r\r\n', gEndOfLine) + + NewContent = NewContent.replace(gEndOfLine, TAB_LINE_BREAK).replace('\r\r\n', gEndOfLine) return NewContent - - - + + + ## # Parse binary dependency expression section # @@ -281,10 +278,15 @@ class DepexParser(object): for Guid in Package.Guids: GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid]) self._GuidDb[GuidValue.upper()] = Guid - + for Ma in Pa.ModuleAutoGenList: + for Pcd in Ma.FixedVoidTypePcds: + PcdValue = Ma.FixedVoidTypePcds[Pcd] + if len(PcdValue.split(',')) == 16: + GuidValue = GuidStructureByteArrayToGuidString(PcdValue) + self._GuidDb[GuidValue.upper()] = Pcd ## # Parse the binary dependency expression files. - # + # # This function parses the binary dependency expression file and translate it # to the instruction list. # @@ -299,14 +301,14 @@ class DepexParser(object): Statement = gOpCodeList[struct.unpack("B", OpCode)[0]] if Statement in ["BEFORE", "AFTER", "PUSH"]: GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \ - struct.unpack("=LHHBBBBBBBB", DepexFile.read(16)) + struct.unpack(PACK_PATTERN_GUID, DepexFile.read(16)) GuidString = self._GuidDb.get(GuidValue, GuidValue) Statement = "%s %s" % (Statement, GuidString) DepexStatement.append(Statement) OpCode = DepexFile.read(1) return DepexStatement - + ## # Reports library information # @@ -324,10 +326,6 @@ class LibraryReport(object): # def __init__(self, M): self.LibraryList = [] - if int(str(M.AutoGenVersion), 0) >= 0x00010005: - self._EdkIIModule = True - else: - self._EdkIIModule = False for Lib in M.DependentLibraryList: LibInfPath = str(Lib) @@ -360,28 +358,23 @@ class LibraryReport(object): LibInfPath = LibraryItem[0] FileWrite(File, LibInfPath) - # - # Report library class, library constructor and destructor for - # EDKII style module. - # - if self._EdkIIModule: - LibClass = LibraryItem[1] - EdkIILibInfo = "" - LibConstructor = " ".join(LibraryItem[2]) - if LibConstructor: - EdkIILibInfo += " C = " + LibConstructor - LibDestructor = " ".join(LibraryItem[3]) - if LibDestructor: - EdkIILibInfo += " D = " + LibDestructor - LibDepex = " ".join(LibraryItem[4]) - if LibDepex: - EdkIILibInfo += " Depex = " + LibDepex - if LibraryItem[5]: - EdkIILibInfo += " Time = " + LibraryItem[5] - if EdkIILibInfo: - FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo)) - else: - FileWrite(File, "{%s}" % LibClass) + LibClass = LibraryItem[1] + EdkIILibInfo = "" + LibConstructor = " ".join(LibraryItem[2]) + if LibConstructor: + EdkIILibInfo += " C = " + LibConstructor + LibDestructor = " ".join(LibraryItem[3]) + if LibDestructor: + EdkIILibInfo += " D = " + LibDestructor + LibDepex = " ".join(LibraryItem[4]) + if LibDepex: + EdkIILibInfo += " Depex = " + LibDepex + if LibraryItem[5]: + EdkIILibInfo += " Time = " + LibraryItem[5] + if EdkIILibInfo: + FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo)) + else: + FileWrite(File, "{%s}" % LibClass) FileWrite(File, gSubSectionEnd) @@ -408,11 +401,11 @@ class DepexReport(object): self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex") ModuleType = M.ModuleType if not ModuleType: - ModuleType = gComponentType2ModuleType.get(M.ComponentType, "") + ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "") - if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "MM_CORE_STANDALONE", "UEFI_APPLICATION"]: + 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]: return - + for Source in M.SourceFileList: if os.path.splitext(Source.Path)[1].lower() == ".dxs": Match = gDxsDependencyPattern.search(open(Source.Path).read()) @@ -421,7 +414,7 @@ class DepexReport(object): self.Source = "DXS" break else: - self.Depex = M.DepexExpressionList.get(M.ModuleType, "") + self.Depex = M.DepexExpressionDict.get(M.ModuleType, "") self.ModuleDepex = " ".join(M.Module.DepexExpression[M.Arch, M.ModuleType]) if not self.ModuleDepex: self.ModuleDepex = "(None)" @@ -458,16 +451,16 @@ class DepexReport(object): FileWrite(File, gSubSectionSep) except: EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName) - + FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source) if self.Source == "INF": - FileWrite(File, "%s" % self.Depex, True) + FileWrite(File, self.Depex, True) FileWrite(File, gSubSectionSep) FileWrite(File, "From Module INF: %s" % self.ModuleDepex, True) FileWrite(File, "From Library INF: %s" % self.LibraryDepex, True) else: - FileWrite(File, "%s" % self.Depex) + FileWrite(File, self.Depex) FileWrite(File, gSubSectionEnd) ## @@ -573,11 +566,11 @@ class ModuleReport(object): if not M.IsLibrary: ModuleType = M.ModuleType if not ModuleType: - ModuleType = gComponentType2ModuleType.get(M.ComponentType, "") + ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "") # # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER" # - if ModuleType == "DXE_SMM_DRIVER": + if ModuleType == SUP_MODULE_DXE_SMM_DRIVER: PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000") if int(PiSpec, 0) >= 0x0001000A: ModuleType = "SMM_DRIVER" @@ -637,7 +630,7 @@ class ModuleReport(object): Match = gTimeStampPattern.search(FileContents) if Match: - self.BuildTimeStamp = datetime.fromtimestamp(int(Match.group(1))) + self.BuildTimeStamp = datetime.utcfromtimestamp(int(Match.group(1))) except IOError: EdkLogger.warn(None, "Fail to read report file", FwReportFileName) @@ -650,7 +643,7 @@ class ModuleReport(object): cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile] try: PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) - except Exception, X: + except Exception as X: EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) EndOfProcedure = threading.Event() EndOfProcedure.clear() @@ -722,8 +715,8 @@ def ReadMessage(From, To, ExitFlag): # read one line a time Line = From.readline() # empty string means "end" - if Line != None and Line != "": - To(Line.rstrip()) + if Line is not None and Line != b"": + To(Line.rstrip().decode(encoding='utf-8', errors='ignore')) else: break if ExitFlag.isSet(): @@ -781,11 +774,18 @@ class PcdReport(object): # Collect the PCD defined in DSC/FDF file, but not used in module # UnusedPcdFullList = [] + StructPcdDict = GlobalData.gStructurePcd.get(self.Arch, collections.OrderedDict()) + for Name, Guid in StructPcdDict: + if (Name, Guid) not in Pa.Platform.Pcds: + Pcd = StructPcdDict[(Name, Guid)] + PcdList = self.AllPcds.setdefault(Guid, {}).setdefault(Pcd.Type, []) + if Pcd not in PcdList and Pcd not in UnusedPcdFullList: + UnusedPcdFullList.append(Pcd) for item in Pa.Platform.Pcds: Pcd = Pa.Platform.Pcds[item] if not Pcd.Type: # check the Pcd in FDF file, whether it is used in module first - for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + for T in PCD_TYPE_LIST: PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(T, []) if Pcd in PcdList: Pcd.Type = T @@ -793,7 +793,7 @@ class PcdReport(object): if not Pcd.Type: PcdTypeFlag = False for package in Pa.PackageList: - for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: + for T in PCD_TYPE_LIST: if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds: Pcd.Type = T PcdTypeFlag = True @@ -805,16 +805,19 @@ class PcdReport(object): if not Pcd.DatumType: PcdType = Pcd.Type # Try to remove Hii and Vpd suffix - if PcdType.startswith("DynamicEx"): - PcdType = "DynamicEx" - elif PcdType.startswith("Dynamic"): - PcdType = "Dynamic" + if PcdType.startswith(TAB_PCDS_DYNAMIC_EX): + PcdType = TAB_PCDS_DYNAMIC_EX + elif PcdType.startswith(TAB_PCDS_DYNAMIC): + PcdType = TAB_PCDS_DYNAMIC for package in Pa.PackageList: if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType) in package.Pcds: Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType)].DatumType break PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) + UnusedPcdList = self.UnusedPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) + if Pcd in UnusedPcdList: + UnusedPcdList.remove(Pcd) if Pcd not in PcdList and Pcd not in UnusedPcdFullList: UnusedPcdFullList.append(Pcd) if len(Pcd.TokenCName) > self.MaxLen: @@ -824,7 +827,7 @@ class PcdReport(object): for PcdItem in GlobalData.gConditionalPcds: if '.' in PcdItem: (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.') - if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds.keys(): + if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds: Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)] PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, []) if Pcd not in PcdList: @@ -877,10 +880,21 @@ class PcdReport(object): self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue def GenerateReport(self, File, ModulePcdSet): - if self.ConditionalPcds: - self.GenerateReportDetail(File, ModulePcdSet, 1) - if self.UnusedPcds: - self.GenerateReportDetail(File, ModulePcdSet, 2) + if not ModulePcdSet: + if self.ConditionalPcds: + self.GenerateReportDetail(File, ModulePcdSet, 1) + if self.UnusedPcds: + IsEmpty = True + for Token in self.UnusedPcds: + TokenDict = self.UnusedPcds[Token] + for Type in TokenDict: + if TokenDict[Type]: + IsEmpty = False + break + if not IsEmpty: + break + if not IsEmpty: + self.GenerateReportDetail(File, ModulePcdSet, 2) self.GenerateReportDetail(File, ModulePcdSet) ## @@ -904,7 +918,7 @@ class PcdReport(object): elif ReportSubType == 2: PcdDict = self.UnusedPcds - if ModulePcdSet == None: + if not ModulePcdSet: FileWrite(File, gSectionStart) if ReportSubType == 1: FileWrite(File, "Conditional Directives used by the build system") @@ -927,192 +941,327 @@ class PcdReport(object): FileWrite(File, gSubSectionStart) FileWrite(File, TAB_BRG_PCD) FileWrite(File, gSubSectionSep) - + AllPcdDict = {} for Key in PcdDict: + AllPcdDict[Key] = {} + for Type in PcdDict[Key]: + for Pcd in PcdDict[Key][Type]: + AllPcdDict[Key][(Pcd.TokenCName, Type)] = Pcd + for Key in sorted(AllPcdDict): # # Group PCD by their token space GUID C Name # First = True - for Type in PcdDict[Key]: + for PcdTokenCName, Type in sorted(AllPcdDict[Key]): # # Group PCD by their usage type # + Pcd = AllPcdDict[Key][(PcdTokenCName, Type)] TypeName, DecType = gPcdTypeMap.get(Type, ("", Type)) - for Pcd in PcdDict[Key][Type]: - PcdTokenCName = Pcd.TokenCName - MixedPcdFlag = False - if GlobalData.MixedPcd: - for PcdKey in GlobalData.MixedPcd: - if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdKey]: - PcdTokenCName = PcdKey[0] - MixedPcdFlag = True - if MixedPcdFlag and not ModulePcdSet: - continue - # - # Get PCD default value and their override relationship - # - DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType)) - DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)) - DscDefaultValBak = DscDefaultValue - DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue) - if DscDefaultValue != DscDefaultValBak: - try: - DscDefaultValue = ValueExpressionEx(DscDefaultValue, Pcd.DatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" %(DscDefaultValue, Pcd.DatumType)) + MixedPcdFlag = False + if GlobalData.MixedPcd: + for PcdKey in GlobalData.MixedPcd: + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdKey]: + PcdTokenCName = PcdKey[0] + MixedPcdFlag = True + if MixedPcdFlag and not ModulePcdSet: + continue + # + # Get PCD default value and their override relationship + # + DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType)) + DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)) + DscDefaultValBak = DscDefaultValue + Field = '' + for (CName, Guid, Field) in self.FdfPcdSet: + if CName == PcdTokenCName and Guid == Key: + DscDefaultValue = self.FdfPcdSet[(CName, Guid, Field)] + break + if DscDefaultValue != DscDefaultValBak: + try: + DscDefaultValue = ValueExpressionEx(DscDefaultValue, Pcd.DatumType, self._GuidDict)(True) + except BadExpression as DscDefaultValue: + EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" %(DscDefaultValue, Pcd.DatumType)) - InfDefaultValue = None - - PcdValue = DecDefaultValue - if DscDefaultValue: - PcdValue = DscDefaultValue - if ModulePcdSet != None: - if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet: - continue - InfDefault, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type] - if InfDefault == "": - InfDefault = None - - BuildOptionMatch = False - if GlobalData.BuildOptionPcd: - for pcd in GlobalData.BuildOptionPcd: - if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]): - PcdValue = pcd[2] - BuildOptionMatch = True - break + InfDefaultValue = None - if First: - if ModulePcdSet == None: - FileWrite(File, "") - FileWrite(File, Key) - First = False + PcdValue = DecDefaultValue + if DscDefaultValue: + PcdValue = DscDefaultValue + #The DefaultValue of StructurePcd already be the latest, no need to update. + if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName): + Pcd.DefaultValue = PcdValue + if ModulePcdSet is not None: + if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet: + continue + InfDefaultValue, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type] + #The DefaultValue of StructurePcd already be the latest, no need to update. + if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName): + Pcd.DefaultValue = PcdValue + if InfDefaultValue: + try: + InfDefaultValue = ValueExpressionEx(InfDefaultValue, Pcd.DatumType, self._GuidDict)(True) + except BadExpression as InfDefaultValue: + EdkLogger.error('BuildReport', FORMAT_INVALID, "PCD Value: %s, Type: %s" % (InfDefaultValue, Pcd.DatumType)) + if InfDefaultValue == "": + InfDefaultValue = None + + BuildOptionMatch = False + if GlobalData.BuildOptionPcd: + for pcd in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]): + if pcd[2]: + continue + PcdValue = pcd[3] + #The DefaultValue of StructurePcd already be the latest, no need to update. + if not self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName): + Pcd.DefaultValue = PcdValue + BuildOptionMatch = True + break + if First: + if ModulePcdSet is None: + FileWrite(File, "") + FileWrite(File, Key) + First = False - if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'): - PcdValueNumber = int(PcdValue.strip(), 0) - if DecDefaultValue == None: - DecMatch = True - else: - DecDefaultValueNumber = int(DecDefaultValue.strip(), 0) - DecMatch = (DecDefaultValueNumber == PcdValueNumber) - if InfDefaultValue == None: - InfMatch = True - else: - InfDefaultValueNumber = int(InfDefaultValue.strip(), 0) - InfMatch = (InfDefaultValueNumber == PcdValueNumber) + if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES: + if PcdValue.startswith('0') and not PcdValue.lower().startswith('0x') and \ + len(PcdValue) > 1 and PcdValue.lstrip('0'): + PcdValue = PcdValue.lstrip('0') + PcdValueNumber = int(PcdValue.strip(), 0) + if DecDefaultValue is None: + DecMatch = True + else: + if DecDefaultValue.startswith('0') and not DecDefaultValue.lower().startswith('0x') and \ + len(DecDefaultValue) > 1 and DecDefaultValue.lstrip('0'): + DecDefaultValue = DecDefaultValue.lstrip('0') + DecDefaultValueNumber = int(DecDefaultValue.strip(), 0) + DecMatch = (DecDefaultValueNumber == PcdValueNumber) + + if InfDefaultValue is None: + InfMatch = True + else: + if InfDefaultValue.startswith('0') and not InfDefaultValue.lower().startswith('0x') and \ + len(InfDefaultValue) > 1 and InfDefaultValue.lstrip('0'): + InfDefaultValue = InfDefaultValue.lstrip('0') + InfDefaultValueNumber = int(InfDefaultValue.strip(), 0) + InfMatch = (InfDefaultValueNumber == PcdValueNumber) + + if DscDefaultValue is None: + DscMatch = True + else: + if DscDefaultValue.startswith('0') and not DscDefaultValue.lower().startswith('0x') and \ + len(DscDefaultValue) > 1 and DscDefaultValue.lstrip('0'): + DscDefaultValue = DscDefaultValue.lstrip('0') + DscDefaultValueNumber = int(DscDefaultValue.strip(), 0) + DscMatch = (DscDefaultValueNumber == PcdValueNumber) + else: + if DecDefaultValue is None: + DecMatch = True + else: + DecMatch = (DecDefaultValue.strip() == PcdValue.strip()) - if DscDefaultValue == None: - DscMatch = True - else: - DscDefaultValueNumber = int(DscDefaultValue.strip(), 0) - DscMatch = (DscDefaultValueNumber == PcdValueNumber) + if InfDefaultValue is None: + InfMatch = True else: - if DecDefaultValue == None: - DecMatch = True - else: - DecMatch = (DecDefaultValue.strip() == PcdValue.strip()) + InfMatch = (InfDefaultValue.strip() == PcdValue.strip()) - if InfDefaultValue == None: - InfMatch = True - else: - InfMatch = (InfDefaultValue.strip() == PcdValue.strip()) + if DscDefaultValue is None: + DscMatch = True + else: + DscMatch = (DscDefaultValue.strip() == PcdValue.strip()) - if DscDefaultValue == None: - DscMatch = True + IsStructure = False + if self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName): + IsStructure = True + if TypeName in ('DYNVPD', 'DEXVPD'): + SkuInfoList = Pcd.SkuInfoList + Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] + Pcd.DatumType = Pcd.StructName + if TypeName in ('DYNVPD', 'DEXVPD'): + Pcd.SkuInfoList = SkuInfoList + if Pcd.PcdValueFromComm or Pcd.PcdFieldValueFromComm: + BuildOptionMatch = True + DecMatch = False + elif Pcd.PcdValueFromFdf or Pcd.PcdFieldValueFromFdf: + DscDefaultValue = True + DscMatch = True + DecMatch = False + elif Pcd.SkuOverrideValues: + DscOverride = False + if Pcd.DefaultFromDSC: + DscOverride = True else: - DscMatch = (DscDefaultValue.strip() == PcdValue.strip()) - - IsStructure = False - if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd.keys()) and ((Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.gStructurePcd[self.Arch]): - IsStructure = True - if TypeName in ('DYNVPD', 'DEXVPD'): - SkuInfoList = Pcd.SkuInfoList - Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] - Pcd.DatumType = Pcd.StructName - if TypeName in ('DYNVPD', 'DEXVPD'): - Pcd.SkuInfoList = SkuInfoList - if Pcd.SkuOverrideValues: + DictLen = 0 + for item in Pcd.SkuOverrideValues: + DictLen += len(Pcd.SkuOverrideValues[item]) + if not DictLen: + DscOverride = False + else: + if not Pcd.SkuInfoList: + OverrideValues = Pcd.SkuOverrideValues + if OverrideValues: + for Data in OverrideValues.values(): + Struct = list(Data.values()) + if Struct: + DscOverride = self.ParseStruct(Struct[0]) + break + else: + SkuList = sorted(Pcd.SkuInfoList.keys()) + for Sku in SkuList: + SkuInfo = Pcd.SkuInfoList[Sku] + if SkuInfo.DefaultStoreDict: + DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys()) + for DefaultStore in DefaultStoreList: + OverrideValues = Pcd.SkuOverrideValues[Sku] + DscOverride = self.ParseStruct(OverrideValues[DefaultStore]) + if DscOverride: + break + if DscOverride: + break + if DscOverride: + DscDefaultValue = True DscMatch = True DecMatch = False - # - # Report PCD item according to their override relationship - # - if DecMatch and InfMatch: - self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, ' ') - elif BuildOptionMatch: - self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*B') + else: + DecMatch = True else: - if DscMatch: - if (Pcd.TokenCName, Key) in self.FdfPcdSet: - self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F') - else: - self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P') + DscDefaultValue = True + DscMatch = True + DecMatch = False + + # + # Report PCD item according to their override relationship + # + if Pcd.DatumType == 'BOOLEAN': + if DscDefaultValue: + DscDefaultValue = str(int(DscDefaultValue, 0)) + if DecDefaultValue: + DecDefaultValue = str(int(DecDefaultValue, 0)) + if InfDefaultValue: + InfDefaultValue = str(int(InfDefaultValue, 0)) + if Pcd.DefaultValue: + Pcd.DefaultValue = str(int(Pcd.DefaultValue, 0)) + if DecMatch: + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, ' ') + elif InfDefaultValue and InfMatch: + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M') + elif BuildOptionMatch: + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*B') + else: + if DscDefaultValue and DscMatch: + if (Pcd.TokenCName, Key, Field) in self.FdfPcdSet: + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*F') else: - self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M') + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*P') + else: + self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M') - if ModulePcdSet == None: - if IsStructure: - continue - if not TypeName in ('PATCH', 'FLAG', 'FIXED'): - continue - if not BuildOptionMatch: - ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {}) - for ModulePath in ModuleOverride: - ModuleDefault = ModuleOverride[ModulePath] - if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'): - ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0) - Match = (ModulePcdDefaultValueNumber == PcdValueNumber) - else: - Match = (ModuleDefault.strip() == PcdValue.strip()) - if Match: - continue - IsByteArray, ArrayList = ByteArrayForamt(ModuleDefault.strip()) - if IsByteArray: - FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, '{')) - for Array in ArrayList: - FileWrite(File, '%s' % (Array)) - else: - FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip())) + if ModulePcdSet is None: + if IsStructure: + continue + if not TypeName in ('PATCH', 'FLAG', 'FIXED'): + continue + if not BuildOptionMatch: + ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {}) + for ModulePath in ModuleOverride: + ModuleDefault = ModuleOverride[ModulePath] + if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES: + if ModuleDefault.startswith('0') and not ModuleDefault.lower().startswith('0x') and \ + len(ModuleDefault) > 1 and ModuleDefault.lstrip('0'): + ModuleDefault = ModuleDefault.lstrip('0') + ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0) + Match = (ModulePcdDefaultValueNumber == PcdValueNumber) + if Pcd.DatumType == 'BOOLEAN': + ModuleDefault = str(ModulePcdDefaultValueNumber) + else: + Match = (ModuleDefault.strip() == PcdValue.strip()) + if Match: + continue + IsByteArray, ArrayList = ByteArrayForamt(ModuleDefault.strip()) + if IsByteArray: + FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 15, ModulePath, '{')) + for Array in ArrayList: + FileWrite(File, Array) + else: + Value = ModuleDefault.strip() + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) + FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 15, ModulePath, Value)) - if ModulePcdSet == None: + if ModulePcdSet is None: FileWrite(File, gSectionEnd) else: if not ReportSubType and ModulePcdSet: FileWrite(File, gSubSectionEnd) + def ParseStruct(self, struct): + HasDscOverride = False + if struct: + for _, Values in list(struct.items()): + for Key, value in Values.items(): + if value[1] and value[1].endswith('.dsc'): + HasDscOverride = True + break + if HasDscOverride == True: + break + return HasDscOverride def PrintPcdDefault(self, File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue): - if not DscMatch and DscDefaultValue != None: + if not DscMatch and DscDefaultValue is not None: Value = DscDefaultValue.strip() IsByteArray, ArrayList = ByteArrayForamt(Value) if IsByteArray: FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', "{")) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', Value)) - if not InfMatch and InfDefaultValue != None: + if not InfMatch and InfDefaultValue is not None: Value = InfDefaultValue.strip() IsByteArray, ArrayList = ByteArrayForamt(Value) if IsByteArray: FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', "{")) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', Value)) - if not DecMatch and DecDefaultValue != None: + if not DecMatch and DecDefaultValue is not None: Value = DecDefaultValue.strip() IsByteArray, ArrayList = ByteArrayForamt(Value) if IsByteArray: FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', "{")) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', Value)) if IsStructure: - self.PrintStructureInfo(File, Pcd.DefaultValues) + for filedvalues in Pcd.DefaultValues.values(): + self.PrintStructureInfo(File, filedvalues) + if DecMatch and IsStructure: + for filedvalues in Pcd.DefaultValues.values(): + self.PrintStructureInfo(File, filedvalues) def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, Flag = ' '): if not Pcd.SkuInfoList: @@ -1121,16 +1270,33 @@ class PcdReport(object): if IsByteArray: FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{')) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith('0') and not Value.lower().startswith('0x') and len(Value) > 1 and Value.lstrip('0'): + Value = Value.lstrip('0') + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value)) if IsStructure: - OverrideValues = Pcd.SkuOverrideValues + FiledOverrideFlag = False + if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in GlobalData.gPcdSkuOverrides: + OverrideValues = GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] + else: + OverrideValues = Pcd.SkuOverrideValues if OverrideValues: - Keys = OverrideValues.keys() - Data = OverrideValues[Keys[0]] - Struct = Data.values()[0] - self.PrintStructureInfo(File, Struct) + for Data in OverrideValues.values(): + Struct = list(Data.values()) + if Struct: + OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct[0]) + self.PrintStructureInfo(File, OverrideFieldStruct) + FiledOverrideFlag = True + break + if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf): + OverrideFieldStruct = self.OverrideFieldValue(Pcd, {}) + self.PrintStructureInfo(File, OverrideFieldStruct) self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue) else: FirstPrint = True @@ -1144,6 +1310,8 @@ class PcdReport(object): for DefaultStore in DefaultStoreList: Value = SkuInfo.DefaultStoreDict[DefaultStore] IsByteArray, ArrayList = ByteArrayForamt(Value) + if Pcd.DatumType == 'BOOLEAN': + Value = str(int(Value, 0)) if FirstPrint: FirstPrint = False if IsByteArray: @@ -1156,8 +1324,13 @@ class PcdReport(object): else: FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{')) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) if self.DefaultStoreSingle and self.SkuSingle: FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value)) elif self.DefaultStoreSingle and not self.SkuSingle: @@ -1177,8 +1350,13 @@ class PcdReport(object): else: FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{')) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) if self.DefaultStoreSingle and self.SkuSingle: FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', Value)) elif self.DefaultStoreSingle and not self.SkuSingle: @@ -1190,12 +1368,14 @@ class PcdReport(object): FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset)) if IsStructure: OverrideValues = Pcd.SkuOverrideValues[Sku] - Struct = OverrideValues[DefaultStore] - self.PrintStructureInfo(File, Struct) + OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[DefaultStore]) + self.PrintStructureInfo(File, OverrideFieldStruct) self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue) else: Value = SkuInfo.DefaultValue IsByteArray, ArrayList = ByteArrayForamt(Value) + if Pcd.DatumType == 'BOOLEAN': + Value = str(int(Value, 0)) if FirstPrint: FirstPrint = False if IsByteArray: @@ -1204,8 +1384,13 @@ class PcdReport(object): else: FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{")) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) if self.SkuSingle: FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', Value)) else: @@ -1213,37 +1398,66 @@ class PcdReport(object): else: if IsByteArray: if self.SkuSingle: - FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', "{")) + FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', "{")) else: - FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{")) + FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{")) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: + if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES: + if Value.startswith(('0x', '0X')): + Value = '{} ({:d})'.format(Value, int(Value, 0)) + else: + Value = "0x{:X} ({})".format(int(Value, 0), Value) if self.SkuSingle: - FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', Value)) + FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', Value)) else: - FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ' , TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value)) + FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value)) if TypeName in ('DYNVPD', 'DEXVPD'): FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset)) + VPDPcdItem = (Pcd.TokenSpaceGuidCName + '.' + PcdTokenCName, SkuIdName, SkuInfo.VpdOffset, Pcd.MaxDatumSize, SkuInfo.DefaultValue) + if VPDPcdItem not in VPDPcdList: + VPDPcdList.append(VPDPcdItem) if IsStructure: + FiledOverrideFlag = False OverrideValues = Pcd.SkuOverrideValues[Sku] if OverrideValues: - Keys = OverrideValues.keys() - Struct = OverrideValues[Keys[0]] - self.PrintStructureInfo(File, Struct) + Keys = list(OverrideValues.keys()) + OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]]) + self.PrintStructureInfo(File, OverrideFieldStruct) + FiledOverrideFlag = True + if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf): + OverrideFieldStruct = self.OverrideFieldValue(Pcd, {}) + self.PrintStructureInfo(File, OverrideFieldStruct) self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue) + def OverrideFieldValue(self, Pcd, OverrideStruct): + OverrideFieldStruct = collections.OrderedDict() + if OverrideStruct: + for _, Values in OverrideStruct.items(): + for Key,value in Values.items(): + if value[1] and value[1].endswith('.dsc'): + OverrideFieldStruct[Key] = value + if Pcd.PcdFieldValueFromFdf: + for Key, Values in Pcd.PcdFieldValueFromFdf.items(): + if Key in OverrideFieldStruct and Values[0] == OverrideFieldStruct[Key][0]: + continue + OverrideFieldStruct[Key] = Values + if Pcd.PcdFieldValueFromComm: + for Key, Values in Pcd.PcdFieldValueFromComm.items(): + if Key in OverrideFieldStruct and Values[0] == OverrideFieldStruct[Key][0]: + continue + OverrideFieldStruct[Key] = Values + return OverrideFieldStruct + def PrintStructureInfo(self, File, Struct): - NewInfo = collections.OrderedDict() - for Key, Value in Struct.items(): - if Key not in NewInfo: - NewInfo[Key] = Value[0] + for Key, Value in sorted(Struct.items(), key=lambda x: x[0]): + if Value[1] and 'build command options' in Value[1]: + FileWrite(File, ' *B %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0])) + elif Value[1] and Value[1].endswith('.fdf'): + FileWrite(File, ' *F %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0])) else: - del NewInfo[Key] - NewInfo[Key] = Value[0] - if NewInfo: - for item in NewInfo: - FileWrite(File, ' %-*s = %s' % (self.MaxLen + 4, '.' + item, NewInfo[item])) + FileWrite(File, ' %-*s = %s' % (self.MaxLen + 4, '.' + Key, Value[0])) def StrtoHex(self, value): try: @@ -1275,6 +1489,12 @@ class PcdReport(object): else: return value + def IsStructurePcd(self, PcdToken, PcdTokenSpaceGuid): + if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd) and ((PcdToken, PcdTokenSpaceGuid) in GlobalData.gStructurePcd[self.Arch]): + return True + else: + return False + ## # Reports platform and module Prediction information # @@ -1313,7 +1533,7 @@ class PredictionReport(object): # their source code to find PPI/Protocol produce or consume # information. # - if Module.ModuleType == "BASE": + if Module.ModuleType == SUP_MODULE_BASE: continue # # Add module referenced source files @@ -1336,15 +1556,8 @@ class PredictionReport(object): if Module.Guid and not Module.IsLibrary: EntryPoint = " ".join(Module.Module.ModuleEntryPointList) - if int(str(Module.AutoGenVersion), 0) >= 0x00010005: - RealEntryPoint = "_ModuleEntryPoint" - else: - RealEntryPoint = EntryPoint - if EntryPoint == "_ModuleEntryPoint": - CCFlags = Module.BuildOption.get("CC", {}).get("FLAGS", "") - Match = gGlueLibEntryPoint.search(CCFlags) - if Match: - EntryPoint = Match.group(1) + + RealEntryPoint = "_ModuleEntryPoint" self._FfsEntryPoint[Module.Guid.upper()] = (EntryPoint, RealEntryPoint) @@ -1356,7 +1569,7 @@ class PredictionReport(object): if Wa.FdfProfile: for Fd in Wa.FdfProfile.FdDict: for FdRegion in Wa.FdfProfile.FdDict[Fd].RegionList: - if FdRegion.RegionType != "FV": + if FdRegion.RegionType != BINARY_FILE_TYPE_FV: continue for FvName in FdRegion.RegionDataList: if FvName in self._FvList: @@ -1429,17 +1642,17 @@ class PredictionReport(object): GuidList = os.path.join(self._EotDir, "GuidList.txt") DispatchList = os.path.join(self._EotDir, "Dispatch.txt") - TempFile = open(SourceList, "w+") + TempFile = [] for Item in self._SourceList: FileWrite(TempFile, Item) - TempFile.close() - TempFile = open(GuidList, "w+") + SaveFileOnChange(SourceList, "".join(TempFile), False) + TempFile = [] for Key in self._GuidMap: FileWrite(TempFile, "%s %s" % (Key, self._GuidMap[Key])) - TempFile.close() + SaveFileOnChange(GuidList, "".join(TempFile), False) try: - from Eot.Eot import Eot + from Eot.EotMain import Eot # # Invoke EOT tool and echo its runtime performance @@ -1450,7 +1663,7 @@ class PredictionReport(object): EotEndTime = time.time() EotDuration = time.strftime("%H:%M:%S", time.gmtime(int(round(EotEndTime - EotStartTime)))) EdkLogger.quiet("EOT run time: %s\n" % EotDuration) - + # # Parse the output of EOT tool # @@ -1626,12 +1839,13 @@ class FdRegionReport(object): self.FvInfo = {} self._GuidsDb = {} self._FvDir = Wa.FvDir + self._WorkspaceDir = Wa.WorkspaceDir # # If the input FdRegion is not a firmware volume, # we are done. # - if self.Type != "FV": + if self.Type != BINARY_FILE_TYPE_FV: return # @@ -1647,7 +1861,7 @@ class FdRegionReport(object): PlatformPcds = {} # # Collect PCDs declared in DEC files. - # + # for Pa in Wa.AutoGenObjectList: for Package in Pa.PackageList: for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds: @@ -1664,8 +1878,8 @@ class FdRegionReport(object): # # Add PEI and DXE a priori files GUIDs defined in PI specification. # - self._GuidsDb["1B45CC0A-156A-428A-AF62-49864DA0E6E6"] = "PEI Apriori" - self._GuidsDb["FC510EE7-FFDC-11D4-BD41-0080C73C8881"] = "DXE Apriori" + self._GuidsDb[PEI_APRIORI_GUID] = "PEI Apriori" + self._GuidsDb[DXE_APRIORI_GUID] = "DXE Apriori" # # Add ACPI table storage file # @@ -1725,11 +1939,19 @@ class FdRegionReport(object): FileWrite(File, "Type: %s" % Type) FileWrite(File, "Base Address: 0x%X" % BaseAddress) - if self.Type == "FV": + if self.Type == BINARY_FILE_TYPE_FV: FvTotalSize = 0 FvTakenSize = 0 FvFreeSize = 0 - FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt") + if FvName.upper().endswith('.FV'): + FileExt = FvName + ".txt" + else: + FileExt = FvName + ".Fv.txt" + + if not os.path.isfile(FileExt): + FvReportFileName = mws.join(self._WorkspaceDir, FileExt) + if not os.path.isfile(FvReportFileName): + FvReportFileName = os.path.join(self._FvDir, FileExt) try: # # Collect size info in the firmware volume. @@ -1758,8 +1980,7 @@ class FdRegionReport(object): for Match in gOffsetGuidPattern.finditer(FvReport): Guid = Match.group(2).upper() OffsetInfo[Match.group(1)] = self._GuidsDb.get(Guid, Guid) - OffsetList = OffsetInfo.keys() - OffsetList.sort() + OffsetList = sorted(OffsetInfo.keys()) for Offset in OffsetList: FileWrite (File, "%s %s" % (Offset, OffsetInfo[Offset])) except IOError: @@ -1780,7 +2001,7 @@ class FdRegionReport(object): if (len(self.FvList) > 0): for FvItem in self.FvList: Info = self.FvInfo[FvItem] - self._GenerateReport(File, Info[0], "FV", Info[1], Info[2], FvItem) + self._GenerateReport(File, Info[0], TAB_FV_DIRECTORY, Info[1], Info[2], FvItem) else: self._GenerateReport(File, "FD Region", self.Type, self.BaseAddress, self.Size) @@ -1806,36 +2027,15 @@ class FdReport(object): self.BaseAddress = Fd.BaseAddress self.Size = Fd.Size self.FdRegionList = [FdRegionReport(FdRegion, Wa) for FdRegion in Fd.RegionList] - self.FvPath = os.path.join(Wa.BuildDir, "FV") - self.VpdFilePath = os.path.join(self.FvPath, "%s.map" % Wa.Platform.VpdToolGuid) + self.FvPath = os.path.join(Wa.BuildDir, TAB_FV_DIRECTORY) self.VPDBaseAddress = 0 self.VPDSize = 0 - self.VPDInfoList = [] for index, FdRegion in enumerate(Fd.RegionList): if str(FdRegion.RegionType) is 'FILE' and Wa.Platform.VpdToolGuid in str(FdRegion.RegionDataList): self.VPDBaseAddress = self.FdRegionList[index].BaseAddress self.VPDSize = self.FdRegionList[index].Size break - if os.path.isfile(self.VpdFilePath): - fd = open(self.VpdFilePath, "r") - Lines = fd.readlines() - for Line in Lines: - Line = Line.strip() - if len(Line) == 0 or Line.startswith("#"): - continue - try: - PcdName, SkuId, Offset, Size, Value = Line.split("#")[0].split("|") - PcdName, SkuId, Offset, Size, Value = PcdName.strip(), SkuId.strip(), Offset.strip(), Size.strip(), Value.strip() - if Offset.lower().startswith('0x'): - Offset = '0x%08X' % (int(Offset, 16) + self.VPDBaseAddress) - else: - Offset = '0x%08X' % (int(Offset, 10) + self.VPDBaseAddress) - self.VPDInfoList.append("%s | %s | %s | %s | %s" % (PcdName, SkuId, Offset, Size, Value)) - except: - EdkLogger.error("BuildReport", CODE_ERROR, "Fail to parse VPD information file %s" % self.VpdFilePath) - fd.close() - ## # Generate report for the firmware device. # @@ -1855,23 +2055,26 @@ class FdReport(object): for FdRegionItem in self.FdRegionList: FdRegionItem.GenerateReport(File) - if len(self.VPDInfoList) > 0: + if VPDPcdList: + VPDPcdList.sort(key=lambda x: int(x[2], 0)) FileWrite(File, gSubSectionStart) FileWrite(File, "FD VPD Region") FileWrite(File, "Base Address: 0x%X" % self.VPDBaseAddress) FileWrite(File, "Size: 0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0)) FileWrite(File, gSubSectionSep) - for item in self.VPDInfoList: - ValueList = item.split('|') - Value = ValueList[-1].strip() - IsByteArray, ArrayList = ByteArrayForamt(Value) + for item in VPDPcdList: + # Add BaseAddress for offset + Offset = '0x%08X' % (int(item[2], 16) + self.VPDBaseAddress) + IsByteArray, ArrayList = ByteArrayForamt(item[-1]) + Skuinfo = item[1] + if len(GlobalData.gSkuids) == 1 : + Skuinfo = GlobalData.gSkuids[0] if IsByteArray: - ValueList[-1] = ' {' - FileWrite(File, '|'.join(ValueList)) + FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], '{')) for Array in ArrayList: - FileWrite(File, '%s' % (Array)) + FileWrite(File, Array) else: - FileWrite(File, item) + FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], item[-1])) FileWrite(File, gSubSectionEnd) FileWrite(File, gSectionEnd) @@ -1909,7 +2112,7 @@ class PlatformReport(object): self.PcdReport = PcdReport(Wa) self.FdReportList = [] - if "FLASH" in ReportType and Wa.FdfProfile and MaList == None: + if "FLASH" in ReportType and Wa.FdfProfile and MaList is None: for Fd in Wa.FdfProfile.FdDict: self.FdReportList.append(FdReport(Wa.FdfProfile.FdDict[Fd], Wa)) @@ -1920,9 +2123,9 @@ class PlatformReport(object): self.DepexParser = None if "DEPEX" in ReportType: self.DepexParser = DepexParser(Wa) - + self.ModuleReportList = [] - if MaList != None: + if MaList is not None: self._IsModuleBuild = True for Ma in MaList: self.ModuleReportList.append(ModuleReport(Ma, ReportType)) @@ -1932,13 +2135,13 @@ class PlatformReport(object): ModuleAutoGenList = [] for ModuleKey in Pa.Platform.Modules: ModuleAutoGenList.append(Pa.Platform.Modules[ModuleKey].M) - if GlobalData.gFdfParser != None: + if GlobalData.gFdfParser is not None: if Pa.Arch in GlobalData.gFdfParser.Profile.InfDict: INFList = GlobalData.gFdfParser.Profile.InfDict[Pa.Arch] for InfName in INFList: InfClass = PathClass(NormPath(InfName), Wa.WorkspaceDir, Pa.Arch) Ma = ModuleAutoGen(Wa, InfClass, Pa.BuildTarget, Pa.ToolChain, Pa.Arch, Wa.MetaFile) - if Ma == None: + if Ma is None: continue if Ma not in ModuleAutoGenList: ModuleAutoGenList.append(Ma) @@ -1995,7 +2198,7 @@ class PlatformReport(object): if not self._IsModuleBuild: if "PCD" in ReportType: self.PcdReport.GenerateReport(File, None) - + if "FLASH" in ReportType: for FdReportListItem in self.FdReportList: FdReportListItem.GenerateReport(File) @@ -2029,7 +2232,7 @@ class BuildReport(object): if ReportFile: self.ReportList = [] self.ReportType = [] - if ReportType: + if ReportType: for ReportTypeItem in ReportType: if ReportTypeItem not in self.ReportType: self.ReportType.append(ReportTypeItem) @@ -2063,19 +2266,18 @@ class BuildReport(object): def GenerateReport(self, BuildDuration, AutoGenTime, MakeTime, GenFdsTime): if self.ReportFile: try: - File = StringIO('') + File = [] for (Wa, MaList) in self.ReportList: PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, self.ReportType) - Content = FileLinesSplit(File.getvalue(), gLineMaxLength) - SaveFileOnChange(self.ReportFile, Content, True) + Content = FileLinesSplit(''.join(File), gLineMaxLength) + SaveFileOnChange(self.ReportFile, Content, False) EdkLogger.quiet("Build report can be found at %s" % os.path.abspath(self.ReportFile)) except IOError: EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile) except: EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False) EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc())) - File.close() - + # This acts like the main() function for the script, unless it is 'import'ed into another script. if __name__ == '__main__': pass