]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/Region.py
2 # process FD Region generation
4 # Copyright (c) 2007 - 2010, 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
24 from Common
import EdkLogger
25 from Common
.BuildToolError
import *
30 class Region(RegionClassObject
):
34 # @param self The object pointer
37 RegionClassObject
.__init
__(self
)
42 # Add region data to the Buffer
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
55 def AddToBuffer(self
, Buffer
, BaseAddress
, BlockSizeList
, ErasePolarity
, ImageBinDict
, vtfDict
= None, MacroDict
= {}):
57 GenFdsGlobalVariable
.InfLogger('\nGenerate Region at Offset 0x%X' % self
.Offset
)
58 GenFdsGlobalVariable
.InfLogger(" Region Size = 0x%X" %Size
)
59 GenFdsGlobalVariable
.SharpCounter
= 0
61 if self
.RegionType
== 'FV':
65 self
.FvAddress
= int(BaseAddress
, 16) + self
.Offset
66 FvBaseAddress
= '0x%X' %self
.FvAddress
68 for RegionData
in self
.RegionDataList
:
70 if RegionData
.endswith(".fv"):
71 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
72 GenFdsGlobalVariable
.InfLogger(' Region FV File Name = .fv : %s'%RegionData
)
73 if RegionData
[1] != ':' :
74 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
75 if not os
.path
.exists(RegionData
):
76 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
79 elif RegionData
.upper() + 'fv' in ImageBinDict
.keys():
80 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
81 FileName
= ImageBinDict
[RegionData
.upper() + 'fv']
87 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
88 FvObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(RegionData
.upper())
91 GenFdsGlobalVariable
.InfLogger(' Region Name = FV')
95 self
.BlockInfoOfRegion(BlockSizeList
, FvObj
)
96 self
.FvAddress
= self
.FvAddress
+ FvOffset
97 FvAlignValue
= self
.GetFvAlignValue(FvObj
.FvAlignment
)
98 if self
.FvAddress
% FvAlignValue
!= 0:
99 EdkLogger
.error("GenFds", GENFDS_ERROR
,
100 "FV (%s) is NOT %s Aligned!" % (FvObj
.UiFvName
, FvObj
.FvAlignment
))
101 FvBuffer
= StringIO
.StringIO('')
102 FvBaseAddress
= '0x%X' %self
.FvAddress
105 FvObj
.AddToBuffer(FvBuffer
, FvBaseAddress
, BlockSize
, BlockNum
, ErasePolarity
, vtfDict
)
106 if FvBuffer
.len > Size
:
108 EdkLogger
.error("GenFds", GENFDS_ERROR
,
109 "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData
, Size
))
111 # Put the generated image into FD buffer.
113 Buffer
.write(FvBuffer
.getvalue())
115 FvOffset
= FvOffset
+ FvBuffer
.len
116 Size
= Size
- FvBuffer
.len
119 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (RegionData
))
121 # Add the exist Fv image into FD buffer
124 FileLength
= os
.stat(FileName
)[ST_SIZE
]
125 if FileLength
> Size
:
126 EdkLogger
.error("GenFds", GENFDS_ERROR
,
127 "Size of FV File (%s) is larger than Region Size 0x%X specified." \
128 % (RegionData
, Size
))
129 BinFile
= open (FileName
, 'r+b')
130 Buffer
.write(BinFile
.read())
132 Size
= Size
- FileLength
134 # Pad the left buffer
137 if (ErasePolarity
== '1') :
141 for i
in range(0, Size
):
142 Buffer
.write(pack('B', PadData
))
144 if self
.RegionType
== 'CAPSULE':
146 # Get Capsule from Capsule Dict
148 for RegionData
in self
.RegionDataList
:
149 if RegionData
.endswith(".cap"):
150 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
151 GenFdsGlobalVariable
.InfLogger(' Region CAPSULE Image Name = .cap : %s'%RegionData
)
152 if RegionData
[1] != ':' :
153 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
154 if not os
.path
.exists(RegionData
):
155 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
157 FileName
= RegionData
158 elif RegionData
.upper() + 'cap' in ImageBinDict
.keys():
159 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
160 FileName
= ImageBinDict
[RegionData
.upper() + 'cap']
163 # Generate Capsule image and Put it into FD buffer
166 if RegionData
.upper() in GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
.keys():
167 CapsuleObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.CapsuleDict
[RegionData
.upper()]
169 if CapsuleObj
!= None :
170 CapsuleObj
.CapsuleName
= RegionData
.upper()
171 GenFdsGlobalVariable
.InfLogger(' Region Name = CAPSULE')
173 # Call GenFv tool to generate Capsule Image
175 FileName
= CapsuleObj
.GenCapsule()
176 CapsuleObj
.CapsuleName
= None
178 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Capsule (%s) is NOT described in FDF file!" % (RegionData
))
181 # Add the capsule image into FD buffer
183 FileLength
= os
.stat(FileName
)[ST_SIZE
]
184 if FileLength
> Size
:
185 EdkLogger
.error("GenFds", GENFDS_ERROR
,
186 "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
187 % (FileLength
, RegionData
, Size
))
188 BinFile
= open (FileName
, 'r+b')
189 Buffer
.write(BinFile
.read())
191 Size
= Size
- FileLength
193 # Pad the left buffer
196 if (ErasePolarity
== '1') :
200 for i
in range(0, Size
):
201 Buffer
.write(pack('B', PadData
))
203 if self
.RegionType
== 'FILE':
204 for RegionData
in self
.RegionDataList
:
205 RegionData
= GenFdsGlobalVariable
.MacroExtend(RegionData
, MacroDict
)
206 if RegionData
[1] != ':' :
207 RegionData
= os
.path
.join (GenFdsGlobalVariable
.WorkSpaceDir
, RegionData
)
208 if not os
.path
.exists(RegionData
):
209 EdkLogger
.error("GenFds", FILE_NOT_FOUND
, ExtraData
=RegionData
)
211 # Add the file image into FD buffer
213 FileLength
= os
.stat(RegionData
)[ST_SIZE
]
214 if FileLength
> Size
:
215 EdkLogger
.error("GenFds", GENFDS_ERROR
,
216 "Size of File (%s) is larger than Region Size 0x%X specified." \
217 % (RegionData
, Size
))
218 GenFdsGlobalVariable
.InfLogger(' Region File Name = %s'%RegionData
)
219 BinFile
= open (RegionData
, 'r+b')
220 Buffer
.write(BinFile
.read())
222 Size
= Size
- FileLength
224 # Pad the left buffer
227 if (ErasePolarity
== '1') :
231 for i
in range(0, Size
):
232 Buffer
.write(pack('B', PadData
))
234 if self
.RegionType
== 'DATA' :
235 GenFdsGlobalVariable
.InfLogger(' Region Name = DATA')
237 for RegionData
in self
.RegionDataList
:
238 Data
= RegionData
.split(',')
239 DataSize
= DataSize
+ len(Data
)
241 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Size of DATA is larger than Region Size ")
244 Buffer
.write(pack('B', int(item
, 16)))
245 Size
= Size
- DataSize
247 # Pad the left buffer
250 if (ErasePolarity
== '1') :
254 for i
in range(0, Size
):
255 Buffer
.write(pack('B', PadData
))
257 if self
.RegionType
== None:
258 GenFdsGlobalVariable
.InfLogger(' Region Name = None')
259 if (ErasePolarity
== '1') :
263 for i
in range(0, Size
):
264 Buffer
.write(pack('B', PadData
))
266 def GetFvAlignValue(self
, Str
):
269 Str
= Str
.strip().upper()
270 if Str
.endswith('K'):
273 elif Str
.endswith('M'):
276 elif Str
.endswith('G'):
277 Granu
= 1024*1024*1024
282 AlignValue
= int(Str
)*Granu
285 ## BlockSizeOfRegion()
287 # @param BlockSizeList List of block information
288 # @param FvObj The object for FV
290 def BlockInfoOfRegion(self
, BlockSizeList
, FvObj
):
293 RemindingSize
= self
.Size
295 for (BlockSize
, BlockNum
, pcd
) in BlockSizeList
:
296 End
= Start
+ BlockSize
* BlockNum
297 # region not started yet
298 if self
.Offset
>= End
:
301 # region located in current blocks
303 # region ended within current blocks
304 if self
.Offset
+ self
.Size
<= End
:
305 ExpectedList
.append((BlockSize
, (RemindingSize
+ BlockSize
- 1)/BlockSize
))
307 # region not ended yet
309 # region not started in middle of current blocks
310 if self
.Offset
<= Start
:
311 UsedBlockNum
= BlockNum
312 # region started in middle of current blocks
314 UsedBlockNum
= (End
- self
.Offset
)/BlockSize
316 ExpectedList
.append((BlockSize
, UsedBlockNum
))
317 RemindingSize
-= BlockSize
* UsedBlockNum
319 if FvObj
.BlockSizeList
== []:
320 FvObj
.BlockSizeList
= ExpectedList
322 # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",
323 # if so, use ExpectedList
324 for Item
in FvObj
.BlockSizeList
:
325 if Item
[0] == None or Item
[1] == None:
326 FvObj
.BlockSizeList
= ExpectedList
328 # make sure region size is no smaller than the summed block size in FV
330 for Item
in FvObj
.BlockSizeList
:
331 Sum
+= Item
[0] * Item
[1]
333 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "
334 %(FvObj
.UiFvName
, Sum
, self
.Size
))
335 # check whether the BlockStatements in FV section is appropriate
336 ExpectedListData
= ''
337 for Item
in ExpectedList
:
338 ExpectedListData
+= "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t"%Item
340 for Item
in FvObj
.BlockSizeList
:
341 if Item
[0] != ExpectedList
[Index
][0]:
342 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
343 %FvObj
.UiFvName
, ExtraData
= ExpectedListData
)
344 elif Item
[1] != ExpectedList
[Index
][1]:
345 if (Item
[1] < ExpectedList
[Index
][1]) and (Index
== len(FvObj
.BlockSizeList
) - 1):
348 EdkLogger
.error("GenFds", GENFDS_ERROR
, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
349 %FvObj
.UiFvName
, ExtraData
= ExpectedListData
)