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