1## @file
2# process FD generation
3#
4#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6#  This program and the accompanying materials
7#  are licensed and made available under the terms and conditions of the BSD License
8#  which accompanies this distribution.  The full text of the license may be found at
9#  http://opensource.org/licenses/bsd-license.php
10#
11#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15##
16# Import Modules
17#
18import Region
19import Fv
20import Common.LongFilePathOs as os
21import StringIO
22import sys
23from struct import *
24from GenFdsGlobalVariable import GenFdsGlobalVariable
25from CommonDataClass.FdfClass import FDClassObject
26from Common import EdkLogger
27from Common.BuildToolError import *
28from Common.Misc import SaveFileOnChange
29from GenFds import GenFds
30
31## generate FD
32#
33#
34class FD(FDClassObject):
35    ## The constructor
36    #
37    #   @param  self        The object pointer
38    #
39    def __init__(self):
40        FDClassObject.__init__(self)
41
42    ## GenFd() method
43    #
44    #   Generate FD
45    #
46    #   @retval string      Generated FD file name
47    #
48    def GenFd (self):
49        if self.FdUiName.upper() + 'fd' in GenFds.ImageBinDict.keys():
50            return GenFds.ImageBinDict[self.FdUiName.upper() + 'fd']
51
52        #
53        # Print Information
54        #
55        GenFdsGlobalVariable.InfLogger("Fd File Name:%s" %self.FdUiName)
56        Offset = 0x00
57        for item in self.BlockSizeList:
58            Offset = Offset + item[0]  * item[1]
59        if Offset != self.Size:
60            EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
61        GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
62        for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
63            GenFdsGlobalVariable.VerboseLogger(FvObj)
64
65        GenFdsGlobalVariable.VerboseLogger('################### Gen VTF ####################')
66        self.GenVtfFile()
67
68        TempFdBuffer = StringIO.StringIO('')
69        PreviousRegionStart = -1
70        PreviousRegionSize = 1
71
72        for RegionObj in self.RegionList :
73            if RegionObj.RegionType == 'CAPSULE':
74                continue
75            if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
76                pass
77            elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
78                pass
79            elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
80                GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
81                PadRegion = Region.Region()
82                PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
83                PadRegion.Size = RegionObj.Offset - PadRegion.Offset
84                PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
85            PreviousRegionStart = RegionObj.Offset
86            PreviousRegionSize = RegionObj.Size
87            #
88            # Call each region's AddToBuffer function
89            #
90            if PreviousRegionSize > self.Size:
91                pass
92            GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
93            RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
94
95        FdBuffer = StringIO.StringIO('')
96        PreviousRegionStart = -1
97        PreviousRegionSize = 1
98        for RegionObj in self.RegionList :
99            if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
100                EdkLogger.error("GenFds", GENFDS_ERROR,
101                                'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\
102                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
103            elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
104                EdkLogger.error("GenFds", GENFDS_ERROR,
105                                'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
106                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
107            elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
108                GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
109                PadRegion = Region.Region()
110                PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
111                PadRegion.Size = RegionObj.Offset - PadRegion.Offset
112                PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
113            PreviousRegionStart = RegionObj.Offset
114            PreviousRegionSize = RegionObj.Size
115            #
116            # Verify current region fits within allocated FD section Size
117            #
118            if PreviousRegionStart + PreviousRegionSize > self.Size:
119                EdkLogger.error("GenFds", GENFDS_ERROR,
120                                'FD %s size too small to fit region with offset 0x%X and size 0x%X'
121                                % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
122            #
123            # Call each region's AddToBuffer function
124            #
125            GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
126            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
127        #
128        # Create a empty Fd file
129        #
130        GenFdsGlobalVariable.VerboseLogger ('Create an empty Fd file')
131        FdFileName = os.path.join(GenFdsGlobalVariable.FvDir,self.FdUiName + '.fd')
132        #
133        # Write the buffer contents to Fd file
134        #
135        GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
136        SaveFileOnChange(FdFileName, FdBuffer.getvalue())
137        FdBuffer.close();
138        GenFds.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
139        return FdFileName
140
141    ## generate VTF
142    #
143    #   @param  self        The object pointer
144    #
145    def GenVtfFile (self) :
146        #
147        # Get this Fd's all Fv name
148        #
149        FvAddDict ={}
150        FvList = []
151        for RegionObj in self.RegionList:
152            if RegionObj.RegionType == 'FV':
153                if len(RegionObj.RegionDataList) == 1:
154                    RegionData = RegionObj.RegionDataList[0]
155                    FvList.append(RegionData.upper())
156                    FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
157                                                RegionObj.Offset, RegionObj.Size)
158                else:
159                    Offset = RegionObj.Offset
160                    for RegionData in RegionObj.RegionDataList:
161                        FvList.append(RegionData.upper())
162                        FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
163                        if len(FvObj.BlockSizeList) < 1:
164                            EdkLogger.error("GenFds", GENFDS_ERROR,
165                                            'FV.%s must point out FVs blocksize and Fv BlockNum' \
166                                            % FvObj.UiFvName)
167                        else:
168                            Size = 0
169                            for blockStatement in FvObj.BlockSizeList:
170                                Size = Size + blockStatement[0] * blockStatement[1]
171                            FvAddDict[RegionData.upper()] = (int(self.BaseAddress,16) + \
172                                                             Offset, Size)
173                            Offset = Offset + Size
174        #
175        # Check whether this Fd need VTF
176        #
177        Flag = False
178        for VtfObj in GenFdsGlobalVariable.FdfParser.Profile.VtfList:
179            compLocList = VtfObj.GetFvList()
180            if set(compLocList).issubset(FvList):
181                Flag = True
182                break
183        if Flag == True:
184            self.vtfRawDict = VtfObj.GenVtf(FvAddDict)
185
186    ## generate flash map file
187    #
188    #   @param  self        The object pointer
189    #
190    def GenFlashMap (self):
191        pass
192
193
194
195
196
197
198
199
200