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