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