]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Eot/Report.py
2 # This file is used to create report for Eot tool
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import absolute_import
12 import Common
.LongFilePathOs
as os
13 from . import EotGlobalData
14 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
18 # This class defined Report
20 # @param object: Inherited from object class
25 # @param self: The object pointer
26 # @param ReportName: name of the report
27 # @param FvObj: FV object after parsing FV images
29 def __init__(self
, ReportName
= 'Report.html', FvObj
= None, DispatchName
=None):
30 self
.ReportName
= ReportName
31 self
.Op
= open(ReportName
, 'w+')
32 self
.DispatchList
= None
34 self
.DispatchList
= open(DispatchName
, 'w+')
38 self
.ProtocolIndex
= 0
39 if EotGlobalData
.gMACRO
['EFI_SOURCE'] == '':
40 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gMACRO
['EDK_SOURCE']
44 # Write a line in the report
46 # @param self: The object pointer
47 # @param Line: The lint to be written into
49 def WriteLn(self
, Line
):
50 self
.Op
.write('%s\n' % Line
)
52 ## GenerateReport() method
54 # A caller to generate report
56 # @param self: The object pointer
58 def GenerateReport(self
):
63 self
.GenerateUnDispatchedList()
65 ## GenerateUnDispatchedList() method
67 # Create a list for not dispatched items
69 # @param self: The object pointer
71 def GenerateUnDispatchedList(self
):
73 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.Name
)
74 for Item
in FvObj
.UnDispatchedFfsDict
.keys():
75 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.UnDispatchedFfsDict
[Item
])
77 ## GenerateFv() method
79 # Generate FV information
81 # @param self: The object pointer
86 <td width="20%%"><strong>Name</strong></td>
87 <td width="60%%"><strong>Guid</strong></td>
88 <td width="20%%"><strong>Size</strong></td>
92 for Info
in FvObj
.BasicInfo
:
101 </tr>""" % (FvName
, FvGuid
, FvSize
)
102 self
.WriteLn(Content
)
104 Content
= """ <td colspan="3"><table width="100%%" border="1">
106 self
.WriteLn(Content
)
108 EotGlobalData
.gOP_DISPATCH_ORDER
.write('Dispatched:\n')
109 for FfsId
in FvObj
.OrderedFfsDict
.keys():
110 self
.GenerateFfs(FvObj
.OrderedFfsDict
[FfsId
])
111 Content
= """ </table></td>
113 self
.WriteLn(Content
)
116 Content
= """ <td colspan="3"><table width="100%%" border="1">
118 <tr><strong>UnDispatched</strong></tr>"""
119 self
.WriteLn(Content
)
121 EotGlobalData
.gOP_DISPATCH_ORDER
.write('\nUnDispatched:\n')
122 for FfsId
in FvObj
.UnDispatchedFfsDict
.keys():
123 self
.GenerateFfs(FvObj
.UnDispatchedFfsDict
[FfsId
])
124 Content
= """ </table></td>
126 self
.WriteLn(Content
)
128 ## GenerateDepex() method
130 # Generate Depex information
132 # @param self: The object pointer
133 # @param DepexString: A DEPEX string needed to be parsed
135 def GenerateDepex(self
, DepexString
):
136 NonGuidList
= ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
137 ItemList
= DepexString
.split(' ')
139 for Item
in ItemList
:
140 if Item
not in NonGuidList
:
141 SqlCommand
= """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item
)
142 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
144 Item
= RecordSet
[0][0]
145 DepexString
= DepexString
+ Item
+ ' '
147 <td width="5%%"></td>
148 <td width="95%%">%s</td>
149 </tr>""" % (DepexString
)
150 self
.WriteLn(Content
)
152 ## GeneratePpi() method
154 # Generate PPI information
156 # @param self: The object pointer
157 # @param Name: CName of a GUID
158 # @param Guid: Value of a GUID
159 # @param Type: Type of a GUID
161 def GeneratePpi(self
, Name
, Guid
, Type
):
162 self
.GeneratePpiProtocol('Ppi', Name
, Guid
, Type
, self
.PpiIndex
)
164 ## GenerateProtocol() method
166 # Generate PROTOCOL information
168 # @param self: The object pointer
169 # @param Name: CName of a GUID
170 # @param Guid: Value of a GUID
171 # @param Type: Type of a GUID
173 def GenerateProtocol(self
, Name
, Guid
, Type
):
174 self
.GeneratePpiProtocol('Protocol', Name
, Guid
, Type
, self
.ProtocolIndex
)
176 ## GeneratePpiProtocol() method
178 # Generate PPI/PROTOCOL information
180 # @param self: The object pointer
181 # @param Model: Model of a GUID, PPI or PROTOCOL
182 # @param Name: Name of a GUID
183 # @param Guid: Value of a GUID
184 # @param Type: Type of a GUID
185 # @param CName: CName(Index) of a GUID
187 def GeneratePpiProtocol(self
, Model
, Name
, Guid
, Type
, CName
):
189 <td width="5%%"></td>
190 <td width="10%%">%s</td>
191 <td width="85%%" colspan="3">%s</td>
193 </tr>""" % (Model
, Name
, Guid
)
194 self
.WriteLn(Content
)
195 if Type
== 'Produced':
196 SqlCommand
= """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
197 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
198 for Record
in RecordSet
:
199 SqlCommand
= """select FullPath from File
201 select DISTINCT BelongsToFile from Inf
202 where Value1 like '%s')""" % Record
[0]
203 ModuleSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
204 Inf
= ModuleSet
[0][0].replace(EotGlobalData
.gMACRO
['WORKSPACE'], '.')
207 for Item
in EotGlobalData
.gMap
:
208 if Function
in EotGlobalData
.gMap
[Item
]:
209 Address
= EotGlobalData
.gMap
[Item
][Function
]
211 if '_' + Function
in EotGlobalData
.gMap
[Item
]:
212 Address
= EotGlobalData
.gMap
[Item
]['_' + Function
]
215 <td width="5%%"></td>
216 <td width="10%%">%s</td>
217 <td width="40%%">%s</td>
218 <td width="35%%">%s</td>
219 <td width="10%%">%s</td>
220 </tr>""" % ('Callback', Inf
, Function
, Address
)
221 self
.WriteLn(Content
)
223 ## GenerateFfs() method
225 # Generate FFS information
227 # @param self: The object pointer
228 # @param FfsObj: FFS object after FV image is parsed
230 def GenerateFfs(self
, FfsObj
):
231 self
.FfsIndex
= self
.FfsIndex
+ 1
232 if FfsObj
is not None and FfsObj
.Type
in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
233 FfsGuid
= FfsObj
.Guid
234 FfsOffset
= FfsObj
._OFF
_
235 FfsName
= 'Unknown-Module'
237 FfsType
= FfsObj
._TypeName
[FfsObj
.Type
]
239 # Hard code for Binary INF
240 if FfsGuid
.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
243 if FfsGuid
.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
244 FfsName
= 'AcpiTables'
246 if FfsGuid
.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
249 # Find FFS Path and Name
250 SqlCommand
= """select Value2 from Inf
251 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
252 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid
, 5001, 5001)
253 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
255 FfsName
= RecordSet
[0][0]
257 SqlCommand
= """select FullPath from File
258 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
259 and Model = %s""" % (FfsGuid
, 5001, 1011)
260 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
262 FfsPath
= RecordSet
[0][0]
265 <tr class='styleFfs' id='FfsHeader%s'>
266 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
267 <td width="15%%">%s</td>
268 <!--<td width="20%%">%s</td>-->
269 <!--<td width="20%%">%s</td>-->
270 <td width="10%%">%s</td>
272 <tr id='Ffs%s' style='display:none;'>
273 <td colspan="4"><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, FfsPath
, FfsName
, FfsGuid
, FfsOffset
, FfsType
, self
.FfsIndex
)
275 if self
.DispatchList
:
276 if FfsObj
.Type
in [0x04, 0x06]:
277 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "P", FfsName
, FfsPath
))
278 if FfsObj
.Type
in [0x05, 0x07, 0x08, 0x0A]:
279 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "D", FfsName
, FfsPath
))
281 self
.WriteLn(Content
)
283 EotGlobalData
.gOP_DISPATCH_ORDER
.write('%s\n' %FfsName
)
285 if FfsObj
.Depex
!= '':
287 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  DEPEX expression</span></td>
289 <tr id='Depex%s' style='display:none;'>
290 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
)
291 self
.WriteLn(Content
)
292 self
.GenerateDepex(FfsObj
.Depex
)
293 Content
= """ </table></td>
295 self
.WriteLn(Content
)
298 # Find Consumed Ppi/Protocol
299 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
300 where SourceFileFullPath in
301 (select Value1 from Inf where BelongsToFile =
302 (select BelongsToFile from Inf
303 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
305 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
306 % (FfsGuid
, 5001, 3007)
308 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
310 Count
= len(RecordSet
)
312 <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Consumed Ppis/Protocols List (%s)</span></td>
314 <tr id='Consumed%s' style='display:none;'>
315 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
316 self
.WriteLn(Content
)
317 self
.ProtocolIndex
= 0
318 for Record
in RecordSet
:
319 self
.ProtocolIndex
= self
.ProtocolIndex
+ 1
324 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Consumed', CName
)
326 Content
= """ </table></td>
328 self
.WriteLn(Content
)
329 #End of Consumed Ppi/Protocol
331 # Find Produced Ppi/Protocol
332 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
333 where SourceFileFullPath in
334 (select Value1 from Inf where BelongsToFile =
335 (select BelongsToFile from Inf
336 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
338 and ItemMode = 'Produced' group by GuidName order by ItemType""" \
339 % (FfsGuid
, 5001, 3007)
341 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
343 Count
= len(RecordSet
)
345 <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Produced Ppis/Protocols List (%s)</span></td>
347 <tr id='Produced%s' style='display:none;'>
348 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
349 self
.WriteLn(Content
)
351 for Record
in RecordSet
:
352 self
.PpiIndex
= self
.PpiIndex
+ 1
357 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Produced', CName
)
359 Content
= """ </table></td>
361 self
.WriteLn(Content
)
363 # End of Produced Ppi/Protocol
365 Content
= """ </table></td>
367 self
.WriteLn(Content
)
369 ## GenerateTail() method
371 # Generate end tags of HTML report
373 # @param self: The object pointer
375 def GenerateTail(self
):
381 ## GenerateHeader() method
383 # Generate start tags of HTML report
385 # @param self: The object pointer
387 def GenerateHeader(self
):
388 Header
= """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
389 "http://www.w3.org/TR/html4/loose.dtd">
392 <title>Execution Order Tool Report</title>
393 <meta http-equiv="Content-Type" content="text/html">
394 <style type="text/css">
414 <Script type="text/javascript">
415 function Display(ParentID, SubID)
417 SubItem = document.getElementById(SubID);
418 ParentItem = document.getElementById(ParentID);
419 if (SubItem.style.display == 'none')
421 SubItem.style.display = ''
422 ParentItem.style.fontWeight = 'normal'
426 SubItem.style.display = 'none'
427 ParentItem.style.fontWeight = 'bold'
432 function funOnMouseOver()
434 document.body.style.cursor = "hand";
437 function funOnMouseOut()
439 document.body.style.cursor = "";
446 <table width="100%%" border="1">"""
451 # This acts like the main() function for the script, unless it is 'import'ed into another
454 if __name__
== '__main__':
455 # Initialize log system
456 FilePath
= 'FVRECOVERYFLOPPY.fv'
457 if FilePath
.lower().endswith(".fv"):
458 fd
= open(FilePath
, 'rb')
461 buf
.fromfile(fd
, os
.path
.getsize(FilePath
))
465 fv
= FirmwareVolume("FVRECOVERY", buf
, 0)
467 report
= Report('Report.html', fv
)
468 report
.GenerateReport()