a9ff26e597eda6ea4bffc4f4d4a698fddc5d1b9a
2 # process FV generation
4 # Copyright (c) 2007, Intel Corporation
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
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.
26 from GenFdsGlobalVariable
import GenFdsGlobalVariable
27 from GenFds
import GenFds
28 from CommonDataClass
.FdfClass
import FvClassObject
29 from Common
.Misc
import SaveFileOnChange
36 class FV (FvClassObject
):
39 # @param self The object pointer
42 FvClassObject
.__init
__(self
)
44 self
.FvAddressFile
= None
45 self
.BaseAddress
= None
46 self
.InfFileName
= None
47 self
.FvAddressFileName
= None
48 self
.CapsuleName
= None
52 # Generate Fv and add it to the Buffer
54 # @param self The object pointer
55 # @param Buffer The buffer generated FV data will be put
56 # @param BaseAddress base address of FV
57 # @param BlockSize block size of FV
58 # @param BlockNum How many blocks in FV
59 # @param ErasePolarity Flash erase polarity
60 # @param VtfDict VTF objects
61 # @param MacroDict macro value pair
62 # @retval string Generated FV file path
64 def AddToBuffer (self
, Buffer
, BaseAddress
=None, BlockSize
= None, BlockNum
=None, ErasePloarity
='1', VtfDict
=None, MacroDict
= {}) :
66 if self
.UiFvName
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
67 return GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv']
70 # Check whether FV in Capsule is in FD flash region.
71 # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.
73 if self
.CapsuleName
!= None:
74 for FdName
in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
75 FdObj
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
[FdName
]
76 for RegionObj
in FdObj
.RegionList
:
77 if RegionObj
.RegionType
== 'FV':
78 for RegionData
in RegionObj
.RegionDataList
:
79 if RegionData
.endswith(".fv"):
81 elif RegionData
.upper() + 'fv' in GenFds
.ImageBinDict
.keys():
83 elif self
.UiFvName
.upper() == RegionData
.upper():
84 GenFdsGlobalVariable
.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self
.CapsuleName
, self
.UiFvName
.upper()))
86 GenFdsGlobalVariable
.InfLogger( "\nGenerating %s FV" %self
.UiFvName
)
88 self
.__InitializeInf
__(BaseAddress
, BlockSize
, BlockNum
, ErasePloarity
, VtfDict
)
90 # First Process the Apriori section
92 MacroDict
.update(self
.DefineVarDict
)
94 GenFdsGlobalVariable
.VerboseLogger('First generate Apriori file !')
96 for AprSection
in self
.AprioriSectionList
:
97 FileName
= AprSection
.GenFfs (self
.UiFvName
, MacroDict
)
98 FfsFileList
.append(FileName
)
99 # Add Apriori file name to Inf file
100 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
104 # Process Modules in FfsList
105 for FfsFile
in self
.FfsList
:
106 FileName
= FfsFile
.GenFfs(MacroDict
)
107 FfsFileList
.append(FileName
)
108 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
112 SaveFileOnChange(self
.InfFileName
, self
.FvInfFile
.getvalue(), False)
113 self
.FvInfFile
.close()
117 FvOutputFile
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
)
118 FvOutputFile
= FvOutputFile
+ '.Fv'
119 # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
120 if self
.CreateFileName
!= None:
121 FvOutputFile
= self
.CreateFileName
123 FvInfoFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.UiFvName
+ '.inf')
124 shutil
.copy(GenFdsGlobalVariable
.FvAddressFileName
, FvInfoFileName
)
125 GenFdsGlobalVariable
.GenerateFirmwareVolume(
128 AddressFile
=FvInfoFileName
,
133 # Write the Fv contents to Buffer
135 FvFileObj
= open ( FvOutputFile
,'r+b')
137 GenFdsGlobalVariable
.VerboseLogger( "\nGenerate %s FV Successfully" %self
.UiFvName
)
138 GenFdsGlobalVariable
.SharpCounter
= 0
140 Buffer
.write(FvFileObj
.read())
142 GenFds
.ImageBinDict
[self
.UiFvName
.upper() + 'fv'] = FvOutputFile
145 ## __InitializeInf__()
147 # Initilize the inf file to create FV
149 # @param self The object pointer
150 # @param BaseAddress base address of FV
151 # @param BlockSize block size of FV
152 # @param BlockNum How many blocks in FV
153 # @param ErasePolarity Flash erase polarity
154 # @param VtfDict VTF objects
156 def __InitializeInf__ (self
, BaseAddress
= None, BlockSize
= None, BlockNum
= None, ErasePloarity
='1', VtfDict
=None) :
160 self
.InfFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
,
161 self
.UiFvName
+ '.inf')
162 self
.FvInfFile
= StringIO
.StringIO()
167 self
.FvInfFile
.writelines("[options]" + T_CHAR_LF
)
168 if BaseAddress
!= None :
169 self
.FvInfFile
.writelines("EFI_BASE_ADDRESS = " + \
173 if BlockSize
!= None:
174 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
175 '0x%X' %BlockSize
+ \
178 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
179 ' 0x%X' %BlockNum
+ \
182 for BlockSize
in self
.BlockSizeList
:
183 if BlockSize
[0] != None:
184 self
.FvInfFile
.writelines("EFI_BLOCK_SIZE = " + \
185 '0x%X' %BlockSize
[0] + \
188 if BlockSize
[1] != None:
189 self
.FvInfFile
.writelines("EFI_NUM_BLOCKS = " + \
190 ' 0x%X' %BlockSize
[1] + \
193 if self
.BsBaseAddress
!= None:
194 self
.FvInfFile
.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \
195 '0x%X' %self
.BsBaseAddress
)
196 if self
.RtBaseAddress
!= None:
197 self
.FvInfFile
.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \
198 '0x%X' %self
.RtBaseAddress
)
202 self
.FvInfFile
.writelines("[attributes]" + T_CHAR_LF
)
204 self
.FvInfFile
.writelines("EFI_ERASE_POLARITY = " + \
205 ' %s' %ErasePloarity
+ \
207 if not (self
.FvAttributeDict
== None):
208 for FvAttribute
in self
.FvAttributeDict
.keys() :
209 self
.FvInfFile
.writelines("EFI_" + \
212 self
.FvAttributeDict
[FvAttribute
] + \
214 if self
.FvAlignment
!= None:
215 self
.FvInfFile
.writelines("EFI_FVB2_ALIGNMENT_" + \
216 self
.FvAlignment
.strip() + \
221 # Generate FV extension header file
223 if self
.FvNameGuid
== None or self
.FvNameGuid
== '':
224 if len(self
.FvExtEntryType
) > 0:
225 GenFdsGlobalVariable
.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self
.UiFvName
))
227 if self
.FvNameGuid
<> None and self
.FvNameGuid
<> '':
230 for Index
in range (0, len(self
.FvExtEntryType
)):
231 if self
.FvExtEntryType
[Index
] == 'FILE':
232 # check if the path is absolute or relative
233 if os
.path
.isabs(self
.FvExtEntryData
[Index
]):
234 FileFullPath
= os
.path
.normpath(self
.FvExtEntryData
[Index
])
236 FileFullPath
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.FvExtEntryData
[Index
]))
237 # check if the file path exists or not
238 if not os
.path
.isfile(FileFullPath
):
239 GenFdsGlobalVariable
.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self
.FvExtEntryData
[Index
]))
240 FvExtFile
= open (FileFullPath
,'rb')
242 Size
= FvExtFile
.tell()
244 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
245 TotalSize
+= (Size
+ 4)
247 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
248 Buffer
+= FvExtFile
.read()
250 if self
.FvExtEntryType
[Index
] == 'DATA':
251 ByteList
= self
.FvExtEntryData
[Index
].split(',')
252 Size
= len (ByteList
)
254 GenFdsGlobalVariable
.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self
.FvExtEntryData
[Index
]))
255 TotalSize
+= (Size
+ 4)
256 Buffer
+= pack('HH', (Size
+ 4), int(self
.FvExtEntryTypeValue
[Index
], 16))
257 for Index1
in range (0, Size
):
258 Buffer
+= pack('B', int(ByteList
[Index1
], 16))
260 Guid
= self
.FvNameGuid
.split('-')
261 Buffer
= pack('LHHBBBBBBBBL',
265 int(Guid
[3][-4:-2], 16),
266 int(Guid
[3][-2:], 16),
267 int(Guid
[4][-12:-10], 16),
268 int(Guid
[4][-10:-8], 16),
269 int(Guid
[4][-8:-6], 16),
270 int(Guid
[4][-6:-4], 16),
271 int(Guid
[4][-4:-2], 16),
272 int(Guid
[4][-2:], 16),
277 # Generate FV extension header file if the total size is not zero
280 FvExtHeaderFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, self
.UiFvName
+ '.ext')
281 FvExtHeaderFile
= open (FvExtHeaderFileName
,'wb')
282 FvExtHeaderFile
.write(Buffer
)
283 FvExtHeaderFile
.close()
284 self
.FvInfFile
.writelines("EFI_FV_EXT_HEADER_FILE_NAME = " + \
285 FvExtHeaderFileName
+ \
292 self
.FvInfFile
.writelines("[files]" + T_CHAR_LF
)
293 if VtfDict
!= None and self
.UiFvName
in VtfDict
.keys():
294 self
.FvInfFile
.writelines("EFI_FILE_NAME = " + \
295 VtfDict
.get(self
.UiFvName
) + \