]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Region.py
01e998e54c6fb6c5fa2ec1aa5c4d0f8e47622c54
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
27 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
32 class Region(RegionClassObject
):
36 # @param self The object pointer
39 RegionClassObject
.__init
__(self
)
44 # Add region data to the Buffer
46 # @param self The object pointer
47 # @param Buffer The buffer generated region data will be put
48 # @param BaseAddress base address of region
49 # @param BlockSize block size of region
50 # @param BlockNum How many blocks in region
51 # @param ErasePolarity Flash erase polarity
52 # @param VtfDict VTF objects
53 # @param MacroDict macro value pair
54 # @retval string Generated FV file path
57 def AddToBuffer(self
, Buffer
, BaseAddress
, BlockSizeList
, ErasePolarity
, ImageBinDict
, vtfDict
=None, MacroDict
={}):
59 GenFdsGlobalVariable
.InfLogger('\nGenerate Region at Offset 0x%X' % self
.Offset
)
60 GenFdsGlobalVariable
.InfLogger(" Region Size = 0x%X" % Size
)
61 GenFdsGlobalVariable
.SharpCounter
= 0
63 if self
.RegionType
== 'FV':
67 self
.FvAddress
= int(BaseAddress
, 16) + self
.Offset
68 FvBaseAddress
= '0x%X' % self
.FvAddress
70 for RegionData
in self
.RegionDataList
:
72 if RegionData
.endswith(".fv"):
73 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
74 GenFdsGlobalVariable
.InfLogger(' Region FV File Name = .fv : %s' % RegionData
)
75 if RegionData
[1] != ':' :
76 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
77 if not os
.path
.exists(RegionData
):
78 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
81 elif RegionData
.upper() + 'fv' in ImageBinDict
.keys():
82 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
83 FileName
= ImageBinDict
[RegionData
.upper() + 'fv']
89 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
90 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(RegionData
.upper())
93 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
97 self
.BlockInfoOfRegion(BlockSizeList
, FvObj
)
98 self
.FvAddress
= self
.FvAddress
+ FvOffset
99 FvAlignValue
= self
.GetFvAlignValue(FvObj
.FvAlignment
)
100 if self
.FvAddress
% FvAlignValue
!= 0:
101 EdkLogger
.error("GenFds", GENFDS_ERROR
,
102 "FV (%s) is NOT %s Aligned!" % (FvObj
.UiFvName
, FvObj
.FvAlignment
))
103 FvBuffer
= StringIO
.StringIO('')
104 FvBaseAddress
= '0x%X' % self
.FvAddress
107 FvObj
.AddToBuffer(FvBuffer
, FvBaseAddress
, BlockSize
, BlockNum
, ErasePolarity
, vtfDict
)
108 if FvBuffer
.len > Size
:
110 EdkLogger
.error("GenFds", GENFDS_ERROR
,
111 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData
, Size
))
113 # Put the generated image into FD buffer.
115 Buffer
.write(FvBuffer
.getvalue())
117 FvOffset
= FvOffset
+ FvBuffer
.len
118 Size
= Size
- FvBuffer
.len
121 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (RegionData
))
123 # Add the exist Fv image into FD buffer
126 FileLength
= os
.stat(FileName
)[ST_SIZE
]
127 if FileLength
> Size
:
128 EdkLogger
.error("GenFds", GENFDS_ERROR
,
129 "Size of FV File (%s) is larger than Region Size 0x%X specified." \
130 % (RegionData
, Size
))
131 BinFile
= open(FileName
, 'r+b')
132 Buffer
.write(BinFile
.read())
134 Size
= Size
- FileLength
136 # Pad the left buffer
139 if (ErasePolarity
== '1') :
143 for i
in range(0, Size
):
144 Buffer
.write(pack('B', PadData
))
146 if self
.RegionType
== 'CAPSULE':
148 # Get Capsule from Capsule Dict
150 for RegionData
in self
.RegionDataList
:
151 if RegionData
.endswith(".cap"):
152 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
153 GenFdsGlobalVariable
.InfLogger(' Region CAPSULE Image Name = .cap : %s' % RegionData
)
154 if RegionData
[1] != ':' :
155 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
156 if not os
.path
.exists(RegionData
):
157 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
159 FileName
= RegionData
160 elif RegionData
.upper() + 'cap' in ImageBinDict
.keys():
161 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
162 FileName
= ImageBinDict
[RegionData
.upper() + 'cap']
165 # Generate Capsule image and Put it into FD buffer
168 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
169 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[RegionData
.upper()]
171 if CapsuleObj
!= None :
172 CapsuleObj
.CapsuleName
= RegionData
.upper()
173 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
175 # Call GenFv tool to generate Capsule Image
177 FileName
= CapsuleObj
.GenCapsule()
178 CapsuleObj
.CapsuleName
= None
180 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Capsule (%s) is NOT described in FDF file!" % (RegionData
))
183 # Add the capsule image into FD buffer
185 FileLength
= os
.stat(FileName
)[ST_SIZE
]
186 if FileLength
> Size
:
187 EdkLogger
.error("GenFds", GENFDS_ERROR
,
188 "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
189 % (FileLength
, RegionData
, Size
))
190 BinFile
= open(FileName
, 'r+b')
191 Buffer
.write(BinFile
.read())
193 Size
= Size
- FileLength
195 # Pad the left buffer
198 if (ErasePolarity
== '1') :
202 for i
in range(0, Size
):
203 Buffer
.write(pack('B', PadData
))
205 if self
.RegionType
== 'FILE':
206 for RegionData
in self
.RegionDataList
:
207 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
208 if RegionData
[1] != ':' :
209 RegionData
= mws
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
210 if not os
.path
.exists(RegionData
):
211 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
213 # Add the file image into FD buffer
215 FileLength
= os
.stat(RegionData
)[ST_SIZE
]
216 if FileLength
> Size
:
217 EdkLogger
.error("GenFds", GENFDS_ERROR
,
218 "Size of File (%s) is larger than Region Size 0x%X specified." \
219 % (RegionData
, Size
))
220 GenFdsGlobalVariable
.InfLogger(' Region File Name = %s' % RegionData
)
221 BinFile
= open(RegionData
, 'rb')
222 Buffer
.write(BinFile
.read())
224 Size
= Size
- FileLength
226 # Pad the left buffer
229 if (ErasePolarity
== '1') :
233 for i
in range(0, Size
):
234 Buffer
.write(pack('B', PadData
))
236 if self
.RegionType
== 'DATA' :
237 GenFdsGlobalVariable
.InfLogger(' Region Name = DATA')
239 for RegionData
in self
.RegionDataList
:
240 Data
= RegionData
.split(',')
241 DataSize
= DataSize
+ len(Data
)
243 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Size of DATA is larger than Region Size ")
246 Buffer
.write(pack('B', int(item
, 16)))
247 Size
= Size
- DataSize
249 # Pad the left buffer
252 if (ErasePolarity
== '1') :
256 for i
in range(0, Size
):
257 Buffer
.write(pack('B', PadData
))
259 if self
.RegionType
== None:
260 GenFdsGlobalVariable
.InfLogger(' Region Name = None')
261 if (ErasePolarity
== '1') :
265 for i
in range(0, Size
):
266 Buffer
.write(pack('B', PadData
))
268 def GetFvAlignValue(self
, Str
):
271 Str
= Str
.strip().upper()
272 if Str
.endswith('K'):
275 elif Str
.endswith('M'):
278 elif Str
.endswith('G'):
279 Granu
= 1024 * 1024 * 1024
284 AlignValue
= int(Str
) * Granu
287 ## BlockSizeOfRegion()
289 # @param BlockSizeList List of block information
290 # @param FvObj The object for FV
292 def BlockInfoOfRegion(self
, BlockSizeList
, FvObj
):
295 RemindingSize
= self
.Size
297 for (BlockSize
, BlockNum
, pcd
) in BlockSizeList
:
298 End
= Start
+ BlockSize
* BlockNum
299 # region not started yet
300 if self
.Offset
>= End
:
303 # region located in current blocks
305 # region ended within current blocks
306 if self
.Offset
+ self
.Size
<= End
:
307 ExpectedList
.append((BlockSize
, (RemindingSize
+ BlockSize
- 1) / BlockSize
))
309 # region not ended yet
311 # region not started in middle of current blocks
312 if self
.Offset
<= Start
:
313 UsedBlockNum
= BlockNum
314 # region started in middle of current blocks
316 UsedBlockNum
= (End
- self
.Offset
) / BlockSize
318 ExpectedList
.append((BlockSize
, UsedBlockNum
))
319 RemindingSize
-= BlockSize
* UsedBlockNum
321 if FvObj
.BlockSizeList
== []:
322 FvObj
.BlockSizeList
= ExpectedList
324 # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",
325 # if so, use ExpectedList
326 for Item
in FvObj
.BlockSizeList
:
327 if Item
[0] == None or Item
[1] == None:
328 FvObj
.BlockSizeList
= ExpectedList
330 # make sure region size is no smaller than the summed block size in FV
332 for Item
in FvObj
.BlockSizeList
:
333 Sum
+= Item
[0] * Item
[1]
335 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "
336 % (FvObj
.UiFvName
, Sum
, self
.Size
))
337 # check whether the BlockStatements in FV section is appropriate
338 ExpectedListData
= ''
339 for Item
in ExpectedList
:
340 ExpectedListData
+= "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t" % Item
342 for Item
in FvObj
.BlockSizeList
:
343 if Item
[0] != ExpectedList
[Index
][0]:
344 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
345 % FvObj
.UiFvName
, ExtraData
=ExpectedListData
)
346 elif Item
[1] != ExpectedList
[Index
][1]:
347 if (Item
[1] < ExpectedList
[Index
][1]) and (Index
== len(FvObj
.BlockSizeList
) - 1):
350 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
351 % FvObj
.UiFvName
, ExtraData
=ExpectedListData
)