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