# This module contains the functionality to generate build report after\r
# build all target completes successfully.\r
#\r
-# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
\r
## Import Modules\r
#\r
-import os\r
+import Common.LongFilePathOs as os\r
import re\r
import platform\r
import textwrap\r
import sys\r
import time\r
import struct\r
+import hashlib\r
+import subprocess\r
+import threading\r
from datetime import datetime\r
-from StringIO import StringIO\r
+from io import BytesIO\r
from Common import EdkLogger\r
from Common.Misc import SaveFileOnChange\r
from Common.Misc import GuidStructureByteArrayToGuidString\r
from Common.Misc import GuidStructureStringToGuidString\r
-from Common.InfClassObject import gComponentType2ModuleType\r
from Common.BuildToolError import FILE_WRITE_FAILURE\r
from Common.BuildToolError import CODE_ERROR\r
-\r
+from Common.BuildToolError import COMMAND_FAILURE\r
+from Common.BuildToolError import FORMAT_INVALID\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+import Common.GlobalData as GlobalData\r
+from AutoGen.AutoGen import ModuleAutoGen\r
+from Common.Misc import PathClass\r
+from Common.StringUtils import NormPath\r
+from Common.DataType import *\r
+import collections\r
+from Common.Expression import *\r
+from GenFds.AprioriSection import DXE_APRIORI_GUID, PEI_APRIORI_GUID\r
\r
## Pattern to extract contents in EDK DXS files\r
gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)\r
## Pattern to find the entry point for EDK module using EDKII Glue library\r
gGlueLibEntryPoint = re.compile(r"__EDKII_GLUE_MODULE_ENTRY_POINT__\s*=\s*(\w+)")\r
\r
+## Tags for MaxLength of line in report\r
+gLineMaxLength = 120\r
+\r
+## Tags for end of line in report\r
+gEndOfLine = "\r\n"\r
+\r
## Tags for section start, end and separator\r
-gSectionStart = ">" + "=" * 118 + "<"\r
-gSectionEnd = "<" + "=" * 118 + ">" + "\n"\r
-gSectionSep = "=" * 120\r
+gSectionStart = ">" + "=" * (gLineMaxLength - 2) + "<"\r
+gSectionEnd = "<" + "=" * (gLineMaxLength - 2) + ">" + "\n"\r
+gSectionSep = "=" * gLineMaxLength\r
\r
## Tags for subsection start, end and separator\r
-gSubSectionStart = ">" + "-" * 118 + "<"\r
-gSubSectionEnd = "<" + "-" * 118 + ">"\r
-gSubSectionSep = "-" * 120\r
+gSubSectionStart = ">" + "-" * (gLineMaxLength - 2) + "<"\r
+gSubSectionEnd = "<" + "-" * (gLineMaxLength - 2) + ">"\r
+gSubSectionSep = "-" * gLineMaxLength\r
+\r
\r
## The look up table to map PCD type to pair of report display type and DEC type\r
gPcdTypeMap = {\r
- 'FixedAtBuild' : ('FIXED', 'FixedAtBuild'),\r
- 'PatchableInModule': ('PATCH', 'PatchableInModule'),\r
- 'FeatureFlag' : ('FLAG', 'FeatureFlag'),\r
- 'Dynamic' : ('DYN', 'Dynamic'),\r
- 'DynamicHii' : ('DYNHII', 'Dynamic'),\r
- 'DynamicVpd' : ('DYNVPD', 'Dynamic'),\r
- 'DynamicEx' : ('DEX', 'Dynamic'),\r
- 'DynamicExHii' : ('DEXHII', 'Dynamic'),\r
- 'DynamicExVpd' : ('DEXVPD', 'Dynamic'),\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
+ SUP_MODULE_MM_STANDALONE : '0xE (MM_STANDALONE)',\r
+ SUP_MODULE_MM_CORE_STANDALONE : '0xF (MM_CORE_STANDALONE)'\r
}\r
\r
## The look up table of the supported opcode in the dependency expression binaries\r
gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"]\r
\r
+## Save VPD Pcd\r
+VPDPcdList = []\r
+\r
##\r
# Writes a string to the file object.\r
#\r
def FileWrite(File, String, Wrapper=False):\r
if Wrapper:\r
String = textwrap.fill(String, 120)\r
- File.write(String + "\r\n")\r
+ File.append(String + gEndOfLine)\r
+\r
+def ByteArrayForamt(Value):\r
+ IsByteArray = False\r
+ SplitNum = 16\r
+ ArrayList = []\r
+ if Value.startswith('{') and Value.endswith('}') and not Value.startswith("{CODE("):\r
+ Value = Value[1:-1]\r
+ ValueList = Value.split(',')\r
+ if len(ValueList) >= SplitNum:\r
+ IsByteArray = True\r
+ if IsByteArray:\r
+ if ValueList:\r
+ Len = len(ValueList)/SplitNum\r
+ for i, element in enumerate(ValueList):\r
+ ValueList[i] = '0x%02X' % int(element.strip(), 16)\r
+ if Len:\r
+ Id = 0\r
+ while (Id <= Len):\r
+ End = min(SplitNum*(Id+1), len(ValueList))\r
+ Str = ','.join(ValueList[SplitNum*Id : End])\r
+ if End == len(ValueList):\r
+ Str += '}'\r
+ ArrayList.append(Str)\r
+ break\r
+ else:\r
+ Str += ','\r
+ ArrayList.append(Str)\r
+ Id += 1\r
+ else:\r
+ ArrayList = [Value + '}']\r
+ return IsByteArray, ArrayList\r
\r
##\r
# Find all the header file that the module source directly includes.\r
FileName = "Protocol/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
elif "PPI" in Type:\r
FileName = "Ppi/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
- elif "GUID" in Type:\r
+ elif TAB_GUID in Type:\r
FileName = "Guid/%(Key)s/%(Key)s.h" % {"Key" : Key}\r
else:\r
continue\r
IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName\r
break\r
\r
+## Split each lines in file\r
+#\r
+# This method is used to split the lines in file to make the length of each line\r
+# less than MaxLength.\r
+#\r
+# @param Content The content of file\r
+# @param MaxLength The Max Length of the line\r
+#\r
+def FileLinesSplit(Content=None, MaxLength=None):\r
+ ContentList = Content.split(TAB_LINE_BREAK)\r
+ NewContent = ''\r
+ NewContentList = []\r
+ for Line in ContentList:\r
+ while len(Line.rstrip()) > MaxLength:\r
+ LineSpaceIndex = Line.rfind(TAB_SPACE_SPLIT, 0, MaxLength)\r
+ LineSlashIndex = Line.rfind(TAB_SLASH, 0, MaxLength)\r
+ LineBackSlashIndex = Line.rfind(TAB_BACK_SLASH, 0, MaxLength)\r
+ if max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex) > 0:\r
+ LineBreakIndex = max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex)\r
+ else:\r
+ LineBreakIndex = MaxLength\r
+ NewContentList.append(Line[:LineBreakIndex])\r
+ Line = Line[LineBreakIndex:]\r
+ if Line:\r
+ NewContentList.append(Line)\r
+ for NewLine in NewContentList:\r
+ NewContent += NewLine + TAB_LINE_BREAK\r
+\r
+ NewContent = NewContent.replace(gEndOfLine, TAB_LINE_BREAK).replace('\r\r\n', gEndOfLine)\r
+ return NewContent\r
+\r
+\r
+\r
##\r
# Parse binary dependency expression section\r
#\r
#\r
def __init__(self, Wa):\r
self._GuidDb = {}\r
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
- for Protocol in Package.Protocols:\r
- GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])\r
- self._GuidDb[GuidValue.upper()] = Protocol\r
- for Ppi in Package.Ppis:\r
- GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])\r
- self._GuidDb[GuidValue.upper()] = Ppi\r
- for Guid in Package.Guids:\r
- GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
- self._GuidDb[GuidValue.upper()] = Guid\r
- \r
+ for Pa in Wa.AutoGenObjectList:\r
+ for Package in Pa.PackageList:\r
+ for Protocol in Package.Protocols:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])\r
+ self._GuidDb[GuidValue.upper()] = Protocol\r
+ for Ppi in Package.Ppis:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])\r
+ self._GuidDb[GuidValue.upper()] = Ppi\r
+ for Guid in Package.Guids:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
+ self._GuidDb[GuidValue.upper()] = Guid\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
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
+ OpCode = DepexFile.read(1)\r
+\r
return DepexStatement\r
- \r
+\r
##\r
# Reports library information\r
#\r
#\r
def __init__(self, M):\r
self.LibraryList = []\r
- if int(str(M.AutoGenVersion), 0) >= 0x00010005:\r
- self._EdkIIModule = True\r
- else:\r
- self._EdkIIModule = False\r
\r
for Lib in M.DependentLibraryList:\r
LibInfPath = str(Lib)\r
LibConstructorList = Lib.ConstructorList\r
LibDesstructorList = Lib.DestructorList\r
LibDepexList = Lib.DepexExpression[M.Arch, M.ModuleType]\r
- self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList))\r
+ for LibAutoGen in M.LibraryAutoGenList:\r
+ if LibInfPath == LibAutoGen.MetaFile.Path:\r
+ LibTime = LibAutoGen.BuildTime\r
+ break\r
+ self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList, LibTime))\r
\r
##\r
# Generate report for module library information\r
# @param File The file object for report\r
#\r
def GenerateReport(self, File):\r
- FileWrite(File, gSubSectionStart)\r
- FileWrite(File, "Library")\r
if len(self.LibraryList) > 0:\r
+ FileWrite(File, gSubSectionStart)\r
+ FileWrite(File, TAB_BRG_LIBRARY)\r
FileWrite(File, gSubSectionSep)\r
for LibraryItem in self.LibraryList:\r
LibInfPath = LibraryItem[0]\r
FileWrite(File, LibInfPath)\r
\r
- #\r
- # Report library class, library constructor and destructor for\r
- # EDKII style module.\r
- #\r
- if self._EdkIIModule:\r
- LibClass = LibraryItem[1]\r
- EdkIILibInfo = ""\r
- LibConstructor = " ".join(LibraryItem[2])\r
- if LibConstructor:\r
- EdkIILibInfo += " C = " + LibConstructor\r
- LibDestructor = " ".join(LibraryItem[3])\r
- if LibDestructor:\r
- EdkIILibInfo += " D = " + LibDestructor\r
- LibDepex = " ".join(LibraryItem[4])\r
- if LibDepex:\r
- EdkIILibInfo += " Depex = " + LibDepex\r
- if EdkIILibInfo:\r
- FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo))\r
- else:\r
- FileWrite(File, "{%s}" % LibClass)\r
+ LibClass = LibraryItem[1]\r
+ EdkIILibInfo = ""\r
+ LibConstructor = " ".join(LibraryItem[2])\r
+ if LibConstructor:\r
+ EdkIILibInfo += " C = " + LibConstructor\r
+ LibDestructor = " ".join(LibraryItem[3])\r
+ if LibDestructor:\r
+ EdkIILibInfo += " D = " + LibDestructor\r
+ LibDepex = " ".join(LibraryItem[4])\r
+ if LibDepex:\r
+ EdkIILibInfo += " Depex = " + LibDepex\r
+ if LibraryItem[5]:\r
+ EdkIILibInfo += " Time = " + LibraryItem[5]\r
+ if EdkIILibInfo:\r
+ FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo))\r
+ else:\r
+ FileWrite(File, "{%s}" % LibClass)\r
\r
- FileWrite(File, gSubSectionEnd)\r
+ FileWrite(File, gSubSectionEnd)\r
\r
##\r
# Reports dependency expression information\r
#\r
def __init__(self, M):\r
self.Depex = ""\r
- self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex") \r
+ self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex")\r
ModuleType = M.ModuleType\r
if not ModuleType:\r
- ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
+ ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "")\r
\r
- if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "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
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
def GenerateReport(self, File, GlobalDepexParser):\r
if not self.Depex:\r
return\r
-\r
FileWrite(File, gSubSectionStart)\r
if os.path.isfile(self._DepexFileName):\r
try:\r
FileWrite(File, gSubSectionSep)\r
except:\r
EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName)\r
- \r
+\r
FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)\r
\r
if self.Source == "INF":\r
- FileWrite(File, "%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
self.FileGuid = M.Guid\r
self.Size = 0\r
self.BuildTimeStamp = None\r
+ self.Hash = 0\r
self.DriverType = ""\r
if not M.IsLibrary:\r
ModuleType = M.ModuleType\r
if not ModuleType:\r
- ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
+ ModuleType = COMPONENT_TO_MODULE_MAP_DICT.get(M.ComponentType, "")\r
#\r
# If a module complies to PI 1.1, promote Module type to "SMM_DRIVER"\r
#\r
- if ModuleType == "DXE_SMM_DRIVER":\r
- PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")\r
- if int(PiSpec, 16) >= 0x0001000A:\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
self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)")\r
self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")\r
self.PciDeviceId = M.Module.Defines.get("PCI_DEVICE_ID", "")\r
self.PciVendorId = M.Module.Defines.get("PCI_VENDOR_ID", "")\r
self.PciClassCode = M.Module.Defines.get("PCI_CLASS_CODE", "")\r
+ self.BuildTime = M.BuildTime\r
\r
self._BuildDir = M.BuildDir\r
self.ModulePcdSet = {}\r
\r
Match = gTimeStampPattern.search(FileContents)\r
if Match:\r
- self.BuildTimeStamp = datetime.fromtimestamp(int(Match.group(1)))\r
+ self.BuildTimeStamp = datetime.utcfromtimestamp(int(Match.group(1)))\r
except IOError:\r
EdkLogger.warn(None, "Fail to read report file", FwReportFileName)\r
\r
+ if "HASH" in ReportType:\r
+ OutputDir = os.path.join(self._BuildDir, "OUTPUT")\r
+ DefaultEFIfile = os.path.join(OutputDir, self.ModuleName + ".efi")\r
+ if os.path.isfile(DefaultEFIfile):\r
+ Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")\r
+ # rebase the efi image since its base address may not zero\r
+ cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile]\r
+ try:\r
+ PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+ except Exception as X:\r
+ EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
+ EndOfProcedure = threading.Event()\r
+ EndOfProcedure.clear()\r
+ if PopenObject.stderr:\r
+ StdErrThread = threading.Thread(target=ReadMessage, args=(PopenObject.stderr, EdkLogger.quiet, EndOfProcedure))\r
+ StdErrThread.setName("STDERR-Redirector")\r
+ StdErrThread.setDaemon(False)\r
+ StdErrThread.start()\r
+ # waiting for program exit\r
+ PopenObject.wait()\r
+ if PopenObject.stderr:\r
+ StdErrThread.join()\r
+ if PopenObject.returncode != 0:\r
+ EdkLogger.error("GenFw", COMMAND_FAILURE, "Failed to generate firmware hash image for %s" % (DefaultEFIfile))\r
+ if os.path.isfile(Tempfile):\r
+ self.Hash = hashlib.sha1()\r
+ buf = open(Tempfile, 'rb').read()\r
+ if self.Hash.update(buf):\r
+ self.Hash = self.Hash.update(buf)\r
+ self.Hash = self.Hash.hexdigest()\r
+ os.remove(Tempfile)\r
+\r
FileWrite(File, "Module Summary")\r
FileWrite(File, "Module Name: %s" % self.ModuleName)\r
FileWrite(File, "Module INF Path: %s" % self.ModuleInfPath)\r
FileWrite(File, "File GUID: %s" % self.FileGuid)\r
if self.Size:\r
FileWrite(File, "Size: 0x%X (%.2fK)" % (self.Size, self.Size / 1024.0))\r
+ if self.Hash:\r
+ FileWrite(File, "SHA1 HASH: %s *%s" % (self.Hash, self.ModuleName + ".efi"))\r
if self.BuildTimeStamp:\r
FileWrite(File, "Build Time Stamp: %s" % self.BuildTimeStamp)\r
+ if self.BuildTime:\r
+ FileWrite(File, "Module Build Time: %s" % self.BuildTime)\r
if self.DriverType:\r
FileWrite(File, "Driver Type: %s" % self.DriverType)\r
if self.UefiSpecVersion:\r
\r
FileWrite(File, gSectionEnd)\r
\r
+def ReadMessage(From, To, ExitFlag):\r
+ while True:\r
+ # read one line a time\r
+ Line = From.readline()\r
+ # empty string means "end"\r
+ if Line is not None and Line != b"":\r
+ To(Line.rstrip().decode(encoding='utf-8', errors='ignore'))\r
+ else:\r
+ break\r
+ if ExitFlag.isSet():\r
+ break\r
+\r
##\r
# Reports platform and module PCD information\r
#\r
#\r
def __init__(self, Wa):\r
self.AllPcds = {}\r
+ self.UnusedPcds = {}\r
+ self.ConditionalPcds = {}\r
self.MaxLen = 0\r
+ self.Arch = None\r
if Wa.FdfProfile:\r
self.FdfPcdSet = Wa.FdfProfile.PcdDict\r
else:\r
self.FdfPcdSet = {}\r
\r
+ self.DefaultStoreSingle = True\r
+ self.SkuSingle = True\r
+ if GlobalData.gDefaultStores and len(GlobalData.gDefaultStores) > 1:\r
+ self.DefaultStoreSingle = False\r
+ if GlobalData.gSkuids and len(GlobalData.gSkuids) > 1:\r
+ self.SkuSingle = False\r
+\r
self.ModulePcdOverride = {}\r
for Pa in Wa.AutoGenObjectList:\r
+ self.Arch = Pa.Arch\r
#\r
# Collect all platform referenced PCDs and grouped them by PCD token space\r
# GUID C Names\r
PcdList.append(Pcd)\r
if len(Pcd.TokenCName) > self.MaxLen:\r
self.MaxLen = len(Pcd.TokenCName)\r
+ #\r
+ # Collect the PCD defined in DSC/FDF file, but not used in module\r
+ #\r
+ UnusedPcdFullList = []\r
+ StructPcdDict = GlobalData.gStructurePcd.get(self.Arch, collections.OrderedDict())\r
+ for Name, Guid in StructPcdDict:\r
+ if (Name, Guid) not in Pa.Platform.Pcds:\r
+ Pcd = StructPcdDict[(Name, Guid)]\r
+ PcdList = self.AllPcds.setdefault(Guid, {}).setdefault(Pcd.Type, [])\r
+ if Pcd not in PcdList and Pcd not in UnusedPcdFullList:\r
+ UnusedPcdFullList.append(Pcd)\r
+ for item in Pa.Platform.Pcds:\r
+ Pcd = Pa.Platform.Pcds[item]\r
+ if not Pcd.Type:\r
+ # check the Pcd in FDF file, whether it is used in module first\r
+ for T in PCD_TYPE_LIST:\r
+ PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(T, [])\r
+ if Pcd in PcdList:\r
+ Pcd.Type = T\r
+ break\r
+ if not Pcd.Type:\r
+ PcdTypeFlag = False\r
+ for package in Pa.PackageList:\r
+ for T in PCD_TYPE_LIST:\r
+ if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds:\r
+ Pcd.Type = T\r
+ PcdTypeFlag = True\r
+ if not Pcd.DatumType:\r
+ Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T)].DatumType\r
+ break\r
+ if PcdTypeFlag:\r
+ break\r
+ if not Pcd.DatumType:\r
+ PcdType = Pcd.Type\r
+ # Try to remove Hii and Vpd suffix\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
+ self.MaxLen = len(Pcd.TokenCName)\r
+\r
+ if GlobalData.gConditionalPcds:\r
+ for PcdItem in GlobalData.gConditionalPcds:\r
+ if '.' in PcdItem:\r
+ (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.')\r
+ if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds:\r
+ Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)]\r
+ PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
+ if Pcd not in PcdList:\r
+ PcdList.append(Pcd)\r
+\r
+ UnusedPcdList = []\r
+ if UnusedPcdFullList:\r
+ for Pcd in UnusedPcdFullList:\r
+ if Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName in GlobalData.gConditionalPcds:\r
+ continue\r
+ UnusedPcdList.append(Pcd)\r
+\r
+ for Pcd in UnusedPcdList:\r
+ PcdList = self.UnusedPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])\r
+ if Pcd not in PcdList:\r
+ PcdList.append(Pcd)\r
\r
for Module in Pa.Platform.Modules.values():\r
#\r
# Collect PCD DEC default value.\r
#\r
self.DecPcdDefault = {}\r
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
- for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
- DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
- self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)\r
+ self._GuidDict = {}\r
+ for Pa in Wa.AutoGenObjectList:\r
+ for Package in Pa.PackageList:\r
+ Guids = Package.Guids\r
+ self._GuidDict.update(Guids)\r
+ for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
+ DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
+ self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)\r
#\r
# Collect PCDs defined in DSC common section\r
#\r
self.DscPcdDefault = {}\r
- for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:\r
- for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:\r
- DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue\r
+ for Pa in Wa.AutoGenObjectList:\r
+ for (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds:\r
+ DscDefaultValue = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DscDefaultValue\r
if DscDefaultValue:\r
self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue\r
\r
+ def GenerateReport(self, File, ModulePcdSet):\r
+ if not ModulePcdSet:\r
+ if self.ConditionalPcds:\r
+ self.GenerateReportDetail(File, ModulePcdSet, 1)\r
+ if self.UnusedPcds:\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
# Generate report for PCD information\r
#\r
# @param File The file object for report\r
# @param ModulePcdSet Set of all PCDs referenced by module or None for\r
# platform PCD report\r
+ # @param ReportySubType 0 means platform/module PCD report, 1 means Conditional\r
+ # directives section report, 2 means Unused Pcds section report\r
# @param DscOverridePcds Module DSC override PCDs set\r
#\r
- def GenerateReport(self, File, ModulePcdSet):\r
- if ModulePcdSet == None:\r
- #\r
- # For platform global PCD section\r
- #\r
+ def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType = 0):\r
+ PcdDict = self.AllPcds\r
+ if ReportSubType == 1:\r
+ PcdDict = self.ConditionalPcds\r
+ elif ReportSubType == 2:\r
+ PcdDict = self.UnusedPcds\r
+\r
+ if not ModulePcdSet:\r
FileWrite(File, gSectionStart)\r
- FileWrite(File, "Platform Configuration Database Report")\r
+ if ReportSubType == 1:\r
+ FileWrite(File, "Conditional Directives used by the build system")\r
+ elif ReportSubType == 2:\r
+ FileWrite(File, "PCDs not used by modules or in conditional directives")\r
+ else:\r
+ FileWrite(File, "Platform Configuration Database Report")\r
+\r
+ FileWrite(File, " *B - PCD override in the build option")\r
FileWrite(File, " *P - Platform scoped PCD override in DSC file")\r
FileWrite(File, " *F - Platform scoped PCD override in FDF file")\r
- FileWrite(File, " *M - Module scoped PCD override")\r
+ if not ReportSubType:\r
+ FileWrite(File, " *M - Module scoped PCD override")\r
FileWrite(File, gSectionSep)\r
else:\r
- #\r
- # For module PCD sub-section\r
- #\r
- FileWrite(File, gSubSectionStart)\r
- FileWrite(File, "PCD")\r
- FileWrite(File, gSubSectionSep)\r
-\r
- for Key in self.AllPcds:\r
+ if not ReportSubType and ModulePcdSet:\r
+ #\r
+ # For module PCD sub-section\r
+ #\r
+ FileWrite(File, gSubSectionStart)\r
+ FileWrite(File, TAB_BRG_PCD)\r
+ FileWrite(File, gSubSectionSep)\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 self.AllPcds[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 self.AllPcds[Key][Type]:\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
- DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue)\r
- InfDefaultValue = None\r
- \r
- PcdValue = DecDefaultValue\r
- if DscDefaultValue:\r
- PcdValue = DscDefaultValue\r
- if ModulePcdSet != None:\r
- if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:\r
- continue\r
- InfDefault, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]\r
- if InfDefault == "":\r
- InfDefault = None\r
- if First:\r
- if ModulePcdSet == None:\r
- FileWrite(File, "")\r
- FileWrite(File, Key)\r
- First = False\r
-\r
-\r
- if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):\r
- PcdValueNumber = int(PcdValue.strip(), 0)\r
- if DecDefaultValue == None:\r
- DecMatch = True\r
- else:\r
- DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)\r
- DecMatch = (DecDefaultValueNumber == PcdValueNumber)\r
-\r
- if InfDefaultValue == None:\r
- InfMatch = True\r
- else:\r
- InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)\r
- InfMatch = (InfDefaultValueNumber == PcdValueNumber)\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
+ #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 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
+\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_NUMERIC_TYPES:\r
+ if PcdValue.startswith('0') and not PcdValue.lower().startswith('0x') and \\r
+ len(PcdValue) > 1 and PcdValue.lstrip('0'):\r
+ PcdValue = PcdValue.lstrip('0')\r
+ PcdValueNumber = int(PcdValue.strip(), 0)\r
+ if DecDefaultValue is None:\r
+ DecMatch = True\r
+ else:\r
+ if DecDefaultValue.startswith('0') and not DecDefaultValue.lower().startswith('0x') and \\r
+ len(DecDefaultValue) > 1 and DecDefaultValue.lstrip('0'):\r
+ DecDefaultValue = DecDefaultValue.lstrip('0')\r
+ DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)\r
+ DecMatch = (DecDefaultValueNumber == PcdValueNumber)\r
+\r
+ if InfDefaultValue is None:\r
+ InfMatch = True\r
+ else:\r
+ if InfDefaultValue.startswith('0') and not InfDefaultValue.lower().startswith('0x') and \\r
+ len(InfDefaultValue) > 1 and InfDefaultValue.lstrip('0'):\r
+ InfDefaultValue = InfDefaultValue.lstrip('0')\r
+ InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)\r
+ InfMatch = (InfDefaultValueNumber == PcdValueNumber)\r
+\r
+ if DscDefaultValue is None:\r
+ DscMatch = True\r
+ else:\r
+ if DscDefaultValue.startswith('0') and not DscDefaultValue.lower().startswith('0x') and \\r
+ len(DscDefaultValue) > 1 and DscDefaultValue.lstrip('0'):\r
+ DscDefaultValue = DscDefaultValue.lstrip('0')\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 DscDefaultValue == None:\r
- DscMatch = True\r
- else:\r
- DscDefaultValueNumber = int(DscDefaultValue.strip(), 0)\r
- DscMatch = (DscDefaultValueNumber == PcdValueNumber)\r
+ if InfDefaultValue is None:\r
+ InfMatch = True\r
else:\r
- if DecDefaultValue == None:\r
- DecMatch = True\r
- else:\r
- DecMatch = (DecDefaultValue.strip() == PcdValue.strip())\r
+ InfMatch = (InfDefaultValue.strip() == PcdValue.strip())\r
\r
- if InfDefaultValue == None:\r
- InfMatch = True\r
+ if DscDefaultValue is None:\r
+ DscMatch = True\r
+ else:\r
+ DscMatch = (DscDefaultValue.strip() == PcdValue.strip())\r
+\r
+ IsStructure = False\r
+ if self.IsStructurePcd(Pcd.TokenCName, Pcd.TokenSpaceGuidCName):\r
+ IsStructure = True\r
+ if TypeName in ('DYNVPD', 'DEXVPD'):\r
+ SkuInfoList = Pcd.SkuInfoList\r
+ Pcd = GlobalData.gStructurePcd[self.Arch][(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)]\r
+ Pcd.DatumType = Pcd.StructName\r
+ if TypeName in ('DYNVPD', 'DEXVPD'):\r
+ Pcd.SkuInfoList = SkuInfoList\r
+ if Pcd.PcdValueFromComm or Pcd.PcdFieldValueFromComm:\r
+ BuildOptionMatch = True\r
+ DecMatch = False\r
+ elif Pcd.PcdValueFromFdf or Pcd.PcdFieldValueFromFdf:\r
+ DscDefaultValue = True\r
+ DscMatch = True\r
+ DecMatch = False\r
+ elif Pcd.SkuOverrideValues:\r
+ DscOverride = False\r
+ if Pcd.DefaultFromDSC:\r
+ DscOverride = True\r
else:\r
- InfMatch = (InfDefaultValue.strip() == PcdValue.strip())\r
-\r
- if DscDefaultValue == None:\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
+ if not Pcd.SkuInfoList:\r
+ OverrideValues = Pcd.SkuOverrideValues\r
+ if OverrideValues:\r
+ for Data in OverrideValues.values():\r
+ Struct = list(Data.values())\r
+ if Struct:\r
+ DscOverride = self.ParseStruct(Struct[0])\r
+ break\r
+ else:\r
+ SkuList = sorted(Pcd.SkuInfoList.keys())\r
+ for Sku in SkuList:\r
+ SkuInfo = Pcd.SkuInfoList[Sku]\r
+ if 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
+ if DscOverride:\r
+ break\r
+ if DscOverride:\r
+ DscDefaultValue = True\r
DscMatch = True\r
+ DecMatch = False\r
else:\r
- DscMatch = (DscDefaultValue.strip() == PcdValue.strip())\r
-\r
- #\r
- # Report PCD item according to their override relationship\r
- #\r
- if DecMatch and InfMatch:\r
- FileWrite(File, ' %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip()))\r
+ DecMatch = True\r
else:\r
- if DscMatch:\r
- if (Pcd.TokenCName, Key) in self.FdfPcdSet:\r
- FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip()))\r
- else:\r
- FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip()))\r
- else:\r
- FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', PcdValue.strip()))\r
- \r
- if TypeName in ('DYNHII', 'DEXHII', 'DYNVPD', 'DEXVPD'):\r
- for SkuInfo in Pcd.SkuInfoList.values():\r
- if TypeName in ('DYNHII', 'DEXHII'):\r
- FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset)) \r
- else:\r
- FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset))\r
- \r
- if not DscMatch and DscDefaultValue != None:\r
- FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValue.strip()))\r
-\r
- if not InfMatch and InfDefaultValue != None:\r
- FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue.strip()))\r
+ DscDefaultValue = True\r
+ DscMatch = True\r
+ DecMatch = False\r
\r
- if not DecMatch and DecDefaultValue != None:\r
- FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue.strip()))\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, '*P')\r
+ else:\r
+ self.PrintPcdValue(File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValBak, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, '*M')\r
\r
- if ModulePcdSet == None:\r
+ if ModulePcdSet is None:\r
+ if IsStructure:\r
+ continue\r
+ if not TypeName in ('PATCH', 'FLAG', 'FIXED'):\r
+ continue\r
+ if not BuildOptionMatch:\r
ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {})\r
for ModulePath in ModuleOverride:\r
ModuleDefault = ModuleOverride[ModulePath]\r
- if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):\r
+ if Pcd.DatumType in TAB_PCD_NUMERIC_TYPES:\r
+ if ModuleDefault.startswith('0') and not ModuleDefault.lower().startswith('0x') and \\r
+ len(ModuleDefault) > 1 and ModuleDefault.lstrip('0'):\r
+ ModuleDefault = ModuleDefault.lstrip('0')\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
- FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip()))\r
-\r
- if ModulePcdSet == None:\r
+ IsByteArray, ArrayList = ByteArrayForamt(ModuleDefault.strip())\r
+ if IsByteArray:\r
+ FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 15, ModulePath, '{'))\r
+ for Array in ArrayList:\r
+ FileWrite(File, Array)\r
+ else:\r
+ Value = ModuleDefault.strip()\r
+ if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+ if Value.startswith(('0x', '0X')):\r
+ Value = '{} ({:d})'.format(Value, int(Value, 0))\r
+ else:\r
+ Value = "0x{:X} ({})".format(int(Value, 0), Value)\r
+ FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 15, ModulePath, Value))\r
+\r
+ if ModulePcdSet is None:\r
FileWrite(File, gSectionEnd)\r
else:\r
- FileWrite(File, gSubSectionEnd)\r
+ if not ReportSubType and ModulePcdSet:\r
+ FileWrite(File, gSubSectionEnd)\r
+\r
+ def ParseStruct(self, struct):\r
+ HasDscOverride = False\r
+ if struct:\r
+ for _, Values in list(struct.items()):\r
+ for Key, value in Values.items():\r
+ if value[1] and value[1].endswith('.dsc'):\r
+ HasDscOverride = True\r
+ break\r
+ if HasDscOverride == True:\r
+ break\r
+ return HasDscOverride\r
+\r
+ def PrintPcdDefault(self, File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue):\r
+ if not DscMatch and DscDefaultValue is not None:\r
+ Value = DscDefaultValue.strip()\r
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if IsByteArray:\r
+ FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', "{"))\r
+ for Array in ArrayList:\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
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if IsByteArray:\r
+ FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', "{"))\r
+ for Array in ArrayList:\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
+ Value = DecDefaultValue.strip()\r
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if IsByteArray:\r
+ FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', "{"))\r
+ for Array in ArrayList:\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
+ for filedvalues in Pcd.DefaultValues.values():\r
+ self.PrintStructureInfo(File, filedvalues)\r
+ if DecMatch and IsStructure:\r
+ for filedvalues in Pcd.DefaultValues.values():\r
+ self.PrintStructureInfo(File, filedvalues)\r
+\r
+ def PrintPcdValue(self, File, Pcd, PcdTokenCName, TypeName, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue, Flag = ' '):\r
+ if not Pcd.SkuInfoList:\r
+ Value = Pcd.DefaultValue\r
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if IsByteArray:\r
+ FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))\r
+ for Array in ArrayList:\r
+ FileWrite(File, Array)\r
+ else:\r
+ if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:\r
+ if Value.startswith('0') and not Value.lower().startswith('0x') and len(Value) > 1 and Value.lstrip('0'):\r
+ Value = Value.lstrip('0')\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
+ FiledOverrideFlag = False\r
+ if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) in GlobalData.gPcdSkuOverrides:\r
+ OverrideValues = GlobalData.gPcdSkuOverrides[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]\r
+ else:\r
+ OverrideValues = Pcd.SkuOverrideValues\r
+ if OverrideValues:\r
+ for Data in OverrideValues.values():\r
+ Struct = list(Data.values())\r
+ if Struct:\r
+ OverrideFieldStruct = self.OverrideFieldValue(Pcd, Struct[0])\r
+ self.PrintStructureInfo(File, OverrideFieldStruct)\r
+ FiledOverrideFlag = True\r
+ break\r
+ if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):\r
+ OverrideFieldStruct = self.OverrideFieldValue(Pcd, {})\r
+ self.PrintStructureInfo(File, OverrideFieldStruct)\r
+ self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
+ else:\r
+ FirstPrint = True\r
+ SkuList = sorted(Pcd.SkuInfoList.keys())\r
+ for Sku in SkuList:\r
+ SkuInfo = Pcd.SkuInfoList[Sku]\r
+ SkuIdName = SkuInfo.SkuIdName\r
+ if TypeName in ('DYNHII', 'DEXHII'):\r
+ if SkuInfo.DefaultStoreDict:\r
+ DefaultStoreList = sorted(SkuInfo.DefaultStoreDict.keys())\r
+ for DefaultStore in DefaultStoreList:\r
+ Value = SkuInfo.DefaultStoreDict[DefaultStore]\r
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if Pcd.DatumType == 'BOOLEAN':\r
+ Value = str(int(Value, 0))\r
+ if FirstPrint:\r
+ FirstPrint = False\r
+ if IsByteArray:\r
+ if self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '{'))\r
+ elif self.DefaultStoreSingle and not self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '{'))\r
+ elif not self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + DefaultStore + ')', '{'))\r
+ else:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
+ for Array in ArrayList:\r
+ FileWrite(File, 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
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value))\r
+ elif not self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + DefaultStore + ')', Value))\r
+ else:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', Value))\r
+ else:\r
+ if IsByteArray:\r
+ if self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '{'))\r
+ elif self.DefaultStoreSingle and not self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '{'))\r
+ elif not self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + DefaultStore + ')', '{'))\r
+ else:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', '{'))\r
+ for Array in ArrayList:\r
+ FileWrite(File, 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
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value))\r
+ elif not self.DefaultStoreSingle and self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + DefaultStore + ')', Value))\r
+ else:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s %10s = %s' % (self.MaxLen, ' ', TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', '(' + DefaultStore + ')', Value))\r
+ FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset))\r
+ if IsStructure:\r
+ OverrideValues = Pcd.SkuOverrideValues[Sku]\r
+ OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[DefaultStore])\r
+ self.PrintStructureInfo(File, OverrideFieldStruct)\r
+ self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
+ else:\r
+ Value = SkuInfo.DefaultValue\r
+ IsByteArray, ArrayList = ByteArrayForamt(Value)\r
+ if Pcd.DatumType == 'BOOLEAN':\r
+ Value = str(int(Value, 0))\r
+ if FirstPrint:\r
+ FirstPrint = False\r
+ if IsByteArray:\r
+ if self.SkuSingle:\r
+ FileWrite(File, ' %-*s : %6s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', "{"))\r
+ else:\r
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', "{"))\r
+ for Array in ArrayList:\r
+ FileWrite(File, 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
+ FileWrite(File, ' %-*s : %6s %10s %10s = %s' % (self.MaxLen, Flag + ' ' + PcdTokenCName, TypeName, '(' + Pcd.DatumType + ')', '(' + SkuIdName + ')', Value))\r
+ else:\r
+ if IsByteArray:\r
+ if self.SkuSingle:\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
+ for Array in ArrayList:\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
+ else:\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
+ VPDPcdItem = (Pcd.TokenSpaceGuidCName + '.' + PcdTokenCName, SkuIdName, SkuInfo.VpdOffset, Pcd.MaxDatumSize, SkuInfo.DefaultValue)\r
+ if VPDPcdItem not in VPDPcdList:\r
+ VPDPcdList.append(VPDPcdItem)\r
+ if IsStructure:\r
+ FiledOverrideFlag = False\r
+ OverrideValues = Pcd.SkuOverrideValues[Sku]\r
+ if OverrideValues:\r
+ Keys = list(OverrideValues.keys())\r
+ OverrideFieldStruct = self.OverrideFieldValue(Pcd, OverrideValues[Keys[0]])\r
+ self.PrintStructureInfo(File, OverrideFieldStruct)\r
+ FiledOverrideFlag = True\r
+ if not FiledOverrideFlag and (Pcd.PcdFieldValueFromComm or Pcd.PcdFieldValueFromFdf):\r
+ OverrideFieldStruct = self.OverrideFieldValue(Pcd, {})\r
+ self.PrintStructureInfo(File, OverrideFieldStruct)\r
+ self.PrintPcdDefault(File, Pcd, IsStructure, DscMatch, DscDefaultValue, InfMatch, InfDefaultValue, DecMatch, DecDefaultValue)\r
+\r
+ def OverrideFieldValue(self, Pcd, OverrideStruct):\r
+ OverrideFieldStruct = collections.OrderedDict()\r
+ if OverrideStruct:\r
+ for _, Values in OverrideStruct.items():\r
+ for Key,value in Values.items():\r
+ if value[1] and value[1].endswith('.dsc'):\r
+ OverrideFieldStruct[Key] = value\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 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
+ def StrtoHex(self, value):\r
+ try:\r
+ value = hex(int(value))\r
+ return value\r
+ except:\r
+ if value.startswith("L\"") and value.endswith("\""):\r
+ valuelist = []\r
+ for ch in value[2:-1]:\r
+ valuelist.append(hex(ord(ch)))\r
+ valuelist.append('0x00')\r
+ return valuelist\r
+ elif value.startswith("\"") and value.endswith("\""):\r
+ return hex(ord(value[1:-1]))\r
+ elif value.startswith("{") and value.endswith("}"):\r
+ valuelist = []\r
+ if ',' not in value:\r
+ return value[1:-1]\r
+ for ch in value[1:-1].split(','):\r
+ ch = ch.strip()\r
+ if ch.startswith('0x') or ch.startswith('0X'):\r
+ valuelist.append(ch)\r
+ continue\r
+ try:\r
+ valuelist.append(hex(int(ch.strip())))\r
+ except:\r
+ pass\r
+ return valuelist\r
+ else:\r
+ return value\r
\r
+ def IsStructurePcd(self, PcdToken, PcdTokenSpaceGuid):\r
+ if GlobalData.gStructurePcd and (self.Arch in GlobalData.gStructurePcd) and ((PcdToken, PcdTokenSpaceGuid) in GlobalData.gStructurePcd[self.Arch]):\r
+ return True\r
+ else:\r
+ return False\r
\r
##\r
# Reports platform and module Prediction information\r
# 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
\r
if Module.Guid and not Module.IsLibrary:\r
EntryPoint = " ".join(Module.Module.ModuleEntryPointList)\r
- if int(str(Module.AutoGenVersion), 0) >= 0x00010005:\r
- RealEntryPoint = "_ModuleEntryPoint"\r
- else:\r
- RealEntryPoint = EntryPoint\r
- if EntryPoint == "_ModuleEntryPoint":\r
- CCFlags = Module.BuildOption.get("CC", {}).get("FLAGS", "")\r
- Match = gGlueLibEntryPoint.search(CCFlags)\r
- if Match:\r
- EntryPoint = Match.group(1)\r
+\r
+ RealEntryPoint = "_ModuleEntryPoint"\r
\r
self._FfsEntryPoint[Module.Guid.upper()] = (EntryPoint, RealEntryPoint)\r
\r
if Wa.FdfProfile:\r
for Fd in Wa.FdfProfile.FdDict:\r
for FdRegion in Wa.FdfProfile.FdDict[Fd].RegionList:\r
- if FdRegion.RegionType != "FV":\r
+ if FdRegion.RegionType != BINARY_FILE_TYPE_FV:\r
continue\r
for FvName in FdRegion.RegionDataList:\r
if FvName in self._FvList:\r
GuidList = os.path.join(self._EotDir, "GuidList.txt")\r
DispatchList = os.path.join(self._EotDir, "Dispatch.txt")\r
\r
- TempFile = open(SourceList, "w+")\r
+ TempFile = []\r
for Item in self._SourceList:\r
FileWrite(TempFile, Item)\r
- TempFile.close()\r
- TempFile = open(GuidList, "w+")\r
+ SaveFileOnChange(SourceList, "".join(TempFile), False)\r
+ TempFile = []\r
for Key in self._GuidMap:\r
FileWrite(TempFile, "%s %s" % (Key, self._GuidMap[Key]))\r
- TempFile.close()\r
+ SaveFileOnChange(GuidList, "".join(TempFile), False)\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
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
# @param Wa Workspace context information\r
#\r
def _DiscoverNestedFvList(self, FvName, Wa):\r
- for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:\r
- for Section in Ffs.SectionList:\r
- try:\r
- for FvSection in Section.SectionList:\r
- if FvSection.FvName in self.FvList:\r
- continue\r
- self._GuidsDb[Ffs.NameGuid.upper()] = FvSection.FvName\r
- self.FvList.append(FvSection.FvName)\r
- self.FvInfo[FvSection.FvName] = ("Nested FV", 0, 0)\r
- self._DiscoverNestedFvList(FvSection.FvName, Wa)\r
- except AttributeError:\r
- pass\r
+ FvDictKey=FvName.upper()\r
+ if FvDictKey in Wa.FdfProfile.FvDict:\r
+ for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:\r
+ for Section in Ffs.SectionList:\r
+ try:\r
+ for FvSection in Section.SectionList:\r
+ if FvSection.FvName in self.FvList:\r
+ continue\r
+ self._GuidsDb[Ffs.NameGuid.upper()] = FvSection.FvName\r
+ self.FvList.append(FvSection.FvName)\r
+ self.FvInfo[FvSection.FvName] = ("Nested FV", 0, 0)\r
+ self._DiscoverNestedFvList(FvSection.FvName, Wa)\r
+ except AttributeError:\r
+ pass\r
\r
##\r
# Constructor function for class FdRegionReport\r
self.FvInfo = {}\r
self._GuidsDb = {}\r
self._FvDir = Wa.FvDir\r
+ self._WorkspaceDir = Wa.WorkspaceDir\r
\r
#\r
# If the input FdRegion is not a firmware volume,\r
# we are done.\r
#\r
- if self.Type != "FV":\r
+ if self.Type != BINARY_FILE_TYPE_FV:\r
return\r
\r
#\r
self._DiscoverNestedFvList(FvName, Wa)\r
\r
PlatformPcds = {}\r
- \r
#\r
# Collect PCDs declared in DEC files.\r
#\r
- for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
- for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
- DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
- PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue\r
+ for Pa in Wa.AutoGenObjectList:\r
+ for Package in Pa.PackageList:\r
+ for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:\r
+ DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue\r
+ PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue\r
#\r
- # Collect PCDs defined in DSC common section\r
+ # Collect PCDs defined in DSC file\r
#\r
- for Platform in Wa.BuildDatabase.WorkspaceDb.PlatformList:\r
- for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:\r
- DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue\r
+ for Pa in Wa.AutoGenObjectList:\r
+ for (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds:\r
+ DscDefaultValue = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue\r
PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue\r
\r
#\r
# Add PEI and DXE a priori files GUIDs defined in PI specification.\r
#\r
- self._GuidsDb["1B45CC0A-156A-428A-AF62-49864DA0E6E6"] = "PEI Apriori"\r
- self._GuidsDb["FC510EE7-FFDC-11D4-BD41-0080C73C8881"] = "DXE Apriori"\r
+ self._GuidsDb[PEI_APRIORI_GUID] = "PEI Apriori"\r
+ self._GuidsDb[DXE_APRIORI_GUID] = "DXE Apriori"\r
#\r
# Add ACPI table storage file\r
#\r
for Pa in Wa.AutoGenObjectList:\r
for ModuleKey in Pa.Platform.Modules:\r
M = Pa.Platform.Modules[ModuleKey].M\r
- InfPath = os.path.join(Wa.WorkspaceDir, M.MetaFile.File)\r
+ InfPath = mws.join(Wa.WorkspaceDir, M.MetaFile.File)\r
self._GuidsDb[M.Guid.upper()] = "%s (%s)" % (M.Module.BaseName, InfPath)\r
\r
#\r
# Collect the GUID map in the FV firmware volume\r
#\r
for FvName in self.FvList:\r
- for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:\r
- try:\r
- #\r
- # collect GUID map for binary EFI file in FDF file.\r
- #\r
- Guid = Ffs.NameGuid.upper()\r
- Match = gPcdGuidPattern.match(Ffs.NameGuid)\r
- if Match:\r
- PcdTokenspace = Match.group(1)\r
- PcdToken = Match.group(2)\r
- if (PcdToken, PcdTokenspace) in PlatformPcds:\r
- GuidValue = PlatformPcds[(PcdToken, PcdTokenspace)]\r
- Guid = GuidStructureByteArrayToGuidString(GuidValue).upper()\r
- for Section in Ffs.SectionList:\r
- try:\r
- ModuleSectFile = os.path.join(Wa.WorkspaceDir, Section.SectFileName)\r
- self._GuidsDb[Guid] = ModuleSectFile\r
- except AttributeError:\r
- pass\r
- except AttributeError:\r
- pass\r
+ FvDictKey=FvName.upper()\r
+ if FvDictKey in Wa.FdfProfile.FvDict:\r
+ for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:\r
+ try:\r
+ #\r
+ # collect GUID map for binary EFI file in FDF file.\r
+ #\r
+ Guid = Ffs.NameGuid.upper()\r
+ Match = gPcdGuidPattern.match(Ffs.NameGuid)\r
+ if Match:\r
+ PcdTokenspace = Match.group(1)\r
+ PcdToken = Match.group(2)\r
+ if (PcdToken, PcdTokenspace) in PlatformPcds:\r
+ GuidValue = PlatformPcds[(PcdToken, PcdTokenspace)]\r
+ Guid = GuidStructureByteArrayToGuidString(GuidValue).upper()\r
+ for Section in Ffs.SectionList:\r
+ try:\r
+ ModuleSectFile = mws.join(Wa.WorkspaceDir, Section.SectFileName)\r
+ self._GuidsDb[Guid] = ModuleSectFile\r
+ except AttributeError:\r
+ pass\r
+ except AttributeError:\r
+ pass\r
\r
\r
##\r
FileWrite(File, "Type: %s" % Type)\r
FileWrite(File, "Base Address: 0x%X" % BaseAddress)\r
\r
- if self.Type == "FV":\r
+ if self.Type == BINARY_FILE_TYPE_FV:\r
FvTotalSize = 0\r
FvTakenSize = 0\r
FvFreeSize = 0\r
- FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt")\r
+ if FvName.upper().endswith('.FV'):\r
+ FileExt = FvName + ".txt"\r
+ else:\r
+ FileExt = FvName + ".Fv.txt"\r
+\r
+ if not os.path.isfile(FileExt):\r
+ FvReportFileName = mws.join(self._WorkspaceDir, FileExt)\r
+ if not os.path.isfile(FvReportFileName):\r
+ FvReportFileName = os.path.join(self._FvDir, FileExt)\r
try:\r
#\r
# Collect size info in the firmware volume.\r
for Match in gOffsetGuidPattern.finditer(FvReport):\r
Guid = Match.group(2).upper()\r
OffsetInfo[Match.group(1)] = self._GuidsDb.get(Guid, Guid)\r
- OffsetList = OffsetInfo.keys()\r
- OffsetList.sort()\r
+ OffsetList = sorted(OffsetInfo.keys())\r
for Offset in OffsetList:\r
FileWrite (File, "%s %s" % (Offset, OffsetInfo[Offset]))\r
except IOError:\r
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
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, TAB_FV_DIRECTORY)\r
+ self.VPDBaseAddress = 0\r
+ self.VPDSize = 0\r
+ for index, FdRegion in enumerate(Fd.RegionList):\r
+ if str(FdRegion.RegionType) is 'FILE' and Wa.Platform.VpdToolGuid in str(FdRegion.RegionDataList):\r
+ self.VPDBaseAddress = self.FdRegionList[index].BaseAddress\r
+ self.VPDSize = self.FdRegionList[index].Size\r
+ break\r
\r
##\r
# Generate report for the firmware device.\r
for FdRegionItem in self.FdRegionList:\r
FdRegionItem.GenerateReport(File)\r
\r
+ if VPDPcdList:\r
+ VPDPcdList.sort(key=lambda x: int(x[2], 0))\r
+ FileWrite(File, gSubSectionStart)\r
+ FileWrite(File, "FD VPD Region")\r
+ FileWrite(File, "Base Address: 0x%X" % self.VPDBaseAddress)\r
+ FileWrite(File, "Size: 0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0))\r
+ FileWrite(File, gSubSectionSep)\r
+ for item in VPDPcdList:\r
+ # Add BaseAddress for offset\r
+ Offset = '0x%08X' % (int(item[2], 16) + self.VPDBaseAddress)\r
+ IsByteArray, ArrayList = ByteArrayForamt(item[-1])\r
+ Skuinfo = item[1]\r
+ if len(GlobalData.gSkuids) == 1 :\r
+ Skuinfo = GlobalData.gSkuids[0]\r
+ if IsByteArray:\r
+ FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], '{'))\r
+ for Array in ArrayList:\r
+ FileWrite(File, Array)\r
+ else:\r
+ FileWrite(File, "%s | %s | %s | %s | %s" % (item[0], Skuinfo, Offset, item[3], item[-1]))\r
+ FileWrite(File, gSubSectionEnd)\r
FileWrite(File, gSectionEnd)\r
\r
\r
self.PcdReport = PcdReport(Wa)\r
\r
self.FdReportList = []\r
- if "FLASH" in ReportType and Wa.FdfProfile and MaList == None:\r
+ if "FLASH" in ReportType and Wa.FdfProfile and MaList is None:\r
for Fd in Wa.FdfProfile.FdDict:\r
self.FdReportList.append(FdReport(Wa.FdfProfile.FdDict[Fd], Wa))\r
\r
self.DepexParser = None\r
if "DEPEX" in ReportType:\r
self.DepexParser = DepexParser(Wa)\r
- \r
+\r
self.ModuleReportList = []\r
- if MaList != None:\r
+ if MaList is not None:\r
self._IsModuleBuild = True\r
for Ma in MaList:\r
self.ModuleReportList.append(ModuleReport(Ma, ReportType))\r
else:\r
self._IsModuleBuild = False\r
for Pa in Wa.AutoGenObjectList:\r
+ ModuleAutoGenList = []\r
for ModuleKey in Pa.Platform.Modules:\r
- self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, ReportType))\r
+ ModuleAutoGenList.append(Pa.Platform.Modules[ModuleKey].M)\r
+ if GlobalData.gFdfParser is not None:\r
+ if Pa.Arch in GlobalData.gFdfParser.Profile.InfDict:\r
+ INFList = GlobalData.gFdfParser.Profile.InfDict[Pa.Arch]\r
+ for InfName in INFList:\r
+ InfClass = PathClass(NormPath(InfName), Wa.WorkspaceDir, Pa.Arch)\r
+ Ma = ModuleAutoGen(Wa, InfClass, Pa.BuildTarget, Pa.ToolChain, Pa.Arch, Wa.MetaFile)\r
+ if Ma is None:\r
+ continue\r
+ if Ma not in ModuleAutoGenList:\r
+ ModuleAutoGenList.append(Ma)\r
+ for MGen in ModuleAutoGenList:\r
+ self.ModuleReportList.append(ModuleReport(MGen, ReportType))\r
\r
\r
\r
# @param self The object pointer\r
# @param File The file object for report\r
# @param BuildDuration The total time to build the modules\r
+ # @param AutoGenTime The total time of AutoGen Phase\r
+ # @param MakeTime The total time of Make Phase\r
+ # @param GenFdsTime The total time of GenFds Phase\r
# @param ReportType The kind of report items in the final report file\r
#\r
- def GenerateReport(self, File, BuildDuration, ReportType):\r
+ def GenerateReport(self, File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, ReportType):\r
FileWrite(File, "Platform Summary")\r
FileWrite(File, "Platform Name: %s" % self.PlatformName)\r
FileWrite(File, "Platform DSC Path: %s" % self.PlatformDscPath)\r
FileWrite(File, "Architectures: %s" % self.Architectures)\r
FileWrite(File, "Tool Chain: %s" % self.ToolChain)\r
FileWrite(File, "Target: %s" % self.Target)\r
+ if GlobalData.gSkuids:\r
+ FileWrite(File, "SKUID: %s" % " ".join(GlobalData.gSkuids))\r
+ if GlobalData.gDefaultStores:\r
+ FileWrite(File, "DefaultStore: %s" % " ".join(GlobalData.gDefaultStores))\r
FileWrite(File, "Output Path: %s" % self.OutputPath)\r
FileWrite(File, "Build Environment: %s" % self.BuildEnvironment)\r
FileWrite(File, "Build Duration: %s" % BuildDuration)\r
+ if AutoGenTime:\r
+ FileWrite(File, "AutoGen Duration: %s" % AutoGenTime)\r
+ if MakeTime:\r
+ FileWrite(File, "Make Duration: %s" % MakeTime)\r
+ if GenFdsTime:\r
+ FileWrite(File, "GenFds Duration: %s" % GenFdsTime)\r
FileWrite(File, "Report Content: %s" % ", ".join(ReportType))\r
\r
+ if GlobalData.MixedPcd:\r
+ FileWrite(File, gSectionStart)\r
+ FileWrite(File, "The following PCDs use different access methods:")\r
+ FileWrite(File, gSectionSep)\r
+ for PcdItem in GlobalData.MixedPcd:\r
+ FileWrite(File, "%s.%s" % (str(PcdItem[1]), str(PcdItem[0])))\r
+ FileWrite(File, gSectionEnd)\r
+\r
if not self._IsModuleBuild:\r
if "PCD" in ReportType:\r
self.PcdReport.GenerateReport(File, None)\r
- \r
+\r
if "FLASH" in ReportType:\r
for FdReportListItem in self.FdReportList:\r
FdReportListItem.GenerateReport(File)\r
if 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
else:\r
- self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "FLASH", "FIXED_ADDRESS"]\r
+ self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "HASH", "FLASH", "FIXED_ADDRESS"]\r
##\r
# Adds platform report to the list\r
#\r
#\r
# @param self The object pointer\r
# @param BuildDuration The total time to build the modules\r
+ # @param AutoGenTime The total time of AutoGen phase\r
+ # @param MakeTime The total time of Make phase\r
+ # @param GenFdsTime The total time of GenFds phase\r
#\r
- def GenerateReport(self, BuildDuration):\r
+ def GenerateReport(self, BuildDuration, AutoGenTime, MakeTime, GenFdsTime):\r
if self.ReportFile:\r
try:\r
- File = StringIO('')\r
+ File = []\r
for (Wa, MaList) in self.ReportList:\r
- PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, self.ReportType)\r
- SaveFileOnChange(self.ReportFile, File.getvalue(), False)\r
+ PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, AutoGenTime, MakeTime, GenFdsTime, self.ReportType)\r
+ Content = FileLinesSplit(''.join(File), gLineMaxLength)\r
+ SaveFileOnChange(self.ReportFile, Content, False)\r
EdkLogger.quiet("Build report can be found at %s" % os.path.abspath(self.ReportFile))\r
except IOError:\r
EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile)\r
except:\r
EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False)\r
EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc()))\r
- File.close()\r
- \r
+\r
# This acts like the main() function for the script, unless it is 'import'ed into another script.\r
if __name__ == '__main__':\r
pass\r