mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
This reverts commit 6693f359b3c213513c5096a06c6f67244a44dc52.. 678f85131238622e576705117e299d81cff755c9. Python3 migration is the fundamental change. It requires every developer to install Python3. Before this migration, the well communication and wide verification must be done. But now, most people is not aware of this change, and not try it. So, Python3 migration is reverted and be moved to edk2-staging Python3 branch for the edk2 user evaluation. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com>
475 lines
17 KiB
Python
475 lines
17 KiB
Python
## @file
|
|
# This file is used to create report for Eot tool
|
|
#
|
|
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
# This program and the accompanying materials
|
|
# are licensed and made available under the terms and conditions of the BSD License
|
|
# which accompanies this distribution. The full text of the license may be found at
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
#
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
#
|
|
|
|
##
|
|
# 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:
|
|
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:
|
|
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:
|
|
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()">  DEPEX 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()">  Consumed 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/Portocol
|
|
|
|
# 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()">  Produced 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()
|