]>
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 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 from __future__
import absolute_import
18 import Common
.LongFilePathOs
as os
19 from . import EotGlobalData
20 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
24 # This class defined Report
26 # @param object: Inherited from object class
31 # @param self: The object pointer
32 # @param ReportName: name of the report
33 # @param FvObj: FV object after parsing FV images
35 def __init__(self
, ReportName
= 'Report.html', FvObj
= None, DispatchName
=None):
36 self
.ReportName
= ReportName
37 self
.Op
= open(ReportName
, 'w+')
38 self
.DispatchList
= None
40 self
.DispatchList
= open(DispatchName
, 'w+')
44 self
.ProtocolIndex
= 0
45 if EotGlobalData
.gMACRO
['EFI_SOURCE'] == '':
46 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gMACRO
['EDK_SOURCE']
50 # Write a line in the report
52 # @param self: The object pointer
53 # @param Line: The lint to be written into
55 def WriteLn(self
, Line
):
56 self
.Op
.write('%s\n' % Line
)
58 ## GenerateReport() method
60 # A caller to generate report
62 # @param self: The object pointer
64 def GenerateReport(self
):
69 self
.GenerateUnDispatchedList()
71 ## GenerateUnDispatchedList() method
73 # Create a list for not dispatched items
75 # @param self: The object pointer
77 def GenerateUnDispatchedList(self
):
79 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.Name
)
80 for Item
in FvObj
.UnDispatchedFfsDict
.keys():
81 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.UnDispatchedFfsDict
[Item
])
83 ## GenerateFv() method
85 # Generate FV information
87 # @param self: The object pointer
92 <td width="20%%"><strong>Name</strong></td>
93 <td width="60%%"><strong>Guid</strong></td>
94 <td width="20%%"><strong>Size</strong></td>
98 for Info
in FvObj
.BasicInfo
:
107 </tr>""" % (FvName
, FvGuid
, FvSize
)
108 self
.WriteLn(Content
)
110 Content
= """ <td colspan="3"><table width="100%%" border="1">
112 self
.WriteLn(Content
)
114 EotGlobalData
.gOP_DISPATCH_ORDER
.write('Dispatched:\n')
115 for FfsId
in FvObj
.OrderedFfsDict
.keys():
116 self
.GenerateFfs(FvObj
.OrderedFfsDict
[FfsId
])
117 Content
= """ </table></td>
119 self
.WriteLn(Content
)
122 Content
= """ <td colspan="3"><table width="100%%" border="1">
124 <tr><strong>UnDispatched</strong></tr>"""
125 self
.WriteLn(Content
)
127 EotGlobalData
.gOP_DISPATCH_ORDER
.write('\nUnDispatched:\n')
128 for FfsId
in FvObj
.UnDispatchedFfsDict
.keys():
129 self
.GenerateFfs(FvObj
.UnDispatchedFfsDict
[FfsId
])
130 Content
= """ </table></td>
132 self
.WriteLn(Content
)
134 ## GenerateDepex() method
136 # Generate Depex information
138 # @param self: The object pointer
139 # @param DepexString: A DEPEX string needed to be parsed
141 def GenerateDepex(self
, DepexString
):
142 NonGuidList
= ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
143 ItemList
= DepexString
.split(' ')
145 for Item
in ItemList
:
146 if Item
not in NonGuidList
:
147 SqlCommand
= """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item
)
148 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
150 Item
= RecordSet
[0][0]
151 DepexString
= DepexString
+ Item
+ ' '
153 <td width="5%%"></td>
154 <td width="95%%">%s</td>
155 </tr>""" % (DepexString
)
156 self
.WriteLn(Content
)
158 ## GeneratePpi() method
160 # Generate PPI information
162 # @param self: The object pointer
163 # @param Name: CName of a GUID
164 # @param Guid: Value of a GUID
165 # @param Type: Type of a GUID
167 def GeneratePpi(self
, Name
, Guid
, Type
):
168 self
.GeneratePpiProtocol('Ppi', Name
, Guid
, Type
, self
.PpiIndex
)
170 ## GenerateProtocol() method
172 # Generate PROTOCOL information
174 # @param self: The object pointer
175 # @param Name: CName of a GUID
176 # @param Guid: Value of a GUID
177 # @param Type: Type of a GUID
179 def GenerateProtocol(self
, Name
, Guid
, Type
):
180 self
.GeneratePpiProtocol('Protocol', Name
, Guid
, Type
, self
.ProtocolIndex
)
182 ## GeneratePpiProtocol() method
184 # Generate PPI/PROTOCOL information
186 # @param self: The object pointer
187 # @param Model: Model of a GUID, PPI or PROTOCOL
188 # @param Name: Name of a GUID
189 # @param Guid: Value of a GUID
190 # @param Type: Type of a GUID
191 # @param CName: CName(Index) of a GUID
193 def GeneratePpiProtocol(self
, Model
, Name
, Guid
, Type
, CName
):
195 <td width="5%%"></td>
196 <td width="10%%">%s</td>
197 <td width="85%%" colspan="3">%s</td>
199 </tr>""" % (Model
, Name
, Guid
)
200 self
.WriteLn(Content
)
201 if Type
== 'Produced':
202 SqlCommand
= """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
203 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
204 for Record
in RecordSet
:
205 SqlCommand
= """select FullPath from File
207 select DISTINCT BelongsToFile from Inf
208 where Value1 like '%s')""" % Record
[0]
209 ModuleSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
210 Inf
= ModuleSet
[0][0].replace(EotGlobalData
.gMACRO
['WORKSPACE'], '.')
213 for Item
in EotGlobalData
.gMap
:
214 if Function
in EotGlobalData
.gMap
[Item
]:
215 Address
= EotGlobalData
.gMap
[Item
][Function
]
217 if '_' + Function
in EotGlobalData
.gMap
[Item
]:
218 Address
= EotGlobalData
.gMap
[Item
]['_' + Function
]
221 <td width="5%%"></td>
222 <td width="10%%">%s</td>
223 <td width="40%%">%s</td>
224 <td width="35%%">%s</td>
225 <td width="10%%">%s</td>
226 </tr>""" % ('Callback', Inf
, Function
, Address
)
227 self
.WriteLn(Content
)
229 ## GenerateFfs() method
231 # Generate FFS information
233 # @param self: The object pointer
234 # @param FfsObj: FFS object after FV image is parsed
236 def GenerateFfs(self
, FfsObj
):
237 self
.FfsIndex
= self
.FfsIndex
+ 1
238 if FfsObj
is not None and FfsObj
.Type
in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
239 FfsGuid
= FfsObj
.Guid
240 FfsOffset
= FfsObj
._OFF
_
241 FfsName
= 'Unknown-Module'
243 FfsType
= FfsObj
._TypeName
[FfsObj
.Type
]
245 # Hard code for Binary INF
246 if FfsGuid
.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
249 if FfsGuid
.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
250 FfsName
= 'AcpiTables'
252 if FfsGuid
.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
255 # Find FFS Path and Name
256 SqlCommand
= """select Value2 from Inf
257 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
258 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid
, 5001, 5001)
259 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
261 FfsName
= RecordSet
[0][0]
263 SqlCommand
= """select FullPath from File
264 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
265 and Model = %s""" % (FfsGuid
, 5001, 1011)
266 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
268 FfsPath
= RecordSet
[0][0]
271 <tr class='styleFfs' id='FfsHeader%s'>
272 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
273 <td width="15%%">%s</td>
274 <!--<td width="20%%">%s</td>-->
275 <!--<td width="20%%">%s</td>-->
276 <td width="10%%">%s</td>
278 <tr id='Ffs%s' style='display:none;'>
279 <td colspan="4"><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, FfsPath
, FfsName
, FfsGuid
, FfsOffset
, FfsType
, self
.FfsIndex
)
281 if self
.DispatchList
:
282 if FfsObj
.Type
in [0x04, 0x06]:
283 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "P", FfsName
, FfsPath
))
284 if FfsObj
.Type
in [0x05, 0x07, 0x08, 0x0A]:
285 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "D", FfsName
, FfsPath
))
287 self
.WriteLn(Content
)
289 EotGlobalData
.gOP_DISPATCH_ORDER
.write('%s\n' %FfsName
)
291 if FfsObj
.Depex
!= '':
293 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  DEPEX expression</span></td>
295 <tr id='Depex%s' style='display:none;'>
296 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
)
297 self
.WriteLn(Content
)
298 self
.GenerateDepex(FfsObj
.Depex
)
299 Content
= """ </table></td>
301 self
.WriteLn(Content
)
304 # Find Consumed Ppi/Protocol
305 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
306 where SourceFileFullPath in
307 (select Value1 from Inf where BelongsToFile =
308 (select BelongsToFile from Inf
309 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
311 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
312 % (FfsGuid
, 5001, 3007)
314 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
316 Count
= len(RecordSet
)
318 <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Consumed Ppis/Protocols List (%s)</span></td>
320 <tr id='Consumed%s' style='display:none;'>
321 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
322 self
.WriteLn(Content
)
323 self
.ProtocolIndex
= 0
324 for Record
in RecordSet
:
325 self
.ProtocolIndex
= self
.ProtocolIndex
+ 1
330 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Consumed', CName
)
332 Content
= """ </table></td>
334 self
.WriteLn(Content
)
335 #End of Consumed Ppi/Portocol
337 # Find Produced Ppi/Protocol
338 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
339 where SourceFileFullPath in
340 (select Value1 from Inf where BelongsToFile =
341 (select BelongsToFile from Inf
342 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
344 and ItemMode = 'Produced' group by GuidName order by ItemType""" \
345 % (FfsGuid
, 5001, 3007)
347 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
349 Count
= len(RecordSet
)
351 <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Produced Ppis/Protocols List (%s)</span></td>
353 <tr id='Produced%s' style='display:none;'>
354 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
355 self
.WriteLn(Content
)
357 for Record
in RecordSet
:
358 self
.PpiIndex
= self
.PpiIndex
+ 1
363 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Produced', CName
)
365 Content
= """ </table></td>
367 self
.WriteLn(Content
)
369 # End of Produced Ppi/Protocol
371 Content
= """ </table></td>
373 self
.WriteLn(Content
)
375 ## GenerateTail() method
377 # Generate end tags of HTML report
379 # @param self: The object pointer
381 def GenerateTail(self
):
387 ## GenerateHeader() method
389 # Generate start tags of HTML report
391 # @param self: The object pointer
393 def GenerateHeader(self
):
394 Header
= """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
395 "http://www.w3.org/TR/html4/loose.dtd">
398 <title>Execution Order Tool Report</title>
399 <meta http-equiv="Content-Type" content="text/html">
400 <style type="text/css">
420 <Script type="text/javascript">
421 function Display(ParentID, SubID)
423 SubItem = document.getElementById(SubID);
424 ParentItem = document.getElementById(ParentID);
425 if (SubItem.style.display == 'none')
427 SubItem.style.display = ''
428 ParentItem.style.fontWeight = 'normal'
432 SubItem.style.display = 'none'
433 ParentItem.style.fontWeight = 'bold'
438 function funOnMouseOver()
440 document.body.style.cursor = "hand";
443 function funOnMouseOut()
445 document.body.style.cursor = "";
452 <table width="100%%" border="1">"""
457 # This acts like the main() function for the script, unless it is 'import'ed into another
460 if __name__
== '__main__':
461 # Initialize log system
462 FilePath
= 'FVRECOVERYFLOPPY.fv'
463 if FilePath
.lower().endswith(".fv"):
464 fd
= open(FilePath
, 'rb')
467 buf
.fromfile(fd
, os
.path
.getsize(FilePath
))
471 fv
= FirmwareVolume("FVRECOVERY", buf
, 0)
473 report
= Report('Report.html', fv
)
474 report
.GenerateReport()