]>
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 - 2010, 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.
22 # This class defined Report
24 # @param object: Inherited from object class
29 # @param self: The object pointer
30 # @param ReportName: name of the report
31 # @param FvObj: FV object after parsing FV images
33 def __init__(self
, ReportName
= 'Report.html', FvObj
= None, DispatchName
=None):
34 self
.ReportName
= ReportName
35 self
.Op
= open(ReportName
, 'w+')
36 self
.DispatchList
= None
38 self
.DispatchList
= open(DispatchName
, 'w+')
42 self
.ProtocolIndex
= 0
43 if EotGlobalData
.gMACRO
['EFI_SOURCE'] == '':
44 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gMACRO
['EDK_SOURCE']
48 # Write a line in the report
50 # @param self: The object pointer
51 # @param Line: The lint to be written into
53 def WriteLn(self
, Line
):
54 self
.Op
.write('%s\n' % Line
)
56 ## GenerateReport() method
58 # A caller to generate report
60 # @param self: The object pointer
62 def GenerateReport(self
):
67 self
.GenerateUnDispatchedList()
69 ## GenerateUnDispatchedList() method
71 # Create a list for not dispatched items
73 # @param self: The object pointer
75 def GenerateUnDispatchedList(self
):
77 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.Name
)
78 for Item
in FvObj
.UnDispatchedFfsDict
:
79 EotGlobalData
.gOP_UN_DISPATCHED
.write('%s\n' % FvObj
.UnDispatchedFfsDict
[Item
])
81 ## GenerateFv() method
83 # Generate FV information
85 # @param self: The object pointer
90 <td width="20%%"><strong>Name</strong></td>
91 <td width="60%%"><strong>Guid</strong></td>
92 <td width="20%%"><strong>Size</strong></td>
96 for Info
in FvObj
.BasicInfo
:
105 </tr>""" % (FvName
, FvGuid
, FvSize
)
106 self
.WriteLn(Content
)
108 Content
= """ <td colspan="3"><table width="100%%" border="1">
110 self
.WriteLn(Content
)
112 EotGlobalData
.gOP_DISPATCH_ORDER
.write('Dispatched:\n')
113 for FfsId
in FvObj
.OrderedFfsDict
:
114 self
.GenerateFfs(FvObj
.OrderedFfsDict
[FfsId
])
115 Content
= """ </table></td>
117 self
.WriteLn(Content
)
120 Content
= """ <td colspan="3"><table width="100%%" border="1">
122 <tr><strong>UnDispatched</strong></tr>"""
123 self
.WriteLn(Content
)
125 EotGlobalData
.gOP_DISPATCH_ORDER
.write('\nUnDispatched:\n')
126 for FfsId
in FvObj
.UnDispatchedFfsDict
:
127 self
.GenerateFfs(FvObj
.UnDispatchedFfsDict
[FfsId
])
128 Content
= """ </table></td>
130 self
.WriteLn(Content
)
132 ## GenerateDepex() method
134 # Generate Depex information
136 # @param self: The object pointer
137 # @param DepexString: A DEPEX string needed to be parsed
139 def GenerateDepex(self
, DepexString
):
140 NonGuidList
= ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
141 ItemList
= DepexString
.split(' ')
143 for Item
in ItemList
:
144 if Item
not in NonGuidList
:
145 SqlCommand
= """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item
)
146 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
148 Item
= RecordSet
[0][0]
149 DepexString
= DepexString
+ Item
+ ' '
151 <td width="5%%"></td>
152 <td width="95%%">%s</td>
153 </tr>""" % (DepexString
)
154 self
.WriteLn(Content
)
156 ## GeneratePpi() method
158 # Generate PPI information
160 # @param self: The object pointer
161 # @param Name: CName of a GUID
162 # @param Guid: Value of a GUID
163 # @param Type: Type of a GUID
165 def GeneratePpi(self
, Name
, Guid
, Type
):
166 self
.GeneratePpiProtocol('Ppi', Name
, Guid
, Type
, self
.PpiIndex
)
168 ## GenerateProtocol() method
170 # Generate PROTOCOL information
172 # @param self: The object pointer
173 # @param Name: CName of a GUID
174 # @param Guid: Value of a GUID
175 # @param Type: Type of a GUID
177 def GenerateProtocol(self
, Name
, Guid
, Type
):
178 self
.GeneratePpiProtocol('Protocol', Name
, Guid
, Type
, self
.ProtocolIndex
)
180 ## GeneratePpiProtocol() method
182 # Generate PPI/PROTOCOL information
184 # @param self: The object pointer
185 # @param Model: Model of a GUID, PPI or PROTOCOL
186 # @param Name: Name of a GUID
187 # @param Guid: Value of a GUID
188 # @param Type: Type of a GUID
189 # @param CName: CName(Index) of a GUID
191 def GeneratePpiProtocol(self
, Model
, Name
, Guid
, Type
, CName
):
193 <td width="5%%"></td>
194 <td width="10%%">%s</td>
195 <td width="85%%" colspan="3">%s</td>
197 </tr>""" % (Model
, Name
, Guid
)
198 self
.WriteLn(Content
)
199 if Type
== 'Produced':
200 SqlCommand
= """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
201 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
202 for Record
in RecordSet
:
203 SqlCommand
= """select FullPath from File
205 select DISTINCT BelongsToFile from Inf
206 where Value1 like '%s')""" % Record
[0]
207 ModuleSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
208 Inf
= ModuleSet
[0][0].replace(EotGlobalData
.gMACRO
['WORKSPACE'], '.')
211 for Item
in EotGlobalData
.gMap
:
212 if Function
in EotGlobalData
.gMap
[Item
]:
213 Address
= EotGlobalData
.gMap
[Item
][Function
]
215 if '_' + Function
in EotGlobalData
.gMap
[Item
]:
216 Address
= EotGlobalData
.gMap
[Item
]['_' + Function
]
219 <td width="5%%"></td>
220 <td width="10%%">%s</td>
221 <td width="40%%">%s</td>
222 <td width="35%%">%s</td>
223 <td width="10%%">%s</td>
224 </tr>""" % ('Callback', Inf
, Function
, Address
)
225 self
.WriteLn(Content
)
227 ## GenerateFfs() method
229 # Generate FFS information
231 # @param self: The object pointer
232 # @param FfsObj: FFS object after FV image is parsed
234 def GenerateFfs(self
, FfsObj
):
235 self
.FfsIndex
= self
.FfsIndex
+ 1
236 if FfsObj
!= None and FfsObj
.Type
in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:
237 FfsGuid
= FfsObj
.Guid
238 FfsOffset
= FfsObj
._OFF
_
239 FfsName
= 'Unknown-Module'
241 FfsType
= FfsObj
._TypeName
[FfsObj
.Type
]
243 # Hard code for Binary INF
244 if FfsGuid
.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
247 if FfsGuid
.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
248 FfsName
= 'AcpiTables'
250 if FfsGuid
.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
253 # Find FFS Path and Name
254 SqlCommand
= """select Value2 from Inf
255 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
256 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid
, 5001, 5001)
257 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
259 FfsName
= RecordSet
[0][0]
261 SqlCommand
= """select FullPath from File
262 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
263 and Model = %s""" % (FfsGuid
, 5001, 1011)
264 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
266 FfsPath
= RecordSet
[0][0]
269 <tr class='styleFfs' id='FfsHeader%s'>
270 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
271 <td width="15%%">%s</td>
272 <!--<td width="20%%">%s</td>-->
273 <!--<td width="20%%">%s</td>-->
274 <td width="10%%">%s</td>
276 <tr id='Ffs%s' style='display:none;'>
277 <td colspan="4"><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, FfsPath
, FfsName
, FfsGuid
, FfsOffset
, FfsType
, self
.FfsIndex
)
279 if self
.DispatchList
:
280 if FfsObj
.Type
in [0x04, 0x06]:
281 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "P", FfsName
, FfsPath
))
282 if FfsObj
.Type
in [0x05, 0x07, 0x08, 0x0A]:
283 self
.DispatchList
.write("%s %s %s %s\n" % (FfsGuid
, "D", FfsName
, FfsPath
))
285 self
.WriteLn(Content
)
287 EotGlobalData
.gOP_DISPATCH_ORDER
.write('%s\n' %FfsName
)
289 if FfsObj
.Depex
!= '':
291 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  DEPEX expression</span></td>
293 <tr id='Depex%s' style='display:none;'>
294 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
)
295 self
.WriteLn(Content
)
296 self
.GenerateDepex(FfsObj
.Depex
)
297 Content
= """ </table></td>
299 self
.WriteLn(Content
)
302 # Find Consumed Ppi/Protocol
303 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
304 where SourceFileFullPath in
305 (select Value1 from Inf where BelongsToFile =
306 (select BelongsToFile from Inf
307 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
309 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
310 % (FfsGuid
, 5001, 3007)
312 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
314 Count
= len(RecordSet
)
316 <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Consumed Ppis/Protocols List (%s)</span></td>
318 <tr id='Consumed%s' style='display:none;'>
319 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
320 self
.WriteLn(Content
)
321 self
.ProtocolIndex
= 0
322 for Record
in RecordSet
:
323 self
.ProtocolIndex
= self
.ProtocolIndex
+ 1
328 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Consumed', CName
)
330 Content
= """ </table></td>
332 self
.WriteLn(Content
)
333 #End of Consumed Ppi/Portocol
335 # Find Produced Ppi/Protocol
336 SqlCommand
= """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
337 where SourceFileFullPath in
338 (select Value1 from Inf where BelongsToFile =
339 (select BelongsToFile from Inf
340 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
342 and ItemMode = 'Produced' group by GuidName order by ItemType""" \
343 % (FfsGuid
, 5001, 3007)
345 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
347 Count
= len(RecordSet
)
349 <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  Produced Ppis/Protocols List (%s)</span></td>
351 <tr id='Produced%s' style='display:none;'>
352 <td><table width="100%%" border="1">""" % (self
.FfsIndex
, self
.FfsIndex
, self
.FfsIndex
, Count
, self
.FfsIndex
)
353 self
.WriteLn(Content
)
355 for Record
in RecordSet
:
356 self
.PpiIndex
= self
.PpiIndex
+ 1
361 self
.GeneratePpiProtocol(Type
, Name
, Guid
, 'Produced', CName
)
363 Content
= """ </table></td>
365 self
.WriteLn(Content
)
367 # End of Produced Ppi/Protocol
369 Content
= """ </table></td>
371 self
.WriteLn(Content
)
373 ## GenerateTail() method
375 # Generate end tags of HTML report
377 # @param self: The object pointer
379 def GenerateTail(self
):
385 ## GenerateHeader() method
387 # Generate start tags of HTML report
389 # @param self: The object pointer
391 def GenerateHeader(self
):
392 Header
= """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
393 "http://www.w3.org/TR/html4/loose.dtd">
396 <title>Execution Order Tool Report</title>
397 <meta http-equiv="Content-Type" content="text/html">
398 <style type="text/css">
418 <Script type="text/javascript">
419 function Display(ParentID, SubID)
421 SubItem = document.getElementById(SubID);
422 ParentItem = document.getElementById(ParentID);
423 if (SubItem.style.display == 'none')
425 SubItem.style.display = ''
426 ParentItem.style.fontWeight = 'normal'
430 SubItem.style.display = 'none'
431 ParentItem.style.fontWeight = 'bold'
436 function funOnMouseOver()
438 document.body.style.cursor = "hand";
441 function funOnMouseOut()
443 document.body.style.cursor = "";
450 <table width="100%%" border="1">"""
455 # This acts like the main() function for the script, unless it is 'import'ed into another
458 if __name__
== '__main__':
459 # Initialize log system
460 FilePath
= 'FVRECOVERYFLOPPY.fv'
461 if FilePath
.lower().endswith(".fv"):
462 fd
= open(FilePath
, 'rb')
465 buf
.fromfile(fd
, os
.path
.getsize(FilePath
))
469 fv
= FirmwareVolume("FVRECOVERY", buf
, 0)
471 report
= Report('Report.html', fv
)
472 report
.GenerateReport()