]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Region.py
2 # process FD Region generation
4 # Copyright (c) 2007 - 2014, 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
31 class Region(RegionClassObject
):
35 # @param self The object pointer
38 RegionClassObject
.__init
__(self
)
43 # Add region data to the Buffer
45 # @param self The object pointer
46 # @param Buffer The buffer generated region data will be put
47 # @param BaseAddress base address of region
48 # @param BlockSize block size of region
49 # @param BlockNum How many blocks in region
50 # @param ErasePolarity Flash erase polarity
51 # @param VtfDict VTF objects
52 # @param MacroDict macro value pair
53 # @retval string Generated FV file path
56 def AddToBuffer(self
, Buffer
, BaseAddress
, BlockSizeList
, ErasePolarity
, ImageBinDict
, vtfDict
= None, MacroDict
= {}):
58 GenFdsGlobalVariable
.InfLogger('\nGenerate Region at Offset 0x%X' % self
.Offset
)
59 GenFdsGlobalVariable
.InfLogger(" Region Size = 0x%X" %Size
)
60 GenFdsGlobalVariable
.SharpCounter
= 0
62 if self
.RegionType
== 'FV':
66 self
.FvAddress
= int(BaseAddress
, 16) + self
.Offset
67 FvBaseAddress
= '0x%X' %self
.FvAddress
69 for RegionData
in self
.RegionDataList
:
71 if RegionData
.endswith(".fv"):
72 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
73 GenFdsGlobalVariable
.InfLogger(' Region FV File Name = .fv : %s'%RegionData
)
74 if RegionData
[1] != ':' :
75 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
76 if not os
.path
.exists(RegionData
):
77 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
80 elif RegionData
.upper() + 'fv' in ImageBinDict
.keys():
81 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
82 FileName
= ImageBinDict
[RegionData
.upper() + 'fv']
88 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
89 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(RegionData
.upper())
92 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
96 self
.BlockInfoOfRegion(BlockSizeList
, FvObj
)
97 self
.FvAddress
= self
.FvAddress
+ FvOffset
98 FvAlignValue
= self
.GetFvAlignValue(FvObj
.FvAlignment
)
99 if self
.FvAddress
% FvAlignValue
!= 0:
100 EdkLogger
.error("GenFds", GENFDS_ERROR
,
101 "FV (%s) is NOT %s Aligned!" % (FvObj
.UiFvName
, FvObj
.FvAlignment
))
102 FvBuffer
= StringIO
.StringIO('')
103 FvBaseAddress
= '0x%X' %self
.FvAddress
106 FvObj
.AddToBuffer(FvBuffer
, FvBaseAddress
, BlockSize
, BlockNum
, ErasePolarity
, vtfDict
)
107 if FvBuffer
.len > Size
:
109 EdkLogger
.error("GenFds", GENFDS_ERROR
,
110 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData
, Size
))
112 # Put the generated image into FD buffer.
114 Buffer
.write(FvBuffer
.getvalue())
116 FvOffset
= FvOffset
+ FvBuffer
.len
117 Size
= Size
- FvBuffer
.len
120 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (RegionData
))
122 # Add the exist Fv image into FD buffer
125 FileLength
= os
.stat(FileName
)[ST_SIZE
]
126 if FileLength
> Size
:
127 EdkLogger
.error("GenFds", GENFDS_ERROR
,
128 "Size of FV File (%s) is larger than Region Size 0x%X specified." \
129 % (RegionData
, Size
))
130 BinFile
= open (FileName
, 'r+b')
131 Buffer
.write(BinFile
.read())
133 Size
= Size
- FileLength
135 # Pad the left buffer
138 if (ErasePolarity
== '1') :
142 for i
in range(0, Size
):
143 Buffer
.write(pack('B', PadData
))
145 if self
.RegionType
== 'CAPSULE':
147 # Get Capsule from Capsule Dict
149 for RegionData
in self
.RegionDataList
:
150 if RegionData
.endswith(".cap"):
151 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
152 GenFdsGlobalVariable
.InfLogger(' Region CAPSULE Image Name = .cap : %s'%RegionData
)
153 if RegionData
[1] != ':' :
154 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
155 if not os
.path
.exists(RegionData
):
156 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
158 FileName
= RegionData
159 elif RegionData
.upper() + 'cap' in ImageBinDict
.keys():
160 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
161 FileName
= ImageBinDict
[RegionData
.upper() + 'cap']
164 # Generate Capsule image and Put it into FD buffer
167 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
168 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[RegionData
.upper()]
170 if CapsuleObj
!= None :
171 CapsuleObj
.CapsuleName
= RegionData
.upper()
172 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
174 # Call GenFv tool to generate Capsule Image
176 FileName
= CapsuleObj
.GenCapsule()
177 CapsuleObj
.CapsuleName
= None
179 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Capsule (%s) is NOT described in FDF file!" % (RegionData
))
182 # Add the capsule image into FD buffer
184 FileLength
= os
.stat(FileName
)[ST_SIZE
]
185 if FileLength
> Size
:
186 EdkLogger
.error("GenFds", GENFDS_ERROR
,
187 "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
188 % (FileLength
, RegionData
, Size
))
189 BinFile
= open (FileName
, 'r+b')
190 Buffer
.write(BinFile
.read())
192 Size
= Size
- FileLength
194 # Pad the left buffer
197 if (ErasePolarity
== '1') :
201 for i
in range(0, Size
):
202 Buffer
.write(pack('B', PadData
))
204 if self
.RegionType
== 'FILE':
205 for RegionData
in self
.RegionDataList
:
206 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
207 if RegionData
[1] != ':' :
208 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
209 if not os
.path
.exists(RegionData
):
210 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
212 # Add the file image into FD buffer
214 FileLength
= os
.stat(RegionData
)[ST_SIZE
]
215 if FileLength
> Size
:
216 EdkLogger
.error("GenFds", GENFDS_ERROR
,
217 "Size of File (%s) is larger than Region Size 0x%X specified." \
218 % (RegionData
, Size
))
219 GenFdsGlobalVariable
.InfLogger(' Region File Name = %s'%RegionData
)
220 BinFile
= open (RegionData
, 'rb')
221 Buffer
.write(BinFile
.read())
223 Size
= Size
- FileLength
225 # Pad the left buffer
228 if (ErasePolarity
== '1') :
232 for i
in range(0, Size
):
233 Buffer
.write(pack('B', PadData
))
235 if self
.RegionType
== 'DATA' :
236 GenFdsGlobalVariable
.InfLogger(' Region Name = DATA')
238 for RegionData
in self
.RegionDataList
:
239 Data
= RegionData
.split(',')
240 DataSize
= DataSize
+ len(Data
)
242 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Size of DATA is larger than Region Size ")
245 Buffer
.write(pack('B', int(item
, 16)))
246 Size
= Size
- DataSize
248 # Pad the left buffer
251 if (ErasePolarity
== '1') :
255 for i
in range(0, Size
):
256 Buffer
.write(pack('B', PadData
))
258 if self
.RegionType
== None:
259 GenFdsGlobalVariable
.InfLogger(' Region Name = None')
260 if (ErasePolarity
== '1') :
264 for i
in range(0, Size
):
265 Buffer
.write(pack('B', PadData
))
267 def GetFvAlignValue(self
, Str
):
270 Str
= Str
.strip().upper()
271 if Str
.endswith('K'):
274 elif Str
.endswith('M'):
277 elif Str
.endswith('G'):
278 Granu
= 1024*1024*1024
283 AlignValue
= int(Str
)*Granu
286 ## BlockSizeOfRegion()
288 # @param BlockSizeList List of block information
289 # @param FvObj The object for FV
291 def BlockInfoOfRegion(self
, BlockSizeList
, FvObj
):
294 RemindingSize
= self
.Size
296 for (BlockSize
, BlockNum
, pcd
) in BlockSizeList
:
297 End
= Start
+ BlockSize
* BlockNum
298 # region not started yet
299 if self
.Offset
>= End
:
302 # region located in current blocks
304 # region ended within current blocks
305 if self
.Offset
+ self
.Size
<= End
:
306 ExpectedList
.append((BlockSize
, (RemindingSize
+ BlockSize
- 1)/BlockSize
))
308 # region not ended yet
310 # region not started in middle of current blocks
311 if self
.Offset
<= Start
:
312 UsedBlockNum
= BlockNum
313 # region started in middle of current blocks
315 UsedBlockNum
= (End
- self
.Offset
)/BlockSize
317 ExpectedList
.append((BlockSize
, UsedBlockNum
))
318 RemindingSize
-= BlockSize
* UsedBlockNum
320 if FvObj
.BlockSizeList
== []:
321 FvObj
.BlockSizeList
= ExpectedList
323 # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",
324 # if so, use ExpectedList
325 for Item
in FvObj
.BlockSizeList
:
326 if Item
[0] == None or Item
[1] == None:
327 FvObj
.BlockSizeList
= ExpectedList
329 # make sure region size is no smaller than the summed block size in FV
331 for Item
in FvObj
.BlockSizeList
:
332 Sum
+= Item
[0] * Item
[1]
334 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "
335 %(FvObj
.UiFvName
, Sum
, self
.Size
))
336 # check whether the BlockStatements in FV section is appropriate
337 ExpectedListData
= ''
338 for Item
in ExpectedList
:
339 ExpectedListData
+= "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t"%Item
341 for Item
in FvObj
.BlockSizeList
:
342 if Item
[0] != ExpectedList
[Index
][0]:
343 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
344 %FvObj
.UiFvName
, ExtraData
= ExpectedListData
)
345 elif Item
[1] != ExpectedList
[Index
][1]:
346 if (Item
[1] < ExpectedList
[Index
][1]) and (Index
== len(FvObj
.BlockSizeList
) - 1):
349 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
350 %FvObj
.UiFvName
, ExtraData
= ExpectedListData
)