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