]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Region.py
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Region.py
1 ## @file
2 # process FD Region generation
3 #
4 # Copyright (c) 2007, Intel Corporation
5 #
6 # All rights reserved. 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 #
18 from struct import *
19 from GenFdsGlobalVariable import GenFdsGlobalVariable
20 import StringIO
21 from CommonDataClass.FdfClass import RegionClassObject
22 import os
23 from Common import EdkLogger
24 from Common.BuildToolError import *
25
26
27 ## generate Region
28 #
29 #
30 class Region(RegionClassObject):
31
32 ## The constructor
33 #
34 # @param self The object pointer
35 #
36 def __init__(self):
37 RegionClassObject.__init__(self)
38
39
40 ## AddToBuffer()
41 #
42 # Add region data to the Buffer
43 #
44 # @param self The object pointer
45 # @param Buffer The buffer generated region data will be put
46 # @param BaseAddress base address of region
47 # @param BlockSize block size of region
48 # @param BlockNum How many blocks in region
49 # @param ErasePolarity Flash erase polarity
50 # @param VtfDict VTF objects
51 # @param MacroDict macro value pair
52 # @retval string Generated FV file path
53 #
54
55 def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, FvBinDict, vtfDict = None, MacroDict = {}):
56 Size = self.Size
57 GenFdsGlobalVariable.InfLogger('Generate Region at Offset 0x%X' % self.Offset)
58 GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" %Size)
59 GenFdsGlobalVariable.SharpCounter = 0
60
61 if self.RegionType == 'FV':
62 #
63 # Get Fv from FvDict
64 #
65 FvBuffer = StringIO.StringIO('')
66 RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList)
67 RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize)
68
69 self.FvAddress = int(BaseAddress, 16) + self.Offset
70 FvBaseAddress = '0x%X' %self.FvAddress
71
72 for RegionData in self.RegionDataList:
73
74 if RegionData.endswith(".fv"):
75 RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
76 GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s'%RegionData)
77 if RegionData[1] != ':' :
78 RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
79 if not os.path.exists(RegionData):
80 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
81
82 BinFile = open (RegionData, 'r+b')
83 FvBuffer.write(BinFile.read())
84 if FvBuffer.len > Size:
85 EdkLogger.error("GenFds", GENFDS_ERROR,
86 "Size of FV File (%s) is larger than Region Size 0x%X specified." \
87 % (RegionData, Size))
88 break
89
90 if RegionData.upper() in FvBinDict.keys():
91 continue
92
93 FvObj = None
94 if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
95 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(RegionData.upper())
96
97 if FvObj != None :
98 GenFdsGlobalVariable.InfLogger(' Region Name = FV')
99 #
100 # Call GenFv tool
101 #
102 BlockSize = RegionBlockSize
103 BlockNum = RegionBlockNum
104 if FvObj.BlockSizeList != []:
105 if FvObj.BlockSizeList[0][0] != None:
106 BlockSize = FvObj.BlockSizeList[0][0]
107 if FvObj.BlockSizeList[0][1] != None:
108 BlockNum = FvObj.BlockSizeList[0][1]
109 self.FvAddress = self.FvAddress + FvBuffer.len
110 FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)
111 if self.FvAddress % FvAlignValue != 0:
112 EdkLogger.error("GenFds", GENFDS_ERROR,
113 "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
114 FvBaseAddress = '0x%X' %self.FvAddress
115 FileName = FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)
116
117 if FvBuffer.len > Size:
118 EdkLogger.error("GenFds", GENFDS_ERROR,
119 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
120 else:
121 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
122
123
124 if FvBuffer.len > 0:
125 Buffer.write(FvBuffer.getvalue())
126 else:
127 BinFile = open (FileName, 'rb')
128 Buffer.write(BinFile.read())
129
130 FvBuffer.close()
131
132 if self.RegionType == 'FILE':
133 FvBuffer = StringIO.StringIO('')
134 for RegionData in self.RegionDataList:
135 RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
136 GenFdsGlobalVariable.InfLogger(' Region File Name = FILE: %s'%RegionData)
137 if RegionData[1] != ':' :
138 RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
139 if not os.path.exists(RegionData):
140 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
141
142 BinFile = open (RegionData, 'r+b')
143 FvBuffer.write(BinFile.read())
144 if FvBuffer.len > Size :
145 EdkLogger.error("GenFds", GENFDS_ERROR,
146 "Size of File (%s) large than Region Size " % RegionData)
147
148 #
149 # If File contents less than region size, append "0xff" after it
150 #
151 if FvBuffer.len < Size:
152 for index in range(0, (Size-FvBuffer.len)):
153 if (ErasePolarity == '1'):
154 FvBuffer.write(pack('B', int('0xFF', 16)))
155 else:
156 FvBuffer.write(pack('B', int('0x00', 16)))
157 Buffer.write(FvBuffer.getvalue())
158 FvBuffer.close()
159
160 if self.RegionType == 'DATA' :
161 GenFdsGlobalVariable.InfLogger(' Region Name = DATA')
162 DataSize = 0
163 for RegionData in self.RegionDataList:
164 Data = RegionData.split(',')
165 DataSize = DataSize + len(Data)
166 if DataSize > Size:
167 EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ")
168 else:
169 for item in Data :
170 Buffer.write(pack('B', int(item, 16)))
171 if DataSize < Size:
172 if (ErasePolarity == '1'):
173 PadData = 0xFF
174 else:
175 PadData = 0
176 for i in range(Size - DataSize):
177 Buffer.write(pack('B', PadData))
178
179 if self.RegionType == None:
180 GenFdsGlobalVariable.InfLogger(' Region Name = None')
181 if (ErasePolarity == '1') :
182 PadData = 0xFF
183 else :
184 PadData = 0
185 for i in range(0, Size):
186 Buffer.write(pack('B', PadData))
187
188 def GetFvAlignValue(self, Str):
189 AlignValue = 1
190 Granu = 1
191 Str = Str.strip().upper()
192 if Str.endswith('K'):
193 Granu = 1024
194 Str = Str[:-1]
195 elif Str.endswith('M'):
196 Granu = 1024*1024
197 Str = Str[:-1]
198 elif Str.endswith('G'):
199 Granu = 1024*1024*1024
200 Str = Str[:-1]
201 else:
202 pass
203
204 AlignValue = int(Str)*Granu
205 return AlignValue
206 ## BlockSizeOfRegion()
207 #
208 # @param BlockSizeList List of block information
209 # @retval int Block size of region
210 #
211 def BlockSizeOfRegion(self, BlockSizeList):
212 Offset = 0x00
213 BlockSize = 0
214 for item in BlockSizeList:
215 Offset = Offset + item[0] * item[1]
216 GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset)
217 GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset)
218
219 if self.Offset < Offset :
220 if Offset - self.Offset < self.Size:
221 EdkLogger.error("GenFds", GENFDS_ERROR,
222 "Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \
223 % (self.Offset, item[0]))
224 BlockSize = item[0]
225 GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize)
226 return BlockSize
227 return BlockSize
228
229 ## BlockNumOfRegion()
230 #
231 # @param BlockSize block size of region
232 # @retval int Block number of region
233 #
234 def BlockNumOfRegion (self, BlockSize):
235 if BlockSize == 0 :
236 EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset)
237 BlockNum = self.Size / BlockSize
238 GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum)
239 return BlockNum
240