]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/Report.py
MdeModulePkg:
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Report.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to create report for Eot tool\r
3#\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
9#\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
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
17import os\r
18import EotGlobalData\r
19\r
20## Report() class\r
21#\r
22# This class defined Report\r
23#\r
24# @param object: Inherited from object class\r
25#\r
26class Report(object):\r
27 ## The constructor\r
28 #\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
32 #\r
33 def __init__(self, ReportName = 'Report.html', FvObj = None, DispatchName=None):\r
34 self.ReportName = ReportName\r
35 self.Op = open(ReportName, 'w+')\r
36 self.DispatchList = None\r
37 if DispatchName:\r
38 self.DispatchList = open(DispatchName, 'w+')\r
39 self.FvObj = FvObj\r
40 self.FfsIndex = 0\r
41 self.PpiIndex = 0\r
42 self.ProtocolIndex = 0\r
43 if EotGlobalData.gMACRO['EFI_SOURCE'] == '':\r
44 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gMACRO['EDK_SOURCE']\r
45\r
46 ## WriteLn() method\r
47 #\r
48 # Write a line in the report\r
49 #\r
50 # @param self: The object pointer\r
51 # @param Line: The lint to be written into\r
52 #\r
53 def WriteLn(self, Line):\r
54 self.Op.write('%s\n' % Line)\r
55\r
56 ## GenerateReport() method\r
57 #\r
58 # A caller to generate report\r
59 #\r
60 # @param self: The object pointer\r
61 #\r
62 def GenerateReport(self):\r
63 self.GenerateHeader()\r
64 self.GenerateFv()\r
65 self.GenerateTail()\r
66 self.Op.close()\r
67 self.GenerateUnDispatchedList()\r
68\r
69 ## GenerateUnDispatchedList() method\r
70 #\r
71 # Create a list for not dispatched items\r
72 #\r
73 # @param self: The object pointer\r
74 #\r
75 def GenerateUnDispatchedList(self):\r
76 FvObj = self.FvObj\r
77 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)\r
78 for Item in FvObj.UnDispatchedFfsDict:\r
79 EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])\r
80\r
81 ## GenerateFv() method\r
82 #\r
83 # Generate FV information\r
84 #\r
85 # @param self: The object pointer\r
86 #\r
87 def GenerateFv(self):\r
88 FvObj = self.FvObj\r
89 Content = """ <tr>\r
90 <td width="20%%"><strong>Name</strong></td>\r
91 <td width="60%%"><strong>Guid</strong></td>\r
92 <td width="20%%"><strong>Size</strong></td>\r
93 </tr>"""\r
94 self.WriteLn(Content)\r
95\r
96 for Info in FvObj.BasicInfo:\r
97 FvName = Info[0]\r
98 FvGuid = Info[1]\r
99 FvSize = Info[2]\r
100\r
101 Content = """ <tr>\r
102 <td>%s</td>\r
103 <td>%s</td>\r
104 <td>%s</td>\r
105 </tr>""" % (FvName, FvGuid, FvSize)\r
106 self.WriteLn(Content)\r
107\r
108 Content = """ <td colspan="3"><table width="100%%" border="1">\r
109 <tr>"""\r
110 self.WriteLn(Content)\r
111\r
112 EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')\r
113 for FfsId in FvObj.OrderedFfsDict:\r
114 self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])\r
115 Content = """ </table></td>\r
116 </tr>"""\r
117 self.WriteLn(Content)\r
118\r
119 # For UnDispatched\r
120 Content = """ <td colspan="3"><table width="100%%" border="1">\r
121 <tr>\r
122 <tr><strong>UnDispatched</strong></tr>"""\r
123 self.WriteLn(Content)\r
124\r
125 EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')\r
126 for FfsId in FvObj.UnDispatchedFfsDict:\r
127 self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])\r
128 Content = """ </table></td>\r
129 </tr>"""\r
130 self.WriteLn(Content)\r
131\r
132 ## GenerateDepex() method\r
133 #\r
134 # Generate Depex information\r
135 #\r
136 # @param self: The object pointer\r
137 # @param DepexString: A DEPEX string needed to be parsed\r
138 #\r
139 def GenerateDepex(self, DepexString):\r
140 NonGuidList = ['AND', 'OR', 'NOT', 'BEFORE', 'AFTER', 'TRUE', 'FALSE']\r
141 ItemList = DepexString.split(' ')\r
142 DepexString = ''\r
143 for Item in ItemList:\r
144 if Item not in NonGuidList:\r
145 SqlCommand = """select DISTINCT GuidName from Report where GuidValue like '%s' and ItemMode = 'Produced' group by GuidName""" % (Item)\r
146 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
147 if RecordSet != []:\r
148 Item = RecordSet[0][0]\r
149 DepexString = DepexString + Item + ' '\r
150 Content = """ <tr>\r
151 <td width="5%%"></td>\r
152 <td width="95%%">%s</td>\r
153 </tr>""" % (DepexString)\r
154 self.WriteLn(Content)\r
155\r
156 ## GeneratePpi() method\r
157 #\r
158 # Generate PPI information\r
159 #\r
160 # @param self: The object pointer\r
161 # @param Name: CName of a GUID\r
162 # @param Guid: Value of a GUID\r
163 # @param Type: Type of a GUID\r
164 #\r
165 def GeneratePpi(self, Name, Guid, Type):\r
166 self.GeneratePpiProtocol('Ppi', Name, Guid, Type, self.PpiIndex)\r
167\r
168 ## GenerateProtocol() method\r
169 #\r
170 # Generate PROTOCOL information\r
171 #\r
172 # @param self: The object pointer\r
173 # @param Name: CName of a GUID\r
174 # @param Guid: Value of a GUID\r
175 # @param Type: Type of a GUID\r
176 #\r
177 def GenerateProtocol(self, Name, Guid, Type):\r
178 self.GeneratePpiProtocol('Protocol', Name, Guid, Type, self.ProtocolIndex)\r
179\r
180 ## GeneratePpiProtocol() method\r
181 #\r
182 # Generate PPI/PROTOCOL information\r
183 #\r
184 # @param self: The object pointer\r
185 # @param Model: Model of a GUID, PPI or PROTOCOL\r
186 # @param Name: Name of a GUID\r
187 # @param Guid: Value of a GUID\r
188 # @param Type: Type of a GUID\r
189 # @param CName: CName(Index) of a GUID\r
190 #\r
191 def GeneratePpiProtocol(self, Model, Name, Guid, Type, CName):\r
192 Content = """ <tr>\r
193 <td width="5%%"></td>\r
194 <td width="10%%">%s</td>\r
195 <td width="85%%" colspan="3">%s</td>\r
196 <!-- %s -->\r
197 </tr>""" % (Model, Name, Guid)\r
198 self.WriteLn(Content)\r
199 if Type == 'Produced':\r
200 SqlCommand = """select DISTINCT SourceFileFullPath, BelongsToFunction from Report where GuidName like '%s' and ItemMode = 'Callback'""" % Name\r
201 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
202 for Record in RecordSet:\r
203 SqlCommand = """select FullPath from File\r
204 where ID = (\r
205 select DISTINCT BelongsToFile from Inf\r
206 where Value1 like '%s')""" % Record[0]\r
207 ModuleSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
208 Inf = ModuleSet[0][0].replace(EotGlobalData.gMACRO['WORKSPACE'], '.')\r
209 Function = Record[1]\r
210 Address = ''\r
211 for Item in EotGlobalData.gMap:\r
212 if Function in EotGlobalData.gMap[Item]:\r
213 Address = EotGlobalData.gMap[Item][Function]\r
214 break\r
215 if '_' + Function in EotGlobalData.gMap[Item]:\r
216 Address = EotGlobalData.gMap[Item]['_' + Function]\r
217 break\r
218 Content = """ <tr>\r
219 <td width="5%%"></td>\r
220 <td width="10%%">%s</td>\r
221 <td width="40%%">%s</td>\r
222 <td width="35%%">%s</td>\r
223 <td width="10%%">%s</td>\r
224 </tr>""" % ('Callback', Inf, Function, Address)\r
225 self.WriteLn(Content)\r
226\r
227 ## GenerateFfs() method\r
228 #\r
229 # Generate FFS information\r
230 #\r
231 # @param self: The object pointer\r
232 # @param FfsObj: FFS object after FV image is parsed\r
233 #\r
234 def GenerateFfs(self, FfsObj):\r
235 self.FfsIndex = self.FfsIndex + 1\r
236 if FfsObj != None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]:\r
237 FfsGuid = FfsObj.Guid\r
238 FfsOffset = FfsObj._OFF_\r
239 FfsName = 'Unknown-Module'\r
240 FfsPath = FfsGuid\r
241 FfsType = FfsObj._TypeName[FfsObj.Type]\r
242\r
243 # Hard code for Binary INF\r
244 if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D':\r
245 FfsName = 'Logo'\r
246\r
247 if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD':\r
248 FfsName = 'AcpiTables'\r
249\r
250 if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F':\r
251 FfsName = 'Fat'\r
252\r
253 # Find FFS Path and Name\r
254 SqlCommand = """select Value2 from Inf\r
255 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
256 and Model = %s and Value1='BASE_NAME'""" % (FfsGuid, 5001, 5001)\r
257 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
258 if RecordSet != []:\r
259 FfsName = RecordSet[0][0]\r
260\r
261 SqlCommand = """select FullPath from File\r
262 where ID = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
263 and Model = %s""" % (FfsGuid, 5001, 1011)\r
264 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
265 if RecordSet != []:\r
266 FfsPath = RecordSet[0][0]\r
267\r
268 Content = """ <tr>\r
269 <tr class='styleFfs' id='FfsHeader%s'>\r
270 <td width="55%%"><span onclick="Display('FfsHeader%s', 'Ffs%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">%s</span></td>\r
271 <td width="15%%">%s</td>\r
272 <!--<td width="20%%">%s</td>-->\r
273 <!--<td width="20%%">%s</td>-->\r
274 <td width="10%%">%s</td>\r
275 </tr>\r
276 <tr id='Ffs%s' style='display:none;'>\r
277 <td colspan="4"><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, FfsPath, FfsName, FfsGuid, FfsOffset, FfsType, self.FfsIndex)\r
278 \r
279 if self.DispatchList:\r
280 if FfsObj.Type in [0x04, 0x06]:\r
281 self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "P", FfsName, FfsPath))\r
282 if FfsObj.Type in [0x05, 0x07, 0x08, 0x0A]:\r
283 self.DispatchList.write("%s %s %s %s\n" % (FfsGuid, "D", FfsName, FfsPath))\r
284 \r
285 self.WriteLn(Content)\r
286\r
287 EotGlobalData.gOP_DISPATCH_ORDER.write('%s\n' %FfsName)\r
288\r
289 if FfsObj.Depex != '':\r
290 Content = """ <tr>\r
291 <td><span id='DepexHeader%s' class="styleDepex" onclick="Display('DepexHeader%s', 'Depex%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspDEPEX expression</span></td>\r
292 </tr>\r
293 <tr id='Depex%s' style='display:none;'>\r
294 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, self.FfsIndex)\r
295 self.WriteLn(Content)\r
296 self.GenerateDepex(FfsObj.Depex)\r
297 Content = """ </table></td>\r
298 </tr>"""\r
299 self.WriteLn(Content)\r
300 # End of DEPEX\r
301\r
302 # Find Consumed Ppi/Protocol\r
303 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report\r
304 where SourceFileFullPath in\r
305 (select Value1 from Inf where BelongsToFile =\r
306 (select BelongsToFile from Inf\r
307 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
308 and Model = %s)\r
309 and ItemMode = 'Consumed' group by GuidName order by ItemType""" \\r
310 % (FfsGuid, 5001, 3007)\r
311\r
312 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
313 if RecordSet != []:\r
314 Count = len(RecordSet)\r
315 Content = """ <tr>\r
316 <td><span id='ConsumedHeader%s' class="styleConsumed" onclick="Display('ConsumedHeader%s', 'Consumed%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspConsumed Ppis/Protocols List (%s)</span></td>\r
317 </tr>\r
318 <tr id='Consumed%s' style='display:none;'>\r
319 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)\r
320 self.WriteLn(Content)\r
321 self.ProtocolIndex = 0\r
322 for Record in RecordSet:\r
323 self.ProtocolIndex = self.ProtocolIndex + 1\r
324 Name = Record[2]\r
325 CName = Record[4]\r
326 Guid = Record[3]\r
327 Type = Record[1]\r
328 self.GeneratePpiProtocol(Type, Name, Guid, 'Consumed', CName)\r
329\r
330 Content = """ </table></td>\r
331 </tr>"""\r
332 self.WriteLn(Content)\r
333 #End of Consumed Ppi/Portocol\r
334\r
335 # Find Produced Ppi/Protocol\r
336 SqlCommand = """select ModuleName, ItemType, GuidName, GuidValue, GuidMacro from Report\r
337 where SourceFileFullPath in\r
338 (select Value1 from Inf where BelongsToFile =\r
339 (select BelongsToFile from Inf\r
340 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
341 and Model = %s)\r
342 and ItemMode = 'Produced' group by GuidName order by ItemType""" \\r
343 % (FfsGuid, 5001, 3007)\r
344\r
345 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
346 if RecordSet != []:\r
347 Count = len(RecordSet)\r
348 Content = """ <tr>\r
349 <td><span id='ProducedHeader%s' class="styleProduced" onclick="Display('ProducedHeader%s', 'Produced%s')" onMouseOver="funOnMouseOver()" onMouseOut="funOnMouseOut()">&nbsp&nbspProduced Ppis/Protocols List (%s)</span></td>\r
350 </tr>\r
351 <tr id='Produced%s' style='display:none;'>\r
352 <td><table width="100%%" border="1">""" % (self.FfsIndex, self.FfsIndex, self.FfsIndex, Count, self.FfsIndex)\r
353 self.WriteLn(Content)\r
354 self.PpiIndex = 0\r
355 for Record in RecordSet:\r
356 self.PpiIndex = self.PpiIndex + 1\r
357 Name = Record[2]\r
358 CName = Record[4]\r
359 Guid = Record[3]\r
360 Type = Record[1]\r
361 self.GeneratePpiProtocol(Type, Name, Guid, 'Produced', CName)\r
362\r
363 Content = """ </table></td>\r
364 </tr>"""\r
365 self.WriteLn(Content)\r
366 RecordSet = None\r
367 # End of Produced Ppi/Protocol\r
368\r
369 Content = """ </table></td>\r
370 </tr>"""\r
371 self.WriteLn(Content)\r
372\r
373 ## GenerateTail() method\r
374 #\r
375 # Generate end tags of HTML report\r
376 #\r
377 # @param self: The object pointer\r
378 #\r
379 def GenerateTail(self):\r
380 Tail = """</table>\r
381</body>\r
382</html>"""\r
383 self.WriteLn(Tail)\r
384\r
385 ## GenerateHeader() method\r
386 #\r
387 # Generate start tags of HTML report\r
388 #\r
389 # @param self: The object pointer\r
390 #\r
391 def GenerateHeader(self):\r
392 Header = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"\r
393"http://www.w3.org/TR/html4/loose.dtd">\r
394<html>\r
395<head>\r
396<title>Execution Order Tool Report</title>\r
397<meta http-equiv="Content-Type" content="text/html">\r
398<style type="text/css">\r
399<!--\r
400.styleFfs {\r
401 color: #006600;\r
402 font-weight: bold;\r
403}\r
404.styleDepex {\r
405 color: #FF0066;\r
406 font-weight: bold;\r
407}\r
408.styleProduced {\r
409 color: #0000FF;\r
410 font-weight: bold;\r
411}\r
412.styleConsumed {\r
413 color: #FF00FF;\r
414 font-weight: bold;\r
415}\r
416-->\r
417</style>\r
418<Script type="text/javascript">\r
419function Display(ParentID, SubID)\r
420{\r
421 SubItem = document.getElementById(SubID);\r
422 ParentItem = document.getElementById(ParentID);\r
423 if (SubItem.style.display == 'none')\r
424 {\r
425 SubItem.style.display = ''\r
426 ParentItem.style.fontWeight = 'normal'\r
427 }\r
428 else\r
429 {\r
430 SubItem.style.display = 'none'\r
431 ParentItem.style.fontWeight = 'bold'\r
432 }\r
433\r
434}\r
435\r
436function funOnMouseOver()\r
437{\r
438 document.body.style.cursor = "hand";\r
439}\r
440\r
441function funOnMouseOut()\r
442{\r
443 document.body.style.cursor = "";\r
444}\r
445\r
446</Script>\r
447</head>\r
448\r
449<body>\r
450<table width="100%%" border="1">"""\r
451 self.WriteLn(Header)\r
452\r
453##\r
454#\r
455# This acts like the main() function for the script, unless it is 'import'ed into another\r
456# script.\r
457#\r
458if __name__ == '__main__':\r
459 # Initialize log system\r
460 FilePath = 'FVRECOVERYFLOPPY.fv'\r
461 if FilePath.lower().endswith(".fv"):\r
462 fd = open(FilePath, 'rb')\r
463 buf = array('B')\r
464 try:\r
465 buf.fromfile(fd, os.path.getsize(FilePath))\r
466 except EOFError:\r
467 pass\r
468\r
469 fv = FirmwareVolume("FVRECOVERY", buf, 0)\r
470\r
471 report = Report('Report.html', fv)\r
472 report.GenerateReport()\r