summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py468
1 files changed, 468 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py
new file mode 100755
index 00000000..1d85c715
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Report.py
@@ -0,0 +1,468 @@
+## @file
+# This file is used to create report for Eot tool
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+from __future__ import absolute_import
+import Common.LongFilePathOs as os
+from . import EotGlobalData
+from Common.LongFilePathSupport import OpenLongFilePath as open
+
+## Report() class
+#
+# This class defined Report
+#
+# @param object: Inherited from object class
+#
+class Report(object):
+ ## The constructor
+ #
+ # @param self: The object pointer
+ # @param ReportName: name of the report
+ # @param FvObj: FV object after parsing FV images
+ #
+ def __init__(self, ReportName = 'Report.html', FvObj = None, DispatchName=None):
+ self.ReportName = ReportName
+ self.Op = open(ReportName, 'w+')
+ self.DispatchList = None
+ if DispatchName:
+ self.DispatchList = open(DispatchName, 'w+')
+ self.FvObj = FvObj
+ self.FfsIndex = 0
+ self.PpiIndex = 0
+ self.ProtocolIndex = 0
+ if EotGlobalData.gMACRO['EFI_SOURCE'] == '':
+ EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gMACRO['EDK_SOURCE']
+
+ ## WriteLn() method
+ #
+ # Write a line in the report
+ #
+ # @param self: The object pointer
+ # @param Line: The lint to be written into
+ #
+ def WriteLn(self, Line):
+ self.Op.write('%s\n' % Line)
+
+ ## GenerateReport() method
+ #
+ # A caller to generate report
+ #
+ # @param self: The object pointer
+ #
+ def GenerateReport(self):
+ self.GenerateHeader()
+ self.GenerateFv()
+ self.GenerateTail()
+ self.Op.close()
+ self.GenerateUnDispatchedList()
+
+ ## GenerateUnDispatchedList() method
+ #
+ # Create a list for not dispatched items
+ #
+ # @param self: The object pointer
+ #
+ def GenerateUnDispatchedList(self):
+ FvObj = self.FvObj
+ EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)
+ for Item in FvObj.UnDispatchedFfsDict.keys():
+ EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])
+
+ ## GenerateFv() method
+ #
+ # Generate FV information
+ #
+ # @param self: The object pointer
+ #
+ def GenerateFv(self):
+ FvObj = self.FvObj
+ Content = """ <tr>
+ <td width="20%%"><strong>Name</strong></td>
+ <td width="60%%"><strong>Guid</strong></td>
+ <td width="20%%"><strong>Size</strong></td>
+ </tr>"""
+ self.WriteLn(Content)
+
+ for Info in FvObj.BasicInfo:
+ FvName = Info[0]
+ FvGuid = Info[1]
+ FvSize = Info[2]
+
+ Content = """ <tr>
+ <td>%s</td>
+ <td>%s</td>
+ <td>%s</td>
+ </tr>""" % (FvName, FvGuid, FvSize)
+ self.WriteLn(Content)
+
+ Content = """ <td colspan="3"><table width="100%%" border="1">
+ <tr>"""
+ self.WriteLn(Content)
+
+ EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')
+ for FfsId in FvObj.OrderedFfsDict.keys():
+ self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+
+ # For UnDispatched
+ Content = """ <td colspan="3"><table width="100%%" border="1">
+ <tr>
+ <tr><strong>UnDispatched</strong></tr>"""
+ self.WriteLn(Content)
+
+ EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')
+ for FfsId in FvObj.UnDispatchedFfsDict.keys():
+ self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+
+ ## GenerateDepex() method
+ #
+ # Generate Depex information
+ #
+ # @param self: The object pointer
+ # @param DepexString: A DEPEX string needed to be parsed
+ #
+ def GenerateDepex(self, DepexString):
+ NonGuidList = ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
+ ItemList = DepexString.split(' ')
+ DepexString = ''
+ for Item in ItemList:
+ if Item not in NonGuidList:
+ SqlCommand = """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item)
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ if RecordSet != []:
+ Item = RecordSet[0][0]
+ DepexString = DepexString + Item + ' '
+ Content = """ <tr>
+ <td width="5%%"></td>
+ <td width="95%%">%s</td>
+ </tr>""" % (DepexString)
+ self.WriteLn(Content)
+
+ ## GeneratePpi() method
+ #
+ # Generate PPI information
+ #
+ # @param self: The object pointer
+ # @param Name: CName of a GUID
+ # @param Guid: Value of a GUID
+ # @param Type: Type of a GUID
+ #
+ def GeneratePpi(self, Name, Guid, Type):
+ self.GeneratePpiProtocol('Ppi', Name, Guid, Type, self.PpiIndex)
+
+ ## GenerateProtocol() method
+ #
+ # Generate PROTOCOL information
+ #
+ # @param self: The object pointer
+ # @param Name: CName of a GUID
+ # @param Guid: Value of a GUID
+ # @param Type: Type of a GUID
+ #
+ def GenerateProtocol(self, Name, Guid, Type):
+ self.GeneratePpiProtocol('Protocol', Name, Guid, Type, self.ProtocolIndex)
+
+ ## GeneratePpiProtocol() method
+ #
+ # Generate PPI/PROTOCOL information
+ #
+ # @param self: The object pointer
+ # @param Model: Model of a GUID, PPI or PROTOCOL
+ # @param Name: Name of a GUID
+ # @param Guid: Value of a GUID
+ # @param Type: Type of a GUID
+ # @param CName: CName(Index) of a GUID
+ #
+ def GeneratePpiProtocol(self, Model, Name, Guid, Type, CName):
+ Content = """ <tr>
+ <td width="5%%"></td>
+ <td width="10%%">%s</td>
+ <td width="85%%" colspan="3">%s</td>
+ <!-- %s -->
+ </tr>""" % (Model, Name, Guid)
+ self.WriteLn(Content)
+ if Type == 'Produced':
+ SqlCommand = """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ for Record in RecordSet:
+ SqlCommand = """select FullPath from File
+ where ID = (
+ select DISTINCT BelongsToFile from Inf
+ where Value1 like '%s')""" % Record[0]
+ ModuleSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ Inf = ModuleSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')
+ Function = Record[1]
+ Address = ''
+ for Item in EotGlobalData.gMap:
+ if Function in EotGlobalData.gMap[Item]:
+ Address = EotGlobalData.gMap[Item][Function]
+ break
+ if '_' + Function in EotGlobalData.gMap[Item]:
+ Address = EotGlobalData.gMap[Item]['_' + Function]
+ break
+ Content = """ <tr>
+ <td width="5%%"></td>
+ <td width="10%%">%s</td>
+ <td width="40%%">%s</td>
+ <td width="35%%">%s</td>
+ <td width="10%%">%s</td>
+ </tr>""" % ('Callback', Inf, Function, Address)
+ self.WriteLn(Content)
+
+ ## GenerateFfs() method
+ #
+ # Generate FFS information
+ #
+ # @param self: The object pointer
+ # @param FfsObj: FFS object after FV image is parsed
+ #
+ def GenerateFfs(self, FfsObj):
+ self.FfsIndex = self.FfsIndex + 1
+ if FfsObj is not None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
+ FfsGuid = FfsObj.Guid
+ FfsOffset = FfsObj._OFF_
+ FfsName = 'Unknown-Module'
+ FfsPath = FfsGuid
+ FfsType = FfsObj._TypeName[FfsObj.Type]
+
+ # Hard code for Binary INF
+ if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
+ FfsName = 'Logo'
+
+ if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
+ FfsName = 'AcpiTables'
+
+ if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
+ FfsName = 'Fat'
+
+ # Find FFS Path and Name
+ SqlCommand = """select Value2 from Inf
+ where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
+ and Model = %s and Value1='BASE_NAME'""" % (FfsGuid, 5001, 5001)
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ if RecordSet != []:
+ FfsName = RecordSet[0][0]
+
+ SqlCommand = """select FullPath from File
+ where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
+ and Model = %s""" % (FfsGuid, 5001, 1011)
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ if RecordSet != []:
+ FfsPath = RecordSet[0][0]
+
+ Content = """ <tr>
+ <tr class='styleFfs' id='FfsHeader%s'>
+ <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
+ <td width="15%%">%s</td>
+ <!--<td width="20%%">%s</td>-->
+ <!--<td width="20%%">%s</td>-->
+ <td width="10%%">%s</td>
+ </tr>
+ <tr id='Ffs%s' style='display:none;'>
+ <td colspan="4"><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, FfsPath, FfsName, FfsGuid, FfsOffset, FfsType, self.FfsIndex)
+
+ if self.DispatchList:
+ if FfsObj.Type in [0x04, 0x06]:
+ self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "P", FfsName, FfsPath))
+ if FfsObj.Type in [0x05, 0x07, 0x08, 0x0A]:
+ self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "D", FfsName, FfsPath))
+
+ self.WriteLn(Content)
+
+ EotGlobalData.gOP_DISPATCH_ORDER.write('%s\n' %FfsName)
+
+ if FfsObj.Depex != '':
+ Content = """ <tr>
+ <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspDEPEX expression</span></td>
+ </tr>
+ <tr id='Depex%s' style='display:none;'>
+ <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, self.FfsIndex)
+ self.WriteLn(Content)
+ self.GenerateDepex(FfsObj.Depex)
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+ # End of DEPEX
+
+ # Find Consumed Ppi/Protocol
+ SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
+ where SourceFileFullPath in
+ (select Value1 from Inf where BelongsToFile =
+ (select BelongsToFile from Inf
+ where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
+ and Model = %s)
+ and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
+ % (FfsGuid, 5001, 3007)
+
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ if RecordSet != []:
+ Count = len(RecordSet)
+ Content = """ <tr>
+ <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspConsumed Ppis/Protocols List (%s)</span></td>
+ </tr>
+ <tr id='Consumed%s' style='display:none;'>
+ <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
+ self.WriteLn(Content)
+ self.ProtocolIndex = 0
+ for Record in RecordSet:
+ self.ProtocolIndex = self.ProtocolIndex + 1
+ Name = Record[2]
+ CName = Record[4]
+ Guid = Record[3]
+ Type = Record[1]
+ self.GeneratePpiProtocol(Type, Name, Guid, 'Consumed', CName)
+
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+ #End of Consumed Ppi/Protocol
+
+ # Find Produced Ppi/Protocol
+ SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
+ where SourceFileFullPath in
+ (select Value1 from Inf where BelongsToFile =
+ (select BelongsToFile from Inf
+ where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
+ and Model = %s)
+ and ItemMode = 'Produced' group by GuidName order by ItemType""" \
+ % (FfsGuid, 5001, 3007)
+
+ RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
+ if RecordSet != []:
+ Count = len(RecordSet)
+ Content = """ <tr>
+ <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspProduced Ppis/Protocols List (%s)</span></td>
+ </tr>
+ <tr id='Produced%s' style='display:none;'>
+ <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
+ self.WriteLn(Content)
+ self.PpiIndex = 0
+ for Record in RecordSet:
+ self.PpiIndex = self.PpiIndex + 1
+ Name = Record[2]
+ CName = Record[4]
+ Guid = Record[3]
+ Type = Record[1]
+ self.GeneratePpiProtocol(Type, Name, Guid, 'Produced', CName)
+
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+ RecordSet = None
+ # End of Produced Ppi/Protocol
+
+ Content = """ </table></td>
+ </tr>"""
+ self.WriteLn(Content)
+
+ ## GenerateTail() method
+ #
+ # Generate end tags of HTML report
+ #
+ # @param self: The object pointer
+ #
+ def GenerateTail(self):
+ Tail = """</table>
+</body>
+</html>"""
+ self.WriteLn(Tail)
+
+ ## GenerateHeader() method
+ #
+ # Generate start tags of HTML report
+ #
+ # @param self: The object pointer
+ #
+ def GenerateHeader(self):
+ Header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>Execution Order Tool Report</title>
+<meta http-equiv="Content-Type" content="text/html">
+<style type="text/css">
+<!--
+.styleFfs {
+ color: #006600;
+ font-weight: bold;
+}
+.styleDepex {
+ color: #FF0066;
+ font-weight: bold;
+}
+.styleProduced {
+ color: #0000FF;
+ font-weight: bold;
+}
+.styleConsumed {
+ color: #FF00FF;
+ font-weight: bold;
+}
+-->
+</style>
+<Script type="text/javascript">
+function Display(ParentID, SubID)
+{
+ SubItem = document.getElementById(SubID);
+ ParentItem = document.getElementById(ParentID);
+ if (SubItem.style.display == 'none')
+ {
+ SubItem.style.display = ''
+ ParentItem.style.fontWeight = 'normal'
+ }
+ else
+ {
+ SubItem.style.display = 'none'
+ ParentItem.style.fontWeight = 'bold'
+ }
+
+}
+
+function funOnMouseOver()
+{
+ document.body.style.cursor = "hand";
+}
+
+function funOnMouseOut()
+{
+ document.body.style.cursor = "";
+}
+
+</Script>
+</head>
+
+<body>
+<table width="100%%" border="1">"""
+ self.WriteLn(Header)
+
+##
+#
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+#
+if __name__ == '__main__':
+ # Initialize log system
+ FilePath = 'FVRECOVERYFLOPPY.fv'
+ if FilePath.lower().endswith(".fv"):
+ fd = open(FilePath, 'rb')
+ buf = array('B')
+ try:
+ buf.fromfile(fd, os.path.getsize(FilePath))
+ except EOFError:
+ pass
+
+ fv = FirmwareVolume("FVRECOVERY", buf, 0)
+
+ report = Report('Report.html', fv)
+ report.GenerateReport()