]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Region.py
2 # process FD Region generation
4 # Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
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
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.
19 from GenFdsGlobalVariable
import GenFdsGlobalVariable
21 from CommonDataClass
.FdfClass
import RegionClassObject
22 import Common
.LongFilePathOs
as os
24 from Common
import EdkLogger
25 from Common
.BuildToolError
import *
26 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
27 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
32 class Region(RegionClassObject
):
36 # @param self The object pointer
39 RegionClassObject
.__init
__(self
)
44 # Add padding bytes to the Buffer
46 # @param Buffer The buffer the generated region data will be put
48 # @param ErasePolarity Flash erase polarity
49 # @param Size Number of padding bytes requested
52 def PadBuffer(self
, Buffer
, ErasePolarity
, Size
):
54 if (ErasePolarity
== '1') :
58 for i
in range(0, Size
):
59 Buffer
.write(pack('B', PadData
))
63 # Add region data to the Buffer
65 # @param self The object pointer
66 # @param Buffer The buffer generated region data will be put
67 # @param BaseAddress base address of region
68 # @param BlockSize block size of region
69 # @param BlockNum How many blocks in region
70 # @param ErasePolarity Flash erase polarity
71 # @param VtfDict VTF objects
72 # @param MacroDict macro value pair
73 # @retval string Generated FV file path
76 def AddToBuffer(self
, Buffer
, BaseAddress
, BlockSizeList
, ErasePolarity
, ImageBinDict
, vtfDict
=None, MacroDict
={}):
78 GenFdsGlobalVariable
.InfLogger('\nGenerate Region at Offset 0x%X' % self
.Offset
)
79 GenFdsGlobalVariable
.InfLogger(" Region Size = 0x%X" % Size
)
80 GenFdsGlobalVariable
.SharpCounter
= 0
82 if self
.RegionType
== 'FV':
86 self
.FvAddress
= int(BaseAddress
, 16) + self
.Offset
87 FvBaseAddress
= '0x%X' % self
.FvAddress
89 for RegionData
in self
.RegionDataList
:
91 if RegionData
.endswith(".fv"):
92 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
93 GenFdsGlobalVariable
.InfLogger(' Region FV File Name = .fv : %s' % RegionData
)
94 if RegionData
[1] != ':' :
95 RegionData
= mws
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
96 if not os
.path
.exists(RegionData
):
97 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
100 elif RegionData
.upper() + 'fv' in ImageBinDict
.keys():
101 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
102 FileName
= ImageBinDict
[RegionData
.upper() + 'fv']
108 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
109 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(RegionData
.upper())
112 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
116 self
.BlockInfoOfRegion(BlockSizeList
, FvObj
)
117 self
.FvAddress
= self
.FvAddress
+ FvOffset
118 FvAlignValue
= self
.GetFvAlignValue(FvObj
.FvAlignment
)
119 if self
.FvAddress
% FvAlignValue
!= 0:
120 EdkLogger
.error("GenFds", GENFDS_ERROR
,
121 "FV (%s) is NOT %s Aligned!" % (FvObj
.UiFvName
, FvObj
.FvAlignment
))
122 FvBuffer
= StringIO
.StringIO('')
123 FvBaseAddress
= '0x%X' % self
.FvAddress
126 FvObj
.AddToBuffer(FvBuffer
, FvBaseAddress
, BlockSize
, BlockNum
, ErasePolarity
, vtfDict
)
127 if FvBuffer
.len > Size
:
129 EdkLogger
.error("GenFds", GENFDS_ERROR
,
130 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData
, Size
))
132 # Put the generated image into FD buffer.
134 Buffer
.write(FvBuffer
.getvalue())
136 FvOffset
= FvOffset
+ FvBuffer
.len
137 Size
= Size
- FvBuffer
.len
140 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (RegionData
))
142 # Add the exist Fv image into FD buffer
145 FileLength
= os
.stat(FileName
)[ST_SIZE
]
146 if FileLength
> Size
:
147 EdkLogger
.error("GenFds", GENFDS_ERROR
,
148 "Size of FV File (%s) is larger than Region Size 0x%X specified." \
149 % (RegionData
, Size
))
150 BinFile
= open(FileName
, 'r+b')
151 Buffer
.write(BinFile
.read())
153 Size
= Size
- FileLength
155 # Pad the left buffer
157 self
.PadBuffer(Buffer
, ErasePolarity
, Size
)
159 if self
.RegionType
== 'CAPSULE':
161 # Get Capsule from Capsule Dict
163 for RegionData
in self
.RegionDataList
:
164 if RegionData
.endswith(".cap"):
165 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
166 GenFdsGlobalVariable
.InfLogger(' Region CAPSULE Image Name = .cap : %s' % RegionData
)
167 if RegionData
[1] != ':' :
168 RegionData
= mws
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
169 if not os
.path
.exists(RegionData
):
170 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
172 FileName
= RegionData
173 elif RegionData
.upper() + 'cap' in ImageBinDict
.keys():
174 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
175 FileName
= ImageBinDict
[RegionData
.upper() + 'cap']
178 # Generate Capsule image and Put it into FD buffer
181 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
182 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[RegionData
.upper()]
184 if CapsuleObj
!= None :
185 CapsuleObj
.CapsuleName
= RegionData
.upper()
186 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
188 # Call GenFv tool to generate Capsule Image
190 FileName
= CapsuleObj
.GenCapsule()
191 CapsuleObj
.CapsuleName
= None
193 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Capsule (%s) is NOT described in FDF file!" % (RegionData
))
196 # Add the capsule image into FD buffer
198 FileLength
= os
.stat(FileName
)[ST_SIZE
]
199 if FileLength
> Size
:
200 EdkLogger
.error("GenFds", GENFDS_ERROR
,
201 "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
202 % (FileLength
, RegionData
, Size
))
203 BinFile
= open(FileName
, 'r+b')
204 Buffer
.write(BinFile
.read())
206 Size
= Size
- FileLength
208 # Pad the left buffer
210 self
.PadBuffer(Buffer
, ErasePolarity
, Size
)
212 if self
.RegionType
in ('FILE', 'INF'):
213 for RegionData
in self
.RegionDataList
:
214 if self
.RegionType
== 'INF':
215 RegionData
.__InfParse
__(None)
216 if len(RegionData
.BinFileList
) != 1:
217 EdkLogger
.error('GenFds', GENFDS_ERROR
, 'INF in FD region can only contain one binary: %s' % RegionData
)
218 File
= RegionData
.BinFileList
[0]
219 RegionData
= RegionData
.PatchEfiFile(File
.Path
, File
.Type
)
221 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
222 if RegionData
[1] != ':' :
223 RegionData
= mws
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
224 if not os
.path
.exists(RegionData
):
225 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
227 # Add the file image into FD buffer
229 FileLength
= os
.stat(RegionData
)[ST_SIZE
]
230 if FileLength
> Size
:
231 EdkLogger
.error("GenFds", GENFDS_ERROR
,
232 "Size of File (%s) is larger than Region Size 0x%X specified." \
233 % (RegionData
, Size
))
234 GenFdsGlobalVariable
.InfLogger(' Region File Name = %s' % RegionData
)
235 BinFile
= open(RegionData
, 'rb')
236 Buffer
.write(BinFile
.read())
238 Size
= Size
- FileLength
240 # Pad the left buffer
242 self
.PadBuffer(Buffer
, ErasePolarity
, Size
)
244 if self
.RegionType
== 'DATA' :
245 GenFdsGlobalVariable
.InfLogger(' Region Name = DATA')
247 for RegionData
in self
.RegionDataList
:
248 Data
= RegionData
.split(',')
249 DataSize
= DataSize
+ len(Data
)
251 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Size of DATA is larger than Region Size ")
254 Buffer
.write(pack('B', int(item
, 16)))
255 Size
= Size
- DataSize
257 # Pad the left buffer
259 self
.PadBuffer(Buffer
, ErasePolarity
, Size
)
261 if self
.RegionType
== None:
262 GenFdsGlobalVariable
.InfLogger(' Region Name = None')
263 self
.PadBuffer(Buffer
, ErasePolarity
, Size
)
265 def GetFvAlignValue(self
, Str
):
268 Str
= Str
.strip().upper()
269 if Str
.endswith('K'):
272 elif Str
.endswith('M'):
275 elif Str
.endswith('G'):
276 Granu
= 1024 * 1024 * 1024
281 AlignValue
= int(Str
) * Granu
284 ## BlockSizeOfRegion()
286 # @param BlockSizeList List of block information
287 # @param FvObj The object for FV
289 def BlockInfoOfRegion(self
, BlockSizeList
, FvObj
):
292 RemindingSize
= self
.Size
294 for (BlockSize
, BlockNum
, pcd
) in BlockSizeList
:
295 End
= Start
+ BlockSize
* BlockNum
296 # region not started yet
297 if self
.Offset
>= End
:
300 # region located in current blocks
302 # region ended within current blocks
303 if self
.Offset
+ self
.Size
<= End
:
304 ExpectedList
.append((BlockSize
, (RemindingSize
+ BlockSize
- 1) / BlockSize
))
306 # region not ended yet
308 # region not started in middle of current blocks
309 if self
.Offset
<= Start
:
310 UsedBlockNum
= BlockNum
311 # region started in middle of current blocks
313 UsedBlockNum
= (End
- self
.Offset
) / BlockSize
315 ExpectedList
.append((BlockSize
, UsedBlockNum
))
316 RemindingSize
-= BlockSize
* UsedBlockNum
318 if FvObj
.BlockSizeList
== []:
319 FvObj
.BlockSizeList
= ExpectedList
321 # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",
322 # if so, use ExpectedList
323 for Item
in FvObj
.BlockSizeList
:
324 if Item
[0] == None or Item
[1] == None:
325 FvObj
.BlockSizeList
= ExpectedList
327 # make sure region size is no smaller than the summed block size in FV
329 for Item
in FvObj
.BlockSizeList
:
330 Sum
+= Item
[0] * Item
[1]
332 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "
333 % (FvObj
.UiFvName
, Sum
, self
.Size
))
334 # check whether the BlockStatements in FV section is appropriate
335 ExpectedListData
= ''
336 for Item
in ExpectedList
:
337 ExpectedListData
+= "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t" % Item
339 for Item
in FvObj
.BlockSizeList
:
340 if Item
[0] != ExpectedList
[Index
][0]:
341 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
342 % FvObj
.UiFvName
, ExtraData
=ExpectedListData
)
343 elif Item
[1] != ExpectedList
[Index
][1]:
344 if (Item
[1] < ExpectedList
[Index
][1]) and (Index
== len(FvObj
.BlockSizeList
) - 1):
347 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
348 % FvObj
.UiFvName
, ExtraData
=ExpectedListData
)