1## @file
2# process FD generation
3#
4#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5#
6#  SPDX-License-Identifier: BSD-2-Clause-Patent
7#
8
9##
10# Import Modules
11#
12from __future__ import absolute_import
13from . import Region
14from . import Fv
15import Common.LongFilePathOs as os
16from io import BytesIO
17import sys
18from struct import *
19from .GenFdsGlobalVariable import GenFdsGlobalVariable
20from CommonDataClass.FdfClass import FDClassObject
21from Common import EdkLogger
22from Common.BuildToolError import *
23from Common.Misc import SaveFileOnChange
24from Common.DataType import BINARY_FILE_TYPE_FV
25
26## generate FD
27#
28#
29class FD(FDClassObject):
30    ## The constructor
31    #
32    #   @param  self        The object pointer
33    #
34    def __init__(self):
35        FDClassObject.__init__(self)
36
37    ## GenFd() method
38    #
39    #   Generate FD
40    #
41    #   @retval string      Generated FD file name
42    #
43    def GenFd (self, Flag = False):
44        if self.FdUiName.upper() + 'fd' in GenFdsGlobalVariable.ImageBinDict:
45            return GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd']
46
47        #
48        # Print Information
49        #
50        FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd')
51        if not Flag:
52            GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName))
53
54        Offset = 0x00
55        for item in self.BlockSizeList:
56            Offset = Offset + item[0]  * item[1]
57        if Offset != self.Size:
58            EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
59        GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
60        for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
61            GenFdsGlobalVariable.VerboseLogger(FvObj)
62
63        HasCapsuleRegion = False
64        for RegionObj in self.RegionList:
65            if RegionObj.RegionType == 'CAPSULE':
66                HasCapsuleRegion = True
67                break
68        if HasCapsuleRegion:
69            TempFdBuffer = BytesIO()
70            PreviousRegionStart = -1
71            PreviousRegionSize = 1
72
73            for RegionObj in self.RegionList :
74                if RegionObj.RegionType == 'CAPSULE':
75                    continue
76                if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
77                    pass
78                elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
79                    pass
80                elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
81                    if not Flag:
82                        GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
83                    PadRegion = Region.Region()
84                    PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
85                    PadRegion.Size = RegionObj.Offset - PadRegion.Offset
86                    if not Flag:
87                        PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
88                PreviousRegionStart = RegionObj.Offset
89                PreviousRegionSize = RegionObj.Size
90                #
91                # Call each region's AddToBuffer function
92                #
93                if PreviousRegionSize > self.Size:
94                    pass
95                GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
96                RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
97
98        FdBuffer = BytesIO()
99        PreviousRegionStart = -1
100        PreviousRegionSize = 1
101        for RegionObj in self.RegionList :
102            if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
103                EdkLogger.error("GenFds", GENFDS_ERROR,
104                                '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.'\
105                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
106            elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
107                EdkLogger.error("GenFds", GENFDS_ERROR,
108                                'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
109                                % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
110            elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
111                if not Flag:
112                    GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
113                PadRegion = Region.Region()
114                PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
115                PadRegion.Size = RegionObj.Offset - PadRegion.Offset
116                if not Flag:
117                    PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
118            PreviousRegionStart = RegionObj.Offset
119            PreviousRegionSize = RegionObj.Size
120            #
121            # Verify current region fits within allocated FD section Size
122            #
123            if PreviousRegionStart + PreviousRegionSize > self.Size:
124                EdkLogger.error("GenFds", GENFDS_ERROR,
125                                'FD %s size too small to fit region with offset 0x%X and size 0x%X'
126                                % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
127            #
128            # Call each region's AddToBuffer function
129            #
130            GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
131            RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict, Flag=Flag)
132        #
133        # Write the buffer contents to Fd file
134        #
135        GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
136        if not Flag:
137            SaveFileOnChange(FdFileName, FdBuffer.getvalue())
138        FdBuffer.close()
139        GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
140        return FdFileName
141
142    ## generate flash map file
143    #
144    #   @param  self        The object pointer
145    #
146    def GenFlashMap (self):
147        pass
148
149
150
151
152
153
154
155
156