]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/GenFds/Fv.py
SecurityPkg: Change TPM MMIO range attribute
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / Fv.py
... / ...
CommitLineData
1## @file\r
2# process FV generation\r
3#\r
4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
18import Common.LongFilePathOs as os\r
19import subprocess\r
20import StringIO\r
21from struct import *\r
22\r
23import Ffs\r
24import AprioriSection\r
25from GenFdsGlobalVariable import GenFdsGlobalVariable\r
26from GenFds import GenFds\r
27from CommonDataClass.FdfClass import FvClassObject\r
28from Common.Misc import SaveFileOnChange\r
29from Common.LongFilePathSupport import CopyLongFilePath\r
30from Common.LongFilePathSupport import OpenLongFilePath as open\r
31\r
32T_CHAR_LF = '\n'\r
33FV_UI_EXT_ENTY_GUID = 'A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C'\r
34\r
35## generate FV\r
36#\r
37#\r
38class FV (FvClassObject):\r
39 ## The constructor\r
40 #\r
41 # @param self The object pointer\r
42 #\r
43 def __init__(self):\r
44 FvClassObject.__init__(self)\r
45 self.FvInfFile = None\r
46 self.FvAddressFile = None\r
47 self.BaseAddress = None\r
48 self.InfFileName = None\r
49 self.FvAddressFileName = None\r
50 self.CapsuleName = None\r
51 self.FvBaseAddress = None\r
52 self.FvForceRebase = None\r
53 \r
54 ## AddToBuffer()\r
55 #\r
56 # Generate Fv and add it to the Buffer\r
57 #\r
58 # @param self The object pointer\r
59 # @param Buffer The buffer generated FV data will be put\r
60 # @param BaseAddress base address of FV\r
61 # @param BlockSize block size of FV\r
62 # @param BlockNum How many blocks in FV\r
63 # @param ErasePolarity Flash erase polarity\r
64 # @param VtfDict VTF objects\r
65 # @param MacroDict macro value pair\r
66 # @retval string Generated FV file path\r
67 #\r
68 def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :\r
69\r
70 if BaseAddress == None and self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
71 return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']\r
72 \r
73 #\r
74 # Check whether FV in Capsule is in FD flash region.\r
75 # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.\r
76 #\r
77 if self.CapsuleName != None:\r
78 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
79 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
80 for RegionObj in FdObj.RegionList:\r
81 if RegionObj.RegionType == 'FV':\r
82 for RegionData in RegionObj.RegionDataList:\r
83 if RegionData.endswith(".fv"):\r
84 continue\r
85 elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
86 continue\r
87 elif self.UiFvName.upper() == RegionData.upper():\r
88 GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))\r
89\r
90 GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)\r
91 GenFdsGlobalVariable.LargeFileInFvFlags.append(False)\r
92 FFSGuid = None\r
93 \r
94 if self.FvBaseAddress != None:\r
95 BaseAddress = self.FvBaseAddress\r
96\r
97 self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)\r
98 #\r
99 # First Process the Apriori section\r
100 #\r
101 MacroDict.update(self.DefineVarDict)\r
102\r
103 GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')\r
104 FfsFileList = []\r
105 for AprSection in self.AprioriSectionList:\r
106 FileName = AprSection.GenFfs (self.UiFvName, MacroDict)\r
107 FfsFileList.append(FileName)\r
108 # Add Apriori file name to Inf file\r
109 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
110 FileName + \\r
111 T_CHAR_LF)\r
112\r
113 # Process Modules in FfsList\r
114 for FfsFile in self.FfsList :\r
115 FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress)\r
116 FfsFileList.append(FileName)\r
117 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
118 FileName + \\r
119 T_CHAR_LF)\r
120\r
121 SaveFileOnChange(self.InfFileName, self.FvInfFile.getvalue(), False)\r
122 self.FvInfFile.close()\r
123 #\r
124 # Call GenFv tool\r
125 #\r
126 FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)\r
127 FvOutputFile = FvOutputFile + '.Fv'\r
128 # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)\r
129 if self.CreateFileName != None:\r
130 FvOutputFile = self.CreateFileName\r
131\r
132 FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')\r
133 CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)\r
134 OrigFvInfo = None\r
135 if os.path.exists (FvInfoFileName):\r
136 OrigFvInfo = open(FvInfoFileName, 'r').read()\r
137 if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:\r
138 FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;\r
139 GenFdsGlobalVariable.GenerateFirmwareVolume(\r
140 FvOutputFile,\r
141 [self.InfFileName],\r
142 AddressFile=FvInfoFileName,\r
143 FfsList=FfsFileList,\r
144 ForceRebase=self.FvForceRebase,\r
145 FileSystemGuid=FFSGuid\r
146 )\r
147\r
148 NewFvInfo = None\r
149 if os.path.exists (FvInfoFileName):\r
150 NewFvInfo = open(FvInfoFileName, 'r').read()\r
151 if NewFvInfo != None and NewFvInfo != OrigFvInfo:\r
152 FvChildAddr = []\r
153 AddFileObj = open(FvInfoFileName, 'r')\r
154 AddrStrings = AddFileObj.readlines()\r
155 AddrKeyFound = False\r
156 for AddrString in AddrStrings:\r
157 if AddrKeyFound:\r
158 #get base address for the inside FvImage\r
159 FvChildAddr.append (AddrString)\r
160 elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:\r
161 AddrKeyFound = True\r
162 AddFileObj.close()\r
163\r
164 if FvChildAddr != []:\r
165 # Update Ffs again\r
166 for FfsFile in self.FfsList :\r
167 FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress)\r
168 \r
169 if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:\r
170 FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;\r
171 #Update GenFv again\r
172 GenFdsGlobalVariable.GenerateFirmwareVolume(\r
173 FvOutputFile,\r
174 [self.InfFileName],\r
175 AddressFile=FvInfoFileName,\r
176 FfsList=FfsFileList,\r
177 ForceRebase=self.FvForceRebase,\r
178 FileSystemGuid=FFSGuid\r
179 )\r
180\r
181 #\r
182 # Write the Fv contents to Buffer\r
183 #\r
184 FvFileObj = open ( FvOutputFile,'r+b')\r
185\r
186 GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s FV Successfully" %self.UiFvName)\r
187 GenFdsGlobalVariable.SharpCounter = 0\r
188\r
189 Buffer.write(FvFileObj.read())\r
190 FvFileObj.seek(0)\r
191 # PI FvHeader is 0x48 byte\r
192 FvHeaderBuffer = FvFileObj.read(0x48)\r
193 # FV alignment position.\r
194 FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)\r
195 # FvAlignmentValue is larger than or equal to 1K\r
196 if FvAlignmentValue >= 0x400:\r
197 if FvAlignmentValue >= 0x10000:\r
198 #The max alignment supported by FFS is 64K.\r
199 self.FvAlignment = "64K"\r
200 else:\r
201 self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"\r
202 else:\r
203 # FvAlignmentValue is less than 1K\r
204 self.FvAlignment = str (FvAlignmentValue)\r
205 FvFileObj.close()\r
206 GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile\r
207 GenFdsGlobalVariable.LargeFileInFvFlags.pop()\r
208 return FvOutputFile\r
209\r
210 ## __InitializeInf__()\r
211 #\r
212 # Initilize the inf file to create FV\r
213 #\r
214 # @param self The object pointer\r
215 # @param BaseAddress base address of FV\r
216 # @param BlockSize block size of FV\r
217 # @param BlockNum How many blocks in FV\r
218 # @param ErasePolarity Flash erase polarity\r
219 # @param VtfDict VTF objects\r
220 #\r
221 def __InitializeInf__ (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1', VtfDict=None) :\r
222 #\r
223 # Create FV inf file\r
224 #\r
225 self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir,\r
226 self.UiFvName + '.inf')\r
227 self.FvInfFile = StringIO.StringIO()\r
228\r
229 #\r
230 # Add [Options]\r
231 #\r
232 self.FvInfFile.writelines("[options]" + T_CHAR_LF)\r
233 if BaseAddress != None :\r
234 self.FvInfFile.writelines("EFI_BASE_ADDRESS = " + \\r
235 BaseAddress + \\r
236 T_CHAR_LF)\r
237\r
238 if BlockSize != None:\r
239 self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \\r
240 '0x%X' %BlockSize + \\r
241 T_CHAR_LF)\r
242 if BlockNum != None:\r
243 self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \\r
244 ' 0x%X' %BlockNum + \\r
245 T_CHAR_LF)\r
246 else:\r
247 if self.BlockSizeList == []:\r
248 #set default block size is 1\r
249 self.FvInfFile.writelines("EFI_BLOCK_SIZE = 0x1" + T_CHAR_LF)\r
250 \r
251 for BlockSize in self.BlockSizeList :\r
252 if BlockSize[0] != None:\r
253 self.FvInfFile.writelines("EFI_BLOCK_SIZE = " + \\r
254 '0x%X' %BlockSize[0] + \\r
255 T_CHAR_LF)\r
256\r
257 if BlockSize[1] != None:\r
258 self.FvInfFile.writelines("EFI_NUM_BLOCKS = " + \\r
259 ' 0x%X' %BlockSize[1] + \\r
260 T_CHAR_LF)\r
261\r
262 if self.BsBaseAddress != None:\r
263 self.FvInfFile.writelines('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \\r
264 '0x%X' %self.BsBaseAddress)\r
265 if self.RtBaseAddress != None:\r
266 self.FvInfFile.writelines('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \\r
267 '0x%X' %self.RtBaseAddress)\r
268 #\r
269 # Add attribute\r
270 #\r
271 self.FvInfFile.writelines("[attributes]" + T_CHAR_LF)\r
272\r
273 self.FvInfFile.writelines("EFI_ERASE_POLARITY = " + \\r
274 ' %s' %ErasePloarity + \\r
275 T_CHAR_LF)\r
276 if not (self.FvAttributeDict == None):\r
277 for FvAttribute in self.FvAttributeDict.keys() :\r
278 self.FvInfFile.writelines("EFI_" + \\r
279 FvAttribute + \\r
280 ' = ' + \\r
281 self.FvAttributeDict[FvAttribute] + \\r
282 T_CHAR_LF )\r
283 if self.FvAlignment != None:\r
284 self.FvInfFile.writelines("EFI_FVB2_ALIGNMENT_" + \\r
285 self.FvAlignment.strip() + \\r
286 " = TRUE" + \\r
287 T_CHAR_LF)\r
288 \r
289 #\r
290 # Generate FV extension header file\r
291 #\r
292 if self.FvNameGuid == None or self.FvNameGuid == '':\r
293 if len(self.FvExtEntryType) > 0:\r
294 GenFdsGlobalVariable.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self.UiFvName))\r
295 \r
296 if self.FvNameGuid <> None and self.FvNameGuid <> '':\r
297 TotalSize = 16 + 4\r
298 Buffer = ''\r
299 #\r
300 # Create EXT entry for FV UI name\r
301 # This GUID is used: A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C\r
302 #\r
303 FvUiLen = len(self.UiFvName)\r
304 TotalSize += (FvUiLen + 16 + 4)\r
305 Guid = FV_UI_EXT_ENTY_GUID.split('-')\r
306 #\r
307 # Layout:\r
308 # EFI_FIRMWARE_VOLUME_EXT_ENTRY : size 4\r
309 # GUID : size 16\r
310 # FV UI name\r
311 #\r
312 Buffer += (pack('HH', (FvUiLen + 16 + 4), 0x0002)\r
313 + pack('=LHHBBBBBBBB', int(Guid[0], 16), int(Guid[1], 16), int(Guid[2], 16),\r
314 int(Guid[3][-4:-2], 16), int(Guid[3][-2:], 16), int(Guid[4][-12:-10], 16),\r
315 int(Guid[4][-10:-8], 16), int(Guid[4][-8:-6], 16), int(Guid[4][-6:-4], 16),\r
316 int(Guid[4][-4:-2], 16), int(Guid[4][-2:], 16))\r
317 + self.UiFvName)\r
318\r
319 for Index in range (0, len(self.FvExtEntryType)):\r
320 if self.FvExtEntryType[Index] == 'FILE':\r
321 # check if the path is absolute or relative\r
322 if os.path.isabs(self.FvExtEntryData[Index]):\r
323 FileFullPath = os.path.normpath(self.FvExtEntryData[Index])\r
324 else:\r
325 FileFullPath = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.FvExtEntryData[Index]))\r
326 # check if the file path exists or not\r
327 if not os.path.isfile(FileFullPath):\r
328 GenFdsGlobalVariable.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self.FvExtEntryData[Index]))\r
329 FvExtFile = open (FileFullPath,'rb')\r
330 FvExtFile.seek(0,2)\r
331 Size = FvExtFile.tell()\r
332 if Size >= 0x10000:\r
333 GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self.FvExtEntryData[Index]))\r
334 TotalSize += (Size + 4)\r
335 FvExtFile.seek(0)\r
336 Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))\r
337 Buffer += FvExtFile.read() \r
338 FvExtFile.close()\r
339 if self.FvExtEntryType[Index] == 'DATA':\r
340 ByteList = self.FvExtEntryData[Index].split(',')\r
341 Size = len (ByteList)\r
342 if Size >= 0x10000:\r
343 GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self.FvExtEntryData[Index]))\r
344 TotalSize += (Size + 4)\r
345 Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))\r
346 for Index1 in range (0, Size):\r
347 Buffer += pack('B', int(ByteList[Index1], 16))\r
348\r
349 Guid = self.FvNameGuid.split('-')\r
350 Buffer = pack('=LHHBBBBBBBBL', \r
351 int(Guid[0], 16), \r
352 int(Guid[1], 16), \r
353 int(Guid[2], 16), \r
354 int(Guid[3][-4:-2], 16), \r
355 int(Guid[3][-2:], 16), \r
356 int(Guid[4][-12:-10], 16),\r
357 int(Guid[4][-10:-8], 16),\r
358 int(Guid[4][-8:-6], 16),\r
359 int(Guid[4][-6:-4], 16),\r
360 int(Guid[4][-4:-2], 16),\r
361 int(Guid[4][-2:], 16),\r
362 TotalSize\r
363 ) + Buffer\r
364\r
365 #\r
366 # Generate FV extension header file if the total size is not zero\r
367 #\r
368 if TotalSize > 0:\r
369 FvExtHeaderFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName + '.ext')\r
370 FvExtHeaderFile = StringIO.StringIO()\r
371 FvExtHeaderFile.write(Buffer)\r
372 Changed = SaveFileOnChange(FvExtHeaderFileName, FvExtHeaderFile.getvalue(), True)\r
373 FvExtHeaderFile.close()\r
374 if Changed:\r
375 if os.path.exists (self.InfFileName):\r
376 os.remove (self.InfFileName)\r
377 self.FvInfFile.writelines("EFI_FV_EXT_HEADER_FILE_NAME = " + \\r
378 FvExtHeaderFileName + \\r
379 T_CHAR_LF)\r
380\r
381 \r
382 #\r
383 # Add [Files]\r
384 #\r
385 self.FvInfFile.writelines("[files]" + T_CHAR_LF)\r
386 if VtfDict != None and self.UiFvName in VtfDict.keys():\r
387 self.FvInfFile.writelines("EFI_FILE_NAME = " + \\r
388 VtfDict.get(self.UiFvName) + \\r
389 T_CHAR_LF)\r