2 # This file is used to create report for Eot tool
\r
4 # Copyright (c) 2008 - 2010, Intel Corporation
\r
5 # All rights reserved. This program and the accompanying materials
\r
6 # are licensed and made available under the terms and conditions of the BSD License
\r
7 # which accompanies this distribution. The full text of the license may be found at
\r
8 # http://opensource.org/licenses/bsd-license.php
\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 import EotGlobalData
\r
22 # This class defined Report
\r
24 # @param object: Inherited from object class
\r
26 class Report(object):
\r
29 # @param self: The object pointer
\r
30 # @param ReportName: name of the report
\r
31 # @param FvObj: FV object after parsing FV images
\r
33 def __init__(self, ReportName = 'Report.html', FvObj = None):
\r
34 self.ReportName = ReportName
\r
35 self.Op = open(ReportName, 'w+')
\r
39 self.ProtocolIndex = 0
\r
40 if EotGlobalData.gMACRO['EFI_SOURCE'] == '':
\r
41 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gMACRO['EDK_SOURCE']
\r
45 # Write a line in the report
\r
47 # @param self: The object pointer
\r
48 # @param Line: The lint to be written into
\r
50 def WriteLn(self, Line):
\r
51 self.Op.write('%s\n' % Line)
\r
53 ## GenerateReport() method
\r
55 # A caller to generate report
\r
57 # @param self: The object pointer
\r
59 def GenerateReport(self):
\r
60 self.GenerateHeader()
\r
64 self.GenerateUnDispatchedList()
\r
66 ## GenerateUnDispatchedList() method
\r
68 # Create a list for not dispatched items
\r
70 # @param self: The object pointer
\r
72 def GenerateUnDispatchedList(self):
\r
74 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)
\r
75 for Item in FvObj.UnDispatchedFfsDict:
\r
76 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])
\r
78 ## GenerateFv() method
\r
80 # Generate FV information
\r
82 # @param self: The object pointer
\r
84 def GenerateFv(self):
\r
87 <td width="20%%"><strong>Name</strong></td>
\r
88 <td width="60%%"><strong>Guid</strong></td>
\r
89 <td width="20%%"><strong>Size</strong></td>
\r
91 self.WriteLn(Content)
\r
93 for Info in FvObj.BasicInfo:
\r
102 </tr>""" % (FvName, FvGuid, FvSize)
\r
103 self.WriteLn(Content)
\r
105 Content = """ <td colspan="3"><table width="100%%" border="1">
\r
107 self.WriteLn(Content)
\r
109 EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')
\r
110 for FfsId in FvObj.OrderedFfsDict:
\r
111 self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])
\r
112 Content = """ </table></td>
\r
114 self.WriteLn(Content)
\r
117 Content = """ <td colspan="3"><table width="100%%" border="1">
\r
119 <tr><strong>UnDispatched</strong></tr>"""
\r
120 self.WriteLn(Content)
\r
122 EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')
\r
123 for FfsId in FvObj.UnDispatchedFfsDict:
\r
124 self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])
\r
125 Content = """ </table></td>
\r
127 self.WriteLn(Content)
\r
129 ## GenerateDepex() method
\r
131 # Generate Depex information
\r
133 # @param self: The object pointer
\r
134 # @param DepexString: A DEPEX string needed to be parsed
\r
136 def GenerateDepex(self, DepexString):
\r
137 NonGuidList = ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']
\r
138 ItemList = DepexString.split(' ')
\r
140 for Item in ItemList:
\r
141 if Item not in NonGuidList:
\r
142 SqlCommand = """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item)
\r
143 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
144 if RecordSet != []:
\r
145 Item = RecordSet[0][0]
\r
146 DepexString = DepexString + Item + ' '
\r
148 <td width="5%%"></td>
\r
149 <td width="95%%">%s</td>
\r
150 </tr>""" % (DepexString)
\r
151 self.WriteLn(Content)
\r
153 ## GeneratePpi() method
\r
155 # Generate PPI information
\r
157 # @param self: The object pointer
\r
158 # @param Name: CName of a GUID
\r
159 # @param Guid: Value of a GUID
\r
160 # @param Type: Type of a GUID
\r
162 def GeneratePpi(self, Name, Guid, Type):
\r
163 self.GeneratePpiProtocol('Ppi', Name, Guid, Type, self.PpiIndex)
\r
165 ## GenerateProtocol() method
\r
167 # Generate PROTOCOL information
\r
169 # @param self: The object pointer
\r
170 # @param Name: CName of a GUID
\r
171 # @param Guid: Value of a GUID
\r
172 # @param Type: Type of a GUID
\r
174 def GenerateProtocol(self, Name, Guid, Type):
\r
175 self.GeneratePpiProtocol('Protocol', Name, Guid, Type, self.ProtocolIndex)
\r
177 ## GeneratePpiProtocol() method
\r
179 # Generate PPI/PROTOCOL information
\r
181 # @param self: The object pointer
\r
182 # @param Model: Model of a GUID, PPI or PROTOCOL
\r
183 # @param Name: Name of a GUID
\r
184 # @param Guid: Value of a GUID
\r
185 # @param Type: Type of a GUID
\r
186 # @param CName: CName(Index) of a GUID
\r
188 def GeneratePpiProtocol(self, Model, Name, Guid, Type, CName):
\r
190 <td width="5%%"></td>
\r
191 <td width="10%%">%s</td>
\r
192 <td width="85%%" colspan="3">%s</td>
\r
194 </tr>""" % (Model, Name, Guid)
\r
195 self.WriteLn(Content)
\r
196 if Type == 'Produced':
\r
197 SqlCommand = """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name
\r
198 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
199 for Record in RecordSet:
\r
200 SqlCommand = """select FullPath from File
\r
202 select DISTINCT BelongsToFile from Inf
\r
203 where Value1 like '%s')""" % Record[0]
\r
204 ModuleSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
205 Inf = ModuleSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')
\r
206 Function = Record[1]
\r
208 for Item in EotGlobalData.gMap:
\r
209 if Function in EotGlobalData.gMap[Item]:
\r
210 Address = EotGlobalData.gMap[Item][Function]
\r
212 if '_' + Function in EotGlobalData.gMap[Item]:
\r
213 Address = EotGlobalData.gMap[Item]['_' + Function]
\r
216 <td width="5%%"></td>
\r
217 <td width="10%%">%s</td>
\r
218 <td width="40%%">%s</td>
\r
219 <td width="35%%">%s</td>
\r
220 <td width="10%%">%s</td>
\r
221 </tr>""" % ('Callback', Inf, Function, Address)
\r
222 self.WriteLn(Content)
\r
224 ## GenerateFfs() method
\r
226 # Generate FFS information
\r
228 # @param self: The object pointer
\r
229 # @param FfsObj: FFS object after FV image is parsed
\r
231 def GenerateFfs(self, FfsObj):
\r
232 self.FfsIndex = self.FfsIndex + 1
\r
233 if FfsObj != None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08]:
\r
234 FfsGuid = FfsObj.Guid
\r
235 FfsOffset = FfsObj._OFF_
\r
236 FfsName = 'Unknonw Ffs Name'
\r
238 FfsType = FfsObj._TypeName[FfsObj.Type]
\r
240 # Hard code for Binary INF
\r
241 if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':
\r
244 if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':
\r
245 FfsName = 'AcpiTables'
\r
247 if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':
\r
250 # Find FFS Path and Name
\r
251 SqlCommand = """select Value2 from Inf
\r
252 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
\r
253 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid, 5001, 5001)
\r
254 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
255 if RecordSet != []:
\r
256 FfsName = RecordSet[0][0]
\r
258 SqlCommand = """select FullPath from File
\r
259 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
\r
260 and Model = %s""" % (FfsGuid, 5001, 1011)
\r
261 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
262 if RecordSet != []:
\r
263 FfsPath = RecordSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')
\r
266 <tr class='styleFfs' id='FfsHeader%s'>
\r
267 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>
\r
268 <td width="15%%">%s</td>
\r
269 <!--<td width="20%%">%s</td>-->
\r
270 <!--<td width="20%%">%s</td>-->
\r
271 <td width="10%%">%s</td>
\r
273 <tr id='Ffs%s' style='display:none;'>
\r
274 <td colspan="4"><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, FfsPath, FfsName, FfsGuid, FfsOffset, FfsType, self.FfsIndex)
\r
276 self.WriteLn(Content)
\r
278 EotGlobalData.gOP_DISPATCH_ORDER.write('%s\n' %FfsName)
\r
280 if FfsObj.Depex != '':
\r
282 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">  DEPEX expression</span></td>
\r
284 <tr id='Depex%s' style='display:none;'>
\r
285 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, self.FfsIndex)
\r
286 self.WriteLn(Content)
\r
287 self.GenerateDepex(FfsObj.Depex)
\r
288 Content = """ </table></td>
\r
290 self.WriteLn(Content)
\r
293 # Find Consumed Ppi/Protocol
\r
294 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
\r
295 where SourceFileFullPath in
\r
296 (select Value1 from Inf where BelongsToFile =
\r
297 (select BelongsToFile from Inf
\r
298 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
\r
300 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \
\r
301 % (FfsGuid, 5001, 3007)
\r
303 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
304 if RecordSet != []:
\r
305 Count = len(RecordSet)
\r
307 <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
309 <tr id='Consumed%s' style='display:none;'>
\r
310 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
\r
311 self.WriteLn(Content)
\r
312 self.ProtocolIndex = 0
\r
313 for Record in RecordSet:
\r
314 self.ProtocolIndex = self.ProtocolIndex + 1
\r
319 self.GeneratePpiProtocol(Type, Name, Guid, 'Consumed', CName)
\r
321 Content = """ </table></td>
\r
323 self.WriteLn(Content)
\r
324 #End of Consumed Ppi/Portocol
\r
326 # Find Produced Ppi/Protocol
\r
327 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report
\r
328 where SourceFileFullPath in
\r
329 (select Value1 from Inf where BelongsToFile =
\r
330 (select BelongsToFile from Inf
\r
331 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
\r
333 and ItemMode = 'Produced' group by GuidName order by ItemType""" \
\r
334 % (FfsGuid, 5001, 3007)
\r
336 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)
\r
337 if RecordSet != []:
\r
338 Count = len(RecordSet)
\r
340 <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
342 <tr id='Produced%s' style='display:none;'>
\r
343 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)
\r
344 self.WriteLn(Content)
\r
346 for Record in RecordSet:
\r
347 self.PpiIndex = self.PpiIndex + 1
\r
352 self.GeneratePpiProtocol(Type, Name, Guid, 'Produced', CName)
\r
354 Content = """ </table></td>
\r
356 self.WriteLn(Content)
\r
358 # End of Produced Ppi/Protocol
\r
360 Content = """ </table></td>
\r
362 self.WriteLn(Content)
\r
364 ## GenerateTail() method
\r
366 # Generate end tags of HTML report
\r
368 # @param self: The object pointer
\r
370 def GenerateTail(self):
\r
376 ## GenerateHeader() method
\r
378 # Generate start tags of HTML report
\r
380 # @param self: The object pointer
\r
382 def GenerateHeader(self):
\r
383 Header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
\r
384 "http://www.w3.org/TR/html4/loose.dtd">
\r
387 <title>Execution Order Tool Report</title>
\r
388 <meta http-equiv="Content-Type" content="text/html">
\r
389 <style type="text/css">
\r
409 <Script type="text/javascript">
\r
410 function Display(ParentID, SubID)
\r
412 SubItem = document.getElementById(SubID);
\r
413 ParentItem = document.getElementById(ParentID);
\r
414 if (SubItem.style.display == 'none')
\r
416 SubItem.style.display = ''
\r
417 ParentItem.style.fontWeight = 'normal'
\r
421 SubItem.style.display = 'none'
\r
422 ParentItem.style.fontWeight = 'bold'
\r
427 function funOnMouseOver()
\r
429 document.body.style.cursor = "hand";
\r
432 function funOnMouseOut()
\r
434 document.body.style.cursor = "";
\r
441 <table width="100%%" border="1">"""
\r
442 self.WriteLn(Header)
\r
446 # This acts like the main() function for the script, unless it is 'import'ed into another
\r
449 if __name__ == '__main__':
\r
450 # Initialize log system
\r
451 FilePath = 'FVRECOVERYFLOPPY.fv'
\r
452 if FilePath.lower().endswith(".fv"):
\r
453 fd = open(FilePath, 'rb')
\r
456 buf.fromfile(fd, os.path.getsize(FilePath))
\r
460 fv = FirmwareVolume("FVRECOVERY", buf, 0)
\r
462 report = Report('Report.html', fv)
\r
463 report.GenerateReport()
\r